Commit ccde2b85 authored by Andrew Price's avatar Andrew Price
Browse files

Add mw_logon, mw_logoff, talker_join and talker_leave mwjs events

Required a lot of IPC_CHECKONOFF-related changes and tidy-ups.
New js events handled like so:

    function handler(ev)
    {
            switch(ev.type) {
            case "mw_logon":
                    d = ev.data;
                    mw.print("d.user: " + d.user);
                    mw.print("d.quiet: " + d.quiet);

                    mw.print("d.autochat: " + d.autochat);
                    break;
            case "mw_logoff":
                    d = ev.data;
                    mw.print("d.user: " + d.user);
                    mw.print("d.method: " + d.method);
                    mw.print("d.quiet: " + d.quiet);

                    mw.print("d.reason: " + d.reason);
                    mw.print("d.agent: " + d.agent);
                    break;
            case "talker_join":
                    d = ev.data;
                    mw.print("d.user: " + d.user);
                    mw.print("d.method: " + d.method);
                    mw.print("d.quiet: " + d.quiet);

                    mw.print("d.channel: " + d.channel);
                    mw.print("d.agent: " + d.agent);
                    break;
            case "talker_leave":
                    d = ev.data;
                    mw.print("d.user: " + d.user);
                    mw.print("d.method: " + d.method);
                    mw.print("d.quiet: " + d.quiet);

                    mw.print("d.channel: " + d.channel);
                    mw.print("d.agent: " + d.agent);
                    mw.print("d.message: " + d.message);
                    break;
            }
    }
    mw.onevent.push(handler);

See src/server/PROTOCOL and src/onoff.h for hints on what those fields
are.
parent c4b787b5
Loading
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -6,12 +6,14 @@
typedef enum {
	MWEV_TYPE_NONE = 0,
	MWEV_TYPE_MSG,
	MWEV_TYPE_ONOFF,
} mwev_type_t;

struct mwevent {
	mwev_type_t ev_type;
	union {
		ipc_message_t *msg;   /* MWEV_TYPE_MSG */
		ipc_message_t *onoff; /* MWEV_TYPE_ONOFF */
	} ev_data;
};

+103 −221
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include "gaglist.h"
#include "js.h"
#include "event.h"
#include "onoff.h"
#include <jansson.h>
#include <str_util.h>

@@ -50,14 +51,13 @@ static void force_text(ipc_message_t *msg, const char *text, const char *from);
static void force_vtext(ipc_message_t *msg, const char *from, const char *format, ...) __attribute__((format (printf, 3, 4)));
static void force_ipc(char *text, char *from);
static void force_rpc(char *text, char *from);
static void force_checkonoff(char *text, char *from);
static void force_wiz(ipc_message_t *msg, char *text, char *from);
static void force_chatmode(char *text, unsigned long theirprivs, const char *from);
static void force_chatmode(char *text, struct user *usr);
static void force_status(char *text, char *from);
static void force_channel(char *text, char *from, unsigned long theirprivs);
static void force_kick(char *text, char *from, unsigned long theirprivs);
static void force_gag(char *text, unsigned long theirprivs, const char *from);
static void zod(char *from, char *msg);
static void zod(const char *from, const char *msg);
static void mrod(char *from, char *msg);
static void force_newmail(void);
static void force_protlevel(char *text, unsigned long theirprivs, const char *from);
@@ -176,11 +176,37 @@ void DisplayStack(void)
			}
			case EST_CHECKONOFF:
			{
				char	*aargs[6];
				char	*backup;
				char	*onoff_name, *sep, *head, *head2;
				char	*uname, *reason = NULL;
				int	ccode, method, isquiet;
				struct {
					char ccode[13];
					char type[13];
					char quiet[3];
					char name[NAMESIZE + 1];
					char version[3];
					char reason[MAXTEXTLENGTH];
				} a;
				char *aargs[6] = {
					a.ccode,
					a.type,
					a.quiet,
					a.name,
					a.version,
					a.reason
				};
				int action_to_ccode[] = {
					[ONOFF_LOGON] = 3,
					[ONOFF_LOGOFF] = 2,
					[ONOFF_JOIN] = 1,
					[ONOFF_LEAVE] = 0,
				};
				char *onoff_name;
				const char *uname, *reason;
				int ccode, isquiet, action, type;
				struct mwevent ev = {
						.ev_type = MWEV_TYPE_ONOFF,
						.ev_data.onoff = new->msg,
				};
				script_output = 1;
				js_handle_event(&ev);

				/* go through list and find checkonoff function */
				onoff_name = NULL;
@@ -189,209 +215,75 @@ void DisplayStack(void)
				/* if no function found, skip everything else */
				if (onoff_name == NULL) break;

				/* backup the input text */
				backup = strdup(new->text);

				/* get the first comma in the checkonoff code */
				sep = strchr(new->text, ',');

				/* if this comma does not exist, use the original version of checkonoff */
				if (sep == NULL)
				{
					/* simply convert to a number */
					ccode = atoi(new->text);

					/* due to backwards compatibility issues, we can only use 0 or 1 */
					if (ccode < 0) { free(backup); break; }
					if (ccode > 1) { free(backup); break; }

					/* create memory for argument strings */
					aargs[0] = malloc(sizeof(char) * 13);
					aargs[1] = malloc(sizeof(char) * 13);
					aargs[2] = malloc(sizeof(char) * 3);
					aargs[3] = malloc(sizeof(char) * NAMESIZE + 1);
					aargs[4] = malloc(sizeof(char) * 3);
					aargs[5] = malloc(sizeof(char) * MAXTEXTLENGTH);

					/* set up the argument strings */
					snprintf(aargs[0], 12, "%d", ccode);
					aargs[1][0] = 0;
					aargs[2][0] = 0;
					aargs[3][0] = 0;
					snprintf(aargs[4], 2, "1");
					aargs[5][0] = 0;

					/* run the event */
					ExecEvent2(onoff_name, "CheckOnOff", new->from, 0, 6, aargs);

					/* free memory and break out */
					free(backup);
					free(aargs[0]);
					free(aargs[1]);
					free(aargs[2]);
					free(aargs[3]);
					free(aargs[4]);
					free(aargs[5]);
					break;
				}

				/* set head to the character after the comma, and terminate the code before the comma */
				head = sep + 1;
				*sep = 0;

				/* get the checkonoff code number */
				ccode = atoi(new->text);

				/* get the next comma in the checkonoff code */
				sep = strchr(head, ',');
				/* if no comma found, then this must be an interim checkonoff */
				if (sep == NULL)
				{
					/* due to backwards compatibility issues, we can only use 0 or 1 */
					if (ccode < 0) { free(backup); break; }
					if (ccode > 1) { free(backup); break; }

					/* simply convert the next argument to a number */
					isquiet = atoi(head);

					/* create memory for argument strings */
					aargs[0] = malloc(sizeof(char) * 13);
					aargs[1] = malloc(sizeof(char) * 13);
					aargs[2] = malloc(sizeof(char) * 3);
					aargs[3] = malloc(sizeof(char) * NAMESIZE + 1);
					aargs[4] = malloc(sizeof(char) * 3);
					aargs[5] = malloc(sizeof(char) * MAXTEXTLENGTH);

					/* set up the argument strings */
					snprintf(aargs[0], 12, "%d", ccode);
					aargs[1][0] = 0;
					snprintf(aargs[2], 2, "%d", isquiet);
					aargs[3][0] = 0;
					snprintf(aargs[4], 2, "2");
					aargs[5][0] = 0;

					/* run the event */
					ExecEvent2(onoff_name, "CheckOnOff", new->from, 0, 6, aargs);

					/* free memory and break out */
					free(backup);
					free(aargs[0]);
					free(aargs[1]);
					free(aargs[2]);
					free(aargs[3]);
					free(aargs[4]);
					free(aargs[5]);
					break;
				}

				/* set second text head to the character after the comma, and terminate the method before the comma */
				head2 = sep + 1;
				*sep = 0;

				/* get the checkonoff method number */
				method = atoi(head);
				json_t *j = ipcmsg_json_decode(new->msg);
				uname = json_getstring(j, "user");
				action = json_getint(j, "action");
				type = json_getint(j, "type");
				isquiet = json_is_true(json_object_get(j, "quiet"));
				if (action == ONOFF_LOGOFF)
					reason = json_getstring(j, "reason");
				else
					reason = json_getstring(j, "message");

				/* get the next comma in the checkonoff code */
				sep = strchr(head2, ',');
				/* if no comma found, then this must be broken! */
				if (sep == NULL)
				{
					printf("Invalid checkonoff broadcast received! (%s)\n", backup);
					free(backup);
				if (action >= ONOFF_SIZE)
					break;
				}

				/* set uname to the character after the comma, and terminate the method before the comma */
				uname = sep + 1;
				*sep = 0;

				/* get the checkonoff quiet flagr */
				isquiet = atoi(head2);

				/* get the optional next comma in the checkonoff code */
				sep = strchr(uname, ',');
				/* if comma is found, then the reason is there */
				if (sep != NULL)
				{
					reason = sep + 1;
					*sep = 0;
				}
				ccode = action_to_ccode[action];

				/* limit the method information */
				switch (ccode)
				switch (action) {
				case ONOFF_LEAVE:
					if (!cp_test(user, CP_CANZOD) && (type == LEAVE_ZOD))
					{
				/* leave the talker */
				case 0:
					if (!cp_test(user, CP_CANZOD) && (method == 1))
					{
						method = 0;
						type = 0;
						uname = new->from;
					}
					if (!u_god(user) && (method == 2))
					if (!u_god(user) && (type == LEAVE_FORCED))
					{
						method = 0;
						type = 0;
						uname = new->from;
					}
					break;
				/* enter the talker */
				case 1:
					if (!cp_test(user, CP_SUMMON) && (method == 1))
				case ONOFF_JOIN:
					if (!cp_test(user, CP_SUMMON) && (type == JOIN_SUMMONED))
					{
						method = 0;
						type = 0;
						uname = new->from;
					}
					if (!u_god(user) && (method == 2))
					if (!u_god(user) && (type == JOIN_FORCED))
					{
						method = 0;
						type = 0;
						uname = new->from;
					}
					break;
				/* leave the board */
				case 2:
					if (!cp_test(user, CP_CANMROD) && (method == 3))
				case ONOFF_LOGOFF:
					if (!cp_test(user, CP_CANMROD) && (type == LOGOFF_MROD))
					{
						method = 0;
						type = 0;
						uname = new->from;
					}
					if (!u_god(user) && ((method == 4) || (method == 5) || (method == 6)))
					if (!u_god(user) && (
					    (type == LOGOFF_BANNED) ||
					    (type == LOGOFF_ERROR) ||
					    (type == LOGOFF_DELETED)))
					{
						method = 0;
						type = 0;
						uname = new->from;
					}
					break;
				/* enter the board */
				case 3:
				case ONOFF_LOGON:
					break;
				}

				/* create memory for argument strings */
				aargs[0] = malloc(sizeof(char) * 13);
				aargs[1] = malloc(sizeof(char) * 13);
				aargs[2] = malloc(sizeof(char) * 3);
				aargs[3] = malloc(sizeof(char) * NAMESIZE + 1);
				aargs[4] = malloc(sizeof(char) * 3);
				aargs[5] = malloc(sizeof(char) * MAXTEXTLENGTH);

				/* set up the argument strings */
				snprintf(aargs[0], 12, "%d", ccode);
				snprintf(aargs[1], 12, "%d", method);
				snprintf(aargs[2], 2, "%d", isquiet);
				snprintf(aargs[3], NAMESIZE, "%s", uname);
				snprintf(aargs[4], 2, "3");
				if (reason) snprintf(aargs[5], MAXTEXTLENGTH - 1, "%s", reason);
				else aargs[5][0] = 0;

				/* display the broadcast message */
				memset(&a, 0, sizeof(a));
				snprintf(a.ccode, 12, "%d", ccode);
				snprintf(a.type, 12, "%d", type);
				snprintf(a.quiet, 2, "%d", isquiet ? 1 : 0);
				snprintf(a.name, NAMESIZE, "%s", uname);
				a.version[0] = '3';
				if (reason != NULL)
					snprintf(a.reason, MAXTEXTLENGTH - 1, "%s", reason);
				ExecEvent2(onoff_name, "CheckOnOff", new->from, 0, 6, aargs);

				/* free up the memory used */
				free(aargs[0]);
				free(aargs[1]);
				free(aargs[2]);
				free(aargs[3]);
				free(aargs[4]);
				free(aargs[5]);
				free(backup);
				break;
			}
			default:
@@ -477,7 +369,7 @@ static void handle_ipc_error(ipc_message_t *msg)
		printf("Undefined server error '%s'\n", type);
	}
	json_decref(j);
	close_down(0, NULL, NULL);
	close_down(LOGOFF_NORMAL, NULL, NULL);
}

static void display_error(ipc_message_t *msg)
@@ -659,12 +551,20 @@ static void display_content(ipc_message_t *msg)
		json_array_foreach(j, i, jgag) {
			gaglist_append(json_string_value(jgag));
		}
	} else
	if (msg->head.type == IPC_CHECKONOFF && cp_test(user, CP_SCRIPT)) {
		struct mstack *ms;

		ms = calloc(1, sizeof(*ms));
		ms->flags = MST_SCREV;
		ms->preamble = EST_CHECKONOFF;
		ms->from = strdup(whom);
		InsertMesg(ms, msg);
	} else {
		printf("Unknown message type %4.4s", (char *)&msg->head.type);
	}

	json_decref(j);

}

static void accept_pipe_cmd(ipc_message_t *msg, struct user *mesg_user)
@@ -703,7 +603,7 @@ static void accept_pipe_cmd(ipc_message_t *msg, struct user *mesg_user)
			user->record.chatprivs = cp_setbycode(user->record.chatprivs, newbuff);
			break;
		case IPC_CHATMODE:
			force_chatmode(newbuff, mesg_user->record.chatprivs, mesg_user->record.name);
			force_chatmode(newbuff, mesg_user);
			break;
		case IPC_GAG:
			force_gag(newbuff, mesg_user->record.chatprivs, mesg_user->record.name);
@@ -738,7 +638,7 @@ static void accept_pipe_cmd(ipc_message_t *msg, struct user *mesg_user)
			force_rpc(newbuff, mesg_user->record.name);
			break;
		case IPC_CHECKONOFF:
			force_checkonoff(newbuff, mesg_user->record.name);
			display_content(msg);
			break;
		case IPC_WIZ:
			force_wiz(msg, newbuff, mesg_user->record.name);
@@ -862,14 +762,6 @@ static void force_wiz(ipc_message_t *msg, char *newbuff, char *from)
	InsertMesg(mesg, msg);
}

static void force_checkonoff(char *text, char *from)
{
	if (cp_test(user, CP_SCRIPT))
	{
		StackEvent(text, from, EST_CHECKONOFF);
	}
}

static void force_ipc(char *text, char *from)
{
	if (cp_test(user, CP_SCRIPT))
@@ -893,39 +785,35 @@ static void force_status(char *newbuff, char *from)
	if (u_ban(user))
	{
		printf(_("\n\n--> You appear to have been banned. Goodbye... <--\r\n"));
		close_down(4, from, NULL);
		close_down(LOGOFF_BANNED, from, NULL);
	}
	/* we have received a +D status change */
	if (u_del(user))
	{
		printf(_("\n\n--> You appear to have been DELETED. Goodbye... <--\r\n"));
		close_down(6, from, NULL);
		close_down(LOGOFF_DELETED, from, NULL);
	}
}

static void force_chatmode(char *newbuff, unsigned long theirprivs, const char *from)
static void force_chatmode(char *newbuff, struct user *usr)
{
	unsigned long mm;
	int ourapl = (user->record.chatprivs & CP_PROTMASK) >> CP_PROTSHIFT;
	int		theirapl = (theirprivs & CP_PROTMASK) >> CP_PROTSHIFT;
	int theirapl = (usr->record.chatprivs & CP_PROTMASK) >> CP_PROTSHIFT;
	int oldchat;

	if (!(theirprivs & CP_PROTECT)) theirapl = 0;
	if (!(usr->record.chatprivs & CP_PROTECT)) theirapl = 0;
	oldchat = cm_test(user, CM_ONCHAT);

	mm=cm_setbycode(user->record.chatmode, newbuff);
	user->record.chatmode=chatmode_describe(user->record.chatmode, mm, ourapl, theirapl, from);
	user->record.chatmode = chatmode_describe(user->record.chatmode, mm, ourapl, theirapl, NULL);

	if (!cm_test(user, CM_ONCHAT) && oldchat)
	{
		/* announce leaving talker */
		broadcast_onoffcode(0, 2, from, NULL);
	}
		announce_leave(user->record.name, user->record.room, LEAVE_FORCED,
		               usr->record.name, NULL, quietmode);
	else if (cm_test(user, CM_ONCHAT) && !oldchat)
	{
		/* announce joining the talker */
		broadcast_onoffcode(1, 2, from, NULL);
	}
		announce_join(user->record.name, user->record.room, JOIN_FORCED,
		              usr->record.name, quietmode);

	disable_rl(1);
}
@@ -1014,10 +902,7 @@ static void force_channel(char *newbuff, char *from, unsigned long theirprivs)

			/* run common talker entrance code with logon type set to 'summon' */
			enter_talker(2);

			/* give an entrance broadcast */
			broadcast_onoffcode(1, 1, from, NULL);

			announce_join(user->record.name, user->record.room, JOIN_SUMMONED, from, quietmode);
			enter_room(newroom);
		}
	}else
@@ -1076,18 +961,15 @@ static void force_kick(char *newbuff, char *from, unsigned long theirprivs)
	}
}

static void zod(char *from, char *msg)
static void zod(const char *from, const char *msg)
{
	char text[MAXTEXTLENGTH];

	/* remove from talker */
	user->record.chatmode = cm_clear(user, CM_ONCHAT);

	/* force update of user */
	update_user(user);

	/* announce leaving talker via zod */
	broadcast_onoffcode(0, 1, from, msg);
	announce_leave(user->record.name, user->record.room, LEAVE_ZOD, from, msg, quietmode);

	/* put standard message to screen */
	snprintf(text, MAXTEXTLENGTH-1, _("\nBoing, Zebedee arrived.  \"%s\033--\", said Zebedee\n"), (msg!=NULL)?msg:_("Time for bed"));
@@ -1129,5 +1011,5 @@ static void mrod(char *from, char *msg)

	mrod_user = malloc(sizeof(char) * (strlen(from) + 1));
	strcpy(mrod_user, from);
	close_down(3, from, msg);
	close_down(LOGOFF_MROD, from, msg);
}
+138 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include "iconv.h"
#include "sqlite.h"
#include "init.h"
#include "onoff.h"

extern struct user * const user;
struct alarm *timeout_event = NULL;
@@ -204,6 +205,125 @@ static int js_push_ipcmsg_event(ipc_message_t *msg)
	return 0;
}

static int js_push_logon_event(json_t *j, duk_idx_t i, int type)
{
	duk_push_boolean(ctx, type == LOGON_AUTOCHAT);
	duk_put_prop_string(ctx, i, "autochat");
	return 0;
}

static int js_push_logoff_event(json_t *j, duk_idx_t i, int type)
{
	const char *reason;
	const char *agent;
	const char *subtypes[] = {
		[LOGOFF_NORMAL] = "normal",
		[LOGOFF_TIMEOUT] = "timeout",
		[LOGOFF_EOFS] = "eof",
		[LOGOFF_MROD] = "mrod",
		[LOGOFF_BANNED] = "banned",
		[LOGOFF_ERROR] = "error",
		[LOGOFF_DELETED] = "deleted"
	};
	if (type > LOGOFF_DELETED || type < 0) {
		fprintf(stderr, "mwjs error: bad logoff event type: %d\n", type);
		duk_pop(ctx);
		return 1;
	}
	duk_push_string(ctx, subtypes[type]);
	duk_put_prop_string(ctx, i, "method");
	reason = json_getstring(j, "reason");
	if (reason != NULL) {
		duk_push_string(ctx, reason);
		duk_put_prop_string(ctx, i, "reason");
	}
	agent = json_getstring(j, "agent");
	if (agent != NULL) {
		duk_push_string(ctx, agent);
		duk_put_prop_string(ctx, i, "agent");
	}
	return 0;
}

static int js_push_join_event(json_t *j, duk_idx_t i, int type)
{
	const char *agent = json_getstring(j, "agent");
	const char *subtypes[] = {
		[JOIN_NORMAL] = "normal",
		[JOIN_SUMMONED] = "summoned",
		[JOIN_FORCED] = "forced",
	};
	if (type > JOIN_FORCED || type < 0) {
		fprintf(stderr, "mwjs error: bad join event type: %d\n", type);
		duk_pop(ctx);
		return 1;
	}
	duk_push_string(ctx, subtypes[type]);
	duk_put_prop_string(ctx, i, "method");
	if (agent != NULL) {
		duk_push_string(ctx, agent);
		duk_put_prop_string(ctx, i, "agent");
	}
	duk_push_number(ctx, json_getint(j, "channel"));
	duk_put_prop_string(ctx, i, "channel");
	return 0;
}

static int js_push_leave_event(json_t *j, duk_idx_t i, int type)
{
	const char *agent = json_getstring(j, "agent");
	const char *msg = json_getstring(j, "message");
	const char *subtypes[] = {
		[LEAVE_NORMAL] = "normal",
		[LEAVE_ZOD] = "zod",
		[LEAVE_FORCED] = "forced",
		[LEAVE_EXIT] = "logoff",
	};
	if (type > LEAVE_EXIT || type < 0) {
		fprintf(stderr, "mwjs error: bad leave event type: %d\n", type);
		duk_pop(ctx);
		return 1;
	}
	duk_push_string(ctx, subtypes[type]);
	duk_put_prop_string(ctx, i, "method");
	if (agent != NULL) {
		duk_push_string(ctx, agent);
		duk_put_prop_string(ctx, i, "agent");
	}
	if (msg != NULL) {
		duk_push_string(ctx, msg);
		duk_put_prop_string(ctx, i, "message");
	}
	duk_push_number(ctx, json_getint(j, "channel"));
	duk_put_prop_string(ctx, i, "channel");
	return 0;
}

static int (*js_push_onoff_func[ONOFF_SIZE])(json_t*, duk_idx_t, int) = {
	js_push_logon_event,
	js_push_logoff_event,
	js_push_join_event,
	js_push_leave_event
};

/* Pushes the event object and attaches the common bits to it before calling
 * the onoff action type-specific function to fill in the rest */
static int js_push_onoff_event(json_t *j, int action)
{
	duk_idx_t idx = duk_push_bare_object(ctx);
	int type = json_getint(j, "type");
	int ret;

	duk_push_boolean(ctx, json_is_true(json_object_get(j, "quiet")));
	duk_put_prop_string(ctx, idx, "quiet");
	duk_push_string(ctx, json_getstring(j, "user"));
	duk_put_prop_string(ctx, idx, "user");

	ret = js_push_onoff_func[action](j, idx, type);
	json_decref(j);
	return ret;
}

static duk_ret_t js_print(duk_context *cx)
{
	int argc = duk_get_top(cx);
@@ -756,6 +876,24 @@ static int js_push_event(struct mwevent *ev)
		if (ret == 0)
			duk_put_prop_string(ctx, idx, "data");
		break;
	case MWEV_TYPE_ONOFF:
		duk_require_stack(ctx, 2);
		/* ONOFF covers 4 different types of events so expose them as
		   separate event types to reduce js boilerplate */
		json_t *j = ipcmsg_json_decode(ev->ev_data.onoff);
		if (j == NULL) {
			fprintf(stderr, "mwjs error: failed to unmarshall message\n");
			return -1;
		}
		int action = json_getint(j, "action");
		if (action >= ONOFF_SIZE || action < 0)
			break;
		duk_push_string(ctx, onoff_action_name[action]);
		duk_put_prop_string(ctx, idx, "type");
		ret = js_push_onoff_event(j, action);
		if (ret == 0)
			duk_put_prop_string(ctx, idx, "data");
		break;
	case MWEV_TYPE_NONE:
		/* Fall through */
	default:
+10 −45
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@
#include "userio.h"
#include "who.h"
#include "alias.h"
#include "onoff.h"

static char version[]="Milliways III - Release "VERSION"\n";

@@ -198,7 +199,7 @@ static void accept_line(char *line)
			broadcast(1, "\03304%s'%s connection has just dropped.", user->record.name,
			          user->record.name[strlen(user->record.name)] == 's' ? "" : "s");
			mwlog("EOF(LOGOUT)");
			close_down(2, NULL, NULL);
			close_down(LOGOFF_EOFS, NULL, NULL);
		}
	} else
	{
@@ -727,8 +728,7 @@ int main(int argc, char **argv)

	/* run all board init functions */
	RunInitFuncs(0);
	/* broadcast board logon signal to other users */
	broadcast_onoffcode(3, autochat, NULL, NULL);
	announce_logon(user->record.name, autochat ? LOGON_AUTOCHAT : LOGON_NORMAL, quietmode);

	/* autochat - log onto talker immediately */
	if (autochat && u_reg(user)) t_chaton();
@@ -757,7 +757,7 @@ int main(int argc, char **argv)
			fflush(stdout);
			perror("stdin");
			mwlog("ERROR on stdin");
			close_down(5, NULL, NULL);
			close_down(LOGOFF_ERROR, NULL, NULL);
		}
		if (!busy && MesgIsStacked())
		{
@@ -837,7 +837,7 @@ void accept_command(char *cmd)
	}
}

void close_down(int exitmode, char *sourceuser, char *reason)
void close_down(int logofftype, char *sourceuser, char *reason)
{
	extern char *event_user;
	extern char *event_body_text;
@@ -862,19 +862,10 @@ void close_down(int exitmode, char *sourceuser, char *reason)
				else ExecEvent(shutdown_name, "", "ShutDown", NULL, 0);
			}
		}
		/* give 'straight to shell' logoff code */
		broadcast_onoffcode(0, 3, sourceuser, NULL);
		announce_leave(user->record.name, user->record.room, LEAVE_EXIT, sourceuser, NULL, quietmode);
	}

	/* send different broadcast depending on exitmode */
	/* 0 - normal */
	/* 1 - timeout */
	/* 2 - too many eof's */
	/* 3 - mrod */
	/* 4 - banned */
	/* 5 - error */
	broadcast_onoffcode(2, exitmode, sourceuser, reason);

	announce_logoff(user->record.name, logofftype, sourceuser, reason, quietmode);

	/* update user information */
	time_t now = time(0);
@@ -904,11 +895,8 @@ void close_down(int exitmode, char *sourceuser, char *reason)
	stop_js();
	alarm_cleanup();

	/* dont display logoff text if quiet, or if dropped */
	if (!quietmode && exitmode!=1 && exitmode!=2)
	{
	if (!quietmode && logofftype != LOGOFF_TIMEOUT && logofftype != LOGOFF_EOFS)
		broadcast(1, "\03302%s has just left the board.", user->record.name);
	}

	mwlog("LOGOUT");
	sleep(1); //dodgy hack for race condition in checkonoff, cunningly we currently get woken by the very message we're waiting for.
@@ -1261,7 +1249,7 @@ static void time_out(void *idle_count_p)

		broadcast(1, _("\03304%s has been timed out."), user->record.name);
		mwlog("TIMEOUT(LOGOUT)");
		close_down(1, NULL, NULL);
		close_down(LOGOFF_TIMEOUT, NULL, NULL);
	}
	else if (*icnt==0)
	{
@@ -1274,7 +1262,7 @@ static void time_out(void *idle_count_p)
	else
	{
		mwlog("TIMEOUT(BLOCKED)");
		close_down(1, NULL, NULL);
		close_down(LOGOFF_TIMEOUT, NULL, NULL);
	}

}
@@ -1846,26 +1834,3 @@ void devel_msg(const char *func, const char *fmt, ...)
	if (cp_test(user, CP_DEVEL))
		printf("\n*** WARNING (%s): %s\n", func, text);
}


void broadcast_onoffcode(int ocode, int method, const char *sourceuser, const char *reason)
{
	char logofftext[MAXTEXTLENGTH];
	extern int talker_logontype;
	const char *usr;

	if (sourceuser == NULL)
		usr = user->record.name;
	else
		usr = sourceuser;

	if (reason == NULL)
		snprintf(logofftext, MAXTEXTLENGTH-1, "%d,%d,%d,%s", ocode, method,
		         talker_logontype & LOGONMASK_QUIET, usr);
	else
		snprintf(logofftext, MAXTEXTLENGTH-1, "%d,%d,%d,%s,%s", ocode, method,
		         talker_logontype & LOGONMASK_QUIET, usr, reason);

	logofftext[MAXTEXTLENGTH-1] = '\0';
	ipc_send_to_all(IPC_CHECKONOFF, logofftext);
}
+0 −1
Original line number Diff line number Diff line
@@ -5,7 +5,6 @@ void close_down(int exitmode, char *sourceuser, char *reason);
void display_message(const char *text, int beeps, int newline);
void format_message(const char *format, ...) __attribute__((format(printf,1,0)));
void printfile(const char *filename);
void broadcast_onoffcode(int code, int method, const char *sourceuser, const char *reason);
void reset_timeout(int secs);
int idle(int fd, int millis);
void set_rights(void);
Loading