Back to index

citadel  8.12
serv_rwho.c
Go to the documentation of this file.
00001 /*
00002  * This module implements server commands related to the display and
00003  * manipulation of the "Who's online" list.
00004  *
00005  * Copyright (c) 1987-2012 by the citadel.org team
00006  *
00007  * This program is open source software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License version 3.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  */
00016 
00017 #include "sysdep.h"
00018 #include <stdlib.h>
00019 #include <unistd.h>
00020 #include <stdio.h>
00021 #include <fcntl.h>
00022 #include <signal.h>
00023 #include <pwd.h>
00024 #include <errno.h>
00025 #include <sys/types.h>
00026 
00027 #if TIME_WITH_SYS_TIME
00028 # include <sys/time.h>
00029 # include <time.h>
00030 #else
00031 # if HAVE_SYS_TIME_H
00032 #  include <sys/time.h>
00033 # else
00034 #  include <time.h>
00035 # endif
00036 #endif
00037 
00038 #include <sys/wait.h>
00039 #include <string.h>
00040 #include <limits.h>
00041 #include <libcitadel.h>
00042 #include "citadel.h"
00043 #include "server.h"
00044 #include "citserver.h"
00045 #include "support.h"
00046 #include "config.h"
00047 #include "control.h"
00048 #include "user_ops.h"
00049 #include "database.h"
00050 #include "msgbase.h"
00051 
00052 
00053 #include "ctdl_module.h"
00054 
00055 
00056 /*
00057  * display who's online
00058  */
00059 void cmd_rwho(char *argbuf) {
00060        struct CitContext *nptr;
00061        int nContexts, i;
00062        int spoofed = 0;
00063        int user_spoofed = 0;
00064        int room_spoofed = 0;
00065        int host_spoofed = 0;
00066        int aide;
00067        char un[40];
00068        char real_room[ROOMNAMELEN], room[ROOMNAMELEN];
00069        char host[64], flags[5];
00070        
00071        /* So that we don't keep the context list locked for a long time
00072         * we create a copy of it first
00073         */
00074        nptr = CtdlGetContextArray(&nContexts) ;
00075        if (!nptr)
00076        {
00077               /* Couldn't malloc so we have to bail but stick to the protocol */
00078               cprintf("%d%c \n", LISTING_FOLLOWS, CtdlCheckExpress() );
00079               cprintf("000\n");
00080               return;
00081        }
00082        
00083        aide = ( (CC->user.axlevel >= AxAideU) || (CC->internal_pgm) ) ;
00084        cprintf("%d%c \n", LISTING_FOLLOWS, CtdlCheckExpress() );
00085        
00086        for (i=0; i<nContexts; i++) 
00087        {
00088               flags[0] = '\0';
00089               spoofed = 0;
00090               user_spoofed = 0;
00091               room_spoofed = 0;
00092               host_spoofed = 0;
00093               
00094               if (!aide && nptr[i].state == CON_SYS)
00095                      continue;
00096 
00097               if (!aide && nptr[i].kill_me != 0)
00098                      continue;
00099 
00100               if (nptr[i].cs_flags & CS_POSTING)
00101                  strcat(flags, "*");
00102               else
00103                  strcat(flags, ".");
00104                  
00105               if (nptr[i].fake_username[0])
00106               {
00107                  strcpy(un, nptr[i].fake_username);
00108                  spoofed = 1;
00109                  user_spoofed = 1;
00110               }
00111               else
00112                  strcpy(un, nptr[i].curr_user);
00113                  
00114               if (nptr[i].fake_hostname[0])
00115               {
00116                  strcpy(host, nptr[i].fake_hostname);
00117                  spoofed = 1;
00118                  host_spoofed = 1;
00119               }
00120               else
00121                  strcpy(host, nptr[i].cs_host);
00122 
00123               GenerateRoomDisplay(real_room, &nptr[i], CC);
00124 
00125               if (nptr[i].fake_roomname[0]) {
00126                      strcpy(room, nptr[i].fake_roomname);
00127                      spoofed = 1;
00128                      room_spoofed = 1;
00129               }
00130               else {
00131                      strcpy(room, real_room);
00132               }
00133               
00134                 if ((aide) && (spoofed)) {
00135                      strcat(flags, "+");
00136               }
00137               
00138               if ((nptr[i].cs_flags & CS_STEALTH) && (aide)) {
00139                      strcat(flags, "-");
00140               }
00141               
00142               if (((nptr[i].cs_flags&CS_STEALTH)==0) || (aide))
00143               {
00144                      cprintf("%d|%s|%s|%s|%s|%ld|%s|%s|",
00145                             nptr[i].cs_pid, un, room,
00146                             host, nptr[i].cs_clientname,
00147                             (long)(nptr[i].lastidle),
00148                             nptr[i].lastcmdname, flags
00149                      );
00150 
00151                      if ((user_spoofed) && (aide)) {
00152                             cprintf("%s|", nptr[i].curr_user);
00153                      }
00154                      else {
00155                             cprintf("|");
00156                      }
00157        
00158                      if ((room_spoofed) && (aide)) {
00159                             cprintf("%s|", real_room);
00160                      }
00161                      else {
00162                             cprintf("|");
00163                      }
00164        
00165                      if ((host_spoofed) && (aide)) {
00166                             cprintf("%s|", nptr[i].cs_host);
00167                      }
00168                      else {
00169                             cprintf("|");
00170                      }
00171        
00172                      cprintf("%d\n", nptr[i].logged_in);
00173               }
00174        }
00175        
00176        /* release out copy of the context list */
00177        free(nptr);
00178 
00179        /* Now it's magic time.  Before we finish, call any EVT_RWHO hooks
00180         * so that external paging modules such as serv_icq can add more
00181         * content to the Wholist.
00182         */
00183        PerformSessionHooks(EVT_RWHO);
00184        cprintf("000\n");
00185 }
00186 
00187 
00188 /*
00189  * Masquerade roomname
00190  */
00191 void cmd_rchg(char *argbuf)
00192 {
00193        char newroomname[ROOMNAMELEN];
00194 
00195        extract_token(newroomname, argbuf, 0, '|', sizeof newroomname);
00196        newroomname[ROOMNAMELEN-1] = 0;
00197        if (!IsEmptyStr(newroomname)) {
00198               safestrncpy(CC->fake_roomname, newroomname,
00199                      sizeof(CC->fake_roomname) );
00200        }
00201        else {
00202               safestrncpy(CC->fake_roomname, "", sizeof CC->fake_roomname);
00203        }
00204        cprintf("%d OK\n", CIT_OK);
00205 }
00206 
00207 /*
00208  * Masquerade hostname 
00209  */
00210 void cmd_hchg(char *argbuf)
00211 {
00212        char newhostname[64];
00213 
00214        extract_token(newhostname, argbuf, 0, '|', sizeof newhostname);
00215        if (!IsEmptyStr(newhostname)) {
00216               safestrncpy(CC->fake_hostname, newhostname,
00217                      sizeof(CC->fake_hostname) );
00218        }
00219        else {
00220               safestrncpy(CC->fake_hostname, "", sizeof CC->fake_hostname);
00221        }
00222        cprintf("%d OK\n", CIT_OK);
00223 }
00224 
00225 
00226 /*
00227  * Masquerade username (aides only)
00228  */
00229 void cmd_uchg(char *argbuf)
00230 {
00231 
00232        char newusername[USERNAME_SIZE];
00233 
00234        extract_token(newusername, argbuf, 0, '|', sizeof newusername);
00235 
00236        if (CtdlAccessCheck(ac_aide)) return;
00237 
00238        if (!IsEmptyStr(newusername)) {
00239               CC->cs_flags &= ~CS_STEALTH;
00240               memset(CC->fake_username, 0, 32);
00241               if (strncasecmp(newusername, CC->curr_user,
00242                             strlen(CC->curr_user)))
00243                      safestrncpy(CC->fake_username, newusername,
00244                             sizeof(CC->fake_username));
00245        }
00246        else {
00247               CC->fake_username[0] = '\0';
00248               CC->cs_flags |= CS_STEALTH;
00249        }
00250        cprintf("%d\n",CIT_OK);
00251 }
00252 
00253 
00254 
00255 
00256 /*
00257  * enter or exit "stealth mode"
00258  */
00259 void cmd_stel(char *cmdbuf)
00260 {
00261        int requested_mode;
00262 
00263        requested_mode = extract_int(cmdbuf,0);
00264 
00265        if (CtdlAccessCheck(ac_logged_in)) return;
00266 
00267        if (requested_mode == 1) {
00268               CC->cs_flags = CC->cs_flags | CS_STEALTH;
00269               PerformSessionHooks(EVT_STEALTH);
00270        }
00271        if (requested_mode == 0) {
00272               CC->cs_flags = CC->cs_flags & ~CS_STEALTH;
00273               PerformSessionHooks(EVT_UNSTEALTH);
00274        }
00275 
00276        cprintf("%d %d\n", CIT_OK,
00277               ((CC->cs_flags & CS_STEALTH) ? 1 : 0) );
00278 }
00279 
00280 
00281 CTDL_MODULE_INIT(rwho)
00282 {
00283        if(!threading)
00284        {
00285                CtdlRegisterProtoHook(cmd_rwho, "RWHO", "Display who is online");
00286               CtdlRegisterProtoHook(cmd_hchg, "HCHG", "Masquerade hostname");
00287                CtdlRegisterProtoHook(cmd_rchg, "RCHG", "Masquerade roomname");
00288               CtdlRegisterProtoHook(cmd_uchg, "UCHG", "Masquerade username");
00289                CtdlRegisterProtoHook(cmd_stel, "STEL", "Enter/exit stealth mode");
00290        }
00291        
00292        /* return our module name for the log */
00293         return "rwho";
00294 }