From bacchus.pa.dec.com!decwrl!uunet!zephyr.ens.tek.com!tekred!saab!billr Sat Aug 11 12:18:52 PDT 1990 Article 1056 of comp.sources.games: Path: bacchus.pa.dec.com!decwrl!uunet!zephyr.ens.tek.com!tekred!saab!billr From: billr@saab.CNA.TEK.COM (Bill Randle) Newsgroups: comp.sources.games Subject: v11i021: tinymud2 - user-extendible multi-user adventure (v1.5.4), xenix_diffs Message-ID: <6123@tekred.CNA.TEK.COM> Date: 10 Aug 90 00:03:29 GMT Sender: news@tekred.CNA.TEK.COM Lines: 1764 Approved: billr@saab.CNA.TEK.COM Submitted-by: Stu Heiss Posting-number: Volume 11, Issue 21 Archive-name: tinymud2/xenix_diffs Patch-To: tinymud2: Volume 11, Issue 5-14 [Not runnning Xenix, I haven't tried these patches.... -br] [[Attached below is what's needed to bring up tinymud on xenix using fifos instead of sockets for server/client communication. The bulk of this is fifoiface.c which replaces oldinterface.c. There are some minor diffs to game.c, Makefile, and a few missing routines. A startup for the server is included as well as a client which is a small shell script. You are, of course, limmited to one machine, but you can have a number of people playing. Have fun.]] #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # xenix.diffs # rename.c # index.c # random.c # fifoiface.c # tinymud.sh # restart # This archive created: Wed Aug 8 14:51:35 1990 # By: stu (JPUSA - Chicago, IL) export PATH; PATH=/bin:/usr/bin:$PATH echo shar: "extracting 'xenix.diffs'" '(7297 characters)' if test -f 'xenix.diffs' then echo shar: "will not over-write existing file 'xenix.diffs'" else sed 's/^X//' << \SHAR_EOFxenix.diffs > 'xenix.diffs' XRCS file: RCS/Makefile,v Xretrieving revision 1.1 Xdiff -c -r1.1 Makefile X*** /tmp/,RCSt1a08638 Wed Aug 8 14:48:47 1990 X--- Makefile Wed Aug 8 14:46:29 1990 X*************** X*** 8,15 X # X X # GCC: X! #CC=gcc X! #OPTIM= -g -W -Wreturn-type -Wunused -Wcomment -Wwrite-strings X X # Systems with 'cc' built from GCC (IBM RT, NeXT): X CC=cc X X--- 8,16 ----- X # X X # GCC: X! CC=gcc X! OPTIM= -g -W -Wreturn-type -Wunused -Wcomment -Wwrite-strings X! OPTIM= -W -Wreturn-type -Wunused -Wcomment -Wwrite-strings X X # Systems with 'cc' built from GCC (IBM RT, NeXT): X #CC=cc X*************** X*** 12,19 X #OPTIM= -g -W -Wreturn-type -Wunused -Wcomment -Wwrite-strings X X # Systems with 'cc' built from GCC (IBM RT, NeXT): X! CC=cc X! OPTIM=-g X X # Dec 3100 C compiler X #CC=cc X X--- 13,20 ----- X OPTIM= -W -Wreturn-type -Wunused -Wcomment -Wwrite-strings X X # Systems with 'cc' built from GCC (IBM RT, NeXT): X! #CC=cc X! #OPTIM=-g X X # Dec 3100 C compiler X #CC=cc X*************** X*** 71,77 X # -DGOD_ONLY_PCREATE -DROBOT_MODE -DRECYCLE -DNOFAKES \ X # -DTINYHELL X X! DEFS= -DGOD_PRIV -DCOMPRESS -DQUIET_WHISPER -DGENDER -DHOST_NAME \ X -DCONNECT_MESSAGES -DPLAYER_LIST -DDETACH -DROBOT_MODE \ X -DRECYCLE -DTINKER -DNOFAKES -DISLANDIA X X X--- 72,78 ----- X # -DGOD_ONLY_PCREATE -DROBOT_MODE -DRECYCLE -DNOFAKES \ X # -DTINYHELL X X! DEFS= -DGOD_PRIV -DCOMPRESS -DQUIET_WHISPER -DGENDER -UHOST_NAME \ X -DCONNECT_MESSAGES -DPLAYER_LIST -DDETACH -DROBOT_MODE \ X -DRECYCLE -DTINKER -DNOFAKES -UISLANDIA -DDEBUG X X*************** X*** 73,79 X X DEFS= -DGOD_PRIV -DCOMPRESS -DQUIET_WHISPER -DGENDER -DHOST_NAME \ X -DCONNECT_MESSAGES -DPLAYER_LIST -DDETACH -DROBOT_MODE \ X! -DRECYCLE -DTINKER -DNOFAKES -DISLANDIA X X CFLAGS= $(OPTIM) $(DEFS) X X X--- 74,80 ----- X X DEFS= -DGOD_PRIV -DCOMPRESS -DQUIET_WHISPER -DGENDER -UHOST_NAME \ X -DCONNECT_MESSAGES -DPLAYER_LIST -DDETACH -DROBOT_MODE \ X! -DRECYCLE -DTINKER -DNOFAKES -UISLANDIA -DDEBUG X X CFLAGS= $(OPTIM) $(DEFS) X X*************** X*** 78,85 X CFLAGS= $(OPTIM) $(DEFS) X X # Everything needed to use db.c X! DBFILES= db.c compress.c player_list.c stringutil.c X! DBOFILES= db.o compress.o player_list.o stringutil.o X X # Everything except interface.c --- allows for multiple interfaces X CFILES= create.c game.c help.c look.c match.c move.c player.c predicates.c \ X X--- 79,86 ----- X CFLAGS= $(OPTIM) $(DEFS) X X # Everything needed to use db.c X! DBFILES= db.c compress.c player_list.c stringutil.c random.c X! DBOFILES= db.o compress.o player_list.o stringutil.o random.o X X # Everything except interface.c --- allows for multiple interfaces X CFILES= create.c game.c help.c look.c match.c move.c player.c predicates.c \ X*************** X*** 84,90 X # Everything except interface.c --- allows for multiple interfaces X CFILES= create.c game.c help.c look.c match.c move.c player.c predicates.c \ X rob.c set.c speech.c utils.c wiz.c game.c \ X! boolexp.c unparse.c conc.c oldinterface.c $(DBFILES) X X # .o versions of above X OFILES= create.o game.o help.o look.o match.o move.o player.o predicates.o \ X X--- 85,91 ----- X # Everything except interface.c --- allows for multiple interfaces X CFILES= create.c game.c help.c look.c match.c move.c player.c predicates.c \ X rob.c set.c speech.c utils.c wiz.c game.c \ X! boolexp.c unparse.c conc.c oldinterface.c $(DBFILES) index.c rename.c X X # .o versions of above X OFILES= create.o game.o help.o look.o match.o move.o player.o predicates.o \ X*************** X*** 89,95 X # .o versions of above X OFILES= create.o game.o help.o look.o match.o move.o player.o predicates.o \ X rob.o set.o speech.o utils.o wiz.o boolexp.o \ X! unparse.o $(DBOFILES) X X # Files in the standard distribution X DISTFILES= $(CFILES) config.h db.h externs.h interface.h match.h \ X X--- 90,96 ----- X # .o versions of above X OFILES= create.o game.o help.o look.o match.o move.o player.o predicates.o \ X rob.o set.o speech.o utils.o wiz.o boolexp.o \ X! unparse.o $(DBOFILES) index.o rename.o X X # Files in the standard distribution X DISTFILES= $(CFILES) config.h db.h externs.h interface.h match.h \ X*************** X*** 108,114 X $(BINDIR)/dump $(BINDIR)/decompress $(BINDIR)/concentrate X X # paths is likely to remain broken X! all: extract sanity-check dump decompress netmud netmud.conc concentrate X X TAGS: *.c *.h X etags *.c *.h X X--- 109,115 ----- X $(BINDIR)/dump $(BINDIR)/decompress $(BINDIR)/concentrate X X # paths is likely to remain broken X! all: extract sanity-check dump decompress fifonetmud # netmud netmud.conc concentrate X X TAGS: *.c *.h X etags *.c *.h X*************** X*** 117,122 X -mv -f netmud.conc netmud.conc~ X $(CC) $(CFLAGS) -o netmud.conc interface.o $(OFILES) X X netmud: $P oldinterface.o $(OFILES) X -mv -f netmud netmud~ X $(CC) $(CFLAGS) -o netmud oldinterface.o $(OFILES) X X--- 118,126 ----- X -mv -f netmud.conc netmud.conc~ X $(CC) $(CFLAGS) -o netmud.conc interface.o $(OFILES) X X+ fifonetmud: $P fifoiface.o $(OFILES) X+ $(CC) $(CFLAGS) -o $@ fifoiface.o $(OFILES) X+ match.h: copyright.h db.h X netmud: $P oldinterface.o $(OFILES) X -mv -f netmud netmud~ X $(CC) $(CFLAGS) -o netmud oldinterface.o $(OFILES) X=================================================================== XRCS file: RCS/game.c,v Xretrieving revision 1.1 Xdiff -c -r1.1 game.c X*** /tmp/,RCSt1a08638 Wed Aug 8 14:48:48 1990 X--- game.c Tue Jul 31 13:07:17 1990 X*************** X*** 3,9 X #include X #include X #include X- #include X #include X #include X X X--- 3,8 ----- X #include X #include X #include X #include X #include X X*************** X*** 46,51 X /* should be void, but it's defined as int */ X static int alarm_handler(void) X { X alarm_triggered = 1; X if(!alarm_block) { X fork_and_dump(); X X--- 45,51 ----- X /* should be void, but it's defined as int */ X static int alarm_handler(void) X { X+ signal(SIGALRM, SIG_IGN); X alarm_triggered = 1; X if(!alarm_block) { X fork_and_dump(); X*************** X*** 50,55 X if(!alarm_block) { X fork_and_dump(); X } X return 0; X } X X X--- 50,56 ----- X if(!alarm_block) { X fork_and_dump(); X } X+ signal(SIGALRM, (void (*)) alarm_handler); X return 0; X } X X*************** X*** 164,177 X alarm(DUMP_INTERVAL); X } X X- static int reaper(void) X- { X- union wait stat; X- X- while(wait3(&stat, WNOHANG, 0) > 0); X- return 0; X- } X- X int init_game(const char *infile, const char *outfile) X { X FILE *f; X X--- 165,170 ----- X alarm(DUMP_INTERVAL); X } X X int init_game(const char *infile, const char *outfile) X { X FILE *f; X*************** X*** 194,200 X dumpfile = alloc_string(outfile); X signal(SIGALRM, (void (*)) alarm_handler); X signal(SIGHUP, (void (*)) alarm_handler); X! signal(SIGCHLD, (void (*)) reaper); X alarm_triggered = 0; X alarm(DUMP_INTERVAL); X X X--- 187,193 ----- X dumpfile = alloc_string(outfile); X signal(SIGALRM, (void (*)) alarm_handler); X signal(SIGHUP, (void (*)) alarm_handler); X! signal(SIGCLD, SIG_IGN); X alarm_triggered = 0; X alarm(DUMP_INTERVAL); X SHAR_EOFxenix.diffs if test 5002 -ne "`sum < 'xenix.diffs' | sed 's/ .*//'`" then echo shar: "possible error transmitting 'xenix.diffs'" '(sum should have been 5002)' echo shar: "trying 'sum -r'" if test 34058 -ne "`sum -r < 'xenix.diffs' | sed 's/ .*//'`" then echo shar: "probable error transmitting 'xenix.diffs'" '(sum should have been 34058)' echo shar: "trying 'wc -c'" if test 7297 -ne "`wc -c < 'xenix.diffs'`" then echo shar: "error transmitting 'xenix.diffs'" '(should have been 7297 characters)' else echo shar: "wc was ok" fi fi fi chmod 644 'xenix.diffs' fi echo shar: "extracting 'rename.c'" '(490 characters)' if test -f 'rename.c' then echo shar: "will not over-write existing file 'rename.c'" else sed 's/^X//' << \SHAR_EOFrename.c > 'rename.c' X#include Xint Xrename(old, new) Xchar *old, *new; X{ X extern int errno; X int fd1,fd2; X char buf[1024]; X int n; X (void)unlink(new); X if (link(old, new) == -1 && errno != EXDEV) X return(-1); X if((fd1=open(old,0)) == -1) X return(-1); X if((fd2=creat(new,0666)) == -1) { X close(fd1); X return(-1); X } X while((n=read(fd1,buf,sizeof buf)) > 0) { X if (write(fd2,buf,n) != n) { X close(fd1); X close(fd2); X unlink(new); X return(-1); X } X } X close(fd1); X close(fd2); X return 0; X} SHAR_EOFrename.c if test 35337 -ne "`sum < 'rename.c' | sed 's/ .*//'`" then echo shar: "possible error transmitting 'rename.c'" '(sum should have been 35337)' echo shar: "trying 'sum -r'" if test 33981 -ne "`sum -r < 'rename.c' | sed 's/ .*//'`" then echo shar: "probable error transmitting 'rename.c'" '(sum should have been 33981)' echo shar: "trying 'wc -c'" if test 490 -ne "`wc -c < 'rename.c'`" then echo shar: "error transmitting 'rename.c'" '(should have been 490 characters)' else echo shar: "wc was ok" fi fi fi chmod 644 'rename.c' fi echo shar: "extracting 'index.c'" '(80 characters)' if test -f 'index.c' then echo shar: "will not over-write existing file 'index.c'" else sed 's/^X//' << \SHAR_EOFindex.c > 'index.c' Xextern char *strchr(); Xchar *index(s,c) char *s; int c; { return strchr(s,c); } SHAR_EOFindex.c if test 6722 -ne "`sum < 'index.c' | sed 's/ .*//'`" then echo shar: "possible error transmitting 'index.c'" '(sum should have been 6722)' echo shar: "trying 'sum -r'" if test 37873 -ne "`sum -r < 'index.c' | sed 's/ .*//'`" then echo shar: "probable error transmitting 'index.c'" '(sum should have been 37873)' echo shar: "trying 'wc -c'" if test 80 -ne "`wc -c < 'index.c'`" then echo shar: "error transmitting 'index.c'" '(should have been 80 characters)' else echo shar: "wc was ok" fi fi fi chmod 644 'index.c' fi echo shar: "extracting 'random.c'" '(74 characters)' if test -f 'random.c' then echo shar: "will not over-write existing file 'random.c'" else sed 's/^X//' << \SHAR_EOFrandom.c > 'random.c' Xint random() { return rand(); } Xvoid srandom(n) unsigned n; { srand(n); } SHAR_EOFrandom.c if test 6351 -ne "`sum < 'random.c' | sed 's/ .*//'`" then echo shar: "possible error transmitting 'random.c'" '(sum should have been 6351)' echo shar: "trying 'sum -r'" if test 19983 -ne "`sum -r < 'random.c' | sed 's/ .*//'`" then echo shar: "probable error transmitting 'random.c'" '(sum should have been 19983)' echo shar: "trying 'wc -c'" if test 74 -ne "`wc -c < 'random.c'`" then echo shar: "error transmitting 'random.c'" '(should have been 74 characters)' else echo shar: "wc was ok" fi fi fi chmod 644 'random.c' fi echo shar: "extracting 'fifoiface.c'" '(27328 characters)' if test -f 'fifoiface.c' then echo shar: "will not over-write existing file 'fifoiface.c'" else sed 's/^X//' << \SHAR_EOFfifoiface.c > 'fifoiface.c' X/* X * interface for xenix - uses fifos instead of sockets X * X * The server creates a fifo called 'fiforXXX' where XXX is replaced by the default port number. X * It then listens for a request which should be an integer, typically the process id of the client, X * and then creates two fifos named 'fiforYYY' and 'fifowYYY', where YYY is the number the client wrote X * the default fifo, for i/o to the client. The client writes to 'fiforYYY' and reads 'fifowYYY'. X * Client code is supplied as the shell script 'tinymud.sh'. X */ X#include "copyright.h" X X#undef NULL X#include X#undef NULL X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X X/* */ X#define u_char unsigned char X#define u_short unsigned short X#define u_long unsigned long Xstruct in_addr { X union { X struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b; X struct { u_short s_w1,s_w2; } S_un_w; X u_long S_addr; X } S_un; X#define s_addr S_un.S_addr X}; Xstruct sockaddr_in { X short sin_family; X u_short sin_port; X struct in_addr sin_addr; X char sin_zero[8]; X}; X#define EWOULDBLOCK 35 /* Operation would block */ X X#undef NULL X#define NULL 0 X#define bzero(s,n) memset(s,'\0',n) X#define getdtablesize() FD_SETSIZE X X#include "db.h" X#include "interface.h" X#include "config.h" X Xextern int errno; Xint shutdown_flag = 0; X Xstatic const char *connect_fail = "Either that player does not exist, or has a different password.\n"; X#ifndef REGISTRATION Xstatic const char *create_fail = "Either there is already a player with that name, or that name is illegal.\n"; X#endif REGISTRATION Xstatic const char *flushed_message = "\n"; Xstatic const char *shutdown_message = "Going down - Bye\n"; X Xstruct text_block { X int nchars; X struct text_block *nxt; X char *start; X char *buf; X}; X Xstruct text_queue { X struct text_block *head; X struct text_block **tail; X}; X Xstruct descriptor_data { X int rdescriptor; X int wdescriptor; X int connected; X dbref player; X char *output_prefix; X char *output_suffix; X int output_size; X struct text_queue output; X struct text_queue input; X char *raw_input; X char *raw_input_at; X long last_time; X long connected_at; X int quota; X struct sockaddr_in address; X const char *hostname; /* 5/18/90 - Fuzzy */ X struct descriptor_data *next; X struct descriptor_data *prev; X} *descriptor_list = 0; X Xstatic int sock; Xstatic int ndescriptors = 0; X Xvoid process_commands(void); Xvoid shovechars(int port); Xvoid shutdownsock(struct descriptor_data *d); Xstruct descriptor_data *initializesock(int r, int w, struct sockaddr_in *a, X const char *hostname); Xvoid make_nonblocking(int s); Xvoid freeqs(struct descriptor_data *d); Xvoid welcome_user(struct descriptor_data *d); Xvoid do_motd(dbref); Xvoid check_connect(struct descriptor_data *d, const char *msg); Xvoid close_sockets(); Xconst char *addrout (long); Xvoid dump_users(struct descriptor_data *d, char *user); Xvoid set_signals(void); Xstruct descriptor_data *new_connection(int sock); Xvoid parse_connect (const char *msg, char *command, char *user, char *pass); Xvoid set_userstring (char **userstring, const char *command); Xint do_command (struct descriptor_data *d, char *command); Xchar *strsave (const char *s); Xint make_socket(int); Xint queue_string(struct descriptor_data *, const char *); Xint queue_write(struct descriptor_data *, const char *, int); Xint process_output(struct descriptor_data *d); Xint process_input(struct descriptor_data *d); X#ifdef CONNECT_MESSAGES Xvoid announce_connect(dbref); Xvoid announce_disconnect(dbref); X#endif CONNECT_MESSAGES Xchar *time_format_1(long); Xchar *time_format_2(long); X X/* Signal handlers */ Xint bailout (int); Xint sigshutdown (int); X#ifdef DETACH Xint logsynch (int); X#endif DETACH X Xchar *logfile = (char *)LOG_FILE; X X#define MALLOC(result, type, number) do { \ X if (!((result) = (type *) malloc ((number) * sizeof (type)))) \ X panic("Out of memory"); \ X } while (0) X X#define FREE(x) (free((void *) x)) X Xchar *fifonames[FD_SETSIZE] = {0}; X Xint shutdown (s) int s; X{ X /* writelog("shutdown %d %s\n",s,fifonames[s]?fifonames[s]:"(nil)"); */ X if (fifonames[s]) { X unlink(fifonames[s]); X free(fifonames[s]); X fifonames[s] = 0; X } X return 0; X} X#define htons(n) (n) X#define bcopy(s,t,n) memcpy(t,s,n) X Xvoid gettimeofday(tv, tz) Xstruct timeval *tv; Xstruct timezone *tz; X{ X long time(); X tv->tv_sec = time((int *)0); X} Xint select (maxd, rfds, wfds, xfds, timeout) Xint maxd; Xfd_set *rfds, *wfds, *xfds; Xstruct timeval *timeout; X{ X int maxfd,fd; X struct stat sbuf; X int sec = 0; X fd_set r, w, x; X X if (timeout) sec=timeout->tv_sec+(timeout->tv_usec+500)/1000; X r= *rfds; w= *wfds; x= *xfds; X X while(1) { X *rfds=r; *wfds=w; *xfds=x; X for(maxfd=fd=0;fd0) X ++maxfd; X else X FD_CLR(fd,rfds); X } X if(FD_ISSET(fd,wfds)) { X if (stat(fifonames[fd],&sbuf) != 0) X goto foo; X else if(sbuf.st_size<5120) X ++maxfd; X else X FD_CLR(fd,wfds); X } X } X if(maxfd > 0 || --sec < 0) break; X sleep(1); X } X return(maxfd); Xfoo: X writelog("SELECT: %s has been unlinked!\n", fifonames[fd]); X shutdown_flag = 1; X return 0; X} Xchar *inet_ntoa(l) long l; X{ X static char buf[80]; X sprintf(buf,"%d.%d.%d.%d", X (l/(256*256))%255,(l/(256*256))%255,(l/256)%255,l%255); X return buf; X} Xint fifo(port,mode) Xint port,mode; X{ X char name[80]; X int fd = -1; X int cmask; X extern char *strdup(); X X sprintf(name,"fifo%c%d",mode==0?'r':'w',port); X X unlink(name); X cmask=umask(0); X fd = mknod(name,0666|S_IFIFO); X umask(cmask); X if (fd != 0) { X perror("mknod"); X writelog("fifo: mknod %s fail\n",name); X fd = -1; X } X else if((fd = open(name,O_RDWR|O_NDELAY)) < 0) { X perror("open fifo"); X writelog("fifo: open %s fail\n",name); X } X if (fd != -1) { X if (fifonames[fd]) free(fifonames[fd]); X fifonames[fd] = strdup(name); X } X return fd; X} X X#ifndef BOOLEXP_DEBUGGING Xvoid main(int argc, char **argv) X{ X if (argc < 3) { X fprintf(stderr, "Usage: %s infile dumpfile [port [logfile]]\n", *argv); X exit (1); X } X X if (argc > 4) logfile = argv[4]; X X set_signals (); X if (init_game (argv[1], argv[2]) < 0) { X writelog("INIT: Couldn't load %s!\n", argv[1]); X exit (2); X } X X /* go do it */ X shovechars (argc >= 4 ? atoi (argv[3]) : TINYPORT); X close_sockets (); X dump_database (); X exit (0); X} X#endif /*BOOLEXP_DEBUGGING*/ X Xvoid set_signals(void) X{ X#ifdef DETACH X int i; X X signal(SIGHUP, SIG_IGN); X if (fork() != 0) exit(0); X X for (i=getdtablesize(); i >= 0; i--) X (void) close(i); X X setpgrp(); X i = open("/dev/tty", O_RDWR, 0); X if (i != -1) { X close(i); X } X X freopen(logfile, "a", stderr); X setbuf(stderr, NULL); X#endif DETACH X X /* we don't care about SIGPIPE, we notice it in select() and write() */ X signal (SIGPIPE, SIG_IGN); X X /* standard termination signals */ X signal (SIGINT, (void (*)) sigshutdown); X signal (SIGTERM, (void (*)) sigshutdown); X X#ifdef DETACH X /* SIGUSR2 synchronizes the log file */ X signal (SIGUSR2, (void (*)) logsynch); X#else DETACH X signal (SIGUSR2, (void (*)) bailout); X#endif DETACH X X /* catch these because we might as well */ X signal (SIGQUIT, (void (*)) bailout); X signal (SIGILL, (void (*)) bailout); X signal (SIGTRAP, (void (*)) bailout); X signal (SIGIOT, (void (*)) bailout); X signal (SIGEMT, (void (*)) bailout); X signal (SIGFPE, (void (*)) bailout); X signal (SIGBUS, (void (*)) bailout); X signal (SIGSEGV, (void (*)) bailout); X signal (SIGSYS, (void (*)) bailout); X signal (SIGUSR1, (void (*)) bailout); X} X Xint notify(dbref player, const char *msg) X{ X struct descriptor_data *d; X int retval = 0; X#ifdef COMPRESS X extern const char *uncompress(const char *); X X msg = uncompress(msg); X#endif /* COMPRESS */ X X for(d = descriptor_list; d; d = d->next) { X if (d->connected && d->player == player) { X queue_string(d, msg); X queue_write(d, "\n", 1); X retval = 1; X } X } X return(retval); X} X Xstruct timeval timeval_sub(struct timeval now, struct timeval then) X{ X now.tv_sec -= then.tv_sec; X now.tv_usec -= then.tv_usec; X if (now.tv_usec < 0) { X now.tv_usec += 1000000; X now.tv_sec--; X } X return now; X} X Xint msec_diff(struct timeval now, struct timeval then) X{ X return ((now.tv_sec - then.tv_sec) * 1000 X + (now.tv_usec - then.tv_usec) / 1000); X} X Xstruct timeval msec_add(struct timeval t, int x) X{ X t.tv_sec += x / 1000; X t.tv_usec += (x % 1000) * 1000; X if (t.tv_usec >= 1000000) { X t.tv_sec += t.tv_usec / 1000000; X t.tv_usec = t.tv_usec % 1000000; X } X return t; X} X Xstruct timeval update_quotas(struct timeval last, struct timeval current) X{ X int nslices; X struct descriptor_data *d; X X nslices = msec_diff (current, last) / COMMAND_TIME_MSEC; X X if (nslices > 0) { X for (d = descriptor_list; d; d = d -> next) { X d -> quota += COMMANDS_PER_TIME * nslices; X if (d -> quota > COMMAND_BURST_SIZE) X d -> quota = COMMAND_BURST_SIZE; X } X } X return msec_add (last, nslices * COMMAND_TIME_MSEC); X} X Xvoid shovechars(int port) X{ X fd_set input_set, output_set; X long now; X struct timeval last_slice, current_time; X struct timeval next_slice; X struct timeval timeout, slice_timeout; X int maxd; X struct descriptor_data *d, *dnext; X struct descriptor_data *newd; X int avail_descriptors; X X sock = make_socket (port); X maxd = sock+1; X gettimeofday(&last_slice, (struct timezone *) 0); X X avail_descriptors = (getdtablesize() - 4)/2; X X while (shutdown_flag == 0) { X gettimeofday(¤t_time, (struct timezone *) 0); X last_slice = update_quotas (last_slice, current_time); X X process_commands(); X X if (shutdown_flag) X break; X timeout.tv_sec = 1000; X timeout.tv_usec = 0; X next_slice = msec_add (last_slice, COMMAND_TIME_MSEC); X slice_timeout = timeval_sub (next_slice, current_time); X X FD_ZERO (&input_set); X FD_ZERO (&output_set); X if (ndescriptors < avail_descriptors) X FD_SET (sock, &input_set); X for (d = descriptor_list; d; d=d->next) { X if (d->input.head) X timeout = slice_timeout; X else X FD_SET (d->rdescriptor, &input_set); X if (d->output.head) X FD_SET (d->wdescriptor, &output_set); X } X X if (select (maxd, &input_set, &output_set, X (fd_set *) 0, &timeout) < 0) { X if (errno != EINTR) { X perror ("select"); X return; X } X } else { X (void) time (&now); X if (FD_ISSET (sock, &input_set)) { X if (!(newd = new_connection (sock))) { X if (errno X && errno != EINTR X && errno != EMFILE X && errno != ENFILE) { X perror ("new_connection"); X return; X } X } else { X if (newd->rdescriptor >= maxd) X maxd = newd->rdescriptor + 1; X if (newd->wdescriptor >= maxd) X maxd = newd->wdescriptor + 1; X } X } X for (d = descriptor_list; d; d = dnext) { X dnext = d->next; X if (FD_ISSET (d->rdescriptor, &input_set)) { X d->last_time = now; X if (!process_input (d)) { X shutdownsock (d); X continue; X } X } X if (FD_ISSET (d->wdescriptor, &output_set)) { X if (!process_output (d)) { X shutdownsock (d); X } X } X } X } X } X} X Xstatic char hostname[128]; X Xstruct descriptor_data *new_connection(int sock) X{ X int rnewsock, wnewsock; X struct sockaddr_in addr; X int addr_len; X char buf[80]; X int n; X X addr_len = read(sock,buf,sizeof(buf)-1); X if (addr_len>0) { X buf[addr_len] = '\0'; X addr.sin_addr.s_addr = n = atoi(buf); X } else { X return 0; X } X X rnewsock = fifo(n,0); X wnewsock = fifo(n,1); X if (rnewsock < 0 || wnewsock < 0) { X close(rnewsock); close(wnewsock); X return 0; X#ifdef LOCKOUT X } else if(forbidden_site(ntohl(addr.sin_addr.s_addr))) { X writelog("REFUSED CONNECTION from %s(%d) on descriptor %d\n", X addrout(addr.sin_addr.s_addr), X ntohs(addr.sin_port), newsock); X shutdown(newsock, 2); X close(newsock); X errno = 0; X return 0; X#endif /* LOCKOUT */ X } else { X strcpy (hostname, addrout (addr.sin_addr.s_addr)); X#ifdef NOISY_LOG X writelog("ACCEPT from %s(%d) on descriptor %d\n", X hostname, X ntohs (addr.sin_port), newsock); X#endif NOISY_LOG X return initializesock (rnewsock, wnewsock, &addr, hostname); X } X} X Xconst char *addrout(long a) X{ X /* New version: returns host names, not octets. Uses gethostbyaddr. */ X extern char *inet_ntoa(long); X X#ifdef HOST_NAME X struct hostent *he; X X he = gethostbyaddr(&a,sizeof(a),AF_INET); X if (he) return he->h_name; X else return inet_ntoa(a); X#else X return inet_ntoa(a); X#endif HOST_NAME X} X X Xvoid clearstrings(struct descriptor_data *d) X{ X if (d->output_prefix) { X FREE(d->output_prefix); X d->output_prefix = 0; X } X if (d->output_suffix) { X FREE(d->output_suffix); X d->output_suffix = 0; X } X} X Xvoid shutdownsock(struct descriptor_data *d) X{ X if (d->connected) { X writelog("DISCONNECT player %s(%d) %d %s\n", X db[d->player].name, d->player, d->rdescriptor, d->hostname); X#ifdef CONNECT_MESSAGES X announce_disconnect(d->player); X#endif CONNECT_MESSAGES X } else { X writelog("DISCONNECT descriptor %d never connected\n", X d->rdescriptor); X } X clearstrings (d); X shutdown (d->rdescriptor, 2); X close (d->rdescriptor); X shutdown (d->wdescriptor, 2); X close (d->wdescriptor); X freeqs (d); X if (d->prev) d->prev->next = d->next; else descriptor_list = d->next; X if (d->next) d->next->prev = d->prev; X FREE (d); X ndescriptors--; X} X Xstruct descriptor_data *initializesock(int r, int w, struct sockaddr_in *a, X const char *hostname) X{ X struct descriptor_data *d; X X ndescriptors++; X MALLOC(d, struct descriptor_data, 1); X d->rdescriptor = r; X d->wdescriptor = w; X d->connected = 0; X/* X make_nonblocking (r); X make_nonblocking (w); X*/ X d->output_prefix = 0; X d->output_suffix = 0; X d->output_size = 0; X d->output.head = 0; X d->output.tail = &d->output.head; X d->input.head = 0; X d->input.tail = &d->input.head; X d->raw_input = 0; X d->raw_input_at = 0; X d->quota = COMMAND_BURST_SIZE; X d->last_time = 0; X d->address = *a; /* added 5/3/90 SCG */ X d->hostname = alloc_string(hostname); X if (descriptor_list) X descriptor_list->prev = d; X d->next = descriptor_list; X d->prev = (struct descriptor_data *) NULL; X descriptor_list = d; X X welcome_user (d); X return d; X} X Xint make_socket(int port) X{ X int s; X X s = fifo(port,0); X if (s < 0) { X perror ("opening fifo"); X exit (3); X } X return s; X} X Xstruct text_block *make_text_block(const char *s, int n) X{ X struct text_block *p; X X MALLOC(p, struct text_block, 1); X MALLOC(p->buf, char, n); X bcopy (s, p->buf, n); X p->nchars = n; X p->start = p->buf; X p->nxt = 0; X return p; X} X Xvoid free_text_block (struct text_block *t) X{ X FREE (t->buf); X FREE ((char *) t); X} X Xvoid add_to_queue(struct text_queue *q, const char *b, int n) X{ X struct text_block *p; X X if (n == 0) return; X X p = make_text_block (b, n); X p->nxt = 0; X *q->tail = p; X q->tail = &p->nxt; X} X Xint flush_queue(struct text_queue *q, int n) X{ X struct text_block *p; X int really_flushed = 0; X X n += strlen(flushed_message); X X while (n > 0 && (p = q->head)) { X n -= p->nchars; X really_flushed += p->nchars; X q->head = p->nxt; X free_text_block (p); X } X p = make_text_block(flushed_message, strlen(flushed_message)); X p->nxt = q->head; X q->head = p; X if (!p->nxt) X q->tail = &p->nxt; X really_flushed -= p->nchars; X return really_flushed; X} X Xint queue_write(struct descriptor_data *d, const char *b, int n) X{ X int space; X X space = MAX_OUTPUT - d->output_size - n; X if (space < 0) X d->output_size -= flush_queue(&d->output, -space); X add_to_queue (&d->output, b, n); X d->output_size += n; X return n; X} X Xint queue_string(struct descriptor_data *d, const char *s) X{ X return queue_write (d, s, strlen (s)); X} X Xint process_output(struct descriptor_data *d) X{ X struct text_block **qp, *cur; X int cnt; X X for (qp = &d->output.head; cur = *qp;) { X cnt = write (d->wdescriptor, cur -> start, cur -> nchars); X if (cnt < 0) { X if (errno == EWOULDBLOCK) X return 1; X return 0; X } X d->output_size -= cnt; X if (cnt == cur -> nchars) { X if (!cur -> nxt) X d->output.tail = qp; X *qp = cur -> nxt; X free_text_block (cur); X continue; /* do not adv ptr */ X } X cur -> nchars -= cnt; X cur -> start += cnt; X break; X } X return 1; X} X X/* Xvoid make_nonblocking(int s) X{ X if (fcntl (s, F_SETFL, FNDELAY) == -1) { X perror ("make_nonblocking: fcntl"); X panic ("FNDELAY fcntl failed"); X } X} X*/ X Xvoid freeqs(struct descriptor_data *d) X{ X struct text_block *cur, *next; X X cur = d->output.head; X while (cur) { X next = cur -> nxt; X free_text_block (cur); X cur = next; X } X d->output.head = 0; X d->output.tail = &d->output.head; X X cur = d->input.head; X while (cur) { X next = cur -> nxt; X free_text_block (cur); X cur = next; X } X d->input.head = 0; X d->input.tail = &d->input.head; X X if (d->raw_input) X FREE (d->raw_input); X d->raw_input = 0; X d->raw_input_at = 0; X} X Xvoid welcome_user(struct descriptor_data *d) X{ X queue_string (d, WELCOME_MESSAGE); X# ifdef CONNECT_FILE X do_connect_msg(d, CONNECT_FILE); X# endif X} X Xvoid goodbye_user(struct descriptor_data *d) X{ X write (d->wdescriptor, LEAVE_MESSAGE, strlen (LEAVE_MESSAGE)); X} X Xchar *strsave (const char *s) X{ X char *p; X X MALLOC (p, char, strlen(s) + 1); X X if (p) X strcpy (p, s); X return p; X} X Xvoid save_command (struct descriptor_data *d, const char *command) X{ X add_to_queue (&d->input, command, strlen(command)+1); X} X Xint process_input (struct descriptor_data *d) X{ X char buf[1024]; X int got; X char *p, *pend, *q, *qend; X X got = read (d->rdescriptor, buf, sizeof buf); X if (got <= 0) X return 0; X if (!d->raw_input) { X MALLOC(d->raw_input,char,MAX_COMMAND_LEN); X d->raw_input_at = d->raw_input; X } X p = d->raw_input_at; X pend = d->raw_input + MAX_COMMAND_LEN - 1; X for (q=buf, qend = buf + got; q < qend; q++) { X if (*q == '\n') { X *p = '\0'; X if (p > d->raw_input) X save_command (d, d->raw_input); X p = d->raw_input; X } else if (p < pend && isascii (*q) && isprint (*q)) { X *p++ = *q; X } X } X if(p > d->raw_input) { X d->raw_input_at = p; X } else { X FREE(d->raw_input); X d->raw_input = 0; X d->raw_input_at = 0; X } X return 1; X} X Xvoid set_userstring (char **userstring, const char *command) X{ X if (*userstring) { X FREE(*userstring); X *userstring = 0; X } X while (*command && isascii (*command) && isspace (*command)) X command++; X if (*command) X *userstring = strsave (command); X} X Xvoid process_commands(void) X{ X int nprocessed; X struct descriptor_data *d, *dnext; X struct text_block *t; X X do { X nprocessed = 0; X for (d = descriptor_list; d; d = dnext) { X dnext = d->next; X if (d -> quota > 0 && (t = d -> input.head)) { X d -> quota--; X nprocessed++; X if (!do_command (d, t -> start)) { X shutdownsock (d); X } else { X d -> input.head = t -> nxt; X if (!d -> input.head) X d -> input.tail = &d -> input.head; X free_text_block (t); X } X } X } X } while (nprocessed > 0); X} X Xint do_command (struct descriptor_data *d, char *command) X{ X if (!strcmp (command, QUIT_COMMAND)) { X goodbye_user (d); X return 0; X } else if (!strncmp (command, WHO_COMMAND, strlen(WHO_COMMAND))) { X if (d->output_prefix) { X queue_string (d, d->output_prefix); X queue_write (d, "\n", 1); X } X dump_users (d, command + strlen(WHO_COMMAND)); X if (d->output_suffix) { X queue_string (d, d->output_suffix); X queue_write (d, "\n", 1); X } X } else if (d->connected && X !strncmp (command, PREFIX_COMMAND, strlen (PREFIX_COMMAND))) { X#ifdef ROBOT_MODE X if (!Robot(d->player)) { X#ifndef TINKER X notify(d->player, X "Only robots can use OUTPUTPREFIX; contact a Wizard."); X#else TINKER X notify(d->player, X "Only robots can use OUTPUTPREFIX; contact a Tinker."); X#endif TINKER X return 1; X } X if (!d->connected) return 1; X#endif ROBOT_MODE X set_userstring (&d->output_prefix, command+strlen(PREFIX_COMMAND)); X } else if (d->connected && X !strncmp (command, SUFFIX_COMMAND, strlen (SUFFIX_COMMAND))) { X#ifdef ROBOT_MODE X if (!Robot(d->player)) { X#ifndef TINKER X notify(d->player, X "Only robots can use OUTPUTSUFFIX; contact a Wizard."); X#else TINKER X notify(d->player, X "Only robots can use OUTPUTSUFFIX; contact a Tinker."); X#endif TINKER X return 1; X } X#endif ROBOT_MODE X set_userstring (&d->output_suffix, command+strlen(SUFFIX_COMMAND)); X } else { X if (d->connected) { X if (d->output_prefix) { X queue_string (d, d->output_prefix); X queue_write (d, "\n", 1); X } X process_command (d->player, command); X if (d->output_suffix) { X queue_string (d, d->output_suffix); X queue_write (d, "\n", 1); X } X } else { X check_connect (d, command); X } X } X return 1; X} X Xvoid check_connect (struct descriptor_data *d, const char *msg) X{ X char command[MAX_COMMAND_LEN]; X char user[MAX_COMMAND_LEN]; X char password[MAX_COMMAND_LEN]; X dbref player; X X parse_connect (msg, command, user, password); X X if (!strncmp (command, "co", 2)) { X player = connect_player (user, password); X if (player == NOTHING) { X queue_string (d, connect_fail); X writelog("FAILED CONNECT %s on %d %s\n", X user, d->rdescriptor, d->hostname); X } else { X writelog("CONNECTED %s(%d) on %d %s\n", X db[player].name, player, d->rdescriptor, d->hostname); X d->connected = 1; X d->connected_at = time(NULL); X d->player = player; X X do_motd (player); X do_look_around (player); X#ifdef CONNECT_MESSAGES X announce_connect(player); X#endif CONNECT_MESSAGES X } X } else if (!strncmp (command, "cr", 2)) { X#ifndef REGISTRATION X player = create_player (user, password); X if (player == NOTHING) { X queue_string (d, create_fail); X writelog("FAILED CREATE %s on %d %s\n", X user, d->rdescriptor, d->hostname); X } else { X writelog("CREATED %s(%d) on descriptor %d %s\n", X db[player].name, player, d->rdescriptor, d->hostname); X d->connected = 1; X d->connected_at = time(NULL); X d->player = player; X X do_motd (player); X do_look_around (player); X#ifdef CONNECT_MESSAGES X announce_connect(player); X#endif CONNECT_MESSAGES X } X#else X queue_string (d, REGISTER_MESSAGE); X#endif REGISTRATION X } else { X welcome_user (d); X } X} X Xvoid parse_connect (const char *msg, char *command, char *user, char *pass) X{ X char *p; X X while (*msg && isascii(*msg) && isspace (*msg)) X msg++; X p = command; X while (*msg && isascii(*msg) && !isspace (*msg)) X *p++ = *msg++; X *p = '\0'; X while (*msg && isascii(*msg) && isspace (*msg)) X msg++; X p = user; X while (*msg && isascii(*msg) && !isspace (*msg)) X *p++ = *msg++; X *p = '\0'; X while (*msg && isascii(*msg) && isspace (*msg)) X msg++; X p = pass; X while (*msg && isascii(*msg) && !isspace (*msg)) X *p++ = *msg++; X *p = '\0'; X} X Xvoid close_sockets(void) X{ X struct descriptor_data *d, *dnext; X X for (d = descriptor_list; d; d = dnext) { X dnext = d->next; X write (d->wdescriptor, shutdown_message, strlen (shutdown_message)); X if (shutdown (d->rdescriptor, 2) < 0) X perror ("shutdown"); X close (d->rdescriptor); X if (shutdown (d->wdescriptor, 2) < 0) X perror ("shutdown"); X close (d->wdescriptor); X } X close (sock); X} X Xvoid emergency_shutdown(void) X{ X close_sockets(); X} X Xvoid boot_off(dbref player) X{ X struct descriptor_data *d, *dnext; X for (d = descriptor_list; d; d = dnext) { X dnext = d->next; X if (d->connected && d->player == player) { X process_output(d); X shutdownsock(d); X } X } X} X Xint bailout (int sig) X{ X writelog("BAILOUT: caught signal %d\n", sig); X panic("PANIC on spurious signal"); X _exit(7); X return 0; X} X Xint sigshutdown (int sig) X{ X writelog("SHUTDOWN: on signal %d\n", sig); X shutdown_flag = 1; X return 0; X} X X#ifdef DETACH Xint logsynch (int sig) X{ X freopen(logfile, "a", stderr); X setbuf(stderr, NULL); X writelog("log file reopened\n"); X return 0; X} X#endif DETACH X Xvoid dump_users(struct descriptor_data *e, char *user) X{ X struct descriptor_data *d; X long now; X char buf[1024]; X int wizard; X int reversed, tabular; X X while (*user && isspace(*user)) user++; X if (!*user) user = NULL; X X reversed = e->connected && Flag(e->player,REVERSED_WHO); X tabular = e->connected && Flag(e->player,TABULAR_WHO); X X (void) time (&now); X queue_string(e, X tabular ? "Player Name On For Idle\n" : "Current Players:\n"); X#ifdef GOD_MODE X wizard = e->connected && God(e->player); X#else GOD_MODE X wizard = e->connected && Wizard(e->player); X#endif GOD_MODE X X d = descriptor_list; X X if (reversed) X while (d && d->next) d = d->next; X X while (d) { X if (d->connected && X (!user || string_prefix(db[d->player].name, user))) { X if (tabular) { X sprintf(buf,"%-16s %10s %4s", X db[d->player].name, X time_format_1(now - d->connected_at), X time_format_2(now - d->last_time)); X if (wizard) X sprintf(buf+strlen(buf), X " %s", d->hostname); X } else { X sprintf(buf, X "%s idle %d seconds", X db[d->player].name, X now - d->last_time); X if (wizard) X sprintf(buf+strlen(buf), X " from host %s", d->hostname); X } X strcat(buf,"\n"); X queue_string (e, buf); X } X if (reversed) d = d->prev; else d = d->next; X } X} X Xchar *time_format_1(long dt) X{ X register struct tm *delta; X static char buf[64]; X X delta = gmtime(&dt); X if (delta->tm_yday > 0) X sprintf(buf, "%dd %02d:%02d", X delta->tm_yday, delta->tm_hour, delta->tm_min); X else X sprintf(buf, "%02d:%02d", X delta->tm_hour, delta->tm_min); X return buf; X} X Xchar *time_format_2(long dt) X{ X register struct tm *delta; X static char buf[64]; X X delta = gmtime(&dt); X if (delta->tm_yday > 0) X sprintf(buf, "%dd", delta->tm_yday); X else if (delta->tm_hour > 0) X sprintf(buf, "%dh", delta->tm_hour); X else if (delta->tm_min > 0) X sprintf(buf, "%dm", delta->tm_min); X else X sprintf(buf, "%ds", delta->tm_sec); X return buf; X} X X#ifdef CONNECT_MESSAGES Xvoid announce_connect(dbref player) X{ X dbref loc; X char buf[BUFFER_LEN]; X X if ((loc = getloc(player)) == NOTHING) return; X if (Dark(player) || Dark(loc)) return; X X sprintf(buf, "%s has connected.", db[player].name); X X notify_except(db[loc].contents, player, buf); X} X Xvoid announce_disconnect(dbref player) X{ X dbref loc; X char buf[BUFFER_LEN]; X X if ((loc = getloc(player)) == NOTHING) return; X if (Dark(player) || Dark(loc)) return; X X sprintf(buf, "%s has disconnected.", db[player].name); X X notify_except(db[loc].contents, player, buf); X} X#endif CONNECT_MESSAGES Xint do_connect_msg(struct descriptor_data * d, const char *filename) X{ X FILE *f; X char buf[BUFFER_LEN]; X X if ((f = fopen(filename, "r")) == (FILE *)NULL) X { X return (0); X } else X { X while (fgets(buf, sizeof buf, f)) X { X queue_string(d, (char *)buf); X X } X fclose(f); X return (1); X } X} SHAR_EOFfifoiface.c if test 47081 -ne "`sum < 'fifoiface.c' | sed 's/ .*//'`" then echo shar: "possible error transmitting 'fifoiface.c'" '(sum should have been 47081)' echo shar: "trying 'sum -r'" if test 31121 -ne "`sum -r < 'fifoiface.c' | sed 's/ .*//'`" then echo shar: "probable error transmitting 'fifoiface.c'" '(sum should have been 31121)' echo shar: "trying 'wc -c'" if test 27328 -ne "`wc -c < 'fifoiface.c'`" then echo shar: "error transmitting 'fifoiface.c'" '(should have been 27328 characters)' else echo shar: "wc was ok" fi fi fi chmod 644 'fifoiface.c' fi echo shar: "extracting 'tinymud.sh'" '(764 characters)' if test -f 'tinymud.sh' then echo shar: "will not over-write existing file 'tinymud.sh'" else sed 's/^X//' << \SHAR_EOFtinymud.sh > 'tinymud.sh' X: X# tinymud client Xport=4201 Xcd /usr/local/games/lib/netmud Xtest -p fifor$port || { echo "no server fifo";exit 1; } Xpid=$$ Xecho $pid >> fifor$port Xecho "connecting...\c" Xtries=30 Xwhile test $tries -gt 0 Xdo X sleep 1 X test -p fifor$pid -a -p fifow$pid && break X tries=`expr $tries - 1` Xdone Xecho Xtest $tries -eq 0 && { echo "$0: timeout waiting for server";exit 1; } Xtrap '' 0 1 2 3 15 Xcat -u fifow$pid & Xchild=$! Xcleanup() { X kill $child 2>/dev/null X test -p fifor$pid && echo QUIT >> fifor$pid X rm -f fifor$pid X} Xtrap 'cleanup; exit' 0 Xtrap 'exit' 1 2 3 15 Xwhile test -p fifor$pid -a -p fifow$pid && read x Xdo X case "$x" in X +x) set +x;; X -x) set -x;; X !) sh -i;echo "\n$0";; X *) test -p fifor$pid || break X echo "$x" >> fifor$pid X sleep 1 X ;; X esac Xdone SHAR_EOFtinymud.sh if test 59606 -ne "`sum < 'tinymud.sh' | sed 's/ .*//'`" then echo shar: "possible error transmitting 'tinymud.sh'" '(sum should have been 59606)' echo shar: "trying 'sum -r'" if test 34991 -ne "`sum -r < 'tinymud.sh' | sed 's/ .*//'`" then echo shar: "probable error transmitting 'tinymud.sh'" '(sum should have been 34991)' echo shar: "trying 'wc -c'" if test 764 -ne "`wc -c < 'tinymud.sh'`" then echo shar: "error transmitting 'tinymud.sh'" '(should have been 764 characters)' else echo shar: "wc was ok" fi fi fi chmod 644 'tinymud.sh' fi echo shar: "extracting 'restart'" '(381 characters)' if test -f 'restart' then echo shar: "will not over-write existing file 'restart'" else sed 's/^X//' << \SHAR_EOFrestart > 'restart' X: Xumask 002 Xport=4201 XS=/u2/src/games/tinymud/src XL=/usr/local/games/lib/netmud Xnetmud=$S/fifonetmud Xcd $L X Xmv tinymud.db tinymud.db.old 2>/dev/null Xif test -f tinymud.db.new; then X mv tinymud.db.new tinymud.db Xelse X cp tinymud.db.old tinymud.db Xfi Xrm -f fifo* Xecho RESTARTED AT `date` >> tinymud.log X# ignore hup Xtrap '' 1 Xexec $netmud tinymud.db tinymud.db.new $port tinymud.log SHAR_EOFrestart if test 32991 -ne "`sum < 'restart' | sed 's/ .*//'`" then echo shar: "possible error transmitting 'restart'" '(sum should have been 32991)' echo shar: "trying 'sum -r'" if test 22561 -ne "`sum -r < 'restart' | sed 's/ .*//'`" then echo shar: "probable error transmitting 'restart'" '(sum should have been 22561)' echo shar: "trying 'wc -c'" if test 381 -ne "`wc -c < 'restart'`" then echo shar: "error transmitting 'restart'" '(should have been 381 characters)' else echo shar: "wc was ok" fi fi fi chmod 755 'restart' fi exit 0 # End of shell archive