rsalz@bbn.com (Rich Salz) (01/05/91)
Submitted-by: Wayne Davison <0004475895@mcimail.com> Posting-number: Volume 23, Issue 69 Archive-name: trn/part10 #! /bin/sh # This is a shell archive. Remove anything before this line, then feed it # into a shell via "sh file" or similar. To overwrite existing files, # type "sh file -c". # The tool that generated this appeared in the comp.sources.unix newsgroup; # send mail to comp-sources-unix@uunet.uu.net if you want that tool. # Contents: Configure.02 getdate.y kfile.c mt-read.c patchlevel # search.c # Wrapped by rsalz@litchi.bbn.com on Thu Dec 27 11:34:09 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH echo If this archive is complete, you will see the following message: echo ' "shar: End of archive 10 (of 14)."' if test -f 'Configure.02' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Configure.02'\" else echo shar: Extracting \"'Configure.02'\" \(12351 characters\) sed "s/^X//" >'Configure.02' <<'END_OF_FILE' X dflt=`loc . /bin /usr/local/bin /usr/lbin /usr/local /usr/bin` X ;; X*) dflt="$rnbin" X ;; Xesac Xrnbin='blurfl/dyick' Xwhile $test ! -d "$rnbin" ; do X case $rnbin in X blurfl*) ;; X *) $echo "$rnbin does not appear to exist." ;; X esac X $echo " " X $echo $n "Where do you want to put the public executables? [$dflt] $c" X . myread X rnbin="$ans" X rnbin=`filexp $rnbin` X case $rnbin in X '') rnbin=$dflt ;; X esac Xdone X X: determine where private executables go Xcase "$rnlib" in X'') X case "$isrrn" in X define) dflt=/usr/local/lib/trn ;; X *) dflt=$lib/trn ;; X esac X ;; X*) dflt="$rnlib" X ;; Xesac X$echo " " X$echo "Trn has a number of auxiliary programs that need not be visible to the" X$echo "whole world. Where do you want to put these private executables?" X$echo $n "[$dflt] (~name ok) $c" X. myread Xrnlib="$ans" Xcase $rnlib in X '') rnlib=$dflt ;; Xesac Xcase $portable in Xundef) X rnlib=`filexp $rnlib` X ;; Xesac X: must not allow self reference Xcase $rnlib in X /*) X filexp=$rnlib/filexp X ;; X *) X filexp=`pwd`/filexp X ;; Xesac X X: get the local distribution prefixes Xif $test -f $libexp/sys ; then X $sed <$libexp/sys -n -e "s/^$sitename://p" | \ X $sed -e "s/:.*//" -e "s/,/ /g" | tr ' ' '\012' | \ X $sed -e "/^to./d" -e "/^net$/d" -e "/^fa$/d" -e "/^mod$/d" > .distlist Xfi X X$cat <<'EOH' X XDistribution groups are the things you use on the Distribution line to limit Xwhere an article will go to. You are likely to be a member of several Xdistribution groups, such as organization, city, state, province, country, Xcontinent, etc. For example, Los Angeles has the distribution prefix "la", XNew Jersey has the prefix "nj", and Europe has the prefix "eunet". X XThe categories you will be asked are: X Xlocal organization (Could be just one machine or a cluster or an office) Xorganization att, dec, kgb, ... Xcity la, ny, mosc, ... Xstate/province ca, nj, bc, ... Xcountry usa, can, rok, whatever Xcontinent na (North America, not "Not Applicable"), asia, etc. X X(If you don't have a distribution prefix in any of these categories then Xjust hit return.) X XEOH Xif $test -f .distlist; then X distlist=`tr '\012' ' ' <.distlist` X if $test "$distlist" ; then X $echo "(These are the distributions in your sys file: $distlist)" X $echo " " X fi Xfi Xcase "$locpref" in X'') dflt="";; X*) dflt="[$locpref] ";; Xesac X$echo $n "What is the distribution prefix for your local organization? $dflt$c" X. myread Xcase "$ans" in X'') ;; X*) locpref="$ans";; Xesac Xcase $locpref in X '') locpref=none ;; Xesac Xcase "$orgpref" in X'') dflt="";; X*) dflt="[$orgpref] ";; Xesac X$echo $n "What is the distribution prefix for your organization? $dflt$c" X. myread Xcase "$ans" in X'') ;; X*) orgpref="$ans";; Xesac Xcase $orgpref in X '') orgpref=none ;; Xesac Xcase "$citypref" in X'') dflt="";; X*) dflt="[$citypref] ";; Xesac X$echo $n "What is the distribution prefix for your city? $dflt$c" X. myread Xcase "$ans" in X'') ;; X*) citypref="$ans";; Xesac Xcase $citypref in X '') citypref=none ;; Xesac Xcase "$statepref" in X'') dflt="";; X*) dflt="[$statepref] ";; Xesac X$echo $n "What is the distribution prefix for your state/province? $dflt$c" X. myread Xcase "$ans" in X'') ;; X*) statepref="$ans";; Xesac Xcase $statepref in X '') statepref=none ;; Xesac Xcase "$cntrypref" in X'') dflt="";; X*) dflt="[$cntrypref] ";; Xesac X$echo $n "What is the distribution prefix for your country? $dflt$c" X. myread Xcase "$ans" in X'') ;; X*) cntrypref="$ans";; Xesac Xcase $cntrypref in X '') cntrypref=none ;; Xesac Xcase "$contpref" in X'') dflt="";; X*) dflt="[$contpref] ";; Xesac X$echo $n "What is the distribution prefix for your continent? $dflt$c" X. myread Xcase "$ans" in X'') ;; X*) contpref="$ans";; Xesac Xcase $contpref in X '') contpref=none ;; Xesac X X$echo " " X$echo "If you have any other distribution groups you will need to edit Pnews" X$echo "and newsetup to add them." X$echo " " X X: determine root id Xrootid=`$sed </etc/passwd -e "/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*"'$'"/\1/" -e "q" -e "}" -e "d"` Xcase $rootid in X '') rootid=0 ;; X *) $echo "Root uid = $rootid" ;; Xesac X X: weed out incompatibilities Xcase $douname in X define) whoami=undef ;; Xesac X X: preserve RCS keywords in files with variable substitution, grrr XLog='$Log' XHeader='$Header' X X: Warnings Xif v7; then X cat <<'EOM' X XNOTE: the V7 compiler may ignore some #undefs that trn uses. If so, you will Xget messages about redefining EXT. Some V7 compilers also have difficulties Xwith #defines near buffer boundaries, so beware. You may have to play with Xthe spacing in common.h. XEOM Xfi X Xif pdp11; then X cat <<'EOM' X XNOTE: the PDP-11 does not have enough data space to do subject caching Xreliably. That feature will be disabled automatically. Subject searching Xwill tend to be slow. XEOM Xfi Xcase "$isrrn" in X define) ;; X *) socketlib="" X rrninclude="" X ;; Xesac X X$echo " " X$echo "End of configuration questions." X$echo " " X X: create config.sh file X$echo " " X$echo "Creating config.sh..." X$spitshell <<EOT >config.sh X$startsh X# config.sh X# This file was produced by running the Configure script. X Xn='$n' Xc='$c' Xlibc='$libc' Xeunicefix='$eunicefix' Xeunice='$eunice' Xcpp='$cpp' Xshsharp='$shsharp' Xstartsh='$startsh' Xspitshell='$spitshell' Xtest='$test' Xexpr='$expr' Xsed='$sed' Xecho='$echo' Xcat='$cat' Xrm='$rm' Xmv='$mv' Xcp='$cp' Xtail='$tail' Xtr='$tr' Xmkdir='$mkdir' Xsort='$sort' Xuniq='$uniq' Xinews='$inews' Xgrep='$grep' Xegrep='$egrep' Xypmatch='$ypmatch' Xcontains='$contains' Xlib='$lib' Xlibexp='$libexp' Xnametype='$nametype' Xcc='$cc' Xiandd='$iandd' Xinclude='$include' Xrrninclude='$rrninclude' Xtermlib='$termlib' Xjobslib='$jobslib' Xsocketlib='$socketlib' Xgetcwd='$getcwd' Xdirtype='$dirtype' Xndirlib='$ndirlib' Xlibndir='$libndir' Xusendir='$usendir' Xndirc='$ndirc' Xndiro='$ndiro' Xpager='$pager' Xmailer='$mailer' Xinternet='$internet' Xrnbin='$rnbin' Xfilexp='$filexp' Xdistlist='$distlist' XLog='$Log' XHeader='$Header' Xsitename='$sitename' Xhostfile='$hostfile' Xdomain='$domain' Xorgname='$orgname' Xisadmin='$isadmin' Xnewsadmin='$newsadmin' Xrnlib='$rnlib' Xmansrc='$mansrc' Xmanext='$manext' Xmaildir='$maildir' Xspool='$spool' Xactive='$active' Xmyactive='$myactive' Xmininact='$mininact' Xpref='$pref' Xdefeditor='$defeditor' Xrootid='$rootid' Xmboxchar='$mboxchar' Xlocpref='$locpref' Xorgpref='$orgpref' Xcitypref='$citypref' Xstatepref='$statepref' Xcntrypref='$cntrypref' Xcontpref='$contpref' Xstrchr='$strchr' Xmemcpy='$memcpy' Xrename='$rename' Xtruncate='$truncate' Xchsize='$chsize' Xsysptem='$sysptem' Xtzset='$tzset' Xthreaddef='$threaddef' Xselectdef='$selectdef' Xthreaddir='$threaddir' Xnovoid='$novoid' Xnovfork='$novfork' Xportable='$portable' Xpassnam='$passnam' Xberknam='$berknam' Xusgnam='$usgnam' Xwhoami='$whoami' Xtermio='$termio' Xfcntl='$fcntl' Xioctl='$ioctl' Xnormsig='$normsig' Xsigblock='$sigblock' Xsigret='$sigret' Xgetuidgid='$getuidgid' Xhavetlib='$havetlib' Xgetpwent='$getpwent' Xgethostname='$gethostname' Xdouname='$douname' Xphostname='$phostname' Xhostcmd='$hostcmd' Xnorelay='$norelay' Xrdchk='$rdchk' Xisrrn='$isrrn' Xserverfile='$serverfile' XNNTPSRC='$NNTPSRC' XCONFIG=true XCTRLA='$CTRLA' XEOT X X: create config.h file X$echo " " X$echo "Creating config.h..." Xcase "$threaddir" in X'.') threaddir='/usr/spool/threads' X tdir='/*';; X*) tdir='';; Xesac Xcase "$strchr" in Xdefine) strchr='';; X*) strchr='/*';; Xesac Xcase "$memcpy" in Xdefine) memcpy='';; X*) memcpy='/*';; Xesac Xcase "$novoid" in Xdefine) novoid='';; X*) novoid='/*';; Xesac Xcase "$novfork" in Xdefine) novfork='';; X*) novfork='/*';; Xesac Xcase "$phostname" in Xdefine) phostname='';; X*) phostname='/*';; Xesac Xcase "$isrrn" in Xdefine) isrrn2='';; X*) isrrn2='/*';; Xesac Xcase "$hostfile" in X'') usehostfile='/*';; X*) usehostfile='';; Xesac X$cat <<EOT >config.h X/* config.h X * This file was produced by running the Configure script. X * Feel free to modify any of this as the need arises. X */ X X/* name of the site. May be overridden by HOSTFILE, gethostname, uname, etc. */ X#define SITENAME "$sitename" X$usehostfile#define HOSTFILE "$hostfile" X X/* OURDOMAIN is added to the site name if no "." is in it. */ X#define OURDOMAIN "$domain" X X/* name of the organization, may be a file name */ X#define ORGNAME "$orgname" X X/* login name of news administrator, if any. */ X#$isadmin NEWSADMIN "$newsadmin" X X/* news library, may use only ~ and %l expansion */ X#define LIB "$lib" X X/* rn private library, may use ~ expansion, %x and %l */ X#define RNLIB "$rnlib" X X/* location of the news spool directory, may use ~ expansion, %x and %l */ X#define SPOOL "$spool" X X/* put thread files in each spool directory, unless THREAD_DIR is defined */ X$tdir#define THREAD_DIR "$threaddir" /* base directory */ X X/* save in subdirectories unless LONG_THREAD_NAMES & THREAD_DIR are defined */ X#undef LONG_THREAD_NAMES /* not for short-name systems */ X X/* location of the active file, may use ~ expansion, %x and %l */ X#define ACTIVE "$active" X X/* location of spooled mail */ X#define MAILFILE "$maildir" X X/* default shell--ok to be a slow shell like csh */ X#define PREFSHELL "$pref" X X/* default editor */ X#define DEFEDITOR "$defeditor" X X/* root uid */ X#define ROOTID $rootid X X/* what is the first character of a mailbox? */ X#define MBOXCHAR '$mboxchar' X X/* how to cancel an article */ X#define CANCEL "$inews -h <%h" X X/* distribution groups */ X#define LOCDIST "$locpref" X#define ORGDIST "$orgpref" X#define CITYDIST "$citypref" X#define STATEDIST "$statepref" X#define CNTRYDIST "$cntrypref" X#define CONTDIST "$contpref" X X#define THREAD_INIT $threaddef X#define SELECT_INIT $selectdef X X$strchr#define index strchr /* cultural */ X$strchr#define rindex strrchr /* differences? */ X$memcpy#define bcopy(s,d,n) memcpy((char*)d,(char*)s,(int)n) /* Different */ X$memcpy#define bzero(d,n) memset((char*)d,0,(int)n) /* flavors. */ X#$rename RENAME /* is rename() a system call? */ X#$truncate TRUNCATE /* is truncate() available? */ X#$chsize CHSIZE /* is chsize() available? */ X#$sysptem SYS_PTEM /* is /usr/include/sys/ptem.h needed? */ X#$tzset TZSET /* modern timezone functions? */ X$novoid#define void int /* is void to be avoided? */ X$novfork#define vfork fork /* is vfork too virtual? */ X#$eunice EUNICE /* no linking? */ X#$eunice VMS /* not currently used, here just in case */ X#$getcwd GETCWD /* do we have getcwd()? */ X#$usendir USENDIR /* include ndir.c? */ X#$libndir LIBNDIR /* include /usr/include/ndir.h? */ X#define DIRTYPE $dirtype X#ifndef USENDIR X#define DIRINC $dirinc X#endif X#$mininact MININACT /* include 2.10.2 optimization? */ X#$portable PORTABLE /* do we do extra lookups to start up? */ X#$passnam PASSNAMES /* do names come from the passwd file? */ X /* (undef to take name from ~/.fullname) */ X#$berknam BERKNAMES /* if so, are they Berkeley format? */ X /* (that is, ":name,stuff:") */ X#$usgnam USGNAMES /* or are they USG format? */ X /* (that is, ":stuff-name(stuff):") */ X#$whoami WHOAMI /* should we include whoami.h? */ X#$rdchk RDCHK /* do we have rdchk()? */ X#$termio TERMIO /* is this a termio system? */ X#$fcntl FCNTL /* should we include fcntl.h? */ X#$ioctl IOCTL /* are ioctl args all defined in one place? */ X#$normsig NORMSIG /* use signal rather than sigset? */ X#$sigblock SIGBLOCK /* use sigblock and sigsetmask */ X#define SIGRET $sigret /* what does signal() return? */ X#$havetlib HAVETERMLIB /* do we have termlib-style routines? */ X#$getuidgid GETUIDGID /* allow setuid (if possible) */ X#$getpwent GETPWENT /* should we include getpwent? */ X#$internet INTERNET /* does our mailer do INTERNET addressing? */ X#$gethostname GETHOSTNAME /* do we have a gethostname function? */ X#$douname DOUNAME /* do we have a uname function? */ X$phostname#define PHOSTNAME "$hostcmd" /* how to get host name with popen */ X#$norelay NORELAY /* 2.10.3 doesn't have Relay-Version line */ X#$isrrn SERVER /* rrn server code */ X$isrrn2#define SERVER_FILE "$serverfile" /* news server file */ XEOT X XCONFIG=true X X$rm -f libc.list .distlist kit*isdone X X$echo " " X$echo "Doing variable substitutions on various files..." X$echo " " Xset `$grep <MANIFEST '\.SH' | awk '{print $1}'` Xfor file in $*; do X . $file Xdone X X$echo " " X$echo 'Now you need to generate make dependencies by running "makedepend".' X$echo 'You might prefer to run it in background: "makedepend > makedepend.out &"' X$echo $n "Would you like me to run it for you (it takes quite a while)? [n] $c" X. myread Xcase "$ans" in Xy*) makedepend;; Xesac X$rm -f myread X: end of Configure END_OF_FILE if test 12351 -ne `wc -c <'Configure.02'`; then echo shar: \"'Configure.02'\" unpacked with wrong size! fi # end of 'Configure.02' fi if test -f 'getdate.y' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'getdate.y'\" else echo shar: Extracting \"'getdate.y'\" \(12373 characters\) sed "s/^X//" >'getdate.y' <<'END_OF_FILE' X%token ID MONTH DAY MERIDIAN NUMBER UNIT MUNIT SUNIT ZONE DAYZONE AGO X%{ X /* Steven M. Bellovin (unc!smb) */ X /* Dept. of Computer Science */ X /* University of North Carolina at Chapel Hill */ X /* @(#)getdate.y 2.13 9/16/86 */ X X#include <sys/types.h> X#include <ctype.h> X#include <time.h> X X#define NULL 0 X X#define daysec (24L*60L*60L) X X static int timeflag, zoneflag, dateflag, dayflag, relflag; X static time_t relsec, relmonth; X static int hh, mm, ss, merid, daylight; X static int dayord, dayreq; X static int month, day, year; X static int ourzone; X X#define AM 1 X#define PM 2 X#define DAYLIGHT 1 X#define STANDARD 2 X#define MAYBE 3 X%} X X%% Xtimedate: /* empty */ X | timedate item; X Xitem: tspec = X {timeflag++;} X | zone = X {zoneflag++;} X | dtspec = X {dateflag++;} X | dyspec = X {dayflag++;} X | rspec = X {relflag++;} X | nspec; X Xnspec: NUMBER = X {if (timeflag && dateflag && !relflag) year = $1; X else {timeflag++;hh = $1/100;mm = $1%100;ss = 0;merid = 24;}}; X Xtspec: NUMBER MERIDIAN = X {hh = $1; mm = 0; ss = 0; merid = $2;} X | NUMBER ':' NUMBER = X {hh = $1; mm = $3; merid = 24;} X | NUMBER ':' NUMBER MERIDIAN = X {hh = $1; mm = $3; merid = $4;} X | NUMBER ':' NUMBER NUMBER = X {hh = $1; mm = $3; merid = 24; X daylight = STANDARD; ourzone = -($4%100 + 60*$4/100);} X | NUMBER ':' NUMBER ':' NUMBER = X {hh = $1; mm = $3; ss = $5; merid = 24;} X | NUMBER ':' NUMBER ':' NUMBER MERIDIAN = X {hh = $1; mm = $3; ss = $5; merid = $6;} X | NUMBER ':' NUMBER ':' NUMBER NUMBER = X {hh = $1; mm = $3; ss = $5; merid = 24; X daylight = STANDARD; ourzone = -($6%100 + 60*$6/100);}; X Xzone: ZONE = X {ourzone = $1; daylight = STANDARD;} X | DAYZONE = X {ourzone = $1; daylight = DAYLIGHT;}; X Xdyspec: DAY = X {dayord = 1; dayreq = $1;} X | DAY ',' = X {dayord = 1; dayreq = $1;} X | NUMBER DAY = X {dayord = $1; dayreq = $2;}; X Xdtspec: NUMBER '/' NUMBER = X {month = $1; day = $3;} X | NUMBER '/' NUMBER '/' NUMBER = X {month = $1; day = $3; year = $5;} X | MONTH NUMBER = X {month = $1; day = $2;} X | MONTH NUMBER ',' NUMBER = X {month = $1; day = $2; year = $4;} X | NUMBER MONTH = X {month = $2; day = $1;} X | NUMBER MONTH NUMBER = X {month = $2; day = $1; year = $3;}; X X Xrspec: NUMBER UNIT = X {relsec += 60L * $1 * $2;} X | NUMBER MUNIT = X {relmonth += $1 * $2;} X | NUMBER SUNIT = X {relsec += $1;} X | UNIT = X {relsec += 60L * $1;} X | MUNIT = X {relmonth += $1;} X | SUNIT = X {relsec++;} X | rspec AGO = X {relsec = -relsec; relmonth = -relmonth;}; X%% X Xstatic int mdays[12] = X {31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; X#define epoch 1970 X Xextern struct tm *localtime(); Xtime_t dateconv(mm, dd, yy, h, m, s, mer, zone, dayflag) Xint mm, dd, yy, h, m, s, mer, zone, dayflag; X{ X time_t tod, jdate; X register int i; X time_t timeconv(); X X if (yy < 0) yy = -yy; X if (yy < 100) yy += 1900; X mdays[1] = 28 + (yy%4 == 0 && (yy%100 != 0 || yy%400 == 0)); X if (yy < epoch || yy > 1999 || mm < 1 || mm > 12 || X dd < 1 || dd > mdays[--mm]) return (-1); X jdate = dd-1; X for (i=0; i<mm; i++) jdate += mdays[i]; X for (i = epoch; i < yy; i++) jdate += 365 + (i%4 == 0); X jdate *= daysec; X jdate += zone * 60L; X if ((tod = timeconv(h, m, s, mer)) < 0) return (-1); X jdate += tod; X if (dayflag==DAYLIGHT || (dayflag==MAYBE&&localtime(&jdate)->tm_isdst)) X jdate += -1*60*60; X return (jdate); X} X Xtime_t dayconv(ord, day, now) int ord, day; time_t now; X{ X register struct tm *loctime; X time_t tod; X time_t daylcorr(); X X tod = now; X loctime = localtime(&tod); X tod += daysec * ((day - loctime->tm_wday + 7) % 7); X tod += 7*daysec*(ord<=0?ord:ord-1); X return daylcorr(tod, now); X} X Xtime_t timeconv(hh, mm, ss, mer) register int hh, mm, ss, mer; X{ X if (mm < 0 || mm > 59 || ss < 0 || ss > 59) return (-1); X switch (mer) { X case AM: if (hh < 1 || hh > 12) return(-1); X return (60L * ((hh%12)*60L + mm)+ss); X case PM: if (hh < 1 || hh > 12) return(-1); X return (60L * ((hh%12 +12)*60L + mm)+ss); X case 24: if (hh < 0 || hh > 23) return (-1); X return (60L * (hh*60L + mm)+ss); X default: return (-1); X } X} Xtime_t monthadd(sdate, relmonth) time_t sdate, relmonth; X{ X struct tm *ltime; X time_t dateconv(); X time_t daylcorr(); X int mm, yy; X X if (relmonth == 0) return 0; X ltime = localtime(&sdate); X mm = 12*ltime->tm_year + ltime->tm_mon + relmonth; X yy = mm/12; X mm = mm%12 + 1; X return daylcorr(dateconv(mm, ltime->tm_mday, yy, ltime->tm_hour, X ltime->tm_min, ltime->tm_sec, 24, ourzone, MAYBE), sdate); X} X Xtime_t daylcorr(future, now) time_t future, now; X{ X int fdayl, nowdayl; X X nowdayl = (localtime(&now)->tm_hour+1) % 24; X fdayl = (localtime(&future)->tm_hour+1) % 24; X return (future-now) + 60L*60L*(nowdayl-fdayl); X} X Xstatic char *lptr; X Xyylex() X{ X extern int yylval; X int sign; X register char c; X register char *p; X char idbuf[20]; X int pcnt; X X for (;;) { X while (isspace(*lptr)) lptr++; X X if (isdigit(c = *lptr) || c == '-' || c == '+') { X if (c== '-' || c == '+') { X if (c=='-') sign = -1; X else sign = 1; X if (!isdigit(*++lptr)) { X /* yylval = sign; return (NUMBER); */ X return yylex(); /* skip the '-' sign */ X } X } else sign = 1; X yylval = 0; X while (isdigit(c = *lptr++)) yylval = 10*yylval + c - '0'; X yylval *= sign; X lptr--; X return (NUMBER); X X } else if (isalpha(c)) { X p = idbuf; X while (isalpha(c = *lptr++) || c=='.') X if (p < &idbuf[sizeof(idbuf)-1]) X *p++ = c; X *p = '\0'; X lptr--; X return (lookup(idbuf)); X } X X else if (c == '(') { X pcnt = 0; X do { X c = *lptr++; X if (c == '\0') return(c); X else if (c == '(') pcnt++; X else if (c == ')') pcnt--; X } while (pcnt > 0); X } X X else return (*lptr++); X } X} X Xstruct table { X char *name; X int type, value; X}; X Xstruct table mdtab[] = { X {"January", MONTH, 1}, X {"February", MONTH, 2}, X {"March", MONTH, 3}, X {"April", MONTH, 4}, X {"May", MONTH, 5}, X {"June", MONTH, 6}, X {"July", MONTH, 7}, X {"August", MONTH, 8}, X {"September", MONTH, 9}, X {"Sept", MONTH, 9}, X {"October", MONTH, 10}, X {"November", MONTH, 11}, X {"December", MONTH, 12}, X X {"Sunday", DAY, 0}, X {"Monday", DAY, 1}, X {"Tuesday", DAY, 2}, X {"Tues", DAY, 2}, X {"Wednesday", DAY, 3}, X {"Wednes", DAY, 3}, X {"Thursday", DAY, 4}, X {"Thur", DAY, 4}, X {"Thurs", DAY, 4}, X {"Friday", DAY, 5}, X {"Saturday", DAY, 6}, X {0, 0, 0}}; X X#define HRS *60 X#define HALFHR 30 Xstruct table mztab[] = { X {"a.m.", MERIDIAN, AM}, X {"am", MERIDIAN, AM}, X {"p.m.", MERIDIAN, PM}, X {"pm", MERIDIAN, PM}, X {"nst", ZONE, 3 HRS + HALFHR}, /* Newfoundland */ X {"n.s.t.", ZONE, 3 HRS + HALFHR}, X {"ast", ZONE, 4 HRS}, /* Atlantic */ X {"a.s.t.", ZONE, 4 HRS}, X {"adt", DAYZONE, 4 HRS}, X {"a.d.t.", DAYZONE, 4 HRS}, X {"est", ZONE, 5 HRS}, /* Eastern */ X {"e.s.t.", ZONE, 5 HRS}, X {"edt", DAYZONE, 5 HRS}, X {"e.d.t.", DAYZONE, 5 HRS}, X {"cst", ZONE, 6 HRS}, /* Central */ X {"c.s.t.", ZONE, 6 HRS}, X {"cdt", DAYZONE, 6 HRS}, X {"c.d.t.", DAYZONE, 6 HRS}, X {"mst", ZONE, 7 HRS}, /* Mountain */ X {"m.s.t.", ZONE, 7 HRS}, X {"mdt", DAYZONE, 7 HRS}, X {"m.d.t.", DAYZONE, 7 HRS}, X {"pst", ZONE, 8 HRS}, /* Pacific */ X {"p.s.t.", ZONE, 8 HRS}, X {"pdt", DAYZONE, 8 HRS}, X {"p.d.t.", DAYZONE, 8 HRS}, X {"yst", ZONE, 9 HRS}, /* Yukon */ X {"y.s.t.", ZONE, 9 HRS}, X {"ydt", DAYZONE, 9 HRS}, X {"y.d.t.", DAYZONE, 9 HRS}, X {"hst", ZONE, 10 HRS}, /* Hawaii */ X {"h.s.t.", ZONE, 10 HRS}, X {"hdt", DAYZONE, 10 HRS}, X {"h.d.t.", DAYZONE, 10 HRS}, X X {"gmt", ZONE, 0 HRS}, X {"g.m.t.", ZONE, 0 HRS}, X {"bst", DAYZONE, 0 HRS}, /* British Summer Time */ X {"b.s.t.", DAYZONE, 0 HRS}, X {"eet", ZONE, 0 HRS}, /* European Eastern Time */ X {"e.e.t.", ZONE, 0 HRS}, X {"eest", DAYZONE, 0 HRS}, /* European Eastern Summer Time */ X {"e.e.s.t.", DAYZONE, 0 HRS}, X {"met", ZONE, -1 HRS}, /* Middle European Time */ X {"m.e.t.", ZONE, -1 HRS}, X {"mest", DAYZONE, -1 HRS}, /* Middle European Summer Time */ X {"m.e.s.t.", DAYZONE, -1 HRS}, X {"wet", ZONE, -2 HRS }, /* Western European Time */ X {"w.e.t.", ZONE, -2 HRS }, X {"west", DAYZONE, -2 HRS}, /* Western European Summer Time */ X {"w.e.s.t.", DAYZONE, -2 HRS}, X X {"jst", ZONE, -9 HRS}, /* Japan Standard Time */ X {"j.s.t.", ZONE, -9 HRS}, /* Japan Standard Time */ X /* No daylight savings time */ X X {"aest", ZONE, -10 HRS}, /* Australian Eastern Time */ X {"a.e.s.t.", ZONE, -10 HRS}, X {"aesst", DAYZONE, -10 HRS}, /* Australian Eastern Summer Time */ X {"a.e.s.s.t.", DAYZONE, -10 HRS}, X {"acst", ZONE, -(9 HRS + HALFHR)}, /* Australian Central Time */ X {"a.c.s.t.", ZONE, -(9 HRS + HALFHR)}, X {"acsst", DAYZONE, -(9 HRS + HALFHR)}, /* Australian Central Summer */ X {"a.c.s.s.t.", DAYZONE, -(9 HRS + HALFHR)}, X {"awst", ZONE, -8 HRS}, /* Australian Western Time */ X {"a.w.s.t.", ZONE, -8 HRS}, /* (no daylight time there, I'm told */ X {0, 0, 0}}; X Xstruct table unittb[] = { X {"year", MUNIT, 12}, X {"month", MUNIT, 1}, X {"fortnight", UNIT, 14*24*60}, X {"week", UNIT, 7*24*60}, X {"day", UNIT, 1*24*60}, X {"hour", UNIT, 60}, X {"minute", UNIT, 1}, X {"min", UNIT, 1}, X {"second", SUNIT, 1}, X {"sec", SUNIT, 1}, X {0, 0, 0}}; X Xstruct table othertb[] = { X {"tomorrow", UNIT, 1*24*60}, X {"yesterday", UNIT, -1*24*60}, X {"today", UNIT, 0}, X {"now", UNIT, 0}, X {"last", NUMBER, -1}, X {"this", UNIT, 0}, X {"next", NUMBER, 2}, X {"first", NUMBER, 1}, X /* {"second", NUMBER, 2}, */ X {"third", NUMBER, 3}, X {"fourth", NUMBER, 4}, X {"fifth", NUMBER, 5}, X {"sixth", NUMBER, 6}, X {"seventh", NUMBER, 7}, X {"eigth", NUMBER, 8}, X {"ninth", NUMBER, 9}, X {"tenth", NUMBER, 10}, X {"eleventh", NUMBER, 11}, X {"twelfth", NUMBER, 12}, X {"ago", AGO, 1}, X {0, 0, 0}}; X Xstruct table milzone[] = { X {"a", ZONE, 1 HRS}, X {"b", ZONE, 2 HRS}, X {"c", ZONE, 3 HRS}, X {"d", ZONE, 4 HRS}, X {"e", ZONE, 5 HRS}, X {"f", ZONE, 6 HRS}, X {"g", ZONE, 7 HRS}, X {"h", ZONE, 8 HRS}, X {"i", ZONE, 9 HRS}, X {"k", ZONE, 10 HRS}, X {"l", ZONE, 11 HRS}, X {"m", ZONE, 12 HRS}, X {"n", ZONE, -1 HRS}, X {"o", ZONE, -2 HRS}, X {"p", ZONE, -3 HRS}, X {"q", ZONE, -4 HRS}, X {"r", ZONE, -5 HRS}, X {"s", ZONE, -6 HRS}, X {"t", ZONE, -7 HRS}, X {"u", ZONE, -8 HRS}, X {"v", ZONE, -9 HRS}, X {"w", ZONE, -10 HRS}, X {"x", ZONE, -11 HRS}, X {"y", ZONE, -12 HRS}, X {"z", ZONE, 0 HRS}, X {0, 0, 0}}; X Xlookup(id) char *id; X{ X#define gotit (yylval=i->value, i->type) X#define getid for(j=idvar, k=id; *j++ = *k++; ) X X char idvar[20]; X register char *j, *k; X register struct table *i; X int abbrev; X X getid; X if (strlen(idvar) == 3) abbrev = 1; X else if (strlen(idvar) == 4 && idvar[3] == '.') { X abbrev = 1; X idvar[3] = '\0'; X } X else abbrev = 0; X X if (islower(*idvar)) *idvar = toupper(*idvar); X X for (i = mdtab; i->name; i++) { X k = idvar; X for (j = i->name; *j++ == *k++;) { X if (abbrev && j==i->name+3) return gotit; X if (j[-1] == 0) return gotit; X } X } X X getid; X for (i = mztab; i->name; i++) X if (strcmp(i->name, idvar) == 0) return gotit; X X for (j = idvar; *j; j++) X if (isupper(*j)) *j = tolower(*j); X for (i=mztab; i->name; i++) X if (strcmp(i->name, idvar) == 0) return gotit; X X getid; X for (i=unittb; i->name; i++) X if (strcmp(i->name, idvar) == 0) return gotit; X X if (idvar[strlen(idvar)-1] == 's') X idvar[strlen(idvar)-1] = '\0'; X for (i=unittb; i->name; i++) X if (strcmp(i->name, idvar) == 0) return gotit; X X getid; X for (i = othertb; i->name; i++) X if (strcmp(i->name, idvar) == 0) return gotit; X X getid; X if (strlen(idvar) == 1 && isalpha(*idvar)) { X if (isupper(*idvar)) *idvar = tolower(*idvar); X for (i = milzone; i->name; i++) X if (strcmp(i->name, idvar) == 0) return gotit; X } X X return(ID); X} X Xtime_t getdate(p, now, zone) char *p; time_t now; long zone; X{ X#define mcheck(f) if (f>1) err++ X time_t monthadd(); X int err; X struct tm *lt; X time_t sdate, tod; X X lptr = p; X if (now <= 0) X (void) time(&now); X lt = localtime(&now); X year = lt->tm_year; X month = lt->tm_mon+1; X day = lt->tm_mday; X relsec = 0; relmonth = 0; X timeflag=zoneflag=dateflag=dayflag=relflag=0; X daylight = MAYBE; X hh = mm = ss = 0; X merid = 24; X ourzone = zone; X X if (err = yyparse()) return (-1); X X mcheck(timeflag); X mcheck(zoneflag); X mcheck(dateflag); X mcheck(dayflag); X X if (err) return (-1); X if (dateflag || timeflag || dayflag) { X sdate = dateconv(month,day,year,hh,mm,ss,merid,ourzone,daylight); X if (sdate < 0) return -1; X } X else { X sdate = now; X if (relflag == 0) X sdate -= (lt->tm_sec + lt->tm_min*60 + X lt->tm_hour*(60L*60L)); X } X X sdate += relsec; X sdate += monthadd(sdate, relmonth); X X if (dayflag && !dateflag) { X tod = dayconv(dayord, dayreq, sdate); X sdate += tod; X } X X return sdate; X} X Xyyerror(s) char *s; X{} END_OF_FILE if test 12373 -ne `wc -c <'getdate.y'`; then echo shar: \"'getdate.y'\" unpacked with wrong size! fi # end of 'getdate.y' fi if test -f 'kfile.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'kfile.c'\" else echo shar: Extracting \"'kfile.c'\" \(7167 characters\) sed "s/^X//" >'kfile.c' <<'END_OF_FILE' X/* $Header: kfile.c,v 4.3.3.1 90/06/20 22:38:06 davison Trn $ X * X * $Log: kfile.c,v $ X * Revision 4.3.3.1 90/06/20 22:38:06 davison X * Initial Trn Release X * X * Revision 1.2 90/03/22 23:04:41 sob X * Fixes provided by Wayne Davison <drivax!davison> X * X * Revision 4.3.1.3 85/05/29 09:11:52 lwall X * Suppressed some killing messages on -t. X * X * Revision 4.3.1.2 85/05/10 14:21:29 lwall X * Prevented THRU from setting art < absfirst. X * X * Revision 4.3.1.1 85/05/10 11:34:33 lwall X * Branch for patches. X * X * Revision 4.3 85/05/01 11:41:53 lwall X * Baseline for release with 4.3bsd. X * X */ X X#include "EXTERN.h" X#include "common.h" X#include "term.h" X#include "util.h" X#include "artsrch.h" X#include "ng.h" X#include "bits.h" X#include "intrp.h" X#include "ngstuff.h" X#include "rcstuff.h" X#include "rn.h" X#ifdef USETHREADS X#include "rthreads.h" X#endif X#include "INTERN.h" X#include "kfile.h" X Xstatic bool exitcmds = FALSE; X Xvoid Xkfile_init() X{ X ; X} X X#ifndef KILLFILES Xint Xedit_kfile() X{ X notincl("^K"); X return -1; X} X X#else /* KILLFILES */ X Xchar killglobal[] = KILLGLOBAL; Xchar killlocal[] = KILLLOCAL; X Xvoid Xmention(str) Xchar *str; X{ X#ifdef VERBOSE X IF(verbose) { X#ifdef NOFIREWORKS X no_sofire(); X#endif X standout(); X fputs(str,stdout); X un_standout(); X putchar('\n'); X } X ELSE X#endif X#ifdef TERSE X putchar('.'); X#endif X fflush(stdout); X} X Xbool kill_mentioned; X Xint Xdo_kfile(kfp,entering) XFILE *kfp; Xint entering; X{ X#ifdef USETHREADS X int i; X ART_NUM kill_thread; X#endif X X art = lastart+1; X fseek(kfp,0L,0); /* rewind file */ X while (fgets(buf,LBUFLEN,kfp) != Nullch) { X buf[strlen(buf)-1] = '\0'; X if (strnEQ(buf,"THRU",4)) { X ART_NUM tmpart; X X tmpart = atol(buf+4)+1; X if (tmpart < absfirst) X tmpart = absfirst; X check_first(tmpart); X firstart = tmpart; X continue; X } X if (*buf == 'X') { /* exit command? */ X if (entering) { X exitcmds = TRUE; X continue; X } X strcpy(buf,buf+1); X } X else { X if (!entering) X continue; X } X if (*buf == '&') { X mention(buf); X switcheroo(); X } X else if (*buf == '/' && firstart <= lastart) { X mention(buf); X kill_mentioned = TRUE; X switch (art_search(buf, (sizeof buf), FALSE)) { X case SRCH_ABORT: X continue; X case SRCH_INTR: X#ifdef VERBOSE X IF(verbose) X printf("\n(Interrupted at article %ld)\n",(long)art) X FLUSH; X ELSE X#endif X#ifdef TERSE X printf("\n(Intr at %ld)\n",(long)art) FLUSH; X#endif X return -1; X case SRCH_DONE: X break; X case SRCH_SUBJDONE: X fputs("\tsubject not found (???)\n",stdout) FLUSH; X break; X case SRCH_NOTFOUND: X fputs("\tnot found\n",stdout) FLUSH; X break; X case SRCH_FOUND: X fputs("\tfound\n",stdout) FLUSH; X } X } X#ifdef USETHREADS X else if (*buf == 'T' && firstart <= lastart && p_roots) { X /* kill a thread by its root id number */ X kill_thread = atol(buf+1); X for (i = 0; i < total.root; i++) { X if (p_roots[i].root_num == kill_thread) { X if (count_one_root(i) != 0) { X mention(buf); X kill_mentioned = TRUE; X printf("%ldx%d ",(long)kill_thread, X root_article_cnts[i]); X p_art = p_articles + p_roots[i].articles; X art = p_art->num; X follow_thread('k'); X } X break; X } X } X } X#endif X } X X return 0; X} X Xvoid Xkill_unwanted(starting,message,entering) XART_NUM starting; Xchar *message; Xint entering; X{ X bool intr = FALSE; /* did we get an interrupt? */ X ART_NUM oldfirst; X bool anytokill = (toread[ng] > 0); X X if (localkfp || globkfp) { X if (!entering && !exitcmds) X return; X exitcmds = FALSE; X oldfirst = firstart; X firstart = starting; X clear(); X#ifdef VERBOSE X# ifdef TERSE X if (message && (verbose || entering)) X# else X if (message) X# endif X#else X if (message && entering) X#endif X fputs(message,stdout) FLUSH; X X kill_mentioned = FALSE; X if (localkfp) X intr = do_kfile(localkfp,entering); X if (globkfp && !intr) X intr = do_kfile(globkfp,entering); X if (entering && localkfp && !intr) X setthru(lastart); X putchar('\n') FLUSH; X if (entering && kill_mentioned) X#ifdef VERBOSE X IF(verbose) X get_anything(); X ELSE X#endif X#ifdef TERSE X pad(just_a_sec); X#endif X if (anytokill) /* if there was anything to kill */ X forcelast = FALSE; /* allow for having killed it all */ X firstart = oldfirst; X } X} X Xvoid Xsetthru(thru) XART_NUM thru; X{ X FILE *newkfp; X bool no_kills = 0; X#ifdef USETHREADS X int i; X ART_NUM kill_thread; X#endif X X fseek(localkfp,0L,0); /* rewind current file */ X if (fgets(buf,LBUFLEN,localkfp) != Nullch X && (strnNE(buf,"THRU",4) || fgets(buf,LBUFLEN,localkfp) != Nullch)) X fseek(localkfp,0L,0); X else X no_kills = 1; X strcpy(buf,filexp(getval("KILLLOCAL",killlocal))); X UNLINK(buf); /* to prevent file reuse */ X if (no_kills) X open_kfile(KF_LOCAL); /* close file and reset open flag */ X else if (newkfp = fopen(buf,"w")) { X fprintf(newkfp,"THRU %ld\n",(long)thru); X while (fgets(buf,LBUFLEN,localkfp) != Nullch) { X if (strnEQ(buf,"THRU",4)) X continue; X#ifdef USETHREADS X /* Leave out any outdated thread kills */ X if (*buf == 'T' && p_roots) { X kill_thread = atol(buf+1); X for (i = 0; i < total.root; i++) { X if (p_roots[i].root_num == kill_thread) { X break; X } X } X if (i == total.root) X continue; X } X#endif X fputs(buf,newkfp); X } X fclose(newkfp); X open_kfile(KF_LOCAL); /* and reopen local file */ X } X else X printf(cantcreate,buf) FLUSH; X} X X/* edit KILL file for newsgroup */ X Xint Xedit_kfile() X{ X int r = -1; X X if (in_ng) X strcpy(buf,filexp(getval("KILLLOCAL",killlocal))); X else X strcpy(buf,filexp(getval("KILLGLOBAL",killglobal))); X if ((r = makedir(buf,MD_FILE)) >= 0) { X sprintf(cmd_buf,"%s %s", X filexp(getval("VISUAL",getval("EDITOR",defeditor))),buf); X printf("\nEditing %s KILL file:\n%s\n", X (in_ng?"local":"global"),cmd_buf) FLUSH; X resetty(); /* make sure tty is friendly */ X r = doshell(sh,cmd_buf);/* invoke the shell */ X noecho(); /* and make terminal */ X crmode(); /* unfriendly again */ X open_kfile(in_ng); X } X else X printf("Can't make %s\n",buf) FLUSH; X return r; X} X Xvoid Xopen_kfile(local) Xint local; X{ X char *kname = filexp(local ? X getval("KILLLOCAL",killlocal) : X getval("KILLGLOBAL",killglobal) X ); X X stat(kname,&filestat); X if (!filestat.st_size) /* nothing in the file? */ X UNLINK(kname); /* delete the file */ X if (local) { X if (localkfp) X fclose(localkfp); X localkfp = fopen(kname,"r"); X } X else { X if (globkfp) X fclose(globkfp); X globkfp = fopen(kname,"r"); X } X} X Xvoid Xkf_append(cmd) Xchar *cmd; X{ X strcpy(cmd_buf,filexp(getval("KILLLOCAL",killlocal))); X if (makedir(cmd_buf,MD_FILE) >= 0) { X#ifdef VERBOSE X IF(verbose) X printf("\nDepositing command in %s...",cmd_buf); X ELSE X#endif X#ifdef TERSE X printf("\n--> %s...",cmd_buf); X#endif X fflush(stdout); X sleep(2); X if ((tmpfp = fopen(cmd_buf,"a")) != Nullfp) { X fseek(tmpfp,0L,2); /* get to EOF for sure */ X fprintf(tmpfp,"%s\n",cmd); X fclose(tmpfp); X fputs("done\n",stdout) FLUSH; X } X else X printf(cantopen,cmd_buf) FLUSH; X } X} X#endif /* KILLFILES */ END_OF_FILE if test 7167 -ne `wc -c <'kfile.c'`; then echo shar: \"'kfile.c'\" unpacked with wrong size! fi # end of 'kfile.c' fi if test -f 'mt-read.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'mt-read.c'\" else echo shar: Extracting \"'mt-read.c'\" \(12568 characters\) sed "s/^X//" >'mt-read.c' <<'END_OF_FILE' X/* $Header: mt-read.c,v 4.3.3.1 90/07/24 23:51:12 davison Trn $ X** X** $Log: mt-read.c,v $ X** Revision 4.3.3.1 90/07/24 23:51:12 davison X** Initial Trn Release X** X*/ X X#include "EXTERN.h" X#include "common.h" X#include "mthreads.h" X Xstatic FILE *fp_in; X Xvoid tweak_roots(); X X/* Attempt to open the thread file. If it's there, only grab the totals X** from the start of the file. This should give them enough information X** to decide if they need to read the whole thing into memory. X*/ Xint Xinit_data( filename ) Xchar *filename; X{ X root_root = Null(ROOT*); X author_root = Null(AUTHOR*); X unk_domain.ids = Nullart; X unk_domain.link = Null(DOMAIN*); X X if( (fp_in = fopen( filename, "r" )) == Nullfp ) { X bzero( &total, sizeof (TOTAL) ); X return 0; X } X if( fread( &total, 1, sizeof (TOTAL), fp_in ) < sizeof (TOTAL) ) { X fclose( fp_in ); X bzero( &total, sizeof (TOTAL) ); X return 0; X } X return 1; X} X X/* They want everything. Read in the packed information and transform it X** into a set of linked structures that is easily manipulated. X*/ Xint Xread_data() X{ X if( read_authors() X && read_subjects() X && read_roots() X && read_articles() X && read_ids() ) X { X tweak_roots(); X fclose( fp_in ); X return 1; X } X /* Something failed. Free takes care of checking if we're partially X ** allocated. Any linked-list structures we created were freed before X ** we got here. X */ X Free( &strings ); X Free( &subject_cnts ); X Free( &author_cnts ); X Free( &root_array ); X Free( &subject_array ); X Free( &article_array ); X Free( &ids ); X fclose( fp_in ); X return 0; X} X X/* They don't want to read the data. Close the file if we opened it. X*/ Xvoid Xdont_read_data( open_flag ) Xint open_flag; /* 0 == not opened, 1 == open failed, 2 == open */ X{ X if( open_flag == 2 ) { X fclose( fp_in ); X } X} X X#define give_string_to( dest ) /* Comment for makedepend to \ X ** ignore the backslash above */ \ X{\ X register MEM_SIZE len = strlen( string_ptr ) + 1;\ X dest = safemalloc( len );\ X bcopy( string_ptr, dest, (int)len );\ X string_ptr += len;\ X} X Xchar *subject_strings; X X/* The author information is an array of use-counts, followed by all the X** null-terminated strings crammed together. The subject strings are read X** in at the same time, since they are appended to the end of the author X** strings. X*/ Xint Xread_authors() X{ X register int count; X register char *string_ptr; X register WORD *authp; X register AUTHOR *author, *last_author, **author_ptr; X X if( !read_item( &author_cnts, (MEM_SIZE)total.author * sizeof (WORD) ) X || !read_item( &strings, total.string1 ) ) { X return 0; X } X X /* We'll use this array to point each article at its proper author X ** (packed values are saved as indexes). X */ X author_array = (AUTHOR**)safemalloc( total.author * sizeof (AUTHOR*) ); X author_ptr = author_array; X X authp = author_cnts; X string_ptr = strings; X X last_author = Null(AUTHOR*); X for( count = total.author; count--; ) { X *author_ptr++ = author = (AUTHOR*)safemalloc( sizeof (AUTHOR) ); X if( !last_author ) { X author_root = author; X } else { X last_author->link = author; X } X give_string_to( author->name ); X author->count = *authp++; X last_author = author; X } X last_author->link = Null(AUTHOR*); X X subject_strings = string_ptr; X X free( author_cnts ); X author_cnts = Null(WORD*); X X return 1; X} X X/* The subject values consist of the crammed-together null-terminated strings X** (already read in above) and the use-count array. They were saved in the X** order that the roots will need when they are unpacked. X*/ Xint Xread_subjects() X{ X if( !read_item( &subject_cnts, (MEM_SIZE)total.subject * sizeof (WORD) ) ) { X return 0; X } X return 1; X} X X/* Read in the packed root structures and recreate the linked list versions, X** processing each root's subjects as we go. Defer interpretation of article X** offsets until we unpack the article structures. X*/ Xint Xread_roots() X{ X register int count; X register char *string_ptr; X register WORD *subjp; X ROOT *root, *last_root, **root_ptr; X SUBJECT *subject, *last_subject, **subj_ptr; X int ret; X X /* Use this array when unpacking the article's subject offsets. */ X subject_array = (SUBJECT**)safemalloc( total.subject * sizeof (SUBJECT*) ); X subj_ptr = subject_array; X /* And this array points the article's root offsets that the right spot. */ X root_array = (ROOT**)safemalloc( total.root * sizeof (ROOT*) ); X root_ptr = root_array; X X subjp = subject_cnts; X string_ptr = subject_strings; X X#ifndef lint X last_root = (ROOT*)&root_root; X#else X last_root = Null(ROOT*); X#endif X for( count = total.root; count--; ) { X ret = fread( &p_root, 1, sizeof (PACKED_ROOT), fp_in ); X if( ret != sizeof (PACKED_ROOT) ) { X log_error( "failed root read -- %d bytes instead of %d.\n", X ret, sizeof (PACKED_ROOT) ); X ret = 0; X /* Free the roots we've read so far and their subjects. */ X while( root_ptr != root_array ) { X free( *--root_ptr ); X } X while( subj_ptr != subject_array ) { X free( (*--subj_ptr)->str ); X free( *subj_ptr ); X } X goto finish_up; X } X *root_ptr++ = root = (ROOT*)safemalloc( sizeof (ROOT) ); X root->link = Null(ROOT*); X root->seq = p_root.articles; X root->root_num = p_root.root_num; X root->thread_cnt = p_root.thread_cnt; X root->subject_cnt = p_root.subject_cnt; X last_subject = Null(SUBJECT*); X while( p_root.subject_cnt-- ) { X *subj_ptr++ = subject = (SUBJECT*)safemalloc( sizeof (SUBJECT) ); X if( !last_subject ) { X root->subjects = subject; X } else { X last_subject->link = subject; X } X give_string_to( subject->str ); X subject->count = *subjp++; X last_subject = subject; X } X last_subject->link = Null(SUBJECT*); X last_root->link = root; X last_root = root; X } X ret = 1; X X finish_up: X free( subject_cnts ); X free( strings ); X subject_cnts = Null(WORD*); X strings = Nullch; X X return ret; X} X X/* A simple routine that checks the validity of the article's subject value. X** A -1 means that it is NULL, otherwise it should be an offset into the X** subject array we just unpacked. X*/ XSUBJECT * Xvalid_subject( num, art_num ) XWORD num; Xlong art_num; X{ X if( num == -1 ) { X return Null(SUBJECT*); X } X if( num < 0 || num >= total.subject ) { X log_error( "Invalid subject in data file: %d [%ld]\n", num, art_num ); X return Null(SUBJECT*); X } X return subject_array[num]; X} X X/* Ditto for author checking. */ XAUTHOR * Xvalid_author( num, art_num ) XWORD num; Xlong art_num; X{ X if( num == -1 ) { X return Null(AUTHOR*); X } X if( num < 0 || num >= total.author ) { X log_error( "Invalid author in data file: %d [%ld]\n", num, art_num ); X return Null(AUTHOR*); X } X return author_array[num]; X} X X/* Our parent/sibling information is a relative offset in the article array. X** zero for none. Child values are always found in the very next array X** element if child_cnt is non-zero. X*/ X#define valid_node( rel, num ) (!(rel)? Nullart : article_array[(rel)+(num)]) X X/* Read the articles into their linked lists. Point everything everywhere. */ Xint Xread_articles() X{ X register int count; X register ARTICLE *article, **article_ptr; X int ret; X X /* Build an array to interpret interlinkages of articles. */ X article_array = (ARTICLE**)safemalloc( total.article * sizeof (ARTICLE*) ); X article_ptr = article_array; X X /* Allocate all the structures up-front so that we can point to un-read X ** siblings as we go. X */ X for( count = total.article; count--; ) { X *article_ptr++ = (ARTICLE*)safemalloc( sizeof (ARTICLE) ); X } X article_ptr = article_array; X for( count = 0; count < total.article; count++ ) { X ret = fread( &p_article, 1, sizeof (PACKED_ARTICLE), fp_in ); X if( ret != sizeof (PACKED_ARTICLE) ) { X log_error( "failed article read -- %d bytes instead of %d.\n", ret, sizeof (PACKED_ARTICLE) ); X ret = 0; X goto finish_up; X } X article = *article_ptr++; X article->num = p_article.num; X article->date = p_article.date; X article->subject = valid_subject( p_article.subject, p_article.num ); X article->author = valid_author( p_article.author, p_article.num ); X article->flags = p_article.flags; X article->child_cnt = p_article.child_cnt; X article->parent = valid_node( p_article.parent, count ); X article->children = article->child_cnt?article_array[count+1]:Nullart; X article->siblings = valid_node( p_article.siblings, count ); X article->root = root_array[p_article.root]; X } X ret = 1; X X finish_up: X /* We're done with most of the pointer arrays. */ X free( root_array ); X free( subject_array ); X free( author_array ); X root_array = Null(ROOT**); X subject_array = Null(SUBJECT**); X author_array = Null(AUTHOR**); X X return ret; X} X X/* Read the message-id strings and attach them to each article. The data X** format consists of the mushed-together null-terminated strings (a domain X** name followed by all its unique-id prefixes) and then the article offsets X** to which they belong. The first domain name was omitted, as it is the X** ".unknown." domain for those truly weird message-id's without '@'s. X*/ Xint Xread_ids() X{ X register DOMAIN *domain, *last; X register ARTICLE *article; X register char *string_ptr; X register int i, count; X X if( !read_item( &strings, total.string2 ) ) { X return 0; X } X if( !read_item( &ids, X (MEM_SIZE)(total.article+total.domain+1) * sizeof (WORD) ) ) { X return 0; X } X string_ptr = strings; X X last = Null(DOMAIN*); X for( i = 0, count = total.domain + 1; count--; i++ ) { X if( i ) { X domain = (DOMAIN*)safemalloc( sizeof (DOMAIN) ); X give_string_to( domain->name ); X } else { X domain = &unk_domain; X } X if( ids[i] == -1 ) { X domain->ids = Nullart; X } else { X article = article_array[ids[i]]; X domain->ids = article; X for( ;; ) { X give_string_to( article->id ); X article->domain = domain; X if( ids[++i] != -1 ) { X article = article->id_link = article_array[ids[i]]; X } else { X article->id_link = Nullart; X break; X } X } X } X if( last ) { X last->link = domain; X } X last = domain; X } X last->link = Null(DOMAIN*); X free( ids ); X free( strings ); X ids = Null(WORD*); X strings = Nullch; X X return 1; X} X X/* And finally, point all the roots at their root articles and get rid X** of anything left over that was used to aid our unpacking. X*/ Xvoid Xtweak_roots() X{ X register ROOT *root; X X for( root = root_root; root; root = root->link ) { X root->articles = article_array[root->seq]; X } X free( article_array ); X article_array = Null(ARTICLE**); X} X X/* A short-hand for reading a chunk of the file into a malloc'ed array. X*/ Xint Xread_item( dest, len ) Xchar **dest; XMEM_SIZE len; X{ X int ret; X X *dest = safemalloc( len ); X ret = fread( *dest, 1, (int)len, fp_in ); X if( ret != len ) { X log_error( "Only read %ld bytes instead of %ld.\n", X (long)ret, (long)len ); X free( *dest ); X *dest = Nullch; X return 0; X } X return 1; X} X X/* Interpret rn's '%X' and '%x' path prefixes without including all their X** source. Names that don't start with '%' or '/' are prefixed with the X** SPOOL directory. X*/ Xchar * Xfile_exp( name ) Xchar *name; X{ X static char name_buff[256]; X X if( *name == '/' ) { /* fully qualified names are left alone */ X return name; X } else if( *name != '%' ) { /* all normal names are relative to SPOOL */ X sprintf( name_buff, "%s/%s", SPOOL, name ); X } else { /* interpret %x (LIB) & %X (RNLIB) */ X if( name[1] == 'x' ) { X strcpy( name_buff, LIB ); X } else if( name[1] == 'X' ) { X strcpy( name_buff, RNLIB ); X } else { X log_entry( "Unknown expansion: %s", name ); X exit( 1 ); X } X strcat( name_buff, name+2 ); X } X return name_buff; X} X X#ifndef lint X/* A malloc that bombs-out when memory is exhausted. */ Xchar * Xsafemalloc( amount ) XMEM_SIZE amount; X{ X register char *cp; X extern char *malloc(); X X if( (cp = malloc( amount )) == Nullch ) { X log_error( "malloc(%ld) failed.\n", (long)amount ); X exit( 1 ); X } X return cp; X} X#endif X X/* Create a malloc'ed copy of a string. */ Xchar * Xsavestr( str ) Xchar *str; X{ X register MEM_SIZE len = strlen( str ) + 1; X register char *newaddr = safemalloc( len ); X X bcopy( str, newaddr, (int)len ); X X return newaddr; X} X X#ifndef lint X/* Free some memory if it hasn't already been freed. */ Xvoid XFree( pp ) Xchar **pp; X{ X if( *pp ) { X free( *pp ); X *pp = Nullch; X } X} X#endif END_OF_FILE if test 12568 -ne `wc -c <'mt-read.c'`; then echo shar: \"'mt-read.c'\" unpacked with wrong size! fi # end of 'mt-read.c' fi if test -f 'patchlevel' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'patchlevel'\" else echo shar: Extracting \"'patchlevel'\" \(11 characters\) sed "s/^X//" >'patchlevel' <<'END_OF_FILE' XTrn v1.0.1 END_OF_FILE if test 11 -ne `wc -c <'patchlevel'`; then echo shar: \"'patchlevel'\" unpacked with wrong size! fi # end of 'patchlevel' fi if test -f 'search.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'search.c'\" else echo shar: Extracting \"'search.c'\" \(13460 characters\) sed "s/^X//" >'search.c' <<'END_OF_FILE' X/* $Header: search.c,v 4.3.2.2 90/03/22 23:05:31 sob Exp $ X * X * $Log: search.c,v $ X * Revision 4.3.2.2 90/03/22 23:05:31 sob X * Fixes provided by Wayne Davison <drivax!davison> X * X * Revision 4.3.2.1 90/03/17 17:46:29 sob X * Added changes to insure that null search strings won't result in core dumps X * on non-VAX computers. X * X * Revision 4.3 85/05/01 11:50:16 lwall X * Baseline for release with 4.3bsd. X * X */ X X/* string search routines */ X X/* Copyright (c) 1981,1980 James Gosling */ X X/* Modified Aug. 12, 1981 by Tom London to include regular expressions X as in ed. RE stuff hacked over by jag to correct a few major problems, X mainly dealing with searching within the buffer rather than copying X each line to a separate array. Newlines can now appear in RE's */ X X/* Ripped to shreds and glued back together to make a search package, X * July 6, 1984, by Larry Wall. (If it doesn't work, it's probably my fault.) X * Changes include: X * Buffer, window, and mlisp stuff gone. X * Translation tables reduced to 1 table. X * Expression buffer is now dynamically allocated. X * Character classes now implemented with a bitmap. X */ X X#include "EXTERN.h" X#include "common.h" X#include "util.h" X#include "INTERN.h" X#include "search.h" X X#ifndef BITSPERBYTE X#define BITSPERBYTE 8 X#endif X X#define BMAPSIZ (127 / BITSPERBYTE + 1) X X/* meta characters in the "compiled" form of a regular expression */ X#define CBRA 2 /* \( -- begin bracket */ X#define CCHR 4 /* a vanilla character */ X#define CDOT 6 /* . -- match anything except a newline */ X#define CCL 8 /* [...] -- character class */ X#define NCCL 10 /* [^...] -- negated character class */ X#define CDOL 12 /* $ -- matches the end of a line */ X#define CEND 14 /* The end of the pattern */ X#define CKET 16 /* \) -- close bracket */ X#define CBACK 18 /* \N -- backreference to the Nth bracketed X string */ X#define CIRC 20 /* ^ matches the beginning of a line */ X X#define WORD 32 /* matches word character \w */ X#define NWORD 34 /* matches non-word characer \W */ X#define WBOUND 36 /* matches word boundary \b */ X#define NWBOUND 38 /* matches non-(word boundary) \B */ X X#define STAR 01 /* * -- Kleene star, repeats the previous X REas many times as possible; the value X ORs with the other operator types */ X X#define ASCSIZ 0200 Xtypedef char TRANSTABLE[ASCSIZ]; X Xstatic TRANSTABLE trans = { X0000,0001,0002,0003,0004,0005,0006,0007, X0010,0011,0012,0013,0014,0015,0016,0017, X0020,0021,0022,0023,0024,0025,0026,0027, X0030,0031,0032,0033,0034,0035,0036,0037, X0040,0041,0042,0043,0044,0045,0046,0047, X0050,0051,0052,0053,0054,0055,0056,0057, X0060,0061,0062,0063,0064,0065,0066,0067, X0070,0071,0072,0073,0074,0075,0076,0077, X0100,0101,0102,0103,0104,0105,0106,0107, X0110,0111,0112,0113,0114,0115,0116,0117, X0120,0121,0122,0123,0124,0125,0126,0127, X0130,0131,0132,0133,0134,0135,0136,0137, X0140,0141,0142,0143,0144,0145,0146,0147, X0150,0151,0152,0153,0154,0155,0156,0157, X0160,0161,0162,0163,0164,0165,0166,0167, X0170,0171,0172,0173,0174,0175,0176,0177, X}; Xstatic bool folding = FALSE; X Xstatic int err; Xstatic char *FirstCharacter; X Xvoid Xsearch_init() X{ X#ifdef UNDEF X register int i; X X for (i = 0; i < ASCSIZ; i++) X trans[i] = i; X#else X ; X#endif X} X Xvoid Xinit_compex(compex) Xregister COMPEX *compex; X{ X /* the following must start off zeroed */ X X compex->eblen = 0; X compex->brastr = Nullch; X} X Xvoid Xfree_compex(compex) Xregister COMPEX *compex; X{ X if (compex->eblen) { X free(compex->expbuf); X compex->eblen = 0; X } X if (compex->brastr) { X free(compex->brastr); X compex->brastr = Nullch; X } X} X Xstatic char *gbr_str = Nullch; Xstatic int gbr_siz = 0; X Xchar * Xgetbracket(compex,n) Xregister COMPEX *compex; Xint n; X{ X int length = compex->braelist[n] - compex->braslist[n]; X X if (!compex->nbra || n > compex->nbra || !compex->braelist[n] || length<0) X return nullstr; X growstr(&gbr_str, &gbr_siz, length+1); X safecpy(gbr_str, compex->braslist[n], length+1); X return gbr_str; X} X Xvoid Xcase_fold(which) Xint which; X{ X register int i; X X if (which != folding) { X if (which) { X for (i = 'A'; i <= 'Z'; i++) X trans[i] = tolower(i); X } X else { X for (i = 'A'; i <= 'Z'; i++) X trans[i] = i; X } X folding = which; X } X} X X/* Compile the given regular expression into a [secret] internal format */ X Xchar * Xcompile (compex, strp, RE, fold) Xregister COMPEX *compex; Xregister char *strp; Xint RE; Xint fold; X{ X register int c; X register char *ep; X char *lastep; X char bracket[NBRA], X *bracketp; X char **alt = compex->alternatives; X char *retmes = "Badly formed search string"; X X case_fold(compex->do_folding = fold); X if (!compex->eblen) { X compex->expbuf = safemalloc(84); X compex->eblen = 80; X } X ep = compex->expbuf; /* point at expression buffer */ X *alt++ = ep; /* first alternative starts here */ X bracketp = bracket; /* first bracket goes here */ X if (*strp == 0) { /* nothing to compile? */ X if (*ep == 0) /* nothing there yet? */ X return "Null search string"; X return Nullch; /* just keep old expression */ X } X compex->nbra = 0; /* no brackets yet */ X lastep = 0; X for (;;) { X if (ep - compex->expbuf >= compex->eblen) X grow_eb(compex); X c = *strp++; /* fetch next char of pattern */ X if (c == 0) { /* end of pattern? */ X if (bracketp != bracket) { /* balanced brackets? */ X#ifdef VERBOSE X retmes = "Unbalanced parens"; X#endif X goto cerror; X } X *ep++ = CEND; /* terminate expression */ X *alt++ = 0; /* terminal alternative list */ X /* X compex->eblen = ep - compex->expbuf + 1; X compex->expbuf = saferealloc(compex->expbuf,compex->eblen+4); */ X return Nullch; /* return success */ X } X if (c != '*') X lastep = ep; X if (!RE) { /* just a normal search string? */ X *ep++ = CCHR; /* everything is a normal char */ X *ep++ = c; X } X else /* it is a regular expression */ X switch (c) { X X case '\\': /* meta something */ X switch (c = *strp++) { X case '(': X if (compex->nbra >= NBRA) { X#ifdef VERBOSE X retmes = "Too many parens"; X#endif X goto cerror; X } X *bracketp++ = ++compex->nbra; X *ep++ = CBRA; X *ep++ = compex->nbra; X break; X case '|': X if (bracketp>bracket) { X#ifdef VERBOSE X retmes = "No \\| in parens"; /* Alas! */ X#endif X goto cerror; X } X *ep++ = CEND; X *alt++ = ep; X break; X case ')': X if (bracketp <= bracket) { X#ifdef VERBOSE X retmes = "Unmatched right paren"; X#endif X goto cerror; X } X *ep++ = CKET; X *ep++ = *--bracketp; X break; X case 'w': X *ep++ = WORD; X break; X case 'W': X *ep++ = NWORD; X break; X case 'b': X *ep++ = WBOUND; X break; X case 'B': X *ep++ = NWBOUND; X break; X case '0': case '1': case '2': case '3': case '4': X case '5': case '6': case '7': case '8': case '9': X *ep++ = CBACK; X *ep++ = c - '0'; X break; X default: X *ep++ = CCHR; X if (c == '\0') X goto cerror; X *ep++ = c; X break; X } X break; X case '.': X *ep++ = CDOT; X continue; X X case '*': X if (lastep == 0 || *lastep == CBRA || *lastep == CKET X || *lastep == CIRC X || (*lastep&STAR)|| *lastep>NWORD) X goto defchar; X *lastep |= STAR; X continue; X X case '^': X if (ep != compex->expbuf && ep[-1] != CEND) X goto defchar; X *ep++ = CIRC; X continue; X X case '$': X if (*strp != 0 && (*strp != '\\' || strp[1] != '|')) X goto defchar; X *ep++ = CDOL; X continue; X X case '[': { /* character class */ X register int i; X X if (ep - compex->expbuf >= compex->eblen - BMAPSIZ) X grow_eb(compex); /* reserve bitmap */ X for (i = BMAPSIZ; i; --i) X ep[i] = 0; X X if ((c = *strp++) == '^') { X c = *strp++; X *ep++ = NCCL; /* negated */ X } X else X *ep++ = CCL; /* normal */ X X i = 0; /* remember oldchar */ X do { X if (c == '\0') { X#ifdef VERBOSE X retmes = "Missing ]"; X#endif X goto cerror; X } X if (*strp == '-' && *(++strp)) X i = *strp++; X else X i = c; X while (c <= i) { X ep[c / BITSPERBYTE] |= 1 << (c % BITSPERBYTE); X if (fold && isalpha(c)) X ep[(c ^ 32) / BITSPERBYTE] |= X 1 << ((c ^ 32) % BITSPERBYTE); X /* set the other bit too */ X c++; X } X } while ((c = *strp++) != ']'); X ep += BMAPSIZ; X continue; X } X X defchar: X default: X *ep++ = CCHR; X *ep++ = c; X } X } Xcerror: X compex->expbuf[0] = 0; X compex->nbra = 0; X return retmes; X} X Xvoid Xgrow_eb(compex) Xregister COMPEX *compex; X{ X compex->eblen += 80; X compex->expbuf = saferealloc(compex->expbuf, (MEM_SIZE)compex->eblen + 4); X} X Xchar * Xexecute (compex, addr) Xregister COMPEX *compex; Xchar *addr; X{ X register char *p1 = addr; X register char *trt = trans; X register int c; X X if (addr == Nullch || compex->expbuf == Nullch) X return Nullch; X if (compex->nbra) { /* any brackets? */ X for (c = 0; c <= compex->nbra; c++) X compex->braslist[c] = compex->braelist[c] = Nullch; X if (compex->brastr) X free(compex->brastr); X compex->brastr = savestr(p1); /* in case p1 is not static */ X p1 = compex->brastr; /* ! */ X } X case_fold(compex->do_folding); /* make sure table is correct */ X FirstCharacter = p1; /* for ^ tests */ X if (compex->expbuf[0] == CCHR && !compex->alternatives[1]) { X c = trt[compex->expbuf[1]]; /* fast check for first character */ X do { X if (trt[*p1] == c && advance (compex, p1, compex->expbuf)) X return p1; X p1++; X } while (*p1 && !err); X return Nullch; X } X else { /* regular algorithm */ X do { X register char **alt = compex->alternatives; X while (*alt) { X if (advance (compex, p1, *alt++)) X return p1; X } X p1++; X } while (*p1 && !err); X return Nullch; X } X} X X/* advance the match of the regular expression starting at ep along the X string lp, simulates an NDFSA */ Xbool Xadvance (compex, lp, ep) Xregister COMPEX *compex; Xregister char *ep; Xregister char *lp; X{ X register char *curlp; X register char *trt = trans; X register int i; X X while ((*ep & STAR) || *lp || *ep == CIRC || *ep == CKET) X switch (*ep++) { X X case CCHR: X if (trt[*ep++] != trt[*lp]) return FALSE; X lp++; X continue; X X case CDOT: X if (*lp == '\n') return FALSE; X lp++; X continue; X X case CDOL: X if (!*lp || *lp == '\n') X continue; X return FALSE; X X case CIRC: X if (lp == FirstCharacter || lp[-1]=='\n') X continue; X return FALSE; X X case WORD: X if (isalnum(*lp)) { X lp++; X continue; X } X return FALSE; X X case NWORD: X if (!isalnum(*lp)) { X lp++; X continue; X } X return FALSE; X X case WBOUND: X if ((lp == FirstCharacter || !isalnum(lp[-1])) != X (!*lp || !isalnum(*lp)) ) X continue; X return FALSE; X X case NWBOUND: X if ((lp == FirstCharacter || !isalnum(lp[-1])) == X (!*lp || !isalnum(*lp))) X continue; X return FALSE; X X case CEND: X return TRUE; X X case CCL: X if (cclass (ep, *lp, 1)) { X ep += BMAPSIZ; X lp++; X continue; X } X return FALSE; X X case NCCL: X if (cclass (ep, *lp, 0)) { X ep += BMAPSIZ; X lp++; X continue; X } X return FALSE; X X case CBRA: X compex->braslist[*ep++] = lp; X continue; X X case CKET: X i = *ep++; X compex->braelist[i] = lp; X compex->braelist[0] = lp; X compex->braslist[0] = compex->braslist[i]; X continue; X X case CBACK: X if (compex->braelist[i = *ep++] == 0) { X fputs("bad braces\n",stdout) FLUSH; X err = TRUE; X return FALSE; X } X if (backref (compex, i, lp)) { X lp += compex->braelist[i] - compex->braslist[i]; X continue; X } X return FALSE; X X case CBACK | STAR: X if (compex->braelist[i = *ep++] == 0) { X fputs("bad braces\n",stdout) FLUSH; X err = TRUE; X return FALSE; X } X curlp = lp; X while (backref (compex, i, lp)) { X lp += compex->braelist[i] - compex->braslist[i]; X } X while (lp >= curlp) { X if (advance (compex, lp, ep)) X return TRUE; X lp -= compex->braelist[i] - compex->braslist[i]; X } X continue; X X case CDOT | STAR: X curlp = lp; X while (*lp++ && lp[-1] != '\n'); X goto star; X X case WORD | STAR: X curlp = lp; X while (*lp++ && isalnum(lp[-1])); X goto star; X X case NWORD | STAR: X curlp = lp; X while (*lp++ && !isalnum(lp[-1])); X goto star; X X case CCHR | STAR: X curlp = lp; X while (*lp++ && trt[lp[-1]] == trt[*ep]); X ep++; X goto star; X X case CCL | STAR: X case NCCL | STAR: X curlp = lp; X while (*lp++ && cclass (ep, lp[-1], ep[-1] == (CCL | STAR))); X ep += BMAPSIZ; X goto star; X X star: X do { X lp--; X if (advance (compex, lp, ep)) X return TRUE; X } while (lp > curlp); X return FALSE; X X default: X fputs("Badly compiled pattern\n",stdout) FLUSH; X err = TRUE; X return -1; X } X if (*ep == CEND || *ep == CDOL) { X return TRUE; X } X return FALSE; X} X Xbool Xbackref (compex, i, lp) Xregister COMPEX *compex; Xregister int i; Xregister char *lp; X{ X register char *bp; X X bp = compex->braslist[i]; X while (*lp && *bp == *lp) { X bp++; X lp++; X if (bp >= compex->braelist[i]) X return TRUE; X } X return FALSE; X} X Xbool Xcclass (set, c, af) Xregister char *set; Xregister int c; X{ X c &= 0177; X#if BITSPERBYTE == 8 X if (set[c >> 3] & 1 << (c & 7)) X#else X if (set[c / BITSPERBYTE] & 1 << (c % BITSPERBYTE)) X#endif X return af; X return !af; X} END_OF_FILE if test 13460 -ne `wc -c <'search.c'`; then echo shar: \"'search.c'\" unpacked with wrong size! fi # end of 'search.c' fi echo shar: End of archive 10 \(of 14\). cp /dev/null ark10isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 14 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still must unpack the following archives: echo " " ${MISSING} fi exit 0 exit 0 # Just in case... -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net. Use a domain-based address or give alternate paths, or you may lose out.