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