e3523aae96d0aace9574da5ca3bd494abd754155
[citadel.git] / citadel / utils / whobbs.c
1 /*
2  * $Id$
3  * 
4  * Command-line "who is online?" utility
5  *
6  */
7
8 #include "sysdep.h"
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <errno.h>
14 #include <libcitadel.h>
15 #include "citadel.h"
16 #include "citadel_ipc.h"
17 #include "citadel_dirs.h"
18
19 void logoff(int code)
20 {
21         exit(code);
22         }
23
24 static void escapize(char *buf, size_t n) {
25         char hold[512];
26         int i, len;
27         size_t tmp;
28
29         strcpy(hold, buf);
30         strcpy(buf, "");
31         tmp = 0;
32         len = strlen(hold);
33         for (i=0; i<len; ++i) {
34                 if (hold[i]=='<') {
35                         snprintf(&buf[tmp], n - tmp, "&lt;");
36                         tmp += 4;
37                 }
38                 else if (hold[i]=='>'){
39                         snprintf(&buf[tmp], n - tmp, "&gt;");
40                         tmp += 4;
41                 }
42                 else if (hold[i]==34){
43                         snprintf(&buf[tmp], n - tmp, "&quot;");
44                         tmp += 6;
45                 }
46                 else{
47                         snprintf(&buf[tmp], n - tmp, "%c", hold[i]);
48                         tmp ++;
49                 }
50         }
51 }
52
53
54
55
56 int main(int argc, char **argv)
57 {
58         char buf[512];
59         char nodetitle[SIZ];
60         int www = 0;
61         int s_pid = 0;
62         int my_pid = 0;
63         char hostbuf[SIZ];
64         char portbuf[SIZ];
65         char s_user[SIZ];
66         char s_room[SIZ];
67         char s_host[SIZ];
68         char s_client[SIZ];
69         int r;                  /* IPC response code */
70         time_t timenow;
71         char *listing = NULL;
72         CtdlIPC *ipc = NULL;
73         int relh=0;
74         int home=0;
75         char relhome[PATH_MAX]="";
76         char ctdldir[PATH_MAX]=CTDLDIR;
77
78         calc_dirs_n_files(relh, home, relhome, ctdldir, 0);
79
80         /* If this environment variable is set, we assume that the program
81          * is being called as a cgi-bin from a webserver and will output
82          * everything as HTML.
83          */     
84         if (getenv("REQUEST_METHOD") != NULL) www = 1;
85
86         ipc = CtdlIPC_new(argc, argv, hostbuf, portbuf);
87         if (!ipc) {
88                 fprintf(stderr, "Server not available: %s\n", strerror(errno));
89                 logoff(errno);
90         }
91         CtdlIPC_chat_recv(ipc, buf);
92         if ((buf[0]!='2')&&(strncmp(buf,"551",3))) {
93                 fprintf(stderr,"%s: %s\n",argv[0],&buf[4]);
94                 logoff(atoi(buf));
95                 }
96         strcpy(nodetitle, "this Citadel site");
97         r = CtdlIPCServerInfo(ipc, buf);
98         if (r / 100 == 1) {
99                 my_pid = ipc->ServInfo.pid;
100                 strcpy(nodetitle, ipc->ServInfo.humannode);
101         }
102         
103         if (www) {
104                 printf( "Content-type: text/html\n"
105                         "\n"
106                         "<HTML><HEAD>"
107                         "<META HTTP-EQUIV=\"Refresh\" CONTENT=\"60\">\n"
108                         "<TITLE>");
109                 printf("%s: who is online", nodetitle);
110                 printf( "</TITLE></HEAD><BODY><H1>");
111         } else {
112                 printf("            ");
113         }
114
115         if (www) {
116                 printf("<CENTER><H1>");
117         }
118
119         printf("Users currently logged on to %s\n", nodetitle);
120
121         if (www) {
122                 printf("</H1>\n");
123         }
124
125         r = CtdlIPCOnlineUsers(ipc, &listing, &timenow, buf);
126         if (r / 100 != 1) {
127                 fprintf(stderr,"%s: %s\n",argv[0], buf);
128                 logoff(atoi(buf));
129         }
130
131         if (www) {
132                 printf( "<TABLE BORDER=1 WIDTH=100%%>"
133                         "<TR><TH>Session</TH><TH>User name</TH>"
134                         "<TH>Room</TH><TH>From host</TH>"
135                         "<TH>Client software</TH></TR>\n");
136         } else {
137
138                 printf( "Session         User name               "
139                         "Room                  From host\n");
140                 printf( "------- ------------------------- "
141                         "------------------- ------------------------\n");
142         }
143
144
145         while (!IsEmptyStr(listing)) {
146                 extract_token(buf, listing, 0, '\n', sizeof buf);
147                 remove_token(listing, 0, '\n');
148
149                 /* Escape some stuff if we're using www mode */
150                 if (www) escapize(buf, sizeof buf);
151
152                 s_pid = extract_int(buf,0);
153                 extract_token(s_user, buf, 1, '|', sizeof s_user);
154                 extract_token(s_room, buf, 2, '|', sizeof s_room);
155                 extract_token(s_host, buf, 3, '|', sizeof s_host);
156                 extract_token(s_client, buf, 4, '|', sizeof s_client);
157                 if (s_pid != my_pid) {
158
159                         if (www) printf("<TR><TD>");
160                         printf("%-7d", s_pid);
161                         printf("%c", 
162                                 ((s_pid == my_pid) ? '*' : ' '));
163                         if (www) printf("</TD><TD>");
164                         printf("%-26s", s_user);
165                         if (www) printf("</TD><TD>");
166                         printf("%-19s ", s_room);
167                         if (www) printf("</TD><TD>");
168                         printf("%-24s\n", s_host);
169                         if (www) printf("</TD><TD>%s</TD></TR>\n", s_client);
170                         }
171                 }
172         free(listing);
173
174         if (www) printf("</TABLE></CENTER>\n"
175                         "<FONT SIZE=-1>"
176                         "(This display will automatically refresh "
177                         "once per minute)</FONT>\n"
178                         "</BODY></HTML>\n");
179
180         r = CtdlIPCQuit(ipc);
181         return (r / 100 == 2) ? 0 : r;
182 }
183
184
185 /*
186  * Stub function
187  */
188 void stty_ctdl(int cmd) {
189 }
190
191
192 #ifndef HAVE_STRERROR
193 /*
194  * replacement strerror() for systems that don't have it
195  */
196 char *strerror(int e)
197 {
198         static char buf[32];
199
200         snprintf(buf, sizeof buf, "errno = %d",e);
201         return(buf);
202         }
203 #endif