4 * This module implements server commands related to the display and
5 * manipulation of the "Who's online" list.
7 * Copyright (c) 1987-2009 by the citadel.org team
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 #include <sys/types.h>
34 #if TIME_WITH_SYS_TIME
35 # include <sys/time.h>
39 # include <sys/time.h>
48 #include <libcitadel.h>
51 #include "citserver.h"
60 #include "ctdl_module.h"
64 * display who's online
66 void cmd_rwho(char *argbuf) {
67 struct CitContext *nptr;
75 char real_room[ROOMNAMELEN], room[ROOMNAMELEN];
76 char host[64], flags[5];
78 /* So that we don't keep the context list locked for a long time
79 * we create a copy of it first
83 nptr = CtdlGetContextArray(&nContexts) ;
86 /* Couldn't malloc so we have to bail but stick to the protocol */
87 cprintf("%d%c \n", LISTING_FOLLOWS, CtdlCheckExpress() );
92 aide = CC->user.axlevel >= AxAideU;
93 cprintf("%d%c \n", LISTING_FOLLOWS, CtdlCheckExpress() );
95 for (i=0; i<nContexts; i++)
103 if (nptr[i].cs_flags & CS_POSTING)
108 if (nptr[i].fake_username[0])
110 strcpy(un, nptr[i].fake_username);
115 strcpy(un, nptr[i].curr_user);
117 if (nptr[i].fake_hostname[0])
119 strcpy(host, nptr[i].fake_hostname);
124 strcpy(host, nptr[i].cs_host);
126 GenerateRoomDisplay(real_room, &nptr[i], CC);
128 if (nptr[i].fake_roomname[0]) {
129 strcpy(room, nptr[i].fake_roomname);
134 strcpy(room, real_room);
137 if ((aide) && (spoofed)) {
141 if ((nptr[i].cs_flags & CS_STEALTH) && (aide)) {
145 if (((nptr[i].cs_flags&CS_STEALTH)==0) || (aide))
147 cprintf("%d|%s|%s|%s|%s|%ld|%s|%s|",
148 nptr[i].cs_pid, un, room,
149 host, nptr[i].cs_clientname,
150 (long)(nptr[i].lastidle),
151 nptr[i].lastcmdname, flags
154 if ((user_spoofed) && (aide)) {
155 cprintf("%s|", nptr[i].curr_user);
161 if ((room_spoofed) && (aide)) {
162 cprintf("%s|", real_room);
168 if ((host_spoofed) && (aide)) {
169 cprintf("%s|", nptr[i].cs_host);
175 cprintf("%d\n", nptr[i].logged_in);
179 /* release out copy of the context list */
182 /* Now it's magic time. Before we finish, call any EVT_RWHO hooks
183 * so that external paging modules such as serv_icq can add more
184 * content to the Wholist.
186 PerformSessionHooks(EVT_RWHO);
192 * Masquerade roomname
194 void cmd_rchg(char *argbuf)
196 char newroomname[ROOMNAMELEN];
198 extract_token(newroomname, argbuf, 0, '|', sizeof newroomname);
199 newroomname[ROOMNAMELEN-1] = 0;
200 if (!IsEmptyStr(newroomname)) {
201 safestrncpy(CC->fake_roomname, newroomname,
202 sizeof(CC->fake_roomname) );
205 safestrncpy(CC->fake_roomname, "", sizeof CC->fake_roomname);
207 cprintf("%d OK\n", CIT_OK);
211 * Masquerade hostname
213 void cmd_hchg(char *argbuf)
215 char newhostname[64];
217 extract_token(newhostname, argbuf, 0, '|', sizeof newhostname);
218 if (!IsEmptyStr(newhostname)) {
219 safestrncpy(CC->fake_hostname, newhostname,
220 sizeof(CC->fake_hostname) );
223 safestrncpy(CC->fake_hostname, "", sizeof CC->fake_hostname);
225 cprintf("%d OK\n", CIT_OK);
230 * Masquerade username (aides only)
232 void cmd_uchg(char *argbuf)
235 char newusername[USERNAME_SIZE];
237 extract_token(newusername, argbuf, 0, '|', sizeof newusername);
239 if (CtdlAccessCheck(ac_aide)) return;
241 if (!IsEmptyStr(newusername)) {
242 CC->cs_flags &= ~CS_STEALTH;
243 memset(CC->fake_username, 0, 32);
244 if (strncasecmp(newusername, CC->curr_user,
245 strlen(CC->curr_user)))
246 safestrncpy(CC->fake_username, newusername,
247 sizeof(CC->fake_username));
250 CC->fake_username[0] = '\0';
251 CC->cs_flags |= CS_STEALTH;
253 cprintf("%d\n",CIT_OK);
260 * enter or exit "stealth mode"
262 void cmd_stel(char *cmdbuf)
266 requested_mode = extract_int(cmdbuf,0);
268 if (CtdlAccessCheck(ac_logged_in)) return;
270 if (requested_mode == 1) {
271 CC->cs_flags = CC->cs_flags | CS_STEALTH;
272 PerformSessionHooks(EVT_STEALTH);
274 if (requested_mode == 0) {
275 CC->cs_flags = CC->cs_flags & ~CS_STEALTH;
276 PerformSessionHooks(EVT_UNSTEALTH);
279 cprintf("%d %d\n", CIT_OK,
280 ((CC->cs_flags & CS_STEALTH) ? 1 : 0) );
284 CTDL_MODULE_INIT(rwho)
288 CtdlRegisterProtoHook(cmd_rwho, "RWHO", "Display who is online");
289 CtdlRegisterProtoHook(cmd_hchg, "HCHG", "Masquerade hostname");
290 CtdlRegisterProtoHook(cmd_rchg, "RCHG", "Masquerade roomname");
291 CtdlRegisterProtoHook(cmd_uchg, "UCHG", "Masquerade username");
292 CtdlRegisterProtoHook(cmd_stel, "STEL", "Enter/exit stealth mode");
295 /* return our Subversion id for the Log */