]> mj.ucw.cz Git - nwho.git/commitdiff
Let nwho buffer all data in memory before printing it out
authorMartin Mares <mj@ucw.cz>
Fri, 31 Dec 2010 16:06:36 +0000 (17:06 +0100)
committerMartin Mares <mj@ucw.cz>
Fri, 31 Dec 2010 16:06:36 +0000 (17:06 +0100)
nwho.c

diff --git a/nwho.c b/nwho.c
index 6dfa7ab2c95d10306f53b59dfd7e0629caf7d10a..b7c932c3b3487c6d9f4684a4b3d7e206eb5652af 100644 (file)
--- a/nwho.c
+++ b/nwho.c
 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; i<num_hosts; i++)
     {
-      int l = ntohl(p->avl[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; u<m; u++)
+  for (int i=0; i<num_users; i++)
     {
-      i = &p->users[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; i<num_hosts; i++)
+    {
+      struct out_host *h = host_array[i];
+      if (ntohl(h->pkt->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;
 }