Xref: utzoo news.software.b:5522 comp.sources.bugs:2514 Path: utzoo!utstat!news-server.csri.toronto.edu!mailrus!uunet!drivax!davison From: davison@drivax.UUCP (Wayne Davison) Newsgroups: news.software.b,comp.sources.bugs Subject: trn patch #1 Message-ID: Date: 21 Aug 90 03:48:38 GMT Organization: Digital Research, Monterey CA Lines: 2120 This is official patch #1 for trn v1.0. It is a shar archive of the files unipatch.c and patch1. To extract it from trn type "e DIR" where DIR is the directory of your trn source, or extract it will a de-shar'ing tool. To apply the patch, compile the program unipatch.c with the command "cc -o unipatch unipatch.c" and patch the source with the command "unipatch 'unipatch.c' /* A filter to turn a unidiff into a degenerate context diff (no '!'s) for patch. Author: davison@dri.com (uunet!drivax!davison). */ #include #define ERR(a) {fputs(a,stderr);exit(1);} struct Ln { struct Ln *lk; char t; char s[1]; } r,*h,*ln; char *malloc(); main() { char bf[2048],*cp,ch; long os,ol,ns,nl,ne,lncnt=0; for(;;){ for(;;){ if(!fgets(bf,sizeof bf,stdin)) exit(0); lncnt++; if(!strncmp(bf,"@@ -",4)) break; fputs(bf,stdout); } if(sscanf(bf+4,"%ld,%ld +%ld,%ld %c",&os,&ol,&ns,&nl,&ch)!=5||ch!='@') goto bad; r.lk=0, h= &r, ne=ns+nl-1; printf("***************\n*** %ld,%ld ****\n",os,os+ol-(os>0)); while(ol||nl){ if(!fgets(bf,sizeof bf,stdin)){ if(nl>2) ERR("Unexpected end of file.\n"); strcpy(bf," \n"); } lncnt++; if(*bf=='\t'||*bf=='\n') ch=' ', cp=bf; else ch= *bf, cp=bf+1; switch(ch){ case'-':if(!ol--) goto bad; printf("- %s",cp); break; case'=':ch=' '; case' ':if(!ol--) goto bad; printf(" %s",cp); case'+':if(!nl--) goto bad; ln = (struct Ln*)malloc(sizeof(*ln)+strlen(cp)); if(!ln) ERR("Out of memory!\n"); ln->lk=0, ln->t=ch, strcpy(ln->s,cp); h->lk=ln, h=ln; break; default: bad: fprintf(stderr,"Malformed unidiff at line %ld: ",lncnt); ERR(bf); } } printf("--- %ld,%ld ----\n",ns,ne); for(ln=r.lk;ln;ln=h){ printf("%c %s",ln->t,ln->s); h=ln->lk; free(ln); } } } SHAR_EOF fi echo shar: "extracting 'patch1'" '(57455 characters)' if test -f 'patch1' then echo shar: "will not over-write existing file 'patch1'" else cat << \SHAR_EOF > 'patch1' Index: patchlevel Prereq: v1.0 @@ -1,1 +1,1 @@ -Trn v1.0 +Trn v1.0.1 Index: Configure @@ -4,7 +4,10 @@ =# shell scripts, Configure will trim # comments from them for you. =# -# $Header: Configure,v 4.3.3.1 90/07/24 21:56:31 davison Trn $ +# $Header: Configure,v 4.3.3.2 90/08/20 16:09:59 davison Trn $ =# =# $Log: Configure,v $ +# Revision 4.3.3.2 90/08/20 16:09:59 davison +# Added MMDF support, revised sitename/domain/signal/tzset/PATH. +# =# Revision 4.3.3.1 90/07/24 21:56:31 davison =# Initial Trn Release @@ -115,4 +118,7 @@ =# Yes, you may rip this off to use in other distribution packages. = +WHITE='[ ]'; : there should be a tab and a space between the brackets. +CTRLA=''; : there should be a control-A between the single-quotes. + =n='' =c='' @@ -167,4 +173,5 @@ =Header='' =sitename='' +hostfile='' =domain='' =orgname='' @@ -232,5 +239,5 @@ = =: sanity checks -PATH='.:/bin:/usr/bin:/usr/local/bin:/usr/ucb:/usr/local:/usr/lbin:/etc' +PATH='.:/bin:/usr/bin:/usr/local/bin:/usr/ucb:/usr/local:/usr/lbin:/etc:/usr/bsd' =export PATH || (echo "OOPS, this isn't sh. Desperation time. I will feed myself to sh."; sh $0; kill $$) = @@ -570,5 +577,4 @@ = rrninclude="-DUSG -DLAI_TCP" = socketlib=-lsocket - sigret=void = rdchk=define = dirtype=dirent @@ -858,4 +864,30 @@ =$eunicefix filexp = +: try to deal with domains +$cat << 'EOH' + +Please enter your domain name. This will be used in conjunction with the +site name for return addresses on news articles and mail. If you use the +4.3ism of having your domain in your hostname, all the posting programs +will figure this out on the fly, so don't worry. + +Examples of some valid domains: + berkeley.edu + nasa.gov +Example of an invalid domain in common use: + uucp +EOH + +case "$domain" in +'') dflt="uucp";; +*) dflt="$domain" ;; +esac +$echo $n "Your domain: [$dflt] $c" +. myread +case "$ans" in +'') domain="$dflt";; +*) domain="$ans" ;; +esac + =: now get the site name =$echo " " @@ -903,59 +935,55 @@ =esac = -: verify guess +: verify site name and allow them to override it =if $test "$sitename" ; then = $echo 'Your site name appears to be "'$sitename'".' - $echo $n "Is this correct? [y] $c" - . myread - case $ans in - y*|'') ;; - *) sitename='' ;; - esac +else + sitename='unknown' =fi +case "$hostfile" in +/*) dflt="$hostfile" ;; +*) dflt="$sitename" ;; +esac +$cat <<'EOM' = -: bad guess or no guess -while $test "X$sitename" = X ; do - $echo $n "Please type the (one word) name of your site: $c" - . myread - sitename="$ans" - case $hostcmd in - sed*) - $echo "(That doesn't agree with your whoami.h file, by the way.)" - ;; - *) - $echo "(That doesn't agree with your $hostcmd command, by the way.)" +In some cases it is not desirable to use the actual site name in your return +addresses (if, for example, all mail gets routed first to one site). In this +case trn allows you to either hard-wire a site name or read the site name from +a file. To indicate a file, start the name with a slash (e.g. /etc/sitename). +To use just your domain name, re-enter it here. A period-less site name will +automatically get your domain name added to it. + +EOM +while $test $dflt ; do + $echo $n "What site name goes in return addresses? [$dflt] $c" + . myread + case $ans in + '') ans=$dflt;; + esac + case $ans in + /*) + if $test -f $ans ; then + hostfile="$ans" + hostcmd="$cat $ans" + sitename=`$hostcmd` + $echo "Trn will read the site name from $ans: $sitename." + dflt='' + else + $echo "Unable to locate $ans." + fi + ;; + *) hostfile='' + if $test "X$sitename" = "X$ans" ; then + $echo "Using the site name derived by $hostcmd: $sitename." + else + hostcmd='' + sitename="$ans" + $echo "Using a hard-wired site name: $sitename." + fi + dflt='' = ;; = esac - hostcmd='' =done = -: try to deal with domains -$cat << 'EOH' - -Please enter your domain name. This will be used in conjunction -with the site name for return addresses on news articles and -mail. If you use the 4.3ism of having your domain in your -hostname, all the posting programs will figure this out on the -fly, so don't worry. - -Examples of some valid domains: - - berkeley.edu - nasa.gov -Example of an invalid domain in common use: - uucp -EOH - -case "$domain" in -'') dflt="uucp";; -*) dflt="$domain" ;; -esac -$echo $n "Your domain: [$dflt] $c" -. myread -case "$ans" in -'') domain="$dflt";; -*) domain="$ans" ;; -esac - =if $test $portable = "undef" ; then = case $sitename in @@ -1121,18 +1149,21 @@ = ;; =esac -maildir='blurfl/dyick' -while $test ! -d "$maildir" ; do - case $maildir in - blurfl*) ;; - *) $echo "$maildir does not appear to exist." ;; - esac - $echo " " - $echo $n "Where is yet-to-be-read mail spooled? [$dflt] $c" - . myread - maildir=`filexp "$ans"` - case $maildir in - '') maildir=$dflt ;; - esac -done +case "$dflt" in +*%L*) ;; +*) dflt="$dflt/%L" +esac +$cat <<'EOM' + +Trn needs to know where to find yet-to-be-read mail. Sendmail sites +use /usr/spool/mail/%L (where '%L' is the user's login name). Some +MMDF sites use /usa/%L/.mail instead. + +EOM +$echo $n "Where is yet-to-be-read mail spooled? [$dflt] $c" +. myread +maildir="$ans" +case $maildir in +'') maildir=$dflt ;; +esac = =: find out how to find out full name @@ -1303,4 +1334,26 @@ =fi = +: check for tzset. +$echo " " +if $contains tzset libc.list >/dev/null 2>&1 || + $contains mktime libc.list >/dev/null 2>&1 || + $contains tzset /usr/include/time.h >/dev/null 2>&1 ; then + $echo "Your system appears to use tzset() rather than ftime()." + $echo $n "Is this correct? [y] $c" + . myread + case $ans in + n*|f*) tzset='undef' ;; + *) tzset='define' ;; + esac +else + $echo "Your system appears to use ftime() rather than tzset()." + $echo $n "Is this correct? [y] $c" + . myread + case $ans in + n*|f*) tzset='define' ;; + *) tzset='undef' ;; + esac +fi + =: determine how to determine when a file is a mailbox =case "$mboxchar" in @@ -1314,8 +1367,8 @@ =of the file in question. On most systems the first line starts "From...", =so the first character is F. On other systems there are magic cookies like -control codes between articles, so one of those would be first. On your -system, if a file is in mailbox format, what is the first character of +control codes between articles, so one of those would be first. For example, +MMDF messages are seperated with lines of 4 control-A's. On your system, if a =EOM -$echo $n "that file? [$dflt] $c" +$echo $n "file is in mailbox format, what is the first character of that file? [$dflt] $c" =. myread =mboxchar="$ans" @@ -1325,4 +1378,5 @@ =case $mboxchar in ='F') ;; +"$CTRLA") ;; =*) cat <<'EOM' =You will need to edit the shell script mbox.saver to properly append an @@ -1513,14 +1567,4 @@ =fi = -: check for tzset. ass_u_me others have ftime. -if $contains tzset libc.list >/dev/null 2>&1 || - $contains mktime libc.list >/dev/null 2>&1 ; then - $echo "tzset() found." - tzset='define' -else - $echo "No tzset() found -- we'll use ftime() instead." - tzset='undef' -fi - =: see if YP could be running here =if $contains yp_master.o libc.list >/dev/null 2>&1 ; then @@ -1543,19 +1587,14 @@ =if [ -f /usr/include/signal.h ] =then - WHITE='[ ]'; : between the brackets are a tab and a space. - if grep "$WHITE*void$WHITE*(\*signal())();" \ - /usr/include/signal.h >/dev/null - then - sigret=void - fi -fi + $cpp /usr/include/signal.h >sigtest +else =if [ -f /usr/include/sys/signal.h ] =then - WHITE='[ ]'; : between the brackets are a tab and a space. - if grep "$WHITE*void$WHITE*(\*signal())();" \ - /usr/include/sys/signal.h >/dev/null - then - sigret=void - fi + $cpp /usr/include/sys/signal.h >sigtest +fi +fi +if grep "$WHITE*void$WHITE*(\*signal())();" sigtest >/dev/null +then + sigret=void =fi =$echo "signal() returns $sigret on this system" @@ -1564,4 +1603,10 @@ =gethostname=undef =phostname=undef +if $test ! "X$hostfile" = X ; then + gethostname=define +else +if $test "X$hostcmd" = X ; then + : it is already compiled in +else =if $contains gethostname.o libc.list >/dev/null 2>&1 ; then = $echo "gethostname() found." @@ -1627,4 +1672,6 @@ = fi =fi +fi +fi = =: see if we need -ljobs and if we have sigset, etc. @@ -1710,4 +1757,5 @@ = ndirc='ndir.c' = ndiro='ndir.o' + dirtype=direct = fi = fi @@ -2459,4 +2507,5 @@ =Header='$Header' =sitename='$sitename' +hostfile='$hostfile' =domain='$domain' =orgname='$orgname' @@ -2517,4 +2566,5 @@ =NNTPSRC='$NNTPSRC' =CONFIG=true +CTRLA='$CTRLA' =EOT = @@ -2551,4 +2601,8 @@ =*) isrrn2='/*';; =esac +case "$hostfile" in +'') usehostfile='/*';; +*) usehostfile='';; +esac =$cat <config.h =/* config.h @@ -2557,6 +2611,10 @@ = */ = -/* name of the site. May be overridden by gethostname, uname, etc. */ +/* name of the site. May be overridden by HOSTFILE, gethostname, uname, etc. */ =#define SITENAME "$sitename" +$usehostfile#define HOSTFILE "$hostfile" + +/* OURDOMAIN is added to the site name if no "." is in it. */ +#define OURDOMAIN "$domain" = =/* name of the organization, may be a file name */ @@ -2585,5 +2643,5 @@ = =/* location of spooled mail */ -#define MAILFILE "$maildir/%L" +#define MAILFILE "$maildir" = =/* default shell--ok to be a slow shell like csh */ Index: Pnews.SH @@ -5,7 +5,10 @@ =$spitshell >Pnews <> ${HOME-$LOGDIR}/dead.article - $echo "Article appended to ${HOME-$LOGDIR}/dead.article" - $echo "A copy may be temporarily found in $tmpart" + if $test -s $tmpart; then + $cat $tmpart >> ${HOME-$LOGDIR}/dead.article + $echo "Article appended to ${HOME-$LOGDIR}/dead.article" + $echo "A copy may be temporarily found in $tmpart" + else + $echo "Null article discarded." + fi = exit = ;; @@ -519,10 +529,7 @@ = set X ${USER-${LOGNAME-`who am i`}} unknown = shift - logname=$1 - if $echo "From $logname `date`" >> $AUTHORCOPY; then - $cat $tmpart >> $AUTHORCOPY + $rnlib/mbox.saver $tmpart "." "." 0 0 Pnews $AUTHORCOPY "From $1 `date`" + if $test $? -eq 0 ; then = $echo "Article appended to $AUTHORCOPY" - $echo "" >> $AUTHORCOPY - $echo "" >> $AUTHORCOPY = else = $echo "Cannot append to $AUTHORCOPY" Index: README @@ -91,4 +91,7 @@ = which will lower the amount of space required for thread files. = + ** If you got trn in shar format, check Configure to ensure that WHITE + and CTRLA have a Tab-Space and a Ctrl-A in them, respectively. ** + =1) Run Configure. This will figure out various things about your system. = Some things Configure will figure out for itself, other things it will @@ -125,9 +128,9 @@ = reasonable place. = -5) Once trn is all compiled, you need to create some thread data to be able - to use all the new features. If you like, you can start small with a - command like: "mthreads rec.humor.funny" or "mthreads news". You can - also choose to create any subset of the entire hierarchy by modifying - the active2 file in the trn library. Read the mthreads manpage for +5) Once trn is compiled, you need to create some thread data to be + able to use all the new features. If you like, you can start small + with a command like: "mthreads rec.humor.funny", process a few more + groups with the command "mthreads news", and then turn them all on + with the command "mthreads all". Read the mthreads manpage for = complete details. = @@ -152,6 +155,6 @@ = it on a regular basis with the standard-output redirected to /dev/null. = -9) IMPORTANT! Help save the world! Communicate any problems and - suggested patches to davison%drivax@uunet.uu.net so we can keep +9) IMPORTANT! Help save the world! Communicate any problems and suggested + patches to davison@dri.com (...!uunet!drivax!davison) so we can keep = everyone in sync. If you have a problem, there's someone else = out there who either has had or will have the same problem. Please Index: Rnmail.SH @@ -5,7 +5,10 @@ =$spitshell >Rnmail <> $MAILRECORD + set X ${USER-${LOGNAME-`who am i`}} unknown + shift + $rnlib/mbox.saver $tmpart "." "." 0 0 Pnews $MAILRECORD "From $1 `date`" = if $test $? -eq 0 ; then = $echo "Message appended to $MAILRECORD" Index: addng.c @@ -1,5 +1,8 @@ -/* $Header: addng.c,v 4.3.3.1 90/06/20 22:35:43 davison Trn $ +/* $Header: addng.c,v 4.3.3.2 90/08/20 16:27:06 davison Trn $ = * = * $Log: addng.c,v $ + * Revision 4.3.3.2 90/08/20 16:27:06 davison + * Allow breaking out of ng adding. Don't add 'X'ed groups. + * = * Revision 4.3.3.1 90/06/20 22:35:43 davison = * Initial Trn Release @@ -43,4 +46,5 @@ =#include "server.h" =#endif +#include "final.h" =#include "INTERN.h" =#include "addng.h" @@ -71,4 +75,9 @@ = } = while (fgets(buf,LBUFLEN,actfp) != Nullch) { + /* Check if they want to break out of the new newsgroups search */ + if (int_count) { + int_count = 0; + return FALSE; + } = if (s = index(buf,' ')) { = status=s; @@ -75,5 +84,10 @@ = while (isdigit(*status) || isspace(*status)) status++; = *s++ = '\0'; +#ifdef USETHREADS + if (strnEQ(buf,"to.",3) || *status == 'x' || *status == 'X' + || *status == '=') +#else = if (strnEQ(buf,"to.",3) || *status == 'x' || *status == '=') +#endif = /* since = groups are refiling to another group, just = ignore their existence */ Index: art.c @@ -1,5 +1,8 @@ -/* $Header: art.c,v 4.3.3.1 90/06/20 22:35:51 davison Trn $ +/* $Header: art.c,v 4.3.3.2 90/08/20 16:05:33 davison Trn $ = * = * $Log: art.c,v $ + * Revision 4.3.3.2 90/08/20 16:05:33 davison + * Fixed bug in backpage code. + * = * Revision 4.3.3.1 90/06/20 22:35:51 davison = * Initial Trn Release @@ -824,6 +827,7 @@ = target = topline - (LINES - 2); = artline = topline; - while (artline >= 0 && artline > target && vrdary(artline-1) >= 0) + if (artline >= 0) do { = artline--; + } while(artline >= 0 && artline > target && vrdary(artline-1) >= 0); = topline = artline; = /* remember top line of screen */ Index: artio.c @@ -1,5 +1,8 @@ -/* $Header: artio.c,v 4.3.3.1 90/07/21 20:11:03 davison Trn $ +/* $Header: artio.c,v 4.3.3.2 90/08/20 16:25:50 davison Trn $ = * = * $Log: artio.c,v $ + * Revision 4.3.3.2 90/08/20 16:25:50 davison + * Fixed bug in artopen ==> nntpopen interaction. + * = * Revision 4.3.3.1 90/07/21 20:11:03 davison = * Initial Trn Release @@ -48,5 +51,5 @@ ={ =#ifdef SERVER - nntpopen(artnum,GET_ARTICLE); + return nntpopen(artnum,GET_ARTICLE); =#else = char artname[32]; /* filename of current article */ @@ -66,5 +69,4 @@ = if (artfp = fopen(artname,"r")) /* if we can open it */ = openart = artnum; /* remember what we did here */ -#endif /* SERVER */ =#ifdef LINKART = { @@ -94,4 +96,5 @@ =#endif = return artfp; /* and return either fp or NULL */ +#endif /* SERVER */ =} = Index: common.h @@ -1,5 +1,8 @@ -/* $Header: common.h,v 4.3.3.1 90/07/21 20:15:23 davison Trn $ +/* $Header: common.h,v 4.3.3.2 90/08/20 16:28:32 davison Trn $ = * = * $Log: common.h,v $ + * Revision 4.3.3.2 90/08/20 16:28:32 davison + * Tweaked a couple rn's into trn's. + * = * Revision 4.3.3.1 90/07/21 20:15:23 davison = * Initial Trn Release @@ -437,5 +440,5 @@ =/* path to private executables */ =#ifndef RNLIB /* ~, %x and %l only */ -# define RNLIB "%x/rn" +# define RNLIB "%x/trn" =#endif = @@ -737,5 +740,5 @@ =#ifndef CANCELHEADER =#ifdef INTERNET -# define CANCELHEADER "Newsgroups: %n\nSubject: cmsg cancel %i\nReferences: %R\nDistribution: %D\nOrganization: %o\n\nThis message was cancelled from within rn.\n" +# define CANCELHEADER "Newsgroups: %n\nSubject: cmsg cancel %i\nReferences: %R\nDistribution: %D\nOrganization: %o\n\nThis message was cancelled from within trn.\n" =#else =# define CANCELHEADER "Newsgroups: %n\nSubject: cmsg cancel %i\nReferences: %R\nDistribution: %D\nOrganization: %o\n" Index: intrp.c @@ -1,5 +1,8 @@ -/* $Header: intrp.c,v 4.3.3.1 90/07/21 20:20:13 davison Trn $ +/* $Header: intrp.c,v 4.3.3.2 90/08/20 16:29:08 davison Trn $ = * = * $Log: intrp.c,v $ + * Revision 4.3.3.2 90/08/20 16:29:08 davison + * Added HOSTFILE handling. Add OURDOMAIN if site has no '.' + * = * Revision 4.3.3.1 90/07/21 20:20:13 davison = * Initial Trn Release @@ -152,4 +155,15 @@ = /* name of this site (%H) */ = +#ifdef HOSTFILE + if ((tmpfp = fopen(HOSTFILE,"r")) == NULL) { + hostname = "unknown"; + printf("Warning: Couldn't open %s to determine hostname!\n", HOSTFILE); + } else { + fgets(buf, sizeof(buf), tmpfp); + buf[strlen(buf)-1] = 0; + hostname = savestr(buf); + fclose(tmpfp); + } +#else =#ifdef GETHOSTNAME = gethostname(buf,sizeof buf); @@ -177,5 +191,12 @@ =#endif =#endif - sitename = savestr(SITENAME); +#endif +#ifdef OURDOMAIN + if (index(SITENAME,'.') == NULL) { + sprintf(buf, "%s.%s", SITENAME, OURDOMAIN); + sitename = savestr(buf); + } else +#endif + sitename = savestr(SITENAME); =} = Index: mbox.saver.SH @@ -5,7 +5,10 @@ =$spitshell >mbox.saver <>mbox.saver <> \$7 +!GROK!THIS! + ;; +*) + $spitshell >>mbox.saver <From /" = $echo "" @@ -44,4 +63,6 @@ = $echo "" ) >> \$7 =!GROK!THIS! + ;; +esac =$eunicefix mbox.saver =chmod 755 mbox.saver Index: mt-process.c @@ -1,5 +1,8 @@ -/* $Header: mt-process.c,v 4.3.3.1 90/07/28 18:04:45 davison Trn $ +/* $Header: mt-process.c,v 4.3.3.2 90/08/20 16:40:31 davison Trn $ =** =** $Log: mt-process.c,v $ +** Revision 4.3.3.2 90/08/20 16:40:31 davison +** Added check of caught_interrupt flag into main loops. +** =** Revision 4.3.3.1 90/07/28 18:04:45 davison =** Initial Trn Release @@ -76,5 +79,4 @@ = i = first_article; = } - processed_groups++; = added_count = last_article - i + 1; = expired_count = 0; @@ -81,4 +83,7 @@ = = for( ; i <= last_article; i++ ) { + if( caught_interrupt ) { + return; + } =#ifdef SERVER = sprintf( buff, "HEAD %ld", (long)i ); @@ -225,4 +230,7 @@ = expire( first_article ); = } + if( caught_interrupt ) { + return; + } = trim_roots(); = order_roots(); @@ -251,4 +259,7 @@ = next_domain = domain->link; = for( article = domain->ids; article; article = next_art ) { + if( caught_interrupt ) { + return; + } = next_art = article->id_link; = if( !article->subject || (article->flags & NEW_ARTICLE) ) { Index: mt.check.SH @@ -5,7 +5,10 @@ =$spitshell >mt.check </dev/null +.PP +to run an mthreads single-pass with extended expire that leaves new groups +unthreaded. =.SH FILES =/usr/lib/news/active @@ -232,3 +284,3 @@ =Lots of thread data files. =.SH AUTHOR -Wayne Davison +Wayne Davison Index: mthreads.c @@ -1,5 +1,8 @@ -/* $Header: mthreads.c,v 4.3.3.1 90/07/24 22:24:17 davison Trn $ +/* $Header: mthreads.c,v 4.3.3.2 90/08/20 16:43:19 davison Trn $ =** =** $Log: mthreads.c,v $ +** Revision 4.3.3.2 90/08/20 16:43:19 davison +** Implemented new command-line interface and database upgrading. +** =** Revision 4.3.3.1 90/07/24 22:24:17 davison =** Initial Trn Release @@ -13,9 +16,9 @@ =** When fully updated, the two files should be identical. This gives us =** quick access to the last processed high/low counts without opening -** each data file, PLUS it allows tn to use the fake active file as if it +** each data file, PLUS it allows trn to use the fake active file as if it =** were the real thing to keep it from seeing articles before they are -** processed. If the active2 file is removed or corrupted, it should -** be automatically repaired in the normal course of operation. We update -** the file IN PLACE so that tn can keep it open all the time. Normally +** processed. If the active2 file is removed or corrupted, it will be +** automatically repaired in the normal course of operation. We update +** the file IN PLACE so that trn can keep it open all the time. Normally =** the size of the file does not change, so it is easy to do. In those =** rare instances where a news admin shuffles the real active file, we @@ -22,5 +25,5 @@ =** take it all in stride by throwing a little memory at the problem. =** -** Usage: mthreads [-d[MM]] [-e[HHMM]] [-f] [-v] [hierarchy] +** Usage: mthreads [-d[MM]] [-e[HHMM]] [-aDfknv] [hierarchy_list] =*/ = @@ -47,4 +50,7 @@ =static char line2[256]; = +/* If you want to change the field size, do it once and then leave it alone. */ +char fmt_active2[] = "%s %06ld %06ld %c\n"; + =char *filename; = @@ -61,10 +67,9 @@ =ACTIVE_LINE *line_root = Nullact, *last_line = Nullact, *pline = Nullact; = -bool force_flag = FALSE, grevious_error; -int daemon_delay = 0; +bool force_flag = FALSE, kill_mthreads = FALSE, no_processing = FALSE; +bool add_new = FALSE, rebuild = FALSE, grevious_error; +int daemon_delay = 0, log_verbosity = 0, debug = 0; =long expire_time = 0; -int log_verbosity = 0; -char *hierarchy = "all"; -int match_len = 0; +char *hierarchy_list = NULL; =long truncate_len = -1; = @@ -82,4 +87,10 @@ =#define TIMER_DEFAULT (10 * 60) = +int added_groups, removed_groups, action; + +#define NG_DEFAULT 0 +#define NG_MATCH 1 +#define NG_SKIP 2 + =#ifdef SERVER =char *server; @@ -102,4 +113,10 @@ = while( *++*argv ) { = switch( **argv ) { + case 'a': /* automatically thread new groups */ + add_new = TRUE; + break; + case 'D': + debug++; + break; = case 'd': = if( *++*argv <= '9' && **argv >= '0' ) { @@ -145,4 +162,10 @@ = force_flag = TRUE; = break; + case 'k': + kill_mthreads = TRUE; + break; + case 'n': + no_processing = TRUE; + break; = case 'v': = log_verbosity++; @@ -154,10 +177,9 @@ = } = } else { - if( match_len ) { - fprintf( stderr, "Only one hierarchy name is currently allowed.\n" ); + if( hierarchy_list ) { + fprintf( stderr, "Specify the newsgroups in one comma-separated list.\n" ); = exit( 1 ); = } - hierarchy = *argv; - match_len = strlen( hierarchy ); + hierarchy_list = *argv; = } = } @@ -204,5 +226,5 @@ = } = fclose( fp_lock ); - if( kill( otherpid, 0 ) == -1 ) { + if( kill( otherpid, kill_mthreads ? SIGTERM : 0 ) == -1 ) { = if( unlink( filename ) == -1 ) { = fprintf( stderr, "unable to unlink lockfile %s\n", filename ); @@ -210,9 +232,16 @@ = exit( 1 ); = } - goto dolink; + if( !kill_mthreads ) { + goto dolink; + } = } - fprintf( stderr, "mthreads is already running.\n" ); = unlink( line ); - exit( 1 ); + if( kill_mthreads ) { + fprintf( stderr, "killing currently running mthreads.\n" ); + exit( 0 ); + } else { + fprintf( stderr, "mthreads is already running.\n" ); + exit( 1 ); + } = } = @@ -219,4 +248,9 @@ = unlink( line ); /* remove temporary LOCK. file */ = + if( kill_mthreads ) { + fprintf( stderr, "mthreads is not running.\n" ); + exit( 1 ); + } + = /* Open our log file */ = filename = file_exp( "%X/mt.log" ); @@ -245,5 +279,5 @@ =#ifdef lint = alarm_handler(); /* foolishness for lint's sake */ - interrupt(14); + interrupt( 14 ); =#endif = @@ -251,8 +285,9 @@ = filename = file_exp( "%X/db.init" ); = if( (fp_lock = fopen( filename, "r")) == Nullfp - || fread( &mt_bmap, 1, sizeof (BMAP), fp_lock ) < sizeof (BMAP) ) { + || fread( &mt_bmap, 1, sizeof (BMAP), fp_lock ) < sizeof (BMAP)-1 ) { = if( fp_lock != Nullfp ) { = fclose( fp_lock ); = } + write_db_init: = mybytemap( &mt_bmap ); = if( (fp_lock = fopen( filename, "w" )) == Nullfp ) { @@ -260,5 +295,5 @@ = exit( 1 ); = } - mt_bmap.version = 1; + mt_bmap.version = DB_VERSION; = fwrite( &mt_bmap, 1, sizeof (BMAP), fp_lock ); = fclose( fp_lock ); @@ -266,4 +301,15 @@ = int i; = + fclose( fp_lock ); + if( mt_bmap.version != DB_VERSION ) { + if( mt_bmap.version == DB_VERSION-1 ) { + rebuild = TRUE; + log_entry( "Upgrading database to version %d.\n", DB_VERSION ); + goto write_db_init; + } + log_entry( "** Database is not the right version (%d instead of %d) **\n", + mt_bmap.version, DB_VERSION ); + exit( 1 ); + } = mybytemap( &my_bmap ); = for( i = 0; i < sizeof (LONG); i++ ) { @@ -276,5 +322,4 @@ = } = } - fclose( fp_lock ); = } = @@ -289,5 +334,5 @@ = /* If we're not in daemon mode, run through once and quit. */ = if( !daemon_delay ) { - log_entry( "mthreads single pass for '%s'\n", hierarchy ); + log_entry( "mthreads single pass started.\n" ); = setbuf( stdout, Nullch ); = extra_expire = (expire_time != 0); @@ -332,5 +377,5 @@ = } = - log_entry( "mthreads daemon started for '%s'\n", hierarchy ); + log_entry( "mthreads daemon started.\n" ); = =#ifndef SERVER @@ -342,5 +387,13 @@ = alarm( TIMER_FIRST ); = for( ;; ) { + if( caught_interrupt ) { + wrap_it_up(); + /* NORETURN */ + } = pause(); /* let alarm go off */ + if( caught_interrupt ) { + wrap_it_up(); + /* NORETURN */ + } = alarm( 0 ); = @@ -387,11 +440,10 @@ ={ = /* Re-open our log file, if needed */ - if( !fp_log && !(fp_log = fopen( file_exp( "%X/mt.log" ), "a" )) ) { - exit( 1 ); - } - if( sig == SIGTERM ) { - log_entry( "interrupt %d\n", sig); - } else { - log_entry( "** interrupt %d **\n", sig); + if( fp_log || (fp_log = fopen( file_exp( "%X/mt.log" ), "a" )) ) { + if( sig == SIGTERM ) { + log_entry( "mthreads halted.\n", sig); + } else { + log_entry( "** interrupt %d **\n", sig); + } = } = if( !daemon_delay ) { @@ -398,6 +450,6 @@ = printf( "interrupt %d!\n", sig ); = } - /* Handle interrupt by just bugging out */ - wrap_it_up(); + /* Flag interrupt occurred -- main loop attempts an orderly retreat. */ + caught_interrupt = TRUE; =} = @@ -448,4 +500,8 @@ = } = while( 1 ) { + if( caught_interrupt ) { + wrap_it_up(); + /* NORETURN */ + } = if( get_server( line, sizeof line ) < 0 ) { = log_entry( "Server failed to send entire active file -- sleeping.\n" ); @@ -478,4 +534,8 @@ = exit( 1 ); = } + if( caught_interrupt ) { + wrap_it_up(); + /* NORETURN */ + } = if( extra_expire && log_verbosity ) { = log_entry( "Using enhanced expiration for this pass.\n" ); @@ -482,7 +542,6 @@ = } = - processed_groups = 0; - added_articles = 0; - expired_articles = 0; + processed_groups = added_groups = removed_groups = 0; + added_articles = expired_articles = 0; = = /* Loop through entire active file. */ @@ -544,9 +603,15 @@ = last2 = total.last; = first2 = total.first; + ch2 = 'y'; = } else { - total.last = last2 = first - 1; + total.last = last2 = last; = total.first = first2 = first; + if( add_new ) { + ch2 = (ch == '=' ? 'x' : ch); + added_groups++; + } else { + ch2 = (ch == '=' ? 'X' : toupper( ch )); + } = } - ch2 = (ch == 'x' ? 'n' : ch); = data_file_open++; /* (1 == empty, 2 == open) */ = break; @@ -593,15 +658,42 @@ = } = } + if( rebuild ) { + unlink( thread_name( line ) ); + } = update_successful = FALSE; - if( match_len && strnNE( line, hierarchy, match_len ) ) { - dont_read_data( data_file_open ); /* skip non-matches */ - } else if( ch == 'x' ) { - if( !daemon_delay ) { /* skip 'x'ed groups */ + if( hierarchy_list ) { + action = ngmatch( hierarchy_list, line ); + } else { + action = NG_DEFAULT; + } + switch( action ) { + case NG_DEFAULT: + if( ch2 < 'a' ) { + action = NG_SKIP; + } else { + action = NG_MATCH; + } + break; + case NG_MATCH: /* add if unthreaded */ + if( ch2 < 'a' ) { + last2 = first2 - 1; + added_groups++; + } + break; + case NG_SKIP: /* remove if threaded */ + if( ch2 >= 'a' && !debug ) { + unlink( thread_name( line ) ); + removed_groups++; + } + break; + } + if( caught_interrupt || (debug && action != NG_MATCH) ) { + dont_read_data( data_file_open ); /* skip silently */ + } else if( ch == 'x' || ch == '=' ) { + if( !daemon_delay ) { /* skip 'x'ed groups */ = putchar( 'x' ); = } - dont_read_data( data_file_open ); - if( ch2 == 'X' ) { - ch = ch2; - } else if( ch2 != 'x' ) { + ch = (action == NG_SKIP ? 'X' : 'x'); + if( (ch2 >= 'a' && ch2 != 'x') || force_flag ) { = /* Remove thread file if group is newly 'x'ed out */ = unlink( thread_name( line ) ); @@ -608,21 +700,22 @@ = } = update_successful = TRUE; - } else if( ch2 < 'a' ) { - /* This group is marked 'Y', 'M', 'N', or '=' in active2. - ** Don't process it. - */ + dont_read_data( data_file_open ); + } else if( action == NG_SKIP ) { /* skip excluded groups */ = if( !daemon_delay ) { = putchar( 'X' ); = } - dont_read_data( data_file_open ); - if( ch2 != '=' ) { - if( ch != '=' ) { - ch = toupper( ch ); - } else { - ch = ch2; - } + ch = toupper( ch ); + if( force_flag ) { + unlink( thread_name( line ) ); = } = update_successful = TRUE; - } else if( !force_flag && !extra_expire + dont_read_data( data_file_open ); + } else if( no_processing ) { + if( !daemon_delay ) { + putchar( ',' ); + } + ch2 = ch; + dont_read_data( data_file_open ); + } else if( !force_flag && !extra_expire && !rebuild = && first == first2 && last == last2 ) { = /* We're up-to-date here. Skip it. */ @@ -630,6 +723,6 @@ = putchar( '.' ); = } - dont_read_data( data_file_open ); = update_successful = TRUE; + dont_read_data( data_file_open ); = } else { = /* Looks like we need to process something. */ @@ -685,5 +778,8 @@ = grevious_error = FALSE; = process_articles( first, last ); - if( !added_count && !expired_count && last == last2 ) { + processed_groups++; + if( caught_interrupt ) { + processed_groups--; /* save nothing -- no update */ + } else if( !added_count && !expired_count && last == last2 ) { = (void) write_data( Nullch ); = if( !daemon_delay ) { @@ -706,5 +802,5 @@ = expired_articles += expired_count; = if( !daemon_delay ) { - putchar( '+' ); + putchar( '#' ); = } = update_successful = TRUE; @@ -720,15 +816,13 @@ = putchar( '!' ); = } - } - } - } - } + }/* if */ + }/* if */ + }/* if */ + }/* if */ = /* Finally, update the active2 entry for this newsgroup. */ = if( update_successful ) { - fprintf( fp_active3, "%s %06ld %06ld %c\n", - line, last, first, ch ); + fprintf( fp_active3, fmt_active2, line, last, first, ch ); = } else { - fprintf( fp_active3, "%s %06ld %06ld %c\n", - line, last2, first2, ch2 ); + fprintf( fp_active3, fmt_active2, line, last2, first2, ch2 ); = } = }/* for */ @@ -794,5 +888,167 @@ = fputs( line, stdout ); = } + if( added_groups ) { + sprintf( line, "Turned %d group%s on.\n", added_groups, + added_groups == 1 ? nullstr : "s" ); + log_entry( line ); + if( !daemon_delay ) { + fputs( line, stdout ); + } + } + if( removed_groups ) { + sprintf( line, "Turned %d group%s off.\n", removed_groups, + removed_groups == 1 ? nullstr : "s" ); + log_entry( line ); + if( !daemon_delay ) { + fputs( line, stdout ); + } + } = extra_expire = FALSE; + rebuild = FALSE; +} + +/* +** ngmatch - newsgroup name matching +** +** returns NG_MATCH for a positive patch, NG_SKIP for a negative match, +** and NG_DEFAULT if the group doesn't match at all. +** +** "all" in a pattern is a wildcard that matches exactly one word; +** it does not cross "." (NGDELIM) delimiters. +** +** This matching code was borrowed from C news. +*/ + +#define ALL "all" /* word wildcard */ + +#define NGNEG '!' +#define NGSEP ',' +#define NGDELIM '.' + +int +ngmatch( ngpat, grp ) +char *ngpat, *grp; +{ + register char *patp; /* point at current pattern */ + register char *patcomma; + register int depth; + register int faildeepest = 0, hitdeepest = 0; /* in case no match */ + register bool negation; + + for( patp = ngpat; patp != Nullch; patp = patcomma ) { + negation = FALSE; + patcomma = index( patp, NGSEP ); + if( patcomma != Nullch ) { + *patcomma = '\0'; /* will be restored below */ + } + if( *patp == NGNEG ) { + ++patp; + negation = TRUE; + } + depth = onepatmatch( patp, grp ); /* try 1 pattern, 1 group */ + if( patcomma != Nullch ) { + *patcomma++ = NGSEP; /* point after the comma */ + } + if( depth == 0 ) { /* mis-match */ + ; /* ignore it */ + } else if( negation ) { + /* record depth of deepest negated matched word */ + if( depth > faildeepest ) { + faildeepest = depth; + } + } else { + /* record depth of deepest plain matched word */ + if( depth > hitdeepest ) { + hitdeepest = depth; + } + } + } + if( hitdeepest > faildeepest ) { + return NG_MATCH; + } else if( faildeepest ) { + return NG_SKIP; + } else { + return NG_DEFAULT; + } +} + +/* +** Match a pattern against a group by looking at each word of pattern in turn. +** +** On a match, return the depth (roughly, ordinal number * k) of the rightmost +** word that matches. If group runs out first, the match fails; if pattern +** runs out first, it succeeds. On a failure, return zero. +*/ +int +onepatmatch( patp, grp ) +char *patp, *grp; +{ + register char *rpatwd; /* used by word match (inner loop) */ + register char *patdot, *grdot; /* point at dots after words */ + register char *patwd, *grwd; /* point at current words */ + register int depth = 0; + + for( patwd = patp, grwd = grp; + patwd != Nullch && grwd != Nullch; + patwd = patdot, grwd = grdot + ) { + register bool match = FALSE; + register int incr = 20; + + /* null-terminate words */ + patdot = index(patwd, NGDELIM); + if( patdot != Nullch ) { + *patdot = '\0'; /* will be restored below */ + } + grdot = index( grwd, NGDELIM ); + if( grdot != Nullch ) { + *grdot = '\0'; /* will be restored below */ + } + /* + * Match one word of pattern with one word of group. + * A pattern word of "all" matches any group word, + * but isn't worth as much. + */ +#ifdef FAST_STRCMP + match = STREQ( patwd, grwd ); + if( !match && STREQ( patwd, ALL ) ) { + match = TRUE; + --incr; + } +#else + for( rpatwd = patwd; *rpatwd == *grwd++; ) { + if( *rpatwd++ == '\0' ) { + match = TRUE; /* literal match */ + break; + } + } + if( !match ) { + /* ugly special case match for "all" */ + rpatwd = patwd; + if( *rpatwd++ == 'a' && *rpatwd++ == 'l' + && *rpatwd++ == 'l' && *rpatwd == '\0' ) { + match = TRUE; + --incr; + } + } +#endif /* FAST_STRCMP */ + + if( patdot != Nullch ) { + *patdot++ = NGDELIM; /* point after the dot */ + } + if( grdot != Nullch ) { + *grdot++ = NGDELIM; + } + if( !match ) { + depth = 0; /* words differed - mismatch */ + break; + } + depth += incr; + } + /* if group name ran out before pattern, then match fails */ + if( grwd == Nullch && patwd != Nullch ) { + depth = 0; + } + return depth; =} = Index: mthreads.h @@ -1,5 +1,8 @@ -/* $Header: mthreads.h,v 4.3.3.1 90/06/20 22:55:27 davison Trn $ +/* $Header: mthreads.h,v 4.3.3.2 90/08/20 16:44:29 davison Trn $ =** =** $Log: mthreads.h,v $ +** Revision 4.3.3.2 90/08/20 16:44:29 davison +** New entries for new command-line interface. +** =** Revision 4.3.3.1 90/06/20 22:55:27 davison =** Initial Trn Release @@ -18,4 +21,5 @@ =EXT int expired_articles, expired_count; =EXT bool extra_expire INIT(FALSE); +EXT bool caught_interrupt INIT(FALSE); = =EXT char *strings INIT(0); @@ -42,4 +46,6 @@ =}; =#endif + +int ngmatch(), onepatmatch(); = =void log_entry(), log_error(); Index: newsnews.SH @@ -24,5 +24,5 @@ =will again be displayed, just once for each person. = -Wayne Davison davison%drivax@uunet.uu.net +Wayne Davison davison@dri.com =!GROK!THIS! =$eunicefix newsnews Index: ng.c @@ -1,5 +1,8 @@ -/* $Header: ng.c,v 4.3.3.1 90/07/21 20:27:17 davison Trn $ +/* $Header: ng.c,v 4.3.3.2 90/08/20 16:03:45 davison Trn $ = * = * $Log: ng.c,v $ + * Revision 4.3.3.2 90/08/20 16:03:45 davison + * Fixed bug in backpage code. + * = * Revision 4.3.3.1 90/07/21 20:27:17 davison = * Initial Trn Release @@ -1450,6 +1453,7 @@ = target = topline - (LINES - 2); = artline = topline; - while (artline >= 0 && artline > target && vrdary(artline-1) >= 0) + if (artline >= 0) do { = artline--; + } while(artline >= 0 && artline > target && vrdary(artline-1) >= 0); = topline = artline; = if (artline < 0) Index: ngstuff.c @@ -1,5 +1,8 @@ -/* $Header: ngstuff.c,v 4.3.3.1 90/07/21 20:29:12 davison Trn $ +/* $Header: ngstuff.c,v 4.3.3.2 90/08/20 18:29:08 davison Trn $ = * = * $Log: ngstuff.c,v $ + * Revision 4.3.3.2 90/08/20 18:29:08 davison + * Expanded path arrays for consistancy. + * = * Revision 4.3.3.1 90/07/21 20:29:12 davison = * Initial Trn Release @@ -54,5 +57,5 @@ = bool interactive = (buf[1] == FINISHCMD); = bool docd; - char whereiam[256]; + char whereiam[512]; = = if (!finish_command(interactive)) /* get remainder of command */ @@ -115,5 +118,5 @@ = else { = bool docd = (instr(buf,"-d") != Nullch); - char whereami[256]; + char whereami[512]; = = if (docd) Index: rcln.c @@ -1,5 +1,8 @@ -/* $Header: rcln.c,v 4.3.3.1 90/06/20 22:39:19 davison Trn $ +/* $Header: rcln.c,v 4.3.3.2 90/08/20 16:46:05 davison Trn $ = * = * $Log: rcln.c,v $ + * Revision 4.3.3.2 90/08/20 16:46:05 davison + * Removed extraneous xref boundary check. + * = * Revision 4.3.3.1 90/06/20 22:39:19 davison = * Initial Trn Release @@ -84,5 +87,5 @@ = set_toread(ngnum); /* the list due to expires if we */ = /* have not yet. */ -#ifdef DEBUGGING +#if defined(DEBUGGING) && !defined(USETHREADS) = if (artnum > ngmax[ngnum] + 10 /* allow for incoming articles */ = ) { @@ -332,5 +335,5 @@ = ART_NUM newmax; = -#ifdef DEBUGGING +#if defined(DEBUGGING) && !defined(USETHREADS) = ngmax[ngnum] = ngsize; /* for checking out-of-range Xrefs */ =#endif Index: rcln.h @@ -1,5 +1,8 @@ -/* $Header: rcln.h,v 4.3 85/05/01 11:45:52 lwall Exp $ +/* $Header: rcln.h,v 4.3.3.1 90/08/20 16:47:22 davison Trn $ = * = * $Log: rcln.h,v $ + * Revision 4.3.3.1 90/08/20 16:47:22 davison + * Removed ngmax array. + * = * Revision 4.3 85/05/01 11:45:52 lwall = * Baseline for release with 4.3bsd. @@ -7,5 +10,5 @@ = */ = -#ifdef DEBUGGING +#if defined(DEBUGGING) && !defined(USETHREADS) =EXT ART_NUM ngmax[MAXRCLINE]; =#endif Index: rcstuff.c @@ -1,5 +1,8 @@ -/* $Header: rcstuff.c,v 4.3.3.1 90/06/20 22:39:28 davison Trn $ +/* $Header: rcstuff.c,v 4.3.3.2 90/08/20 16:47:44 davison Trn $ = * = * $Log: rcstuff.c,v $ + * Revision 4.3.3.2 90/08/20 16:47:44 davison + * Removed ngmax array. + * = * Revision 4.3.3.1 90/06/20 22:39:28 davison = * Initial Trn Release @@ -479,5 +482,5 @@ = ACT_POS tmpsoftptr; = register NG_NUM i; -#ifdef DEBUGGING +#if defined(DEBUGGING) && !defined(USETHREADS) = ART_NUM tmpngmax; =#endif @@ -502,5 +505,5 @@ = tmprcnums = rcnums[ngx]; = tmpsoftptr = softptr[ngx]; -#ifdef DEBUGGING +#if defined(DEBUGGING) && !defined(USETHREADS) = tmpngmax = ngmax[ngx]; =#endif @@ -514,5 +517,5 @@ = rcnums[i-1] = rcnums[i]; = softptr[i-1] = softptr[i]; -#ifdef DEBUGGING +#if defined(DEBUGGING) && !defined(USETHREADS) = ngmax[i-1] = ngmax[i]; =#endif @@ -526,5 +529,5 @@ = rcnums[nextrcline-1] = tmprcnums; = softptr[nextrcline-1] = tmpsoftptr; -#ifdef DEBUGGING +#if defined(DEBUGGING) && !defined(USETHREADS) = ngmax[nextrcline-1] = tmpngmax; =#endif @@ -658,5 +661,5 @@ = tmprcnums = rcnums[nextrcline-1]; = tmpsoftptr = softptr[nextrcline-1]; -#ifdef DEBUGGING +#if defined(DEBUGGING) && !defined(USETHREADS) = tmpngmax = ngmax[nextrcline-1]; =#endif @@ -670,5 +673,5 @@ = rcnums[i+1] = rcnums[i]; = softptr[i+1] = softptr[i]; -#ifdef DEBUGGING +#if defined(DEBUGGING) && !defined(USETHREADS) = ngmax[i+1] = ngmax[i]; =#endif @@ -682,5 +685,5 @@ = rcnums[newng] = tmprcnums; = softptr[newng] = tmpsoftptr; -#ifdef DEBUGGING +#if defined(DEBUGGING) && !defined(USETHREADS) = ngmax[newng] = tmpngmax; =#endif Index: rn.c @@ -10,8 +10,11 @@ =*/ = -static char rnid[] = "@(#)$Header: rn.c,v 4.3.3.1 90/07/21 20:31:38 davison Trn $"; -static char patchlevel[] = "Trn v1.0 based on Rn patchlevel 47"; +static char rnid[] = "@(#)$Header: rn.c,v 4.3.3.2 90/08/20 16:48:19 davison Trn $"; +static char patchlevel[] = "Trn v1.0.1 based on Rn patchlevel 47"; = =/* $Log: rn.c,v $ + * Revision 4.3.3.2 90/08/20 16:48:19 davison + * Changed unthreaded group's default action, version #, email address. + * = * Revision 4.3.3.1 90/07/21 20:31:38 davison = * Initial Trn Release @@ -204,7 +207,6 @@ = reprompt_newsgroup: =#ifdef USETHREADS - dfltcmd = (use_threads && select_on - && (ART_NUM)toread[ng] >= select_on ? - ThreadedGroup ? "+ynq" : "=ynq" : "ynq"); + dfltcmd = (ThreadedGroup && select_on + && (ART_NUM)toread[ng] >= select_on ? "+ynq" : "ynq"); =#else = dfltcmd = "ynq"; @@ -537,5 +539,5 @@ = printf("\n%s",rnid); = printf("\n%s",patchlevel); - printf("\nSend bugs to davison@drivax.UUCP (davison%%drivax@uunet.uu.net)\n") FLUSH; + printf("\nSend bugs to davison@dri.com (...!uunet!drivax!davison)\n") FLUSH; = goto reask_newsgroup; = default: Index: rt-select.c @@ -1,5 +1,8 @@ -/* $Header: rt-select.c,v 4.3.3.1 90/07/24 22:04:07 davison Trn $ +/* $Header: rt-select.c,v 4.3.3.2 90/08/20 18:32:33 davison Trn $ =** =** $Log: rt-select.c,v $ +** Revision 4.3.3.2 90/08/20 18:32:33 davison +** Reset scan_all_roots while selecting. +** =** Revision 4.3.3.1 90/07/24 22:04:07 davison =** Initial Trn Release @@ -31,6 +34,6 @@ =static char *display_mode = select_order; =static ART_NUM article_count; -static int author_line, mask = 1; -static char first_two_chars[3] = { ' ', ' ', '\0' }; +static int author_line; +static char first_two_chars[3] = { ' ', ' ', '\0' }, mask = 1; = =#define MAX_SEL 64 @@ -73,4 +76,5 @@ = select_threads: = /* Setup for selecting articles to read or set unread */ + scan_all_roots = FALSE; = if( unread_selector ) { = page_char = '>'; Index: rthreads.c @@ -1,5 +1,8 @@ -/* $Header: rthreads.c,v 4.3.3.1 90/06/20 23:00:28 davison Trn $ +/* $Header: rthreads.c,v 4.3.3.2 90/08/20 16:58:14 davison Trn $ =** =** $Log: rthreads.c,v $ +** Revision 4.3.3.2 90/08/20 16:58:14 davison +** Added message for missing/bad db.init file. +** =** Revision 4.3.3.1 90/06/20 23:00:28 davison =** Initial Trn Release @@ -36,5 +39,9 @@ = filename = filexp( "%X/db.init" ); = if( (fp_in = fopen( filename, "r" )) != Nullfp ) { - if( fread( &mt_bmap, 1, sizeof (BMAP), fp_in ) == sizeof (BMAP) ) { + if( fread( &mt_bmap, 1, sizeof (BMAP), fp_in ) >= sizeof (BMAP)-1 ) { + if( mt_bmap.version != DB_VERSION ) { + printf( "\nThread database is the wrong version -- ignoring it.\n" ) FLUSH; + use_threads = FALSE; + } = mybytemap( &my_bmap ); = for( i = 0; i < sizeof (LONG); i++ ) { @@ -48,6 +55,11 @@ = } = } + } else { + goto no_db_init; = } = fclose( fp_in ); + } else { + no_db_init: + printf( "\ndb.init read failed -- assuming no byte-order translations.\n\n" ) FLUSH; = } =} Index: threads.c @@ -1,5 +1,8 @@ -/* $Header: threads.c,v 4.3.3.1 90/07/21 20:33:23 davison Trn $ +/* $Header: threads.c,v 4.3.3.2 90/08/20 16:49:38 davison Trn $ =** =** $Log: threads.c,v $ +** Revision 4.3.3.2 90/08/20 16:49:38 davison +** Enlarged path buffers to be more consistent. +** =** Revision 4.3.3.1 90/07/21 20:33:23 davison =** Initial Trn Release @@ -23,7 +26,7 @@ ={ = register char *ptr; - static char name_buff[256]; + static char name_buff[512]; =#ifndef LONG_THREAD_NAMES - char group_buff[256]; + char group_buff[512]; = = strcpy( group_buff, group); @@ -70,5 +73,5 @@ = } = *--mp = j; - while (u.b[j] != 0) { + while( u.b[j] != 0 && u.w ) { = u.w <<= 1; = } @@ -95,5 +98,5 @@ = } = *--mp = j; - while (u.b[j] != 0) { + while( u.b[j] != 0 && u.l ) { = u.l <<= 1; = } Index: threads.h @@ -1,5 +1,8 @@ -/* $Header: threads.h,v 4.3.3.1 90/06/20 22:56:18 davison Trn $ +/* $Header: threads.h,v 4.3.3.2 90/08/20 16:50:09 davison Trn $ =** =** $Log: threads.h,v $ +** Revision 4.3.3.2 90/08/20 16:50:09 davison +** Padded odd-boundaried arrays. Upgraded database version #. +** =** Revision 4.3.3.1 90/06/20 22:56:18 davison =** Initial Trn Release @@ -7,4 +10,6 @@ =*/ = +#define DB_VERSION 2 + =typedef char BYTE; =typedef short WORD; @@ -64,4 +69,5 @@ = WORD thread_cnt; = WORD subject_cnt; + WORD pad_hack; =} PACKED_ROOT; = @@ -85,4 +91,5 @@ = WORD author; = WORD domain; + WORD pad_hack; =} TOTAL; = @@ -91,3 +98,4 @@ = BYTE w[sizeof (WORD)]; = BYTE version; + BYTE pad_hack; =} BMAP; Index: trn.1 @@ -1,5 +1,8 @@ -''' $Header: trn.1,v 4.3.3.1 90/07/24 21:30:38 davison Trn $ +''' $Header: trn.1,v 4.3.3.2 90/08/20 16:50:51 davison Trn $ =''' =''' $Log: trn.1,v $ +''' Revision 4.3.3.2 90/08/20 16:50:51 davison +''' Changed email address. +''' =''' Revision 4.3.3.1 90/07/24 21:30:38 davison =''' Initial Trn Release @@ -2186,5 +2189,5 @@ =and is now under the direction of Stan Barber . =.br -Threaded version by Wayne Davison +Threaded version by Wayne Davison =.br =(Mail all bug reports for trn to Wayne.) Index: util.c @@ -1,5 +1,8 @@ -/* $Header: util.c,v 4.3.3.1 90/07/21 20:34:10 davison Trn $ +/* $Header: util.c,v 4.3.3.2 90/08/20 16:51:44 davison Trn $ = * = * $Log: util.c,v $ + * Revision 4.3.3.2 90/08/20 16:51:44 davison + * Fixed getcwd call to not overflow any buffers. + * = * Revision 4.3.3.1 90/07/21 20:34:10 davison = * Initial Trn Release @@ -262,5 +265,5 @@ = char * name; = extern char * getcwd(); - name = getcwd(np,1024); + name = getcwd(np,512); = return(name); =} SHAR_EOF fi exit 0 # End of shell archive