]> mj.ucw.cz Git - nwho.git/blob - nwho.c
Remember down servers for some time.
[nwho.git] / nwho.c
1 /*
2  *      The Remote User Information Lister
3  *
4  *      (c) 1997--2002 Martin Mares <mj@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU General Public License. See file COPYING in any of the GNU packages.
8  */
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <fcntl.h>
14 #include <unistd.h>
15 #include <dirent.h>
16 #include <time.h>
17 #include <netinet/in.h>
18 #include <asm/types.h>
19
20 #include "net.h"
21
22 static int is_uptime;
23 static time_t now;
24
25 static void
26 puttime(int s)
27 {
28   int d, h, m;
29   if (s < 100)
30     printf("%4ds", s);
31   else
32     {
33       m = s/60;
34       s %= 60;
35       h = m/60;
36       m %= 60;
37       if (h < 100)
38         printf("%02d.%02d", h, m);
39       else
40         {
41           d = h/24;
42           h %= 24;
43           if (d < 100)
44             printf("%2dd%02d", d, h);
45           else
46             printf("%4dd", d);
47         }
48     }
49 }
50
51 static void
52 show_uptime(char *name, struct rywho_pkt *p)
53 {
54   int i;
55
56   if (p->server_time - now >= DEFAULT_DOWN_TIME)
57     {
58       printf("%-16s down\n", name);
59       return;
60     }
61   printf("%-16s up ", name);
62   puttime(ntohl(p->uptime));
63   printf("  load");
64   for(i=0; i<3; i++)
65     {
66       int l = ntohl(p->avl[i]);
67       printf(" %2d.%02d", l/100, l%100);
68     }
69   printf(" %3d users\n", (int) ntohl(p->num_users));
70 }
71
72 static void
73 show_users(char *name, struct rywho_pkt *p)
74 {
75   int u;
76   int m = ntohl(p->num_users);
77   struct userinfo *i;
78
79   if (p->server_time - now >= DEFAULT_DOWN_TIME)
80     return;
81   for(u=0; u<m; u++)
82     {
83       i = &p->users[u];
84       printf("%-8.8s %-7s %c %-16s ", i->name, i->con, (i->mesg_y ? ' ' : '-'), name);
85       puttime(ntohl(i->login_time));
86       putchar(' ');
87       puttime(ntohl(i->idle_time));
88       putchar('\n');
89     }
90   if (m == MAX_USERS)
91     printf("%s: MAX_USERS reached!\n", name);
92 }
93
94 static void
95 scan(void)
96 {
97   DIR *d;
98   struct dirent *e;
99   struct rywho_pkt pkt;
100   int fd, r;
101   int is = 0;
102
103   if (chdir(NWHO_SPOOL_DIR) < 0)
104     {
105       fprintf(stderr, "chdir(" NWHO_SPOOL_DIR "): %m\n");
106       exit(1);
107     }
108   d = opendir(".");
109   if (!d)
110     {
111       perror("opendir");
112       exit(1);
113     }
114   while (e = readdir(d))
115     if (e->d_name[0] != '.')
116       {
117         fd = open(e->d_name, O_RDONLY);
118         if (fd < 0)
119           {
120             fprintf(stderr, "%s: %m\n", e->d_name);
121             continue;
122           }
123         r = read(fd, &pkt, sizeof(pkt));
124         close(fd);
125         if (r < sizeof(struct rywho_pkt) - MAX_USERS*sizeof(struct userinfo)
126             || pkt.magic != htonl(NWHO_MAGIC)
127             || r != sizeof(struct rywho_pkt) - (MAX_USERS - ntohl(pkt.num_users))*sizeof(struct userinfo))
128           {
129             fprintf(stderr, "%s: Malformed record\n", e->d_name);
130             continue;
131           }
132         (is_uptime ? show_uptime : show_users)(e->d_name, &pkt);
133         is = 1;
134       }
135   closedir(d);
136   if (!is)
137     puts("No data available.");
138 }
139
140 int
141 main(int argc, char **argv)
142 {
143   if (strstr(argv[0], "uptime"))
144     is_uptime = 1;
145   if (argc != 1)
146     {
147       fprintf(stderr, "Usage: %s\n", argv[0]);
148       return 1;
149     }
150   if (!is_uptime)
151     puts("Name     Li      M Where            LogT  IdleT");
152   now = time(NULL);
153   scan();
154   return 0;
155 }