This is a patch that transforms trn 3.3 into trn 3.4. It is in unified diff format, so you either need a modern version of patch (any of the versions with 'u' or 'g' in them, such as the latest gnu version will work fine) or you need to make the unipatch filter program by typing: make unipatch in the trn source directory. To apply this patch, chdir to your trn 3.3 source directory and use one of the following commands: patch -p /tmp/c1$$ </dev/null 2>&1; then +if test -f /hp-ux -a -f /bin/ksh; then if (alias -x) >/dev/null 2>&1; then : already under /bin/ksh @@ -87,6 +83,4 @@ cd UU && rm -f * -cf_by='' -cf_time='' d_bsd='' d_eunice='' @@ -96,10 +90,5 @@ awk='' bash='' -bison='' cat='' -chgrp='' -chmod='' -chown='' -compress='' cpp='' csh='' @@ -107,7 +96,5 @@ echo='' egrep='' -emacs='' expr='' -flex='' gcc='' grep='' @@ -116,13 +103,6 @@ ksh='' less='' -line='' lint='' -ln='' -lp='' -lpr='' -ls='' mail='' -mailx='' -make='' metamail='' mhn='' @@ -131,42 +111,23 @@ mv='' nroff='' -perl='' pg='' -pmake='' -pr='' rm='' rmail='' sed='' sendmail='' -sh='' -shar='' -sleep='' smail='' sort='' -submit='' tail='' -tar='' -tbl='' test='' -touch='' tr='' -troff='' uname='' uniq='' uuname='' vi='' -zcat='' +vspell='' hint='' myuname='' -Author='' -Date='' -Header='' Id='' -Locker='' Log='' -RCSfile='' -Revision='' -Source='' -State='' active='' acttimes='' @@ -174,4 +135,5 @@ myactive='' bin='' +binexp='' installbin='' cc='' @@ -181,4 +143,6 @@ lkflags='' optimize='' +cf_by='' +cf_time='' contains='' cppminus='' @@ -210,6 +174,4 @@ d_normsig='' jobslib='' -d_hvfork='' -d_novfork='' d_novoid='' void='' @@ -220,5 +182,5 @@ d_sighold='' d_sizet='' -d_strcasecmp='' +d_strccmp='' d_strchr='' d_strftime='' @@ -230,4 +192,5 @@ ndirc='' ndiro='' +d_vfork='' d_voidsig='' signal_t='' @@ -267,6 +230,8 @@ mailer='' mailfile='' +installmansrc='' manext='' mansrc='' +mansrcexp='' mboxchar='' c='' @@ -282,4 +247,5 @@ orgname='' package='' +spackage='' pager='' phost='' @@ -288,4 +254,5 @@ installprivlib='' privlib='' +privlibexp='' rootid='' sharpbang='' @@ -308,7 +275,4 @@ usrinc='' d_whoami='' -i_sysfile='' -i_sysselct='' -large='' CONFIG='' @@ -344,6 +308,6 @@ EOS -: process the command line options -set X `for arg in "$@"; do echo $arg; done | awk ' +: produce awk script to parse command line options +cat >options.awk <<'EOF' BEGIN { optstr = "deEf:hrsSV"; # getopt-style specification @@ -364,5 +328,5 @@ str = $0; if (substr(str, 1, 1) != "-") { - printf("'"'%s'"'\n", str); + printf("'%s'\n", str); next; } @@ -377,5 +341,5 @@ if (arg[c]) { if (i < len) - printf("'"'%s'"'\n", substr(str, i + 1)); + printf("'%s'\n", substr(str, i + 1)); else expect = 1; @@ -388,8 +352,12 @@ print "?"; } -'` +EOF + +: process the command line options +set X `for arg in "$@"; do echo $arg; done | awk -f options.awk` eval "set $*" shift - +rm -f options.awk + : set up default values fastread='' @@ -422,5 +390,5 @@ -E) shift; alldone=exit;; -S) shift; extractsh=true;; - -V) echo "Configure generated by metaconfig 2.9dev PL20." >&2 + -V) echo "Configure generated by metaconfig 3.0 PL14." >&2 exit 0;; --) break;; @@ -474,5 +442,7 @@ : set package name package=trn -Package=Trn +first=`echo $package | sed -e 's/^\(.\).*/\1/'` +last=`echo $package | sed -e 's/^.\(.*\)/\1/'` +spackage=`echo $first | tr '[a-z]' '[A-Z]'`$last : Eunice requires " " instead of "", can you believe it @@ -510,11 +480,16 @@ attrlist="$attrlist __unix__ vax venix xenix z8000" +i_sysselct='' : change the next line if compiling for Xenix/286 on Xenix/386 xlibpth='/usr/lib/386 /lib/386' : general looking path for locating libraries -libpth='/usr/lib/large /lib /lib/large /usr/lib/small /lib/small' +libpth='/usr/lib/large /lib '$xlibpth' /lib/large' +libpth=$libpth' /usr/lib/small /lib/small' + +: no additional library wanted by default +libswanted='' -: no include file wanted by default +large='' inclwanted='/usr/include/NET-5000' @@ -681,4 +656,10 @@ ;; esac + case "\$ans\$xxxm\$nostick" in + '') + ans=! + $myecho + ;; + esac done case "\$ans" in @@ -687,4 +668,91 @@ EOSC +: create .config dir to save info across Configure sessions +test -d ../.config || mkdir ../.config +cat >../.config/README </dev/null || whoami) 2>&1` +if $contains "^$user\$" ../.config/instruct >/dev/null 2>&1; then + firsttime=false + echo " " + rp='Would you like to see the instructions?' + dflt=n + . ./myread + case "$ans" in + [yY]*) ;; + *) needman=false;; + esac +fi +if $needman; then + cat <>../.config/instruct;; + esac +fi + : see if sh knows # comments echo " " @@ -751,63 +819,4 @@ rm -f try -: general instructions -cat <&4 +echo "Checking compatibility between $echo and builtin echo (if any)..." >&4 $echo $n "hi there$c" >foo1 echo $n "hi there$c" >foo2 @@ -954,7 +963,7 @@ cat </dev/null 2>&1; then + eval "old`grep myuname= ../config.sh`" + fi if test "X$myuname" = "X$oldmyuname"; then dflt=y @@ -991,14 +999,14 @@ echo " " rp="I see a config.sh file. Do you want to use it to set the defaults?" - . ./UU/myread + . UU/myread case "$ans" in n*|N*) echo "OK, I'll ignore it."; mv config.sh config.sh.old;; *) echo "Fetching default answers from your old config.sh file..." >&4 tmp="$n" - ans="$c" + tans="$c" . ./config.sh cp config.sh UU n="$tmp" - c="$ans" + c="$tans" hint=previous ;; @@ -1021,5 +1029,7 @@ $test -f /dynix && dflt="$dflt dynix" $test -f /bin/mips && /bin/mips && dflt="$dflt mips" + $test -f /lib/libc && $test -f /lib/clib && dflt="$dflt domainos" $test -d /NextApps && test -f /usr/adm/software_version && dflt="$dflt next" + $test -f Policy.sh && dflt="Policy $dflt" if $test -f $uname; then set `$uname -a | tr '[A-Z]' '[a-z]'` @@ -1044,4 +1054,5 @@ irix) dflt="$dflt sgi" ;; convexos) dflt="$dflt convexos";; + domainos) dflt="$dflt domainos";; $2) if $test -f /usr/lib/sysadm/sysadm.menu; then if $test ! -f /etc/copyrights/01.sco; then @@ -1106,5 +1117,5 @@ echo "Fetching default answers from $config_sh..." >&4 tmp="$n" - ans="$c" + tans="$c" cd .. cp $config_sh config.sh 2>/dev/null @@ -1113,5 +1124,5 @@ cp ../config.sh . n="$tmp" - c="$ans" + c="$tans" hint=previous ;; @@ -1123,4 +1134,8 @@ done +: who configured the system +cf_time=`$date 2>&1` +cf_by=`( (logname) 2>/dev/null || whoami) 2>&1` + : set up shell script to do ~ expansion cat >filexp <getfile tilde='' @@ -1255,4 +1270,5 @@ skip='' none_ok='' +exp_file='' orig_rp="$rp" orig_dflt="$dflt" @@ -1270,4 +1286,7 @@ *n*) none_ok=true;; esac +case "$fn" in +*e*) exp_file=true;; +esac case "$fn" in @@ -1281,6 +1300,15 @@ Locate) what='File';; esac -cd .. + +case "$exp_file" in +'') + case "$d_portable" in + "$define") ;; + *) exp_file=true;; + esac + ;; +esac +cd .. while test "$type"; do redo='' @@ -1290,8 +1318,9 @@ true) rp="$rp (~name ok)";; esac - . ./UU/myread + . UU/myread case "$ans" in none) value='' + ansexp='' case "$none_ok" in true) type='';; @@ -1301,10 +1330,10 @@ case "$tilde" in '') value="$ans" - testvalue="$ans";; + ansexp="$ans";; *) - value=`./UU/filexp $ans` + value=`UU/filexp $ans` case $? in 0) - if test "X$ans" != "X$value"; then + if test "$ans" != "$value"; then echo "(That is $value on this particular system.)" fi @@ -1312,7 +1341,7 @@ *) value="$ans";; esac - testvalue="$value" - case "$d_portable" in - "$define") value="$ans";; + ansexp="$value" + case "$exp_file" in + '') value="$ans";; esac ;; @@ -1320,6 +1349,6 @@ case "$fullpath" in true) - case "$testvalue" in - /*) ;; + case "$ansexp" in + /*) value="$ansexp" ;; *) redo=true @@ -1346,7 +1375,7 @@ case "$type" in File) - if test -f "$testvalue"; then + if test -f "$ansexp"; then type='' - elif test -r "$testvalue" || (test -h "$testvalue") >/dev/null 2>&1 + elif test -r "$ansexp" || (test -h "$ansexp") >/dev/null 2>&1 then echo "($value is not a plain file, but that's ok.)" @@ -1355,5 +1384,5 @@ ;; Directory) - if test -d "$testvalue"; then + if test -d "$ansexp"; then type='' fi @@ -1383,5 +1412,5 @@ fi rp="$what $value doesn't exist. Use that name anyway?" - . ./UU/myread + . UU/myread dflt='' case "$ans" in @@ -1495,6 +1524,17 @@ echo " " $echo $n "Hmm... $c" +echo exit 1 >bsd +echo exit 1 >usg +echo exit 1 >v7 +echo exit 1 >osf1 +echo exit 1 >eunice +echo exit 1 >xenix +echo exit 1 >venix $cat /usr/include/signal.h /usr/include/sys/signal.h >foo 2>/dev/null -if test `echo abc | tr a-z A-Z` = Abc ; then +if test -f /osf_boot || $contains 'OSF/1' /usr/include/ctype.h >/dev/null 2>&1 +then + echo "Looks kind of like an OSF/1 system, but we'll see..." + echo exit 0 >osf1 +elif test `echo abc | tr a-z A-Z` = Abc ; then xxx=`./loc addbib blurfl $pth` if $test -f $xxx; then @@ -1502,5 +1542,4 @@ echo exit 0 >bsd echo exit 0 >usg - echo exit 1 >v7 else if $contains SIGTSTP foo >/dev/null 2>&1 ; then @@ -1509,7 +1548,5 @@ echo "Looks kind of like a USG system, but we'll see..." fi - echo exit 1 >bsd echo exit 0 >usg - echo exit 1 >v7 fi d_bsd="$undef" @@ -1518,11 +1555,7 @@ d_bsd="$define" echo exit 0 >bsd - echo exit 1 >usg - echo exit 1 >v7 else echo "Looks kind of like a Version 7 system, but we'll see..." d_bsd="$undef" - echo exit 1 >bsd - echo exit 1 >usg echo exit 0 >v7 fi @@ -1533,5 +1566,5 @@ something...hmm...yes...I've got it...there's a VMS nearby, or I'm a Blit. EOI - echo "exit 0" >eunice + echo exit 0 >eunice d_eunice="$define" : it so happens the Eunice I know will not run shell scripts in Unix format @@ -1541,15 +1574,13 @@ echo "Congratulations. You aren't running Eunice." d_eunice="$undef" - echo "exit 1" >eunice ;; esac if test -f /xenix; then echo "Actually, this looks more like a XENIX system..." - echo "exit 0" >xenix + echo exit 0 >xenix d_xenix="$define" else echo " " echo "It's not Xenix..." - echo "exit 1" >xenix d_xenix="$undef" fi @@ -1558,5 +1589,5 @@ if test -f /venix; then echo "Actually, this looks more like a VENIX system..." - echo "exit 0" >venix + echo exit 0 >venix else echo " " @@ -1566,8 +1597,7 @@ echo "Nor is it Venix..." fi - echo "exit 1" >venix fi -chmod +x bsd usg v7 eunice venix -$eunicefix bsd usg v7 eunice venix +chmod +x bsd usg v7 osf1 eunice xenix venix +$eunicefix bsd usg v7 osf1 eunice xenix venix $rm -f foo @@ -1647,5 +1677,12 @@ echo " " case "$sysman" in -'') sysman=`./loc . /local/man/man1 /usr/man/man1 /usr/man/man1 /usr/man/mann /usr/man/manl /usr/man/local/man1 /usr/man/u_man/man1 /usr/share/man/man1 /usr/catman/u_man/man1 /usr/man/l_man/man1 /usr/local/man/u_man/man1 /usr/local/man/l_man/man1 /usr/man/man.L1 /usr/man/man.L` +'') + syspath='/usr/man/man1 /usr/man/man1 /usr/man/mann' + syspath="$syspath /usr/man/manl /usr/man/local/man1" + syspath="$syspath /usr/man/u_man/man1 /usr/share/man/man1" + syspath="$syspath /usr/catman/u_man/man1 /usr/man/l_man/man1" + syspath="$syspath /usr/local/man/u_man/man1 /usr/local/man/l_man/man1" + syspath="$syspath /usr/man/man.L /local/man/man1" + sysman=`./loc . $syspath` ;; esac @@ -1825,7 +1862,7 @@ . ./myread case "$ans" in -none) ans=' '; +none) libs=' ';; +*) libs="$ans";; esac -libs="$ans" usenm=true @@ -1887,8 +1924,10 @@ ;; esac +xxx=normal case "$libc" in unknown) set /usr/ccs/lib/libc.so $test -r $1 || set /usr/lib/libc.so + $test -r $1 || set /usr/shlib/libc.so $test -r $1 || set /usr/lib/libc.so.[0-9]* $test -r $1 || set /lib/libsys_s.a @@ -1899,5 +1938,4 @@ ;; esac -apollo='false' if $test -r "$1"; then echo "Your (shared) C library seems to be in $1." @@ -1905,4 +1943,5 @@ elif $test -r /lib/libc && $test -r /lib/clib; then echo "Your C library seems to be in both /lib/clib and /lib/libc." + xxx=apollo libc='/lib/clib /lib/libc' if $test -r /lib/syslib; then @@ -1910,5 +1949,4 @@ libc="$libc /lib/syslib" fi - apollo='true' elif $test -r "$libc" || (test -h "$libc") >/dev/null 2>&1; then echo "Your C library seems to be in $libc, as you said before." @@ -1920,28 +1958,27 @@ echo "Your C library seems to be in $libc. You're normal." else - if ans=`./loc libc.a blurfl/dyick $libpth`; $test -r "$ans"; then + if tans=`./loc libc.a blurfl/dyick $libpth`; $test -r "$tans"; then : - elif ans=`./loc libc blurfl/dyick $libpth`; $test -r "$ans"; then + elif tans=`./loc libc blurfl/dyick $libpth`; $test -r "$tans"; then libnames="$libnames "`./loc clib blurfl/dyick $libpth` - elif ans=`./loc clib blurfl/dyick $libpth`; $test -r "$ans"; then + elif tans=`./loc clib blurfl/dyick $libpth`; $test -r "$tans"; then : - elif ans=`./loc Slibc.a blurfl/dyick $xlibpth`; $test -r "$ans"; then + elif tans=`./loc Slibc.a blurfl/dyick $xlibpth`; $test -r "$tans"; then : - elif ans=`./loc Mlibc.a blurfl/dyick $xlibpth`; $test -r "$ans"; then + elif tans=`./loc Mlibc.a blurfl/dyick $xlibpth`; $test -r "$tans"; then : else - ans=`./loc Llibc.a blurfl/dyick $xlibpth` + tans=`./loc Llibc.a blurfl/dyick $xlibpth` fi - if $test -r "$ans"; then - echo "Your C library seems to be in $ans, of all places." - libc=$ans + if $test -r "$tans"; then + echo "Your C library seems to be in $tans, of all places." + libc=$tans else libc='blurfl' fi fi -if $test "$apollo" = 'false'; then - if $test -r "$libc" || (test -h "$libc") >/dev/null 2>&1; then - dflt="$libc" - cat </dev/null 2>&1; then + dflt="$libc" + cat < libpath - cat >&4 < libpath + cat >&4 < t.c; - if $cc $ccflags -o t t.c $libs >/dev/null 2>&1; + if $cc $ccflags -o t t.c $ldflags $libs >/dev/null 2>&1; then tval=true; else tval=false; @@ -2519,8 +2559,8 @@ : where do we get termlib routines from echo " " -ans=`./loc libcurses.a x $libpth` -case "$ans" in +xxx=`./loc libcurses.a x $libpth` +case "$xxx" in /*) - ar t $ans >grimble + ar t $xxx >grimble if $contains tputs.o grimble >/dev/null 2>&1; then termlib='-lcurses' @@ -2528,13 +2568,13 @@ echo "Terminfo library found." >&4 else - ans=x + xxx=x fi rm -f grimble ;; esac -case "$ans" in +case "$xxx" in x) - ans=`./loc libtermlib.a x $libpth` - case "$ans" in + xxx=`./loc libtermlib.a x $libpth` + case "$xxx" in /usr/lib*|/lib*) termlib='-ltermlib' @@ -2543,11 +2583,11 @@ ;; /*) - termlib="$ans" + termlib="$xxx" d_havetlib="$define" echo "Termlib library found." >&4 ;; *) - ans=`./loc libtermcap.a x $libpth` - case "$ans" in + xxx=`./loc libtermcap.a x $libpth` + case "$xxx" in /usr/lib*|/lib*) termlib='-ltermcap' @@ -2556,5 +2596,5 @@ ;; /*) - termlib="$ans" + termlib="$xxx" d_havetlib="$define" echo "Termcap library found." >&4 @@ -2598,5 +2638,5 @@ cat <testcpp.out 2>&1; \ - $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then - cppstdin="$wrapper" - cppminus='' - echo "Eureka!" elif echo 'No such luck, maybe "'$cpp'" will work...'; \ $cpp testcpp.out 2>&1; \ @@ -2728,4 +2732,10 @@ cppstdin="$cc -P" cppminus='-'; +elif echo 'Uh-uh. Time to get fancy. Trying a wrapper...'; \ + $wrapper testcpp.out 2>&1; \ + $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then + cppstdin="$wrapper" + cppminus='' + echo "Eureka!" else dflt='' @@ -2741,4 +2751,8 @@ fi fi +case "$cppstdin" in +"$wrapper") ;; +*) $rm -f $wrapper;; +esac $rm -f testcpp.c testcpp.out @@ -2858,5 +2872,5 @@ $cat <&4 + xxx=y + while $test "$xxx" = 'y'; do + ./blurfl 1>&4 dflt=n rp='Would you like to see that again?' . ./myread + case "$ans" in + [yY]*) xxx="y";; + *) xxx="n";; + esac done - dflt=y - rp="Do you have buffering (printed all at once)?" - . ./myread - case "$ans" in - n*) val="$define";; - *) val="$undef";; - esac - ;; + dflt=y + rp="Do you have buffering (printed all at once)?" + . ./myread + case "$ans" in + n*) val="$define";; + *) val="$undef";; + esac + ;; *) case "$d_nolnbuf" in @@ -3006,20 +3024,4 @@ eval $setvar -: see if there is a vfork -echo " " -if set vfork val -f d_hvfork; eval $csym; $val; then - echo "vfork() found." >&4 - val="$undef" -else - echo "No vfork() found--will use fork() instead." >&4 - val="$define" -fi -set d_novfork -eval $setvar -case "$d_novfork" in -"$define") d_hvfork="$undef";; -*) d_hvfork="$define";; -esac - : check for void type echo " " @@ -3061,5 +3063,5 @@ : see if strcasecmp exists -set strcasecmp d_strcasecmp +set strcasecmp d_strccmp eval $inlibc @@ -3068,14 +3070,14 @@ strings=`./findhdr string.h` if $test "$strings" && $test -r "$strings"; then - echo "Using instead of ." >&4 - val="$define" + echo "Using instead of ." >&4 + val="$define" else - val="$undef" - strings=`./findhdr strings.h` - if $test "$strings" && $test -r "$strings"; then - echo "Using instead of ." >&4 - else - echo "No string header found -- You'll surely have problems." >&4 - fi + val="$undef" + strings=`./findhdr strings.h` + if $test "$strings" && $test -r "$strings"; then + echo "Using instead of ." >&4 + else + echo "No string header found -- You'll surely have problems." >&4 + fi fi set i_string @@ -3089,24 +3091,24 @@ echo " " if set index val -f; eval $csym; $val; then - if set strchr val -f d_strchr; eval $csym; $val; then - if $contains strchr "$strings" >/dev/null 2>&1 ; then - val="$define" - echo "strchr() found." >&4 + if set strchr val -f d_strchr; eval $csym; $val; then + if $contains strchr "$strings" >/dev/null 2>&1 ; then + val="$define" + echo "strchr() found." >&4 + else + val="$undef" + echo "index() found." >&4 + fi else - val="$undef" - echo "index() found." >&4 + val="$undef" + echo "index() found." >&4 fi - else - val="$undef" - echo "index() found." >&4 - fi else - if set strchr val -f d_strchr; eval $csym; $val; then - val="$define" - echo "strchr() found." >&4 - else - echo "No index() or strchr() found!" >&4 - val="$undef" - fi + if set strchr val -f d_strchr; eval $csym; $val; then + val="$define" + echo "strchr() found." >&4 + else + echo "No index() or strchr() found!" >&4 + val="$undef" + fi fi set d_strchr @@ -3128,5 +3130,5 @@ esac $cat <&4 - $echo " " >&4 + echo "Here is your distributions file:" >&4 + echo " " >&4 $cat >&4 $newslibexp/distributions - $echo " " >&4 + echo " " >&4 fi -$echo "Use 'none' for any distributions you don't have." -$echo " " +echo "Use 'none' for any distributions you don't have." +echo " " case "$locdist" in '') dflt="none";; @@ -3340,4 +3352,5 @@ : determine default editor +echo " " case "$defeditor" in '') @@ -3350,5 +3363,4 @@ ;; esac -$echo " " fn=f/ rp="What is the default editor on your system?" @@ -3376,7 +3388,7 @@ fi privlib="$ans" - +privlibexp="$ansexp" case "$installprivlib" in -'') dflt=`echo $privlib | sed 's#^/afs/#/afs/.#'` ;; +'') dflt=`echo $privlibexp | sed 's#^/afs/#/afs/.#'` ;; *) dflt="$installprivlib" ;; esac @@ -3387,4 +3399,5 @@ EOM +fn=de~ rp='What directory name should be used for the install?' . ./getfile @@ -3397,23 +3410,90 @@ esac -: check for ispell spelling checker +: determine where manual pages go +$cat <&4 -cf_time=`$date 2>&1` -cf_by=`( (logname) 2>/dev/null || whoami) 2>&1` $spitshell <config.sh $startsh @@ -4037,6 +4108,4 @@ # Target system: $myuname -cf_by='$cf_by' -cf_time='$cf_time' d_bsd='$d_bsd' d_eunice='$d_eunice' @@ -4046,10 +4115,5 @@ awk='$awk' bash='$bash' -bison='$bison' cat='$cat' -chgrp='$chgrp' -chmod='$chmod' -chown='$chown' -compress='$compress' cpp='$cpp' csh='$csh' @@ -4057,7 +4121,5 @@ echo='$echo' egrep='$egrep' -emacs='$emacs' expr='$expr' -flex='$flex' gcc='$gcc' grep='$grep' @@ -4066,13 +4128,6 @@ ksh='$ksh' less='$less' -line='$line' lint='$lint' -ln='$ln' -lp='$lp' -lpr='$lpr' -ls='$ls' mail='$mail' -mailx='$mailx' -make='$make' metamail='$metamail' mhn='$mhn' @@ -4081,42 +4136,23 @@ mv='$mv' nroff='$nroff' -perl='$perl' pg='$pg' -pmake='$pmake' -pr='$pr' rm='$rm' rmail='$rmail' sed='$sed' sendmail='$sendmail' -sh='$sh' -shar='$shar' -sleep='$sleep' smail='$smail' sort='$sort' -submit='$submit' tail='$tail' -tar='$tar' -tbl='$tbl' test='$test' -touch='$touch' tr='$tr' -troff='$troff' uname='$uname' uniq='$uniq' uuname='$uuname' vi='$vi' -zcat='$zcat' +vspell='$vspell' hint='$hint' myuname='$myuname' -Author='$Author' -Date='$Date' -Header='$Header' Id='$Id' -Locker='$Locker' Log='$Log' -RCSfile='$RCSfile' -Revision='$Revision' -Source='$Source' -State='$State' active='$active' acttimes='$acttimes' @@ -4124,4 +4160,5 @@ myactive='$myactive' bin='$bin' +binexp='$binexp' installbin='$installbin' cc='$cc' @@ -4131,4 +4168,6 @@ lkflags='$lkflags' optimize='$optimize' +cf_by='$cf_by' +cf_time='$cf_time' contains='$contains' cppminus='$cppminus' @@ -4160,6 +4199,4 @@ d_normsig='$d_normsig' jobslib='$jobslib' -d_hvfork='$d_hvfork' -d_novfork='$d_novfork' d_novoid='$d_novoid' void='$void' @@ -4170,5 +4207,5 @@ d_sighold='$d_sighold' d_sizet='$d_sizet' -d_strcasecmp='$d_strcasecmp' +d_strccmp='$d_strccmp' d_strchr='$d_strchr' d_strftime='$d_strftime' @@ -4180,4 +4217,5 @@ ndirc='$ndirc' ndiro='$ndiro' +d_vfork='$d_vfork' d_voidsig='$d_voidsig' signal_t='$signal_t' @@ -4217,6 +4255,8 @@ mailer='$mailer' mailfile='$mailfile' +installmansrc='$installmansrc' manext='$manext' mansrc='$mansrc' +mansrcexp='$mansrcexp' mboxchar='$mboxchar' c='$c' @@ -4232,4 +4272,5 @@ orgname='$orgname' package='$package' +spackage='$spackage' pager='$pager' phost='$phost' @@ -4238,4 +4279,5 @@ installprivlib='$installprivlib' privlib='$privlib' +privlibexp='$privlibexp' rootid='$rootid' sharpbang='$sharpbang' @@ -4276,11 +4318,13 @@ echo " " dflt='' + nostick=true echo "If you didn't make any mistakes, then just type a carriage return here." rp="If you need to edit config.sh, do it as a shell escape here:" . UU/myread + nostick='' case "$ans" in '') ;; *) : in case they cannot read - sh 1>&4 -c "$ans";; + sh 1>&4 -c "$ans";; esac ;; @@ -4292,5 +4336,5 @@ echo " " exec 1>&4 -. ./UU/extract +. UU/extract echo " " Index:INSTALL @@ -54,5 +54,10 @@ public directory (normally /usr/local/bin), and put a number of files into the private trn library (e.g. /usr/local/lib/trn). It - also tries to put the trn man page in a reasonable place. + also tries to put the trn man page in a reasonable place. One of + the installed scripts is "newsetup", which creates a .newsrc for a + user that doesn't have one. This script reads the subscriptions + file from your news library directory or sends a LIST SUBSCRIPTIONS + command to your server to get the default list of newsgroups for a + new user. If you don't like this, customize the script as desired. 7) Read the manual entry before running trn, or at least read the file @@ -91,3 +96,3 @@ unipatch $tweak + cp $tweak $tmpart + rm -f $tweak + ;; *) exit ;; esac $echo " " - $echo "OK, but you will have to edit the 'Newsgroups:' line in the message." + $echo "The Cc: line should have the poster's requested return address." ;; esac @@ -520,5 +527,5 @@ *) $echo Unable to mail to moderator $moderator - state=rescue + state=ask ;; esac @@ -538,5 +545,5 @@ : null else - state=rescue + state=ask fi cc=`$sed -n '1,/^[ ]*$/{/^[Cc][Cc]:[ ][^ ]/p;}' $tmpart| Index:Policy.sh.SH @@ -0,0 +1,160 @@ +case $CONFIG in +'') . ./config.sh ;; +esac +case "$0" in +*/*) cd `expr X$0 : 'X\(.*\)/'` ;; +esac +echo "Extracting Policy.sh (with variable substitutions)" +$spitshell <Policy.sh +$startsh +# +# This file was produced by running the Polich.sh.SH script, which +# gets its values from config.sh, which is generally produced by +# running Configure. +# +# \$Id: Policy.sh.SH,v 1.2 1993/09/15 18:07:06 schnoebe Exp $ + +# Configuration time: $cf_time +# Configured by: $cf_by +# Target system: $myuname + +# login name of the person who configured trn. not particularly interesting. +cf_by='$cf_by' +# time of configuration. Not particularly interesting. +cf_time='$cf_time' + +# install directives. + +# bin directories (string values) +# name of the final resting place +bin='$bin' +# how to get to the final resting place (thank you AFS) +installbin='$installbin' + +# private libraries +# name of the final resting place for those items in the library +# directory (string value) +privlib='$privlib' +# How toget to the library final resting place (thanks AFS) +installprivlib='$installprivlib' + +# interesting questions about man +# where to man page sources go? +mansrc='$mansrc' +# what extention do man pages get? +manext='$manext' + +# path to assorted programs that we might want to override. +# name of the default editor. (string value) +defeditor='$defeditor' +# prefered user shell (string value) +prefshell='$prefshell' +# favorite local pager (string value) +pager='$pager' +# where is inews? (string value) +inewsloc='$inewsloc' +# path to interactive speller or "none" (string value) +ispell_prg='$ispell_prg' +# spelling options for ispell_prg or "spell" if "none" (string value) +ispell_options='$ispell_options' + +# internal options +# ingore the ORGANIZATION environment variable? (define/undef) +d_ignoreorg='$d_ignoreorg' +# does the mailer understand FQDN addressing? (define/undef) +d_internet='$d_internet' +# Do you have a news admin? (define/undef) +d_newsadm='$d_newsadm' +# name of the news admin? (string value) +newsadmin='$newsadmin' +# read via NNTP? (define/undef) +d_nntp='$d_nntp' +# use the XDATA NNTP extension? (define/undef) +d_xdata='$d_xdata' +# path to a file containing a server name, or a hostname (string value) +servername='$servername' + +# distribution names (string values) +# local city +citydist='$citydist' +# "local" country +cntrydist='$cntrydist' +# "local" contentient +contdist='$contdist' +# site distribution +locdist='$locdist' +# organizational distribution +orgdist='$orgdist' +# state/province distribution name +statedist='$statedist' + +# Naming information. +# password file contains names (define/undef) +d_passnames='$d_passnames' +# berkeley style password entries (name first in GCOS) (define/undef) +d_berknames='$d_berknames' +# USG style password entries (account number first in GCOS) +# (define/undef) +d_usgnames='$d_usgnames' +# what type of name to use.. (bsd/usg/other) +nametype='$nametype' + +# How portable do we want to be? Determines if we do lookups now +# or wait until run time. (define/undef) +d_portable='$d_portable' + +# news library information +# where is the news library (usually /usr/lib/news) may contain ~ +newslib='$newslib' +# absolute path name to /usr/lib/news. +newslibexp='$newslibexp' +# where is the news spool (usually /{var,usr}/spool/news) +newsspool='$newsspool' +# active file stuff, like where is it, what is its name, etc +# path to the active file. (string value) +active='$active' +# do we have an active.times file? (define/undef) +d_acttimes='$d_acttimes' +# path to the active.times file. (string value) +acttimes='$acttimes' +# organizations name. path to file, or constant string +orgname='$orgname' + +# only one of the two following is needed +# command to find the posting hosts name (string value, optional) +phostcmd='$phostcmd' +# file containing posting hosts name or constant string +# (string value, optional) +# +phost='$phost' + +# what should we use? mthreads or overview +# use the mthreads format? (define/undef) +d_usemt='$d_usemt' +# where do we find the thread files? (string value) +threaddir='$threaddir' +# use the overview format? (define/undef) +d_useov='$d_useov' +# where do we find the .overview fils? (string value) +overviewdir='$overviewdir' + +# trn start up options +trn_init='$trn_init' +# start up with the selector? +trn_select='$trn_select' + +!GROK!THIS! +$eunicefix Policy.sh +if test -f hints/Policy.sh ; then + echo "Checking for changes." + if diff hints/Policy.sh Policy.sh >/dev/null ; then + echo "Policy.sh unchanged, retaining original" + rm Policy.sh + else + echo "installing new Policy.sh, old one left in Policy.sh.old" + (cd hints; mv Policy.sh Policy.sh.old) + mv Policy.sh hints + fi +else + mv Policy.sh hints +fi Index:README @@ -1,3 +1,3 @@ - Trn Kit, Version 3.0 + Trn Kit, Version 3.4 Copyright (c) 1993, Wayne Davison Index:Speller.SH @@ -131,5 +131,6 @@ if $test "$ispell " = "none "; then ($echo ---- misspelled words ------------------------------------- - spell $mine | fmt + #spell $ispell_options $mine | fmt + spell $ispell_options $mine | pr -t -4 $echo ----------------------------------------------------------- ) | $pager Index:addng.c @@ -143,5 +143,5 @@ printf("<%s\n", ser_line) FLUSH; #endif - if (ser_line[0] == '.') + if (NNTP_LIST_END(ser_line)) break; if ((s = index(ser_line, ' ')) != Nullch) Index:art.c @@ -89,5 +89,4 @@ char oldmode = mode; - interp(cmd_buf,(sizeof cmd_buf),getval("MIMESHOW",MIMESHOW)); fputs("Process MIME article? [yn]",stdout); fflush(stdout); @@ -111,4 +110,5 @@ termlib_reset(); resetty(); + interp(cmd_buf,(sizeof cmd_buf),getval("MIMESHOW",MIMESHOW)); code = doshell(SH,cmd_buf); noecho(); @@ -301,6 +301,11 @@ #endif #ifdef MIME_SUPPORT - else if (in_header == CONTENT_LINE && !isspace(*art_buf)) { - mime_article = nontext(art_buf+14); + else if (!isspace(*art_buf)) { + int nontext _((char *)); + int nonprint _((char *)); + if (in_header == CONTENT_LINE) + mime_article = mime_article || nontext(art_buf+14); + else if (in_header == CONTXFER_LINE) + mime_article = mime_article || nonprint(art_buf+27); } #endif @@ -1010,25 +1015,28 @@ #ifdef MIME_SUPPORT int -nontext(content_type) -char *content_type; +nontext(s) +char *s; { char *t; - if (content_type[0] == '\n') + if (*s == '\n') return 0; - while (content_type && isspace(*content_type)) - content_type++; - t = index(content_type, ';'); + while (isspace(*s)) + s++; + t = index(s, ';'); if (!t) - t = index(content_type, '\n'); + t = index(s, '\n'); if (t) *t-- = '\0'; - while (t && *t && t > content_type && isspace(*t)) - *t-- = '\0'; - if (notplain(content_type)) + while (t >= s && isspace(*t)) + t--; + *++t = '\0'; + if (notplain(s)) return 1; return 0; } +/* return true if this isn't "text" or "text/plain" */ + int notplain(s) @@ -1038,28 +1046,29 @@ if (!s) return 1; - while (*s && isspace(*s)) + while (isspace(*s)) s++; - for (t=s; *t; ++t) { - if (isupper(*t)) - *t = tolower(*t); - } - while (t > s && isspace(*--t)) ; - if (((t-s) == 3) && !strncmp(s, "text", 4)) + t = s + strlen(s) - 1; + while (t >= s && isspace(*t)) + t--; + *++t = '\0'; + if (t - s == 4 && !strncasecmp(s, "text", 4)) return 0; - if (strncmp(s, "text/plain", 10)) + if (strncasecmp(s, "text/plain", 10)) return 1; t = index(s, ';'); while (t) { t++; - while (*t && isspace(*t)) t++; - if (!strncmp(t, "charset", 7)) { + while (isspace(*t)) + t++; + if (!strncasecmp(t, "charset", 7)) { s = index(t, '='); if (s) { s++; - while (*s && isspace(*s)) s++; - if (!strncmp(s, "us-ascii", 8)) + while (isspace(*s)) + s++; + if (!strncasecmp(s, "us-ascii", 8)) return 0; } - return(1); + return 1; } t = index(t, ';'); @@ -1067,3 +1076,22 @@ return 0; /* no charset, was text/plain */ } + +/* return true if this isn't "7bit", "8bit", or "binary" */ + +int +nonprint(s) +char *s; +{ + while (isspace(*s)) + s++; + if (strncasecmp(s, "7bit", 4) == 0) + s += 4; + else if (strncasecmp(s, "8bit", 4) == 0) + s += 4; + else if (strncasecmp(s, "binary", 6) == 0) + s += 6; + else + return 1; + return !(*s == '\0' || isspace(*s) || *s == ';' || *s == '('); /*)*/ +} #endif Index:artsrch.c @@ -66,4 +66,6 @@ bool doread; /* search read articles? */ bool foldcase = TRUE; /* fold upper and lower case? */ + int ignorethru = 0; /* should we ignore the thru line? */ + ART_NUM srchfirst; @@ -92,5 +94,5 @@ } if (*s) { /* modifiers or commands? */ - for (s++; *s && index("KarchHf",*s); s++) { + for (s++; *s && index("KarcfhHIN",*s); s++) { if (*s == 'f') /* scan from line */ howmuch = ARTSCOPE_FROM; @@ -117,4 +119,8 @@ else if (*s == 'c') /* make search case sensitive */ foldcase = FALSE; + else if (*s == 'I') /* ignore the killfile thru line */ + ignorethru = 1; + else if (*s == 'N') /* override ignore if -k was used */ + ignorethru = -1; } } @@ -122,5 +128,9 @@ s++; if (*s) { +#ifdef OLD_RN_WAY if (*s == 'm' || *s == 'M') +#else + if (*s == 'm') +#endif doread = TRUE; if (*s == 'k') /* grandfather clause */ @@ -143,4 +153,5 @@ howmuch = ARTSCOPE_SUBJECT; /* just search subjects */ + srchhdr = Nullch; doread = (cmdchr == Ctl('p')); if (cmdchr == Ctl('n')) @@ -157,7 +168,7 @@ normal_return = SRCH_DONE; if (cmdchr == '+') - cmdlst = savestr("++"); + cmdlst = savestr("I:++"); else if (cmdchr == '.') - cmdlst = savestr("."); + cmdlst = savestr("I:."); else { if (cmdchr == ',') @@ -207,9 +218,15 @@ #ifdef KILLFILES if (saltaway) { - char saltbuf[LBUFLEN]; + char saltbuf[LBUFLEN], *f; s = saltbuf; - sprintf(s,"/%s/",pattern); - s += strlen(s); + f = pattern; + *s++ = '/'; + while (*f) { + if (*f == '/') + *s++ = '\\'; + *s++ = *f++; + } + *s++ = '/'; if (doread) *s++ = 'r'; @@ -246,7 +263,9 @@ normal_return = SRCH_DONE; } - srchfirst = (doread? absfirst : - (mode == 'k' && (howmuch > ARTSCOPE_FROM || lastart - last_cached > 25) - ? killfirst : firstart)); + if (ignorethru == 0 && kill_thru_kludge && cmdlst + && (*cmdlst == '+' || *cmdlst == '.')) + ignorethru = 1; + srchfirst = doread? absfirst + : (mode != 'k' || ignorethru > 0)? firstart : killfirst; if (backward) { if (cmdlst && art <= lastart) Index:bits.c @@ -234,5 +234,5 @@ for (priornum = absfirst-1, ap = article_ptr(absfirst);; ap++) { nntp_gets(ser_line, sizeof ser_line); - if (*ser_line == '.') + if (NNTP_LIST_END(ser_line)) break; num = atol(ser_line); Index:cache.c @@ -234,9 +234,28 @@ } if (!(ap->flags & AF_FROMTRUNCED)) { - if (instr(ap->from,phostname,FALSE)) { - if (instr(ap->from,loginName,TRUE)) + char *s = cmd_buf, *u, *h; + strcpy(s,ap->from); + if ((h=index(s,'<')) != Nullch) { /* grab the good part */ + s = h+1; + if ((h=index(s,'>')) != Nullch) + *h = '\0'; + } else if ((h=index(s,'(')) != Nullch) { + while (h-- != s && *h == ' ') + ; + h[1] = '\0'; /* or strip the comment */ + } + if ((h=index(s,'%'))!=Nullch || (h=index(s,'@'))!=Nullch) { + *h++ = '\0'; + u = s; + } else if ((u=rindex(s,'!')) != Nullch) { + *u++ = '\0'; + h = s; + } else + h = u = s; + if (strEQ(u,loginName)) { + if (instr(h,phostname,FALSE)) select_subthread(ap,AF_AUTOSELECT); else { -#ifdef SLOW_BUT_COMPLETE_POSTER_CHECKING +#ifdef REPLYTO_POSTER_CHECKING char *reply_buf = fetchlines(article_num(ap),REPLY_LINE); if (instr(reply_buf,loginName,TRUE)) @@ -259,5 +278,5 @@ bool_int remove_empties; { - register ARTICLE *next, *ap2; + register ARTICLE *next; if (ap->subj) { @@ -265,8 +284,13 @@ if ((next = ap->subj->articles) == ap) ap->subj->articles = ap->subj_next; - else if (next) { - while (next && (next = (ap2 = next)->subj_next) != ap) - ; - ap2->subj_next = next; + else { + register ARTICLE *ap2; + while (next) { + if ((ap2 = next->subj_next) == ap) { + next->subj_next = ap->subj_next; + break; + } + next = ap2; + } } } @@ -281,4 +305,5 @@ else sp->next->prev = sp->prev; + hashdelete(subj_hash, sp->str+4, strlen(sp->str+4)); free((char*)sp); ap->subj = Nullsubj; @@ -639,4 +664,5 @@ cache_all_arts() { + int old_last_cached = last_cached; if (!cached_all_in_range) last_cached = first_cached-1; @@ -647,6 +673,10 @@ setspin(SPIN_BACKGROUND); if (last_cached < lastart) { - if (!art_data(last_cached+1, lastart, TRUE, TRUE)) + if (ov_opened) + ov_data(last_cached+1, lastart, TRUE); + if (!art_data(last_cached+1, lastart, TRUE, TRUE)) { + last_cached = old_last_cached; return FALSE; + } cached_all_in_range = TRUE; } @@ -657,6 +687,8 @@ art_data(absfirst, first_cached-1, TRUE, TRUE); /* If we got interrupted, make a quick exit */ - if (first_cached > absfirst) + if (first_cached > absfirst) { + last_cached = old_last_cached; return FALSE; + } } /* We're all done threading the group, so if the current article is @@ -664,4 +696,7 @@ if (curr_artp && !(curr_artp->flags & AF_CACHED) && !input_pending()) pushchar('\f' | 0200); + /* A completely empty group needs a count & a sort */ + if (mode != 't' && !article_count && !selected_only) + thread_grow(); return TRUE; } Index:common.h @@ -85,5 +85,6 @@ #define PUSHSIZE 256 #define MAXFILENAME 512 -#define LONGKEY 15 /* longest keyword: currently "posting-version" */ +#define LONGKEY 25 /* longest keyword */ + /* (currently "Content-Transfer-Encoding") */ #define FINISHCMD 0177 @@ -582,5 +583,5 @@ #ifndef NEWSHEADER /* % */ # ifdef CONDSUB -# define NEWSHEADER "%(%[followup-to]=^$?:X-ORIGINAL-NEWSGROUPS: %n\n)Newsgroups: %(%F=^$?%C:%F)\nSubject: %(%S=^$?%\"\n\nSubject: \":Re: %S)\nSummary: \nExpires: \n%(%R=^$?:References: %R\n)Sender: \nFollowup-To: \n%(%{REPLYTO}=^$?:Reply-To: %{REPLYTO}\n)Distribution: %(%i=^$?%\"Distribution: \":%D)\nOrganization: %o\nKeywords: %[keywords]\nCc: \n\n" +# define NEWSHEADER "%(%[followup-to]=^$?:X-ORIGINAL-NEWSGROUPS: %n\n)Newsgroups: %(%F=^$?%C:%F)\nSubject: %(%S=^$?%\"\n\nSubject: \":Re: %S)\nSummary: \nExpires: \n%(%R=^$?:References: %R\n)Sender: \nFollowup-To: \n%(%{REPLYTO}=^$?:Reply-To: %{REPLYTO}\n)Distribution: %(%i=^$?%\"Distribution: \":%D)\nOrganization: %o\nKeywords: %[keywords]\nCc: %(%F=poster?%t:%(%F!=@?:%F))\n\n" # else # define NEWSHEADER "Newsgroups: %F\nSubject: Re: %S\nSummary: \nExpires: \nReferences: %R\nSender: \nFollowup-To: \nDistribution: %D\nOrganization: %o\nKeywords: %[keywords]\nCc: \n\n" @@ -747,4 +748,8 @@ #endif +#ifndef HAS_VFORK +# define vfork fork +#endif + /* *** end of the machine dependent stuff *** */ @@ -803,4 +808,5 @@ EXT bool dont_filter_control INIT(FALSE); /* -j */ +EXT bool kill_thru_kludge INIT(TRUE); /* -k */ EXT bool mbox_always INIT(FALSE); /* -M */ EXT bool norm_always INIT(FALSE); /* -N */ @@ -924,3 +930,4 @@ #define advise(str) fputs(str,stdout) +#define report_error(str) fputs(str,stderr) #define fatal_error(str) fputs(str,stderr), finalize(1) Index:config.h.SH @@ -6,5 +6,5 @@ esac echo "Extracting config.h (with variable substitutions)" -sed <config.h -e 's!^#undef!/\*#define!' +sed <config.h -e 's!^#undef\(.*\)/\*!/\*#define\1\*//\*!' /* * This file was produced by running the config.h.SH script, which @@ -16,5 +16,5 @@ * For a more permanent change edit config.sh and rerun config.h.SH. * - * \$Id: Config.h.U,v 2.8.1.2 91/10/11 10:07:56 ram Exp Locker: ram $ + * \$Id: Config_h.U,v 3.0.1.2 1993/08/24 12:13:20 ram Exp $ */ @@ -41,5 +41,5 @@ #$d_eunice VMS /**/ -/* HAS_GETPWENT +/* HAS_GETPWENT: * This symbol, if defined, indicates that the getpwent() routine * should be used instead of the getpw() routine. @@ -47,5 +47,5 @@ #$d_getpwent HAS_GETPWENT /**/ -/* HAS_TERMLIB +/* HAS_TERMLIB: * This symbol, when defined, indicates that termlib-style routines * are available. There is nothing to include. @@ -53,5 +53,11 @@ #$d_havetlib HAS_TERMLIB /**/ -/* HAS_MEMCMP +/* INTERNET: + * This symbol, if defined, indicates that there is a mailer available + * which supports internet-style addresses (user@site.domain). + */ +#$d_internet INTERNET /**/ + +/* HAS_MEMCMP: * This symbol, if defined, indicates that the memcmp routine is available * to compare blocks of memory. @@ -59,5 +65,5 @@ #$d_memcmp HAS_MEMCMP /**/ -/* HAS_MEMCPY +/* HAS_MEMCPY: * This symbol, if defined, indicates that the memcpy routine is available * to copy blocks of memory. @@ -65,5 +71,5 @@ #$d_memcpy HAS_MEMCPY /**/ -/* HAS_MEMSET +/* HAS_MEMSET: * This symbol, if defined, indicates that the memset routine is available * to set blocks of memory. @@ -71,5 +77,5 @@ #$d_memset HAS_MEMSET /**/ -/* NEWS_ADMIN +/* NEWS_ADMIN: * This symbol, if defined, contains the login name of the news * administrator. @@ -89,11 +95,5 @@ #$d_normsig NORMSIG /**/ -/* vfork: - * This symbol, if defined, remaps the vfork routine to fork if the - * vfork() routine isn't supported here. - */ -#$d_novfork vfork fork /**/ - -/* HAS_RDCHK +/* HAS_RDCHK: * This symbol, if defined, indicates that the rdchk routine is available * to find out if there is input pending on an IO channel. Generally @@ -102,5 +102,5 @@ #$d_rdchk HAS_RDCHK /**/ -/* HAS_RENAME +/* HAS_RENAME: * This symbol, if defined, indicates that the rename routine is available * to rename files. Otherwise you should do the unlink(), link(), unlink() @@ -122,10 +122,15 @@ /* HAS_STRCASECMP: - * This symbol, if defined, indicates that the strcasecmp routine is + * This symbol, if defined, indicates that the strcasecmp() routine is * available for case-insensitive string compares. */ -#$d_strcasecmp HAS_STRCASECMP /**/ +#$d_strccmp HAS_STRCASECMP /**/ -/* Signal_t +/* HAS_VFORK: + * This symbol, if defined, indicates that vfork() exists. + */ +#$d_vfork HAS_VFORK /**/ + +/* Signal_t: * This symbol's value is either "void" or "int", corresponding to the * appropriate return type of a signal handler. Thus, you can declare @@ -135,4 +140,9 @@ #define Signal_t $signal_t /* Signal handler's return type */ +/* DEFEDITOR: + * This symbol contains the full pathname of the default editor. + */ +#define DEFEDITOR "$defeditor" /**/ + /* I_DIRENT: * This symbol, if defined, indicates to the C program that it should @@ -147,5 +157,11 @@ #$i_stdlib I_STDLIB /**/ -/* I_SYS_DIR +/* I_STRING: + * This symbol, if defined, indicates to the C program that it should + * include (USG systems) instead of (BSD systems). + */ +#$i_string I_STRING /**/ + +/* I_SYS_DIR: * This symbol, if defined, indicates to the C program that it should * include . @@ -153,5 +169,5 @@ #$i_sysdir I_SYS_DIR /**/ -/* I_SYS_IOCTL +/* I_SYS_IOCTL: * This symbol, if defined, indicates that exists and should * be included. Otherwise, include or . @@ -159,5 +175,5 @@ #$i_sysioctl I_SYS_IOCTL /**/ -/* I_SYS_NDIR +/* I_SYS_NDIR: * This symbol, if defined, indicates to the C program that it should * include . @@ -189,5 +205,5 @@ * include . */ -#$i_unistd I_UNISTD /**/ +#$i_unistd I_UNISTD /**/ /* I_VFORK: @@ -210,4 +226,16 @@ #define MBOXCHAR '$mboxchar' /**/ +/* PASSNAMES: + * This symbol, if defined, indicates that full names are stored in + * the /etc/passwd file. + */ +/* BERKNAMES: + * This symbol, if defined, indicates that full names are stored in + * the /etc/passwd file in Berkeley format (name first thing, everything + * up to first comma, with & replaced by capitalized login id, yuck). + */ +#$d_passnames PASSNAMES /* (undef to take name from ~/.fullname) */ +#$d_berknames BERKNAMES /* (that is, ":name,stuff:") */ + /* ORGNAME: * This symbol contains either the organizaton name or the full pathname @@ -246,10 +274,10 @@ #$d_ftime HAS_FTIME /**/ -/* HAS_GETHOSTNAME +/* HAS_GETHOSTNAME: * This symbol, if defined, indicates that the C program may use the * gethostname() routine to derive the host name. See also HAS_UNAME * and PHOSTCMD. */ -/* HAS_UNAME +/* HAS_UNAME: * This symbol, if defined, indicates that the C program may use the * uname() routine to derive the host name. See also HAS_GETHOSTNAME @@ -267,5 +295,5 @@ #$d_phostcmd PHOSTCMD "$aphostcmd" /* How to get the host name */ -/* HAS_GETWD +/* HAS_GETWD: * This symbol, if defined, indicates that the getwd routine is * available to get the working directory. @@ -284,10 +312,4 @@ #$d_ignoreorg IGNOREORG /**/ -/* INTERNET: - * This symbol, if defined, indicates that there is a mailer available - * which supports internet-style addresses (user@site.domain). - */ -#$d_internet INTERNET /**/ - /* MIME_SUPPORT: * This symbol, if defined, indicates mime articles should be processed @@ -301,6 +323,6 @@ */ #$d_mime MIME_SUPPORT /**/ -#$d_mime MIMESHOW "$mimeshow" -#$d_mime MIMESTORE "$mimestore" +#$d_mime MIMESHOW "$mimeshow" /**/ +#$d_mime MIMESTORE "$mimestore" /**/ /* USE_NNTP: @@ -338,7 +360,8 @@ /* HAS_STRCHR: * This symbol is defined to indicate that the strchr()/strrchr() - * functions are available for string searching. + * functions are available for string searching. If not, try the + * index()/rindex() pair. */ -#$d_strchr HAS_STRCHR /**/ +#$d_strchr HAS_STRCHR /**/ /* HAS_STRFTIME: @@ -359,9 +382,4 @@ #$d_libndir I_NDIR /**/ -/* DEFEDITOR: - * This symbol contains the full pathname of the default editor. - */ -#define DEFEDITOR "$defeditor" /**/ - /* I_PTEM: * This symbol, if defined, indicates to the C program that it should @@ -370,15 +388,9 @@ #$i_ptem I_PTEM /**/ -/* I_STRING: - * This symbol, if defined, indicates to the C program that it should - * include (USG systems) instead of (BSD systems). - */ -#$i_string I_STRING /**/ - -/* I_TIME +/* I_TIME: * This symbol, if defined, indicates to the C program that it should * include . */ -/* I_SYS_TIME +/* I_SYS_TIME: * This symbol, if defined, indicates to the C program that it should * include . @@ -387,16 +399,4 @@ #$i_systime I_SYS_TIME /**/ -/* PASSNAMES: - * This symbol, if defined, indicates that full names are stored in - * the /etc/passwd file. - */ -/* BERKNAMES: - * This symbol, if defined, indicates that full names are stored in - * the /etc/passwd file in Berkeley format (name first thing, everything - * up to first comma, with & replaced by capitalized login id, yuck). - */ -#$d_passnames PASSNAMES /* (undef to take name from ~/.fullname) */ -#$d_berknames BERKNAMES /* (that is, ":name,stuff:") */ - /* NEWSLIB: * This symbol contains the name of the directory serving as the news @@ -451,9 +451,9 @@ #define SELECT_INIT $trn_select -#undef LONG_THREAD_NAMES /**/ +/*#define LONG_THREAD_NAMES *//**/ #define CANCEL "$inewsloc -h <%h" #define SPEED_OVER_MEM /* use more memory to run faster */ -/*#define ANCIENT_NEWS /* if your B news system is <= 2.10.1 */ +/*#define ANCIENT_NEWS *//* if your B news system is <= 2.10.1 */ #endif Index:dependencies @@ -752,4 +752,5 @@ Makefile: Makefile.SH config.sh ; /bin/sh Makefile.SH Pnews: Pnews.SH config.sh ; /bin/sh Pnews.SH +Policy.sh: Policy.sh.SH config.sh ; /bin/sh Policy.sh.SH Rnmail: Rnmail.SH config.sh ; /bin/sh Rnmail.SH Speller: Speller.SH config.sh ; /bin/sh Speller.SH Index:final.c @@ -52,4 +52,10 @@ #endif +#ifndef lint +#ifdef SIGEMT + sigignore(SIGEMT); /* Ignore EMT signals from old [t]rn's */ +#endif +#endif + #ifdef DEBUG /* sometimes we WANT a core dump */ Index:final.h @@ -36,3 +36,7 @@ void final_init _((void)); -void finalize _((int)); +void finalize _((int)) +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR >= 5) + __attribute__((noreturn)) +#endif + ; Index:getactive.c @@ -42,5 +42,6 @@ argv++; } - nntp_connect(); + if (!nntp_connect()) + finalize(1); sprintf(command,"LIST %s",action); nntp_command(command); @@ -61,5 +62,5 @@ while (nntp_gets(ser_line, sizeof ser_line) >= 0) { - if (ser_line[0] == '.') /* while there's another line */ + if (NNTP_LIST_END(ser_line)) /* while there's another line */ break; /* get it and write it to */ if (actfp != NULL) { /* the temporary active file */ @@ -81,5 +82,5 @@ sigrelse(SIGINT); #endif - nntp_close(); + nntp_close(TRUE); return 0; } @@ -89,5 +90,13 @@ int num; { - nntp_close(); + nntp_close(TRUE); exit(num); } + +char +nntp_handle_timeout(strict) +bool_int strict; +{ + fatal_error("\n503 Server timed out.\n"); + return NNTP_CLASS_FATAL; +} Index:hash.c @@ -37,9 +37,11 @@ } *aap; + if (size < 1) /* size < 1 is nonsense */ + size = 1; aap = (struct alignalloc*) safemalloc(sizeof *aap + (size-1)*sizeof (HASHENT*)); bzero((char*)aap, sizeof *aap + (size-1)*sizeof (HASHENT*)); tbl = &aap->ht; - tbl->ht_size = (size == 0? 1: size); /* size of 0 is nonsense */ + tbl->ht_size = size; tbl->ht_magic = HASHMAG; tbl->ht_cmp = (cmpfunc == NULL? default_cmp: cmpfunc); Index:hash.h @@ -29,8 +29,7 @@ #ifdef DOINIT -#define BADTBL(tbl) (((tbl)->ht_magic&BYTEMASK) != HASHMAG) +#define BADTBL(tbl) ((tbl)->ht_magic != HASHMAG) -#define HASHMAG 0257 -#define BYTEMASK 0377 +#define HASHMAG ((char)0257) #define HASHENT struct hashent Index:head.c @@ -206,5 +206,5 @@ return; #else - set_subj_line(ap,"Subject: ",15); + set_subj_line(ap,"",6); #endif } @@ -384,5 +384,5 @@ printf("<%s\n", ser_line) FLUSH; # endif - if (ser_line[0] == '.') + if (NNTP_LIST_END(ser_line)) break; if ((t = index(ser_line, '\r')) != Nullch) Index:head.h @@ -28,6 +28,7 @@ #define ANPA_LINE (ACAT_LINE+1) /* ANPA (ClariNet) */ #define CODES_LINE (ANPA_LINE+1) /* Codes (ClariNet) */ -#define CONTENT_LINE (CODES_LINE+1) /* MIME */ -#define CANCEL_LINE (CONTENT_LINE+1) /* cancel */ +#define CONTENT_LINE (CODES_LINE+1) /* Content-Type (MIME) */ +#define CONTXFER_LINE (CONTENT_LINE+1) /* Content-Transfer-Encoding */ +#define CANCEL_LINE (CONTXFER_LINE+1) /* cancel */ #define DIST_LINE (CANCEL_LINE+1) /* distribution */ #define DATE_LINE (DIST_LINE+1) /* date */ @@ -90,6 +91,10 @@ #ifdef MIME_SUPPORT {"content-type", 0, 0, 12, HT_MAGIC }, + {"content-transfer-encoding", + 0, 0, 25, HT_MAGIC }, #else {"content-type", 0, 0, 12, 0 }, + {"content-transfer-encoding", + 0, 0, 25, 0 }, #endif {"control", 0, 0, 7, 0 }, Index:help.c @@ -253,5 +253,5 @@ 1 Go to the first newsgroup.\n\ ^ Go to the first newsgroup with unread news.\n\ -$ Go to the last newsgroup.\n\ +$ Go to the end of newsgroups.\n\ ",NOMARKING)) || (cmd = print_lines("\ Index:hints/domainos.sh @@ -0,0 +1,2 @@ +ccflags='-A nansi' +d_ignoreorg='define' Index:hints/sgi.sh @@ -1,3 +1,3 @@ d_voidsig=define -d_novfork=define +d_vfork=undef d_sigblock=undef Index:hints/solaris_2_0.sh @@ -1,1 +1,1 @@ -d_novfork=undef +d_vfork=undef Index:hints/solaris_2_1.sh @@ -1,3 +1,4 @@ -d_novfork=undef -i_dirent=undef -i_sysdir=define +#d_vfork=undef +i_dirent=define +i_sysdir=undef +libs='-lmalloc -lsocket -lnls -lnsl -lintl -lucb' Index:init.c @@ -134,5 +134,6 @@ /* open connection to server if appropriate */ - nntp_connect(); + if (!nntp_connect()) + finalize(1); #endif Index:intrp.c @@ -1000,9 +1000,4 @@ abort_interp(); } - if (tick_quote) { - *dest++ = '\''; - if ((destsize -= 2) <= 0) - abort_interp(); - } while (*s) { if ((re_quote && index(regexp_specials, *s)) @@ -1014,6 +1009,4 @@ *dest++ = *s++; } - if (tick_quote) - *dest++ = '\''; } else { /* straight copy. */ Index:kfile.c @@ -95,4 +95,6 @@ killfirst = firstart; fseek(kfp,0L,0); /* rewind file */ + if (entering) + localkf_changes |= 1; while (fgets(buf,LBUFLEN,kfp) != Nullch) { if (*(cp = buf + strlen(buf) - 1) == '\n') @@ -104,6 +106,4 @@ if (killfirst > lastart) killfirst = lastart+1; - if (entering) - localkf_changes |= 1; continue; } @@ -321,4 +321,6 @@ else if (flags & AF_AUTOSELECT) ch = '.'; + else + ch = '?'; fprintf(newkfp,"%s T%c\n", ap->msgid, ch); } Index:last.c @@ -40,5 +40,14 @@ lastnewtime = atol(tcbuf); else - lastnewtime = (lasttime? lasttime : time(Null(time_t*))-24L*60*60); + lastnewtime = lasttime; +#if 1 + /* If the time is in the future, rewind by thirty days */ + if (lastnewtime > time(Null(time_t*))) + lastnewtime = time(Null(time_t*)) - 30L*24*60*60; +#endif + /* If the time wasn't set, just give them 2 days worth of groups */ + if (!lastnewtime) + lastnewtime = time(Null(time_t*)) - 2L*24*60*60; + if (fgets(tcbuf,1024,tmpfp) != Nullch) lastnewsize = atol(tcbuf); @@ -52,6 +61,6 @@ lastactsiz = 0; lastnewsize = 0; - /* Use yesterday as an initial value for finding new groups. */ - lastnewtime = time(Null(time_t*)) - 24L*60*60; + /* Use two days ago as an initial value for finding new groups. */ + lastnewtime = time(Null(time_t*)) - 2L*24*60*60; } } Index:newsnews.SH @@ -7,5 +7,5 @@ *** NEWS NEWS *** -Welcome to trn 3.3. This is a minor update from 3.2 with some bug fixes +Welcome to trn 3.4. This is mainly a bugfix release of version 3.3 and a few improvements. Trn is "threaded read news", based on rn. Index:ng.c @@ -202,4 +202,5 @@ artp = find_article(art); if (start_command) { /* do we have an initial command? */ + hide_pending(); pushstring(start_command, 0); free(start_command); @@ -221,6 +222,6 @@ } count_subjects(CS_RETAIN); - for (i=last_cached+1, ap=article_ptr(i); i<=lastart; i++, ap++) - if (!(ap->flags & AF_READ)) + for (i = absfirst, ap = article_ptr(i); i <= lastart; i++, ap++) + if (!(ap->flags & (AF_READ|AF_CACHED))) article_count++; toread[ng] = (ART_UNREAD)article_count; @@ -541,5 +542,5 @@ case '[': /* goto parent article */ case '{': /* goto thread's root article */ - if (artp) { + if (artp && ThreadedGroup) { if (!find_parent(*buf == '{')) { register char *cp = (*buf=='['?"parent":"root"); @@ -581,5 +582,5 @@ case ']': /* goto child article */ case '}': /* goto thread's leaf article */ - if (artp) { + if (artp && ThreadedGroup) { if (!find_leaf(*buf == '}')) { #ifdef VERBOSE @@ -600,5 +601,5 @@ case '(': /* goto previous sibling */ case ')': /* goto next sibling */ - if (artp) { + if (artp && ThreadedGroup) { if (!(*buf == '(' ? find_prev_sib() : find_next_sib())) { register char *cp = (*buf == '(' ? "previous" : "next"); @@ -658,5 +659,5 @@ goto not_threaded; kill_subject(artp->subj,KF_ALL); - if (last_cached < lastart) { + if (!ThreadedGroup || last_cached < lastart) { *buf = 'k'; goto normal_search; @@ -773,4 +774,6 @@ if (art <= lastart) reread = TRUE; + else + forcelast = TRUE; #ifdef ARTSEARCH srchahead = 0; @@ -1142,18 +1145,27 @@ return AS_NORM; case '+': + if (!artp) + goto not_threaded; if (ThreadedGroup) { - select_thread(artp->subj->thread, 0); + select_arts_thread(artp, 0); printf("\nSelected all articles in this thread.\n"); } else { - select_subject(artp->subj, 0); + select_arts_subject(artp, 0); printf("\nSelected all articles in this subject.\n"); } - return AS_ASK; + if ((artp = first_art(artp->subj)) != Nullart) { + if (art == article_num(artp)) + return AS_ASK; + art = article_num(artp); + } + return AS_NORM; case '-': + if (!artp) + goto not_threaded; if (sel_mode == SM_THREAD) { - deselect_thread(artp->subj->thread); + deselect_arts_thread(artp); printf("\nDeselected all articles in this thread.\n"); } else { - deselect_subject(artp->subj); + deselect_arts_subject(artp); printf("\nDeselected all articles in this subject.\n"); } @@ -1355,7 +1367,7 @@ ch = (use_one_line? '+' : '.'); if (thread_cmd) - select_thread(artp->subj->thread, AF_AUTOSELECTALL); + select_arts_thread(artp, AF_AUTOSELECTALL); else - select_subject(artp->subj, 0); + select_arts_subject(artp, 0); if (mode != 't') printf("\nSelection memorized.\n"); Index:ngdata.c @@ -138,6 +138,9 @@ strcpy(buf, "More news -- auto-processing...\n\n"); #endif - if (has_normal_kills) + if (has_normal_kills) { + bool forcelast_save = forcelast; kill_unwanted(tmpfirst,buf,TRUE); + forcelast = forcelast_save; + } #endif art = tmpart; Index:nghash.c @@ -55,5 +55,5 @@ while (1) { nntp_gets(ser_line, sizeof ser_line); - if (ser_line[0] == '.') /* while there's another line */ + if (NNTP_LIST_END(ser_line)) /* while there's another line */ break; /* get it and write it to */ fputs(ser_line, actfp); @@ -61,4 +61,5 @@ } + fflush(actfp); if (ferror(actfp)) { printf("Error writing to active file %s.\n", active_name) FLUSH; Index:ngstuff.c @@ -334,21 +334,21 @@ deselect_article(artp); } else if (ch == '+') { - if ((saveit || cmdlst[1] == '+') && artp->subj) { + if (saveit || cmdlst[1] == '+') { if (sel_mode == SM_THREAD) - select_thread(artp->subj->thread, - saveit? AF_AUTOSELECTALL : 0); + select_arts_thread(artp, saveit? AF_AUTOSELECTALL : 0); else - select_subject(artp->subj, saveit? AF_AUTOSELECTALL : 0); - cmdlst++; + select_arts_subject(artp, saveit? AF_AUTOSELECTALL : 0); + if (cmdlst[1] == '+') + cmdlst++; } else - select_article(artp, (saveit? AF_AUTOSELECTALL : 0) | AF_ECHO); + select_article(artp, AF_ECHO); } else if (ch == '.') { select_subthread(artp, saveit? AF_AUTOSELECT : 0); } else if (ch == '-') { - if (cmdlst[1] == '-' && artp->subj) { + if (cmdlst[1] == '-') { if (sel_mode == SM_THREAD) - deselect_thread(artp->subj->thread); + deselect_arts_thread(artp); else - deselect_subject(artp->subj); + deselect_arts_subject(artp); cmdlst++; } else @@ -357,13 +357,8 @@ kill_subthread(artp, saveit? (KF_ALL|KF_KILLFILE) : KF_ALL); } else if (ch == 'J' || ch == 'j') { - if (!artp->subj) { - set_read(artp); - artp->flags |= AF_AUTOKILLALL; - } else if (sel_mode == SM_THREAD) - kill_thread(artp->subj->thread, - saveit? (KF_ALL|KF_KILLFILE) : KF_ALL); + if (sel_mode == SM_THREAD) + kill_arts_thread(artp, saveit? (KF_ALL|KF_KILLFILE) : KF_ALL); else - kill_subject(artp->subj, - saveit? (KF_ALL|KF_KILLFILE) : KF_ALL); + kill_arts_subject(artp, saveit? (KF_ALL|KF_KILLFILE) : KF_ALL); } else if (ch == 't') { entire_tree(artp); Index:nntp.c @@ -108,5 +108,5 @@ for (;;) { nntp_gets(ser_line, sizeof ser_line); - if (ser_line[0] == '.' && ser_line[1] == '\0') + if (NNTP_LIST_END(ser_line)) break; fputs((ser_line[0] == '.' ? ser_line + 1 : ser_line), fp); @@ -131,14 +131,13 @@ return time((time_t*)NULL); - s = ser_line + strlen(ser_line) - 1; + s = rindex(ser_line, ' ') + 1; + month = (s[4] - '0') * 10 + (s[5] - '0'); + day = (s[6] - '0') * 10 + (s[7] - '0'); + hh = (s[8] - '0') * 10 + (s[9] - '0'); + mm = (s[10] - '0') * 10 + (s[11] - '0'); + ss = (s[12] - '0') * 10 + (s[13] - '0'); + s[4] = '\0'; + year = atoi(s); - ss = (*s - '0') + (*--s - '0') * 10; - mm = (*--s - '0') + (*--s - '0') * 10; - hh = (*--s - '0') + (*--s - '0') * 10; - day = (*--s - '0') + (*--s - '0') * 10; - month = (*--s - '0') + (*--s - '0') * 10; - *s = '\0'; - year = atoi(s-4); - /* This simple algorithm will be valid until the year 2400 */ if (year % 4) @@ -177,5 +176,9 @@ nntp_listgroup() { +#ifdef NO_LISTGROUP + static bool listgroup_works = FALSE; +#else static bool listgroup_works = TRUE; +#endif if (!listgroup_works) @@ -232,4 +235,26 @@ } +char +nntp_handle_timeout(strict) +bool_int strict; +{ + static bool handling_timeout = FALSE; + extern char last_command[]; + char last_command_save[NNTP_STRLEN]; + char ch; + + if (handling_timeout) + return NNTP_CLASS_FATAL; + handling_timeout = TRUE; + strcpy(last_command_save, last_command); + nntp_close(FALSE); + if (!nntp_connect() || (in_ng && !nntp_group(ngname, -1))) + fatal_error("\n503 Server timed out.\n"); + nntp_command(last_command_save); + ch = nntp_check(strict); + handling_timeout = FALSE; + return ch; +} + /* cleanup the odds and ends associated with NNTP usage */ @@ -240,5 +265,5 @@ if (*active_name) UNLINK(active_name); - nntp_close(); + nntp_close(TRUE); } Index:nntp.h @@ -17,4 +17,5 @@ char *nntp_get_a_line _((char*, int)); char *nntp_artname _((void)); +char nntp_handle_timeout _((bool_int)); void nntp_cleanup _((void)); Index:nntpclient.c @@ -19,5 +19,5 @@ "This machine does not have permission to use the %s news server.\n" -void +int nntp_connect() { @@ -46,5 +46,6 @@ Couldn't get name of news server from %s\n\ Either fix this file, or put NNTPSERVER in your environment.\n", SERVER_NAME); - fatal_error(ser_line); + report_error(ser_line); + return 0; } } @@ -55,13 +56,15 @@ char tmpbuf[LBUFLEN]; sprintf(tmpbuf,"News server %s unavailable: %s\n",server,&ser_line[4]); - fatal_error(tmpbuf); + report_error(tmpbuf); + return 0; } case -1: sprintf(ser_line,"News server %s unavailable, try again later.\n",server); - fatal_error(ser_line); + report_error(ser_line); + return 0; case NNTP_ACCESS_VAL: sprintf(ser_line,CANTUSE,server); - fatal_error(ser_line); - /* NOT REACHED */ + report_error(ser_line); + return 0; case NNTP_NOPOSTOK_VAL: advise(CANTPOST); @@ -71,16 +74,21 @@ default: sprintf(ser_line,"Unknown response code %d from %s.\n", response, server); - fatal_error(ser_line); + report_error(ser_line); + return 0; } + return 1; } +char last_command[NNTP_STRLEN]; + void nntp_command(buf) char *buf; { -#ifdef DEBUG +#if defined(DEBUG) && defined(FLUSH) if (debug & DEB_NNTP) printf(">%s\n", buf) FLUSH; #endif + strcpy(last_command, buf); fprintf(ser_wr_fp, "%s\r\n", buf); fflush(ser_wr_fp); @@ -101,12 +109,21 @@ #endif if (n < 0) +#ifdef fatal_error fatal_error("\nUnexpected close of server socket.\n"); +#else + return NNTP_CLASS_FATAL; +#endif n = strlen(ser_line); if (n >= 2 && ser_line[n-1] == '\n' && ser_line[n-2] == '\r') ser_line[n-2] = '\0'; -#ifdef DEBUG +#if defined(DEBUG) && defined(FLUSH) if (debug & DEB_NNTP) printf("<%s\n", ser_line) FLUSH; #endif + if (atoi(ser_line) == NNTP_TMPERR_VAL) { + /* See if this was really a timeout */ + return nntp_handle_timeout(strict); + } +#ifdef fatal_error if (strict && *ser_line == NNTP_CLASS_FATAL) { /* Fatal error */ char tmpbuf[LBUFLEN]; @@ -114,4 +131,5 @@ fatal_error(tmpbuf); } +#endif return *ser_line; } @@ -132,5 +150,9 @@ #endif if (n < 0) +#ifdef fatal_error fatal_error("\nUnexpected close of server socket.\n"); +#else + return -1; +#endif n = strlen(buf); if (n >= 2 && buf[n-1] == '\n' && buf[n-2] == '\r') @@ -140,12 +162,14 @@ void -nntp_close() +nntp_close(send_quit) +bool_int send_quit; { if (ser_wr_fp != NULL && ser_rd_fp != NULL) { - nntp_command("QUIT"); + if (send_quit) { + nntp_command("QUIT"); + nntp_check(FALSE); + } fclose(ser_wr_fp); ser_wr_fp = NULL; - - nntp_check(FALSE); fclose(ser_rd_fp); ser_rd_fp = NULL; Index:nntpclient.h @@ -10,10 +10,12 @@ int server_init _((char*)); -void nntp_connect _((void)); +int nntp_connect _((void)); void nntp_command _((char*)); char nntp_check _((bool_int)); int nntp_gets _((char*, int)); -void nntp_close _((void)); +void nntp_close _((bool_int)); +#define NNTP_LIST_END(s) ((s)[0]=='.' && ((s)[1]=='\0' || (s)[1]=='\r')) + /* RFC 977 defines these, so don't change them */ Index:nntpinit.c @@ -89,4 +89,5 @@ nntp_check(FALSE); +#ifndef NO_INN_SUPPORT if (*ser_line == NNTP_CLASS_OK) { /* Send a MODE READER command in case we're talking to innd. @@ -97,4 +98,5 @@ strcpy(ser_line, line2); } +#endif return atoi(ser_line); } @@ -104,4 +106,5 @@ char *server; { + int portno; int s; struct sockaddr_in sin; @@ -129,4 +132,5 @@ return -1; } + portno = sp->s_port; /* If not a raw ip address, try nameserver */ if (!isdigit(*server) @@ -153,5 +157,5 @@ bzero((char *) &sin, sizeof(sin)); sin.sin_family = hp->h_addrtype; - sin.sin_port = sp->s_port; + sin.sin_port = portno; #endif /* !NONETDB */ Index:overview.h @@ -32,6 +32,6 @@ ** or without the "Xref:" prefix. */ -#undef OV_XREFS /* only define when using non-standard .overview */ -#undef OV_LAX_XREFS /* allow xref field to have a header-prefix */ +/*#define OV_XREFS 8 *//* only define when using non-standard .overview */ +/*#define OV_LAX_XREFS *//* allow xref field to have a header-prefix */ /* What name to append to the directory name to read an overview file. Index:rt-mt.c @@ -114,5 +114,8 @@ return TRUE; - printf("\nGetting thread file."), fflush(stdout); +#ifdef VERBOSE + IF(verbose) + printf("\nGetting thread file."), fflush(stdout); +#endif if (nntp_read((char*)&total, (long)sizeof (TOTAL)) < sizeof (TOTAL)) goto exit; @@ -121,5 +124,8 @@ if ((fp = fopen(mt_name(ngname), FOPEN_RB)) == Nullfp) return TRUE; - printf("\nReading thread file."), fflush(stdout); +#ifdef VERBOSE + IF(verbose) + printf("\nReading thread file."), fflush(stdout); +#endif if (fread((char*)&total, 1, sizeof (TOTAL), fp) < sizeof (TOTAL)) Index:rt-ov.c @@ -40,5 +40,5 @@ do { nntp_gets(ser_line, sizeof ser_line); - } while (*ser_line != '.'); + } while (NNTP_LIST_END(ser_line)); } #endif @@ -89,6 +89,9 @@ goto exit; } - if (!ov_opened) - printf("\nGetting overview file."), fflush(stdout); +#ifdef VERBOSE + IF(verbose) + if (!ov_opened) + printf("\nGetting overview file."), fflush(stdout); +#endif ov_next_art = last+1; @@ -99,5 +102,8 @@ return FALSE; } - printf("\nReading overview file."), fflush(stdout); +#ifdef VERBOSE + IF(verbose) + printf("\nReading overview file."), fflush(stdout); +#endif } setspin(cheating? SPIN_BACKGROUND : SPIN_FOREGROUND); @@ -109,5 +115,5 @@ #ifdef USE_XOVER line = nntp_get_a_line(last_buf, last_buflen); - if (*line == '.') + if (NNTP_LIST_END(line)) break; #else @@ -119,7 +125,7 @@ artnum = atol(line); spin(100); -#ifndef USE_XOVER if (artnum < first) continue; +#ifndef USE_XOVER if (artnum > last) { artnum = last; Index:rt-page.c @@ -156,4 +156,5 @@ int desired_flags = (sel_rereading? AF_READ : 0); limit = artptr_list + artptr_list_size; + ap = Nullart; for (app = sel_page_app; app < limit; app++) { ap = *app; @@ -162,5 +163,5 @@ } sort_articles(); - if (app == limit) + if (ap == Nullart) sel_page_app = artptr_list + artptr_list_size; else { @@ -468,5 +469,5 @@ int line_cnt; bool etc; - char ch; + char ch = ' '; sp = sel_page_sp; Index:rt-process.c @@ -343,7 +343,7 @@ if (select_this_art & AF_AUTOSELECTALL) { if (sel_mode == SM_THREAD) - select_thread(article->subj->thread, AF_AUTOSELECTALL); + select_arts_thread(article, AF_AUTOSELECTALL); else - select_subject(article->subj, AF_AUTOSELECTALL); + select_arts_subject(article, AF_AUTOSELECTALL); } else if (select_this_art & AF_AUTOSELECT) select_subthread(article, AF_AUTOSELECT); Index:rt-select.c @@ -97,5 +97,5 @@ *promptbuf = '\0'; disp_status_line = FALSE; - if (added_articles > 0) { + if (added_articles) { register long i = added_articles, j; register ARTICLE *ap = article_ptr(lastart - i + 1); @@ -124,7 +124,7 @@ /* Check if there is really anything left to display. */ - if (!sel_item_cnt && !empty_ok) { /*TODO: this may not be needed anymore */ + if (!sel_item_cnt && !empty_ok) { empty_complaint(); - sel_ret = '+'; + sel_ret = 'q'; goto sel_exit; } Index:rt-util.c @@ -161,4 +161,5 @@ if (mid == s+1) { /* no middle name */ mid = 0; + midlen = 0; } else { *mid++ = '\0'; Index:rthread.c @@ -74,7 +74,7 @@ (void) ov_data(absfirst, lastart, FALSE); else if (firstart > lastart) { - /* If no unread articles, see if ov. exists as quick as possible */ + /* If no unread articles, see if ov. exists as fast as possible */ (void) ov_data(absfirst, absfirst, FALSE); - first_cached = last_cached+1; + cached_all_in_range = FALSE; } else (void) ov_data(firstart, lastart, FALSE); @@ -102,6 +102,6 @@ thread_grow() { - added_articles = lastart - last_cached; - if (added_articles > 0 && thread_always) + added_articles += lastart - last_cached; + if (added_articles && thread_always) cache_range(last_cached + 1, lastart); count_subjects(CS_NORM); @@ -201,5 +201,6 @@ { register ARTICLE *ap = artp; - int subj_mask = (sel_mode == SM_THREAD? (SF_THREAD|SF_VISIT) : SF_VISIT); + int subj_mask = (sel_mode == SM_THREAD? SF_THREAD : 0) + | (rereading? 0 : SF_VISIT); /* Use the explicit article-order if it exists */ @@ -247,6 +248,8 @@ ap = first_art(sp); while (!ap) { + if (sel_mode == SM_THREAD && sp->thread) + sp = sp->thread->subj; while ((sp = sp->next) != Nullsubj - && !rereading && (sp->flags & subj_mask) != subj_mask) + && (sp->flags & subj_mask) != subj_mask) ; if (!sp) @@ -298,5 +301,6 @@ { register ARTICLE *ap = artp; - int subj_mask = (sel_mode == SM_THREAD? (SF_THREAD|SF_VISIT) : SF_VISIT); + int subj_mask = (sel_mode == SM_THREAD? SF_THREAD : 0) + | (rereading? 0 : SF_VISIT); /* Use the explicit article-order if it exists */ @@ -338,6 +342,8 @@ ap = last_art(sp); while (!ap) { + if (sel_mode == SM_THREAD && sp->thread) + sp = sp->thread->subj; while ((sp = sp->prev) != Nullsubj - && !rereading && (sp->flags & subj_mask) != subj_mask) + && (sp->flags & subj_mask) != subj_mask) ; if (!sp) @@ -570,4 +576,17 @@ } +/* Select this article's subject. +*/ +void +select_arts_subject(ap, sel_flags) +register ARTICLE *ap; +int sel_flags; +{ + if (ap->subj && ap->subj->articles) + select_subject(ap->subj, sel_flags); + else + select_article(ap, sel_flags); +} + /* Select all the articles in a subject. */ @@ -604,4 +623,17 @@ } +/* Select this article's thread. +*/ +void +select_arts_thread(ap, sel_flags) +register ARTICLE *ap; +int sel_flags; +{ + if (ap->subj && ap->subj->thread) + select_thread(ap->subj->thread, sel_flags); + else + select_arts_subject(ap, sel_flags); +} + /* Select all the articles in a thread. */ @@ -684,4 +716,16 @@ } +/* Deselect this article's subject. +*/ +void +deselect_arts_subject(ap) +register ARTICLE *ap; +{ + if (ap->subj && ap->subj->articles) + deselect_subject(ap->subj); + else + deselect_article(ap); +} + /* Deselect all the articles in a subject. */ @@ -710,4 +754,16 @@ } +/* Deselect this article's thread. +*/ +void +deselect_arts_thread(ap) +register ARTICLE *ap; +{ + if (ap->subj && ap->subj->thread) + deselect_thread(ap->subj->thread); + else + deselect_arts_subject(ap); +} + /* Deselect all the articles in a thread. */ @@ -742,4 +798,18 @@ } +/* Kill all unread articles attached to this article's subject. +*/ +void +kill_arts_subject(ap, kill_flags) +register ARTICLE *ap; +{ + if (ap->subj && ap->subj->articles) + kill_subject(ap->subj, kill_flags); + else { + set_read(ap); + ap->flags |= AF_AUTOKILLALL; + } +} + /* Kill all unread articles attached to the given subject. */ @@ -765,4 +835,16 @@ } +/* Kill all unread articles attached to this article's thread. +*/ +void +kill_arts_thread(ap, kill_flags) +register ARTICLE *ap; +{ + if (ap->subj && ap->subj->thread) + kill_thread(ap->subj->thread, kill_flags); + else + kill_arts_subject(ap, kill_flags); +} + /* Kill all unread articles attached to the given thread. */ @@ -1197,6 +1279,6 @@ */ void -count_subjects(mode) -int mode; +count_subjects(cmode) +int cmode; { register int count, sel_count; @@ -1210,5 +1292,5 @@ firstart = lastart+1; - if (mode != CS_RETAIN) + if (cmode != CS_RETAIN) for (sp = first_subject; sp; sp = sp->next) sp->flags &= ~SF_VISIT; @@ -1227,10 +1309,10 @@ } } - if (mode == CS_UNSEL_STORE) { + if (cmode == CS_UNSEL_STORE) { if (sp->flags & SF_SEL) sp->flags |= SF_OLDSEL; else sp->flags &= ~SF_OLDSEL; - } else if (mode == CS_RESELECT) { + } else if (cmode == CS_RESELECT) { if (sp->flags & SF_OLDSEL) sp->flags |= SF_SEL; @@ -1241,4 +1323,6 @@ if (subjdate) sp->date = subjdate; + else if (!sp->date && sp->articles) + sp->date = sp->articles->date; article_count += count; if (sel_count) { @@ -1246,5 +1330,5 @@ selected_count += sel_count; selected_subj_cnt++; - } else if (mode >= CS_UNSELECT) + } else if (cmode >= CS_UNSELECT) sp->flags &= ~sel_mask; else if (sp->flags & sel_mask) { @@ -1260,5 +1344,5 @@ } } - if (mode != CS_RETAIN && !article_count && !selected_only) { + if (cmode != CS_RETAIN && !article_count && !selected_only) { for (sp = first_subject; sp; sp = sp->next) sp->flags |= SF_VISIT; @@ -1378,4 +1462,6 @@ threadorder_count : subjorder_count); break; + default: + return; } @@ -1475,4 +1561,6 @@ sort_procedure = artorder_groups; break; + default: + return; } sel_page_app = 0; Index:rthread.h @@ -29,9 +29,13 @@ void select_article _((ARTICLE*,int)); +void select_arts_subject _((ARTICLE*,int)); void select_subject _((SUBJECT*,int)); +void select_arts_thread _((ARTICLE*,int)); void select_thread _((ARTICLE*,int)); void select_subthread _((ARTICLE*,int)); void deselect_article _((ARTICLE*)); +void deselect_arts_subject _((ARTICLE*)); void deselect_subject _((SUBJECT*)); +void deselect_arts_thread _((ARTICLE*)); void deselect_thread _((ARTICLE*)); void deselect_all _((void)); Index:sw.c @@ -318,4 +318,7 @@ dont_filter_control = TRUE; break; + case 'k': + kill_thru_kludge = upordown; + break; case 'l': muck_up_clear = upordown; @@ -553,4 +556,5 @@ printf("%cI ", mp[append_unsub]); printf("%cj ", mp[dont_filter_control]); + printf("%ck ", mp[kill_thru_kludge]); printf("%cl ", mp[muck_up_clear]); #ifdef CLEAREOL Index:term.c @@ -494,4 +494,38 @@ } +int not_echoing = 0; + +void +hide_pending() +{ + not_echoing = 1; + pushchar(0200); +} + +bool +macro_pending() +{ + if (nextout != nextin) { + if (circlebuf[nextout] == '\200') { + switch (not_echoing) { + case 0: + break; + case 1: + nextout++; + nextout %= PUSHSIZE; + not_echoing = 0; + break; + default: + circlebuf[nextout] = '\n'; + not_echoing = 0; + break; + } + return nextout != nextin; + } + return 1; + } + return 0; +} + /* input the 2nd and succeeding characters of a multi-character command */ /* returns TRUE if command finished, FALSE if they rubbed out first character */ @@ -509,7 +543,11 @@ if (s[1] != FINISHCMD) /* someone faking up a command? */ return TRUE; + if (not_echoing) + not_echoing = 2; do { top: - if (*(unsigned char *)s < ' ') { + if (not_echoing) + ; + else if (*(unsigned char *)s < ' ') { putchar('^'); putchar(*s | 64); @@ -639,7 +677,10 @@ { bool ret; + int buflimit_save = buflimit; + int not_echoing_save = not_echoing; buflimit = 2; ret = finish_command(FALSE); - buflimit = LBUFLEN; + buflimit = buflimit_save; + not_echoing = not_echoing_save; return ret; } @@ -650,5 +691,5 @@ eat_typeahead() { - if (!typeahead && nextin==nextout) { /* cancel only keyboard stuff */ + if (!typeahead && !macro_pending()) { /* cancel only keyboard stuff */ #ifdef PENDING while (input_pending()) @@ -700,5 +741,5 @@ int size; { - if (nextout != nextin) { + if (macro_pending()) { *addr = circlebuf[nextout++]; nextout %= PUSHSIZE; @@ -829,5 +870,9 @@ tryagain: curmap = topmap; - no_macros = (whatbuf != buf && nextin == nextout); +#ifdef OLD_RN_WAY + no_macros = (whatbuf != buf && !macro_pending()); +#else + no_macros = (whatbuf != buf); +#endif for (;;) { int_count = 0; @@ -1196,8 +1241,11 @@ if (from == to) return; - if (*CM && !muck_up_clear) - cmcost = strlen(str = tgoto(CM,0,to)); - else + if (*CM && !muck_up_clear) { + str = tgoto(CM,0,to); + cmcost = strlen(str); + } else { + str = Nullch; cmcost = 9999; + } if (to > from) { go_down: Index:term.h @@ -22,5 +22,5 @@ EXT long iocount INIT(0); # ifndef lint -#define input_pending() (nextin!=nextout || (ioctl(0, FIONREAD, &iocount),(int)iocount)) +#define input_pending() (macro_pending() || (ioctl(0, FIONREAD, &iocount),(int)iocount)) # else #define input_pending() bizarre @@ -28,10 +28,10 @@ # else /* FIONREAD */ # ifdef HAS_RDCHK -#define input_pending() (nextin!=nextout || rdchk(0)) +#define input_pending() (macro_pending() || rdchk(0)) # else /* HAS_RDCHK */ int circfill(); EXT int devtty INIT(0); # ifndef lint -#define input_pending() (nextin!=nextout || circfill()) +#define input_pending() (macro_pending() || circfill()) # else #define input_pending() bizarre @@ -41,5 +41,5 @@ #else /* PENDING */ # ifndef lint -#define input_pending() (nextin!=nextout) +#define input_pending() macro_pending() # else #define input_pending() bizarre @@ -204,4 +204,6 @@ void show_macros _((void)); char putchr _((char_int)); /* routine for tputs to call */ +void hide_pending _((void)); +bool macro_pending _((void)); bool finish_command _((int)); bool finish_dblchar _((void)); @@ -213,7 +215,5 @@ void termlib_reset _((void)); #endif -#ifndef read_tty int read_tty _((char*,int)); -#endif void underprint _((char*)); #ifdef NOFIREWORKS Index:trn.1 @@ -757,4 +757,12 @@ Make search case sensitive. Ordinarily upper- and lower-case are considered the same. +.Ip /pattern/I 8 +Force the search to ignore the THRU line when executed as a memorized +command. +If the command portion is a selection command (i.\|e. it starts with +a \*(L'+\*(R' or a \*(L'.\*(R') this is the default behavior. +.Ip /pattern/N 8 +Force the search to NOT ignore the THRU line when executed as a memorized +command (useful on selection commands -- see also \-k). .Ip "/pattern/modifiers:command{:command}" 8 Apply the commands listed to articles matching the search command (possibly @@ -1416,4 +1424,12 @@ forces trn to leave control characters unmolested in messages. .TP 5 +.B \-k +tells trn to ignore the THRU line when processing selection searches +(i.\|e. searches with a command portion that starts with a \*(L'+\*(R' +or a \*(L'.\*(R') in the memorized commands (aka kill files). +This is turned on by default, so use +.B +k +if you want to turn it off. +.TP 5 .B \-l disables the clearing of the screen at the beginning of each @@ -1553,6 +1569,6 @@ .TP 5 .B \-T -allows you to type ahead of rn. -Ordinarily rn will eat typeahead to prevent your autorepeating space bar from +allows you to type ahead of trn. +Ordinarily trn will eat typeahead to prevent your autorepeating space bar from doing a very frustrating thing when you accidentally hold it down. If you don't have a repeating space bar, or you are working at low baud @@ -1808,5 +1824,5 @@ Organization (yours). .Ip %O 8 -Original working directory (where you ran rn from). +Original working directory (where you ran trn from). .Ip %p 8 Your private news directory, normally ~/News. @@ -1845,5 +1861,5 @@ The news library directory. .Ip %X 8 -The rn library directory. +The trn library directory. .Ip %z 8 The length of the current article in bytes. @@ -1854,5 +1870,5 @@ .Ip %. 8 The directory containing your dot files, which is your home directory unless -the environment variable DOTDIR is defined when rn is invoked. +the environment variable DOTDIR is defined when trn is invoked. .Ip %# 8 The current count for a multi-file save, starting with 1. @@ -1984,5 +2000,5 @@ Organization: %o .sp 1 -%i cancelled from rn. +%i cancelled from trn. .Ip DOTDIR 8 Where to find your dot files, if they aren't in your home directory. @@ -2183,5 +2199,5 @@ .Ip NNTPSERVER 8 The hostname of your NNTPSERVER. -[This does not apply unless you are running the NNTP version of rn.] +[This does not apply unless you are running the NNTP version of trn.] .Sp Default: the hostname listed in the server file, usually @@ -2598,5 +2614,5 @@ .I .newsrc .Ip "%./.rnlast" 1.25i -info from last run of rn +info from last run of trn .Ip "%./.rnsoft" 1.25i soft pointers into /usr/lib/news/active to speed startup, synchronous with Index:trn.c @@ -180,5 +180,6 @@ set_ngname(rcline[ng]); } - } + } else + shoe_fits = TRUE; if (toread[ng] < (emptyOnly || special ? TR_NONE : TR_ONE) || !shoe_fits) { /* unwanted newsgroup? */ @@ -579,7 +580,6 @@ #endif case 'v': - printf("\n%s",rnid); - printf("\n%s",patchlevel); - printf("\nSend bugs to davison@borland.com\n") FLUSH; + printf("\n%s\n%s\n",rnid,patchlevel); + printf("Send bug reports to davison@borland.com\n") FLUSH; goto reask_newsgroup; default: