From ec34304fa15a8fb1d75e68cbb28dafffad06487e Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Fri, 31 Dec 2010 17:06:36 +0100 Subject: [PATCH] Let nwho buffer all data in memory before printing it out --- nwho.c | 148 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 113 insertions(+), 35 deletions(-) diff --git a/nwho.c b/nwho.c index 6dfa7ab..b7c932c 100644 --- a/nwho.c +++ b/nwho.c @@ -18,6 +18,68 @@ static int is_uptime; static time_t now; +struct out_host { + char name[32]; + struct nwho_pkt *pkt; +}; + +struct out_user { + struct userinfo *user; + struct out_host *host; +}; + +static struct out_host **host_array; +static int num_hosts; +static int max_hosts = 16; + +static struct out_user *user_array; +static int num_users; +static int max_users = 16; + +static void * +xmalloc(size_t size) +{ + void *p = malloc(size); + if (!p) + die("Out of memory"); + return p; +} + +static struct out_host * +new_host(struct nwho_pkt *orig_pkt, char *name) +{ + int len = nwho_pkt_size(orig_pkt); + struct nwho_pkt *pkt = xmalloc(len); + memcpy(pkt, orig_pkt, len); + + struct out_host *host = xmalloc(sizeof(*host)); + snprintf(host->name, sizeof(host->name), "%s", name); + host->pkt = pkt; + + if (!host_array || num_hosts >= max_hosts) + { + max_hosts *= 2; + host_array = realloc(host_array, max_hosts * sizeof(struct out_host)); + } + host_array[num_hosts++] = host; + + return host; +} + +static void +new_user(struct out_host *host, struct userinfo *ui) +{ + if (!user_array || num_users >= max_users) + { + max_users *= 2; + user_array = realloc(user_array, max_users * sizeof(struct out_user)); + } + user_array[num_users++] = (struct out_user) { + .user = ui, + .host = host + }; +} + static void puttime(int s) { @@ -45,46 +107,55 @@ puttime(int s) } static void -show_uptime(char *name, struct nwho_pkt *p) +show_uptime(void) { - int i; - - if (now - ntohl(p->server_time) >= DEFAULT_DOWN_TIME) - { - printf("%-16s down\n", name); - return; - } - printf("%-16s up ", name); - puttime(ntohl(p->uptime)); - printf(" load"); - for(i=0; i<3; i++) + for (int i=0; iavl[i]); - printf(" %2d.%02d", l/100, l%100); + struct out_host *h = host_array[i]; + struct nwho_pkt *p = h->pkt; + + if (now - ntohl(p->server_time) >= DEFAULT_DOWN_TIME) + { + printf("%-16s down\n", h->name); + continue; + } + printf("%-16s up ", h->name); + puttime(ntohl(p->uptime)); + printf(" load"); + for(int j=0; j<3; j++) + { + int l = ntohl(p->avl[j]); + printf(" %2d.%02d", l/100, l%100); + } + printf(" %3d users\n", (int) ntohl(p->num_users)); } - printf(" %3d users\n", (int) ntohl(p->num_users)); } static void -show_users(char *name, struct nwho_pkt *p) +show_users(void) { - int u; - int m = ntohl(p->num_users); - struct userinfo *i; + puts("Name Li M Where LogT IdleT"); - if (now - ntohl(p->server_time) >= DEFAULT_DOWN_TIME) - return; - for(u=0; uusers[u]; - printf("%-8.8s %-7s %c %-16s ", i->name, i->con, (i->mesg_y ? ' ' : '-'), name); - puttime(ntohl(i->login_time)); + struct out_host *h = user_array[i].host; + struct userinfo *u = user_array[i].user; + + if (now - ntohl(h->pkt->server_time) >= DEFAULT_DOWN_TIME) + continue; + printf("%-8.8s %-7s %c %-16s ", u->name, u->con, (u->mesg_y ? ' ' : '-'), h->name); + puttime(ntohl(u->login_time)); putchar(' '); - puttime(ntohl(i->idle_time)); + puttime(ntohl(u->idle_time)); putchar('\n'); } - if (m == MAX_USERS) - printf("%s: MAX_USERS reached!\n", name); + + for (int i=0; ipkt->num_users) >= MAX_USERS) + printf("%s: MAX_USERS reached!\n", h->name); + } } static void @@ -94,7 +165,6 @@ scan(void) struct dirent *e; struct nwho_pkt pkt; int fd, r; - int is = 0; if (chdir(NWHO_SPOOL_DIR) < 0) { @@ -125,12 +195,11 @@ scan(void) fprintf(stderr, "%s: Malformed record\n", e->d_name); continue; } - (is_uptime ? show_uptime : show_users)(e->d_name, &pkt); - is = 1; + struct out_host *host = new_host(&pkt, e->d_name); + for (int i=0; i < ntohl(pkt.num_users); i++) + new_user(host, &host->pkt->users[i]); } closedir(d); - if (!is) - puts("No data available."); } int @@ -149,9 +218,18 @@ main(int argc, char **argv) fprintf(stderr, "Usage: %s\n", argv[0]); return 1; } - if (!is_uptime) - puts("Name Li M Where LogT IdleT"); + now = time(NULL); scan(); + if (!num_hosts) + { + puts("No data available."); + return 0; + } + + if (!is_uptime) + show_users(); + else + show_uptime(); return 0; } -- 2.39.2