00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #define MODULE_NAME "uptime"
00034 #define MAKING_UPTIME
00035
00036 #include "uptime.h"
00037 #include "../module.h"
00038 #include "../server.mod/server.h"
00039 #include <netdb.h>
00040 #include <netinet/in.h>
00041 #include <arpa/inet.h>
00042 #include <unistd.h>
00043 #include <fcntl.h>
00044 #include <sys/types.h>
00045 #include <sys/socket.h>
00046 #include <fcntl.h>
00047 #include <sys/stat.h>
00048 #include <unistd.h>
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 typedef struct PackUp {
00064 int regnr;
00065 int pid;
00066 int type;
00067 unsigned long packets_sent;
00068 unsigned long uptime;
00069 unsigned long ontime;
00070 unsigned long now2;
00071 unsigned long sysup;
00072 char string[3];
00073 } PackUp;
00074
00075 PackUp upPack;
00076
00077 static Function *global = NULL;
00078
00079 static int minutes = 0;
00080 static int seconds = 0;
00081 static int next_seconds = 0;
00082 static int next_minutes = 0;
00083 static int update_interval = 720;
00084 static time_t next_update = 0;
00085 static int uptimesock;
00086 static int uptimecount;
00087 static unsigned long uptimeip;
00088 static char uptime_version[48] = "";
00089
00090 void check_secondly(void);
00091 void check_minutely(void);
00092
00093 static int uptime_expmem()
00094 {
00095 return 0;
00096 }
00097
00098 static void uptime_report(int idx, int details)
00099 {
00100 int delta_seconds;
00101 char *next_update_at;
00102
00103 if (details) {
00104 delta_seconds = (int) (next_update - time(NULL));
00105 next_update_at = ctime(&next_update);
00106 next_update_at[strlen(next_update_at) - 1] = 0;
00107
00108 dprintf(idx, " %d uptime packet%s sent\n", uptimecount,
00109 (uptimecount != 1) ? "s" : "");
00110 dprintf(idx, " Approximately %-.2f hours until next update "
00111 "(at %s)\n", delta_seconds / 3600.0, next_update_at);
00112 }
00113 }
00114
00115 unsigned long get_ip()
00116 {
00117 struct hostent *hp;
00118 IP ip;
00119 struct in_addr *in;
00120
00121
00122 if (uptime_host[0]) {
00123 if ((uptime_host[strlen(uptime_host) - 1] >= '0') &&
00124 (uptime_host[strlen(uptime_host) - 1] <= '9'))
00125 return (IP) inet_addr(uptime_host);
00126 }
00127 hp = gethostbyname(uptime_host);
00128 if (hp == NULL)
00129 return -1;
00130 in = (struct in_addr *) (hp->h_addr_list[0]);
00131 ip = (IP) (in->s_addr);
00132 return ip;
00133 }
00134
00135 int init_uptime(void)
00136 {
00137 struct sockaddr_in sai;
00138 char x[64], *z = x;
00139
00140 upPack.regnr = 0;
00141 upPack.pid = 0;
00142 upPack.type = htonl(uptime_type);
00143 upPack.packets_sent = 0;
00144 upPack.uptime = 0;
00145 uptimecount = 0;
00146 uptimeip = -1;
00147
00148 strncpyz(x, ver, sizeof x);
00149 newsplit(&z);
00150 strncpyz(uptime_version, z, sizeof uptime_version);
00151
00152 if ((uptimesock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
00153 putlog(LOG_DEBUG, "*", "init_uptime socket returned < 0 %d", uptimesock);
00154 return ((uptimesock = -1));
00155 }
00156 egg_memset(&sai, 0, sizeof(sai));
00157 sai.sin_addr.s_addr = INADDR_ANY;
00158 sai.sin_family = AF_INET;
00159 if (bind(uptimesock, (struct sockaddr *) &sai, sizeof(sai)) < 0) {
00160 close(uptimesock);
00161 return ((uptimesock = -1));
00162 }
00163 fcntl(uptimesock, F_SETFL, O_NONBLOCK | fcntl(uptimesock, F_GETFL));
00164
00165 next_minutes = rand() % update_interval;
00166 next_seconds = rand() % 59;
00167 next_update = (time_t) ((time(NULL) / 60 * 60) + (next_minutes * 60) +
00168 next_seconds);
00169
00170 return 0;
00171 }
00172
00173
00174 int send_uptime(void)
00175 {
00176 struct sockaddr_in sai;
00177 struct stat st;
00178 PackUp *mem;
00179 int len, servidx;
00180 char servhost[UHOSTLEN] = "none";
00181 module_entry *me;
00182
00183 if (uptimeip == -1) {
00184 uptimeip = get_ip();
00185 if (uptimeip == -1)
00186 return -2;
00187 }
00188
00189 uptimecount++;
00190 upPack.packets_sent = htonl(uptimecount);
00191
00192 upPack.now2 = htonl(time(NULL));
00193 upPack.ontime = 0;
00194
00195 if ((me = module_find("server", 1, 0))) {
00196 Function *server_funcs = me->funcs;
00197
00198 if (server_online) {
00199 servidx = findanyidx(serv);
00200 strncpyz(servhost, dcc[servidx].host, sizeof servhost);
00201 upPack.ontime = htonl(server_online);
00202 }
00203 }
00204
00205 if (!upPack.pid)
00206 upPack.pid = htonl(getpid());
00207
00208 if (!upPack.uptime)
00209 upPack.uptime = htonl(online_since);
00210
00211 if (stat("/proc", &st) < 0)
00212 upPack.sysup = 0;
00213 else
00214 upPack.sysup = htonl(st.st_ctime);
00215
00216 len = sizeof(upPack) + strlen(botnetnick) + strlen(servhost) +
00217 strlen(uptime_version);
00218 mem = (PackUp *) nmalloc(len);
00219 egg_bzero(mem, len);
00220
00221
00222
00223 my_memcpy(mem, &upPack, sizeof(upPack));
00224 sprintf(mem->string, "%s %s %s", botnetnick, servhost, uptime_version);
00225 egg_bzero(&sai, sizeof(sai));
00226 sai.sin_family = AF_INET;
00227 sai.sin_addr.s_addr = uptimeip;
00228 sai.sin_port = htons(uptime_port);
00229 len = sendto(uptimesock, (void *) mem, len, 0, (struct sockaddr *) &sai,
00230 sizeof(sai));
00231 nfree(mem);
00232 return len;
00233 }
00234
00235 void check_minutely()
00236 {
00237 minutes++;
00238 if (minutes >= next_minutes) {
00239
00240 del_hook(HOOK_MINUTELY, (Function) check_minutely);
00241 add_hook(HOOK_SECONDLY, (Function) check_secondly);
00242 }
00243 }
00244
00245 void check_secondly()
00246 {
00247 seconds++;
00248 if (seconds >= next_seconds) {
00249 del_hook(HOOK_SECONDLY, (Function) check_secondly);
00250
00251 send_uptime();
00252
00253 minutes = 0;
00254 seconds = 0;
00255 next_minutes = rand() % update_interval;
00256 next_seconds = rand() % 59;
00257 next_update = (time_t) ((time(NULL) / 60 * 60) + (next_minutes * 60) +
00258 next_seconds);
00259
00260
00261 add_hook(HOOK_MINUTELY, (Function) check_minutely);
00262 }
00263 }
00264
00265 static char *uptime_close()
00266 {
00267 return "You cannot unload the uptime module "
00268 "(doing so will reset your stats).";
00269 }
00270
00271 EXPORT_SCOPE char *uptime_start(Function *);
00272
00273 static Function uptime_table[] = {
00274 (Function) uptime_start,
00275 (Function) uptime_close,
00276 (Function) uptime_expmem,
00277 (Function) uptime_report,
00278 };
00279
00280 char *uptime_start(Function *global_funcs)
00281 {
00282 if (global_funcs) {
00283 global = global_funcs;
00284
00285 module_register(MODULE_NAME, uptime_table, 1, 3);
00286 if (!module_depend(MODULE_NAME, "eggdrop", 106, 11)) {
00287 module_undepend(MODULE_NAME);
00288 return "This module requires Eggdrop 1.6.11 or later.";
00289 }
00290
00291 add_help_reference("uptime.help");
00292 add_hook(HOOK_MINUTELY, (Function) check_minutely);
00293 init_uptime();
00294 }
00295 return NULL;
00296 }