Lines 47-52
Link Here
|
47 |
#include <signal.h> |
47 |
#include <signal.h> |
48 |
#include <sys/ioctl.h> |
48 |
#include <sys/ioctl.h> |
49 |
#include <sys/file.h> |
49 |
#include <sys/file.h> |
|
|
50 |
#include <dirent.h> |
50 |
|
51 |
|
51 |
#include <net/if.h> |
52 |
#include <net/if.h> |
52 |
#include <netinet/in.h> |
53 |
#include <netinet/in.h> |
Lines 96-101
Link Here
|
96 |
static int configure(int s); |
97 |
static int configure(int s); |
97 |
static int verify(const char *name); |
98 |
static int verify(const char *name); |
98 |
static int getloadavg(double ptr[3], int n); |
99 |
static int getloadavg(double ptr[3], int n); |
|
|
100 |
static void sendspool(char *myname); |
99 |
|
101 |
|
100 |
/* |
102 |
/* |
101 |
* We communicate with each neighbor in |
103 |
* We communicate with each neighbor in |
Lines 114-119
Link Here
|
114 |
static struct neighbor *neighbors; |
116 |
static struct neighbor *neighbors; |
115 |
static struct servent *sp; |
117 |
static struct servent *sp; |
116 |
static int sk; |
118 |
static int sk; |
|
|
119 |
static int route = 0; |
117 |
static int use_pointopoint = 0; |
120 |
static int use_pointopoint = 0; |
118 |
static int use_broadcast = 0; |
121 |
static int use_broadcast = 0; |
119 |
static int need_init = 1; |
122 |
static int need_init = 1; |
Lines 123-128
Link Here
|
123 |
- ((caddr_t) 0)) |
126 |
- ((caddr_t) 0)) |
124 |
|
127 |
|
125 |
static void huphandler(int); |
128 |
static void huphandler(int); |
|
|
129 |
static time_t getsendtime(char *); |
126 |
static void termhandler(int); |
130 |
static void termhandler(int); |
127 |
static void sendpacket(struct whod *); |
131 |
static void sendpacket(struct whod *); |
128 |
static void getboottime(struct whod *); |
132 |
static void getboottime(struct whod *); |
Lines 137-150
Link Here
|
137 |
char *user = NULL; |
141 |
char *user = NULL; |
138 |
int on = 1; |
142 |
int on = 1; |
139 |
int opt; |
143 |
int opt; |
|
|
144 |
size_t len; |
140 |
|
145 |
|
141 |
if (getuid()) { |
146 |
if (getuid()) { |
142 |
fprintf(stderr, "rwhod: not super user\n"); |
147 |
fprintf(stderr, "rwhod: not super user\n"); |
143 |
exit(1); |
148 |
exit(1); |
144 |
} |
149 |
} |
145 |
|
150 |
|
146 |
while ((opt = getopt(argc, argv, "bpau:")) != EOF) { |
151 |
while ((opt = getopt(argc, argv, "rbpau:")) != EOF) { |
147 |
switch (opt) { |
152 |
switch (opt) { |
|
|
153 |
case 'r': |
154 |
route = 1; |
155 |
break; |
148 |
case 'b': |
156 |
case 'b': |
149 |
use_broadcast = 1; |
157 |
use_broadcast = 1; |
150 |
break; |
158 |
break; |
Lines 201-206
Link Here
|
201 |
} |
209 |
} |
202 |
sine.sin_family = AF_INET; |
210 |
sine.sin_family = AF_INET; |
203 |
sine.sin_port = sp->s_port; |
211 |
sine.sin_port = sp->s_port; |
|
|
212 |
len = sizeof(sine); |
204 |
if (bind(sk, (struct sockaddr *)&sine, sizeof(sine)) < 0) { |
213 |
if (bind(sk, (struct sockaddr *)&sine, sizeof(sine)) < 0) { |
205 |
syslog(LOG_ERR, "bind: %m"); |
214 |
syslog(LOG_ERR, "bind: %m"); |
206 |
exit(1); |
215 |
exit(1); |
Lines 247-253
Link Here
|
247 |
for (;;) { |
256 |
for (;;) { |
248 |
struct whod wd; |
257 |
struct whod wd; |
249 |
int cc, whod; |
258 |
int cc, whod; |
250 |
size_t len = sizeof(from); |
259 |
len = sizeof(from); |
251 |
|
260 |
|
252 |
memset(&wd, 0, sizeof(wd)); |
261 |
memset(&wd, 0, sizeof(wd)); |
253 |
cc = recvfrom(sk, (char *)&wd, sizeof(struct whod), 0, |
262 |
cc = recvfrom(sk, (char *)&wd, sizeof(struct whod), 0, |
Lines 276-281
Link Here
|
276 |
from.sin_addr); |
285 |
from.sin_addr); |
277 |
continue; |
286 |
continue; |
278 |
} |
287 |
} |
|
|
288 |
if((time_t)ntohl(wd.wd_sendtime) == getsendtime(wd.wd_hostname)) |
289 |
continue; |
279 |
snprintf(path, sizeof(path), "whod.%s", wd.wd_hostname); |
290 |
snprintf(path, sizeof(path), "whod.%s", wd.wd_hostname); |
280 |
/* |
291 |
/* |
281 |
* Rather than truncating and growing the file each time, |
292 |
* Rather than truncating and growing the file each time, |
Lines 325-330
Link Here
|
325 |
exit(0); |
336 |
exit(0); |
326 |
} |
337 |
} |
327 |
|
338 |
|
|
|
339 |
static time_t getsendtime(char *hostname) |
340 |
{ |
341 |
int f, ret; |
342 |
struct whod wd; |
343 |
char path[64]; |
344 |
|
345 |
snprintf(path, sizeof(path), "whod.%s", hostname); |
346 |
if((f = open(path, O_RDONLY)) < 0) { |
347 |
if(errno != ENOENT) |
348 |
fprintf(stderr, "rwhod: %s: %s\n", path, strerror(errno)); |
349 |
return(0); |
350 |
} |
351 |
if((ret = read(f, &wd, sizeof(wd))) < 0) { |
352 |
fprintf(stderr, "rwhod: %s: %s\n", path, strerror(errno)); |
353 |
return(0); |
354 |
} |
355 |
close(f); |
356 |
if(ret < WHDRSIZE) |
357 |
return(0); |
358 |
return(wd.wd_sendtime); |
359 |
} |
360 |
|
328 |
/* |
361 |
/* |
329 |
* Obtain boot time again |
362 |
* Obtain boot time again |
330 |
*/ |
363 |
*/ |
Lines 366-371
Link Here
|
366 |
getboottime(&mywd); |
399 |
getboottime(&mywd); |
367 |
|
400 |
|
368 |
while (1) { |
401 |
while (1) { |
|
|
402 |
if(route) |
403 |
sendspool(mywd.wd_hostname); |
369 |
sendpacket(&mywd); |
404 |
sendpacket(&mywd); |
370 |
(void) sleep(AL_INTERVAL); |
405 |
(void) sleep(AL_INTERVAL); |
371 |
} |
406 |
} |
Lines 390-395
Link Here
|
390 |
return size > 0; |
425 |
return size > 0; |
391 |
} |
426 |
} |
392 |
|
427 |
|
|
|
428 |
static int down(time_t rcv, time_t now) { |
429 |
return (now - rcv > 11 * 60); |
430 |
} |
431 |
|
432 |
static void sendspool(char *myname) |
433 |
{ |
434 |
DIR *dirp; |
435 |
struct dirent *dp; |
436 |
int i, f, ret; |
437 |
struct whod wd; |
438 |
struct whoent *we; |
439 |
struct neighbor *np; |
440 |
|
441 |
if((dirp = opendir(".")) == NULL) { |
442 |
fprintf(stderr, "rwhod: opening spool dir: %s\n", strerror(errno)); |
443 |
exit(1); |
444 |
} |
445 |
while((dp = readdir(dirp)) != NULL) { |
446 |
if(strncmp(dp->d_name, "whod.", 5)) |
447 |
continue; |
448 |
if(!strcmp(dp->d_name + 5, myname)) |
449 |
continue; |
450 |
if((f = open(dp->d_name, O_RDONLY)) < 0) { |
451 |
fprintf(stderr, "rwhod: %s: %s\n", dp->d_name, strerror(errno)); |
452 |
continue; |
453 |
} |
454 |
if((ret = read(f, &wd, sizeof(wd))) < 0) { |
455 |
fprintf(stderr, "rwhod: %s: %s\n", dp->d_name, strerror(errno)); |
456 |
continue; |
457 |
} |
458 |
close(f); |
459 |
if(ret < WHDRSIZE) |
460 |
continue; |
461 |
if(down(wd.wd_recvtime, time(NULL))) |
462 |
continue; |
463 |
wd.wd_sendtime = htonl(wd.wd_sendtime); |
464 |
for(i = 0; i < 3; i++) |
465 |
wd.wd_loadav[i] = htonl(wd.wd_loadav[i]); |
466 |
wd.wd_boottime = htonl(wd.wd_boottime); |
467 |
for(we = wd.wd_we; (char *)we < ((char *)&wd) + ret; we++) { |
468 |
we->we_idle = htonl(we->we_idle); |
469 |
we->we_utmp.out_time = htonl(we->we_utmp.out_time); |
470 |
} |
471 |
for(np = neighbors; np != NULL; np = np->n_next) { |
472 |
if(sendto(sk, &wd, ret, 0, (struct sockaddr *) np->n_addr, np->n_addrlen) < 0) |
473 |
syslog(LOG_ERR, "sendto(%s): %m", inet_ntoa(((struct sockaddr_in *)np->n_addr)->sin_addr)); |
474 |
} |
475 |
} |
476 |
closedir(dirp); |
477 |
} |
393 |
|
478 |
|
394 |
static void |
479 |
static void |
395 |
sendpacket(struct whod *wd) |
480 |
sendpacket(struct whod *wd) |