/* misc.c */ #include "copyright.h" #include "config.h" #include <stdio.h> #include <sys/types.h> #include <ctype.h> #include <sys/time.h> #ifdef STRING_H #include <string.h> #else #include <strings.h> #endif /* STRING_H */ #include "teeny.h" #include "io.h" #include "case.h" #include "rwho.h" /* The WHO list. Surprise. */ Iob *wholist = (Iob *) 0; /* Time last time timers() was called. */ static struct timeval last; /* Last time we did a dump */ static long lastdump; /* The time that the mud went up. */ static long startingtimeofmud; #define DOING_MAX 40 /* max length of a doing string */ static char *poll_str; /* the poll */ #ifdef PDX static long lastmaxdaemon; extern int max_logins; #endif #ifdef SUPPORT_RWHO static long lastrwho; #endif static void set_output_str(); static void log_create(); static void log_badconnect(); extern void check_last(); extern void check_news(); void do_where(); void init_timers() { (void) gettimeofday(&last, (struct timezone *) 0); lastdump = last.tv_sec; startingtimeofmud = last.tv_sec; #ifdef PDX max_daemon(); lastmaxdaemon = last.tv_sec; #endif #ifdef SUPPORT_RWHO if (rwho_enabled) rwhocli_setup(rwho_server, rwho_pword, RWHO_NAME, RWHO_COMMENT); lastrwho = last.tv_sec; #endif } /* * This checks the current time and resets quotas if the current timeslice * has elapsed, and does a dump if the current dump interval has elapsed. * */ void timers() { struct timeval now; int delta; Iob *curr; (void) gettimeofday(&now, (struct timezone *) 0); /* How many tenths of seconds have elapsed since last time */ delta = (now.tv_sec - last.tv_sec) * 10 + (now.tv_usec - last.tv_usec) / 100000; if (delta >= TIME_SLICE) { /* timeout idle connects */ timeout_daemon(); /* Update all the quotas */ curr = wholist; if (curr != (Iob *) 0) { do { curr->quota = SLICE_QUOTA; curr = curr->whofwd; } while (curr != wholist); } last.tv_sec = now.tv_sec; last.tv_usec = now.tv_usec; } if (now.tv_sec - lastdump > DUMP_INTERVAL) { lastdump = now.tv_sec; /* Dump the DB */ dump_db(); } #ifdef PDX if (now.tv_sec - lastmaxdaemon > 1750) { lastmaxdaemon = now.tv_sec; max_daemon(); } #endif #ifdef SUPPORT_RWHO if (now.tv_sec - lastrwho > RWHO_INTERVAL) { lastrwho = now.tv_sec; if (rwho_enabled) rwho_daemon(); } #endif } /* * The network code calls this with Iob's with pending goo to process. * Process it. * */ void dispatch(bp) Iob *bp; { char *buff, *cmd, *p; int count; int player; int fullbuff; int z; bp->lastcmd = last.tv_sec; if (bp->quota < 0) { bp->inputcnt = 0; if (bp->typ != INPUT_PLAY) { iobflush(bp); iobdrop(bp); log_disconnect(bp); } return; } buff = bp->inputbuf; count = bp->inputcnt; /* Slide along, chopping it up into commands. */ fullbuff = (count == (MUDBUFSIZ - 1)); /* One for terminating \0 */ while (1) { cmd = buff; while (*buff != '\n' && count > 0 && *buff != '\r') { buff++; count--; } if (count <= 0 && !fullbuff) break; if ((bp->typ == INPUT_PLAY && !isrobot(bp->player)) || bp->typ != INPUT_PLAY) (bp->quota)--; if (bp->quota < 0) { /* Fuck this guy */ (bp->blown)++; buff = cmd; /* Fake an empty buffer */ break; } fullbuff = 0; *buff++ = '\0'; count--; /* change all non-printing characters to whitespace */ for (z = 0; cmd[z]; z++) { if (!isprint(cmd[z])) cmd[z] = ' '; } /* strip leading and trailing whitespace */ for (z--; isspace(cmd[z]); z--); cmd[z + 1] = '\0'; for (; isspace(cmd[0]); cmd++); if (!cmd[0]) continue; /* Check special commands. */ #ifdef WHO_CI if (!strncasecmp(cmd, WHO_COMMAND, strlen(WHO_COMMAND))) { #else if (!strncmp(cmd, WHO_COMMAND, strlen(WHO_COMMAND))) { #endif /* WHO_CI */ if ((bp->typ == INPUT_PLAY) && bp->outputprefix) { iobput(bp, bp->outputprefix); iobput(bp, "\r\n"); } do_wholist(bp, cmd + strlen(WHO_COMMAND)); if ((bp->typ == INPUT_PLAY) && bp->outputsuffix) { iobput(bp, bp->outputsuffix); iobput(bp, "\r\n"); } continue; } else #ifdef WHERE_CI if (!strncasecmp(cmd, WHERE_COMMAND, strlen(WHERE_COMMAND))) { #else if (!strncmp(cmd, WHERE_COMMAND, strlen(WHERE_COMMAND))) { #endif if ((bp->typ == INPUT_PLAY) && bp->outputprefix) { iobput(bp, bp->outputprefix); iobput(bp, "\r\n"); } do_where(bp, cmd + strlen(WHERE_COMMAND)); if ((bp->typ == INPUT_PLAY) && bp->outputsuffix) { iobput(bp, bp->outputsuffix); iobput(bp, "\r\n"); } continue; #ifdef QUIT_CI } else if (!strcasecmp(cmd, QUIT_COMMAND)) { #else } else if (!strcmp(cmd, QUIT_COMMAND)) { #endif /* QUIT_CI */ if ((bp->typ == INPUT_PLAY) && bp->outputprefix) { iobput(bp, bp->outputprefix); iobput(bp, "\r\n"); } if (bp->typ == INPUT_PLAY) iobput(bp, GOODBYE_MSG); if ((bp->typ == INPUT_PLAY) && bp->outputsuffix) { iobput(bp, bp->outputsuffix); iobput(bp, "\r\n"); } iobflush(bp); iobdrop(bp); if (bp->typ == INPUT_PLAY) { disconnect_player(bp->player); } log_disconnect(bp); continue; } switch (bp->typ) { case INPUT_NEWCONN: if (!strncmp(cmd, PREFIX_COMMAND, strlen(PREFIX_COMMAND))) { #ifndef RESTRICT_BOT set_output_str(bp, cmd + strlen(PREFIX_COMMAND), PREFIX_CODE); #else iobput(bp, RESTRICT_BOT_MSG); #endif break; } if (!strncmp(cmd, SUFFIX_COMMAND, strlen(SUFFIX_COMMAND))) { #ifndef RESTRICT_BOT set_output_str(bp, cmd + strlen(SUFFIX_COMMAND), SUFFIX_CODE); #else iobput(bp, RESTRICT_BOT_MSG); #endif break; } /* We grok two commands, create and connect. */ for (p = cmd; !isspace(*p) && *p; p++); if (*p == '\0') { greet(bp); break; } *p++ = '\0'; if (stringprefix(cmd, "connect")) { player = connect_player(p); if (player == -1) { iobput(bp, BAD_CONNECT); log_badconnect(p, bp); } else { #ifdef PDX if (mud_fullPDX(player)) { iobput(bp, "Sorry, ThreadWay is currently full. Do try again later.\r\n"); } else { #endif /* PDX */ connect_player2(player); /* announce and such */ bp->typ = INPUT_PLAY; bp->player = player; newwho(bp); log_connect(bp); #ifdef SUPPORT_RWHO if (rwho_enabled) rwho_login(player, bp->connect); #endif iob_spit_file(bp, MOTD_FILE); if (iswiz(player)) iob_spit_file(bp, WIZN_FILE); check_last(player); check_news(player); if (set_str_elt(player, SITE, bp->hostname) == -1) { warning("dispatch", "couldn't set SITE."); } stamp(player); #ifdef RESTRICT_BOT if (!isrobot(player) && (bp->outputprefix || bp->outputsuffix)) { iobput(bp, "Your OUTPUTPREFIX and OUTPUTSUFFIX strings have been cleared.\r\n"); if (bp->outputprefix) { ty_free(bp->outputprefix); bp->outputprefix = (char *) 0; } if (bp->outputsuffix) { ty_free(bp->outputsuffix); bp->outputsuffix = (char *) 0; } } #endif /* RESTRICT_BOT */ do_look(player, (char *) 0); #ifdef PDX } #endif /* PDX */ } } else if (stringprefix(cmd, "create")) { #ifdef PDX if (mud_fullPDX(-1)) { iobput(bp, "Sorry, ThreadWay is currently full. Do try again later.\r\n"); } else { #endif /* PDX */ #ifndef REGISTRATION #ifdef SUPPORT_LOCKOUT { char *msg; if (check_lockout_list(bp->site, LOCK_REGISTER, &msg)) { if (msg && *msg) { iobput(bp, msg); } else { if (iob_spit_file(bp, REGISTER_FILE) == -1) iobput(bp, REGISTER_MSG); } iobflush(bp); break; } } #endif player = create_player(p, -1); if (player == -1) { iobput(bp, BAD_CREATE); } else { bp->typ = INPUT_PLAY; bp->player = player; newwho(bp); log_create(bp); #ifdef SUPPORT_RWHO if (rwho_enabled) rwho_login(player, bp->connect); #endif iob_spit_file(bp, MOTD_FILE); iob_spit_file(bp, NEWP_FILE); check_news(player); if (set_str_elt(player, SITE, bp->hostname) == -1) { warning("dispatch", "couldn't set SITE."); } stamp(player); #ifdef RESTRICT_BOT if (!isrobot(player) && (bp->outputprefix || bp->outputsuffix)) { iobput(bp, "Your OUTPUTPREFIX and OUTPUTSUFFIX strings have been cleared.\r\n"); if (bp->outputprefix) { ty_free(bp->outputprefix); bp->outputprefix = (char *) 0; } if (bp->outputsuffix) { ty_free(bp->outputsuffix); bp->outputsuffix = (char *) 0; } } #endif /* RESTRICT_BOT */ do_look(player, (char *) 0); } #else /* REGISTRATION */ if (iob_spit_file(bp, REGISTER_FILE) == -1) { iobput(bp, REGISTER_MSG); } #endif /* REGISTRATION */ #ifdef PDX } #endif /* PDX */ } else { /* Re-greet this idiot. */ greet(bp); } break; case INPUT_PLAY: /* check for OUTPUT*X commands first */ if (!strncmp(cmd, PREFIX_COMMAND, strlen(PREFIX_COMMAND))) { #ifdef RESTRICT_BOT if (!isrobot(bp->player)) iobput(bp, RESTRICT_BOT_MSG); else set_output_str(bp, cmd + strlen(PREFIX_COMMAND), PREFIX_CODE); #else set_output_str(bp, cmd + strlen(PREFIX_COMMAND), PREFIX_CODE); #endif break; } if (!strncmp(cmd, SUFFIX_COMMAND, strlen(SUFFIX_COMMAND))) { #ifdef RESTRICT_BOT if (!isrobot(bp->player)) iobput(bp, RESTRICT_BOT_MSG); else set_output_str(bp, cmd + strlen(SUFFIX_COMMAND), SUFFIX_CODE); #else set_output_str(bp, cmd + strlen(SUFFIX_COMMAND), SUFFIX_CODE); #endif break; } if (bp->outputprefix) { iobput(bp, bp->outputprefix); iobput(bp, "\r\n"); } handle_cmd(bp->player, cmd); if (bp->outputsuffix) { iobput(bp, bp->outputsuffix); iobput(bp, "\r\n"); } break; } } /* OK We banged into the end of the buffer. */ if (cmd != buff) { /* Is there anything left in the buffer? */ bp->inputcnt = buff - cmd; bcopy(cmd, bp->inputbuf, bp->inputcnt); } else { bp->inputcnt = 0; } } static void set_output_str(bp, string, code) Iob *bp; char *string; int code; { while (*string && isspace(*string) && isascii(*string)) string++; if (code == PREFIX_CODE) { if (!string || !*string) { ty_free(bp->outputprefix); bp->outputprefix = 0; } else { ty_free(bp->outputprefix); bp->outputprefix = (char *) ty_malloc(strlen(string) + 1, "set_output_str"); if (bp->outputprefix) strcpy(bp->outputprefix, string); } } if (code == SUFFIX_CODE) { if (!string || !*string) { ty_free(bp->outputsuffix); bp->outputsuffix = 0; } else { ty_free(bp->outputsuffix); bp->outputsuffix = (char *) ty_malloc(strlen(string) + 1, "set_output_str"); if (bp->outputsuffix) strcpy(bp->outputsuffix, string); } } } void newwho(bp) Iob *bp; { if (wholist == (Iob *) 0) { wholist = bp->whofwd = bp->whoback = bp; } else { bp->whoback = wholist; bp->whofwd = wholist->whofwd; (wholist->whofwd)->whoback = bp; wholist->whofwd = bp; } } void dropwho(bp) Iob *bp; { if (bp->whofwd == bp) { wholist = (Iob *) 0; } else { if (wholist == bp) { wholist = bp->whoback; } (bp->whoback)->whofwd = bp->whofwd; (bp->whofwd)->whoback = bp->whoback; } } void greet(bp) Iob *bp; { if (bp->typ == INPUT_NEWCONN) { if (iob_spit_file(bp, GREET_FILE) == -1) { iobput(bp, DEFAULT_GREET); } } } int iob_spit_file(bp, filename) Iob *bp; char *filename; { FILE *in; char filebuff[128]; if ((in = fopen(filename, "r")) == NULL) { return (-1); } while (fgets(filebuff, 127, in) != NULL) { fix_newline(filebuff); iobput(bp, filebuff); } (void) fclose(in); return (1); } /* * Matches against the list of active players. * * returns -1 if no match, -2 if ambiguous, or the object number. * * This lives here, 'cause it needs to screw around with the network's notion of * the who list. * */ int match_who(name) char *name; { Iob *curr; char *player_name; curr = wholist; do { if (get_str_elt(curr->player, NAME, &player_name) == -1) { warning("match_who", "bad name reference on WHO list"); return (-1); } if (player_name == (char *) 0) { warning("match_who", "active player with NULL name"); curr = curr->whofwd; continue; } if (!strcasecmp(name, player_name)) return (curr->player); curr = curr->whofwd; } while (curr != wholist); return (-1); } /* * Display the WHO list to a bp. */ void do_wholist(bp, arg) Iob *bp; char *arg; { Iob *who; char *whonm, idletype; char work2[82]; char work3[14]; char line[82]; int g, h, i, j, k, total = 0; int wizard = 0; #ifdef REVERSED_WHO Iob *first; #endif /* REVERSED_WHO */ while (arg[0] == ' ') arg++; #ifdef WIZWHOALL if (bp->typ == INPUT_PLAY) wizard = 1; #else /* WIZWHOALL */ if ((bp->typ == INPUT_PLAY) && iswiz(bp->player)) wizard = 1; #endif /* WIZWHOALL */ (void) sprintf(line, "Player Name On For Idle %s\r\n", (poll_str && *poll_str) ? poll_str : "Doing"); iobput(bp, line); if ((who = wholist) == (Iob *) 0) goto uptime; #ifdef REVERSED_WHO first = who = who->whofwd; #endif /* REVERSED_WHO */ do { if (isdark(who->player) && !wizard) goto skipthisline; total++; if (get_str_elt(who->player, NAME, &whonm) != -1) { (void) strcpy(work2, whonm); } else (void) strcpy(work2, "???"); if (strlen(arg) && !stringprefix(arg, work2)) goto skipthisline; if (wizard) { sprintf(work3, "(#%d%s%s%s%s)", who->player, (iswiz(who->player)) ? "W" : "", (isdark(who->player)) ? "D" : "", (issticky(who->player)) ? "S" : "", (isguest(who->player)) ? "G" : ""); strcat(work2, work3); } g = (int) (last.tv_sec - who->connect); h = g / 86400; g %= 86400; i = g / 3600; j = g / 60 % 60; k = (int) (last.tv_sec - who->lastcmd); idletype = 's'; if (k > 59) { idletype = 'm'; k /= 60; if (k > 59) { idletype = 'h'; k /= 60; if (k > 23) { idletype = 'd'; k /= 24; } } } if (h) sprintf(line, "%-19s %dd %02d:%02d %2d%c", work2, h, i, j, k, idletype); else sprintf(line, "%-22s %02d:%02d %2d%c", work2, i, j, k, idletype); if (who->doing) { strcat(line, " "); strcat(line, who->doing); } strcat(line, "\r\n"); iobput(bp, line); skipthisline: #ifdef REVERSED_WHO who = who->whofwd; } while (who != first); #else /* REVERSED_WHO */ who = who->whoback; } while (who != wholist); #endif /* REVERSED_WHO */ uptime: if (total) { #ifdef PDX sprintf(line, "%d (of %d) user%s %s connected. ", total, max_logins, #else sprintf(line, "%d user%s %s connected. ", total, #endif /* PDX */ (total == 1) ? "" : "s", (total == 1) ? "is" : "are"); iobput(bp, line); } else iobput(bp, "No users are connected. "); h = last.tv_sec - startingtimeofmud; j = h / 3600 % 24; k = h / 60 % 60; i = h / 86400; if (i) sprintf(line, "Uptime: %dd, %02d:%02d.\r\n", i, j, k); else sprintf(line, "Uptime: %02d:%02d.\r\n", j, k); iobput(bp, line); } void do_where(bp, arg) Iob *bp; char *arg; { Iob *who; char *whonm, *p; char work2[82]; char work3[82]; char line[82]; int where, wizard = 0; #ifdef REVERSED_WHO Iob *first; #endif /* REVERSED_WHO */ if (strlen(arg)) while (arg[0] == ' ') arg++; #ifdef WIZWHOALL wizard = 1; #else /* WIZWHOALL */ if (bp->typ == INPUT_PLAY && iswiz(bp->player) && arg[0] != '-') wizard = 1; #endif /* WIZWHOALL */ if (arg[0] == '-') arg++; iobput(bp, "Player Name Location"); iobput(bp, wizard ? " Site\r\n" : "\r\n"); if ((who = wholist) == (Iob *) 0) { iobput(bp, "No users are connected.\r\n"); return; } #ifdef REVERSED_WHO first = who = who->whofwd; #endif /* REVERSED_WHO */ do { if (!wizard && isdark(who->player)) goto skipthisline2; if (get_str_elt(who->player, NAME, &whonm) != -1) { (void) strcpy(work2, whonm); } else (void) strcpy(work2, "???"); if (strlen(arg) && !stringprefix(arg, work2)) goto skipthisline2; if (wizard) { sprintf(work3, "(#%d%s%s%s)", who->player, (iswiz(who->player)) ? "W" : "", (isdark(who->player)) ? "D" : "", (issticky(who->player)) ? "S" : ""); strcat(work2, work3); } if (!wizard) { if (!issticky(who->player)) { if (get_int_elt(who->player, LOC, &where) == -1) where = -1; if (where != -1) { if (get_str_elt(where, NAME, &p) != -1) { if (p == NULL) p = "???"; if (strlen(p) > 50) { strncpy(work3, p, 50); work3[49] = 0; } else strcpy(work3, p); if ((isjumpok(where) || (bp->typ == INPUT_PLAY && controls(bp->player, where))) && strlen(work3) < 45) { sprintf(work3 + strlen(work3), "(#%d)", where); } } } else strcpy(work3, "???"); } else work3[0] = 0; sprintf(line, "%-19s %s", work2, work3); } else { if (get_int_elt(who->player, LOC, &where) == -1) where = -1; sprintf(work3, "(#%d)", where); sprintf(line, "%-19s %8s %s", work2, work3, who->hostname); } strcat(line, "\r\n"); iobput(bp, line); skipthisline2: #ifdef REVERSED_WHO who = who->whofwd; } while (who != first); #else /* REVERSED_WHO */ who = who->whoback; } while (who != wholist); #endif /* REVERSED_WHO */ } void log_disconnect(bp) Iob *bp; { char *name; if (bp->typ == INPUT_PLAY) { if (get_str_elt(bp->player, NAME, &name) != -1) { log_status("DISCONNECT: %s(#%d) on fd %d.\n", name, bp->player, bp->fd); } else log_status("DISCONNECT: ???(#%d) on fd %d.\n", bp->player, bp->fd); } else log_status("DISCONNECT: fd %d never connected.\n", bp->fd); } void log_connect(bp) Iob *bp; { char *name; if (bp->typ == INPUT_PLAY) { if (get_str_elt(bp->player, NAME, &name) != -1) { log_status("CONNECTED: %s(#%d) on fd %d.\n", name, bp->player, bp->fd); } else log_status("CONNECTED: ???(#%d) on fd %d.\n", bp->player, bp->fd); } else log_status("CONNECTION: fd %d connected from [%s].\n", bp->fd, bp->hostname); } static void log_create(bp) Iob *bp; { char *name; if (get_str_elt(bp->player, NAME, &name) != -1) { log_status("CREATED: %s(#%d) on fd %d.\n", name, bp->player, bp->fd); } else log_status("CREATED: ???(#%d) on fd %d.\n", bp->player, bp->fd); } static void log_badconnect(s, bp) char *s; Iob *bp; { char buf[65]; char *p, *q; for (p = s, q = buf; p && *p && *p != ' ' && (q - buf) < 64; *q++ = *p++); *q = '\0'; log_status("FAILED CONNECT: fd %d failed connection to \"%s\".\n", bp->fd, buf); } #ifdef SUPPORT_RWHO void rwho_daemon() { Iob *cur = wholist; rwhocli_pingalive(); if (wholist != (Iob *) 0) { do { rwho_login(cur->player, cur->connect); cur = cur->whoback; } while (cur != wholist); } } #endif #ifdef PDX int mud_fullPDX(player) int player; { Iob *cur = wholist; int total = 0; extern int max_logins; if (player != -1 && iswiz(player)) return (0); if (wholist != (Iob *) 0) { do { #ifndef HOSTNAMES if (strncmp(cur->hostname, "131.252", 7) && strcmp(cur->hostname, "127.0.0.1") && strncmp(cur->hostname, "128.193", 7)) #else if ((domaincmp(cur->hostname, "pdx.edu", 2) || domaincmp(cur->hostname, "cs.pdx.edu", 1)) && (domaincmp(cur->hostname, "CS.ORST.EDU", 1) || domaincmp(cur->hostname, "ORST.EDU", 1)) && strncmp(cur->hostname, "localhost", 9)) #endif total++; cur = cur->whofwd; } while (cur != wholist); } return (total >= max_logins); } #endif int match_active_player(arg) char *arg; { Iob *who; Iob *first; int number = 0; int player; char *name; who = wholist; first = who = who->whofwd; do { if (get_str_elt(who->player, NAME, &name) == -1) { warning("match_active_player", "bad player name"); return (-1); } if (strlen(arg) && stringprefix(arg, name)) { if (strlen(arg) == strlen(name)) return (who->player); number++; if (number == 1) { player = who->player; } else { if (who->player != player) return (-2); else number = 1; } } who = who->whofwd; } while (who != first); if (number) return (player); else return (-1); } #ifdef SUPPORT_LOCKOUT int check_lockout_list(site, flag, msg) long site; int flag; char **msg; { FILE *file; int a, b, c, d; long lockedsite; int lockedout = FALSE; register int lockflag; char buf[512]; char *p; if ((file = fopen(LOCKOUT_FILE, "r")) == NULL) { log_error("check_lockout_list: %s does not exist", LOCKOUT_FILE); return (lockedout); } while (!lockedout && fgets(buf, 511, file) != NULL) { a = b = c = d = 0; p = buf; lockflag = LOCK_REGISTER; switch (buf[0]) { case 'R': lockflag = LOCK_REGISTER; for (p++; *p && isspace(*p); p++); break; case 'L': lockflag = LOCK_DISCONNECT; for (p++; *p && isspace(*p); p++); break; } if (*p && *p != '#') { a = atoi(p); while (*p != '.') p++; p++; b = atoi(p); while (*p != '.') p++; p++; c = atoi(p); while (*p != '.') p++; p++; d = atoi(p); lockedsite = ((a & 0xff) << 24) + ((b & 0xff) << 16) + ((c & 0xff) << 8) + (d & 0xff); if ((lockedsite == site) && (flag == lockflag)) { lockedout = TRUE; for (; *p && !isspace(*p); p++); for (; *p && isspace(*p); p++); fix_newline(p); *msg = p; } } } fclose(file); return (lockedout); } #endif voidfunc do_doing(player, who, str) int player; char *who, *str; { Iob *curr; int person; if (str && *str) { if ((person = resolve_player(player, who, iswiz(player))) == -1 || person == -2) { notify_player(player, "No such player.\r\n"); return; } if (!iswiz(player) && person != player) { notify_player(player, "You can't do that.\r\n"); return; } } else { person = player; str = who; } if (!isalive(person)) { /* @forse won't crash me */ notify_player(player, "That person is not connected.\r\n"); return; } if (str && *str && strlen(str) > DOING_MAX) str[DOING_MAX - 1] = 0; curr = wholist; do { if (curr->player != person) goto nextone; if (curr->doing) { ty_free(curr->doing); curr->doing = 0; } if (str && *str) { curr->doing = ty_malloc(strlen(str) + 1, "do_doing"); (void) strcpy(curr->doing, str); } nextone: curr = curr->whofwd; } while (curr != wholist); notify_player(player, (person == player) ? "Set. Have fun doing it.\r\n" : "Set.\r\n"); } voidfunc do_poll(player, str) int player; char *str; { extern char cmdwork[]; char *name; if (!iswiz(player)) { notify_player(player, "Having delusions of grandeur, are we?\r\n"); return; } if (!str || !*str) str = "Doing"; if (strlen(str) > DOING_MAX) str[DOING_MAX - 1] = 0; if (poll_str) ty_free(poll_str); poll_str = ty_malloc(strlen(str) + 1, "do_poll"); (void) strcpy(poll_str, str); notify_player(player, "Poll set.\r\n"); if (get_str_elt(player, NAME, &name) != -1) { (void) sprintf(cmdwork, "* %s has added a new poll. *\r\n", name); notify_wall(cmdwork); } }