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