X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=nwhod.c;h=9407f6fa0334af796649741e361cc4b0e30969a8;hb=HEAD;hp=5d0cee02fae186192658bf61d73da082bef5f040;hpb=b62667ca593722d6a70fc8e107a2153501aff9a3;p=nwho.git diff --git a/nwhod.c b/nwhod.c index 5d0cee0..9407f6f 100644 --- a/nwhod.c +++ b/nwhod.c @@ -1,14 +1,14 @@ /* * The Remote User Information Daemon * - * (c) 1997--2010 Martin Mares + * (c) 1997--2017 Martin Mares */ #include #include #include -#include #include +#include #include #include #include @@ -22,7 +22,7 @@ #include #include -#include "net.h" +#include "nwho.h" struct hostrec { struct hostrec *next; @@ -31,23 +31,11 @@ struct hostrec { u32 addr; }; +static int do_not_daemonize; static int sock, port; static struct hostrec *first_host; static time_t now, last_local_scan; - -static void die(char *msg, ...) __attribute__((noreturn)); - -static void -die(char *msg, ...) -{ - va_list args; - - va_start(args, msg); - fprintf(stderr, "nwhod: "); - vfprintf(stderr, msg, args); - fputc('\n', stderr); - exit(1); -} +static char hostname[64]; static void net_init(char *name) @@ -79,6 +67,9 @@ net_init(char *name) if (connect(sock, (struct sockaddr *) &sa, sizeof(sa)) < 0) die("Cannot connect socket: %m"); } + + if (gethostname(hostname, sizeof(hostname)) < 0) + die("Unable to get my own host name: %m"); } static void @@ -101,8 +92,8 @@ scan_utmp(struct nwho_pkt *p, time_t now) name[9] = 0; strcpy(h->name, name); h->login_time = htonl(now - u->ut_time); - sprintf(h->con, "%.7s", u->ut_line); - sprintf(device, "/dev/%s", u->ut_line); + snprintf(h->con, sizeof(h->con), "%s", u->ut_line); + snprintf(device, sizeof(device), "/dev/%s", u->ut_line); if (stat(device, &st) < 0) continue; h->mesg_y = !!(S_IWGRP & st.st_mode); @@ -147,7 +138,7 @@ scan_load(struct nwho_pkt *p) static void make_pkt(struct nwho_pkt *pkt) { - bzero(pkt, sizeof(pkt)); + bzero(pkt, sizeof(*pkt)); pkt->magic = htonl(NWHO_MAGIC); pkt->local_time = htonl(now); scan_utmp(pkt, now); @@ -170,8 +161,9 @@ cleanup(void) } static void -save_pkt(char *name, struct nwho_pkt *pkt, int len) +save_pkt(char *name, struct nwho_pkt *pkt) { + int len = nwho_pkt_size(pkt); int fd = open(name, O_WRONLY | O_CREAT, 0666); if (fd < 0) { @@ -218,25 +210,23 @@ receive(void) if (!is_valid(sa.sin_addr.s_addr) || sa.sin_port != port) { - syslog(LOG_WARNING, "Received packet from invalid source %s.%d", inet_ntoa(sa.sin_addr), ntohs(sa.sin_port)); + syslog(LOG_WARNING, "Received packet from invalid source %s:%d", inet_ntoa(sa.sin_addr), ntohs(sa.sin_port)); return; } - if (r < n || r != n + ntohl(pkt.num_users)*sizeof(struct userinfo)) + if (r < n || + pkt.magic != htonl(NWHO_MAGIC) || + ntohl(pkt.num_users) > MAX_USERS || + r < nwho_pkt_size(&pkt)) { syslog(LOG_WARNING, "Malformed packet from %s", inet_ntoa(sa.sin_addr)); return; } - if (pkt.magic != htonl(NWHO_MAGIC)) - { - syslog(LOG_WARNING, "Received ancient nwho packet from %s", inet_ntoa(sa.sin_addr)); - return; - } - for(e=first_host; e; e=e->next) if (e->addr == sa.sin_addr.s_addr) break; + if (!e) { e = malloc(sizeof(struct hostrec)); @@ -250,8 +240,8 @@ receive(void) h = gethostbyaddr((char *) &sa.sin_addr, sizeof(sa.sin_addr), AF_INET); if (h) { - sprintf(e->name, "%.30s", h->h_name); - for(c=e->name; *c; c++) + snprintf(e->name, sizeof(e->name), "%s", h->h_name); + for (c=e->name; *c; c++) if (*c == '.') { *c = 0; @@ -269,19 +259,16 @@ receive(void) } e->last_rec = now; - save_pkt(e->name, &pkt, r); + save_pkt(e->name, &pkt); } static void local_scan(void) { struct nwho_pkt pkt; - static char hostname[64]; make_pkt(&pkt); - if (!hostname[0] && gethostname(hostname, sizeof(hostname)) < 0) - die("gethostname: %m"); - save_pkt(hostname, &pkt, sizeof(pkt) - (MAX_USERS - ntohl(pkt.num_users))*sizeof(struct userinfo)); + save_pkt(hostname, &pkt); } static void @@ -306,6 +293,9 @@ do_tick(void) static void daemonize(void) { + if (do_not_daemonize) + return; + pid_t pid = fork(); if (pid < 0) die("Fork failed: %m"); @@ -359,23 +349,49 @@ client(char *serv) { now = time(NULL); make_pkt(&pkt); - if (send(sock, &pkt, sizeof(pkt) - (MAX_USERS - ntohl(pkt.num_users))*sizeof(struct userinfo), 0) < 0) + if (send(sock, &pkt, nwho_pkt_size(&pkt), 0) < 0) syslog(LOG_ERR, "sendmsg: %m"); sleep(DEFAULT_SEND_TIME); } } +static void +usage(void) +{ + fprintf(stderr, "Usage: nwhod [-d] []\n"); + exit(1); +} + int main(int argc, char **argv) { - if (argc == 2) - client(argv[1]); - else if (argc == 1) - server(); - else + if (argc == 2 && !strcmp(argv[1], "--version")) { - fprintf(stderr, "Usage: nwhod []\n"); - return 1; + printf("nwho " STRINGIFY(VERSION) "\n"); + return 0; } + + int opt; + while ((opt = getopt(argc, argv, "d")) >= 0) + switch (opt) + { + case 'd': + do_not_daemonize = 1; + break; + default: + usage(); + } + + if (optind == argc-1) + { + if (argv[optind][0]) + client(argv[optind]); + else + server(); + } + else if (optind == argc) + server(); + else + usage(); return 0; }