d8a1285babaf72f612b672d2896d3fe81a161e36
[citadel.git] / citadel / modules / rwho / serv_rwho.c
1 /*
2  * $Id$
3  *
4  * This module implementsserver commands related to the display and
5  * manipulation of the "Who's online" list.
6  *
7  */
8
9 #include "sysdep.h"
10 #include <stdlib.h>
11 #include <unistd.h>
12 #include <stdio.h>
13 #include <fcntl.h>
14 #include <signal.h>
15 #include <pwd.h>
16 #include <errno.h>
17 #include <sys/types.h>
18
19 #if TIME_WITH_SYS_TIME
20 # include <sys/time.h>
21 # include <time.h>
22 #else
23 # if HAVE_SYS_TIME_H
24 #  include <sys/time.h>
25 # else
26 #  include <time.h>
27 # endif
28 #endif
29
30 #include <sys/wait.h>
31 #include <string.h>
32 #include <limits.h>
33 #include "citadel.h"
34 #include "server.h"
35 #include "citserver.h"
36 #include "support.h"
37 #include "config.h"
38 #include "control.h"
39 #include "room_ops.h"
40 #include "user_ops.h"
41 #include "policy.h"
42 #include "database.h"
43 #include "msgbase.h"
44 #include "tools.h"
45
46
47 #include "ctdl_module.h"
48
49
50 /*
51  * display who's online
52  */
53 void cmd_rwho(char *argbuf) {
54         struct CitContext *cptr;
55         int spoofed = 0;
56         int user_spoofed = 0;
57         int room_spoofed = 0;
58         int host_spoofed = 0;
59         int aide;
60         char un[40];
61         char real_room[ROOMNAMELEN], room[ROOMNAMELEN];
62         char host[64], flags[5];
63         
64         aide = CC->user.axlevel >= 6;
65         cprintf("%d%c \n", LISTING_FOLLOWS, CtdlCheckExpress() );
66         
67         for (cptr = ContextList; cptr != NULL; cptr = cptr->next) 
68         {
69                 flags[0] = '\0';
70                 spoofed = 0;
71                 user_spoofed = 0;
72                 room_spoofed = 0;
73                 host_spoofed = 0;
74                 
75                 if (cptr->cs_flags & CS_POSTING)
76                    strcat(flags, "*");
77                 else
78                    strcat(flags, ".");
79                    
80                 if (cptr->fake_username[0])
81                 {
82                    strcpy(un, cptr->fake_username);
83                    spoofed = 1;
84                    user_spoofed = 1;
85                 }
86                 else
87                    strcpy(un, cptr->curr_user);
88                    
89                 if (cptr->fake_hostname[0])
90                 {
91                    strcpy(host, cptr->fake_hostname);
92                    spoofed = 1;
93                    host_spoofed = 1;
94                 }
95                 else
96                    strcpy(host, cptr->cs_host);
97
98                 GenerateRoomDisplay(real_room, cptr, CC);
99
100                 if (cptr->fake_roomname[0]) {
101                         strcpy(room, cptr->fake_roomname);
102                         spoofed = 1;
103                         room_spoofed = 1;
104                 }
105                 else {
106                         strcpy(room, real_room);
107                 }
108                 
109                 if ((aide) && (spoofed)) {
110                         strcat(flags, "+");
111                 }
112                 
113                 if ((cptr->cs_flags & CS_STEALTH) && (aide)) {
114                         strcat(flags, "-");
115                 }
116                 
117                 if (((cptr->cs_flags&CS_STEALTH)==0) || (aide))
118                 {
119                         cprintf("%d|%s|%s|%s|%s|%ld|%s|%s|",
120                                 cptr->cs_pid, un, room,
121                                 host, cptr->cs_clientname,
122                                 (long)(cptr->lastidle),
123                                 cptr->lastcmdname, flags
124                         );
125
126                         if ((user_spoofed) && (aide)) {
127                                 cprintf("%s|", cptr->curr_user);
128                         }
129                         else {
130                                 cprintf("|");
131                         }
132         
133                         if ((room_spoofed) && (aide)) {
134                                 cprintf("%s|", real_room);
135                         }
136                         else {
137                                 cprintf("|");
138                         }
139         
140                         if ((host_spoofed) && (aide)) {
141                                 cprintf("%s|", cptr->cs_host);
142                         }
143                         else {
144                                 cprintf("|");
145                         }
146         
147                         cprintf("%d\n", cptr->logged_in);
148                 }
149         }
150
151         /* Now it's magic time.  Before we finish, call any EVT_RWHO hooks
152          * so that external paging modules such as serv_icq can add more
153          * content to the Wholist.
154          */
155         PerformSessionHooks(EVT_RWHO);
156         cprintf("000\n");
157         }
158
159
160 /*
161  * Masquerade roomname
162  */
163 void cmd_rchg(char *argbuf)
164 {
165         char newroomname[ROOMNAMELEN];
166
167         extract_token(newroomname, argbuf, 0, '|', sizeof newroomname);
168         newroomname[ROOMNAMELEN-1] = 0;
169         if (!IsEmptyStr(newroomname)) {
170                 safestrncpy(CC->fake_roomname, newroomname,
171                         sizeof(CC->fake_roomname) );
172         }
173         else {
174                 safestrncpy(CC->fake_roomname, "", sizeof CC->fake_roomname);
175         }
176         cprintf("%d OK\n", CIT_OK);
177 }
178
179 /*
180  * Masquerade hostname 
181  */
182 void cmd_hchg(char *argbuf)
183 {
184         char newhostname[64];
185
186         extract_token(newhostname, argbuf, 0, '|', sizeof newhostname);
187         if (!IsEmptyStr(newhostname)) {
188                 safestrncpy(CC->fake_hostname, newhostname,
189                         sizeof(CC->fake_hostname) );
190         }
191         else {
192                 safestrncpy(CC->fake_hostname, "", sizeof CC->fake_hostname);
193         }
194         cprintf("%d OK\n", CIT_OK);
195 }
196
197
198 /*
199  * Masquerade username (aides only)
200  */
201 void cmd_uchg(char *argbuf)
202 {
203
204         char newusername[USERNAME_SIZE];
205
206         extract_token(newusername, argbuf, 0, '|', sizeof newusername);
207
208         if (CtdlAccessCheck(ac_aide)) return;
209
210         if (!IsEmptyStr(newusername)) {
211                 CC->cs_flags &= ~CS_STEALTH;
212                 memset(CC->fake_username, 0, 32);
213                 if (strncasecmp(newusername, CC->curr_user,
214                                 strlen(CC->curr_user)))
215                         safestrncpy(CC->fake_username, newusername,
216                                 sizeof(CC->fake_username));
217         }
218         else {
219                 CC->fake_username[0] = '\0';
220                 CC->cs_flags |= CS_STEALTH;
221         }
222         cprintf("%d\n",CIT_OK);
223 }
224
225
226
227
228 /*
229  * enter or exit "stealth mode"
230  */
231 void cmd_stel(char *cmdbuf)
232 {
233         int requested_mode;
234
235         requested_mode = extract_int(cmdbuf,0);
236
237         if (CtdlAccessCheck(ac_logged_in)) return;
238
239         if (requested_mode == 1) {
240                 CC->cs_flags = CC->cs_flags | CS_STEALTH;
241         }
242         if (requested_mode == 0) {
243                 CC->cs_flags = CC->cs_flags & ~CS_STEALTH;
244         }
245
246         cprintf("%d %d\n", CIT_OK,
247                 ((CC->cs_flags & CS_STEALTH) ? 1 : 0) );
248 }
249
250
251
252
253
254
255
256 CTDL_MODULE_INIT(rwho)
257 {
258         CtdlRegisterProtoHook(cmd_rwho, "RWHO", "Display who is online");
259         CtdlRegisterProtoHook(cmd_hchg, "HCHG", "Masquerade hostname");
260         CtdlRegisterProtoHook(cmd_rchg, "RCHG", "Masquerade roomname");
261         CtdlRegisterProtoHook(cmd_uchg, "UCHG", "Masquerade username");
262         CtdlRegisterProtoHook(cmd_stel, "STEL", "Enter/exit stealth mode");
263
264         /* return our Subversion id for the Log */
265         return "$Id$";
266 }