/*
- * $Id$
- *
* This module implements server commands related to the display and
* manipulation of the "Who's online" list.
*
+ * Copyright (c) 1987-2012 by the citadel.org team
+ *
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
*/
#include "sysdep.h"
#include "support.h"
#include "config.h"
#include "control.h"
-#include "room_ops.h"
#include "user_ops.h"
-#include "policy.h"
#include "database.h"
#include "msgbase.h"
#include "ctdl_module.h"
+/* Don't show the names of private rooms unless the viewing
+ * user also knows the rooms.
+ */
+void GenerateRoomDisplay(char *real_room,
+ CitContext *viewed,
+ CitContext *viewer) {
+
+ int ra;
+
+ strcpy(real_room, viewed->room.QRname);
+ if (viewed->room.QRflags & QR_MAILBOX) {
+ strcpy(real_room, &real_room[11]);
+ }
+ if (viewed->room.QRflags & QR_PRIVATE) {
+ CtdlRoomAccess(&viewed->room, &viewer->user, &ra, NULL);
+ if ( (ra & UA_KNOWN) == 0) {
+ strcpy(real_room, " ");
+ }
+ }
+
+ if (viewed->cs_flags & CS_CHAT) {
+ while (strlen(real_room) < 14) {
+ strcat(real_room, " ");
+ }
+ strcpy(&real_room[14], "<chat>");
+ }
+
+}
+
+
/*
* display who's online
*/
void cmd_rwho(char *argbuf) {
- struct CitContext *cptr;
struct CitContext *nptr;
int nContexts, i;
int spoofed = 0;
/* So that we don't keep the context list locked for a long time
* we create a copy of it first
*/
-
-
nptr = CtdlGetContextArray(&nContexts) ;
if (!nptr)
{
return;
}
- aide = CC->user.axlevel >= 6;
+ aide = ( (CC->user.axlevel >= AxAideU) || (CC->internal_pgm) ) ;
cprintf("%d%c \n", LISTING_FOLLOWS, CtdlCheckExpress() );
for (i=0; i<nContexts; i++)
room_spoofed = 0;
host_spoofed = 0;
+ if (!aide && nptr[i].state == CON_SYS)
+ continue;
+
+ if (!aide && nptr[i].kill_me != 0)
+ continue;
+
if (nptr[i].cs_flags & CS_POSTING)
strcat(flags, "*");
else
cprintf("000\n");
}
+/*
+ * check for async io jobs that are stuck (didn't ping back for 10 mins)
+ */
+void dead_io_check(void) {
+ struct CitContext *nptr;
+ int nContexts, i;
+ char real_room[ROOMNAMELEN];
+
+ /* So that we don't keep the context list locked for a long time
+ * we create a copy of it first
+ */
+ nptr = CtdlGetContextArray(&nContexts) ;
+ if (!nptr)
+ {
+ /* Couldn't malloc so we have to bail but stick to the protocol */
+ return;
+ }
+
+ time_t now = time(NULL);
+ time_t idle;
+
+ for (i=0; i<nContexts; i++)
+ {
+ if ((nptr[i].state != CON_SYS) || (nptr[i].IO == NULL) || (nptr[i].lastcmd == 0))
+ continue;
+
+ if (nptr[i].kill_me != 0)
+ continue;
+ idle = now - nptr[i].lastcmd;
+ if (idle < 600)
+ continue;
+
+ GenerateRoomDisplay(real_room, &nptr[i], CC);
+
+ syslog(LOG_WARNING,
+ "Found stuck event context: CC[%d] "
+
+ "Username: '%s' "
+ "Room: '%s' "
+ "while talking to host: '%s' "
+ "Status: '%s' "
+ "stuck in IO State: '%s' "
+
+ "idle since: %d:%d "
+ "Triggering context termination now!",
+
+ nptr[i].cs_pid,
+
+ nptr[i].curr_user,
+ real_room,
+ nptr[i].cs_host,
+ nptr[i].cs_clientname,
+ nptr[i].lastcmdname,
+
+ (int) idle / 60,
+ (int) idle % 60);
+
+ CtdlTerminateOtherSession(nptr[i].cs_pid);
+ }
+
+ /* release out copy of the context list */
+ free(nptr);
+
+}
/*
* Masquerade roomname
CtdlRegisterProtoHook(cmd_rchg, "RCHG", "Masquerade roomname");
CtdlRegisterProtoHook(cmd_uchg, "UCHG", "Masquerade username");
CtdlRegisterProtoHook(cmd_stel, "STEL", "Enter/exit stealth mode");
+ CtdlRegisterSessionHook(dead_io_check, EVT_TIMER, PRIO_QUEUE + 50);
+
}
- /* return our Subversion id for the Log */
- return "$Id$";
+ /* return our module name for the log */
+ return "rwho";
}