fix to previous commit
[citadel.git] / citadel / modules / rwho / serv_rwho.c
1 /*
2  * This module implements server commands related to the display and
3  * manipulation of the "Who's online" list.
4  *
5  * Copyright (c) 1987-2019 by the citadel.org team
6  *
7  * This program is open source software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 3.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  */
16
17 #include "sysdep.h"
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <stdio.h>
21 #include <fcntl.h>
22 #include <signal.h>
23 #include <pwd.h>
24 #include <errno.h>
25 #include <sys/types.h>
26
27 #if TIME_WITH_SYS_TIME
28 # include <sys/time.h>
29 # include <time.h>
30 #else
31 # if HAVE_SYS_TIME_H
32 #  include <sys/time.h>
33 # else
34 #  include <time.h>
35 # endif
36 #endif
37
38 #include <sys/wait.h>
39 #include <string.h>
40 #include <limits.h>
41 #include <libcitadel.h>
42 #include "citadel.h"
43 #include "server.h"
44 #include "citserver.h"
45 #include "support.h"
46 #include "config.h"
47 #include "control.h"
48 #include "user_ops.h"
49 #include "database.h"
50 #include "msgbase.h"
51
52
53 #include "ctdl_module.h"
54
55 /* Don't show the names of private rooms unless the viewing
56  * user also knows the rooms.
57  */
58 void GenerateRoomDisplay(char *real_room,
59                         CitContext *viewed,
60                         CitContext *viewer) {
61
62         int ra;
63
64         strcpy(real_room, viewed->room.QRname);
65         if (viewed->room.QRflags & QR_MAILBOX) {
66                 strcpy(real_room, &real_room[11]);
67         }
68         if (viewed->room.QRflags & QR_PRIVATE) {
69                 CtdlRoomAccess(&viewed->room, &viewer->user, &ra, NULL);
70                 if ( (ra & UA_KNOWN) == 0) {
71                         strcpy(real_room, " ");
72                 }
73         }
74
75         if (viewed->cs_flags & CS_CHAT) {
76                 while (strlen(real_room) < 14) {
77                         strcat(real_room, " ");
78                 }
79                 strcpy(&real_room[14], "<chat>");
80         }
81
82 }
83
84
85
86 /*
87  * display who's online
88  */
89 void cmd_rwho(char *argbuf) {
90         struct CitContext *nptr;
91         int nContexts, i;
92         int spoofed = 0;
93         int aide;
94         char room[ROOMNAMELEN];
95         char flags[5];
96         
97         /* So that we don't keep the context list locked for a long time
98          * we create a copy of it first
99          */
100         nptr = CtdlGetContextArray(&nContexts) ;
101         if (!nptr)
102         {
103                 /* Couldn't malloc so we have to bail but stick to the protocol */
104                 cprintf("%d%c \n", LISTING_FOLLOWS, CtdlCheckExpress() );
105                 cprintf("000\n");
106                 return;
107         }
108         
109         aide = ( (CC->user.axlevel >= AxAideU) || (CC->internal_pgm) ) ;
110         cprintf("%d%c \n", LISTING_FOLLOWS, CtdlCheckExpress() );
111         
112         for (i=0; i<nContexts; i++)  {
113                 flags[0] = '\0';
114                 spoofed = 0;
115                 
116                 if (!aide && nptr[i].state == CON_SYS)
117                         continue;
118
119                 if (!aide && nptr[i].kill_me != 0)
120                         continue;
121
122                 if (nptr[i].cs_flags & CS_POSTING) {
123                         strcat(flags, "*");
124                 }
125                 else {
126                         strcat(flags, ".");
127                 }
128                    
129                 GenerateRoomDisplay(room, &nptr[i], CC);
130
131                 if ((aide) && (spoofed)) {
132                         strcat(flags, "+");
133                 }
134                 
135                 if ((nptr[i].cs_flags & CS_STEALTH) && (aide)) {
136                         strcat(flags, "-");
137                 }
138                 
139                 if (((nptr[i].cs_flags&CS_STEALTH)==0) || (aide)) {
140
141                         cprintf("%d|%s|%s|%s|%s|%ld|%s|%s|",
142                                 nptr[i].cs_pid, nptr[i].curr_user, room,
143                                 nptr[i].cs_host, nptr[i].cs_clientname,
144                                 (long)(nptr[i].lastidle),
145                                 nptr[i].lastcmdname, flags
146                         );
147
148                         cprintf("|");   // no spoofed user names anymore
149                         cprintf("|");   // no spoofed room names anymore
150                         cprintf("|");   // no spoofed host names anymore
151         
152                         cprintf("%d\n", nptr[i].logged_in);
153                 }
154         }
155         
156         /* release our copy of the context list */
157         free(nptr);
158
159         /* Now it's magic time.  Before we finish, call any EVT_RWHO hooks
160          * so that external paging modules such as serv_icq can add more
161          * content to the Wholist.
162          */
163         PerformSessionHooks(EVT_RWHO);
164         cprintf("000\n");
165 }
166
167
168 /*
169  * enter or exit "stealth mode"
170  */
171 void cmd_stel(char *cmdbuf)
172 {
173         int requested_mode;
174
175         requested_mode = extract_int(cmdbuf,0);
176
177         if (CtdlAccessCheck(ac_logged_in)) return;
178
179         if (requested_mode == 1) {
180                 CC->cs_flags = CC->cs_flags | CS_STEALTH;
181                 PerformSessionHooks(EVT_STEALTH);
182         }
183         if (requested_mode == 0) {
184                 CC->cs_flags = CC->cs_flags & ~CS_STEALTH;
185                 PerformSessionHooks(EVT_UNSTEALTH);
186         }
187
188         cprintf("%d %d\n", CIT_OK,
189                 ((CC->cs_flags & CS_STEALTH) ? 1 : 0) );
190 }
191
192
193 CTDL_MODULE_INIT(rwho)
194 {
195         if(!threading)
196         {
197                 CtdlRegisterProtoHook(cmd_rwho, "RWHO", "Display who is online");
198                 CtdlRegisterProtoHook(cmd_stel, "STEL", "Enter/exit stealth mode");
199                 //CtdlRegisterSessionHook(dead_io_check, EVT_TIMER, PRIO_QUEUE + 50);
200
201         }
202         
203         /* return our module name for the log */
204         return "rwho";
205 }