#ifdef SYSV #include <sys/file.h> #endif #include <errno.h> #include <stdio.h> #include <ctype.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/wait.h> #include <netinet/in.h> #include <netdb.h> #include <string.h> #include <sys/time.h> #include <fcntl.h> #include <signal.h> #include <setjmp.h> #include <stdlib.h> #include "structs.h" #include "utils.h" #include "comm.h" #include "interpreter.h" #include "handler.h" #include "db.h" #define DFLT_PORT 2150 /* default port */ #define MAX_NAME_LENGTH 12 #define MAX_HOSTNAME 256 #define OPT_USEC 100000 #define MAXFDALLOWED 200 #define MAXOCLOCK 500 extern int errno; extern struct room_data *world; extern int top_of_world; extern struct time_info_data time_info; extern char help[]; extern int reboottime; /* local globals */ struct descriptor_data *descriptor_list, *next_to_process; jmp_buf env; int s; int slow_death = 0; int shutdowngame = 0; int shutdownwarn = 0; int maxdesc, avail_descs; int tics = 0; int newsflashflag = 0; int nonewplayers = 0; int nonewconnect = 0; int nostealflag = 1; int nokillflag = 1; int noshoutflag = 0; int mischance = 20; int hitchance = 80; int bobflag=0; int jokecount=10; int timeoflastconnect = 0; int pcdeaths=0,mobdeaths=0; int grand_total = 0; int melsnumber = -1; int bytetotal[256]; struct char_data *out_char; /* SLUG_CHANGE 11-17-96 */ int baddoms; char baddomain[BADDOMS][BADSTRLEN]; int newbeedoms; char newbeedomain[BADDOMS][BADSTRLEN]; char *bobname; struct descriptor_data *xo; int freq_ct[300]; void logsig(int sig); void hupsig(int sig); void shutdown_request(int sig); void checkpointing(int sig); int get_from_q(struct txt_q *queue, char *dest); /* write_to_q is in comm.h for the macro */ int run_the_game(int port); int game_loop(int s); int init_socket(int port); int new_connection(int s); int new_descriptor(int s); int process_output(struct descriptor_data *t); int process_input(struct descriptor_data *t); void close_sockets(int s); void close_socket(struct descriptor_data *d); struct timeval timediff(struct timeval *a, struct timeval *b); void flush_queues(struct descriptor_data *d); void nonblock(int s); void parse_name(struct descriptor_data *desc, char *arg); void freaky(struct descriptor_data *d); /* extern fcnts */ struct char_data *make_char(char *name, struct descriptor_data *desc); void boot_db(void); void zone_update(void); void affect_update( void ); /* In spells.c */ void point_update( void ); /* In limits.c */ void free_char(struct char_data *ch); void log(char *str); void mobile_activity(void); void string_add(struct descriptor_data *d, char *str); void perform_violence(void); void stop_fighting(struct char_data *ch); void show_string(struct descriptor_data *d, char *input); void save_char(struct char_data *ch, sh_int load_room); /* ********************************************************************* * main game loop and related stuff * ********************************************************************* */ int sigct=0; int main(int argc, char **argv) { int i,port; char buf[512]; char *dir; port = DFLT_PORT; dir = DFLT_DIR; newbeedoms=0; baddoms=1; strcpy(baddomain[0],"141.109.20.61"); if (argc > 1) { if (!isdigit(*argv[1])) { fprintf(stderr, "Usage: %s [ port # ]\n", argv[0]); exit(0); } else if ((port = atoi(argv[1])) <= 1024) { fprintf(stderr,"Illegal port #\n"); exit(0); } } bobname=(char *)strdup("Bob"); if (chdir(dir) < 0) { perror("chdir"); exit(0); } for(i=0;i<256;i++) bytetotal[i]=0; reboottime=time(0); srand48(reboottime); sprintf(buf,"Boottime = %d",reboottime); log(buf); run_the_game(port); return(0); } int run_the_game(int port) { struct descriptor_data *point,*next_point; void signal_setup(void); void saveallplayers(); descriptor_list = NULL; signal_setup(); do { s = init_socket(port); if(s < 0) exit(0); } while(s < 0); boot_db(); log("Entering game loop."); game_loop(s); saveallplayers(); close_sockets(s); log("Normal termination of game."); } void saveallplayers() { struct descriptor_data *pt, *npt; for (pt = descriptor_list; pt; pt = npt) { npt = pt->next; if(pt->connected == CON_PLYNG) { if(pt->character) stash_char(pt->character,0); } else { if(pt->character){ if(pt->character->specials.timer > 20){ log("Tried auto-closing a non-playing descriptor."); close_socket(pt); } } } } } fd_set input_set, output_set, exc_set; int game_loop(int s) { int tmp_room, old_len; struct timeval last_time, now, timespent, timeout, null_time; static struct timeval opt_time; char comm[MAX_INPUT_LENGTH]; struct descriptor_data *t, *point, *next_point; int pulse = 0, testmask, mask, xoclock = 0, flag; char prmpt[64]; null_time.tv_sec = 0; null_time.tv_usec = 0; opt_time.tv_usec = OPT_USEC; /* Init time values */ opt_time.tv_sec = 0; gettimeofday(&last_time, (struct timezone *) 0); maxdesc = s; avail_descs = MAXFDALLOWED; /* mask = sigmask(SIGUSR1) | sigmask(SIGUSR2) | sigmask(SIGINT) | sigmask(SIGBUS ) | sigmask(SIGSEGV) | sigmask(SIGTRAP) | sigmask(SIGPIPE) | sigmask(SIGALRM) | sigmask(SIGTERM) | sigmask(SIGURG ) | sigmask(SIGXCPU) | sigmask(SIGHUP); testmask = sigmask(SIGBUS) | sigmask(SIGSEGV); */ /* Main loop */ while(!shutdowngame) { setjmp(env); if(shutdowngame) continue; if(shutdownwarn){ if(shutdownwarn==1) shutdowngame=1; else --shutdownwarn; } /* Check what's happening out there */ FD_ZERO(&input_set); FD_ZERO(&output_set); FD_ZERO(&exc_set); FD_SET(s, &input_set); for (point = descriptor_list; point; point = point->next) { FD_SET(point->descriptor, &input_set); FD_SET(point->descriptor, &exc_set); FD_SET(point->descriptor, &output_set); } /* check out the time */ gettimeofday(&now, (struct timezone *) 0); timespent = timediff(&now, &last_time); timeout = timediff(&opt_time, ×pent); last_time.tv_sec = now.tv_sec + timeout.tv_sec; last_time.tv_usec = now.tv_usec + timeout.tv_usec; if (last_time.tv_usec >= 1000000) { last_time.tv_usec -= 1000000; last_time.tv_sec++; } extern int sigsetmask (int __mask) __THROW __attribute_deprecated__; if(timeout.tv_usec) if(select(0, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, &timeout) < 0) { perror("Select sleep"); exit(1); } if(select(maxdesc+1, &input_set, &output_set, &exc_set, &null_time) < 0) { perror("Select poll"); exit(0); } extern int sigsetmask (int __mask) __THROW __attribute_deprecated__; if(!nonewconnect) if(FD_ISSET(s, &input_set)) new_descriptor(s); for(point = descriptor_list; point; point = next_point) { next_point = point->next; if(FD_ISSET(point->descriptor, &exc_set)) { freaky(point); FD_CLR(point->descriptor, &input_set); FD_CLR(point->descriptor, &output_set); } } for (point = descriptor_list; point; point = next_point) { next_point = point->next; if (FD_ISSET(point->descriptor, &input_set)) if (process_input(point) < 0) { FD_CLR(point->descriptor, &input_set); FD_CLR(point->descriptor, &output_set); if (point->connected == CON_PLYNG) { stash_char(point->character,0); } close_socket(point); } } /* process_commands; */ if(sigct < 10) for (point = descriptor_list; point; point = next_to_process) { next_to_process = point->next; if ((--(point->wait) <= 0) && get_from_q(&point->input, comm)) { if(point->character && (point->connected == CON_PLYNG) && (point->character->specials.was_in_room != NOWHERE)) { if (point->character->in_room != NOWHERE) char_from_room(point->character); char_to_room(point->character, point->character->specials.was_in_room); point->character->specials.was_in_room = NOWHERE; act("$n has returned.", TRUE, point->character, 0, 0, TO_ROOM); } point->wait = 1; if (point->character) point->character->specials.timer = 0; point->prompt_mode = 1; if (point->str) string_add(point, comm); else if (!point->connected) if (point->showstr_point) show_string(point, comm); else { point->wait += command_interpreter(point->character, comm); ++point->ncmds; } else nanny(point, comm); } } for (point = descriptor_list; point; point = next_point) { next_point = point->next; if (FD_ISSET(point->descriptor, &exc_set)) { freaky(point); FD_CLR(point->descriptor, &input_set); FD_CLR(point->descriptor, &output_set); } } for (point = descriptor_list; point; point = next_point) { next_point = point->next; xo=point; if (FD_ISSET(point->descriptor, &output_set) && point->output.head) if((flag=process_output(point)) < 0){ FD_CLR(point->descriptor, &input_set); FD_CLR(point->descriptor, &output_set); if (point->connected == CON_PLYNG) { stash_char(point->character,0); } close_socket(point); } else point->prompt_mode = flag; } /* give the people some prompts */ ++xoclock; if (xoclock == MAXOCLOCK) { xoclock=0; } for (point = descriptor_list; point; point = point->next){ if((!point->connected) && (!point->original) && (GET_LEVEL(point->character)<IMO) && (point->descriptor==xoclock)){ save_char(point->character,NOWHERE); stash_char(point->character,0); } if (point->prompt_mode) { out_char = point->character; /* SLUG_CHANGE 11-17-96 */ if (point->str) write_to_descriptor(point->descriptor, "] "); else if (!point->connected) if (point->showstr_point) write_to_descriptor(point->descriptor, "--<< Press return >>--"); else { if(GET_LEVEL(point->character) < IMO){ if(point->character->specials.fighting){ sprintf(prmpt, "\[%d,%d,%d](%d) ", GET_HIT(point->character), GET_MANA(point->character), GET_MOVE(point->character), GET_HIT(point->character->specials.fighting)); } else { sprintf(prmpt, "\[%d,%d,%d] ", GET_HIT(point->character),GET_MANA(point->character), GET_MOVE(point->character)); } } else { sprintf(prmpt, "\[%d] ", world[point->character->in_room].number); } write_to_descriptor(point->descriptor, prmpt); } point->prompt_mode = 0; } } pulse++; if (!(pulse % PULSE_ZONE)) zone_update(); if (!(pulse % PULSE_MOBILE)) mobile_activity(); if (!(pulse % PULSE_VIOLENCE)) perform_violence(); if (!(pulse % SECS_PER_MUD_HOUR)){ weather_and_time(1); affect_update(); point_update(); } if (pulse >= 2400) { pulse = 0; /* zapper(); */ } tics++; } } /* zapper shuts down the game on Mon-Fri at 7 am EST */ zapper() { int dow,tod,t; t=time(0)-18000; dow=((t/86400)+5)%7; tod=(t%86400)/60; if(dow >= 2){ if(tod > 900) return; if(tod > 390) send_to_all("The game will shut down soon.\n\r"); if(tod >= 420){ shutdowngame=1; if(getppid() > 1) kill(getppid(),9); } } } /* ****************************************************************** * general utility stuff (for local use) * ****************************************************************** */ int get_from_q(struct txt_q *queue, char *dest) { struct txt_block *tmp; /* Q empty? */ if (!queue->head) return(0); tmp = queue->head; strcpy(dest, queue->head->text); queue->head = queue->head->next; free(tmp->text); free(tmp); return(1); } void write_to_q(char *txt, struct txt_q *queue) { struct txt_block *new; CREATE(new, struct txt_block, 1); CREATE(new->text, char, strlen(txt) + 1); strcpy(new->text, txt); if (!queue->head) { new->next = NULL; queue->head = queue->tail = new; } else { queue->tail->next = new; queue->tail = new; new->next = NULL; } } struct timeval timediff(struct timeval *a, struct timeval *b) { struct timeval rslt, tmp; tmp = *a; if ((rslt.tv_usec = tmp.tv_usec - b->tv_usec) < 0) { rslt.tv_usec += 1000000; --(tmp.tv_sec); } if ((rslt.tv_sec = tmp.tv_sec - b->tv_sec) < 0) { rslt.tv_usec = 0; rslt.tv_sec = 0; } return(rslt); } /* Empty the queues before closing connection */ void flush_queues(struct descriptor_data *d) { char dummy[MAX_STRING_LENGTH]; while (get_from_q(&d->output, dummy)); while (get_from_q(&d->input, dummy)); } /* ****************************************************************** * socket handling * ****************************************************************** */ int init_socket(int port) { int s; char *opt; char hostname[MAX_HOSTNAME+1]; struct sockaddr_in sa; struct hostent *hp; struct linger ld; bzero((char *)&sa, sizeof(struct sockaddr_in)); gethostname(hostname, MAX_HOSTNAME); log(hostname); hp = gethostbyname(hostname); if (hp == NULL) { perror("gethostbyname"); exit(1); } sa.sin_family = hp->h_addrtype; sa.sin_port = htons(port); s = socket(AF_INET,SOCK_STREAM,0); if(s < 0) { perror("Init-socket"); exit(1); } if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *) &opt, sizeof(opt)) < 0){ perror ("setsockopt REUSEADDR"); exit (1); } /* ld.l_onoff = 0; ld.l_linger = 0; if (setsockopt(s, SOL_SOCKET, SO_LINGER, &ld, sizeof(ld)) < 0) { perror("setsockopt LINGER"); exit(1); } */ if (bind(s,(struct sockaddr *) &sa, sizeof(sa)) < 0) { perror("bind"); close(s); return(-1); } listen(s, 3); return(s); } int new_connection(int s) { struct sockaddr_in isa; /* struct sockaddr peer; */ int i; int t; char buf[100]; i = sizeof(isa); getsockname(s, (struct sockaddr *) &isa, &i); if ((t = accept(s, (struct sockaddr *) &isa, &i)) < 0) { return(-1); } nonblock(t); return(t); } int new_descriptor(int s) { int desc; struct descriptor_data *newd; int i,size; struct sockaddr_in sock; struct hostent *from; char buf[10]; if ((desc = new_connection(s)) < 0) return (-1); bytetotal[desc]=0; timeoflastconnect=time(0); size = sizeof(sock); if(getpeername(desc,(struct sockaddr *)&sock,&size) < 0){ *newd->host = 0; close(desc); return(-1); } else { if(unfriendly_domain((char *)inet_ntoa(sock.sin_addr),baddomain,baddoms)){ close(desc); return(-1); } } CREATE(newd, struct descriptor_data, 1); strncpy(newd->host,(char *)inet_ntoa(sock.sin_addr),16); if((maxdesc+1) >= avail_descs){ close(desc); flush_queues(newd); free((char *)newd); return(0); } else if (desc > maxdesc) maxdesc = desc; newd->ncmds = 0; newd->contime = time(0); newd->descriptor = desc; newd->connected = 1; newd->wait = 1; newd->prompt_mode = 0; *newd->buf = '\0'; newd->str = 0; newd->showstr_head = 0; newd->showstr_point = 0; *newd->last_input= '\0'; newd->output.head = NULL; newd->input.head = NULL; newd->next = descriptor_list; newd->character = 0; newd->original = 0; newd->snoop.snooping = 0; newd->snoop.snoop_by = 0; /* prepend to list */ descriptor_list = newd; SEND_TO_Q(GREETINGS, newd); if(nonewplayers){ SEND_TO_Q("WARNING:\n\r",newd); SEND_TO_Q("No NEW characters are being accepted right now.\n\r\n\r",newd); } SEND_TO_Q("By what name do you wish to be known? ", newd); return(0); } unfriendly_domain(h,list,listlen) char *h; char list[BADDOMS][BADSTRLEN]; int listlen; { int i; for(i=0;i<listlen;++i){ if(strncmp(h,list[i],strlen(list[i]))==0){ return(1); } } return(0); } int process_output(struct descriptor_data *t) { char i[MAX_STRING_LENGTH + 1]; int iter=0; out_char = t->character; /* SLUG_CHANGE 11-17-96 */ if(!t->prompt_mode && !t->connected) if (write_to_descriptor(t->descriptor, "\n\r") < 0) return(-1); while(get_from_q(&t->output, i)){ if(t->snoop.snoop_by) { write_to_q("> ",&t->snoop.snoop_by->desc->output); write_to_q(i,&t->snoop.snoop_by->desc->output); } if (write_to_descriptor(t->descriptor, i)) return(-1); } if(!t->connected && !(t->character && !IS_NPC(t->character) && IS_SET(t->character->specials.act, PLR_COMPACT))) if(write_to_descriptor(t->descriptor, "\n\r") < 0) return(-1); return(1); } #include <sys/ioctl.h> int write_to_descriptor(int desc, char *txt) { int sofar, thisround, total; int w,x,y,z; char buf[256]; static int max=0; total = strlen(txt); /* if(total > max){ sprintf(buf,"Output Max = %d.",max=total); log(buf); } */ sofar = 0; do { /* ioctl(desc,SIOCGPGRP,&w); ioctl(desc,SIOCATMARK,&x); ioctl(desc,SIOCGHIWAT,&y); ioctl(desc,SIOCGLOWAT,&z); sprintf(buf,"IOCTL: %d %d %x %x",w,x,y,z); log(buf); */ thisround = write(desc, txt + sofar, total - sofar); if (thisround < 0) { perror("Write to socket"); return(-1); } else if(thisround==0) { } else { sofar += thisround; } } while (sofar < total); grand_total += sofar; bytetotal[desc] += sofar; if(out_char) out_char->specials.outbytes += sofar; /* SLUG_CHANGE 11-17-96 */ return(0); } int process_input(struct descriptor_data *t) { int sofar, thisround, begin, squelch, i, k, flag; char tmp[MAX_STRING_LENGTH],buffer[MAX_STRING_LENGTH]; sofar = 0; flag = 0; begin = strlen(t->buf); /* Read in some stuff */ do { if ((thisround = read(t->descriptor, t->buf + begin + sofar, MAX_INPUT_LENGTH - (begin + sofar) - 1)) > 0) sofar += thisround; else if (thisround < 0) if(errno != EWOULDBLOCK) { perror("Read1 - ERROR"); return(-1); } else break; else { return(-1); } } while (!ISNEWL(*(t->buf + begin + sofar - 1))); *(t->buf + begin + sofar) = 0; /* if no newline is contained in input, return without proc'ing */ for (i = begin; !ISNEWL(*(t->buf + i)); i++) if (!*(t->buf + i)) return(0); if(t->character) /* SLUG_CHANGE 11-17-96 */ t->character->specials.inbytes += sofar; /* input contains 1 or more newlines; process the stuff */ for (i = 0, k = 0; *(t->buf + i);) { if (!ISNEWL(*(t->buf + i)) && !(flag = (k >= (MAX_INPUT_LENGTH - 2)))) if(*(t->buf + i) == '\b') /* backspace */ if (k) /* more than one char ? */ { if (*(tmp + --k) == '$') k--; i++; } else i++; /* no or just one char.. Skip backsp */ else if (isascii(*(t->buf + i)) && isprint(*(t->buf + i))) { if ((*(tmp + k) = *(t->buf + i)) == '$') *(tmp + ++k) = '$'; k++; i++; } else i++; else { *(tmp + k) = 0; if(*tmp == '!') strcpy(tmp,t->last_input); else strcpy(t->last_input,tmp); write_to_q(tmp, &t->input); if(t->snoop.snoop_by) { write_to_q("% ",&t->snoop.snoop_by->desc->output); write_to_q(tmp,&t->snoop.snoop_by->desc->output); write_to_q("\n\r",&t->snoop.snoop_by->desc->output); } if (flag) { out_char = t->character; /* SLUG_CHANGE 11-17-96 */ sprintf(buffer, "Line too long. Truncated to:\n\r%s\n\r", tmp); if (write_to_descriptor(t->descriptor, buffer) < 0) return(-1); /* skip the rest of the line */ for (; !ISNEWL(*(t->buf + i)); i++); } /* find end of entry */ for (; ISNEWL(*(t->buf + i)); i++); /* squelch the entry from the buffer */ for (squelch = 0;; squelch++) if ((*(t->buf + squelch) = *(t->buf + i + squelch)) == '\0') break; k = 0; i = 0; } } return(1); } void close_sockets(int s) { log("Closing all sockets."); shutdown(s,2); while(descriptor_list){ close_socket(descriptor_list); } close(s); } void close_socket(struct descriptor_data *d) { struct affected_type *af; struct descriptor_data *tmp; char buf[100]; close(d->descriptor); flush_queues(d); if (d->descriptor == maxdesc) --maxdesc; /* Forget snooping */ if (d->snoop.snooping) d->snoop.snooping->desc->snoop.snoop_by = 0; if (d->snoop.snoop_by) { send_to_char("Your victim is no longer among us.\n\r",d->snoop.snoop_by); d->snoop.snoop_by->desc->snoop.snooping = 0; } if (d->character){ if (d->connected == CON_PLYNG) { save_char(d->character, NOWHERE); stash_char(d->character,0); act("$n has lost $s link.", TRUE, d->character, 0, 0, TO_ROOM); sprintf(buf, "Closing link to: %s.", GET_NAME(d->character)); log(buf); d->character->desc = 0; } else { /* sprintf(buf, "Losing player: %s.", GET_NAME(d->character)); log(buf); */ free_char(d->character); } } else /* log("Losing descriptor without char."); */ if (next_to_process == d) /* to avoid crashing the process loop */ next_to_process = next_to_process->next; if (d == descriptor_list) /* this is the head of the list */ descriptor_list = descriptor_list->next; else /* This is somewhere inside the list */ { /* Locate the previous element */ for (tmp = descriptor_list; (tmp->next != d) && tmp; tmp = tmp->next); tmp->next = d->next; } if (d->showstr_head) free(d->showstr_head); free(d); } void nonblock(int s) { #ifndef NO_FNDELAY if (fcntl(s, F_SETFL, FNDELAY) == -1) { perror("Noblock"); exit(1); } #endif } /* **************************************************************** * Public routines for system-to-player-communication * **************************************************************** */ void send_to_char(char *messg, struct char_data *ch) { if(ch->desc && messg) write_to_q(messg, &ch->desc->output); } void send_to_all(char *messg) { struct descriptor_data *i; if (messg) for (i = descriptor_list; i; i = i->next) if (!i->connected) write_to_q(messg, &i->output); } void send_to_outdoor(char *messg) { struct descriptor_data *i; if (messg) for (i = descriptor_list; i; i = i->next) if (!i->connected) if (OUTSIDE(i->character)) write_to_q(messg, &i->output); } void send_to_except(char *messg, struct char_data *ch) { struct descriptor_data *i; if (messg) for (i = descriptor_list; i; i = i->next) if (ch->desc != i && !i->connected) write_to_q(messg, &i->output); } void send_to_room(char *messg, int room) { struct char_data *i; if (messg) for (i = world[room].people; i; i = i->next_in_room) if (i->desc) write_to_q(messg, &i->desc->output); } void send_to_room_except(char *messg, int room, struct char_data *ch) { struct char_data *i; if (messg) for (i = world[room].people; i; i = i->next_in_room) if (i != ch && i->desc) write_to_q(messg, &i->desc->output); } void send_to_room_except_two (char *messg, int room, struct char_data *ch1, struct char_data *ch2) { struct char_data *i; if (messg) for (i = world[room].people; i; i = i->next_in_room) if (i != ch1 && i != ch2 && i->desc) write_to_q(messg, &i->desc->output); } /* higher-level communication */ void act(char *str, int hide_invisible, struct char_data *ch, struct obj_data *obj, void *vict_obj, int type) { char *strp, *point, *i; struct char_data *to; char buf[MAX_STRING_LENGTH]; if (!str) return; if (!*str) return; if (type == TO_VICT) to = (struct char_data *) vict_obj; else if (type == TO_CHAR) to = ch; else to = world[ch->in_room].people; for (; to; to = to->next_in_room) { if (to->desc && ((to != ch) || (type == TO_CHAR)) && (CAN_SEE(to, ch) || !hide_invisible) && AWAKE(to) && !((type == TO_NOTVICT) && (to == (struct char_data *) vict_obj))) { for (strp = str, point = buf;;) if (*strp == '$') { switch (*(++strp)) { case 'n': i = PERS(ch, to); break; case 'N': i = PERS((struct char_data *) vict_obj, to); break; case 'm': i = HMHR(ch); break; case 'M': i = HMHR((struct char_data *) vict_obj); break; case 's': i = HSHR(ch); break; case 'S': i = HSHR((struct char_data *) vict_obj); break; case 'e': i = HSSH(ch); break; case 'E': i = HSSH((struct char_data *) vict_obj); break; case 'o': i = OBJN(obj, to); break; case 'O': i = OBJN((struct obj_data *) vict_obj, to); break; case 'p': i = OBJS(obj, to); break; case 'P': i = OBJS((struct obj_data *) vict_obj, to); break; case 'a': i = SANA(obj); break; case 'A': i = SANA((struct obj_data *) vict_obj); break; case 'T': i = (char *) vict_obj; break; case 'F': i = fname((char *) vict_obj); break; case '$': i = "$"; break; default: log("Illegal $-code to act():"); log(str); break; } while (*point = *(i++)) ++point; ++strp; } else if (!(*(point++) = *(strp++))) break; *(--point) = '\n'; *(++point) = '\r'; *(++point) = '\0'; if((type & 1) || !IS_SET(to->specials.act,PLR_VERYBRIEF)) write_to_q(CAP(buf), &to->desc->output); } if ((type == TO_VICT) || (type == TO_CHAR)) return; } } void freaky(struct descriptor_data *d) { char buf[128]; struct char_data *vict; int i; vict=d->original ? d->original : d->character; sprintf(buf,"Freaky: %d %d %s", d->connected, d->descriptor, vict->player.name); log(buf); stash_char(vict,0); for(i=0;i<MAX_WEAR;i++) if(vict->equipment[i]){ extract_obj(unequip_char(vict,i)); vict->equipment[i]=0; } wipe_obj(vict->carrying); vict->carrying=0; if(vict->desc) close_socket(vict->desc); extract_char(vict); } void signal_setup(void) { struct itimerval itime; struct timeval interval; signal(SIGUSR2, shutdown_request); signal(SIGALRM, logsig); /*siginterrupt(SIGHUP , 1); */ signal(SIGHUP , hupsig); /*siginterrupt(SIGINT , 1); */ signal(SIGINT , hupsig); /*siginterrupt(SIGTERM, 1); */ signal(SIGTERM, hupsig); /*siginterrupt(SIGSEGV, 1); */ signal(SIGSEGV, hupsig); /*siginterrupt(SIGBUS , 1); */ signal(SIGBUS , hupsig); /*siginterrupt(SIGPIPE, 1); */ signal(SIGPIPE, hupsig); /*siginterrupt(SIGTRAP, 1); */ signal(SIGTRAP, hupsig); return; interval.tv_sec = 900; /* 15 minutes */ interval.tv_usec = 0; itime.it_interval = interval; itime.it_value = interval; setitimer(ITIMER_VIRTUAL, &itime, 0); signal(SIGVTALRM, checkpointing); } void checkpointing(int sig) { extern int tics; if (!tics) { log("CHECKPOINT shutdown: tics not updated"); abort(); } else tics = 0; log("checkpointing"); exit(0); } void shutdown_request(int sig) { send_to_all("Shut down signal has been received.\n\r"); log("Received USR2 - shutdown request"); shutdowngame = 1; } /* kick out players etc */ void hupsig(int sig) { char ss[MAX_STRING_LENGTH]; struct descriptor_data *tmp, *point; signal(sig,hupsig); sigct++; sprintf(ss,"SIG(%d,%d): %s %s", sigct,sig,xo->character->player.name,xo->host); --GET_INT(xo->character); log(ss); if(sigct > 3) exit(0); if(sigct > 1) shutdowngame = 100; longjmp(env,sigct); } void logsig(int sig) { log("Signal received. Ignoring."); }