]> code.citadel.org Git - citadel.git/commitdiff
* Added server-side REQT command to issue client termination requests
authorArt Cancro <ajc@citadel.org>
Mon, 11 Dec 2000 03:22:13 +0000 (03:22 +0000)
committerArt Cancro <ajc@citadel.org>
Mon, 11 Dec 2000 03:22:13 +0000 (03:22 +0000)
citadel/ChangeLog
citadel/citadel.c
citadel/commands.c
citadel/serv_chat.c
citadel/techdoc/session.txt

index faa70901333bdf5efe3fc12bc2b9cd1efe2ee851..f8b1d9121bf26d4e7b126b9499db0a0202c03701 100644 (file)
@@ -1,4 +1,7 @@
  $Log$
+ Revision 573.46  2000/12/11 03:22:11  ajc
+ * Added server-side REQT command to issue client termination requests
+
  Revision 573.45  2000/12/11 02:19:26  ajc
  * Client now honors EM_GO_AWAY flag, used by the server to request that a
    client log off.  (The server doesn't support sending that flag yet, though)
@@ -2204,4 +2207,3 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant <bryant@cs.usm.maine.edu>
 
 Fri Jul 10 1998 Art Cancro <ajc@uncensored.citadel.org>
        * Initial CVS import 
-
index d838321d2124c4486c9ea598dade03771ac23a5a..0a152672dc9dec427b7a30558d068fe53bcfd641 100644 (file)
@@ -93,7 +93,7 @@ char floor_mode;
 char curr_floor = 0;           /* number of current floor */
 char floorlist[128][256];      /* names of floors */
 char express_msgs = 0;         /* express messages waiting! */
-volatile int termn8 = 0;       /* Set to nonzero to cause a logoff */
+int termn8 = 0;                        /* Set to nonzero to cause a logoff */
 
 extern int rc_ansi_color;      /* ansi color value from citadel.rc */
 
@@ -1503,11 +1503,13 @@ PWOK:
                        }       /* end switch */
        } while (termn8 == 0);
 
-      TERMN8:printf("%s logged out.\n", fullname);
-       while (march != NULL)
+TERMN8:        printf("%s logged out.\n", fullname);
+       while (march != NULL) {
                remove_march(march->march_name, 0);
-       if (mcmd == 30)
+       }
+       if (mcmd == 30) {
                printf("\n\nType 'off' to hang up, or next user...\n");
+       }
        snprintf(aaa, sizeof aaa, "LOUT");
        serv_puts(aaa);
        serv_gets(aaa);
@@ -1517,4 +1519,4 @@ PWOK:
        }
        goto GSTA;
 
-}                              /* end main() */
+}      /* end main() */
index e83696d021e870fbb3a859b7bcabfd82717198d5..8a2cf2d28e6aaf077519c17e2187b553f448bfac 100644 (file)
@@ -215,6 +215,12 @@ void print_express(void)
                extract(node, &buf[4], 4);
        
                stamp = localtime(&timestamp);
+
+               /* If the page is a Logoff Request, honor it. */
+               if (flags & 2) {
+                       termn8 = 1;
+                       return;
+               }
        
                if (strlen(rc_exp_cmd) > 0) {
                        outpipe = popen(rc_exp_cmd, "w");
@@ -293,10 +299,6 @@ void print_express(void)
        printf("\n---\n");
        color(BRIGHT_WHITE);
 
-       /* If the page is a Logoff Request, honor it. */
-       if (flags & 2) {
-               termn8 = 1;
-       }
 
 }
 
index 20ba220ac1fca53f2552e63bc119fbfb0fb8f2be..09a47d3b8f841530fd2f3070d4ce2211141d7267 100644 (file)
@@ -444,6 +444,28 @@ void cmd_gexp(char *argbuf) {
 }
 
 
+/*
+ * Back end support function for send_express_message() and company
+ */
+void add_xmsg_to_context(struct CitContext *ccptr, 
+                       struct ExpressMessage *newmsg) 
+{
+       struct ExpressMessage *findend;
+
+       if (ccptr->FirstExpressMessage == NULL) {
+               ccptr->FirstExpressMessage = newmsg;
+       }
+       else {
+               findend = ccptr->FirstExpressMessage;
+               while (findend->next != NULL) {
+                       findend = findend->next;
+               }
+               findend->next = newmsg;
+       }
+}
+
+
+
 
 /* 
  * This is the back end to the express message sending function.  
@@ -455,7 +477,7 @@ int send_express_message(char *lun, char *x_user, char *x_msg)
        int message_sent = 0;           /* number of successful sends */
 
        struct CitContext *ccptr;
-       struct ExpressMessage *newmsg, *findend;
+       struct ExpressMessage *newmsg;
        char *un;
        size_t msglen = 0;
        int do_send = 0;                /* set to 1 to actually page, not
@@ -495,17 +517,9 @@ int send_express_message(char *lun, char *x_user, char *x_msg)
                                            sizeof newmsg->sender);
                                if (!strcasecmp(x_user, "broadcast"))
                                        newmsg->flags |= EM_BROADCAST;
-                               newmsg->text = mallok(msglen);
-                               safestrncpy(newmsg->text, x_msg, msglen);
-
-                               if (ccptr->FirstExpressMessage == NULL)
-                                       ccptr->FirstExpressMessage = newmsg;
-                               else {
-                                       findend = ccptr->FirstExpressMessage;
-                                       while (findend->next != NULL)
-                                               findend = findend->next;
-                                       findend->next = newmsg;
-                               }
+                               newmsg->text = strdoop(x_msg);
+
+                               add_xmsg_to_context(ccptr, newmsg);
 
                                /* and log it ... */
                                if (ccptr != CC) {
@@ -658,6 +672,40 @@ void cmd_dexp(char *argbuf)
        }
 
 
+/*
+ * Request client termination
+ */
+void cmd_reqt(char *argbuf) {
+       struct CitContext *ccptr;
+       int sessions = 0;
+       int which_session;
+       struct ExpressMessage *newmsg;
+
+       if (CtdlAccessCheck(ac_aide)) return;
+       which_session = extract_int(argbuf, 0);
+
+       begin_critical_section(S_SESSION_TABLE);
+       for (ccptr = ContextList; ccptr != NULL; ccptr = ccptr->next) {
+               if ((ccptr->cs_pid == which_session) || (which_session == 0)) {
+
+                       newmsg = (struct ExpressMessage *)
+                               mallok(sizeof (struct ExpressMessage));
+                       memset(newmsg, 0,
+                               sizeof (struct ExpressMessage));
+                       time(&(newmsg->timestamp));
+                       safestrncpy(newmsg->sender, CC->usersupp.fullname,
+                                   sizeof newmsg->sender);
+                       newmsg->flags |= EM_GO_AWAY;
+                       newmsg->text = strdoop("Automatic logoff requested.");
+
+                       add_xmsg_to_context(ccptr, newmsg);
+                       ++sessions;
+
+               }
+       }
+       end_critical_section(S_SESSION_TABLE);
+       cprintf("%d Sent termination request to %d sessions.\n", OK, sessions);
+}
 
 
 
@@ -668,6 +716,7 @@ char *Dynamic_Module_Init(void)
        CtdlRegisterProtoHook(cmd_gexp, "GEXP", "Get express messages");
        CtdlRegisterProtoHook(cmd_sexp, "SEXP", "Send an express message");
        CtdlRegisterProtoHook(cmd_dexp, "DEXP", "Disable express messages");
+       CtdlRegisterProtoHook(cmd_reqt, "REQT", "Request client termination");
        CtdlRegisterSessionHook(delete_express_messages, EVT_STOP);
        CtdlRegisterXmsgHook(send_express_message, XMSG_PRI_LOCAL);
        return "$Id$";
index ec288e94c7f86c26dd20cb27b2914d523ea14e4e..65405f416bc854b05938641f88469228b7312bfb 100644 (file)
@@ -1483,6 +1483,8 @@ of the session to be terminated.
 a client program is prohibited from terminating the session it is currently
 running on.
  
+ See also: REQT
  
  NSET   (Network SETup commands)
  
@@ -1788,3 +1790,25 @@ exist in the current room, or if the specified moderation level is not within
 acceptable limits, ERROR+ILLEGAL_VALUE is returned.  This command requires at
 least Room Aide access; if the calling user is not an Aide, or a Room Aide for
 the current room, ERROR+HIGHER_ACCESS_REQUIRED is returned.
+ REQT   (REQuest client Termination)
+ Request that the specified client (or all clients) log off.  Aide level
+access is required to run this command, otherwise ERROR+HIGHER_ACCESS_REQUIRED
+is returned.
+ The REQT command accepts one parameter: the session ID of the client which
+should be terminated, or 0 for all clients.  When successful, the REQT command
+returns OK.
+ It should be noted that REQT simply transmits an express message to the
+specified client(s) with the EM_GO_AWAY flag set.  Older clients do not honor
+this flag, and it is certainly possible for users to re-program their client
+software to ignore it.  Therefore the effects of the REQT command should be
+considered advisory only.  The recommended implementation practice is to first
+issue a REQT command, then wait a little while (from 30 seconds up to a few
+minutes) for well-behaved clients to voluntarily terminate, and then issue a
+TERM command to forcibly disconnect the client (or perhaps a DOWN command, if
+you are logging off users for the purpose of shutting down the server).
+