Newsgroups: comp.sources.unix From: thalerd@quip.eecs.umich.edu (Dave Thaler) Subject: v28i045: yapp - conferencing system (similar to PicoSpan), Part01/05 Message-id: <1.770288965.8721@gw.home.vix.com> Sender: unix-sources-moderator@gw.home.vix.com Approved: vixie@gw.home.vix.com Submitted-By: thalerd@quip.eecs.umich.edu (Dave Thaler) Posting-Number: Volume 28, Issue 45 Archive-Name: yapp/part01 [ i have mixed feelings about publishing shareware, but since i have seen a lot of requests for software like this, and since the fee required is for usage beyond a demonstration period rather than for copying or distribution, i am relaxing the "no shareware" rule for this submission. --vix ] yapp - conferencing system Yapp is a shareware, customizable, text-based conferencing system for Unix. It is backward compatible with PicoSpan, an older, widely- used commercial conferencing system, and contains many additional features. Yapp has been tested under the following OS's: SunOS, Ultrix, HP/UX, BSDI, NeXT, Linux, and SCO Unix. thalerd@quip.eecs.umich.edu (Dave Thaler) #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'Changes' <<'END_OF_FILE' XChangeLog X XVERSION 2.2 Changes: X 1/22/94 updated help files with new information X 1/21/94 comment lines are now allowed in ulist and .cflist files X 1/20/94 finished news article incorporation so conflicts won't arise X 1/20/94 created log for kill/link/retire/unretire/freeze/thaw X 1/20/94 separated observer/readonly to allow joining readonly cfs X 1/20/94 improved performance by caching subject/author/config info X 1/14/94 fixed filename hash warnings X12/30/93 moved article # to article file X12/30/93 added partfile name hash code to sum X12/30/93 added timelocal define for ultrix X12/30/93 fixed warning in lib.c X XVERSION 2.1 Changes: X12/30/93 mods to use various sum file formats & byte orders X11/22/93 fixed sum saving bug when response added X XVERSION 2.0 Changes: X11/12/93 added auto-response number fixing routine per sno's request X11/09/93 added input redirection per russ' request X11/09/93 changed RF_SCRIBBLED to flag and added RF_EXPIRED X10/14/93 finished reading of news files with article incorporation X10/12/93 ADDED "d flags" command END_OF_FILE if test 1048 -ne `wc -c <'Changes'`; then echo shar: \"'Changes'\" unpacked with wrong size! fi # end of 'Changes' fi if test -f 'INFO' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'INFO'\" else echo shar: Extracting \"'INFO'\" \(3583 characters\) sed "s/^X//" >'INFO' <<'END_OF_FILE' XFollowing is a list of some differences between PicoSpan and YAPP. X XSome bugs in PicoSpan fixed in YAPP: X1) "browse 184-184" when 184 is retired, and 185 is active, shows 185. X2) Censoring/scribbling a previously censored/scribbled response repeats X the operation, adding unnecessary garbage to the censorlog. X3) "browse 1-10 new" sometimes displays items not in the specified X range. X4) "unforget" is an alias for "remember" at the OK prompt, but not at X the RFP prompt. X XThings that work differently: X1) Picospan: The range "1 1 1" does #1 three times. X YAPP : Does items only once. X2) "display size", "display fds": Give implementation-dependant X information on memory usage and open files. X3) Picospan: pwd,type,dir,chat,shell are builtins X YAPP : should be done by aliasing to unix commands in rc X4) Picospan: "participants" goes through passwd file X YAPP : goes through ulist file or passwd file if ulist doesn't exist. X If going through passwd file, create a ulist file. When X a new user joins a cf, adds login to ulist file. (Note that X a non-participant cannot officially join a secure conference.) X XSome additions in YAPP beyond PicoSpan functionality X----------------------------------------------- X XConferences: X * Fairwitnesses and ulist entries can be specified by either UID or X login name (instead of only by login), to resolve problem with old X logins being deleted and new users later using the same login. X * A facility exists for making a secure conference readonly to X general users (i.e. those who are not on an access list, or X who fail a password check, depending on the conference security X type). X * Newsgroup conferences are allowed. Yapp directly accesses files X in the news spool directory, and allows reading and responding as X if they were items and responses in a normal conference. X * All kill/link/freeze/thaw/retire/unretire activity is logged in X the conference directory. X * Comment lines are allowed in .cflist and ulist files. X * Responses to responses are allowed. X XCommands: X * "`command`" is expanded as in most Unix shells, with the output X of command replacing `command` in the input. X * "#-#" at rfp prompt displays a range of responses. X * "cfdir" command prompts for alternate name of .cfdir. This X is so that group accounts can put this in .cfonce, allowing X multiple work directories under a single home directory. X * "display flags" displays the status of all flags. X * "eval" command expands a sep string for the current conf or X for a specified item range. This can be used to define aliases X to give customized reports. X * "list" command (also "display conferences") gives information about all X existing conferences, using a new "listmsg" confsep. X * "reply #" sends mail to the author of a response, including the X response text in a format controlled by new "replymsg" itemsep X before invoking editor. X * "respond #" at rfp prompt marks the new response as a response to a X previous response. X * "set scribbler" turns on new scribbler flag. This will display the X scribbler's login when attempting to read a scribbled response. X XSeparators: X * Confseps are expanded in all redefineable prompts except "text". X * General: %D current timestamp (default style is 0) X * Confsep: %m lastmod of sum file if any (default style is 0) X * "listmsg" confsep controls format of list command output X * "replymsg" itemsep controls format of reply command text X * "newsmsg" itemsep controls format of response in a newsgroup cf. END_OF_FILE if test 3583 -ne `wc -c <'INFO'`; then echo shar: \"'INFO'\" unpacked with wrong size! fi # end of 'INFO' fi if test -f 'LICENSE' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'LICENSE'\" else echo shar: Extracting \"'LICENSE'\" \(1909 characters\) sed "s/^X//" >'LICENSE' <<'END_OF_FILE' XTHE AUTHOR DISCLAIMS ALL WARRANTIES RELATING TO THIS SOFTWARE, WHETHER XEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES XOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND ALL SUCH XWARRANTIES ARE EXPRESSLY AND SPECIFICALLY DISCLAIMED. NEITHER THE XAUTHOR NOR ANYONE ELSE WHO HAS BEEN INVOLVED IN THE CREATION, XPRODUCTION, OR DELIVERY OF THIS SOFWARE SHALL BE LIABLE FOR ANY XINDIRECT, CONSEQUENTIAL, OR INCIDENTAL DAMAGES OR CLAIMS. IN NO EVENT XSHALL THE AUTHOR'S LIABILITY FOR ANY DAMAGES EVER EXCEED THE PRICE PAID XFOR THE LICENSE TO USE THE SOFTWARE, REGARDLESS OF THE FORM OF CLAIM. XTHE PERSON USING THE SOFTWARE BEARS ALL RISK AS TO THE QUALITY AND XPERFORMANCE OF THE SOFTWARE. X Some states do not allow the exclusion of the limit of liability for Xconsequential or incidental damages, so the above limitation may not Xapply to you. X This agreement shall be governed by the laws of the State of Michigan Xand shall inure to the benefit of the author and any successors, Xadministrators, heirs and assigns. Any action or proceeding brought by Xeither party against the other arising out of or related to this Xagreement shall be brought only in a STATE or FEDERAL COURT of competent Xjurisdiction located in Washtenaw County, Michigan. The parties hereby Xconsent to in personam jurisdiction of said courts. X XThe author grants permission for this program to be copied and distributed, Xif no fee is charged. Otherwise, you must get written permission from the Xauthor to distribute copies of this program. If you use this software for Xmore than 90 days, you are required to purchase a registered copy for $100. XSite licenses negotiable. X X David G. Thaler X Armidale Software thaler@ais.org X 1929 Plymouth Rd. #2024 thaler@m-net.arbornet.org X Ann Arbor, MI 48105 thalerd@umich.edu X (313) 995-4638 END_OF_FILE if test 1909 -ne `wc -c <'LICENSE'`; then echo shar: \"'LICENSE'\" unpacked with wrong size! fi # end of 'LICENSE' fi if test -f 'Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Makefile'\" else echo shar: Extracting \"'Makefile'\" \(3904 characters\) sed "s/^X//" >'Makefile' <<'END_OF_FILE' XVERSION = 2 XMAJOR = 2 X X# Compiler XCC = cc X#CFLAGS = -a -p -I/usr/X11R5/include -D_NO_PROTO -DSTRINGS_ALIGNED -DVERSION=$(VERSION) X#CFLAGS = -g -DVERSION=$(VERSION) XCFLAGS = -O -DVERSION=$(VERSION) XXLIBS = -L/usr/X11R5/lib -lXm -lXt -lX11 X XOBJS1 = xbbs_ui_main.o xbbs_ui_read.o xbbs_ui_scan.o xbbs_ui_dialog.o XOBJS2 = $(OBJS1) xbbs_ui_enter.o xbbs_ui_help.o xbbs_ui_join.o xbbs_ui_quit.o XOBJS3 = $(OBJS2) xbbs_ui_respond.o X XSRCS1 = xbbs_ui_main.c xbbs_ui_read.c xbbs_ui_scan.c xbbs_ui_dialog.c XSRCS2 = $(SRCS1) xbbs_ui_enter.c xbbs_ui_help.c xbbs_ui_join.c xbbs_ui_quit.c XSRCS3 = $(SRCS2) xbbs_ui_respond.c X XTARFILE = bbs$(MAJOR).$(VERSION).tar X X# Executable file XBINFILE = dbbs X X# List of build files XOBJS = driver.o misc.o joq.o rfp.o conf.o change.o item.o edbuf.o arch.o system.o help.o macro.o sep.o sum.o range.o dates.o lib.o files.o xalloc.o news.o stats.o X XSRC1 = driver.c misc.c joq.c rfp.c conf.c change.c item.c edbuf.c arch.c XSRC2 = system.c help.c macro.c sep.c sum.c range.c dates.c lib.c files.c XSRC3 = xalloc.c news.c stats.c XSRCS = $(SRC1) $(SRC2) $(SRC3) X X$(BINFILE): $(OBJS) main.o X $(CC) $(CFLAGS) -n -o $(BINFILE) $(OBJS) main.o X chmod 4755 $(BINFILE) X Xall: $(BINFILE) xbbs X Xdepend: X makedepend -- $(CFLAGS) -- $(SRCS) X Xclean: X /bin/rm -f - $(OBJS) main.o X Xinstall: X cp $(BINFILE) /usr/local/bin/yapp X chmod 4711 /usr/local/bin/yapp X Xinstall2: X cp $(BINFILE) /usr/local/bin/bbs2 X chmod 4711 /usr/local/bin/bbs2 X Xtar: X tar -cvf $(TARFILE) README LICENSE INFO Changes Makefile *.h *.c help.tar data.tar X compress $(TARFILE) X Xshar: X makekit -nyapp -s90k README LICENSE INFO Changes Makefile *.h *.c help.tar.Z.uu data.tar.Z.uu X Xhelptar: X cd bbs X tar -cvf help.tar help X compress help.tar X Xlint: X lint -abchu $(SRCS) X Xxbbs: $(OBJS3) $(OBJS) X cc $(CFLAGS) -o xbbs $(OBJS3) $(OBJS) $(XLIBS) X chmod 4711 /usr/bbs/xbbs X Xdriver.o: config.h struct.h help.h conf.h system.h files.h sum.h edbuf.h misc.h Xdriver.o: driver.h xalloc.h lib.h macro.h joq.h rfp.h change.h item.h sep.h Xmisc.o: config.h struct.h globals.h files.h arch.h driver.h lib.h Xmisc.o: misc.h change.h help.h system.h macro.h range.h item.h sum.h sep.h Xjoq.o: config.h struct.h lib.h globals.h joq.h item.h sum.h xalloc.h files.h Xjoq.o: stats.h Xrfp.o: config.h struct.h system.h files.h range.h sep.h news.h stats.h Xrfp.o: globals.h rfp.h item.h macro.h driver.h lib.h sum.h xalloc.h arch.h Xconf.o: config.h struct.h globals.h sep.h xalloc.h driver.h stats.h Xconf.o: conf.h lib.h joq.h sum.h item.h range.h macro.h system.h change.h Xchange.o: config.h struct.h sep.h xalloc.h stats.h Xchange.o: globals.h conf.h lib.h joq.h sum.h item.h range.h macro.h system.h Xitem.o: config.h struct.h Xitem.o: macro.h item.h range.h globals.h lib.h arch.h system.h sum.h sep.h Xitem.o: conf.h xalloc.h edbuf.h main.h driver.h files.h news.h stats.h Xedbuf.o: config.h files.h Xedbuf.o: struct.h globals.h macro.h driver.h lib.h item.h edbuf.h help.h Xarch.o: config.h struct.h item.h lib.h globals.h arch.h xalloc.h news.h sum.h Xsystem.o: config.h struct.h lib.h xalloc.h macro.h globals.h files.h Xhelp.o: config.h struct.h lib.h globals.h conf.h Xmacro.o: config.h struct.h globals.h macro.h lib.h xalloc.h Xsep.o: config.h struct.h main.h news.h stats.h Xsep.o: item.h range.h globals.h sep.h change.h lib.h sum.h macro.h xalloc.h Xsum.o: config.h struct.h globals.h lib.h sum.h item.h xalloc.h files.h Xsum.o: macro.h sep.h news.h stats.h Xrange.o: config.h struct.h item.h range.h globals.h dates.h Xrange.o: macro.h lib.h sum.h stats.h xalloc.h Xdates.o: config.h Xlib.o: config.h struct.h xalloc.h globals.h lib.h Xlib.o: macro.h system.h main.h files.h Xfiles.o: config.h struct.h globals.h files.h xalloc.h system.h Xxalloc.o: config.h struct.h xalloc.h globals.h Xnews.o: config.h struct.h news.h arch.h item.h sep.h range.h sum.h files.h Xnews.o: globals.h xalloc.h lib.h stats.h rfp.h Xstats.o: config.h struct.h globals.h lib.h stats.h xalloc.h END_OF_FILE if test 3904 -ne `wc -c <'Makefile'`; then echo shar: \"'Makefile'\" unpacked with wrong size! fi # end of 'Makefile' fi if test -f 'README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README'\" else echo shar: Extracting \"'README'\" \(1525 characters\) sed "s/^X//" >'README' <<'END_OF_FILE' XTo install this program from scratch, you need to: X 1) Read and understand the LICENSE file. YAPP is shareware. X 2) Decide on what login to run the bbs as. Typically, a separate X account, such as 'cfadm' is created to own the bbs files. X Access to this account is needed for an administrator to X create new conferences. X 3) Edit config.h and change the first 4 defines to the right X directories for your system. X 4) Do "make". This program has been tested under the following OS's: X SunOS, Linux, SCO Unix, HPUX, Ultrix, NeXT, and BSDI. For anything X else, some other defines might be needed. Use the defines for the X other OS's in config.h as examples. X 5) Once you get a binary (the file 'bbs' in the same directory), you X can remove the .o files with "make clean". The binary can be X installed anywhere. X 6) The BBSDIR specified in config.h needs to contain a conflist file, X as described in the picospan.doc document. A subdirectory should X be created for each conference, each containing a login, logout, X and config file at minimum. The file data.tar contains sample X files. If you wish, this can be untarred in the BBSDIR. If your X BBSDIR is something other than /usr/bbs, then you will need to X modify the conflist file appropriately. X 7) Untar help.tar in the directory you specified for HELPDIR X XFor questions, comments, and bug reports, send mail to either: X thalerd@eecs.umich.edu X thaler@m-net.arbornet.org END_OF_FILE if test 1525 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'arch.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'arch.c'\" else echo shar: Extracting \"'arch.c'\" \(6673 characters\) sed "s/^X//" >'arch.c' <<'END_OF_FILE' X/* ARCH.C Copyright */ Xstatic char sccsid[] = "@(#)arch.c 1.8 93/05/01 (c)1993 thalerd"; X#include X#include X#include "config.h" X#include "struct.h" X#include "item.h" X#include "lib.h" X#include "globals.h" X#include "arch.h" X#include "xalloc.h" X#include "news.h" X#include "sum.h" X X#ifdef NEWS Xvoid Xcheck_news(re) Xresponse_t *re; X{ X /* News article? */ X if (xsizeof(re->text) && !strncmp(re->text[0],",N",2)) { X X /* Get article # */ X if (sscanf(re->text[0]+2,"%d",&(re->article))>0 X && re->article) { X xfree(re->text); X get_article(re); X } X X /* Get message id# */ X if (re->text && xsizeof(re->text)>1 && !strncmp(re->text[1],",M",2)) { X if (re->mid) xfree(re->mid); X re->mid=xstrdup(re->text[1]+2); X } X } X} X#endif X X/******************************************************************************/ X/* READ IN A SINGLE RESPONSE */ X/* Starting at current file position, read in a response. The ending file */ X/* position will be the start of the next response. Also, allocates space */ X/* for text which needs to be freed. */ X/* Assumes (sum) that this is always done within the current conference */ X/******************************************************************************/ Xvoid /* RETURNS: (nothing) */ Xget_resp(fp,re,fast,num) /* ARGUMENTS */ XFILE *fp; /* Current file position */ Xresponse_t *re; /* Response to fill in */ Xshort fast; /* Don't save the actual text? */ Xshort num; X{ X/* Xgr: at offset %ld got line %s Xget_resp: returning response author %s date %lx flags %d textoff %ld XCorrupted item (missing fields before offset %ld) X */ X char buff[MAX_LINE_LENGTH]; X char **who; X char done=0; X X#if 0 X/* ifdef NEWS */ X if (st_glob.c_security & CT_NEWS) { X news_get_resp(fp,re,fast,num); X return; X } X#endif X X /* Get response */ X if (re->offset>=0 && re->numchars>0 && fast==GR_ALL) { X if (fseek(fp,re->textoff,0)) { X sprintf(buff,"%d",re->textoff); X error("fseeking to ",buff); X } X re->text = grab_more(fp,",E",0); X#ifdef NEWS X check_news(re); X#endif X return; X } X if (re->offset>=0 && fseek(fp,re->offset,0)) { X sprintf(buff,"%d",re->textoff); X error("fseeking to ",buff); X } X if (re->offset<0) { /* Find start of response */ X short i,j; X X for (i=1; i<=num && re[-i].endoff<0; i++); /* find prev offset */ X for (j=i-1; j>0; j--) { X get_resp(fp,&(re[-j]),GR_OFFSET,num-j); X } X if (num && fseek(fp,re[-1].endoff,0)) { X sprintf(buff,"%d",re[-1].endoff); X error("fseeking to ",buff); X } X } X if (fast==GR_OFFSET) { X re->offset = ftell(fp); X while (ngets(buff,fp) && buff[1]!='T'); X re->textoff = ftell(fp); X while (ngets(buff,fp) && strcmp(buff,",E") && strncmp(buff,",R",2)); X if (!strncmp(buff,",R",2)) re->endoff = ftell(fp)-strlen(buff)-1; X else re->endoff = ftell(fp); X re->numchars = -1; X } else { X X#ifdef NEWS X if (re->mid) X xfree(re->mid); X re->mid = NULL; X re->article = 0; X#endif X re->parent = 0; X X/*printf("Lines: ");*/ X while (!done && !(status & S_INT)) { X if (!ngets(buff,fp)) break; /* UNK error */ X/*putchar(buff[1]);*/ X switch(buff[1]) { X case 'A': if (re->fullname) xfree(re->fullname); X re->fullname=xstrdup(buff+2); X break; X case 'D': sscanf(buff+2,"%lx",&(re->date)); break; X case 'E': done=1; re->endoff = ftell(fp); break; X /* case 'H': strcpy(subj,buff+2); break; */ X case 'R': re->offset = ftell(fp)-strlen(buff)-1; X sscanf(buff+2,"%hx",&(re->flags)); break; X/* X case 'M': if (re->mid) xfree(re->mid); X re->mid=xstrdup(buff+2); X break; X*/ X case 'P': sscanf(buff+2,"%hd",&(re->parent)); X re->parent++; X break; X case 'T': re->textoff = ftell(fp); X re->numchars= 0; X if (fast==GR_ALL) { X re->text = grab_more(fp,",E",0); X } else { X while (ngets(buff,fp) && strcmp(buff,",E") && strncmp(buff,",R",2)); X re->text = NULL; X } X re->numchars= ftell(fp)-re->textoff-3; /* -",E" */ X#ifdef NEWS X check_news(re); X#endif X done=1; X break; X case 'U': who=explode(buff+2,","); X re->uid = atoi(who[0]); X if (re->login) xfree(re->login); X re->login = xstrdup(who[1]); X xfree(who); X break; X } X } X } X if (flags & O_DEBUG) X printf("get_resp: returning response author %s date %lx flags %d textoff %ld\n", re->login,get_date(re->date,0),re->flags, re->textoff); X} X X/******************************************************************************/ X/* READ IN INFORMATION SUMMARIZING ALL THE RESPONSES IN AN ITEM */ X/* Note that this is currently only used within the current cf, but could */ X/* easily be used for a remote cf by passing in the right sum & re, confidx */ X/******************************************************************************/ Xvoid /* RETURNS: (nothing) */ Xget_item(fp,n,re,sum) /* ARGUMENTS: */ XFILE *fp; /* File pointer to read from */ Xshort n; /* Which item # we're reading */ Xresponse_t re[MAX_RESPONSES]; /* Buffer array to hold response info */ Xsumentry_t sum[MAX_ITEMS]; /* Buffer array holding info on items */ X{ X short i; X long offset=0; X X /* For each response */ X for (i=0; i'arch.h' <<'END_OF_FILE' X/* ARCH.H: @(#)arch.h 1.5 93/06/07 Copyright (c)1993 thalerd */ Xvoid get_resp PROTO((FILE *fp, response_t *re, SHORT fast, SHORT num)); Xvoid get_item PROTO((FILE *fp, SHORT n, response_t *re, sumentry_t *sum)); X X#define GR_ALL 0x0000 X#define GR_OFFSET 0x0001 X#define GR_HEADER 0x0002 END_OF_FILE if test 287 -ne `wc -c <'arch.h'`; then echo shar: \"'arch.h'\" unpacked with wrong size! fi # end of 'arch.h' fi if test -f 'change.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'change.h'\" else echo shar: Extracting \"'change.h'\" \(226 characters\) sed "s/^X//" >'change.h' <<'END_OF_FILE' X/* CHANGE.H: @(#)change.h 1.3 93/04/22 Copyright (c)1993 thalerd */ Xint display PROTO((int argc, char **argv)); Xint change PROTO((int argc, char **argv)); X#define CF_PUBLIC 5 /* 1st N+1 files of cfiles[] are ok for sep %Ng */ END_OF_FILE if test 226 -ne `wc -c <'change.h'`; then echo shar: \"'change.h'\" unpacked with wrong size! fi # end of 'change.h' fi if test -f 'conf.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'conf.h'\" else echo shar: Extracting \"'conf.h'\" \(527 characters\) sed "s/^X//" >'conf.h' <<'END_OF_FILE' X/* CONF.H: @(#)conf.h 1.2 94/01/20 (c)1993 thalerd */ Xint check PROTO((int argc, char **argv)); Xchar checkpoint PROTO((SHORT idx, CHAR sec)); Xint do_next PROTO((int argc, char **argv)); Xshort get_idx PROTO((char *elt, assoc_t *list, SHORT size)); Xchar join PROTO((char *conf, int observe)); Xint leave PROTO((int argc, char **argv)); Xint participants PROTO((int argc, char **argv)); Xint resign PROTO((int argc, char **argv)); Xvoid log PROTO((SHORT idx, char *str)); END_OF_FILE if test 527 -ne `wc -c <'conf.h'`; then echo shar: \"'conf.h'\" unpacked with wrong size! fi # end of 'conf.h' fi if test -f 'data.tar.Z.uu' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'data.tar.Z.uu'\" else echo shar: Extracting \"'data.tar.Z.uu'\" \(6343 characters\) sed "s/^X//" >'data.tar.Z.uu' <<'END_OF_FILE' Xbegin 644 data.tar.Z XM'YV0+EX &$BPH,&#"!,J7,BPH4.$("+>J%$#! 0-V+4F&'#8L2/,#Q^'!DQ XM) B*,F#,4$G#AHR/-%+*N/BPILV;.'/JW,FSI\^?0(,*'=HPH)PQ1),J)?C1 XM!@T:'C-N['AQ9,BJ)$_2F!$1I4J6&F'6N&&#YM*S:-.J79,J8 7$' XMS9NL$7. .%''31H\=.TJB#OWCIPT=,IDUMTN322/G2YDQ=-[(R0-BM6/7Q#VSF9-\+IT\.[\7SAE%F&F6;G@9;8>G.@408;;(SG7W#GC9%@ XM=YTI!H<<;[0!!W\B<.'&$VOHX)H";Y5HHE !C?&&&V:PD<8<=)QX8E-/1:41 XM1R*!E"-), DFBV.664:;"B0VQQ=TO E; XMEU^J2.<+>M)!XI2()JKHHHPV2E2*87[IJ%(?353115+AB%5).V9E4@U;P6"D XMJ$E^M!$,,UDTZ:JLMNIJ6Y .6JA K^I4*44V3M7I5?!Q>E*07_F845,RV%"6 XMJK4FJ^RRS"H4JYB$E@%C96^,>20 U1TZ,?&G>^MD0:#9;P76AL@Q* XMO/+2V_"]^=;P8[__FB8PP2 8C+#"B3%,P\/QSEOOO37DH .N& .\L1P%'SPP XMR&4P+ /)$==; [XQZ+!5P_ZZG!G''L\,PL(@S("SR0WOK*3/XK:L\= P=RQS XMPD>'?)("*K91AKM@A]WHLU_..D<=;8A=4+:\9DI5MYV.5..OY*H4@PWB2J12 XM#>JJ[???@/-4Y1QMH*HE WD<&@%-TA @Q5X$ 0#00&T$(0A=UB.>1H>!$ XM !0 8("@9J1A+4$"@,)Y "2&7H!E9W1FD # K X!Z*+#_D8=,1(T "K6X![ XM 76X"*-! QS=.0:X$R!&\6P<- 8JWN NP%S/"='&;T/- @JZ/P !H ''#' XM@EU_'?CZ[/M-=K33?A%#X&QO^[95<4?T%%=T!WMWWB"P 45FT+?V&?" @*L2 XM'.9@. 6P E%P$,8-#0P$$BA#&$@PXK80)TAA.E.91I#&1PH!5&)RH%5D$$. XM-D(#%@2,:F1P8!"H@(87':TW83"-M S% B+(@ @TB $.\'8#!U)! 32TH0W' XM4 RH B'0J NT_*^69'.=&JK'Z9N=#\=;8HD,ZA(_\(E@QH( XM\%8PX!NR=DG-:C)+@6-HH L*Y8(QF$$!,,C3RQ20$@6X#G:R*PCM;'<]W?&N XM(+\+WO#^>#QX*B\ S N=\Z G/>IUSGJAPY[VN =/\'5.?(@HW_G8D#YK.O2A XM[IL3M&:%3C?X39@8(>:N\MD,FZW*6*BADE?T[YG#24#FN=Z2,(Z$F'-RH@0^I;J5K7&E'2E6V'U#K# XM[KH'-HRZ;:/''(E+NA*J45G,)!@Y%4K92MC")J6E=7AI5M]P!Q ,+ QVZ$Q- XM Z:80H$ C$PMPQN/\(8WD$$,>2A#"$BT3P;ULWK7,^/VZ/J]\#T %@I%'UH- XM2]O:KJ^7<"7K19&DK6'JZIC>^A;_O!*N(+:D4D0BX#1MR]SFVD2N5!UA'= P XMAH&U09PPY)H9,GC=? *@M-%#GC\# %#1J9:@OC-H ,1'C-@R=+;.C:]\V8?; XM:3W/M+L-8&\S^ENXY34B,3#21YD9I)=()"4G7>Y\%RS?I/;&ACFDP@Y!"3WN XMA;5T W-!1)+ '\S(2PR*25AHW@/:5X)@N\RY V)T,X=:WI3!,(XQX.I+AQ>< XMEZ[NLJM&@ABKY XMREAV*(T_(UNOB4W'_<7??QNFD@&'M 8P . -BJ3<++M9I0Z^H8DMN]#TG?A@ XMFMUPATL&XDLN)S$DIDX.42P'%=.!Q2[.Y9L7S6@IO4]-=\H,K?)K*?OAM5<@ XM^!2P5E+4KC> XM+T]G;2"LC@K#J^CLQHN%=E9KKNI4+R<>0 D "$!^NH[W?$MM)DEONZZ\;=N. XM_=LK(FME):,*,/\"' -ZX5K>"%<6-K4)Z39U\YOA?.' Y !.!;RN6NE$';G- XM+==WHD[=#VCON^>7\)*;_"'TCK1FQ(UO_>H[S,:$C[T^U5<:H"J9 #;AL4[. XM)FY(GV*2 -,K567/^Z00JUC' XM8C"R-!5KT>O=(,PJ7<-,CZ.<*>O8<_-.ZF5@@0*J?ED^A_C/6"OQH+]>Z+"W XM^(UZ#[UMSRYI>*LZ@*SF;]LY]=^,@.NCLZ[UW$,M^MI'28$,]+4#D?#S]WHM XMJB#(0AC@ (?1LJ"$)D2A"EGHPI?%D 5!( -DT_">,U3QJVQXC\3OY$ ? E&( XM-2C"R%AP1".\@4&,E:R<KQ1P)0W5N\![@MW[0D0:3]$D)PEB] XM 7YO) ,@. 1E$G\S=08V-@:'$2Z@7]S4$7487UR( 9A XM0"; QWA42(2P\T8S ((B(((\6((H&!+'H8+QYS6&Y#6]L1RGQ :;]& ATQM: XM=33RPGATP8@ XM)@ ?2 XMD1KT9W]/%$5YT($?Z'\ >$KQ(B(T](7QHH22!USD 9Z(!J?) (#69 G XM1@;<(2)'@(.*$8\$63-E*07EGV'\8)BV "((32%4#*"+VX4)KQ ++(0&A$@#2 ?< 0)RI8[NN#MG@ ;LD45SX!Z0]Y0':(\1(2)S^7084@=W XM.5;M!WDJ*0=YV6)\69-',Q=D-7_Z. =N< +\409X $CS.))),!=RI7YU:9AX XM24B.^1XU^4E(B$&+E$.369.(=P4*X@;%B&DY=!QCE3V,J09OT!E:Y$UL")&- XM%SN9>!>OB6>(AP).0$J5I1\B.9(F-DHJ (&J WY4$L1CJ XM>'5]MHE>E0:91QUE@!@*PIA5D 1$L)@+^!%1YP83I!@HX)N)D4$J.1=056(5 XME0*?U)6F='Z3I(Q:6#-T8:(JF7TM&A$5E7\E&GAQ,3!;1WFX*1EWTAN2*%.Y XM*9I#-X>_5U$***%!X'6(Y")II)F U!LFJ4D&PX0@,)XP99YC]%1N($5=68P- XM=W14*@>],:,ND&=3555VT7?:28 $. 9RZ%B ]$FK5(Q6Y74'8V*FN9?2874* XM,@9K\$D>629N6%-\Q(=)=YYM^AQ-Y)])JD;AX48X):%.L!MS< :%"0=(UZ"9 XMA4,PY9V,E3"()WS$-W\P"!U2% :&*G;J6)-S4(QAQ7C'T1NGU%D-$I3/$1W3 XM(8/O8:N\L448M*FO-(/6NJPSJ'ZN:*S>H2#4<3XPQ8_9^AY<")_[2(",=))' XM!Z>B&*$@$ 0,8C4,4AF=L08O8 ;OF)"$HA]W\ (ON#V1X08#&Y,W&%EI9$.P XM0R8*0YL?X:FRJG2\NCW0T9)?ZE,9XC50A*@LUG?4FH$@\'")F:&)2:P9>T'< XMFCUU=!?IZH6T&I/H=SYD8%8>U 9A"9$0*J$B 9@675@H((VI)D#&!?3.I9M XM0%7\4077<90,,@>?9&AX:8:\ P>\HP )\'Y(A[.4!X:2B$B!Y[,;"[28*%:= XM8;5EE:JN,0(M, *W6$IF *L7LHS\T9"3:&*@J(=:^[(LF[$BX$U!J8(_JZUS XMZXMHNDJ9(5,PND@P^GM:^W!!B7A-9ZS**G2XZ*J[ ZO JB)] 9?8R1Z/%S!* XM)"\/]X^1]THS*UG%V ;%8T@721?36+'/*ATBVAM]$1>,*9Z254%V\7O.>K'3 XMX;=V2QTMDH=Q.;Q/IQ@PLA^2<:.HVR#%"X%^^X29(;ACJZU$6W5:E#VP"B-% XM^(J,R8=-=(VQBJ,4EP!I*I[AP8DB2C,,D[=+UW2?VV=4JGUW01@5@KIID$72 XM@K5=&3M!RD0PDB$(B35@*!UPZ;?M9[U2QUN&ZIBJ4F/ XMVI6,%P:\8Q>,J;4YQ+>GVQG550?82EE8*\0ZA ?\$9[@BY*Q2@<8\C%<%TN- XM%8LPS$$L? 9"6XDPC+4@9I(5Z09V\ 9K6E-:)QTR+"U=^!XUC(MR$+?*Z(N: XM9$7):\7;VH69Y(I!S,;J"GS"E@!."(7-*\1^FSU;A81IH(1WHH)TT$15J)+R XM@IMSH,B,S)C1*[F*IV+U.L%(_!&5G(43=P)6BG'R4A?]MQ\ALR&BZ;+7:F*A XMO,A#BJY^[(5F-04P7$7[(1USL+,:^\(+U'?9.X,BZYW6BK^Z$09#.L<;TAN: XM*4(;XAJ)P<0BD+&#IW(B4@(K>D;DVX@[-$&PB@*$P<-LL%7?44$V! /I*:\, XM*B8PG,T,(XDPDK2J!']HHYA>E:W4([7RBL4$F0<'/4LL#,-1/,4.#<5[F\5?=+W:IYF& XM1B9B 1)G29B1^IAXIIIJKSK&Z(C>DDFZDHINJ*+ XEZJ*FG!LQ2D8T^LI:FZ/4L:,]ZLKQQP9!.K=#RC!2>Z3O48R6 4DF X Xend END_OF_FILE if test 6343 -ne `wc -c <'data.tar.Z.uu'`; then echo shar: \"'data.tar.Z.uu'\" unpacked with wrong size! fi # end of 'data.tar.Z.uu' fi if test -f 'dates.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dates.c'\" else echo shar: Extracting \"'dates.c'\" \(3361 characters\) sed "s/^X//" >'dates.c' <<'END_OF_FILE' X/* DATES.C */ Xstatic char *sccsid="@(#)dates.c 1.2 93/05/10 Copyright (c)1993 thalerd"; X#include X#include X#include X#include X#include "config.h" X Xstatic char *month[]={ X "jan_uary","feb_ruary","mar_ch","apr_il","may","jun_e", X "jul_y","aug_ust","sep_tember","oct_ober","nov_ember","dec_ember" X}; X Xvoid Xget_num(a,ptr) Xint *a; Xchar **ptr; X{ X while (isdigit(**ptr)) { *a = (*a)*10 + **ptr - '0'; (*ptr)++; } X} X Xvoid Xget_str(m,ptr) Xint *m; Xchar **ptr; X{ X int i,l; X char buff[20],*p; X X p = *ptr; X for (l=0; isalpha(p[l]) && l<19; l++) buff[l]=p[l]; X buff[l]=0; X X for (i=0; i<12; i++) { X if (match(buff,month[i])) { X (*m) = i+1; X (*ptr) += l; X } X } X} X Xvoid Xget_time(tm,ptr) Xstruct tm *tm; Xchar **ptr; X{ X tm->tm_hour=0; X get_num(&(tm->tm_hour),ptr); X if (**ptr==':') { X (*ptr)++; X tm->tm_min=0; X get_num(&(tm->tm_min),ptr); X } else tm->tm_min = 0; X if (**ptr==':') { X (*ptr)++; X tm->tm_sec=0; X get_num(&(tm->tm_sec),ptr); X } else tm->tm_sec = 0; X while (**ptr==' ') (*ptr)++; X if (tolower(**ptr)=='a' || tolower(**ptr)=='m') tm->tm_hour %= 12; X if (tolower(**ptr)=='p' || tolower(**ptr)=='n') tm->tm_hour = (tm->tm_hour%12)+12; X} X X/* Take a string, return time_t value */ Xchar * Xgetdate(tt,str) Xtime_t *tt; Xchar *str; X{ X struct tm tm; X time_t t; X int i,sgn; X char *ptr,*ptr2; X int a=0,b=0,c=0,m=0; X X time(&t); /* get current time */ X memcpy(&tm,localtime(&t),sizeof(tm)); X tm.tm_sec = tm.tm_min = tm.tm_hour = 0; /* ok on grex */ X X ptr=str; X while (*ptr==' ') ptr++; /* skip leading spaces */ X if (*ptr=='+' || *ptr=='-') { X sgn = (*ptr=='+')? 1 : -1; X ptr++; i=0; X while (isdigit(*ptr)) { i = i*10 + (*ptr - '0'); ptr++; } X *tt = timelocal(&tm) + sgn*i*24*60*60; X } else { X X /* Leading (timestamp) */ X if (*ptr=='(') { /* ) */ X ptr++; X get_time(&tm,&ptr); X while (*ptr && *ptr!=')') ptr++; X if (*ptr==')') ptr++; X while (isspace(*ptr)) ptr++; X } X X /* Get date */ X if (isdigit(*ptr)) get_num(&a,&ptr); X else get_str(&m,&ptr); X while (*ptr==' ' || *ptr=='/' || *ptr=='-') ptr++; X if (isdigit(*ptr)) get_num(&b,&ptr); X else get_str(&m,&ptr); X while (*ptr==' ' || *ptr=='/' || *ptr=='-' || *ptr==',') ptr++; X if (isdigit(*ptr)) get_num(&c,&ptr); X if (c>1900) c-=1900; X if (c) tm.tm_year = c; X X /* Assign values to date structure */ X if (m) { X tm.tm_mon = m-1; X if (a) tm.tm_mday = a; X else if (b) tm.tm_mday = b; X } else if (a*b) { X tm.tm_mon = a-1; X tm.tm_mday = b; X/* X } else { X *tt = LONG_MAX; X printf("Bad date near \"%s\"\n",ptr); X return ptr; X*/ X } X X /* Trailing (timestamp) */ X while (isspace(*ptr)) ptr++; X if (*ptr=='(') { /* ) */ X ptr++; X get_time(&tm,&ptr); X while (*ptr && *ptr!=')') ptr++; X if (*ptr==')') ptr++; X X /* Trailing timestamp */ X } else if (isdigit(*ptr)) X get_time(&tm,&ptr); X /* do we need to advance ptr? */ X X *tt = timelocal(&tm); X memcpy(&tm,localtime(tt),sizeof(tm)); X } X return ptr; X} END_OF_FILE if test 3361 -ne `wc -c <'dates.c'`; then echo shar: \"'dates.c'\" unpacked with wrong size! fi # end of 'dates.c' fi if test -f 'dates.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dates.h'\" else echo shar: Extracting \"'dates.h'\" \(134 characters\) sed "s/^X//" >'dates.h' <<'END_OF_FILE' X/* DATES.H: @(#)dates.h 1.5 93/06/07 Copyright (c)1993 thalerd */ X#include Xchar *getdate PROTO((time_t *tt,char *str)); END_OF_FILE if test 134 -ne `wc -c <'dates.h'`; then echo shar: \"'dates.h'\" unpacked with wrong size! fi # end of 'dates.h' fi if test -f 'driver.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'driver.h'\" else echo shar: Extracting \"'driver.h'\" \(532 characters\) sed "s/^X//" >'driver.h' <<'END_OF_FILE' X/* DRIVER.H: @(#)driver.h 1.16 93/06/07 Copyright (c)1993 thalerd */ X Xvoid endbbs PROTO(()); Xvoid init PROTO(()); Xchar source PROTO((char *dir,char *file)); Xchar command PROTO((char *cmd, int lvl)); Xvoid print_prompt PROTO((U_CHAR mode)); Xchar ok_cmd_dispatch PROTO((int argc, char **argv)); Xchar get_command PROTO((char *deflt)); Xvoid handle_int PROTO(()); Xvoid handle_pipe PROTO(()); Xvoid handle_other PROTO((int sig, int code, void *scp, char *addr)); Xvoid open_cluster PROTO((char *bdir, char *hdir)); Xvoid open_pipe PROTO(()); END_OF_FILE if test 532 -ne `wc -c <'driver.h'`; then echo shar: \"'driver.h'\" unpacked with wrong size! fi # end of 'driver.h' fi if test -f 'edbuf.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'edbuf.h'\" else echo shar: Extracting \"'edbuf.h'\" \(554 characters\) sed "s/^X//" >'edbuf.h' <<'END_OF_FILE' X/* EDBUF.H: @(#)edbuf.h 1.5 93/06/07 Copyright (c)1993 thalerd */ Xint text_read PROTO((int argc, char **argv)); Xint text_write PROTO((int argc, char **argv)); Xint text_edit PROTO((int argc, char **argv)); Xint text_print PROTO((int argc, char **argv)); Xint text_clear PROTO((int argc, char **argv)); Xint text_abort PROTO((int argc, char **argv)); Xint text_done PROTO((int argc, char **argv)); Xchar text_cmd_dispatch PROTO((int argc, char **argv)); Xchar text_loop PROTO((int new, int resp)); Xchar edb_cmd_dispatch PROTO((int argc, char **argv)); END_OF_FILE if test 554 -ne `wc -c <'edbuf.h'`; then echo shar: \"'edbuf.h'\" unpacked with wrong size! fi # end of 'edbuf.h' fi if test -f 'files.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'files.c'\" else echo shar: Extracting \"'files.c'\" \(6618 characters\) sed "s/^X//" >'files.c' <<'END_OF_FILE' X/* MOPEN.C */ Xstatic char sccsid[]="@(#)files.c 1.4 93/05/11 Copyright (c)1993 thalerd"; X#include X#include X#include X#include X#include /* to get O_CREAT, etc */ X#include X#include X#include "config.h" X#include "struct.h" X#include "globals.h" X#include "files.h" X#include "xalloc.h" X#include "system.h" /* to get SL_OWNER */ X X/* Information about each open file */ Xtypedef struct fd_tt { X char *filename; X short flg; X int fd; X struct fd_tt *next; X} fd_t; Xstatic fd_t *first_fd=0; X X#ifdef FLOCKF X/******************************************************************************/ X/* FLOCK FOR SYSTEMS WITH LOCKF() ONLY */ X/******************************************************************************/ X#include X#define LOCK_EX 2 X#define LOCK_NB 4 Xint Xflock(fd, operation) Xint fd, operation; X{ X return lockf(fd,(operation & LOCK_NB)? F_TLOCK : F_LOCK,0L); X} X#endif X X/******************************************************************************/ X/* DUMP ALL FILES CURRENTLY OPEN */ X/******************************************************************************/ Xvoid /* RETURNS: (nothing) */ Xmdump() /* ARGUMENTS: (none) */ X{ X fd_t *this; X X for (this=first_fd; this; this = this->next) { X printf("mdump: fd=%d filename='%s' flg=%x\n",this->fd, X this->filename, this->flg); X } X} X X/******************************************************************************/ X/* ADD AN OPEN FD TO THE DATABASE (FROM SPOPEN/MOPEN) */ X/******************************************************************************/ Xvoid Xmadd(fd,file,flg) Xint fd; Xchar *file; Xshort flg; X{ X fd_t *this; X X /* Save info for debugging */ X this = (fd_t *)malloc(sizeof(fd_t)); X this->fd = fd; X this->filename = xstrdup(file); X this->flg = flg; X this->next = first_fd; X first_fd = this; X} X X/******************************************************************************/ X/* OPEN A FILE AND LOCK IT FOR EXCLUSIVE ACCESS */ X/******************************************************************************/ XFILE * /* RETURNS: Open file pointer, or NULL on error */ Xmopen(file,flg) /* ARGUMENTS: */ Xchar *file; /* Filename to open */ Xlong flg; /* Flag: 0=append only, 1=create new (only) */ X{ X struct stat st; X short err; X int fd, X perm; X char modestr[3]; X FILE *fp; X char buff[MAX_LINE_LENGTH]; X#ifdef NOFLOCK X short timeout=0; X#endif X X if (flags & O_DEBUG) X printf("mopen: flags=%x\n",flg); X X /* Process flags */ X if (flg & (O_EXCL|O_NOCREATE)) err=stat(file,&st); X if ( err && (flg & O_NOCREATE)) { X if (!(flg & O_SILENT)) error("opening ",file); X return NULL; /* append: doesn't exist */ X } else if (!err && (flg & O_CREAT) && (flg & O_EXCL)) { X error("creating ",file); X return NULL; /* create: already exists */ X } X perm=umask(0); X X#ifdef NOFLOCK X /* For auxilary file locking */ X if (flg & O_LOCK) { X sprintf(buff,"%s.lock",file); X while ((fd=open(buff,O_WRONLY|O_CREAT|O_EXCL,0400))<0 X && errno==EEXIST && timeout<10 && !(status & S_INT)) { X if (flg & O_NOBLOCK) X return NULL; /* can't lock */ X timeout++; X sleep(1); X } X if (fd>=0) close(fd); X X /* Currently overrides lock after timeout X * X * if (timeout>=10 || (status & S_INT)) { X * error("locking ",buff); X * umask(perm); X * return NULL; X * } X */ X if (timeout>=10) printf("Warning: overriding lock on %s\n",file); X } X#endif X X /* Open file */ X fd=open(file,flg & O_PASSTHRU,(flg & O_PRIVATE)? 0600 : 0644); X if (fd < 0) { X error("opening ",file); X#ifdef NOFLOCK X if (flg & O_LOCK) X rm(buff,SL_OWNER); /* unlock */ X#endif X umask(perm); X return NULL; X } X X#ifndef NOFLOCK X /* Lock it */ X if (flg & O_LOCK) { X if (flock(fd,(flg & O_NOBLOCK)? LOCK_EX|LOCK_NB : LOCK_EX)) { X umask(perm); X return NULL; X } X } X#endif X X umask(perm); X if (flg & O_APPEND) lseek(fd,0L,2); X X /* Determine mode string */ X if ((flg & O_WPLUS)==O_WPLUS) strcpy(modestr,"w+"); X else if ((flg & O_W )==O_W ) strcpy(modestr,"w"); X else if ((flg & O_APLUS)==O_APLUS) strcpy(modestr,"a+"); X else if ((flg & O_A )==O_A ) strcpy(modestr,"a"); X else if ((flg & O_RPLUS)==O_RPLUS) strcpy(modestr,"r+"); /* should be next to last */ X else if ((flg & O_R )==O_R ) strcpy(modestr,"r"); /* MUST be last */ X else printf("KKK Invalid mopen mode\n"); X X /* Save info for debugging */ X madd(fd,file,flg); X X if ((fp = fdopen(fd,modestr))==NULL) { X sprintf(buff,"%s for %s after mode %x\n",file,modestr,flg); X error("reopening ",buff); X } X return fp; X} X X/******************************************************************************/ X/* CLOSE AND UNLOCK A FILE */ X/******************************************************************************/ Xint /* RETURNS: non-zero on error */ Xmclose(fp) /* ARGUMENTS: */ XFILE *fp; /* File pointer to close */ X{ X fd_t *this,*prev=0; X int ret; X#ifdef NOFLOCK X char buff[MAX_LINE_LENGTH]; X#endif X X fflush(fp); X for (this=first_fd; this && this->fd != fileno(fp); prev=this, this = this->next); X if (!this) { X (void)printf("Tried to close unopened file\n"); X return 1; /* not found */ X } X if (!fp) { X (void)printf("Tried to close null file\n"); X return 1; X } X X ret=fclose(fp); /* flock automatically closes */ X X#ifdef NOFLOCK X /* For auxilary file locking */ X if (this->flg & O_LOCK) { X sprintf(buff,"%s.lock",this->filename); X rm(buff,SL_OWNER); X } X#endif X X /* Remove from debugging database */ X if (!prev) first_fd = this->next; X else prev->next = this->next; X xfree(this->filename); X free((char *)this); X X return ret; X} X X/******************************************************************************/ X/* VERIFY THAT ALL FILES HAVE BEEN CLOSED */ X/******************************************************************************/ Xvoid Xmcheck() X{ X if (!first_fd) { X if (flags & O_DEBUG) X puts("mcheck: Everything closed.\n"); X } else { X printf("mcheck: Error, failed to close the following:\n"); X mdump(); X } X} END_OF_FILE if test 6618 -ne `wc -c <'files.c'`; then echo shar: \"'files.c'\" unpacked with wrong size! fi # end of 'files.c' fi if test -f 'files.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'files.h'\" else echo shar: Extracting \"'files.h'\" \(1075 characters\) sed "s/^X//" >'files.h' <<'END_OF_FILE' X/* MOPEN.H: @(#)files.h 1.2 93/05/11 Copyright (c)1993 thalerd */ X X/* mopen() flags */ X#include X#define O_PASSTHRU 0x00000FFF /* actual flags to open() */ X#define O_PRIVATE 0x00001000 /* mode 0600 (vs. 0644) */ X#define O_NOCREATE 0x00002000 /* don't create (must exist) */ X#define O_LOCK 0x00004000 /* need to lock it? */ X#define O_PIPE 0x00008000 /* is this a pipe? */ X#define O_SILENT 0x00010000 /* is this a pipe? */ X#define O_NOBLOCK 0x00020000 /* don't block, fail on no lock */ X#define O_R (O_RDONLY|O_NOCREATE) /* "r" */ X#define O_W (O_WRONLY|O_CREAT|O_TRUNC |O_LOCK) /* "w" */ X#define O_A (O_WRONLY|O_CREAT|O_APPEND|O_LOCK) /* "a" */ X#define O_RPLUS (O_RDWR |O_NOCREATE |O_LOCK) /* "r+" */ X#define O_WPLUS (O_RDWR |O_CREAT|O_TRUNC |O_LOCK) /* "w+" */ X#define O_APLUS (O_RDWR |O_CREAT|O_APPEND|O_LOCK) /* "a+" */ X XFILE *mopen PROTO((char *file,long fl)); Xint mclose PROTO((FILE *fp)); Xvoid mcheck PROTO(()); Xvoid mdump PROTO(()); END_OF_FILE if test 1075 -ne `wc -c <'files.h'`; then echo shar: \"'files.h'\" unpacked with wrong size! fi # end of 'files.h' fi if test -f 'globals.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'globals.h'\" else echo shar: Extracting \"'globals.h'\" \(1268 characters\) sed "s/^X//" >'globals.h' <<'END_OF_FILE' X/* GLOBALS.H: @(#)globals.h 1.2 94/01/20 (c)1993 thalerd */ X X/* GLOBAL VARS */ X#include X#include X X/* Status info */ Xextern flag_t flags; Xextern unsigned char mode; Xextern flag_t status; X X/* Conference info */ Xextern short current; /* current index to cflist */ Xextern short confidx; /* current index to conflist */ Xextern short joinidx; /* current index to conflist */ Xextern char **cflist; /* User's cflist */ Xextern char **fw; /* List of FW's for current conf */ X X/* System info */ Xextern char bbsdir[MAX_LINE_LENGTH]; Xextern char helpdir[MAX_LINE_LENGTH]; Xextern assoc_t conflist[MAX_LIST_LENGTH]; /* System table of conferences */ Xextern short maxconf; /* maximum index to conflist */ Xextern option_t option[]; Xextern char hostname[MAX_LINE_LENGTH]; X X/* Info on the user */ Xextern uid_t uid; Xextern char login[L_cuserid]; Xextern char home[MAX_LINE_LENGTH]; /* User's home directory */ Xextern char work[MAX_LINE_LENGTH]; /* User's work directory */ X X/* Item info */ Xextern status_t st_glob, X st_new; Xextern response_t re[MAX_RESPONSES]; Xextern sumentry_t sum[MAX_ITEMS]; Xextern partentry_t part[MAX_ITEMS]; END_OF_FILE if test 1268 -ne `wc -c <'globals.h'`; then echo shar: \"'globals.h'\" unpacked with wrong size! fi # end of 'globals.h' fi if test -f 'help.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'help.c'\" else echo shar: Extracting \"'help.c'\" \(3115 characters\) sed "s/^X//" >'help.c' <<'END_OF_FILE' X/* HELP.C */ Xstatic char sccsid[] = "@(#)help.c 1.12 93/04/21 Copyright (c)1993 thalerd"; X#include X#include X#include X#include X#include "config.h" X#include "struct.h" X#include "lib.h" X#include "globals.h" X#include "conf.h" /* for get_idx */ X X/* Index files of help text, in order by mode */ X#define HELPINDEX "Index" X Xvoid Xshow_help(count,argc,argv,file,hdr) Xint *count; /* Number of arguments */ Xint argc; Xchar **argv; /* Argument list */ Xchar *file;/* Filename of list */ Xchar *hdr; /* Help display header */ X{ X assoc_t helplist[MAX_LIST_LENGTH]; X short helpsize,idx=0,i,j; X char *dir,*fil; X char **header,name[MAX_LINE_LENGTH]; X X /* Set location */ X if (file[0]=='%') { X dir = bbsdir; X fil = file+1; X } else { X dir = helpdir; X fil = file; X } X X /* Is this a text file or a list? */ X if (!(header = grab_file(dir,fil,GF_HEADER))) return; X if (strcmp(header[0],"!")) { X if (*count < argc) X printf("Sorry, only this message available.\n"); X else if (hdr) X printf("**** %s ****\n",hdr); X if (!more(dir,fil)) X printf("UNK Can't find help file %s/%s.\n",dir,fil); X xfree(header); X return; X } X xfree(header); X X /* Read in help list */ X if (!grab_list(dir,fil,helplist,&helpsize)) return; X X /* Display requested file */ X if (*count>=argc) { X X /* No arguments, use default file */ X show_help(count,argc,argv,helplist[0].location,hdr); X X } else { X X idx=get_idx(argv[*count],helplist,helpsize); X (*count)++; X if (idx<0) X printf("Sorry, no help available for \"%s\"\n",argv[(*count)-1]); X X /* %filename indicates file is in bbsdir not helpdir */ X else if (helplist[idx].location[0]=='%') { X show_help(count,argc,argv,helplist[idx].location,hdr); X X /* normal help files are in helpdir & get a header displayed */ X } else { X char buff[MAX_LINE_LENGTH]; X X strcpy(name,compress(helplist[idx].name)); X for (j=strlen(name)-1; j>=0; j--) X name[j]=toupper(name[j]); X if (hdr) X sprintf(buff,"%s %s",hdr,name); X else X strcpy(buff,name); X show_help(count,argc,argv,helplist[idx].location,buff); X } X } X X /* Free the list */ X for (i=0; i'help.h' <<'END_OF_FILE' X/* HELP.H: @(#)help.h 1.1 93/04/22 Copyright (c)1993 thalerd */ X Xint help PROTO((int argc, char **argv)); END_OF_FILE if test 106 -ne `wc -c <'help.h'`; then echo shar: \"'help.h'\" unpacked with wrong size! fi # end of 'help.h' fi if test -f 'item.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'item.h'\" else echo shar: Extracting \"'item.h'\" \(1004 characters\) sed "s/^X//" >'item.h' <<'END_OF_FILE' X/* ITEM.H: @(#)item.h 1.4 94/01/20 (c)1993 thalerd */ X#include X X#define RF_NORMAL 0x0000 X#define RF_CENSORED 0x0001 X#define RF_SCRIBBLED 0x0002 X#define RF_EXPIRED 0x0004 X Xint do_enter PROTO((sumentry_t *this, char *sub, char **text, SHORT idx, X sumentry_t *sum, partentry_t *part, status_t *stt, X long art, char *mid, U_SHORT uid, char *login, X char *fullname)); Xint do_find PROTO((int argc, char **argv)); Xint do_kill PROTO((int argc, char **argv)); Xint do_read PROTO((int argc, char **argv)); Xint enter PROTO((int argc, char **argv)); Xint fixseen PROTO((int argc, char **argv)); Xint forget PROTO((int argc, char **argv)); Xint freeze PROTO((int argc, char **argv)); Xint linkfrom PROTO((int argc, char **argv)); Xint remember PROTO((int argc, char **argv)); Xvoid show_header PROTO(()); Xvoid show_resp PROTO((FILE *fp)); Xvoid show_range PROTO(()); Xvoid show_nsep PROTO((FILE *fp)); END_OF_FILE if test 1004 -ne `wc -c <'item.h'`; then echo shar: \"'item.h'\" unpacked with wrong size! fi # end of 'item.h' fi if test -f 'joq.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'joq.c'\" else echo shar: Extracting \"'joq.c'\" \(6603 characters\) sed "s/^X//" >'joq.c' <<'END_OF_FILE' X/* JOQ.C */ Xstatic char sccsid[] = "@(#)joq.c 1.24 93/06/09 Copyright (c)1993 thalerd"; X#include X#include X#include X#include X#include "config.h" X#include "struct.h" X#include "lib.h" X#include "globals.h" X#include "joq.h" X#include "item.h" X#include "sum.h" X#include "xalloc.h" X#include "files.h" X#include "stats.h" X Xstatic int pdebug = 0; X X/******************************************************************************/ X/* DISPATCH CONTROL TO APPROPRIATE JOQ COMMAND FUNCTION */ X/******************************************************************************/ Xchar /* RETURNS: 0 on abort, 1 else */ Xjoq_cmd_dispatch(argc,argv) /* ARGUMENTS: */ Xint argc; /* Number of arguments */ Xchar **argv; /* Argument list */ X{ X char **ulst,file[MAX_LINE_LENGTH],buff[MAX_LINE_LENGTH]; X short j; X char **config; X X if (match(argv[0],"r_egister") X || match(argv[0],"j_oin") X || match(argv[0],"p_articipate")) { X if (confidx>=0) leave(0,(char**)0); X write_part((char *)NULL); X st_new.c_status |= CS_JUSTJOINED; X mode=M_OK; X X /* Add login to ulist */ X if (config = get_config(joinidx)) { X char sec; X sec=(xsizeof(config)>CF_SECURITY)? atoi(config[CF_SECURITY]) : 0; X if (!(sec & CT_READONLY) X && (sec & CT_BASIC)!=CT_PRESELECT X && (sec & CT_BASIC)!=CT_PARANOID) { X X sprintf(file,"%s/%s",conflist[joinidx].location,"ulist"); X sprintf(buff,"%s\n",login); X if (!(ulst=grab_file(conflist[joinidx].location,"ulist", X GF_SILENT|GF_WORD|GF_IGNCMT))) X write_file(file,buff); X else { X for (j=xsizeof(ulst)-1; X j>=0 && strcmp(ulst[j],login) && uid!=atoi(ulst[j]); X j--); X if (j<0) X write_file(file,buff); X xfree(ulst); X } X } X } X X } else if (match(argv[0],"o_bserver")) { X sumentry_t sum2[MAX_ITEMS]; X short i; X X if (confidx>=0) leave(0,(char**)0); X st_new.c_status |= (CS_OBSERVER|CS_JUSTJOINED); X mode=M_OK; X X /* Initialize part[] */ X for (i=0; isumtime = 0; X } X X /* Create WORK/.name.cf */ X sprintf(buff,"%s/%s",work,file); X if (flags & O_DEBUG) printf("join: Partfile=%s\n",buff); X if (pdebug) printf("WRITING %s\n",buff); X X /* FORK */ X if (cpid=fork()) { /* parent */ X if (cpid<0) return; /* error: couldn't fork */ X while ((wpid = wait((int *)0)) != cpid && wpid != -1); X } else { /* child */ X setuid(getuid()); X setgid(getgid()); X X /* KKK*** in the future, allocate string array of #items+2, X save lines in there, call dump_file, and free the array */ X if ((fp=mopen(buff,O_W))==NULL) /* "w" */ X exit(1); X fprintf(fp,"!\n%s\n",st_glob.fullname); X X if (pdebug) printf("first %d last %d\n",stt->i_first, stt->i_last); X for (i=stt->i_first; i<=stt->i_last; i++) { X if (pdebug) printf("sum3[%d]=%d ",i-1,sum3[i-1].nr); X if (sum3[i-1].nr || part[i-1].last) { X fprintf(fp,"%d %d %X\n",i,part[i-1].nr,part[i-1].last); X if (pdebug) printf(": %d %d %X",i,part[i-1].nr,part[i-1].last); X fflush(fp); X } X if (pdebug) printf("\n"); X } X mclose(fp); X exit(0); X } /* ENDFORK */ X X if (flags & O_DEBUG) printf("write_part: fullname=%s\n",st_glob.fullname); X} X X/******************************************************************************/ X/* READ IN A USER PARTICIPATION FILE FOR SOME CONFERENCE */ X/******************************************************************************/ Xchar /* RETURNS: (nothing) */ Xread_part(partfile,part,stt,idx) /* ARGUMENTS: */ Xchar *partfile; /* Filename */ Xpartentry_t part[MAX_ITEMS]; /* Array to fill in */ Xstatus_t *stt; Xshort idx; X{ X char **partf,buff[MAX_LINE_LENGTH]; X short sz,i,a,b; X long d; X struct stat st; X sumentry_t sum2[MAX_ITEMS]; X X for (i=0; ifullname,st_glob.fullname); X if (!(partf=grab_file(work,partfile,GF_SILENT))) { X X /* Newly joined, Initialize part[] */ X for (i=0; isumtime = 0; X for (i=stt->i_first+1; ii_last; i++) time(&(part[i-1].last)); X X return 0; X } X sz=xsizeof(partf); X if (!sz || strcmp(partf[0],"!")) X printf("UNK Invalid participation file format.\n"); X else if (sz>1) X strcpy(stt->fullname,partf[1]); X for (i=2; i0) X stt->parttime = st.st_mtime; X X if (flags & O_DEBUG) printf("read_part: fullname=%s\n",st_glob.fullname); X return 1; X} END_OF_FILE if test 6603 -ne `wc -c <'joq.c'`; then echo shar: \"'joq.c'\" unpacked with wrong size! fi # end of 'joq.c' fi if test -f 'joq.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'joq.h'\" else echo shar: Extracting \"'joq.h'\" \(265 characters\) sed "s/^X//" >'joq.h' <<'END_OF_FILE' X/* JOQ.H: @(#)joq.h 1.5 93/06/07 Copyright (c)1993 thalerd */ Xchar joq_cmd_dispatch PROTO((int argc, char **argv)); Xvoid write_part PROTO((char *partfile)); Xchar read_part PROTO((char *partfile, partentry_t part[], status_t *st, X SHORT idx)); END_OF_FILE if test 265 -ne `wc -c <'joq.h'`; then echo shar: \"'joq.h'\" unpacked with wrong size! fi # end of 'joq.h' fi if test -f 'lib.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'lib.h'\" else echo shar: Extracting \"'lib.h'\" \(1127 characters\) sed "s/^X//" >'lib.h' <<'END_OF_FILE' X/* LIB.H: @(#)lib.h 1.16 93/06/07 Copyright (c)1993 thalerd */ X X/* Grab file options */ X#define GF_SILENT 0x0001 X#define GF_WORD 0x0002 X#define GF_HEADER 0x0004 X#define GF_IGNCMT 0x0008 /* ignore comment lines? */ X Xchar match PROTO((char *a, char *b)); Xchar cat PROTO((char *dir, char *file)); Xchar **grab_file PROTO((char *dir, char *file, CHAR silent)); Xchar **grab_more PROTO((FILE *fp, char *end, CHAR silent)); Xshort searcha PROTO((char *elt, char **arr, SHORT start)); Xchar **explode PROTO((char *str, char *sep)); Xvoid implode PROTO((char *buff, char **arr, char *sep, SHORT start)); Xchar *get_password PROTO(()); Xchar *ngets PROTO((char *str, FILE *fp)); Xchar grab_list PROTO((char *dir,char *file, assoc_t list[], short *size)); Xchar get_yes PROTO((char *pr)); Xchar *get_date PROTO((time_t t,CHAR sty)); X#ifdef NOSTRNICMP Xint strnicmp PROTO((char *s1, char *s2, int n)); X#endif Xchar *compress PROTO((char *str)); Xchar *noquote PROTO((char *str,int x)); Xvoid error PROTO((char *str1,char *str2)); Xchar *lower_case PROTO((char *str)); Xchar write_file PROTO((char *file, char *buff)); END_OF_FILE if test 1127 -ne `wc -c <'lib.h'`; then echo shar: \"'lib.h'\" unpacked with wrong size! fi # end of 'lib.h' fi if test -f 'macro.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'macro.h'\" else echo shar: Extracting \"'macro.h'\" \(548 characters\) sed "s/^X//" >'macro.h' <<'END_OF_FILE' X/* MACRO.H: @(#)macro.h 1.16 93/06/07 Copyright (c)1993 thalerd */ X/* Define macro mask */ X#define DM_OK 0x0001 X#define DM_VAR 0x0002 X#define DM_PARAM 0x0004 X#define DM_RFP 0x0008 X#define DM_SUPERSANE 0x0040 X#define DM_SANE 0x0080 X#define DM_ENVAR 0x0100 X Xvoid undef_macro PROTO((U_SHORT i)); Xvoid undef_name PROTO((char *name)); Xchar *expand PROTO((char *mac, U_SHORT mask)); Xint define PROTO((int argc, char **argv)); Xvoid def_macro PROTO((char *name, int mask, char *value)); END_OF_FILE if test 548 -ne `wc -c <'macro.h'`; then echo shar: \"'macro.h'\" unpacked with wrong size! fi # end of 'macro.h' fi if test -f 'main.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'main.c'\" else echo shar: Extracting \"'main.c'\" \(2130 characters\) sed "s/^X//" >'main.c' <<'END_OF_FILE' X/* MAIN.C */ Xstatic char sccsid[] = "@(#)main.c 1.5 93/04/21 Copyright (c)1993 thalerd"; X#include X#include "config.h" X X/******************************************************************************/ X/* PROCESS COMMAND LINE ARGUMENTS */ X/****************************************************************************** XFunction: main XCalled by: (user) XArguments: command line arguments XReturns: (nothing) XCalls: init to set up global variables X join to start up first conference X command to process user commands XDescription: This function parses the command line arguments, X and acts as the main driver. X*******************************************************************************/ Xvoid /* RETURNS: (nothing) */ Xmain(argc, argv) /* ARGUMENTS: */ Xint argc; /* Number of command line arguments */ Xchar **argv; /* Array of command line arguments */ X{ X init(argc,argv); /* set up globals */ X X while (get_command(NULL)); X endbbs(0); X} X X/******************************************************************************/ X/* The following output routines simply call the standard output routines. */ X/* In the Motif version, the w-output routines send output to the windows */ X/******************************************************************************/ Xvoid Xwputs(s) Xchar *s; X{ X fputs(s,stdout); /* NO newline like puts() does */ X} X Xextern char evalbuf[MAX_LINE_LENGTH]; X/* KKK note that the eval stuff won't work with MOTIF until this is X changed around a bit */ Xvoid Xwfputs(s,stream) Xchar *s; XFILE *stream; X{ X if (stream) X fputs(s,stream); X else X strcat(evalbuf,s,MAX_LINE_LENGTH-strlen(evalbuf)-1); X} X Xvoid Xwputchar(c) Xchar c; X{ X putchar(c); X} X Xvoid Xwfputc(c,fp) Xchar c; XFILE *fp; X{ X char s[2]; X X if (fp) X fputc(c,fp); X else { X s[0]=c; s[1]='\0'; X strcat(evalbuf,s,MAX_LINE_LENGTH-strlen(evalbuf)-1); X } X} X Xvoid Xwgets(a,b) Xchar *a,*b; X{ X} END_OF_FILE if test 2130 -ne `wc -c <'main.c'`; then echo shar: \"'main.c'\" unpacked with wrong size! fi # end of 'main.c' fi if test -f 'main.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'main.h'\" else echo shar: Extracting \"'main.h'\" \(208 characters\) sed "s/^X//" >'main.h' <<'END_OF_FILE' X/* MAIN.H: @(#)main.h 1.2 93/04/21 Copyright (c)1993 thalerd */ Xvoid wputchar PROTO((char c)); Xvoid wputs PROTO((char *s)); Xvoid wfputs PROTO((char *s,FILE *fp)); Xvoid wfputc PROTO((char c,FILE *fp)); END_OF_FILE if test 208 -ne `wc -c <'main.h'`; then echo shar: \"'main.h'\" unpacked with wrong size! fi # end of 'main.h' fi if test -f 'misc.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'misc.h'\" else echo shar: Extracting \"'misc.h'\" \(557 characters\) sed "s/^X//" >'misc.h' <<'END_OF_FILE' X/* MISC.H: @(#)misc.h 1.3 93/05/20 Copyright (c)1993 thalerd */ X Xint cluster PROTO((int argc, char **argv)); Xint date PROTO((int argc, char **argv)); Xint echo PROTO((int argc, char **argv)); Xint eval PROTO((int argc, char **argv)); Xint mail PROTO((int argc, char **argv)); Xint cd PROTO((int argc, char **argv)); Xint do_source PROTO((int argc, char **argv)); Xint test PROTO((int argc, char **argv)); Xint do_umask PROTO((int argc, char **argv)); Xint set_cfdir PROTO((int argc, char **argv)); Xchar misc_cmd_dispatch PROTO((int argc, char **argv)); END_OF_FILE if test 557 -ne `wc -c <'misc.h'`; then echo shar: \"'misc.h'\" unpacked with wrong size! fi # end of 'misc.h' fi if test -f 'news.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'news.h'\" else echo shar: Extracting \"'news.h'\" \(545 characters\) sed "s/^X//" >'news.h' <<'END_OF_FILE' X/* NEWS.H: @(#)news.h 1.2 94/01/20 (c)1993 thalerd */ X X#ifdef NEWS Xchar *dot2slash PROTO((char *str)); Xint make_rnhead PROTO((response_t *re, SHORT par)); Xchar *message_id PROTO((char *conf, SHORT itm, SHORT rsp, response_t *re)); Xvoid get_article PROTO((response_t *re)); Xint news_item_sum PROTO(( long i, sumentry_t *sum, X partentry_t *part, status_t *stt, SHORT idx)); Xvoid refresh_news PROTO((sumentry_t *sum, partentry_t *part, status_t *stt, X SHORT idx)); X#endif END_OF_FILE if test 545 -ne `wc -c <'news.h'`; then echo shar: \"'news.h'\" unpacked with wrong size! fi # end of 'news.h' fi if test -f 'range.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'range.h'\" else echo shar: Extracting \"'range.h'\" \(1226 characters\) sed "s/^X//" >'range.h' <<'END_OF_FILE' X/* RANGE.H: @(#)range.h 1.2 94/01/22 (c)1993 thalerd */ X X/* Option flags */ X#define OF_NEWRESP 0x0001 X#define OF_REVERSE 0x0002 X#define OF_UID 0x0004 X#define OF_NUMBERED 0x0008 X#define OF_DATE 0x0010 X#define OF_PASS 0x0020 X#define OF_NOFORGET 0x0040 X#define OF_RANGE 0x0080 X#define OF_BRANDNEW 0x0100 X#define OF_FORMFEED 0x0200 X#define OF_UNSEEN 0x0400 X#define OF_FORGOTTEN 0x0800 X#define OF_RETIRED 0x1000 X#define OF_SHORT 0x2000 X#define OF_NORESPONSE 0x4000 X#define OF_EXPIRED 0x8000 X# define OF_NEXT 0x10000 X# define OF_NONE 0x20000 X X/* Action values */ X#define A_SKIP 0 /* Don't do item */ X#define A_COVER 1 /* Do item based on option flags */ X#define A_FORCE 2 /* Always do item */ X Xchar cover PROTO((SHORT i, SHORT idx, SHORT spec, SHORT act, X sumentry_t *sum, partentry_t *part, status_t *st)); Xvoid range PROTO((int argc, char **argv, short *flags, char *act, X sumentry_t *sum, status_t *st, int bef)); Xvoid rangetoken PROTO((char *token, short *flags, char *act, sumentry_t *sum, X status_t *st)); Xtime_t since PROTO((int argc, char **argv, short *ip)); Xvoid rangeinit PROTO(()); END_OF_FILE if test 1226 -ne `wc -c <'range.h'`; then echo shar: \"'range.h'\" unpacked with wrong size! fi # end of 'range.h' fi if test -f 'rfp.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'rfp.h'\" else echo shar: Extracting \"'rfp.h'\" \(841 characters\) sed "s/^X//" >'rfp.h' <<'END_OF_FILE' X/* RFP.H: @(#)rfp.h 1.3 94/01/22 (c)1993 thalerd */ X Xint add_response PROTO((sumentry_t *this, char **text, X SHORT idx, sumentry_t *sum, partentry_t *part, X status_t *stt, long art, char *mid, U_SHORT uid, X char *login, char *fullname, SHORT resp)); Xint censor PROTO((int argc, char **argv)); Xint preserve PROTO((int argc, char **argv)); Xint reply PROTO((int argc, char **argv)); Xint respond PROTO((int argc, char **argv)); Xint tree PROTO((int argc, char **argv)); Xint rfp_respond PROTO((int argc, char **argv)); Xchar rfp_cmd_dispatch PROTO((int argc, char **argv)); Xshort sibling PROTO((SHORT r)); Xshort parent PROTO((SHORT r)); Xshort child PROTO((SHORT r)); END_OF_FILE if test 841 -ne `wc -c <'rfp.h'`; then echo shar: \"'rfp.h'\" unpacked with wrong size! fi # end of 'rfp.h' fi if test -f 'sep.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'sep.h'\" else echo shar: Extracting \"'sep.h'\" \(706 characters\) sed "s/^X//" >'sep.h' <<'END_OF_FILE' X/* SEP.H: @(#)sep.h 1.5 93/06/07 Copyright (c)1993 thalerd */ X X/* Once flags */ X#define IS_START 0x0001 X#define IS_ITEM 0x0002 X#define IS_CFIDX 0x0004 /* special flag used for k cond in checkmsg */ X#define IS_RESP 0x0400 X X#define IS_ALL 0x0BF8 /* all below */ X#define IS_RETIRED 0x0008 /* used to check "if retired stuff" */ X#define IS_FORGOTTEN 0x0010 X#define IS_FROZEN 0x0020 X#define IS_LINKED 0x0040 X#define IS_CENSORED 0x0080 X#define IS_UID 0x0100 X#define IS_DATE 0x0200 X#define IS_PARENT 0x0800 X X Xvoid confsep PROTO((char *str, SHORT idx, status_t *st, partentry_t *part, int fl)); Xvoid itemsep PROTO((char *str, int fl)); Xvoid sepinit PROTO((SHORT x)); END_OF_FILE if test 706 -ne `wc -c <'sep.h'`; then echo shar: \"'sep.h'\" unpacked with wrong size! fi # end of 'sep.h' fi if test -f 'stats.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'stats.c'\" else echo shar: Extracting \"'stats.c'\" \(4031 characters\) sed "s/^X//" >'stats.c' <<'END_OF_FILE' Xstatic char sccsid[] = "%Z%%M% %I% %E% (c)1993 thalerd"; X/* STATS.C X * This module will cache subjects and authors for items in conferences X * Loading entries is delayed until reference time X * NUMCACHE conferences may be cached at a time X */ X#include X#include X#include "config.h" X#include "struct.h" X#include "globals.h" X#include "lib.h" X#include "stats.h" X#include "xalloc.h" X X#define NUMCACHE 2 X Xtypedef struct { X short idx; /* conference index */ X char **config; /* config info */ X char *subj[MAX_ITEMS]; X char *auth[MAX_ITEMS]; X} cache_t; X Xstatic cache_t cache[NUMCACHE]; Xstatic int start=1; X X/* GET INDEX OF CF */ Xint Xget_cache(idx) Xint idx; X{ X short i; X X /* Initialize cache */ X if (start) { X for (i=0; i=0) { X xfree(cache[i].config); X free_elts(cache[i].subj); X free_elts(cache[i].auth); X } X } X X /* Initialize with new conference info */ X cache[i].idx = idx; X if (!(cache[i].config=grab_file(conflist[idx].location,"config",0))) X return -1; X return i; X} X Xvoid Xclear_cache() X{ X int i; X for (i=0; i'stats.h' <<'END_OF_FILE' X/* STATS.H: %Z%%M% %I% %E% (c)1993 thalerd */ Xvoid free_elts PROTO((char **arr)); Xchar *get_subj PROTO((SHORT idx, SHORT item, sumentry_t *sum)); Xchar *get_auth PROTO((SHORT idx, SHORT item, sumentry_t *sum)); Xchar **get_config PROTO((SHORT idx)); Xvoid clear_cache PROTO(()); Xvoid store_subj PROTO((SHORT idx, SHORT item, char *str)); Xvoid store_auth PROTO((SHORT idx, SHORT item, char *str)); END_OF_FILE if test 422 -ne `wc -c <'stats.h'`; then echo shar: \"'stats.h'\" unpacked with wrong size! fi # end of 'stats.h' fi if test -f 'struct.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'struct.h'\" else echo shar: Extracting \"'struct.h'\" \(3906 characters\) sed "s/^X//" >'struct.h' <<'END_OF_FILE' X/* STRUCT.H: @(#)struct.h 1.14 93/06/06 Copyright (c)1993 thalerd */ X#include X#include X X/* Flag type */ Xtypedef unsigned long flag_t; /* expand type when we need > 16 option flags */ X X/* Command line option flag */ Xtypedef struct { X char *name; /* name used with define, change */ X flag_t mask; /* bitmask */ X char deflt; X} option_t; X X/* Macros */ Xtypedef struct { X char *name; X unsigned short mask; X char *value; X} macro_t; X X/* Error */ Xtypedef struct { X int severity; /* severity level, 0 informational */ X char *message; /* Format string for printing error */ X} error_t; X Xtypedef struct { X char *name; X int token_type; X} keyword_t; X Xtypedef struct { X char *name; X char *location; X} assoc_t; X Xtypedef struct { X short flags,nr; X time_t last,first; X/* char *subj; Subj must be separate so sum.c can block dump sum file */ X} sumentry_t; X Xtypedef struct { X short nr; X long last; X} partentry_t; X Xtypedef struct { X char *name; X int (*func)PROTO((int,char **)); X} dispatch_t; X X/* Global status structure */ Xtypedef struct { Xunsigned char c_security; /* cf security type */ X#ifdef NEWS X long c_article; /* highest article # seen */ X#endif X short c_status, /* cf status flags */ X i_first, /* first item in conference */ X i_last, /* last item in conference */ X i_current, /* current item */ X i_newresp, /* # of old items with new responses */ X i_brandnew, /* # of brand new items */ X i_unseen, /* # of unseen items */ X i_numitems, /* total # of items */ X r_first, /* first resp to process */ X r_last, /* last resp to process */ X r_current, /* current response */ X r_max, /* highest response # of current item */ X r_lastseen, /* highest response # seen */ X l_current; /* current line # of response */ X char fullname[MAX_LINE_LENGTH]; /* fullname in current cf */ X X /* Range specifiers */ X char string[MAX_LINE_LENGTH]; /* "string" range */ X char author[MAX_LINE_LENGTH]; /* author (login) specified */ X short rng_flags; /* item status flags for range */ X time_t since, /* since range */ X before; /* before range */ X X off_t mailsize; /* last size of mailbox */ X time_t listtime, /* lastmod of .cflist */ X sumtime, /* lastmod of sum file */ X parttime; /* lastmod of participation file */ X FILE *outp; /* output stream (pager) pointer */ X FILE *inp; /* input stream pointer */ X short opt_flags, /* option flags */ X count; /* count of something */ X} status_t; X X/* Response */ Xtypedef struct { X char *fullname; /* Author's full name */ X char *login; /* Author's login */ X uid_t uid; /* Author's UID */ X short flags; X char **text; /* The actual text lines */ X short numchars; /* How many characters in the response? */ X time_t date; /* Timestamp of entry */ X long offset, /* Offset to start of ,R line */ X textoff, /* Offset to start of actual text */ X endoff; /* Offset to start of next response */ X short parent; /* This is a response to what # (+1)? */ X#ifdef NEWS X char *mid; /* Message ID string (for Usenet) */ X long article; /* Article number (for Usenet) */ X#endif X} response_t; END_OF_FILE if test 3906 -ne `wc -c <'struct.h'`; then echo shar: \"'struct.h'\" unpacked with wrong size! fi # end of 'struct.h' fi if test -f 'sum.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'sum.h'\" else echo shar: Extracting \"'sum.h'\" \(871 characters\) sed "s/^X//" >'sum.h' <<'END_OF_FILE' X/* SUM.H: @(#)sum.h 1.2 94/01/20 (c)1993 thalerd */ Xvoid check_mail PROTO((int f)); Xvoid get_status PROTO((status_t *st, sumentry_t *sum, X partentry_t *part, SHORT idx)); Xint item_sum PROTO((SHORT i, sumentry_t *sum, X partentry_t *part, SHORT idx, status_t *stt)); Xvoid load_sum PROTO((sumentry_t *sum, X partentry_t *part, status_t *stt, SHORT idx)); Xvoid refresh_link PROTO((status_t *stt,sumentry_t *sum, X partentry_t *part,SHORT idx,SHORT i)); Xvoid refresh_list PROTO(()); Xvoid refresh_stats PROTO((sumentry_t *sum, partentry_t *part, status_t *st)); Xvoid refresh_sum PROTO((SHORT item, SHORT idx, X sumentry_t *sum, partentry_t *part, status_t *st)); Xvoid save_sum PROTO((sumentry_t *sum, SHORT i, SHORT idx, status_t *stt)); END_OF_FILE if test 871 -ne `wc -c <'sum.h'`; then echo shar: \"'sum.h'\" unpacked with wrong size! fi # end of 'sum.h' fi if test -f 'system.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'system.h'\" else echo shar: Extracting \"'system.h'\" \(371 characters\) sed "s/^X//" >'system.h' <<'END_OF_FILE' X/* SYSTEM.H: @(#)system.h 1.5 93/05/01 Copyright (c)1993 thalerd */ Xint unix_cmd PROTO((char *cmd)); XFILE *spopen PROTO((char *cmd)); Xint spclose PROTO((FILE *fp)); Xint edit PROTO((char *dir, char *file, int visual)); Xint rm PROTO((char *file, int sec)); Xint copy_file PROTO((char *src, char *dest, int sec)); X X/* Security levels */ X#define SL_OWNER 0 X#define SL_USER 1 END_OF_FILE if test 371 -ne `wc -c <'system.h'`; then echo shar: \"'system.h'\" unpacked with wrong size! fi # end of 'system.h' fi if test -f 'xalloc.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xalloc.c'\" else echo shar: Extracting \"'xalloc.c'\" \(7740 characters\) sed "s/^X//" >'xalloc.c' <<'END_OF_FILE' X/* XALLOC.C */ Xstatic char sccsid[] = "@(#)xalloc.c 1.12 93/06/07 Copyright (c)1993 thalerd"; X#ifndef NeXT X#ifndef bsdi X#include X#endif X#endif X/* to get flags var for debugging only... */ X#include "config.h" X#include "struct.h" X#include "xalloc.h" X#include "globals.h" X#define NUMXST 3 Xstatic long xst[NUMXST][2]={ 0 }; X#define XS_ACALLS 0 X#define XS_RCALLS 1 X#define XS_FCALLS 2 X X/* Information about each array */ Xtypedef struct mem_tt { X char **ptr; X struct mem_tt *next; X short num; /* # of elements */ X short eltsize; /* size of an element */ X} mem_t; Xstatic mem_t *first_arr=0,*first_mem=0; X X/******************************************************************************/ X/* DUMP ALL ARRAYS CURRENTLY ALLOCATED */ X/******************************************************************************/ Xvoid /* RETURNS: (nothing) */ Xxdump() /* ARGUMENTS: (none) */ X{ X mem_t *this; X short i; X X printf("ARRAYS:\n"); X for (this=first_arr; this; this = this->next) { X printf("xdump: ptr %x size %hd*%hd\n",this->ptr,this->num,this->eltsize); X for (i=0; inum; i++) X if (this->ptr[i]) printf("%4hd: %s\n",i,this->ptr[i]); X } X printf("\nOTHER:\n"); X for (this=first_mem; this; this = this->next) X printf("xdump: ptr %x size %hd*%hd str !%s!\n",this->ptr,this->num, X this->eltsize,this->ptr); X} X X/******************************************************************************/ X/* GET # OF ELEMENTS IN AN ARRAY */ X/******************************************************************************/ Xshort /* RETURNS: size of array */ Xxsizeof(arr) /* ARGUMENTS: */ Xchar **arr; /* Array */ X{ X mem_t *this; X X if (!arr) return 0; X for (this=first_arr; this && this->ptr != arr; this = this->next); X if (!this) X for (this=first_mem; this && this->ptr != arr; this = this->next); X if (!this) { X (void)wputs("Tried to get sizeof unxalloced ptr\n"); X return 0; /* not found */ X } X return this->num; X} X X/******************************************************************************/ X/* ALLOCATE A NEW ARRAY */ X/******************************************************************************/ Xchar ** /* RETURNS: New array */ Xxalloc(num,eltsize) /* ARGUMENTS: */ Xshort num; /* Size of array to get */ Xshort eltsize; /* Size of each element */ X{ X mem_t *this; X char **mem; X X mem=(char **)calloc((unsigned)num?num:1,(unsigned)eltsize); X/*printf("xalloc: %d %d > %x\n",num,eltsize,mem);*/ X this = (mem_t *)malloc(sizeof(mem_t)); X this->ptr = mem; X this->num = num; X this->eltsize = eltsize; X if (num) { X this->next = first_arr; X first_arr = this; X } else { X this->next = first_mem; X first_mem = this; X } X X if (flags & O_DEBUG) printf("xalloc: got %x size %hd*%hd\n", X mem,num,eltsize); X xst[XS_ACALLS][!num]++; X return mem; X} X X/******************************************************************************/ X/* CHANGE SIZE OF AN ARRAY */ X/******************************************************************************/ Xchar ** /* RETURNS: new array */ Xxrealloc(arr,num) /* ARGUMENTS: */ Xchar **arr; /* Old array */ Xshort num; /* New size */ X{ X mem_t *this; X char **mem; X short i; X X for (this=first_arr; this->ptr != arr; this = this->next); X if (!this) { X (void)wputs("Tried to xrealloc unxalloced ptr\n"); X return 0; /* not found */ X } X for (i=num; inum; i++) X if (arr[i]) X xfree((char *)arr[i]); X if (flags & O_DEBUG) printf("xrealloc: from %x size %hd*%hd\n", X arr,this->num,this->eltsize); X mem=(char **)realloc((char *)arr,(unsigned)num * this->eltsize); X this->num = num; X this->ptr = mem; X if (flags & O_DEBUG) printf("xrealloc: to %x size %hd*%hd\n", X mem,num,this->eltsize); X xst[XS_RCALLS][!num]++; X return mem; X} X X/******************************************************************************/ X/* VERIFY THAT ALL ARRAYS HAVE BEEN FREED */ X/******************************************************************************/ Xvoid Xxcheck() X{ X if (!first_arr && !first_mem) { X if (flags & O_DEBUG) X puts("xcheck: Everything freed.\n"); X } else { X printf("xcheck: Error, failed to xfree the following:\n"); X xdump(); X } X/* X if (first_arr) X printf("xcheck: Error, failed to xfree array %x!\n",first_arr->ptr); X else if (first_mem) X printf("xcheck: Error, failed to xfree other %x!\n",first_mem->ptr); X else if (flags & O_DEBUG) X puts("xcheck: Everything freed.\n"); X*/ X} X X/******************************************************************************/ X/* FREE AN ARRAY */ X/******************************************************************************/ Xvoid /* RETURNS: (nothing) */ Xxfree(arr) /* ARGUMENTS: */ Xvoid *arr; /* Array to free */ X{ X mem_t *this,*prev=0; X short i,typ=0; X X if (!arr) return; X for (this=first_arr; this && this->ptr != arr; prev=this, this = this->next); X if (!this) { X prev=0; X for (this=first_mem; this && this->ptr != arr; prev=this, this = this->next); X typ++; X } X if (!this) { X (void)wputs("Tried to free unxalloced ptr\n"); X return; /* not found */ X } X/*printf("xfree: %d %d > %x\n",this->num,this->eltsize,arr);*/ X if (flags & O_DEBUG) printf("xfree: free %x size %hd*%hd\n", X arr,this->num,this->eltsize); X if ((flags & O_DEBUG) && typ) X printf("Str:!%s!\n",(char*)arr); X X for (i=0; inum; i++) { X if (((char**)arr)[i]) xfree(((char**)arr)[i]); X } X free((char *)arr); X if (!prev) { X if (!typ) { X first_arr = this->next; X } else { X first_mem = this->next; X } X } else prev->next = this->next; X xst[XS_FCALLS][!this->num]++; X free((char *)this); X} X X/******************************************************************************/ X/* STANDARD strdup() CODE FOR THOSE OS'S WHICH DON'T HAVE IT */ X/******************************************************************************/ Xchar * /* RETURNS: New string */ Xxstrdup(str) /* ARGUMENTS: */ Xchar *str; /* String to duplicate */ X{ X char *ptr; X ptr = (char*)xalloc(0,strlen(str)+1); X strcpy(ptr,str); X return ptr; X} X X/******************************************************************************/ X/* DUMP ALL ARRAYS CURRENTLY ALLOCATED */ X/******************************************************************************/ Xvoid /* RETURNS: (nothing) */ Xxstat() /* ARGUMENTS: (none) */ X{ X mem_t *this; X short i; X long n,s,b,nt=0,st=0,bt=0; X X printf("Category: Number Size Bytes Acalls Rcalls Fcalls\n"); X n=s=b=0; X for (this=first_arr; this; this = this->next) { X n++; X s += this->num; X b += (this->num * this->eltsize); X } X printf("Arrays : %6d %6d %6d",n,s,b); X for (i=0; inext) { X n++; X s++; X b+= this->eltsize; X } X printf("\nStrings : %6d %6d %6d",n,s,b); X for (i=0; i'xalloc.h' <<'END_OF_FILE' X/* XALLOC.H: @(#)xalloc.h 1.5 93/06/07 Copyright (c)1993 thalerd */ Xshort xsizeof PROTO((char **arr)); Xchar **xalloc PROTO((SHORT num, SHORT eltsize)); Xvoid xfree PROTO((void *arr)); Xchar **xrealloc PROTO((char **arr, SHORT num)); Xvoid xcheck PROTO(()); Xvoid xdump PROTO(()); Xchar *xstrdup PROTO((char *str)); END_OF_FILE if test 330 -ne `wc -c <'xalloc.h'`; then echo shar: \"'xalloc.h'\" unpacked with wrong size! fi # end of 'xalloc.h' fi echo shar: End of archive 1 \(of 5\). cp /dev/null ark1isdone MISSING="" for I in 1 2 3 4 5 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 5 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0