/* interface.c */ #include "config.h" /* * This file is part of TeenyMUD II. * Copyright(C) 1993, 1994, 1995 by Jason Downs. * All rights reserved. * * TeenyMUD II is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * TeenyMUD II 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. * * You should have received a copy of the GNU General Public License * along with this program (see the file 'COPYING'); if not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. * */ /* AIX requires this to be the first thing in the file. */ #ifdef __GNUC__ #define alloca __builtin_alloca #else /* not __GNUC__ */ #ifdef HAVE_ALLOCA_H #include <alloca.h> #else /* not HAVE_ALLOCA_H */ #ifdef _AIX #pragma alloca #endif /* not _AIX */ #endif /* not HAVE_ALLOCA_H */ #endif /* not __GNUC__ */ #include <stdio.h> #include <sys/types.h> #ifdef HAVE_STRING_H #include <string.h> #else #include <strings.h> #endif /* HAVE_STRING_H */ #include <ctype.h> #ifdef HAVE_SYS_TIME_H #include <sys/time.h> #else #include <time.h> #endif /* HAVE_SYS_TIME_H */ #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif /* HAVE_STDLIB_H */ #include "conf.h" #include "teeny.h" #include "commands.h" #include "fcache.h" #include "conn.h" #include "externs.h" enum who_code { LIST_WHO, LIST_WHERE, LIST_SESSION }; enum str_code { PREFIX, SUFFIX }; static char poll_str[41]; /* the poll */ static void conn_updsite _ANSI_ARGS_((struct conn *)); static void set_output_str _ANSI_ARGS_((struct conn *, char *, enum str_code)); static void do_wholine _ANSI_ARGS_((struct conn *, struct conn *, char *, enum who_code, int, int *, int *)); static void do_wholist _ANSI_ARGS_((struct conn *, char *, enum who_code)); static void do_stty _ANSI_ARGS_((struct conn *, char *)); static void log_create _ANSI_ARGS_((struct conn *)); static void log_badconnect _ANSI_ARGS_((struct conn *, char *)); static void log_badcreate _ANSI_ARGS_((struct conn *, char *)); void interface_init() { time_t now; time(&now); mudstat.now = now; mudstat.lastdump = now; mudstat.startup = now; mudstat.lasttime = now; poll_str[0] = '\0'; } void timers() { register struct conn *cp; /* run the queue */ queue_run(mudconf.queue_slice); /* timeout connections. */ if (mudstat.now > mudstat.lasttime) { for(cp = connlist; cp != (struct conn *)NULL; cp = cp->next) { if((cp->player == -1) && mudconf.login_timeout) { if((cp->last - mudstat.now) > mudconf.login_timeout) { conn_dump_file(cp, mudconf.timeout_file); conn_logoff(cp); } } if((cp->player != -1) && mudconf.player_timeout && !isWIZARD(cp->player)) { if((cp->last - mudstat.now) > mudconf.player_timeout) { conn_dump_file(cp, mudconf.timeout_file); conn_logoff(cp); } } cp->cc = 0; } } /* dump the database. */ if ((mudstat.now - mudstat.lastdump) > mudconf.dump_interval) { mudstat.lastdump = mudstat.now; dump_db(); } /* ping rwho */ if (mudconf.enable_rwho && ((mudstat.now - mudstat.lastrwho) > mudconf.rwho_interval)) { mudstat.lastrwho = mudstat.now; rwho_ping(); } mudstat.lasttime = mudstat.now; } #define SKIP_WORD(x, y) for(y = x; y[0] && !isspace(y[0]); y++); \ for(; y[0] && isspace(y[0]); y++) VOID handle_input(cp, input) struct conn *cp; char *input; { switch(input[0]) { case 'W': case 'w': /* WHO or WHERE */ if(!strncasecmp(input, "WHO", 3)) { if(cp->outputprefix != (char *)NULL) conn_put(cp, cp->outputprefix); do_wholist(cp, input + 3, LIST_WHO); if(cp->outputsuffix != (char *)NULL) conn_put(cp, cp->outputsuffix); return; } else if(!strncasecmp(input, "WHERE", 5)) { if(cp->outputprefix != (char *)NULL) conn_put(cp, cp->outputprefix); do_wholist(cp, input + 5, LIST_WHERE); if(cp->outputsuffix != (char *)NULL) conn_put(cp, cp->outputsuffix); return; } break; case 'S': case 's': /* SESSION or STTY */ if(!strncasecmp(input, "SESSION", 7)) { if(cp->outputprefix != (char *)NULL) conn_put(cp, cp->outputprefix); do_wholist(cp, input + 7, LIST_SESSION); if(cp->outputsuffix != (char *)NULL) conn_put(cp, cp->outputsuffix); return; } else if(!strncasecmp(input, "STTY", 4)) { if(cp->outputprefix != (char *)NULL) conn_put(cp, cp->outputprefix); do_stty(cp, input + 4); if(cp->outputsuffix != (char *)NULL) conn_put(cp, cp->outputsuffix); return; } break; case 'Q': case 'q': if(!strcasecmp(input, "QUIT")) { conn_dump_file(cp, mudconf.bye_file); conn_logoff(cp); return; } break; case 'O': /* OUPUT*X */ if(!strncmp(input, "OUTPUTPREFIX", 12)) { if(isROBOT(cp->player)) { set_output_str(cp, input + 12, PREFIX); } else { conn_put(cp, "Only robots may use OUTPUTPREFIX."); } return; } else if(!strncmp(input, "OUTPUTSUFFIX", 12)) { if(isROBOT(cp->player)) { set_output_str(cp, input + 12, SUFFIX); } else { conn_put(cp, "Only robots may use OUTPUTSUFFIX."); } return; } break; case 'P': /* PUEBLO */ if(!strncmp(input, "PUEBLOCLIENT", 12)) { if(mudconf.enable_pueblo) { cp->html_ext = HTML_PUEBLO; conn_put_raw(cp, "</xch_mudtext><img xch_mode=html>"); } else { conn_put(cp, "Sorry, I don't *do* that."); } return; } break; } /* still here? */ if(cp->outputprefix != (char *)NULL) conn_put(cp, cp->outputprefix); handle_cmd(cp->player, cp->player, input, 0, (char **)NULL); if(cp->outputsuffix != (char *)NULL) conn_put(cp, cp->outputsuffix); } VOID handle_login(cp, input) struct conn *cp; char *input; { char *ptr, *name, *pwd, *mesg; int player; switch(input[0]) { case 'W': case 'w': /* WHO or WHERE */ if(!strncasecmp(input, "WHO", 3)) { if(cp->outputprefix != (char *)NULL) conn_put(cp, cp->outputprefix); do_wholist(cp, input + 3, LIST_WHO); if(cp->outputsuffix != (char *)NULL) conn_put(cp, cp->outputsuffix); } else if(!strncasecmp(input, "WHERE", 5)) { if(cp->outputprefix != (char *)NULL) conn_put(cp, cp->outputprefix); do_wholist(cp, input + 5, LIST_WHERE); if(cp->outputsuffix != (char *)NULL) conn_put(cp, cp->outputsuffix); } return; case 'S': case 's': /* SESSION or STTY */ if(!strncasecmp(input, "SESSION", 7)) { if(cp->outputprefix != (char *)NULL) conn_put(cp, cp->outputprefix); do_wholist(cp, input + 7, LIST_SESSION); if(cp->outputsuffix != (char *)NULL) conn_put(cp, cp->outputsuffix); } else if(!strncasecmp(input, "STTY", 4)) { if(cp->outputprefix != (char *)NULL) conn_put(cp, cp->outputprefix); do_stty(cp, input + 4); if(cp->outputsuffix != (char *)NULL) conn_put(cp, cp->outputsuffix); } return; case 'Q': case 'q': /* QUIT */ if(!strcasecmp(input, "QUIT")) conn_logoff(cp); return; case 'O': /* OUTPUT*X */ if(!strncmp(input, "OUTPUTPREFIX", 12)) set_output_str(cp, input + 12, PREFIX); else if(!strncmp(input, "OUTPUTSUFFIX", 12)) set_output_str(cp, input + 12, SUFFIX); return; case 'P': /* PUEBLO */ if(!strncmp(input, "PUEBLOCLIENT", 12)) { if(mudconf.enable_pueblo) { cp->html_ext = HTML_PUEBLO; conn_put_raw(cp, "</xch_mudtext><img xch_mode=html>"); } else { conn_put(cp, "Sorry, I don't *do* that."); } return; } break; } /* still here? */ if(!strncasecmp(input, "co", 2)) { /* login attempt */ SKIP_WORD(input, ptr); if(parse_name_pwd(ptr, &name, &pwd) != 0) conn_put(cp, "Error parsing connection sequence."); else { player = connect_player(name, pwd); if(player == -1) { conn_dump_file(cp, mudconf.badconn_file); log_badconnect(cp, name); } else { char *hatr; int haflgs; if((mudstat.logins != LOGINS_DISABLED) || isWIZARD(player)) { announce_connect(player, cp->user, cp->host); /* first */ animate(player); cp->player = player; cp->handler = handle_input; log_connect(cp); if(mudconf.enable_rwho) rwho_login(player); if(!isGUEST(player)) { if(attr_get(player, SITE, &hatr, &haflgs) != -1) { if((hatr == (char *)NULL) || (hatr[0] == '\0')) conn_dump_file(cp, mudconf.newp_file); } else logfile(LOG_ERROR, "handle_login: couldn't get host on player #%d\n", player); conn_dump_file(cp, mudconf.motd_file); if(mudstat.exmotd != (char *)NULL) conn_put(cp, mudstat.exmotd); if(isWIZARD(player)) { conn_dump_file(cp, mudconf.wizn_file); if(mudstat.exwiz != (char *)NULL) conn_put(cp, mudstat.exwiz); } } else conn_dump_file(cp, mudconf.guest_file); check_last(player); check_news(player); if(mudconf.enable_money) check_paycheck(player); conn_updsite(cp); stamp(player, STAMP_LOGIN); if(!isROBOT(player) && ((cp->outputprefix != (char *)NULL) || (cp->outputsuffix != (char *)NULL))) { conn_put(cp, "Your OUTPUTREFIX and OUTPUTSUFFIX strings have been cleared."); if(cp->outputprefix != (char *)NULL) { ty_free((VOID *)cp->outputprefix); cp->outputprefix = (char *)NULL; } if(cp->outputsuffix != (char *)NULL) { ty_free((VOID *)cp->outputsuffix); cp->outputsuffix = (char *)NULL; } } stty_restore(cp); look_location(player, player, 0); } else conn_put(cp, "Sorry, logins are disabled."); } } } else if(!strncasecmp(input, "cr", 2)) { /* creation attempt */ SKIP_WORD(input, ptr); if(mudstat.logins != LOGINS_DISABLED) { if(!mudconf.registration) { if(check_host(cp->host, LOCK_REGISTER, &mesg)) { if(mesg && *mesg) { conn_put(cp, mesg); } else { conn_dump_file(cp, mudconf.register_file); } return; } if(parse_name_pwd(ptr, &name, &pwd) != 0) conn_put(cp, "Error parsing creation sequence."); else { player = create_player(name, pwd, -1); if(player == -1) { conn_dump_file(cp, mudconf.badcrt_file); log_badcreate(cp, name); } else { announce_connect(player, cp->user, cp->host); /* first */ animate(player); cp->player = player; cp->handler = handle_input; log_create(cp); if(mudconf.enable_rwho) rwho_login(player); conn_dump_file(cp, mudconf.newp_file); conn_dump_file(cp, mudconf.motd_file); if(mudstat.exmotd != (char *)NULL) conn_put(cp, mudstat.exmotd); check_news(player); conn_updsite(cp); stamp(player, STAMP_LOGIN); if(!isROBOT(player) && ((cp->outputprefix != (char *)NULL) || (cp->outputsuffix != (char *)NULL))) { conn_put(cp, "Your OUTPUTPREFIX and OUTPUTSUFFIX strings have been cleared."); if(cp->outputprefix != (char *)NULL) { ty_free((VOID *)cp->outputprefix); cp->outputprefix = (char *)NULL; } if(cp->outputsuffix != (char *)NULL) { ty_free((VOID *)cp->outputsuffix); cp->outputsuffix = (char *)NULL; } } stty_restore(cp); look_location(player, player, 0); } } } else conn_dump_file(cp, mudconf.register_file); } else conn_put(cp, "Sorry, logins are disabled."); } else conn_greet(cp); } static void conn_updsite(cp) struct conn *cp; { if(cp->player == -1) return; if(cp->user != (char *)NULL) { char *buff = (char *)alloca(strlen(cp->user) + strlen(cp->host) + 2); if(buff == (char *)NULL) { panic("conn_updsite: stack allocation failed.\n"); } strcpy(buff, cp->user); strcat(buff, "@"); strcat(buff, cp->host); if(attr_add(cp->player, SITE, buff, SITE_FLGS) == -1) logfile(LOG_ERROR, "conn_updsite: couldn't set host on player #%d\n", cp->player); } else if((cp->host != (char *)NULL) && (cp->host[0] != '\0')) { if(attr_add(cp->player, SITE, cp->host, SITE_FLGS) == -1) logfile(LOG_ERROR, "conn_updsite: couldn't set host on player #%d\n", cp->player); } } #if defined(__STDC__) static void set_output_str(struct conn *cp, char *string, enum str_code code) #else static void set_output_str(cp, string, code) struct conn *cp; char *string; enum str_code code; #endif { while (string[0] && isspace(string[0])) string++; switch(code) { case PREFIX: if (!string || !*string) { ty_free((VOID *)cp->outputprefix); cp->outputprefix = (char *)NULL; } else { ty_free((VOID *)cp->outputprefix); cp->outputprefix = (char *)ty_strdup(string, "set_output_str.outputprefix"); } break; case SUFFIX: if (!string || !*string) { ty_free((VOID *)cp->outputsuffix); cp->outputsuffix = (char *)NULL; } else { ty_free((VOID *)cp->outputsuffix); cp->outputsuffix = (char *)ty_strdup(string, "set_output_str.outputprefix"); } break; } } void conn_greet(cp) struct conn *cp; { if (cp->player == -1) { if (mudconf.enable_pueblo) conn_put(cp, "This world is Pueblo 1.0 Enhanced."); conn_dump_file(cp, mudconf.greet_file); } } int conn_dump_file(cp, filename) struct conn *cp; char *filename; { FCACHE *fc; off_t size; /* problem: fcache'd files of zero lenght return NULL. */ fc = fcache_open(filename, &size); if ((fc == (FCACHE *)NULL) && (size == -1)) { char buff[256]; snprintf(buff, sizeof(buff), "I'm sorry, %s seems to be broken.", filename); conn_put(cp, buff); return(-1); } while(fc != (FCACHE *)NULL) { conn_put(cp, fcache_read(fc)); fc = fcache_next(fc); } return(1); } /* Display the WHO list to a connection. */ INLINE static char *convtime1(wtime) time_t wtime; { register time_t g, h, i, j; static char ret[40]; g = wtime; h = g / 86400; g %= 86400; i = g / 3600; j = g / 60 % 60; if (h) snprintf(ret, sizeof(ret), "%ldd %02ld:%02ld", h, i, j); else snprintf(ret, sizeof(ret), "%02ld:%02ld", i, j); return (ret); } INLINE static char *convtime2(idtime) time_t idtime; { register time_t k; register char idletype; static char ret[40]; k = idtime; idletype = 's'; if (k > 59) { idletype = 'm'; k /= 60; if (k > 59) { idletype = 'h'; k /= 60; if (k > 23) { idletype = 'd'; k /= 24; } } } snprintf(ret, sizeof(ret), "%2ld%c", k, idletype); return (ret); } #if defined(__STDC__) static void do_wholine(register struct conn *cp, register struct conn *who, char *arg, enum who_code code, int wizard, int *total, int *utotal) #else static void do_wholine(cp, who, arg, code, wizard, total, utotal) register struct conn *cp, *who; char *arg; enum who_code code; int wizard, *total, *utotal; #endif { char *whonm; char line[256], namebuf[40], locbuf[60]; int loc; if (wizard || ((who->player != -1) && (!isDARK(who->player)))) { if(who->player != -1) { (*total)++; if (get_str_elt(who->player, NAME, &whonm) != -1) strcpy(namebuf, whonm); else strcpy(namebuf, "???"); if ((arg != (char *)NULL) && (arg[0] != '\0') && !stringprefix(namebuf, arg)) return; if (wizard) { snprintf(&namebuf[strlen(namebuf)], sizeof(namebuf) - strlen(namebuf), "(#%d%s%s%s%s%s)", who->player, (isWIZARD(who->player) ? "W" : ""), (isDARK(who->player) ? "D" : ""), (isHIDDEN(who->player) ? "h" : ""), (isGUEST(who->player) ? "g" : ""), ((who->html_ext == HTML_PUEBLO) ? "P" : "")); } } else { (*utotal)++; if ((arg != (char *)NULL) && (arg[0] != '\0')) /* They don't match. */ return; strcpy(namebuf, "***"); } switch (code) { case LIST_WHO: snprintf(line, sizeof(line), "%-19s%9s%7s %s", namebuf, convtime1(mudstat.now - who->connect), convtime2(mudstat.now - who->last), (who->doing != (char *)NULL) ? who->doing : ""); break; case LIST_WHERE: if ((who->player == -1) || (get_int_elt(who->player, LOC, &loc) == -1) || !exists_object(loc)) loc = -1; if (!wizard) { if (!isHIDDEN(who->player) && (loc != -1) && !isHIDDEN(loc) && (get_str_elt(loc, NAME, &whonm) != -1)) { ty_strncpy(locbuf, whonm, 50); } else strcpy(locbuf, "???"); if ((strlen(locbuf) < 45) && exists_object(loc) && (isJUMP_OK(loc) || ((cp->player != -1) && controls(cp->player, cp->player, loc)))) { snprintf(&locbuf[strlen(locbuf)], sizeof(locbuf) - strlen(locbuf), "(#%d)", loc); } snprintf(line, sizeof(line), "%-20s%s", namebuf, locbuf); } else { if (loc == -1) { strcpy(locbuf, "???"); } else { snprintf(locbuf, sizeof(locbuf), "(#%d)", loc); } if (who->user != (char *)NULL) { snprintf(line, sizeof(line), "%-20s%8s %-3d %-5d %s@%s", namebuf, locbuf, who->fd, who->port, who->user, who->host); } else { snprintf(line, sizeof(line), "%-20s%8s %-3d %-5d %s", namebuf, locbuf, who->fd, who->port, who->host); } } break; case LIST_SESSION: snprintf(line, sizeof(line), "%-20s %-10d %-15d %-15d", namebuf, who->bcc, who->ibyte, who->obyte); break; } conn_put(cp, line); } } #if defined(__STDC__) static void do_wholist(struct conn *cp, char *arg, enum who_code code) #else static void do_wholist(cp, arg, code) struct conn *cp; char *arg; enum who_code code; #endif { register struct conn *who; int total = 0, utotal = 0; int wizard = 0; int reverse = 0; char line[128]; while (isspace(arg[0])) arg++; if (mudconf.wizwhoall || ((cp->player != -1) && isWIZARD(cp->player))) wizard = 1; if((cp->player != -1) && isREVERSED_WHO(cp->player)) reverse = 1; if(!wizard && (code == LIST_SESSION)) code = LIST_WHO; switch(code) { case LIST_WHO: snprintf(line, sizeof(line), "Player Name On For Idle %s", (poll_str[0] ? poll_str : "Doing")); break; case LIST_WHERE: strcpy(line, "Player Name Location"); if(wizard) strcat(line, " Fd Port User/Site"); break; case LIST_SESSION: strcpy(line, "Player Name Blown Input Count Output Count"); break; } conn_put(cp, line); /* dump the list. */ if(reverse) { who = connlist->prev; do { do_wholine(cp, who, arg, code, wizard, &total, &utotal); who = who->prev; } while(who != connlist->prev); } else { for(who = connlist; who != (struct conn *)NULL; who = who->next) do_wholine(cp, who, arg, code, wizard, &total, &utotal); } if (utotal) { snprintf(line, sizeof(line), "There are %d connections to the twilight zone.", utotal); conn_put(cp, line); } if (total) { snprintf(line, sizeof(line), "%d user%s %s connected. %sUptime: %s", total, ((total == 1) ? "" : "s"), ((total == 1) ? "is" : "are"), ((mudstat.logins == LOGINS_DISABLED) ? "Logins disabled. " : ""), convtime1(mudstat.now - mudstat.startup)); } else { snprintf(line, sizeof(line), "No users are connected. %sUptime: %s", ((mudstat.logins == LOGINS_DISABLED) ? "Logins disabled. " : ""), convtime1(mudstat.now - mudstat.startup)); } conn_put(cp, line); } /* Return a 'list' of the connected object numbers. */ void who_strlist(buffer, bufsiz) char *buffer; int bufsiz; { struct conn *who; char sbuf[32]; buffer[0] = '\0'; for(who = connlist; who != (struct conn *)NULL; who = who->next) { if((who->player != -1) && ((!isDARK(who->player) && !isHIDDEN(who->player)) || mudconf.wizwhoall)) { snprintf(sbuf, sizeof(sbuf), "#%d", who->player); slist_add(sbuf, buffer, bufsiz); } } } /* Count how many people are logged in from the host, or all. */ int count_logins(host) char *host; { register int count = 0; register struct conn *who; for(who = connlist; who != (struct conn *)NULL; who = who->next) { if((host == (char *)NULL) || quick_wild(who->host, host)) count++; } return(count); } /* IMPORTANT: These all must be in the same order! */ const char *const stty_nlmodekey[] = {"crnl", "cr", "nl", "nlcr"}; const int stty_nlmodeval[] = {CONN_CRNL, CONN_CR, CONN_NL, CONN_NLCR}; const char *const stty_nlmodes[] = {"\r\n", "\r", "\n", "\n\r"}; const char *const stty_nltab[] = {"CONN_CRNL", "CONN_CR", "CONN_NL", "CONN_NLCR" }; static void do_stty(cp, input) struct conn *cp; char *input; { int i; char *ptr; char buf[BUFFSIZ]; while((*input != '\0') && isspace(*input)) input++; switch(*input) { case 'N': case 'n': if(!strncasecmp(input, "nlmode", 6)) { while((*input != '\0') && !isspace(*input)) input++; while((*input != '\0') && isspace(*input)) input++; if(*input == '\0') break; for(i = 0; i < 4; i++) { if(!strcasecmp(input, stty_nlmodekey[i])) { cp->lcrnl = stty_nlmodeval[i]; conn_put(cp, "Newline mode changed."); return; } } } break; case 'W': case 'w': if(!strncasecmp(input, "wrap", 4)) { while((*input != '\0') && !isspace(*input)) input++; while((*input != '\0') && isspace(*input)) input++; if(*input == '\0') break; i = (int)strtol(input, &ptr, 10); if(ptr == input) break; if(i < 0) i = 0; cp->lwrap = i; conn_put(cp, ((i == 0) ? "Line wrap disabled." : "Line wrap enabled.")); return; } break; case 'H': case 'h': if(!strncasecmp(input, "html", 4)) { while((*input != '\0') && !isspace(*input)) input++; while((*input != '\0') && isspace(*input)) input++; if(*input == '\0') break; if(!strcasecmp(input, "none")) { cp->html_ext = HTML_NONE; conn_put(cp, "Html mode disabled."); } else if(!strcasecmp(input, "pueblo")) { if(mudconf.enable_pueblo) { cp->html_ext = HTML_PUEBLO; conn_put(cp, "Html mode enabled for Pueblo."); conn_put_raw(cp, "</xch_mudtext><img xch_mode=html>"); } else conn_put(cp, "I don't *do* that!"); } return; } break; } conn_put(cp, "Current stty settings:"); if(cp->lwrap) snprintf(buf, sizeof(buf), "Line wrap: %d Newline mode: ", cp->lwrap); else strcpy(buf, "Line wrap: *DISABLED* Newline mode: "); strcat(buf, stty_nlmodekey[cp->lcrnl]); conn_put(cp, buf); switch (cp->html_ext) { case HTML_NONE: conn_put(cp, "Html mode: *DISABLED*"); break; case HTML_PUEBLO: conn_put(cp, "Html mode: Pueblo"); break; } } void log_disconnect(cp) struct conn *cp; { char *name; if (cp->player != -1) { if (get_str_elt(cp->player, NAME, &name) != -1) { logfile(LOG_STATUS, "DISCONNECT: %s(#%d) on fd %d.\n", name, cp->player, cp->fd); } else logfile(LOG_STATUS, "DISCONNECT: ???(#%d) on fd %d.\n", cp->player, cp->fd); } else logfile(LOG_STATUS, "DISCONNECT: fd %d never connected.\n", cp->fd); } void log_connect(cp) struct conn *cp; { char *name; if (cp->player != -1) { if (get_str_elt(cp->player, NAME, &name) != -1) { logfile(LOG_STATUS, "CONNECTED: %s(#%d) on fd %d.\n", name, cp->player, cp->fd); } else logfile(LOG_STATUS, "CONNECTED: ???(#%d) on fd %d.\n", cp->player, cp->fd); } else { if(cp->user != (char *)NULL) { logfile(LOG_STATUS, "CONNECTION: fd %d connected from [%s@%s], remort port %d.\n", cp->fd, cp->user, cp->host, cp->port); } else { logfile(LOG_STATUS, "CONNECTION: fd %d connected from [%s], remote port %d.\n", cp->fd, cp->host, cp->port); } } } static void log_create(cp) struct conn *cp; { char *name; if (get_str_elt(cp->player, NAME, &name) != -1) { logfile(LOG_STATUS, "CREATED: %s(#%d) on fd %d.\n", name, cp->player, cp->fd); } else logfile(LOG_STATUS, "CREATED: ???(#%d) on fd %d.\n", cp->player, cp->fd); } static void log_badconnect(cp, s) struct conn *cp; char *s; { logfile(LOG_STATUS, "FAILED CONNECT: fd %d failed connection to \"%s\".\n", cp->fd, s); } static void log_badcreate(cp, s) struct conn *cp; char *s; { logfile(LOG_STATUS, "FAILED CREATE: fd %d failed to create player \"%s\".\n", cp->fd, s); } int numconnected(player) int player; { register struct conn *cp; register int ret = 0; for (cp = connlist; cp != (struct conn *) NULL; cp = cp->next) { if ((cp->player != -1) && (cp->player == player)) ret++; } return (ret); } int fd_conn(player) int player; { register struct conn *cp; for (cp = connlist; cp != (struct conn *) NULL; cp = cp->next) { if ((cp->player != -1) && (cp->player == player)) return (cp->fd); } return (-1); } /* * Determine if a player can do HTML. * * Since HTML status is per-connection, but the player state has no * notion of connections, we fudge things. */ int has_html(player) int player; { register struct conn *cp; for (cp = connlist; cp != (struct conn *)NULL; cp = cp->next) { if ((cp->player != -1) && (cp->html_ext != HTML_NONE)) return (cp->html_ext); } return (HTML_NONE); } int match_active_player(arg) char *arg; { register struct conn *cp; int number = 0; int player = -1; int aflags; char *name, *alias; for (cp = connlist; cp != (struct conn *) NULL; cp = cp->next) { if(cp->player == -1) continue; if (get_str_elt(cp->player, NAME, &name) == -1) { logfile(LOG_ERROR, "match_active_player: bad player name reference #%d\n", cp->player); return (-1); } if (attr_get(cp->player, ALIAS, &alias, &aflags) == -1) { logfile(LOG_ERROR, "match_active_player: bad player alias ref #%d\n", cp->player); return(-1); } if (arg[0] && stringprefix(name, arg)) { if (strlen(arg) == strlen(name)) return (cp->player); number++; if (number == 1) { player = cp->player; } else { if (cp->player != player) return (-2); else number = 1; } } if (arg[0] && (alias != (char *)NULL) && alias[0] && stringprefix(alias, arg)) { if (strlen(arg) == strlen(name)) return (cp->player); number++; if (number == 1) { player = cp->player; } else { if (cp->player != player) return (-2); else number = 1; } } } if (number) return (player); else return (-1); } VOID do_doing(player, cause, switches, argone, argtwo) int player, cause, switches; char *argone, *argtwo; { struct conn *cp; register char *ptr; int person; if ((argtwo != (char *)NULL) && argtwo[0]) { person = resolve_player(player, cause, argone, (!(switches & CMD_QUIET) ? RSLV_NOISY : 0)); if(person == -1) return; if (!controls(player, cause, person)) { if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "You can't do that.", NOT_QUIET); return; } } else { person = player; argtwo = argone; } if (!isALIVE(person)) { /* @force won't crash me */ if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "That person is not connected.", NOT_QUIET); return; } if (argtwo && *argtwo && (strlen(argtwo) > (sizeof(poll_str)-1))) argtwo[sizeof(poll_str)] = '\0'; for (cp = connlist; cp != (struct conn *) NULL; cp = cp->next) { if ((cp->player == -1) || (cp->player != person)) continue; if (cp->doing != (char *)NULL) { ty_free((VOID *)cp->doing); cp->doing = (char *) NULL; } if (argtwo && *argtwo) cp->doing = (char *) ty_strdup(argtwo, "do_doing.doing"); if (cp->doing != (char *)NULL) { for(ptr = cp->doing; *ptr != '\0'; ptr++) { if(!isprint(*ptr)) *ptr = ' '; } } } if(!(switches & CMD_QUIET)) notify_player(player, cause, player, ((person == player) ? "Set. Have fun doing it." : "Set."), NOT_QUIET); } VOID do_poll(player, cause, switches, argone) int player, cause, switches; char *argone; { if ((argone == (char *)NULL) || (argone[0] == '\0')) argone = "Doing"; if (strlen(argone) > (sizeof(poll_str)-1)) argone[sizeof(poll_str)-1] = '\0'; strcpy(poll_str, argone); if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "Poll set.", NOT_QUIET); } void stty_restore(cp) struct conn *cp; { int aflags; char *stty, *ptr; if((cp->player != -1) && exists_object(cp->player) && isPLAYER(cp->player)) { if(attr_get(cp->player, STTY, &stty, &aflags) != -1) { if(stty && *stty) { cp->lwrap = (short)strtol(stty, &ptr, 10); if(*ptr != ':') { cp->lwrap = 0; return; } else { register int idx; ptr++; for(idx = 0; idx < 4; idx++) { if(strncmp(stty_nltab[idx], ptr, strlen(stty_nltab[idx])) == 0) { cp->lcrnl = idx; break; } } } conn_put(cp, "Stty settings restored."); } } } } VOID do_savestty(player, cause, switches, argone) int player, cause, switches; char *argone; { struct conn *cp; char buf[40]; int person; if((argone != (char *)NULL) && argone[0]) { person = resolve_player(player, cause, argone, (!(switches & CMD_QUIET) ? RSLV_NOISY : 0)); if(person == -1) return; } else person = player; if (!controls(player, cause, person)) { if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "You can't do that.", NOT_QUIET); return; } if (switches & SAVESTTY_RESTORE) { for (cp = connlist; cp != (struct conn *) NULL; cp = cp->next) { if ((cp->player == -1) || (cp->player != person)) continue; stty_restore(cp); } return; } else if (!(switches & SAVESTTY_CLEAR)) { if (!isALIVE(person)) { /* @force won't crash me */ if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "That person is not connected.", NOT_QUIET); return; } for (cp = connlist; cp != (struct conn *) NULL; cp = cp->next) { if ((cp->player == -1) || (cp->player != person)) continue; snprintf(buf, sizeof(buf), "%d:%s", cp->lwrap, stty_nltab[cp->lcrnl]); if(attr_add(player, STTY, buf, STTY_FLGS) == -1) { notify_bad(player); return; } break; } if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "Stty settings saved.", NOT_QUIET); } else { if(attr_delete(player, STTY) == -1) { notify_bad(player); return; } if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "Saved stty settings cleared.", NOT_QUIET); } }