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 */
} /* 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);
}
goto GSTA;
-} /* end main() */
+} /* end main() */
}
+/*
+ * 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.
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
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) {
}
+/*
+ * 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);
+}
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$";
a client program is prohibited from terminating the session it is currently
running on.
+ See also: REQT
+
NSET (Network SETup commands)
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).
+