purdon@athena.mit.edu (James R. Purdon III) (12/21/90)
The slugnet program is a multiple-user, interactive conferencing facility. It currently runs under a variety of System V-based and BSD-based operating systems (although certain functions may not be possible under some of these operating systems). Cut here------------------------------------------------------------------- #!/bin/sh # to extract, remove the header and type "sh filename" if `test ! -s ./chgusr.c` then echo "writing ./chgusr.c" cat > ./chgusr.c << '\End\Of\Shar\' /* @(#)chgusr.c 1.7 */ #include "slugnet.h" int chgusr(name,un,jsn,confer,rcvfil,usrfil,exitit,host,pid,mode) /* changes directory entry */ char name[NAMLEN],un[UNLEN],jsn[JSNLEN],confer[CFRLEN],rcvfil[FLNMLN],usrfil[FLNMLN],host[HOSTLEN],pid[PIDLEN],mode[MODELN]; int exitit; /* if exit is ON, jsn is replaced by blanks */ { struct slugdir inpstr, outstr; int found,i,numbyt,reclen,usr; long fpos,lseek(); /* initialize variables */ found=OFF; reclen=sizeof( struct slugdir ); strncpy(inpstr.jsn," ",JSNLEN-1); strcpy(outstr.name,name); strcpy(outstr.un,un); strcpy(outstr.jsn,jsn); strcpy(outstr.confer,confer); strcpy(outstr.rcvfil,rcvfil); strcpy(outstr.host,host); strcpy(outstr.pid,pid); strcpy(outstr.mode,mode); /* open the user directory file */ lock(usrfil); #ifdef SYSV2 usr=open(usrfil,O_RDWR|O_SYNC); #endif SYSV2 #ifdef SYSV3 usr=open(usrfil,O_RDWR|O_SYNC); #endif SYSV3 #ifdef BSD4 usr=open(usrfil,O_RDWR|O_FSYNC); #endif BSD4 #ifdef ULTRIX usr=open(usrfil,O_RDWR|O_FSYNC); #endif ULTRIX if(usr<NULL) { #ifdef SYSV2 usr=creat(usrfil,S_IREAD|S_IWRITE|O_SYNC); #endif SYSV2 #ifdef SYSV3 usr=creat(usrfil,S_IREAD|S_IWRITE|O_SYNC); #endif SYSV3 #ifdef BSD4 usr=creat(usrfil,S_IREAD|S_IWRITE|O_FSYNC); #endif BSD4 #ifdef ULTRIX usr=creat(usrfil,S_IREAD|S_IWRITE|O_FSYNC); #endif ULTRIX i=close(usr); #ifdef SYSV2 usr=open(usrfil,O_RDWR|O_SYNC); #endif SYSV2 #ifdef SYSV3 usr=open(usrfil,O_RDWR|O_SYNC); #endif SYSV3 #ifdef BSD4 usr=open(usrfil,O_RDWR|O_FSYNC); #endif BSD4 #ifdef ULTRIX usr=open(usrfil,O_RDWR|O_FSYNC); #endif ULTRIX if(usr<NULL) { unlock(usrfil); return(-1); } } /* make sure user isn't already there */ #ifndef SYSV2 fpos=lseek(usr,(long)NULL,SEEK_SET); #endif SYSV2 #ifdef SYSV2 fpos=lseek(usr,(long)NULL,BEGINNING); #endif SYSV2 if(fpos<(long)NULL) { unlock(usrfil); return(-3); } for(;;) { #ifdef SYSV2 numbyt=read(usr,&inpstr,(unsigned)reclen); #endif SYSV2 #ifdef SYSV3 numbyt=read(usr,&inpstr,(unsigned)reclen); #endif SYSV3 #ifdef BSD4 numbyt=read(usr,&inpstr,reclen); #endif BSD4 #ifdef ULTRIX numbyt=read(usr,&inpstr,reclen); #endif ULTRIX if(numbyt == NULL ) break; else if(numbyt!=reclen) { unlock(usrfil); return(-4); } if(strncmp(inpstr.jsn,jsn,JSNLEN-1)==NULL &&strncmp(inpstr.host,host,HOSTLEN-1)==NULL ){ #ifndef SYSV2 fpos=lseek(usr,-(long)reclen,SEEK_CUR); #endif SYSV2 #ifdef SYSV2 fpos=lseek(usr,-(long)reclen,CURRENT); #endif SYSV2 if(fpos<(long)NULL) { unlock(usrfil); return(-5); } /* make sure we don't replace a real rcvfil with a "*" (this happens if an internodal client is hooked to an internodal server on the same host */ if( strcmp( outstr.rcvfil, "*" ) == NULL && strcmp( inpstr.rcvfil, "*" ) != NULL ) strcpy( outstr.rcvfil, inpstr.rcvfil ); /* user is logging out */ if(exitit==ON) strcpy(outstr.jsn," "); #ifdef SYSV2 numbyt=write(usr,&outstr,(unsigned)reclen); #endif SYSV2 #ifdef SYSV3 numbyt=write(usr,&outstr,(unsigned)reclen); #endif SYSV3 #ifdef BSD4 numbyt=write(usr,&outstr,reclen); #endif BSD4 #ifdef ULTRIX numbyt=write(usr,&outstr,reclen); #endif ULTRIX if(numbyt!=reclen) { unlock(usrfil); return(-6); } found=ON; break; } } /* add new user */ if(found==OFF) { #ifndef SYSV2 fpos=lseek(usr,(long)NULL,SEEK_SET); #endif SYSV2 #ifdef SYSV2 fpos=lseek(usr,(long)NULL,BEGINNING); #endif SYSV2 if(fpos<(long)NULL) { unlock(usrfil); return(-7); } for(;;) { #ifdef SYSV2 numbyt=read(usr,&inpstr,(unsigned)reclen); #endif SYSV2 #ifdef SYSV3 numbyt=read(usr,&inpstr,(unsigned)reclen); #endif SYSV3 #ifdef BSD4 numbyt=read(usr,&inpstr,reclen); #endif BSD4 #ifdef ULTRIX numbyt=read(usr,&inpstr,reclen); #endif ULTRIX if(numbyt == NULL ) break; else if(numbyt!=reclen) { unlock(usrfil); return(-8); } if(strncmp(inpstr.jsn," ",JSNLEN-1)==NULL) { #ifndef SYSV2 fpos=lseek(usr,-(long)reclen,SEEK_CUR); #endif SYSV2 #ifdef SYSV2 fpos=lseek(usr,-(long)reclen,CURRENT); #endif SYSV2 if(fpos<(long)NULL) { unlock(usrfil); return(-9); } #ifdef SYSV2 numbyt=write(usr,&outstr,(unsigned)reclen); #endif SYSV2 #ifdef SYSV3 numbyt=write(usr,&outstr,(unsigned)reclen); #endif SYSV3 #ifdef BSD4 numbyt=write(usr,&outstr,reclen); #endif BSD4 #ifdef ULTRIX numbyt=write(usr,&outstr,reclen); #endif ULTRIX if(numbyt!=reclen) { unlock(usrfil); return(-10); } found=ON; break; } } /* we must be at eof! */ if( found != ON ) { #ifndef SYSV2 fpos=lseek(usr,(long)NULL,SEEK_END); #endif SYSV2 #ifdef SYSV2 fpos=lseek(usr,(long)NULL,END); #endif SYSV2 if(fpos<(long)NULL) { unlock(usrfil); return(-11); } #ifdef SYSV2 numbyt=write(usr,&outstr,(unsigned)reclen); #endif SYSV2 #ifdef SYSV3 numbyt=write(usr,&outstr,(unsigned)reclen); #endif SYSV3 #ifdef BSD4 numbyt=write(usr,&outstr,reclen); #endif BSD4 #ifdef ULTRIX numbyt=write(usr,&outstr,reclen); #endif ULTRIX if(numbyt!=reclen) { unlock(usrfil); return(-12); } found=ON; } } /* make sure he got in */ if(found==OFF) { unlock(usrfil); return(-13); } /* close it */ i=close(usr); unlock(usrfil); if(i!=NULL) return(-14); return(NULL); } \End\Of\Shar\ else echo "will not over write ./chgusr.c" fi chmod 400 ./chgusr.c if [ `wc -c ./chgusr.c | awk '{printf $1}'` -ne 6808 ] then echo `wc -c ./chgusr.c | awk '{print "Got " $1 ", Expected " 6808}'` fi if `test ! -s ./cleanup.c` then echo "writing ./cleanup.c" cat > ./cleanup.c << '\End\Of\Shar\' /* @(#)cleanup.c 1.4 */ #ifdef NETWORK #include "net.h" /* as children die we should get catch their returns or else we get zombies, A Bad Thing. cleanup() catches falling children. */ void cleanup() { int i; #ifdef BDS4 union wait wstatus; #endif BSD4 #ifdef ULTRIX union wait wstatus; #endif ULTRIX #ifdef BDS4 while(( i = wait3(&wstatus,WNOHANG,NULL)) > 0); #endif BSD4 #ifdef ULTRIX while(( i = wait3(&wstatus,WNOHANG,NULL)) > 0); #endif ULTRIX } #endif NETWORK \End\Of\Shar\ else echo "will not over write ./cleanup.c" fi chmod 400 ./cleanup.c if [ `wc -c ./cleanup.c | awk '{printf $1}'` -ne 480 ] then echo `wc -c ./cleanup.c | awk '{print "Got " $1 ", Expected " 480}'` fi if `test ! -s ./clnusr.c` then echo "writing ./clnusr.c" cat > ./clnusr.c << '\End\Of\Shar\' /* @(#)clnusr.c 1.6 */ #include "slugnet.h" int clnusr(name,un,jsn,confer,rcvfil,usrfil,host,pid,mode) /* cleans up zombie user directory entries */ char name[NAMLEN],un[UNLEN],jsn[JSNLEN],confer[CFRLEN],rcvfil[FLNMLN],usrfil[FLNMLN],host[HOSTLEN],pid[PIDLEN],mode[MODELN]; { struct slugdir inpstr, outstr; char zmbfil[ FLNMLN + 1 ]; int i, ipid, numbyt,reclen,usr; long fpos,lseek(); /* initialize variables */ reclen=sizeof( struct slugdir ); strncpy(inpstr.jsn," ",JSNLEN-1); strcpy(outstr.name,name); strcpy(outstr.un,un); strcpy(outstr.jsn,jsn); strcpy(outstr.confer,confer); strcpy(outstr.rcvfil,rcvfil); strcpy(outstr.host,host); strcpy(outstr.pid,pid); strcpy(outstr.mode,mode); /* open the user directory file */ lock(usrfil); #ifdef SYSV2 usr=open(usrfil,O_RDWR|O_SYNC); #endif SYSV2 #ifdef SYSV3 usr=open(usrfil,O_RDWR|O_SYNC); #endif SYSV3 #ifdef BSD4 usr=open(usrfil,O_RDWR|O_FSYNC); #endif BSD4 #ifdef ULTRIX usr=open(usrfil,O_RDWR|O_FSYNC); #endif ULTRIX if(usr<NULL) { #ifdef SYSV2 usr=creat(usrfil,S_IREAD|S_IWRITE|O_SYNC); #endif SYSV2 #ifdef SYSV3 usr=creat(usrfil,S_IREAD|S_IWRITE|O_SYNC); #endif SYSV3 #ifdef BSD4 usr=creat(usrfil,S_IREAD|S_IWRITE|O_FSYNC); #endif BSD4 #ifdef ULTRIX usr=creat(usrfil,S_IREAD|S_IWRITE|O_FSYNC); #endif ULTRIX i=close(usr); usr=open(usrfil,O_RDWR); if(usr<NULL) { unlock(usrfil); return(-1); } } /* Look for zombies */ #ifndef SYSV2 fpos=lseek(usr,(long)NULL,SEEK_SET); #endif SYSV2 #ifdef SYSV2 fpos=lseek(usr,(long)NULL,BEGINNING); #endif SYSV2 if(fpos<(long)NULL) { unlock(usrfil); return(-3); } for(;;) { #ifdef SYSV2 numbyt=read(usr,&inpstr,(unsigned)reclen); #endif SYSV2 #ifdef SYSV3 numbyt=read(usr,&inpstr,(unsigned)reclen); #endif SYSV3 #ifdef BSD4 numbyt=read(usr,&inpstr,reclen); #endif BSD4 #ifdef ULTRIX numbyt=read(usr,&inpstr,reclen); #endif ULTRIX if(numbyt== NULL ) break; else if(numbyt!=reclen) { close( usr ); unlock(usrfil); return(NULL); } if(strncmp(inpstr.jsn," ",JSNLEN-1)!=NULL) { #ifndef SYSV2 fpos=lseek(usr,-(long)reclen,SEEK_CUR); #endif SYSV2 #ifdef SYSV2 fpos=lseek(usr,-(long)reclen,CURRENT); #endif SYSV2 if(fpos<(long)NULL) { unlock(usrfil); return(-5); } /* see if its a zombie */ sscanf( inpstr.pid, "%d", &ipid ); if(kill(ipid,NULL)<NULL) { strcpy(outstr.jsn," "); #ifdef SYSV2 numbyt=write(usr,&outstr,(unsigned)reclen); #endif SYSV2 #ifdef SYSV3 numbyt=write(usr,&outstr,(unsigned)reclen); #endif SYSV3 #ifdef BSD4 numbyt=write(usr,&outstr,reclen); #endif BSD4 #ifdef ULTRIX numbyt=write(usr,&outstr,reclen); #endif ULTRIX if(numbyt!=reclen) { unlock(usrfil); return(-6); } strncpy( zmbfil, inpstr.rcvfil, FLNMLN ); i = unlink( zmbfil ); } else { #ifndef SYSV2 fpos=lseek(usr,(long)reclen,SEEK_CUR); #endif SYSV2 #ifdef SYSV2 fpos=lseek(usr,(long)reclen,CURRENT); #endif SYSV2 } } } /* close it */ i=close(usr); unlock(usrfil); if(i!=NULL) return(-12); return(NULL); } \End\Of\Shar\ else echo "will not over write ./clnusr.c" fi chmod 400 ./clnusr.c if [ `wc -c ./clnusr.c | awk '{printf $1}'` -ne 3782 ] then echo `wc -c ./clnusr.c | awk '{print "Got " $1 ", Expected " 3782}'` fi if `test ! -s ./copyright.h` then echo "writing ./copyright.h" cat > ./copyright.h << '\End\Of\Shar\' /* @(#)copyright.h 1.3 */ static char copyright[] = "Slugnet COPYRIGHT 1988 James R. Purdon III"; /* Slugnet COPYRIGHT 1988 James R. Purdon III All rights reserved. This program may be used with the following conditions: 1. This program may be installed on any system. 2. If installed on a particular system, the author must be notified within 30 days of installation via postal sevice or electronic mail. Such notification should include the following information: A. Postal service address. B. Electronic mail address, if available. C. OS and hardware types. D. Contact name and phone number. This information will be kept strictly confidential. 3. Changes may be free made to the code with the following exceptions: A. Copyright notices must be left unchanged. B. The file copyright.h must be left unchanged. 4. Copies of this code may be freely distributed with the following provisions: A. Copies must include all files originally provided. B. No charge may be made, except for the cost of media and postage. 5. This code is used at your own risk. The author assumes no liability for any and all damages which may result from the use of this program. 6. The conditions described above may be changed at any time by the author, without notification. Contact: The author may be contacted at the following addresses: 1. INTERNET: purdon@cons1.mit.edu 2. Phone: 617-253-7954 3. Address: James R. Purdon III M.I.T. Building 11-124A Cambridge, MA 02178 */ \End\Of\Shar\ else echo "will not over write ./copyright.h" fi chmod 400 ./copyright.h if [ `wc -c ./copyright.h | awk '{printf $1}'` -ne 1672 ] then echo `wc -c ./copyright.h | awk '{print "Got " $1 ", Expected " 1672}'` fi if `test ! -s ./establish.c` then echo "writing ./establish.c" cat > ./establish.c << '\End\Of\Shar\' /* @(#)establish.c 1.3 */ #ifdef NETWORK #include "net.h" /* code to establish a socket */ int establish( portnum ) u_short portnum; { char myname[ MAXHOSTNAMELEN + 1 ]; int on = 1; int s; struct sockaddr_in sa; struct hostent *hp; bzero(&sa,sizeof(struct sockaddr_in)); /* clear our address */ gethostname(myname,MAXHOSTNAMELEN); /* who are we? */ hp= gethostbyname(myname); /* get our address info */ if (hp == NULL) /* we don't exist !? */ return(-1); sa.sin_family= hp->h_addrtype; /* this is our host address */ sa.sin_port= htons(portnum); /* this is our port number */ if ((s= socket(AF_INET,SOCK_STREAM,0)) < 0) /* create socket */ return(-1); setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)); if (bind(s,&sa,sizeof sa,0) < 0) return(-1); /* bind address to socket */ listen(s, 3); /* max # of queued connects */ return(s); } #endif NETWORK \End\Of\Shar\ else echo "will not over write ./establish.c" fi chmod 400 ./establish.c if [ `wc -c ./establish.c | awk '{printf $1}'` -ne 1035 ] then echo `wc -c ./establish.c | awk '{print "Got " $1 ", Expected " 1035}'` fi if `test ! -s ./find.c` then echo "writing ./find.c" cat > ./find.c << '\End\Of\Shar\' /* @(#)find.c 1.2 */ #include "slugnet.h" int find(string,c,line) /* returns position of c in string as integer */ char string[],c; int line; { int i; i=0; while(string[i]!=(char)NULL&&i<line) { if(string[i]==c) return(i); ++i; } return(-1); } \End\Of\Shar\ else echo "will not over write ./find.c" fi chmod 400 ./find.c if [ `wc -c ./find.c | awk '{printf $1}'` -ne 327 ] then echo `wc -c ./find.c | awk '{print "Got " $1 ", Expected " 327}'` fi if `test ! -s ./get_connect.c` then echo "writing ./get_connect.c" cat > ./get_connect.c << '\End\Of\Shar\' /* @(#)get_connect.c 1.2 */ #ifdef NETWORK #include "net.h" int get_connection(s) int s; /* socket created with establish() */ { struct sockaddr_in isa; /* address of socket */ int i; /* size of address */ int t; /* socket of connection */ i = sizeof(isa); /* find socket's address */ getsockname(s,&isa,&i); /* for accept() */ if ((t = accept(s,&isa,&i)) < 0) /* accept connection if there is one */ return(-1); return(t); } #endif NETWORK \End\Of\Shar\ else echo "will not over write ./get_connect.c" fi chmod 400 ./get_connect.c if [ `wc -c ./get_connect.c | awk '{printf $1}'` -ne 538 ] then echo `wc -c ./get_connect.c | awk '{print "Got " $1 ", Expected " 538}'` fi if `test ! -s ./getcfg.c` then echo "writing ./getcfg.c" cat > ./getcfg.c << '\End\Of\Shar\' /* @(#)getcfg.c 1.4 */ #include "slugnet.h" int getcfg(sysfil,access,actfil,bgnfil,billing,bilfil,deffil,dirfil,hlpfil,jsnfil,logset,modem,newfil,portstr,privs,profil,usrfil,valfil) /* gets system configuration from sysfil */ char sysfil[FLNMLN]; /* system configuration file */ char access[FLNMLN]; /* access mode for new users */ char actfil[FLNMLN]; /* system accounting file name */ char bgnfil[FLNMLN]; /* prelogin file name */ char billing[4]; /* billing option flag */ char bilfil[FLNMLN]; /* billing options file name */ char deffil[FLNMLN]; /* user definition file name */ char dirfil[FLNMLN]; /* user directory file name */ char hlpfil[FLNMLN]; /* help file name */ char jsnfil[FLNMLN]; /* jsn file name */ char logset[4]; /* login flag */ char modem[LINLEN]; /* modem initialization string */ char newfil[FLNMLN]; /* news file name */ char portstr[4]; /* port number in string form */ char privs[FLNMLN]; /* default privileges */ char profil[FLNMLN]; /* user prologue file name */ char usrfil[FLNMLN]; /* user directory file name */ char valfil[FLNMLN]; /* validated user list file name */ { char line[LINLEN]; FILE *sys; #ifdef SYSV2 FILE *fopen(); #endif SYSV2 int acc,act,bgn,bil,blf,def,dir,hlp,i,jsn,log,mod,new,por,pri,pro,usr,val; /* set flags */ acc=OFF; act=OFF; bgn=OFF; bil=OFF; blf=OFF; def=OFF; dir=OFF; hlp=OFF; jsn=OFF; log=OFF; mod=OFF; new=OFF; por=OFF; pri=OFF; pro=OFF; usr=OFF; val=OFF; /* check sysfil and set file names */ sys=fopen(sysfil,"r"); if(sys!=NULL) { while(feof(sys)==NULL) { fscanf(sys,"%79s",line); /* default access mode */ if(strncmp(line,"acc=",4)==NULL) { strncpy(access,line+4,FLNMLN-1); access[FLNMLN-1]=(char)NULL; acc=ON; } /* accounting file name */ else if(strncmp(line,"act=",4)==NULL) { strncpy(actfil,line+4,FLNMLN-1); actfil[FLNMLN-1]=(char)NULL; act=ON; } /* prelogin file name */ else if(strncmp(line,"bgn=",4)==NULL) { strncpy(bgnfil,line+4,FLNMLN-1); bgnfil[FLNMLN-1]=(char)NULL; bgn=ON; } /* billing option flag */ else if(strncmp(line,"bil=",4)==NULL) { strncpy(billing,line+4,3); billing[4]=(char)NULL; bil=ON; } /* billing options file name */ else if(strncmp(line,"blf=",4)==NULL) { strncpy(bilfil,line+4,FLNMLN-1); bilfil[FLNMLN-1]=(char)NULL; blf=ON; } /* default user definition file name */ else if(strncmp(line,"def=",4)==NULL) { strncpy(deffil,line+4,FLNMLN-1); deffil[FLNMLN-1]=(char)NULL; def=ON; } /* directory file name */ else if(strncmp(line,"dir=",4)==NULL) { strncpy(dirfil,line+4,FLNMLN-1); dirfil[FLNMLN-1]=(char)NULL; dir=ON; } /* help file name */ else if(strncmp(line,"hlp=",4)==NULL) { strncpy(hlpfil,line+4,FLNMLN-1); hlpfil[FLNMLN-1]=(char)NULL; hlp=ON; } /* jsn file name */ else if(strncmp(line,"jsn=",4)==NULL) { strncpy(jsnfil,line+4,FLNMLN-1); jsnfil[FLNMLN-1]=(char)NULL; jsn=ON; } /* login flag */ else if(strncmp(line,"log=",4)==NULL) { strncpy(logset,line+4,3); logset[4]=(char)NULL; log=ON; } /* modem initialization string */ else if(strncmp(line,"mod=",4)==NULL) { strncpy(modem,line+4,LINLEN-1); modem[LINLEN-1]=(char)NULL; repchar(modem,'_',' '); mod=ON; } /* news file name */ else if(strncmp(line,"new=",4)==NULL) { strncpy(newfil,line+4,FLNMLN-1); newfil[FLNMLN-1]=(char)NULL; new=ON; } /* port number */ else if( strncmp(line,"por=",4)==NULL) { strncpy(portstr,line+4,3); portstr[3]=(char)NULL; por=ON; if(sscanf(portstr,"%u",&i)==NULL) por=OFF; } /* default privileges */ #ifndef NETWORK else if(strncmp(line,"net=",4)==NULL) { pri=pri; } else if(strncmp(line,"pri=",4)==NULL) { strncpy(privs,line+4,FLNMLN-1); privs[FLNMLN-1]=(char)NULL; pri=ON; } #else else if(strncmp(line,"pri=",4)==NULL) { pri=pri; } else if(strncmp(line,"net=",4)==NULL) { strncpy(privs,line+4,FLNMLN-1); privs[FLNMLN-1]=(char)NULL; pri=ON; } #endif /* default user prologue file name */ else if(strncmp(line,"pro=",4)==NULL) { strncpy(profil,line+4,FLNMLN-1); profil[FLNMLN-1]=(char)NULL; pro=ON; } /* default user directory file name */ else if(strncmp(line,"usr=",4)==NULL) { strncpy(usrfil,line+4,FLNMLN-1); usrfil[FLNMLN-1]=(char)NULL; usr=ON; } /* user validation list file name */ else if(strncmp(line,"val=",4)==NULL) { strncpy(valfil,line+4,FLNMLN-1); valfil[FLNMLN-1]=(char)NULL; val=ON; } else { printf("%s\n",line); return(-1); } } } if(sys!=NULL) fclose(sys); /* if flag is not set, set default */ if(acc==OFF)strcpy(access,"immediate"); if(act==OFF)strcpy(actfil,"slugact.dat"); if(bgn==OFF)strcpy(bgnfil,"slugbgn.dat"); if(bil==OFF)strcpy(billing,"off"); if(blf==OFF)strcpy(bilfil,"slugbil.dat"); if(def==OFF)strcpy(deffil,"slugdef.dat"); if(dir==OFF)strcpy(dirfil,"slugdir.dat"); if(hlp==OFF)strcpy(hlpfil,"slughlp.dat"); if(jsn==OFF)strcpy(jsnfil,"slugjsn.dat"); if(log==OFF)strcpy(logset,"off"); if(mod==OFF)strcpy(modem,"ATZ S0=1 X1 E0 V0 S2=128"); if(new==OFF)strcpy(newfil,"slugnew.dat"); #ifdef SYSV2 if(pri==OFF)strcpy(privs,PRIVS); #endif SYSV2 #ifdef SYSV3 if(pri==OFF)strcpy(privs,PRIVS); #endif SYSV3 #ifdef BSD4 if(pri==OFF)strcpy(privs,PRIVS); #endif BSD4 #ifdef ULTRIX if(pri==OFF)strcpy(privs,PRIVS); #endif ULTRIX if(pro==OFF)strcpy(profil,"slugpro.dat"); if(usr==OFF)strcpy(usrfil,"slugusr.dat"); if(val==OFF)strcpy(valfil,"slugval.dat"); return(NULL); } \End\Of\Shar\ else echo "will not over write ./getcfg.c" fi chmod 400 ./getcfg.c if [ `wc -c ./getcfg.c | awk '{printf $1}'` -ne 9386 ] then echo `wc -c ./getcfg.c | awk '{print "Got " $1 ", Expected " 9386}'` fi if `test ! -s ./getjsn.c` then echo "writing ./getjsn.c" cat > ./getjsn.c << '\End\Of\Shar\' /* @(#)getjsn.c 1.2 */ #include "slugnet.h" int getjsn(jsn,jsnfil,rcvfil) /* creates the user's jsn and receiver file according to info found in sysfil */ char jsn[JSNLEN],jsnfil[FLNMLN],rcvfil[FLNMLN]; { FILE *djsn,*rcv; #ifdef SYSV2 FILE *fopen(); #endif SYSV2 int i; /* read jsn from jsn file */ lock(jsnfil); djsn=fopen(jsnfil,"r"); if(djsn==NULL) strcpy(jsn,"aaaa"); else { fscanf(djsn,"%4s",jsn); fclose(djsn); i=3; while(i>=0) { if(jsn[i]=='z') { jsn[i]='a'; --i; } else { jsn[i]=(char)((int)jsn[i]+1); i= -1; } } } /* printf("%s\n",jsnfil); */ djsn=fopen(jsnfil,"w"); if(djsn==NULL) { unlock(jsnfil); return(-1); } else { chmod(jsnfil,00600); fprintf(djsn,"%4s",jsn); fclose(djsn); unlock(jsnfil); } /* create receive file */ strcpy(rcvfil,jsn); strcat(rcvfil,"rcv.dat"); /* printf("%s\n",rcvfil); */ lock(rcvfil); /* mknod( rcvfil, 0010000 | 0000400 | 0000200, NULL ); */ rcv=fopen(rcvfil,"w"); if(rcv==NULL) { unlock(rcvfil); return(-2); } chmod(rcvfil,00600); fclose(rcv); unlock(rcvfil); return(NULL); } \End\Of\Shar\ else echo "will not over write ./getjsn.c" fi chmod 400 ./getjsn.c if [ `wc -c ./getjsn.c | awk '{printf $1}'` -ne 1721 ] then echo `wc -c ./getjsn.c | awk '{print "Got " $1 ", Expected " 1721}'` fi if `test ! -s ./lock.c` then echo "writing ./lock.c" cat > ./lock.c << '\End\Of\Shar\' /* @(#)lock.c 1.2 */ #include "slugnet.h" lock( string ) /* psuedo file locking */ char string[]; { char lstring[FLNMLN+FLNMLN]; int i,j; #ifdef SYSV2 unsigned sleep(),u; #endif SYSV2 #ifdef SYSV3 unsigned sleep(),u; #endif SYSV3 #ifdef ULTRIX void sleep(); #endif ULTRIX strcpy(lstring,"LCK_"); strcat(lstring,string); i = (int)NULL; j = (int)NULL; while( i <= (int)NULL ) { i = creat( lstring, O_CREAT | O_EXCL ); if( i <= (int)NULL ) { #ifdef SYSV2 sleep((unsigned)1); #endif SYSV2 #ifdef SYSV3 u=sleep((unsigned)1); #endif SYSV3 #ifdef BSD4 sleep((unsigned)1); #endif BSD4 #ifdef ULTRIX sleep((unsigned)1); #endif ULTRIX ++j; /* if wait is longer than timeout, stop */ if(j > TIMEOUT) goto quit; } } chmod(lstring,00600); close(i); quit:; } \End\Of\Shar\ else echo "will not over write ./lock.c" fi chmod 400 ./lock.c if [ `wc -c ./lock.c | awk '{printf $1}'` -ne 807 ] then echo `wc -c ./lock.c | awk '{print "Got " $1 ", Expected " 807}'` fi if `test ! -s ./lower.c` then echo "writing ./lower.c" cat > ./lower.c << '\End\Of\Shar\' /* @(#)lower.c 1.2 */ #include "slugnet.h" int lower(string) /* converts lower case to upper case */ char string[]; { static char low[27]="abcdefghijklmnopqrstuvwxyz"; static char high[27]="ABCDEFGHIJKLMNOPQRSTUVWXYZ"; int i,j; j=0; for(i=0;i<26;i++) j=j+repchar(string,high[i],low[i]); return(j); } \End\Of\Shar\ else echo "will not over write ./lower.c" fi chmod 400 ./lower.c if [ `wc -c ./lower.c | awk '{printf $1}'` -ne 351 ] then echo `wc -c ./lower.c | awk '{print "Got " $1 ", Expected " 351}'` fi if `test ! -s ./main.c` then echo "writing ./main.c" cat > ./main.c << '\End\Of\Shar\' /* @(#)main.c 1.6 */ #ifdef NETWORK #ifdef INTERLAN #include <signal.h> #define SIGCHLD SIGCLD #define SIGURG SIGUSR2 #endif INTERLAN #include "net.h" void cleanup(), task(); main( argc, argv ) int argc; char *argv[]; { char *rhost; extern int optind; extern char *optarg; int a, i, n, s, t; a = 0; n= 0; rhost = (char *)NULL; while(( i = getopt( argc, argv, "a:n:" )) != EOF ){ switch( i ) { /* address */ case 'a': a = 1; n = 0; rhost = optarg; break; case 'n': a = 0; n = 1; rhost = optarg; break; } } if( rhost != (char *)NULL ){ for(;;){ s = 0; while( s == 0 ){ if( a ) s = callbyaddr( rhost, PORTNUM ); if( n ) s = callbyhost( rhost, PORTNUM ); } i = slugnet( s, rhost ); close( s ); fprintf( stderr, "slugnet: Error %d\n", i ); exit(1); } } if ((s= establish(PORTNUM)) < 0) { /* plug in the phone */ perror("establish"); exit(1); } signal(SIGCHLD, cleanup); /* this eliminates zombies */ /* loop for phone calls */ for (;;) { /* get a connection */ if ((t= get_connection(s)) < 0) { /* EINTR might happen on accept(), */ if (errno == EINTR) /* try again */ continue; /* bad */ perror("accept"); exit(1); } /* try to handle connection */ switch(fork()) { /* bad news. scream and die */ case -1 : perror("fork"); close(s); exit(1); /* we're the child, do something */ case 0 : task(t); exit(0); /* we're the parent so look for another connection */ default : close( t ); continue; } } } #endif NETWORK \End\Of\Shar\ else echo "will not over write ./main.c" fi chmod 400 ./main.c if [ `wc -c ./main.c | awk '{printf $1}'` -ne 1786 ] then echo `wc -c ./main.c | awk '{print "Got " $1 ", Expected " 1786}'` fi if `test ! -s ./net.h` then echo "writing ./net.h" cat > ./net.h << '\End\Of\Shar\' /* @(#)net.h 1.5 */ /* net include file */ #include <sys/param.h> #include <errno.h> #ifdef INTERLAN #include <interlan/il_errno.h> #endif #include <signal.h> #include <stdio.h> #ifdef SYSV2 #include <sys/types.h> #endif SYSV2 #ifdef SYSV3 #ifdef INTERLAN #include <interlan/il_types.h> #else #include <sys/types.h> #endif #endif SYSV3 #ifdef INTERLAN #include <interlan/socket.h> #else #include <sys/socket.h> #endif #ifdef BSD4 #include <sys/wait.h> #endif BSD4 #ifdef ULTRIX #include <sys/wait.h> #endif ULTRIX #ifdef INTERLAN #include <interlan/in.h> #include <interlan/netdb.h> #define MAXHOSTNAMELEN 64 #else #include <netinet/in.h> #include <netdb.h> #endif #define PORTNUM 2727 /* use chat port number */ \End\Of\Shar\ else echo "will not over write ./net.h" fi chmod 400 ./net.h if [ `wc -c ./net.h | awk '{printf $1}'` -ne 724 ] then echo `wc -c ./net.h | awk '{print "Got " $1 ", Expected " 724}'` fi if `test ! -s ./rdline.c` then echo "writing ./rdline.c" cat > ./rdline.c << '\End\Of\Shar\' /* @(#)rdline.c 1.2 */ #include "slugnet.h" int rdline( fp, string, strln ) /* reads a file a line at a time */ FILE *fp; char string[]; int strln; { int c,i; for( i = 0; i < strln; ++i ) string[ i ] = (char)NULL; c=0; i=0; strln=strln-1; for(i = 0; i < strln; ++i ){ c=fgetc(fp); if( c == CR || c == LF ) { string[i]=(char)NULL; break; } else if( feof(fp)==NULL ) string[i]=(char)c; else { string[i]=(char)NULL; break; } } string[i]=(char)NULL; return(i); } \End\Of\Shar\ else echo "will not over write ./rdline.c" fi chmod 400 ./rdline.c if [ `wc -c ./rdline.c | awk '{printf $1}'` -ne 594 ] then echo `wc -c ./rdline.c | awk '{print "Got " $1 ", Expected " 594}'` fi if `test ! -s ./receive.c` then echo "writing ./receive.c" cat > ./receive.c << '\End\Of\Shar\' /* @(#)receive.c 1.5 */ #include "slugnet.h" #define VLDLEN 129 int receive( socket, string, maxlen, echoplex ) /* reads until a return is encountered, or maxlen-1 characters entered */ int socket; char string[]; int maxlen,echoplex; { /* 12345678911234567892123456789312345678941234567895123456789612345678971 23 456 78 9812345678991234 5 6 7 8 */ static char valid[VLDLEN]=" 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,./;'[]\`-=\\<>\?:\"{}~!@#$%^&*()+|_"; char buffer[2]; int c,err,i,tlen; tlen=0; for( i=0;i < maxlen; i++ ) string[i] = (char)NULL; --maxlen; i = 1; while( buffer[ 0 ] != '\n' ){ i = read( socket, buffer, 1 ); if( i > 0 ){ if(echoplex==ON){ #ifdef SYSV2 err = write( socket, buffer, i ); #endif SYSV2 #ifdef SYSV3 err = write( socket, buffer, i ); #endif SYSV3 #ifdef BSD4 err = write( socket, buffer, i ); #endif BSD4 #ifdef ULTRIX err = write( socket, buffer, i ); #endif ULTRIX } if( find(valid,buffer[0],strlen(valid)) != -1 ){ string[tlen] = buffer[ 0 ]; ++tlen; } if( tlen == maxlen ) buffer[ 0 ] = '\n'; } else if( i == 0 ){ strcpy( string, "exit" ); tlen = 5; break; } else { string[ 0 ] = ( char )NULL; tlen = 0; break; } } return(tlen); } #undef VLDLEN \End\Of\Shar\ else echo "will not over write ./receive.c" fi chmod 400 ./receive.c if [ `wc -c ./receive.c | awk '{printf $1}'` -ne 1392 ] then echo `wc -c ./receive.c | awk '{print "Got " $1 ", Expected " 1392}'` fi if `test ! -s ./repchar.c` then echo "writing ./repchar.c" cat > ./repchar.c << '\End\Of\Shar\' /* @(#)repchar.c 1.2 */ #include "slugnet.h" int repchar(string,old,new) /* replaces old character in a string with the new character */ char string[],old,new; { int c,i; c=0; i=0; while(string[i]!=(char)NULL) { if(string[i]==old) { string[i]=new; ++c; } ++i; } return(c); } \End\Of\Shar\ else echo "will not over write ./repchar.c" fi chmod 400 ./repchar.c if [ `wc -c ./repchar.c | awk '{printf $1}'` -ne 446 ] then echo `wc -c ./repchar.c | awk '{print "Got " $1 ", Expected " 446}'` fi if `test ! -s ./send_file.c` then echo "writing ./send_file.c" cat > ./send_file.c << '\End\Of\Shar\' /* @(#)send_file.c 1.2 */ #include "slugnet.h" int send_file(socket,filnam) /* transmits a file as an ascii stream */ int socket; char filnam[]; { static char line[32]="\0"; FILE *d_file; #ifdef SYSV2 FILE *fopen(); #endif SYSV2 int c,len; len=0; d_file=fopen(filnam,"r"); if(d_file!=NULL) { c=NULL; while(c!=EOF) { c=fgetc(d_file); sprintf(line,"%c",(char)c); len=len+transmit(socket,line,NOCRLF); } fclose(d_file); } len=len+transmit(socket," ",CRLF); return(len); } \End\Of\Shar\ else echo "will not over write ./send_file.c" fi chmod 400 ./send_file.c if [ `wc -c ./send_file.c | awk '{printf $1}'` -ne 706 ] then echo `wc -c ./send_file.c | awk '{print "Got " $1 ", Expected " 706}'` fi if `test ! -s ./setjsn.c` then echo "writing ./setjsn.c" cat > ./setjsn.c << '\End\Of\Shar\' /* @(#)setjsn.c 1.2 */ #include "slugnet.h" int setjsn(jsn,jsnfil) /* updates the local jsn to jsn, if conditions are met */ char jsn[JSNLEN],jsnfil[FLNMLN]; { char ojsn[ JSNLEN ]; FILE *djsn; #ifdef SYSV2 FILE *fopen(); #endif SYSV2 int i; /* read jsn from jsn file */ lock(jsnfil); djsn=fopen(jsnfil,"r"); if(djsn==NULL) strcpy(ojsn,"zzzz"); else { fscanf(djsn,"%4s",ojsn); fclose(djsn); } /* decide whether to update jsn or not */ for( i = 0; i < JSNLEN; ++i ){ if( i == 0 ){ if( jsn[ i ] == 'z' ){ if( ojsn[ i ] == 'a' ) break; } else if( jsn[ i ] > ojsn [ i ] ){ strcpy( ojsn, jsn ); break; } } else if( jsn[ i ] > ojsn [ i ] ){ strcpy( ojsn, jsn ); break; } } djsn=fopen(jsnfil,"w"); if(djsn==NULL) { unlock(jsnfil); return(-1); } else { chmod(jsnfil,00600); fprintf(djsn,"%4s",ojsn); fclose(djsn); unlock(jsnfil); } return(NULL); } \End\Of\Shar\ else echo "will not over write ./setjsn.c" fi chmod 400 ./setjsn.c if [ `wc -c ./setjsn.c | awk '{printf $1}'` -ne 1140 ] then echo `wc -c ./setjsn.c | awk '{print "Got " $1 ", Expected " 1140}'` fi if `test ! -s ./sighang.c` then echo "writing ./sighang.c" cat > ./sighang.c << '\End\Of\Shar\' /* @(#)sighang.c 1.2 */ #include "slugnet.h" #ifdef SYSV2 void sighang() #endif SYSV2 #ifdef SYSV3 void sighang() #endif SYSV3 #ifdef BSD4 sighang() #endif BSD4 #ifdef ULTRIX sighang() #endif ULTRIX { signal(SIGHUP, sighang); if(hungup==OFF) hungup=ON; } \End\Of\Shar\ else echo "will not over write ./sighang.c" fi chmod 400 ./sighang.c if [ `wc -c ./sighang.c | awk '{printf $1}'` -ne 260 ] then echo `wc -c ./sighang.c | awk '{print "Got " $1 ", Expected " 260}'` fi if `test ! -s ./sigquit.c` then echo "writing ./sigquit.c" cat > ./sigquit.c << '\End\Of\Shar\' /* @(#)sigquit.c 1.2 */ #include "slugnet.h" #ifdef SYSV2 void sigquit() #endif SYSV2 #ifdef SYSV3 void sigquit() #endif SYSV3 #ifdef BSD4 sigquit() #endif BSD4 #ifdef ULTRIX sigquit() #endif ULTRIX { signal(SIGQUIT,sigquit); if( hungup==OFF) hungup=ON; } \End\Of\Shar\ else echo "will not over write ./sigquit.c" fi chmod 400 ./sigquit.c if [ `wc -c ./sigquit.c | awk '{printf $1}'` -ne 261 ] then echo `wc -c ./sigquit.c | awk '{print "Got " $1 ", Expected " 261}'` fi if `test ! -s ./sigstop.c` then echo "writing ./sigstop.c" cat > ./sigstop.c << '\End\Of\Shar\' /* @(#)sigstop.c 1.2 */ #include "slugnet.h" #ifdef SYSV2 void sigstop() #endif SYSV2 #ifdef SYSV3 void sigstop() #endif SYSV3 #ifdef BSD4 sigstop() #endif BSD4 #ifdef ULTRIX sigstop() #endif ULTRIX { signal(SIGINT , sigstop); if( stopscroll==OFF) stopscroll=ON; } \End\Of\Shar\ else echo "will not over write ./sigstop.c" fi chmod 400 ./sigstop.c if [ `wc -c ./sigstop.c | awk '{printf $1}'` -ne 277 ] then echo `wc -c ./sigstop.c | awk '{print "Got " $1 ", Expected " 277}'` fi if `test ! -s ./sigterm.c` then echo "writing ./sigterm.c" cat > ./sigterm.c << '\End\Of\Shar\' /* @(#)sigterm.c 1.2 */ #include "slugnet.h" #ifdef SYSV2 void sigterm() #endif SYSV2 #ifdef SYSV3 void sigterm() #endif SYSV3 #ifdef BSD4 sigterm() #endif BSD4 #ifdef ULTRIX sigterm() #endif ULTRIX { signal(SIGTERM,sigterm); } \End\Of\Shar\ else echo "will not over write ./sigterm.c" fi chmod 400 ./sigterm.c if [ `wc -c ./sigterm.c | awk '{printf $1}'` -ne 230 ] then echo `wc -c ./sigterm.c | awk '{print "Got " $1 ", Expected " 230}'` fi if `test ! -s ./sigtstp.c` then echo "writing ./sigtstp.c" cat > ./sigtstp.c << '\End\Of\Shar\' /* @(#)sigtstp.c 1.2 */ #include "slugnet.h" #ifdef SYSV2 void sigtstp() #endif SYSV2 #ifdef SYSV3 void sigtstp() #endif SYSV3 #ifdef BSD4 sigtstp() #endif BSD4 #ifdef ULTRIX sigtstp() #endif ULTRIX { #ifdef ULTRIX signal(SIGTSTP , sigtstp); #endif ULTRIX #ifdef BSD4 signal(SIGTSTP , sigtstp); #endif BSD4 if( stopscroll==OFF) stopscroll=ON; } \End\Of\Shar\ else echo "will not over write ./sigtstp.c" fi chmod 400 ./sigtstp.c if [ `wc -c ./sigtstp.c | awk '{printf $1}'` -ne 365 ] then echo `wc -c ./sigtstp.c | awk '{print "Got " $1 ", Expected " 365}'` fi if `test ! -s ./sigurg.c` then echo "writing ./sigurg.c" cat > ./sigurg.c << '\End\Of\Shar\' /* @(#)sigurg.c 1.2 */ #ifdef NETWORK #include "slugnet.h" #ifdef SYSV2 void sigurg() #endif SYSV2 #ifdef SYSV3 void sigurg() #endif SYSV3 #ifdef BSD4 sigurg() #endif BSD4 #ifdef ULTRIX sigurg() #endif ULTRIX { signal(SIGURG,sigurg); if( hungup==OFF) hungup=ON; } #endif NETWORK \End\Of\Shar\ else echo "will not over write ./sigurg.c" fi chmod 400 ./sigurg.c if [ `wc -c ./sigurg.c | awk '{printf $1}'` -ne 284 ] then echo `wc -c ./sigurg.c | awk '{print "Got " $1 ", Expected " 284}'` fi if `test ! -s ./slughlp.dat` then echo "writing ./slughlp.dat" cat > ./slughlp.dat << '\End\Of\Shar\' *BELL: Bell Send a control-G to the user's terminal. *BROADCAST: Broadcast Sends a message to all conferences. *BYE: Bye Log off Slugnet ( and system ). *CLEAR: Clear Clears the user's message buffer. *COPYRIGHT: Slugnet COPYRIGHT 1988 James R. Purdon III All rights reserved. *DELAY: Delay Rolls out the terminal for a period of time ( default is 15 seconds ). This time can be changed using the 'Set delay' command. *EXIT: Exit Exit Slugnet. *HELP: Help n Displays help for n, where n is a Slugnet command or topic. A list of topics can be obtained by typing 'help' with no arguments. *JOIN: Join n Leave current conference and join or create n, where n is a conference name. Join will create new conferences. If a conference name begins with '-', it will not be displayed by a "Show conferences" command. If no conference name is given, the conference "Root" is joined. *REWIND: Rewind Rewinds the input stream. *RING: Ring n Sends a control-G sequence to n, where n is the JSN. *SCROLL: Scroll Enter scroll mode. In scroll mode, the user's receive buffer is scanned without pausing for input. When using a local copy of slugnet, scroll mode may be cancelled by entering the INTR control character. When using a remote copy the RETURN character should be used. *SEND: Send n Send a private message to n, where n is a JSN. If n is blank, message will be broadcast to all conference members. *SET CONFIGURATION: Set configuration Saves the user's configuration in a file called "slugcon.dat" in the current working directory. Slugnet will use this file to restore the user's configuration whenever it is invoked. *SET CONTINUOUS: Set continuous n Sets continuous mode to n, where n is ON or OFF. When continuous mode is ON, new messages are displayed automatically, and the prompt is not displayed (unless the user issues a "set prompt on" after entering continuous mode - this is NOT recommended). Setting continuous mode OFF will also set prompt mode on. The time between checks for new messages is specified by the SET DELAY command. *SET DEFINITION: Set definition n Sets the user definition file name to n. The default name is SLUGDEF.DAT. The user definition file should already exist and be a permanent file ( see the help entry for a description of the user definition file ). *SET DELAY: Set delay n Set the delay time to n seconds, where n is an integer between 0 and 9999> The delay time is used by scroll mode, the delay command, and continuous mode. *SET ECHO: Set echo n Set echo mode to n, where n is ON or OFF. If echo mode is set to OFF, messages sent by the user and lines from a redirected input file are not echoed. *SET LOGIN: Set login n Set the user's login name to n, where n is a text string. This option is only available when Slugnet is operating as a network server. If no login is specified, or Slugnet is unable to verify the specified login, the login will be set to 'unknown'. *SET NAME: Set name n Set the user's name to n, where n is a text string. If no name is specified, the name will be set to 'Anonymous'. *SET NOVICE: Set novice n Set novice mode to n, where n is ON or OFF. When novice mode is OFF, it is no longer necessary to precede message text with a blank. *SET PROMPT: Set prompt n Set prompt mode to n, where n is ON or OFF. When prompt mode is OFF, the name of the current conference is no longer printed on an input request. *SET RING: Set ring n Set ring mode to n, where n is ON or OFF. When ring mode is OFF, the user's terminal will not respond to 'Ring' commands given by other users. *SET TIMER: Set timer n Sets timer mode to n, where n is ON or OFF. When timer mode is ON, a time stamp is sent to the output stream while in scroll and wait wait modes. *SET WAIT: Set wait n Sets the string used by the 'wait' command to n. The default string is "From". *SHOW BUFFER Show buffer Displays the user's message buffer. *SHOW CONFERENCES: Show conferences Displays active conferences ( except for conferences whose name begins with '-' ). *SHOW CONFIGURATION: Show configuration Displays the user's current configuration. *SHOW HOSTS: Show hosts Displays the host names of the members of the current conference. *SHOW LOGINS: Show logins Displays the login names of the members of the current conference. This information may not be completely accurate. *SHOW MEMBERS: Show members Displays the JSN, login, host name, and name of all members of your current conference. The login name and host name may be truncated to fit on a line. *WAIT: Wait Enters scroll mode until a specified text string is received. The default text string is "From". The string can be set with the 'Set wait' command. When using a local copy of slugnet, wait mode may be cancelled by entering the INTR control character. When using a remote copy the RETURN character should be used. *WRITE: Write n Writes the user's message buffer to the file n. *OS COMMANDS: !n Pass n to the OS for processing, where n is a OS command ( n should be followed by a period ). After the command has been processed, Slugnet will resume. *ENTERING COMMANDS AND TEXT: Entering Commands and Message Text All input starting in column 1 will be interpreted as Slugnet commands. Input intended as message text should begin in column 2. A blank line or a "Send" command will flush the message buffer and send the text. If novice mode is set to OFF, message text does not have to begin in column 2. However, if the text contains an embedded command string starting in column 1, Slugnet will attempt to process the command. *RESERVED CHARACTERS: Reserved Characters Slugnet reserves the characters '<', '>', '*', and '!' in column 1 for input redirection, output redirection, comments, and OS command flag. *FILE REDIRECTION: File Redirection Slugnet allows redirection of the input and output streams, using <n or >n, where n is a valid name of a local Nos file ( >n will create the file ). The output stream is restored to the terminal by entering '>output' or '>'. The input stream is restored to the terminal when a file partition, '<input', or '<' is encountered in an input stream. *USER DEFINITION FILE: The User Definition File Slugnet allows the user to define his or her own command phrases by means of a definition file. When Slugnet encounters a command it does not understand, it attempts to open a definition file "slugdef.dat" ( SLUGnet DEFinition file ). If successful, it scans the contents of the file for a match with the user's command, and replaces the user's command with the definition. This allows for a great deal of freedom on the part of the user. For example, a user who was used to the "/" command signal of many conference programs might make the following definition file: * * "/" definition file for users who love "/" commands * commands * /who=show members; /w=show members; * /name=set name; /n=set name; * /h=help; * /s=send; * /b=bye; With this file, the user would be able use /b, /h, /n, /s, and /w as commands. If several different users share the same login, they can create definition files with names other than "slugdef.dat" and use the 'Set definition' command to set the definition file name. Definitions should start in column 1 of the definition file and terminate with a semicolon ( ';' ). The user's command should be separated from the definition by an equal sign ( '=' ). Neither the user's command or the definition should contain equal signs or semicolons, other than the separator and terminator. The definition does not have to be a Slugnet command, but may be any text string ( it will be interpreted just the same as if the user entered it directly ). *ADDITIONAL NOTES: Additional Notes 1. Slugnet Server messages may be recognized because they have the Server's user number in the "From" message. 2. Slugnet allows the installer to set various options, such as permissions to access certain commands. You may not be able to execute all of the commands for this reason. *USER PROLOGUE FILE: The User Prologue File A user prologue file is file of Slugnet commands that the user wants executed when Slugnet is started. By default, Slugnet looks for a file called "slugpro.dat", but the user may specify his own file name by using the "set prologue" command, followed by a "set configuration" command. *EOF: Help is available for the following commands and topics: Additional notes Bell Broadcast Bye Clear Copyright Delay Entering commands and text Exit File redirection Help Join OS commands Reserved characters Rewind Ring Scroll Send Set configuration Set continuous Set definition Set delay Set echo Set login Set name Set novice Set prologue Set prompt Set ring Set timer Set wait Show buffer Show conferences Show configuration Show hosts Show logins Show members User definition file User prologue file Wait Write To view the help for a particular topic, type 'help n', where n is the topic. \End\Of\Shar\ else echo "will not over write ./slughlp.dat" fi chmod 400 ./slughlp.dat if [ `wc -c ./slughlp.dat | awk '{printf $1}'` -ne 12822 ] then echo `wc -c ./slughlp.dat | awk '{print "Got " $1 ", Expected " 12822}'` fi if `test ! -s ./slugnet.1` then echo "writing ./slugnet.1" cat > ./slugnet.1 << '\End\Of\Shar\' .\" @(#)slugnet.1 1.1 .TH slugnet 1 .SH NAME slugnet \- use slugnet, a multiple\-user, interactive conferencing system .SH SYNTAX .B slugnet .SH DESCRIPTION .NXR "slugnet" .NXA "multiple\-user" "interactive" "conferencing" "system" .NXA "local" "slugnet program" .NXR "message" "interactive" The .PN slugnet is a multiple\-user conferencing system which allows users to simultaneously carry on conversations with several users at once, in much the same way that the write(1) or talk(1) commands allow a single user to communicate with just one other user. .PP Users limit the number of other users they are communicating with by joining conferences. Conferences are arbitrarily named groups of users. Messages from a user in a conference are by default only sent to other users in the same conference, although it is possible to send messages to a single user or all the users. .PP .PN slugnet has many installation\-dependent features. The program has its own help files which may be accessed by the .PN slugnet command "help". .SH RESTRICTIONS Access to some of commands described in the internal help may be installation\-dependent. .PP .SH "SEE ALSO" slugnetd(1) \End\Of\Shar\ else echo "will not over write ./slugnet.1" fi chmod 400 ./slugnet.1 if [ `wc -c ./slugnet.1 | awk '{printf $1}'` -ne 1170 ] then echo `wc -c ./slugnet.1 | awk '{print "Got " $1 ", Expected " 1170}'` fi echo "Finished archive 5 of 6" exit