home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / t / trn-23.zip / TRN-23.PAT < prev   
Text File  |  1993-03-25  |  118KB  |  4,413 lines

  1. Here's patch #3 for trn 2 -- this creates version 2.3.  To apply it, you
  2. need either a unified version of Larry Wall's patch program (such as 12u8),
  3. or the unidiff filter (included with trn) and an old version of patch.
  4.  
  5. To apply this from within trn, you would type:
  6.  
  7.     | patch -p -d /trn/source/dir
  8. or
  9.     | unipatch | patch -p -d /trn/source/dir
  10.  
  11. After installing the patch you should do the following:
  12.  
  13.     Configure             # (optional if you're not an INN site)
  14.     make Makefile
  15.     make depend
  16.     make
  17.     make install
  18.  
  19. Also, if you're using NNTP, see the new NNTP patches in the nntp subdir.
  20.  
  21. Additions to trn:
  22.    o    Added the 'Z' command in article mode to supersede an article and
  23.     include its text for easy modification.
  24.    o    Added thread-movement commands to go to an article's next/previous
  25.     sibling with '(' and ')', including "cousin" siblings.
  26.    o    The thread selector now lets you press 'c'+'y' to catch up without
  27.     chasing the xref'ed articles (easier than having to first leave the
  28.     thread selector).  Purists will want to set their own SELECTCHARS.
  29.    o    The Makefile knows how to use INN's nntp client library.
  30.    o    Added -b option to force trn to read threads in a breadth-first
  31.     manner rather than depth first.
  32.    o    Added -j option to have trn pass-through control characters in
  33.     articles.
  34.  
  35. Fixes for trn:
  36.    o    Trn no longer puts bogus Reference lines in new articles.
  37.    o    Fixed a problem in the KILL file processing of new articles
  38.     that arrive while within the group.
  39.    o    The default extract directory is now correctly set to a
  40.     group's SAVEDIR when entering a group.
  41.    o    Relative paths that contain a slash are not bumped out of
  42.     SAVEDIR when saving articles.
  43.    o    You can now 'g'o to a group name that starts with a number.
  44.    o    Trn opens the correct article when it is pre-fetching.
  45.    o    Turned off subject-prefetch in a threaded group.
  46.    o    Fixed a bug in the subject-search code that would result in
  47.     very slow search times if a group had lots of missing articles.
  48.    o    When using the 'k'ill thread command in the thread selector, it
  49.     no longer tries to chases xrefs for each keypress -- instead it
  50.     batches all the killing until after you're done selecting.
  51.    o    Added Geoff Collyer's hdbm hasing routines to make scaning the
  52.     active file faster (e.g. when bogus groups are discovered).
  53.    o    Various small fixes, including all the missing tweaks from
  54.     rn's last patch.
  55.  
  56. Fixes/enhancements for mthreads:
  57.    o    Fixed a couple bugs in the free code when attempting to ignore a
  58.     damaged thread file.
  59.    o    Added an intelligent name-squishing algorithm.
  60.    o    The NNTP version knows how to use the LISTGROUP command for the
  61.     extra-expire pass.
  62.    o    Other small fixes and minor speed tweaking.
  63.  
  64. Configure updates:
  65.    o    Added detection/query for INN.
  66.    o    Fixes to support more nm output formats.
  67.    o    Configure now checks for DGUX.
  68.    o    Fixed Configure's understanding of Domain/OS (hopefully).
  69.  
  70. Misc:
  71.    o    The HINTS file was corrected and an additional hint added.
  72.  
  73. NNTP changes for v1.5.11[t]:
  74.    o    Added LISTGROUP command (for mthreads).
  75.    o    The NEWGROUPS command is now filtered to remove groups you don't
  76.     have permission to access.
  77.    o    Fixed LONG_THREAD_NAMES support.
  78.    o    All clientlib changed have been removed and put into local code.
  79.     This allows trn to use the XTHREAD call using a wider variety of
  80.     clientlibs, including the one that comes with INN.
  81.  
  82. NOTE: use nntp/xthread.patch to upgrade v1.5.11 to v1.5.11t2.  Use the
  83. nntp/xthread-11t.to.11t2 to upgrade v1.5.11t to v1.5.11t2.
  84.  
  85. ..wayne..
  86. ---8<------8<------8<------8<---cut here--->8------>8------>8------>8---
  87. Index:patchlevel
  88. Prereq: v2.2
  89. @@ -1,1 +1,1 @@
  90. -trn v2.2
  91. +trn v2.3
  92. Index:Configure
  93. @@ -16,10 +16,13 @@
  94.  # shell scripts, Configure will trim # comments from them for you.
  95.  #
  96. -# $Id: Configure,v 4.4.3.1 1991/11/22 04:11:10 davison Trn $
  97. +# $Id: Configure,v 2.3 1992/03/01 02:06:01 davison Trn $
  98.  #
  99.  # $Log: Configure,v $
  100. -# Revision 4.4.3.1  1991/11/22  04:11:10  davison
  101. -# Trn Release 2.0
  102. -# 
  103. +# Revision 4.4.4.1  1992/02/23  21:25:39  sob
  104. +# Patch level 4
  105. +#
  106. +# Revision 4.4.3.1  1992/02/01  03:09:32  sob
  107. +# Release 4.4 Patchlevel 3
  108. +#
  109.  # Revision 4.4.2.1  1991/12/01  18:05:42  sob
  110.  # Patchlevel 2 changes
  111. @@ -165,4 +168,5 @@
  112.  hostcmd=''
  113.  norelay=''
  114. +haveinn=''
  115.  isrrn=''
  116.  xthread=''
  117. @@ -320,5 +324,5 @@
  118.      echo "Your C library is in /lib/libc.a.  You're normal."
  119.      if test -f /lib/libc_s.a; then
  120. -        echo "You also have AT&T shared libraries, we'll use those."
  121. +        echo "You also have AT&T shared libraries, we'll use those too."
  122.          sharedclib=-lc_s
  123.      fi
  124. @@ -326,11 +330,7 @@
  125.      fi
  126.  else
  127. -  if test -f /lib/clib; then
  128. -    echo "Your C library is in /lib/clib.  How nonstandard, must be Apollo."
  129. -    libc=/lib/clib
  130. -  else
  131. -    if test -f /lib/libc; then
  132. -    echo "Your C library is in /lib/libc.  This might be Domain/OS."
  133. -    libc=/lib/libc
  134. +    if test -f /lib/clib; then
  135. +    echo "Your C library is in /lib/clib.  How nonstandard, must be Apollo."
  136. +    libc='/lib/clib /lib/libc'
  137.      else
  138.      if test -f /lib/386/Slibc.a; then
  139. @@ -368,5 +368,4 @@
  140.      fi
  141.      fi
  142. -  fi
  143.  fi
  144.  
  145. @@ -391,28 +390,48 @@
  146.  echo $n "Extracting names from $libc for later perusal...$c"
  147.  nm $bopt $libc > nm.list 2>/dev/null
  148. -sed -n -e 's/^.* T _//p' -e 's/^.* T //p' < nm.list > libc.list
  149. +sed -n -e 's/^.* [ATDS]  *__*//p' -e 's/^.* [ATDS] //p' <nm.list >libc.list
  150. +if $contains '^printf$' libc.list >/dev/null 2>&1; then
  151. +    echo done
  152. +else
  153. +sed -n -e 's/^__*//' -e 's/^\([a-zA-Z_0-9$]*\).*xtern.*/\1/p' <nm.list >libc.list
  154. +if $contains '^printf$' libc.list >/dev/null 2>&1; then
  155. +    echo done
  156. +else
  157. +sed -n -e '/|UNDEF/d' -e '/FUNC..GL/s/^.*|__*//p' <nm.list >libc.list
  158. +if $contains '^printf$' libc.list >/dev/null 2>&1; then
  159. +    echo done
  160. +else
  161. +sed -n -e 's/^_//' -e 's/^\([a-zA-Z_0-9]*\).*xtern.*text.*/\1/p' <nm.list >libc.list
  162. +if $contains '^printf$' libc.list >/dev/null 2>&1; then
  163. +    echo done
  164. +else
  165. +grep '|' <nm.list | sed -n -e '/|COMMON/d' -e '/|DATA/d' -e '/ file/d' \
  166. +                           -e 's/^\([^     ]*\).*/\1/p' >libc.list
  167. +if $contains '^printf$' libc.list >/dev/null 2>&1; then
  168. +    echo done
  169. +else
  170. +sed -n -e 's/^.*|FUNC |GLOB .*|//p' -e 's/^.*|FUNC |WEAK .*|//p' <nm.list >libc.list
  171. +if $contains '^printf$' libc.list >/dev/null 2>&1; then
  172. +    echo done
  173. +else
  174. +: This is supposed to have a space and a tab in the three brackets
  175. +sed -n -e 's/^[     ]*[0-9][0-9a-f]*[     ]*Def. Text[     ]*//p' <nm.list | sed -e 's/\[.*\]//' >libc.list
  176. +if $contains '^printf$' libc.list >/dev/null 2>&1; then
  177. +    echo done
  178. +else
  179. +$contains .text nm.list | grep -v static | awk '{ print $1 }' > libc.list
  180.  if $contains '^printf$' libc.list >/dev/null 2>&1; then
  181. -    echo "done"
  182. +    echo done
  183.  else
  184. -    sed -n -e 's/^.* [AD] _//p' -e 's/^.* [AD] //p' < nm.list > libc.list
  185. -    if $contains '^printf$' libc.list >/dev/null 2>&1; then
  186. -    echo "done"
  187. -    else
  188. -     $contains .text nm.list | grep -v static | awk '{ print $1 }' > libc.list
  189. -        if $contains '^printf$' libc.list >/dev/null 2>&1; then
  190. -        echo "done"
  191. -        else
  192. -         echo " "
  193. -         echo "nm didn't seem to work right."
  194. -         echo "Trying ar instead..."
  195. -         if ar t $libc | sed -e 's/\.o$//' > libc.list; then
  196. -        echo "Ok."
  197. -         else
  198. -        echo "That didn't work either.  Giving up."
  199. -        exit 1
  200. -         fi
  201. -     fi
  202. +    echo " "
  203. +    echo "nm didn't seem to work right."
  204. +    echo "Trying ar instead..."
  205. +    if ar t $libc | sed -e 's/\.o$//' > libc.list; then
  206. +    echo "Ok."
  207. +    else
  208. +    echo "That didn't work either.  Giving up."
  209. +    exit 1
  210.      fi
  211. -fi
  212. +fi ; fi ; fi ; fi ; fi ; fi ; fi ; fi
  213.  rm nm.list
  214.  : make some quick guesses about what we are up against
  215. @@ -638,4 +657,21 @@
  216.      socketlib=
  217.  fi
  218. +
  219. +: check for DGUX
  220. +cat <<'EOT' >DGUX.c
  221. +#ifdef DGUX
  222. +exit 0
  223. +#else
  224. +exit 1
  225. +#endif
  226. +EOT
  227. +$cpp DGUX.c | grep exit >DGUX
  228. +chmod +x DGUX
  229. +$eunicefix DGUX
  230. +rm DGUX.c
  231. +if DGUX; then
  232. +    echo "This appears to be a DG AViiON..."
  233. +fi
  234. +
  235.  : check for sgi
  236.  cat <<'EOT' >sgi.c
  237. @@ -1339,5 +1375,9 @@
  238.  case "$mtmansrc" in
  239.  '') case "$manext" in
  240. -    '1') dflt="`dirname $mansrc`/`basename $mansrc 1`8" ;;
  241. +    '1') if pyr; then
  242. +         dflt="`att dirname $mansrc`/`basename $mansrc 1`8"
  243. +     else
  244. +         dflt="`dirname $mansrc`/`basename $mansrc 1`8"
  245. +     fi ;;
  246.      *)   dflt="$mansrc"
  247.      esac
  248. @@ -1854,4 +1894,9 @@
  249.      getwd=define
  250.  else
  251. +if DGUX; then
  252. +    $echo "I know DG/UX has getwd()."
  253. +    getcwd=undef
  254. +    getwd=define
  255. +else
  256.  : see if the system has getcwd
  257.  if $contains '^getcwd$' libc.list >/dev/null 2>&1 ; then
  258. @@ -1864,4 +1909,5 @@
  259.  fi
  260.  fi
  261. +fi
  262.  
  263.  : see if there is a vfork
  264. @@ -2190,5 +2236,5 @@
  265.      n*) syslog='' ;;
  266.      *)  case $syslog in
  267. -        LOG_*) dflt="$dflt" ;;
  268. +        LOG_*) dflt="$syslog" ;;
  269.          *)     dflt=LOG_NEWS ;;
  270.          esac
  271. @@ -2210,4 +2256,21 @@
  272.  fi
  273.  
  274. +: check for inn
  275. +$echo " "
  276. +if test -f $lib/newsfeeds; then
  277. +    dflt="y"
  278. +else
  279. +    dflt="n"
  280. +fi
  281. +$echo $n "Is your system or news server running inn news software? [${dflt}] $c"
  282. +. myread
  283. +case "$ans" in
  284. +'') ans=$dflt;;
  285. +esac
  286. +case "$ans" in
  287. +y*) haveinn='define';;
  288. +*)  haveinn='undef';;
  289. +esac
  290. +
  291.  : locate spool directory and check if rrn
  292.  case "$isrrn" in
  293. @@ -2337,5 +2400,8 @@
  294.      while $test ! -d "$ans"; do
  295.          $echo " "
  296. -        $echo $n "Enter the pathname of the NNTP source directory: [$dflt] $c"
  297. +        case "$haveinn" in
  298. +        undef) $echo $n "Enter the pathname of the NNTP source directory: [$dflt] $c" ;;
  299. +        *) $echo $n "Enter the pathname of the inn source directory: [$dflt] $c" ;;
  300. +        esac
  301.          . myread
  302.          case "$ans" in
  303. @@ -2343,8 +2409,14 @@
  304.          esac
  305.          ans=`filexp "$ans"`
  306. -        if $test ! -r $ans/common/nntp.h ; then
  307. -        $echo "Can't find $ans/common/nntp.h!"
  308. -        ans='blurfl/dyick'
  309. -        fi
  310. +        case "$haveinn" in
  311. +        undef) if $test ! -r $ans/common/nntp.h ; then
  312. +            $echo "Can't find $ans/common/nntp.h!"
  313. +            ans='blurfl/dyick'
  314. +        fi;;
  315. +        *)  if $test ! -r $ans/include/nntp.h ; then
  316. +            $echo "Can't find $ans/include/nntp.h!"
  317. +            ans='blurfl/dyick'
  318. +        fi;;
  319. +        esac
  320.      done
  321.      NNTPSRC="$ans"
  322. @@ -2577,6 +2649,8 @@
  323.  
  324.  : check for 2.10.2 and above
  325. -$echo " "
  326. -if $contains ' [0-9][0-9]* [0-9]' "$myactive" >/dev/null 2>&1; then
  327. +case "$haveinn" in
  328. +undef)
  329. +  $echo " "
  330. +  if $contains ' [0-9][0-9]* [0-9]' "$myactive" >/dev/null 2>&1; then
  331.      case "$norelay" in
  332.      undef) dflt="y";;
  333. @@ -2610,6 +2684,9 @@
  334.      esac
  335.      norelay='undef'
  336. -fi
  337. -
  338. +  fi ;;
  339. +define)
  340. +  norelay='define' 
  341. +  mininact='define' ;;
  342. +esac
  343.  
  344.  : check for void type
  345. @@ -3155,4 +3232,5 @@
  346.  norelay='$norelay'
  347.  rdchk='$rdchk'
  348. +haveinn='$haveinn'
  349.  isrrn='$isrrn'
  350.  xthread='$xthread'
  351. Index:HINTS
  352. @@ -12,7 +12,5 @@
  353.  you want to read on the current page, press space, and you will read the
  354.  selected articles immediately (if there were any).  All other articles on the
  355. -current page will be marked as read.  (Don't use -XXD, because new articles
  356. -might have arrived while reading, and they could be marked as read without
  357. -ever seeing them.)
  358. +current page will be marked as read.
  359.  ----------
  360.  I like to use the -xls command-line option to only have the long and short
  361. @@ -29,6 +27,6 @@
  362.  unread?" prompt (except at the thread selector), 'U' goes directly to the
  363.  already-read article selector, and Ctrl-U unsubscribes from the group (even
  364. -while in the thread selector).  Put the following 3 macros in your .trninit
  365. -file to accomplish this:
  366. +while in the thread selector).  Put the following 3 macros in your .rnmac
  367. +file to accomplish this (or change RNMACROS to .trnmac and put them there):
  368.  
  369.  u    %(%m=[anp]?U:u)
  370. @@ -37,7 +35,12 @@
  371.  ----------
  372.  If you like the way that 'q' worked in the thread selector in trn 1.x, put
  373. -the following macro in your .trninit file:
  374. +the following macro in your .rnmac file:
  375.  
  376.  q    %(%m=t?+:q)
  377. +----------
  378. +If you would like the 'f' command to always answer yes to the "Are you start-
  379. +ing an unreleated topic?" question, put this line into your .rnmac file:
  380. +
  381. +f    %(%m=[ap]?f%(%m=F?y:^@):f)
  382.  ----------
  383.  If you want to be able to save your shar headers in a file as they are
  384. Index:Makefile.SH
  385. @@ -4,5 +4,5 @@
  386.  echo "Extracting Makefile (with variable substitutions)"
  387.  $cat >Makefile <<!GROK!THIS!
  388. -# $Id: Makefile.SH,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
  389. +# $Id: Makefile.SH,v 2.3 1992/03/01 02:13:32 davison Trn $
  390.  #
  391.  # This software is Copyright 1991 by Stan Barber. 
  392. @@ -19,4 +19,7 @@
  393.  #
  394.  # $Log: Makefile.SH,v $
  395. +# Revision 4.4.3.1  1992/02/01  03:09:32  sob
  396. +# Release 4.4 Patchlevel 3
  397. +#
  398.  # Revision 4.4.2.1  1991/12/01  18:05:42  sob
  399.  # Changed clientlib to be built in the rn tree instead of the nntp tree.
  400. @@ -59,7 +62,7 @@
  401.  
  402.  h1 = addng.h art.h artio.h artsrch.h autosub.h backpage.h bits.h cheat.h 
  403. -h2 = common.h decode.h final.h head.h help.h init.h intrp.h kfile.h last.h
  404. -h3 = ng.h ngdata.h ngsrch.h ngstuff.h only.h rcln.h rcstuff.h
  405. -h4 = respond.h rn.h search.h sw.h term.h util.h
  406. +h2 = common.h decode.h final.h hdbm.h hdbmint.h head.h help.h init.h
  407. +h3 = intrp.h kfile.h last.h ng.h ngdata.h ngsrch.h ngstuff.h only.h rcln.h
  408. +h4 = rcstuff.h respond.h rn.h search.h sw.h term.h util.h
  409.  
  410.  h = $(h1) $(h2) $(h3) $(h4)
  411. @@ -66,9 +69,10 @@
  412.  
  413.  c1 = addng.c art.c artio.c artsrch.c autosub.c backpage.c bits.c cheat.c
  414. -c2 = decode.c final.c head.c help.c init.c intrp.c kfile.c last.c $(NDIRC)
  415. -c3 = ng.c ngdata.c ngsrch.c ngstuff.c only.c rcln.c rcstuff.c respond.c rn.c
  416. -c4 = rthreads.c rt-rn.c rt-select.c search.c sw.c term.c threads.c util.c
  417. -c5 = unship.c uudecode.c
  418. -#NNTPc6 = server.c $(NNTPDIR)/common/clientlib.c
  419. +c2 = decode.c final.c hdbm.c head.c help.c init.c intrp.c kfile.c last.c
  420. +c3 = $(NDIRC) ng.c ngdata.c nghash.c ngsrch.c ngstuff.c only.c rcln.c
  421. +c4 = rcstuff.c respond.c rn.c rthreads.c rt-rn.c rt-select.c search.c sw.c
  422. +c5 = term.c threads.c util.c unship.c uudecode.c
  423. +#INN#NNTPc6 = server.c
  424. +#NO_INN#NNTPc6 = server.c $(NNTPDIR)/common/clientlib.c
  425.  
  426.  c = $(c1) $(c2) $(c3) $(c4) $(c5) $(c6)
  427. @@ -81,9 +85,10 @@
  428.  
  429.  obj1 = addng.o art.o artio.o artsrch.o autosub.o backpage.o bits.o cheat.o
  430. -obj2 = decode.o final.o head.o help.o init.o intrp.o kfile.o last.o $(NDIRO)
  431. -obj3 = ng.o ngdata.o ngsrch.o ngstuff.o only.o rcln.o rcstuff.o respond.o rn.o
  432. -obj4 = rthreads.o rt-rn.o rt-select.o search.o sw.o term.o threads.o util.o
  433. -obj5 = unship.o uudecode.o
  434. -#NNTPobj6 = server.o clientlib.o
  435. +obj2 = decode.o final.o hdbm.o head.o help.o init.o intrp.o kfile.o last.o
  436. +obj3 = $(NDIRO) ng.o ngdata.o nghash.o ngsrch.o ngstuff.o only.o rcln.o
  437. +obj4 = rcstuff.o respond.o rn.o rthreads.o rt-rn.o rt-select.o search.o sw.o
  438. +obj5 = term.o threads.o util.o unship.o uudecode.o
  439. +#INN#NNTPobj6 = server.o $(NNTPDIR)/libinn.a
  440. +#NO_INN#NNTPobj6 = server.o clientlib.o
  441.  
  442.  obj = $(obj1) $(obj2) $(obj3) $(obj4) $(obj5) $(obj6)
  443. @@ -101,8 +106,8 @@
  444.  
  445.  add1 = Makefile.old Pnews Rnmail mt.check
  446. -add2 = bsd config.h config.sh eunice filexp 
  447. +add2 = bsd config.h eunice filexp 
  448.  add3 = loc makedepend makedir mbox.saver ndir.h newsetup
  449.  add4 = newsgroups newsnews norm.saver
  450. -add5 = pdp11 usg v7 ultrix sun hp-ux sgi xenix next server.h mips uts
  451. +add5 = pdp11 usg v7 ultrix sun hp-ux sgi xenix next server.h mips uts DGUX
  452.  add6 = all pyr grimble .falseactive Pnews.header s5uniq sigtest stardent
  453.  
  454. @@ -131,9 +136,11 @@
  455.      $(CC) $(LDFLAGS) mtgroups.o mt-misc.o -lcurses $(libs) -o mtgroups
  456.  
  457. -#NNTPgetactive: getactive.o server.o clientlib.o
  458. -#NNTP    $(CC) $(LDFLAGS) getactive.o server.o clientlib.o -o getactive $(libs)
  459. +#INN#NNTPgetactive: getactive.o server.o $(NNTPDIR)/libinn.a
  460. +#INN#NNTP    $(CC) $(LDFLAGS) getactive.o server.o -o getactive $(libs) $(NNTPDIR)/libinn.a
  461. +#NO_INN#NNTPgetactive: getactive.o server.o clientlib.o
  462. +#NO_INN#NNTP    $(CC) $(LDFLAGS) getactive.o server.o clientlib.o -o getactive $(libs)
  463.  
  464. -#NNTPclientlib.o:
  465. -#NNTP    $(CC) -c $(CFLAGS) $(NNTPINC) $(NNTPDIR)/common/clientlib.c
  466. +#NO_INN#NNTPclientlib.o:
  467. +#NO_INN#NNTP    $(CC) -c $(CFLAGS) $(NNTPINC) $(NNTPDIR)/common/clientlib.c
  468.  
  469.  # if a .h file depends on another .h file...
  470. @@ -149,4 +156,5 @@
  471.      - if test `pwd` != $(rnbin); then cd $(rnbin); chmod 755 $(public); strip trn tmpthread ; fi
  472.      - ./makedir `./filexp $(rnlib)`
  473. +    - chmod 755 `./filexp $(rnlib)`
  474.  #MT    - cd `./filexp $(rnlib)`; mv mthreads mthreads.old
  475.      - if test `pwd` != `./filexp $(rnlib)`; then cp INIT $(private) `./filexp $(rnlib)`; fi
  476. @@ -158,4 +166,5 @@
  477.  for page in $(manpages); do \
  478.  cp $$page $(mansrc)/`basename $$page .1`.$(manext); \
  479. +chmod 444 $(mansrc)/`basename $$page .1`.$(manext); \
  480.  done; \
  481.  #NNTPecho ".so man$(manext)/trn.$(manext)" > $(mansrc)/trrn.$(manext) ; \
  482. @@ -163,12 +172,18 @@
  483.  #MT    - if test `pwd` != $(mtmansrc); then \
  484.  #MTcp mthreads.8 $(mtmansrc)/mthreads.$(mtmanext); \
  485. +#MTchmod 444 $(mtmansrc)/mthreads.$(mtmanext); \
  486.  #MTfi
  487.  
  488.  clean:
  489. +    @ echo 'Use "make realclean" to remove the executables and Configure droppings.'
  490. +    @ echo 'Use "make spotless" to also remove config.sh'
  491.      rm -f *.o
  492.  
  493. -realclean:
  494. -    rm -f trn mthreads tmpthread *.o core $(addedbyconf) 
  495. -#NNTP    rm -f clientlib.o getactive
  496. +realclean: clean
  497. +    rm -f trn mthreads tmpthread core $(addedbyconf)
  498. +#NNTP    rm -f getactive
  499. +
  500. +spotless: realclean
  501. +    rm -f config.sh
  502.  
  503.  # The following lint has practically everything turned on.  Unfortunately,
  504. @@ -200,4 +215,11 @@
  505.      @ echo "You haven't done a "'"make depend" yet!'; exit 1
  506.  !NO!SUBS!
  507. +case "$haveinn" in
  508. +undef) sed < Makefile -e '/^#NO_INN/s/^#NO_INN//
  509. +              /^#INN/d' > Makefile.new ;;
  510. +define) sed < Makefile -e '/^#INN/s/^#INN//
  511. +              /^#NO_INN/d' > Makefile.new ;;
  512. +esac
  513. +mv Makefile.new Makefile
  514.  case "$isrrn" in
  515.  define) if $test "$serverspool " != " " ; then
  516. Index:NEW
  517. @@ -1,3 +1,3 @@
  518. -            TRN 2.0 vs TRN 1.0.3:
  519. +            TRN 2.3 vs TRN 1.0.3:
  520.  
  521.  [If you're upgrading from trn 1.x, at least read the ** LOOK ** section.]
  522. @@ -115,5 +115,5 @@
  523.      resources to destroy the old database and rebuild it with the new
  524.      mthreads, put the -o2 option in your global INIT file for a few
  525. -    weeks -- you can remove it once the old article data has expired
  526. +    days -- you can remove it once the old article data has expired
  527.      (if you begin using the new mthreads, of course).
  528.     o    NOTE that the new mthreads puts its db.init file in the root of the
  529. Index:Pnews.1
  530. @@ -1,5 +1,8 @@
  531. -.\" $Id: Pnews.1,v 4.4.1.1 1991/09/25 19:36:48 sob Exp sob $
  532. +.\" $Id: Pnews.1,v 4.4.3.1 1992/02/01 03:17:20 sob PATCH_3 sob $
  533.  .\" 
  534.  .\" $Log: Pnews.1,v $
  535. +.\" Revision 4.4.3.1  1992/02/01  03:17:20  sob
  536. +.\" Version 4.4 Patchlevel 3
  537. +.\"
  538.  .\" Revision 4.4.1.1  1991/09/25  19:36:48  sob
  539.  .\" Changed quote macro to "standard" one
  540. Index:Pnews.SH
  541. @@ -5,7 +5,13 @@
  542.  $spitshell >Pnews <<!GROK!THIS!
  543.  $startsh
  544. -# $Id: Pnews.SH,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
  545. +# $Id: Pnews.SH,v 4.4.4.1 1992/02/23 21:25:39 sob PATCH_4 sob $
  546.  #
  547.  # $Log: Pnews.SH,v $
  548. +# Revision 4.4.4.1  1992/02/23  21:25:39  sob
  549. +# Patch level 4
  550. +#
  551. +# Revision 4.4.3.1  1992/02/01  03:09:32  sob
  552. +# Release 4.4 Patchlevel 3
  553. +#
  554.  # Revision 4.4.2.1  1991/12/01  18:05:42  sob
  555.  # Patchlevel 2
  556. @@ -87,4 +93,5 @@
  557.  loc="$locpref"
  558.  org="$orgpref"
  559. +multistate="$multistatepref"
  560.  city="$citypref"
  561.  state="$statepref"
  562. @@ -139,6 +146,11 @@
  563.  
  564.  case $cntry in
  565. -  can) stpr=Province ;;
  566. -  *)   stpr=State ;;
  567. +  can) Stpr=Province ; stpr=province ;;
  568. +  *)   Stpr=State ; stpr=state ;;
  569. +esac
  570. +
  571. +case $multistate in
  572. +  pnw) multistpr="Pacific NorthWest" ;;
  573. +  *)   multistpr="Multi-State Area" ;;
  574.  esac
  575.  
  576. @@ -269,6 +281,9 @@
  577.      $echo 'This program posts news to many machines throughout the country.'
  578.      ;;
  579. +$multistate.*)
  580. +    $echo "This program posts news to many machines throughout the ${multistpr}."
  581. +    ;;
  582.  $state.*)
  583. -    $echo 'This program posts news to many machines throughout the state.'
  584. +    $echo "This program posts news to many machines throughout the ${stpr}."
  585.      ;;
  586.  $city.*)
  587. @@ -523,5 +538,5 @@
  588.          set X ${USER-${LOGNAME-`who am i`}} unknown
  589.          shift
  590. -        $rnlib/mbox.saver $tmpart "." "." 0 0 Pnews $AUTHORCOPY "From $1 `date`"
  591. +        $rnlib/mbox.saver $tmpart "." "." 0 0 Pnews $AUTHORCOPY "From $1 `LANG= date`"
  592.          if $test $? -eq 0 ; then
  593.          $echo "Article appended to $AUTHORCOPY"
  594. @@ -607,5 +622,6 @@
  595.      Organization:    $org
  596.      City:        $city
  597. -    $stpr:          $state
  598. +    $Stpr:          $state
  599. +    $multistpr:    $multistate
  600.      Country:        $cntry
  601.      Continent:        $cont
  602. @@ -631,5 +647,5 @@
  603.  EOH
  604.      ;;
  605. -    ''|$loc*|$org*|$city*|$state*|$cntry*|$cont*|$defdist)
  606. +    ''|$loc*|$org*|$city*|$state*|$multistate*|$cntry*|$cont*|$defdist)
  607.      ;;
  608.      world*|comp*|news*|sci*|rec*|misc*|soc*|talk*|alt*)
  609. Index:README
  610. @@ -1,3 +1,3 @@
  611. -              Trn Kit, Version 2.0
  612. +              Trn Kit, Version 2.x
  613.  
  614.              Copyright (c) 1991, Wayne Davison
  615. @@ -158,5 +158,5 @@
  616.  
  617.  11) IMPORTANT!  Help save the world!  Communicate any problems and suggested
  618. -    patches to Wayne Davison (davison@borland.com) so we can keep the world
  619. +    patches to Wayne Davison <davison@borland.com> so we can keep the world
  620.      in sync.  If you have a problem, there's someone else out there who either
  621.      has had or will have the same problem.  If the problem affects regular rn,
  622. Index:Rnmail.1
  623. @@ -1,5 +1,8 @@
  624. -.\" $Id: Rnmail.1,v 4.4.1.1 1991/09/25 19:36:48 sob Exp sob $
  625. +.\" $Id: Rnmail.1,v 4.4.3.1 1992/02/01 03:17:20 sob PATCH_3 sob $
  626.  .\" 
  627.  .\" $Log: Rnmail.1,v $
  628. +.\" Revision 4.4.3.1  1992/02/01  03:17:20  sob
  629. +.\" Version 4.4 Patchlevel 3
  630. +.\"
  631.  .\" Revision 4.4.1.1  1991/09/25  19:36:48  sob
  632.  .\" Changed quote macro to "standard" one
  633. Index:Rnmail.SH
  634. @@ -5,7 +5,13 @@
  635.  $spitshell >Rnmail <<!GROK!THIS!
  636.  $startsh
  637. -# $Id: Rnmail.SH,v 4.4 1991/09/09 20:18:23 sob Exp sob $
  638. +# $Id: Rnmail.SH,v 4.4.4.1 1992/02/23 21:25:39 sob PATCH_4 sob $
  639.  # 
  640.  # $Log: Rnmail.SH,v $
  641. +# Revision 4.4.4.1  1992/02/23  21:25:39  sob
  642. +# Patch level 4
  643. +#
  644. +# Revision 4.4.3.1  1992/02/01  03:09:32  sob
  645. +# Release 4.4 Patchlevel 3
  646. +#
  647.  # Revision 4.4  1991/09/09  20:18:23  sob
  648.  # release 4.4
  649. @@ -325,5 +331,5 @@
  650.          set X ${USER-${LOGNAME-`who am i`}} unknown
  651.          shift
  652. -        $rnlib/mbox.saver $tmpart "." "." 0 0 Pnews $MAILRECORD "From $1 `date`"
  653. +        $rnlib/mbox.saver $tmpart "." "." 0 0 Pnews $MAILRECORD "From $1 `LANG= date`"
  654.          if $test $? -eq 0 ; then
  655.          $echo "Message appended to $MAILRECORD"
  656. Index:addng.c
  657. @@ -1,5 +1,8 @@
  658. -/* $Id: addng.c,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
  659. +/* $Id: addng.c,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  660.   *
  661.   * $Log: addng.c,v $
  662. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  663. + * Release 4.4 Patchlevel 3
  664. + *
  665.   * Revision 4.4.2.1  1991/12/01  18:05:42  sob
  666.   * Patchlevel 2 changes
  667. @@ -39,11 +42,4 @@
  668.  #include "INTERN.h"
  669.  #include "addng.h"
  670. -
  671. -#ifdef TZSET
  672. -#include <time.h>
  673. -#else
  674. -#include <sys/time.h>
  675. -#include <sys/timeb.h>
  676. -#endif
  677.  
  678.  void
  679. Index:addng.h
  680. @@ -1,5 +1,8 @@
  681. -/* $Id: addng.h,v 4.4 1991/09/09 20:18:23 sob Exp sob $
  682. +/* $Id: addng.h,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  683.   *
  684.   * $Log: addng.h,v $
  685. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  686. + * Release 4.4 Patchlevel 3
  687. + *
  688.   * Revision 4.4  1991/09/09  20:18:23  sob
  689.   * release 4.4
  690. Index:art.c
  691. @@ -1,3 +1,3 @@
  692. -/* $Id: art.c,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
  693. +/* $Id: art.c,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  694.   *
  695.   *
  696. @@ -508,14 +508,18 @@
  697.  #endif
  698.              {
  699. -                putchar('^');
  700. -                if (highlight == artline && *UC && marking == 1) {
  701. -                backspace();
  702. -                underchar();
  703. -                putchar(*bufptr+64);
  704. -                backspace();
  705. -                underchar();
  706. +                if (dont_filter_control)
  707. +                putchar(*bufptr);
  708. +                else {
  709. +                putchar('^');
  710. +                if (highlight == artline && *UC && marking == 1) {
  711. +                    backspace();
  712. +                    underchar();
  713. +                    putchar(*bufptr+64);
  714. +                    backspace();
  715. +                    underchar();
  716. +                }
  717. +                else
  718. +                    putchar(*bufptr+64);
  719.                  }
  720. -                else
  721. -                putchar(*bufptr+64);
  722.              }
  723.              bufptr++;
  724. @@ -875,4 +879,5 @@
  725.      case '[':    case ']':
  726.      case '{':    case '}':
  727. +    case '(':   case ')':
  728.      case '+':   case ':':
  729.  #endif
  730. @@ -905,5 +910,5 @@
  731.  #endif
  732.      case Ctl('x'):
  733. -    case 'z':
  734. +    case 'z':    case 'Z':
  735.      case '^':
  736.  
  737. Index:artio.c
  738. @@ -1,5 +1,8 @@
  739. -/* $Id: artio.c,v 4.4 1991/09/09 20:18:23 sob Exp sob $
  740. +/* $Id: artio.c,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  741.   *
  742.   * $Log: artio.c,v $
  743. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  744. + * Release 4.4 Patchlevel 3
  745. + *
  746.   * Revision 4.4  1991/09/09  20:18:23  sob
  747.   * release 4.4
  748. Index:artsrch.c
  749. @@ -1,5 +1,8 @@
  750. -/* $Id: artsrch.c,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
  751. +/* $Id: artsrch.c,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  752.   *
  753.   * $Log: artsrch.c,v $
  754. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  755. + * Release 4.4 Patchlevel 3
  756. + *
  757.   * Revision 4.4.2.1  1991/12/01  18:05:42  sob
  758.   * Patchlevel 2 changes
  759. @@ -296,7 +299,6 @@
  760.      
  761.  #ifdef USETHREADS
  762. -    if (ThreadedGroup)
  763. +    if (ThreadedGroup) {
  764.          find_article(art);
  765. -    if (p_art) {
  766.          if (mode != 't')
  767.          strcpy(subj_buf, "Subject: ");
  768. @@ -303,6 +305,9 @@
  769.          else
  770.          *subj_buf = '\0';
  771. -        if (p_art->subject != -1)
  772. +        if (p_art && p_art->subject != -1) {
  773. +        if (!(p_art->flags & ROOT_ARTICLE))
  774. +            strcat(subj_buf,"Re: ");
  775.          strcat(subj_buf,subject_ptrs[p_art->subject]);
  776. +        }
  777.      }
  778.      else
  779. Index:artsrch.h
  780. @@ -1,5 +1,8 @@
  781. -/* $Id: artsrch.h,v 4.4 1991/09/09 20:18:23 sob Exp sob $
  782. +/* $Id: artsrch.h,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  783.   *
  784.   * $Log: artsrch.h,v $
  785. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  786. + * Release 4.4 Patchlevel 3
  787. + *
  788.   * Revision 4.4  1991/09/09  20:18:23  sob
  789.   * release 4.4
  790. Index:autosub.c
  791. @@ -1,6 +1,9 @@
  792.  /*
  793. - * $Id: autosub.c,v 4.4 1991/09/09 20:18:23 sob Exp sob $
  794. + * $Id: autosub.c,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  795.   *
  796.   * $Log: autosub.c,v $
  797. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  798. + * Release 4.4 Patchlevel 3
  799. + *
  800.   * Revision 4.4  1991/09/09  20:18:23  sob
  801.   * release 4.4
  802. Index:bits.c
  803. @@ -1,5 +1,8 @@
  804. -/* $Id: bits.c,v 4.4 1991/09/09 20:18:23 sob Exp sob $
  805. +/* $Id: bits.c,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  806.   *
  807.   * $Log: bits.c,v $
  808. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  809. + * Release 4.4 Patchlevel 3
  810. + *
  811.   * Revision 4.4  1991/09/09  20:18:23  sob
  812.   * release 4.4
  813. Index:cheat.c
  814. @@ -1,5 +1,8 @@
  815. -/* $Id: cheat.c,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
  816. +/* $Id: cheat.c,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  817.   *
  818.   * $Log: cheat.c,v $
  819. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  820. + * Release 4.4 Patchlevel 3
  821. + *
  822.   * Revision 4.4.2.1  1991/12/01  18:05:42  sob
  823.   * Patchlevel 2 changes
  824. @@ -29,4 +32,5 @@
  825.  #include "search.h"
  826.  #include "ng.h"
  827. +#include "ngdata.h"
  828.  #include "bits.h"
  829.  #include "artio.h"
  830. @@ -34,4 +38,8 @@
  831.  #include "artsrch.h"
  832.  #include "head.h"
  833. +#ifdef USETHREADS
  834. +#include "threads.h"
  835. +#include "rthreads.h"
  836. +#endif
  837.  #include "INTERN.h"
  838.  #include "cheat.h"
  839. @@ -64,4 +72,23 @@
  840.      }
  841.  #endif
  842. +#endif
  843. +
  844. +#ifdef USETHREADS
  845. +    if (ThreadedGroup) {
  846. +    int save_art = art;
  847. +    PACKED_ARTICLE *save_p_art = p_art;
  848. +
  849. +    follow_thread('n');
  850. +#ifdef SERVER
  851. +    nntpopen(art,GET_HEADER);
  852. +#else
  853. +    artopen(art);
  854. +#endif
  855. +        art = save_art;
  856. +    p_art = save_p_art;
  857. +    }
  858. +    else
  859. +#endif /* USETHREADS */
  860. +#ifdef ARTSEARCH
  861.      if (srchahead && srchahead < art) {    /* in ^N mode? */
  862.      char *pattern;
  863. @@ -123,5 +150,5 @@
  864.      }
  865.      else
  866. -#endif
  867. +#endif /* ARTSEARCH */
  868.      {
  869.      if (art+1 <= lastart)/* how about a pre-fetch? */
  870. @@ -133,5 +160,5 @@
  871.      }
  872.  }
  873. -#endif
  874. +#endif /* PENDING */
  875.  
  876.  /* see what else we can do while they are reading */
  877. @@ -147,4 +174,8 @@
  878.      if (!in_ng || !srchahead)
  879.      return;
  880. +#ifdef USETHREADS
  881. +    if (ThreadedGroup)
  882. +    return;
  883. +#endif
  884.      if (oldart)            /* remember where we were in art */
  885.      oldartpos = ftell(artfp);
  886. Index:common.h
  887. @@ -1,5 +1,11 @@
  888. -/* $Id: common.h,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
  889. +/* $Id: common.h,v 4.4.4.1 1992/02/23 21:25:39 sob PATCH_4 sob $
  890.   * 
  891.   * $Log: common.h,v $
  892. + * Revision 4.4.4.1  1992/02/23  21:25:39  sob
  893. + * Patch level 4
  894. + *
  895. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  896. + * Release 4.4 Patchlevel 3
  897. + *
  898.   * Revision 4.4.2.1  1991/12/01  18:05:42  sob
  899.   * Patchlevel 2 changes
  900. @@ -69,4 +75,11 @@
  901.  #endif
  902.  
  903. +#ifdef TZSET
  904. +# include <time.h>
  905. +#else
  906. +# include <sys/time.h>
  907. +# include <sys/timeb.h>
  908. +#endif
  909. +
  910.  #define BITSPERBYTE 8
  911.  #ifdef pdp11
  912. @@ -456,5 +469,5 @@
  913.  /* default characters to use in the selection menu */
  914.  #ifndef SELECTCHARS
  915. -#   define SELECTCHARS "abcdefgijlorstuvwxz1234567890"
  916. +#   define SELECTCHARS "abdefgijlorstuvwxz1234567890"
  917.  #endif
  918.  
  919. @@ -638,15 +651,7 @@
  920.  #ifndef NEWSHEADER        /* % */
  921.  #   ifdef CONDSUB
  922. -#ifdef INTERNET
  923. -#    define NEWSHEADER "Newsgroups: %(%F=^$?%C:%F)\nSubject: %(%S=^$?%\"\n\nSubject: \":Re: %S)\nSummary: \nExpires: \n%(%R=^$?:References: %R\n)Sender: \nFollowup-To: \nDistribution: %(%i=^$?%\"Distribution: \":%D)\nOrganization: %o\nKeywords: %[keywords]\n\n"
  924. -#else
  925.  #    define NEWSHEADER "Newsgroups: %(%F=^$?%C:%F)\nSubject: %(%S=^$?%\"\n\nSubject: \":Re: %S)\nSummary: \nExpires: \n%(%R=^$?:References: %R\n)Sender: \nFollowup-To: \nDistribution: %(%i=^$?%\"Distribution: \":%D)\nOrganization: %o\nKeywords: %[keywords]\n\n"
  926. -#endif
  927.  #   else
  928. -#    ifdef INTERNET
  929. -#        define NEWSHEADER "Newsgroups: %F\nSubject: Re: %S\nSummary: \nExpires: \nReferences: %R\nSender: \nFollowup-To: \nDistribution: %D\nOrganization: %o\nKeywords: %[keywords]\n\n"
  930. -#    else
  931. -#        define NEWSHEADER "Newsgroups: %F\nSubject: Re: %S\nSummary: \nExpires: \nReferences: %R\nSender: \nFollowup-To: \nDistribution: %D\nOrganization: %o\nKeywords: %[keywords]\n\n"
  932. -#    endif
  933. +#    define NEWSHEADER "Newsgroups: %F\nSubject: Re: %S\nSummary: \nExpires: \nReferences: %R\nSender: \nFollowup-To: \nDistribution: %D\nOrganization: %o\nKeywords: %[keywords]\n\n"
  934.  #   endif
  935.  #endif
  936. @@ -691,7 +696,7 @@
  937.  #   ifdef MININACT        /* 2.10.2 site? */
  938.  #       ifdef SERVER
  939. -#           define MBOXSAVER "%X/mbox.saver %P/rrn%a.%$ %P %c %a %B %C \"%b\" \"From %T %`date`\""
  940. +#           define MBOXSAVER "%X/mbox.saver %P/rrn%a.%$ %P %c %a %B %C \"%b\" \"From %T %`LANG= date`\""
  941.  #       else
  942. -#        define MBOXSAVER "%X/mbox.saver %A %P %c %a %B %C \"%b\" \"From %T %`date`\""
  943. +#        define MBOXSAVER "%X/mbox.saver %A %P %c %a %B %C \"%b\" \"From %T %`LANG= date`\""
  944.  #    endif
  945.  #   else
  946. @@ -752,18 +757,10 @@
  947.  /* how to cancel an article, continued */
  948.  #ifndef CANCELHEADER
  949. -#ifdef INTERNET
  950. -#   define CANCELHEADER "From: %L@%H (%N)\nNewsgroups: %n\nSubject: cmsg cancel %i\nReferences: %R\nDistribution: %D\nOrganization: %o\n\n%i was cancelled from within trn.\n"
  951. -#else
  952. -#   define CANCELHEADER "From:%L@%H.UUCP (%N)\nNewsgroups: %n\nSubject: cmsg cancel %i\nReferences: %R\nDistribution: %D\nOrganization: %o\n\n%i was cancelled from within trn.\n"
  953. +#   define CANCELHEADER "Newsgroups: %n\nSubject: cmsg cancel %i\nReferences: %R\nDistribution: %D\nOrganization: %o\n\n%i was cancelled from within trn.\n"
  954.  #endif
  955. -#endif
  956.  
  957.  /* how to supersede an article */
  958.  #ifndef SUPERSEDEHEADER
  959. -#ifdef INTERNET
  960. -#   define SUPERSEDEHEADER "From: %L@%H (%N)\nNewsgroups: %n\nSupersedes: %i\nSubject: %S\nDistribution: %D\nOrganization: %o\n"
  961. -#else
  962. -#   define SUPERSEDEHEADER "From:%L@%H.UUCP (%N)\nNewsgroups: %n\nSupersedes: %i\nSubject: %S\nDistribution: %D\nOrganization: %o\n"
  963. -#endif
  964. +#    define SUPERSEDEHEADER "Newsgroups: %n\nSubject: %S\nSummary: %[summary]\nExpires: %[expires]\nReferences: %[references]\nSupersedes: %i\nSender: %[sender]\nFollowup-To: %[followup-to]\nDistribution: %D\nOrganization: %o\nKeywords: %[keywords]\n\n"
  965.  #endif
  966.  
  967. @@ -874,9 +871,11 @@
  968.  #endif
  969.  
  970. +EXT bool dont_filter_control INIT(FALSE);        /* -j */
  971.  EXT bool mbox_always INIT(FALSE);            /* -M */
  972.  EXT bool norm_always INIT(FALSE);            /* -N */
  973.  EXT bool thread_always INIT(FALSE);            /* -a */
  974. +EXT bool breadth_first INIT(FALSE);            /* -b */
  975.  EXT bool olden_days INIT(FALSE);            /* -o */
  976. -EXT bool checkflag INIT(FALSE);            /* -c */
  977. +EXT bool checkflag INIT(FALSE);                /* -c */
  978.  EXT bool suppress_cn INIT(FALSE);            /* -s */
  979.  EXT int countdown INIT(5);    /* how many lines to list before invoking -s */
  980. Index:config.h.SH
  981. @@ -35,7 +35,10 @@
  982.   * that running config.h.SH again will wipe out any changes you've made.
  983.   * For a more permanent change edit config.sh and rerun config.h.SH.
  984. - * $Id: config.h.SH,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
  985. + * $Id: config.h.SH,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  986.   *
  987.   * $Log: config.h.SH,v $
  988. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  989. + *Release 4.4 Patchlevel 3
  990. + *
  991.   * Revision 4.4.2.1  1991/12/01  18:05:42  sob
  992.   * Fixed problems with CTRLA flag.
  993. @@ -193,3 +196,4 @@
  994.  #$syslog2 USESYSLOG $syslog    /* use syslog for mthreads' log messages */
  995.  #$xthread XTHREAD     /* get thread files via NNTP */
  996. +#$haveinn HAVE_INN     /* are we running inn? */
  997.  EOT
  998. Index:final.c
  999. @@ -1,5 +1,8 @@
  1000. -/* $Id: final.c,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
  1001. +/* $Id: final.c,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  1002.   *
  1003.   * $Log: final.c,v $
  1004. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  1005. + * Release 4.4 Patchlevel 3
  1006. + *
  1007.   * Revision 4.4.2.1  1991/12/01  18:05:42  sob
  1008.   * Patchlevel 2 changes
  1009. @@ -35,4 +38,5 @@
  1010.  #include "ngdata.h"
  1011.  #include "artio.h"
  1012. +#include "intrp.h"
  1013.  #ifdef SERVER
  1014.  #include "server.h"
  1015. @@ -41,4 +45,8 @@
  1016.  #include "final.h"
  1017.  
  1018. +#ifndef sigmask
  1019. +#define sigmask(m)    (1 << ((m)-1))
  1020. +#endif
  1021. +
  1022.  void
  1023.  final_init()
  1024. @@ -112,4 +120,7 @@
  1025.      chdir("/usr/tmp");
  1026.      sigset(SIGILL,SIG_DFL);
  1027. +#ifdef SIGBLOCK
  1028. +    sigsetmask(sigblock(0) & ~(sigmask(SIGILL) | sigmask(SIGIOT)));
  1029. +#endif
  1030.      abort();
  1031.      }
  1032. @@ -186,6 +197,10 @@
  1033.      }
  1034.  #endif
  1035. -    if (panic)
  1036. +    if (panic) {
  1037. +#ifdef SIGBLOCK
  1038. +      sigsetmask(sigblock(0) & ~(sigmask(SIGILL) | sigmask(SIGIOT)));
  1039. +#endif
  1040.      abort();
  1041. +      }
  1042.      (void) sigset(SIGILL,SIG_DFL);
  1043.      panic = TRUE;            /* disable terminal I/O */
  1044. Index:final.h
  1045. @@ -1,5 +1,8 @@
  1046. -/* $Id: final.h,v 4.4 1991/09/09 20:18:23 sob Exp sob $
  1047. +/* $Id: final.h,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  1048.   * 
  1049.   * $Log: final.h,v $
  1050. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  1051. + * Release 4.4 Patchlevel 3
  1052. + *
  1053.   * Revision 4.4  1991/09/09  20:18:23  sob
  1054.   * release 4.4
  1055. Index:hdbm.c
  1056. @@ -0,0 +1,305 @@
  1057. +/*
  1058. + * Copyright (c) 1992 Geoffrey Collyer
  1059. + * All rights reserved.
  1060. + * Written by Geoffrey Collyer.
  1061. + *
  1062. + * This software is not subject to any license of the American Telephone
  1063. + * and Telegraph Company, the Regents of the University of California, or
  1064. + * the Free Software Foundation.
  1065. + *
  1066. + * Permission is granted to anyone to use this software for any purpose on
  1067. + * any computer system, and to alter it and redistribute it freely, subject
  1068. + * to the following restrictions:
  1069. + *
  1070. + * 1. The author is not responsible for the consequences of use of this
  1071. + *    software, no matter how awful, even if they arise from flaws in it.
  1072. + *
  1073. + * 2. The origin of this software must not be misrepresented, either by
  1074. + *    explicit claim or by omission.  Since few users ever read sources,
  1075. + *    credits must appear in the documentation.
  1076. + *
  1077. + * 3. Altered versions must be plainly marked as such, and must not be
  1078. + *    misrepresented as being the original software.  Since few users
  1079. + *    ever read sources, credits must appear in the documentation.
  1080. + *
  1081. + * 4. This notice may not be removed or altered.
  1082. + */
  1083. +/*
  1084. + * general-purpose in-core hashing, dbm interface
  1085. + */
  1086. +
  1087. +#include <stdio.h>
  1088. +#include <stdlib.h>
  1089. +#include <string.h>
  1090. +#include "hdbm.h"
  1091. +#include "hdbmint.h"
  1092. +
  1093. +/* tunable parameters */
  1094. +#define RETAIN 300        /* retain & recycle this many HASHENTs */
  1095. +
  1096. +/* fundamental constants */
  1097. +#define YES 1
  1098. +#define NO 0
  1099. +
  1100. +static HASHENT *hereuse = NULL;
  1101. +static int reusables = 0;
  1102. +
  1103. +static hefree();
  1104. +
  1105. +
  1106. +static unsigned                /* not yet taken modulus table size */
  1107. +hdbmdef(key)
  1108. +HDBMDATUM key;
  1109. +{
  1110. +    register char *s = key.dat_ptr;
  1111. +    register unsigned len = key.dat_len;
  1112. +    register unsigned hash = 0;
  1113. +
  1114. +    while (len-- > 0)
  1115. +        hash += *s++;
  1116. +    return hash;
  1117. +}
  1118. +
  1119. +HASHTABLE *
  1120. +hdbmcreate(size, hashfunc)
  1121. +register unsigned size;            /* a crude guide to size */
  1122. +unsigned (*hashfunc)();
  1123. +{
  1124. +    register HASHTABLE *tbl;
  1125. +    register HASHENT **hepp;
  1126. +    /*
  1127. +     * allocate HASHTABLE and (HASHENT *) array together to reduce the
  1128. +     * number of malloc calls.  this idiom ensures correct alignment of
  1129. +     * the array.
  1130. +     * dmr calls the one-element array trick `unwarranted chumminess with
  1131. +     * the compiler' though.
  1132. +     */
  1133. +    register struct alignalloc {
  1134. +        HASHTABLE ht;
  1135. +        HASHENT *hepa[1];    /* longer than it looks */
  1136. +    } *aap;
  1137. +
  1138. +    aap = (struct alignalloc *)
  1139. +        malloc(sizeof *aap + (size-1)*sizeof(HASHENT *));
  1140. +    if (aap == NULL)
  1141. +        return NULL;
  1142. +    tbl = &aap->ht;
  1143. +    tbl->ht_size = (size == 0? 1: size);    /* size of 0 is nonsense */
  1144. +    tbl->ht_magic = HASHMAG;
  1145. +    tbl->ht_hash = (hashfunc == NULL? hdbmdef: hashfunc);
  1146. +    tbl->ht_addr = hepp = aap->hepa;
  1147. +    while (size-- > 0)
  1148. +        hepp[size] = NULL;
  1149. +    return tbl;
  1150. +}
  1151. +
  1152. +/*
  1153. + * free all the memory associated with tbl, erase the pointers to it, and
  1154. + * invalidate tbl to prevent further use via other pointers to it.
  1155. + */
  1156. +hdbmdestroy(tbl)
  1157. +register HASHTABLE *tbl;
  1158. +{
  1159. +    register unsigned idx;
  1160. +    register HASHENT *hp, *next;
  1161. +    register HASHENT **hepp;
  1162. +    register int tblsize;
  1163. +
  1164. +    if (tbl == NULL || BADTBL(tbl))
  1165. +        return;
  1166. +    tblsize = tbl->ht_size;
  1167. +    hepp = tbl->ht_addr;
  1168. +    for (idx = 0; idx < tblsize; idx++) {
  1169. +        for (hp = hepp[idx]; hp != NULL; hp = next) {
  1170. +            next = hp->he_next;
  1171. +            hp->he_next = NULL;
  1172. +            hefree(hp);
  1173. +        }
  1174. +        hepp[idx] = NULL;
  1175. +    }
  1176. +    tbl->ht_magic = 0;        /* de-certify this table */
  1177. +    tbl->ht_addr = NULL;
  1178. +    free((char *)tbl);
  1179. +}
  1180. +
  1181. +/*
  1182. + * The returned value is the address of the pointer that refers to the
  1183. + * found object.  Said pointer may be NULL if the object was not found;
  1184. + * if so, this pointer should be updated with the address of the object
  1185. + * to be inserted, if insertion is desired.
  1186. + */
  1187. +static HASHENT **
  1188. +hdbmfind(tbl, key)
  1189. +register HASHTABLE *tbl;
  1190. +HDBMDATUM key;
  1191. +{
  1192. +    register HASHENT *hp, *prevhp = NULL;
  1193. +    register char *hpkeydat, *keydat = key.dat_ptr;
  1194. +    register int keylen = key.dat_len;
  1195. +    register HASHENT **hepp;
  1196. +    register unsigned size; 
  1197. +
  1198. +    if (BADTBL(tbl))
  1199. +        return NULL;
  1200. +    size = tbl->ht_size;
  1201. +    if (size == 0)            /* paranoia: avoid division by zero */
  1202. +        size = 1;
  1203. +    hepp = &tbl->ht_addr[(*tbl->ht_hash)(key) % size];
  1204. +    for (hp = *hepp; hp != NULL; prevhp = hp, hp = hp->he_next) {
  1205. +        hpkeydat = hp->he_key.dat_ptr;
  1206. +        if (hp->he_key.dat_len == keylen && hpkeydat[0] == keydat[0] &&
  1207. +            memcmp(hpkeydat, keydat, keylen) == 0)
  1208. +            break;
  1209. +    }
  1210. +    /* assert: *(returned value) == hp */
  1211. +    return (prevhp == NULL? hepp: &prevhp->he_next);
  1212. +}
  1213. +
  1214. +static HASHENT *
  1215. +healloc()                    /* allocate a hash entry */
  1216. +{
  1217. +    register HASHENT *hp;
  1218. +
  1219. +    if (hereuse == NULL)
  1220. +        return (HASHENT *)malloc(sizeof(HASHENT));
  1221. +    /* pull the first reusable one off the pile */
  1222. +    hp = hereuse;
  1223. +    hereuse = hereuse->he_next;
  1224. +    hp->he_next = NULL;            /* prevent accidents */
  1225. +    reusables--;
  1226. +    return hp;
  1227. +}
  1228. +
  1229. +static
  1230. +hefree(hp)                    /* free a hash entry */
  1231. +register HASHENT *hp;
  1232. +{
  1233. +    if (reusables >= RETAIN)        /* compost heap is full? */
  1234. +        free((char *)hp);        /* yup, just pitch this one */
  1235. +    else {                    /* no, just stash for reuse */
  1236. +        ++reusables;
  1237. +        hp->he_next = hereuse;
  1238. +        hereuse = hp;
  1239. +    }
  1240. +}
  1241. +
  1242. +int
  1243. +hdbmstore(tbl, key, data)
  1244. +register HASHTABLE *tbl;
  1245. +HDBMDATUM key, data;
  1246. +{
  1247. +    register HASHENT *hp;
  1248. +    register HASHENT **nextp;
  1249. +
  1250. +    if (BADTBL(tbl))
  1251. +        return NO;
  1252. +    nextp = hdbmfind(tbl, key);
  1253. +    if (nextp == NULL)
  1254. +        return NO;
  1255. +    hp = *nextp;
  1256. +    if (hp == NULL) {            /* absent; allocate an entry */
  1257. +        hp = healloc();
  1258. +        if (hp == NULL)
  1259. +            return NO;
  1260. +        hp->he_next = NULL;
  1261. +        hp->he_key = key;
  1262. +        *nextp = hp;            /* append to hash chain */
  1263. +    }
  1264. +    hp->he_data = data;    /* supersede any old data for this key */
  1265. +    return YES;
  1266. +}
  1267. +
  1268. +/* return any existing entry for key; otherwise call allocator to make one */
  1269. +HDBMDATUM
  1270. +hdbmentry(tbl, key, allocator)
  1271. +register HASHTABLE *tbl;
  1272. +HDBMDATUM key;
  1273. +HDBMDATUM (*allocator)();
  1274. +{
  1275. +    register HASHENT *hp;
  1276. +    register HASHENT **nextp;
  1277. +    static HDBMDATUM errdatum = { NULL, 0 };
  1278. +
  1279. +    if (BADTBL(tbl))
  1280. +        return errdatum;
  1281. +    nextp = hdbmfind(tbl, key);
  1282. +    if (nextp == NULL)
  1283. +        return errdatum;
  1284. +    hp = *nextp;
  1285. +    if (hp == NULL) {            /* absent; allocate an entry */
  1286. +        hp = healloc();
  1287. +        if (hp == NULL)
  1288. +            return errdatum;
  1289. +        hp->he_next = NULL;
  1290. +        hp->he_key = key;
  1291. +        hp->he_data = (*allocator)(key);
  1292. +        *nextp = hp;            /* append to hash chain */
  1293. +    }
  1294. +    return hp->he_data;
  1295. +}
  1296. +
  1297. +int
  1298. +hdbmdelete(tbl, key)
  1299. +register HASHTABLE *tbl;
  1300. +HDBMDATUM key;
  1301. +{
  1302. +    register HASHENT *hp;
  1303. +    register HASHENT **nextp;
  1304. +
  1305. +    nextp = hdbmfind(tbl, key);
  1306. +    if (nextp == NULL)
  1307. +        return NO;
  1308. +    hp = *nextp;
  1309. +    if (hp == NULL)                /* absent */
  1310. +        return NO;
  1311. +    *nextp = hp->he_next;            /* skip this entry */
  1312. +    hp->he_next = NULL;
  1313. +    hp->he_data.dat_ptr = hp->he_key.dat_ptr = NULL;
  1314. +    hefree(hp);
  1315. +    return YES;
  1316. +}
  1317. +
  1318. +HDBMDATUM                    /* data corresponding to key */
  1319. +hdbmfetch(tbl, key)
  1320. +register HASHTABLE *tbl;
  1321. +HDBMDATUM key;
  1322. +{
  1323. +    register HASHENT *hp;
  1324. +    register HASHENT **nextp;
  1325. +    static HDBMDATUM errdatum = { NULL, 0 };
  1326. +
  1327. +    if (BADTBL(tbl))
  1328. +        return errdatum;
  1329. +    nextp = hdbmfind(tbl, key);
  1330. +    if (nextp == NULL)
  1331. +        return errdatum;
  1332. +    hp = *nextp;
  1333. +    if (hp == NULL)                /* absent */
  1334. +        return errdatum;
  1335. +    else
  1336. +        return hp->he_data;
  1337. +}
  1338. +
  1339. +/*
  1340. + * visit each entry by calling nodefunc at each, with key, data and hook as
  1341. + * arguments.  hook is an attempt to allow side-effects and reentrancy at
  1342. + * the same time.
  1343. + */
  1344. +hdbmwalk(tbl, nodefunc, hook)
  1345. +HASHTABLE *tbl;
  1346. +register int (*nodefunc)();
  1347. +register char *hook;                /* (void *) really */
  1348. +{
  1349. +    register unsigned idx;
  1350. +    register HASHENT *hp;
  1351. +    register HASHENT **hepp;
  1352. +    register int tblsize;
  1353. +
  1354. +    if (BADTBL(tbl))
  1355. +        return;
  1356. +    hepp = tbl->ht_addr;
  1357. +    tblsize = tbl->ht_size;
  1358. +    for (idx = 0; idx < tblsize; idx++)
  1359. +        for (hp = hepp[idx]; hp != NULL; hp = hp->he_next)
  1360. +            (*nodefunc)(hp->he_key, hp->he_data, hook);
  1361. +}
  1362. Index:hdbm.h
  1363. @@ -0,0 +1,18 @@
  1364. +/*
  1365. + * general-purpose in-core hashing, dbm interface
  1366. + */
  1367. +
  1368. +#define HDBMDATUM struct hdbmdatum
  1369. +HDBMDATUM {
  1370. +    char    *dat_ptr;
  1371. +    unsigned dat_len;
  1372. +};
  1373. +
  1374. +#ifndef HASHTABLE
  1375. +#define HASHTABLE struct hashtable
  1376. +#endif
  1377. +
  1378. +extern HASHTABLE *hdbmcreate();
  1379. +extern hdbmdestroy(), hdbmwalk();
  1380. +extern int hdbmstore(), hdbmdelete();
  1381. +extern HDBMDATUM hdbmfetch(), hdbmentry();
  1382. Index:hdbmint.h
  1383. @@ -0,0 +1,25 @@
  1384. +/*
  1385. + * general-purpose in-core hashing, dbm interface (internals)
  1386. + */
  1387. +
  1388. +#define    STREQ(a, b)    (*(a) == *(b) && strcmp((a), (b)) == 0)
  1389. +
  1390. +#define BADTBL(tbl)    (((tbl)->ht_magic&BYTEMASK) != HASHMAG)
  1391. +
  1392. +#define HASHMAG  0257
  1393. +#define BYTEMASK 0377
  1394. +
  1395. +#define HASHENT struct hashent
  1396. +
  1397. +HASHENT {
  1398. +    HASHENT    *he_next;        /* in hash chain */
  1399. +    HDBMDATUM he_key;        /* to verify a match */
  1400. +    HDBMDATUM he_data;
  1401. +};
  1402. +
  1403. +HASHTABLE {
  1404. +    HASHENT **ht_addr;        /* array of HASHENT pointers */
  1405. +    unsigned ht_size;
  1406. +    char    ht_magic;
  1407. +    unsigned (*ht_hash)();
  1408. +};
  1409. Index:head.c
  1410. @@ -1,5 +1,11 @@
  1411. -/* $Id: head.c,v 4.4 1991/09/09 20:18:23 sob Exp sob $
  1412. +/* $Id: head.c,v 4.4.4.1 1992/02/23 21:25:39 sob PATCH_4 sob $
  1413.   *
  1414.   * $Log: head.c,v $
  1415. + * Revision 4.4.4.1  1992/02/23  21:25:39  sob
  1416. + * Patch level 4
  1417. + *
  1418. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  1419. + * Release 4.4 Patchlevel 3
  1420. + *
  1421.   * Revision 4.4  1991/09/09  20:18:23  sob
  1422.   * release 4.4
  1423. @@ -171,4 +177,6 @@
  1424.      if (parsed_art == artnum)
  1425.      return 0;
  1426. +    if (artnum > lastart)
  1427. +    return -1;
  1428.      /* no maybe about it now */
  1429.  #ifdef SERVER
  1430. @@ -217,5 +225,5 @@
  1431.          subj_list[i] = Nullch;
  1432.      }
  1433. -    if (!artnum || artnum > lastart)
  1434. +    if (artnum < absfirst || artnum > lastart)
  1435.      s = nullstr;
  1436.      else
  1437. Index:head.h
  1438. @@ -1,5 +1,8 @@
  1439. -/* $Id: head.h,v 4.4 1991/09/09 20:18:23 sob Exp sob $
  1440. +/* $Id: head.h,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  1441.   *
  1442.   * $Log: head.h,v $
  1443. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  1444. + * Release 4.4 Patchlevel 3
  1445. + *
  1446.   * Revision 4.4  1991/09/09  20:18:23  sob
  1447.   * release 4.4
  1448. Index:help.c
  1449. @@ -1,5 +1,8 @@
  1450. -/* $Id: help.c,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
  1451. +/* $Id: help.c,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  1452.   *
  1453.   * $Log: help.c,v $
  1454. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  1455. + * Release 4.4 Patchlevel 3
  1456. + *
  1457.   * Revision 4.4.2.1  1991/12/01  18:05:42  sob
  1458.   * Patchlevel 2 changes
  1459. @@ -91,4 +94,5 @@
  1460.      selected for browsing.  Entering an empty group browses all threads.\n\
  1461.  [,],{,} Go to parent/child/root/leaf in thread.\n\
  1462. +(,)    Go to article's previous/next sibling.\n\
  1463.  \n\
  1464.  ",NOMARKING)) ||
  1465. @@ -149,4 +153,5 @@
  1466.  [,]    Go to article's parent/child.\n\
  1467.  {,}    Go to tree's root/leaf.\n\
  1468. +(,)    Go to article's previous/next sibling.\n\
  1469.  t    Display the entire article tree and all its subjects.\n\
  1470.  ",NOMARKING)) ||
  1471. @@ -474,4 +479,5 @@
  1472.      reading if articles were selected, else go to next page.\n\
  1473.  J    Junk all selected articles (mark them as read).\n\
  1474. +c    Catch up -- marks ALL articles as read without chasing xrefs.\n\
  1475.  ^K    Edit local KILL file (the one for this newsgroup).\n\
  1476.  :cmd    Perform a command on all the selected articles.\n\
  1477. Index:init.c
  1478. @@ -1,5 +1,8 @@
  1479. -/* $Id: init.c,v 4.4 1991/09/09 20:18:23 sob Exp sob $
  1480. +/* $Id: init.c,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  1481.   *
  1482.   * $Log: init.c,v $
  1483. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  1484. + * Release 4.4 Patchlevel 3
  1485. + *
  1486.   * Revision 4.4  1991/09/09  20:18:23  sob
  1487.   * release 4.4
  1488. Index:intrp.c
  1489. @@ -1,5 +1,8 @@
  1490. -/* $Id: intrp.c,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
  1491. +/* $Id: intrp.c,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  1492.   *
  1493.   * $Log: intrp.c,v $
  1494. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  1495. + * Release 4.4 Patchlevel 3
  1496. + *
  1497.   * Revision 4.4.2.1  1991/12/01  18:05:42  sob
  1498.   * Patchlevel 2 changes
  1499. @@ -91,10 +94,4 @@
  1500.  {
  1501.      char *getlogin();
  1502. -
  1503. -    spool = savestr(filexp(SPOOL));    /* usually /usr/spool/news */
  1504. -#ifdef USETHREADS
  1505. -    mtlib = savestr(filexp(MTLIB));
  1506. -    threaddir = savestr(filexp(THREAD_DIR));
  1507. -#endif
  1508.      
  1509.      /* get environmental stuff */
  1510. @@ -136,4 +133,10 @@
  1511.      if (logname == Nullch)
  1512.      logname = savestr(getlogin());
  1513. +#endif
  1514. +
  1515. +    spool = savestr(filexp(SPOOL));    /* usually /usr/spool/news */
  1516. +#ifdef USETHREADS
  1517. +    mtlib = savestr(filexp(MTLIB));
  1518. +    threaddir = savestr(filexp(THREAD_DIR));
  1519.  #endif
  1520.  
  1521. Index:intrp.h
  1522. @@ -1,5 +1,8 @@
  1523. -/* $Id: intrp.h,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
  1524. +/* $Id: intrp.h,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  1525.   *
  1526.   * $Log: intrp.h,v $
  1527. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  1528. + * Release 4.4 Patchlevel 3
  1529. + *
  1530.   * Revision 4.4.2.1  1991/12/01  18:05:42  sob
  1531.   * Patchlevel 2 changes
  1532. Index:kfile.c
  1533. @@ -143,5 +143,5 @@
  1534.          break;
  1535.          case SRCH_SUBJDONE:
  1536. -        fputs("\tsubject not found (???)\n",stdout) FLUSH;
  1537. +        fputs("\tsubject not found (?)\n",stdout) FLUSH;
  1538.          break;
  1539.          case SRCH_NOTFOUND:
  1540. Index:last.c
  1541. @@ -1,5 +1,8 @@
  1542. -/* $Id: last.c,v 4.4 1991/09/09 20:23:31 sob Exp sob $
  1543. +/* $Id: last.c,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  1544.   *
  1545.   * $Log: last.c,v $
  1546. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  1547. + * Release 4.4 Patchlevel 3
  1548. + *
  1549.   * Revision 4.4  1991/09/09  20:23:31  sob
  1550.   * release 4.4
  1551. Index:last.h
  1552. @@ -1,5 +1,8 @@
  1553. -/* $Id: last.h,v 4.4 1991/09/09 20:23:31 sob Exp sob $
  1554. +/* $Id: last.h,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  1555.   *
  1556.   * $Log: last.h,v $
  1557. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  1558. + * Release 4.4 Patchlevel 3
  1559. + *
  1560.   * Revision 4.4  1991/09/09  20:23:31  sob
  1561.   * release 4.4
  1562. Index:mt-lint.h
  1563. @@ -1,8 +1,4 @@
  1564. -/* $Id: mt-lint.h,v 4.4.3.1 1991/11/22 04:12:15 davison Trn $
  1565. +/* $Id: mt-lint.h,v 2.3 1992/12/14 00:14:01 davison Trn $
  1566.  **
  1567. -** $Log: mt-lint.h,v $
  1568. -** Revision 4.4.3.1  1991/11/22  04:12:15  davison
  1569. -** Trn Release 2.0
  1570. -** 
  1571.  ** Handle brain-dead lints that only have 6 significant-character names.
  1572.  */
  1573. Index:mt-misc.c
  1574. @@ -1,8 +1,3 @@
  1575. -/* $Id: mt-misc.c,v 4.4.3.1 1991/11/22 04:12:15 davison Trn $
  1576. -**
  1577. -** $Log: mt-misc.c,v $
  1578. -** Revision 4.4.3.1  1991/11/22  04:12:15  davison
  1579. -** Trn Release 2.0
  1580. -** 
  1581. +/* $Id: mt-misc.c,v 2.3 1992/12/14 00:14:02 davison Trn $
  1582.  */
  1583.  
  1584. @@ -160,4 +155,5 @@
  1585.          wrap_it_up(1);
  1586.      }
  1587. +    break;
  1588.      }
  1589.      default:            /* all "normal" names are relative to SPOOL */
  1590. Index:mt-process.c
  1591. @@ -1,8 +1,3 @@
  1592. -/* $Id: mt-process.c,v 4.4.3.1 1991/11/22 04:12:15 davison Trn $
  1593. -**
  1594. -** $Log: mt-process.c,v $
  1595. -** Revision 4.4.3.1  1991/11/22  04:12:15  davison
  1596. -** Trn Release 2.0
  1597. -** 
  1598. +/* $Id: mt-process.c,v 2.3 1992/12/14 00:14:03 davison Trn $
  1599.  */
  1600.  
  1601. @@ -18,13 +13,4 @@
  1602.  #include "bits.h"
  1603.  
  1604. -#include <time.h>
  1605. -#ifndef TZSET
  1606. -# include <sys/timeb.h>
  1607. -#endif
  1608. -
  1609. -#if defined(SERVER) && !defined(USLEEP)
  1610. -# include <sys/time.h>
  1611. -#endif
  1612. -
  1613.  #define buff buf
  1614.  
  1615. @@ -330,7 +316,29 @@
  1616.      /* List all articles and use ctl_set() to keep track of what's there. */
  1617.  #ifdef SERVER
  1618. -    sprintf(buff, "XHDR message-id %ld-%ld", (long)absfirst, (long)lastart);
  1619. -    put_server(buff);
  1620. -    if (get_server(buff, sizeof buff) == 0 && *buff == CHAR_OK) {
  1621. +    /* Try my after-market LISTGROUP command before trying XHDR. */
  1622. +    put_server("LISTGROUP");
  1623. +    if (get_server(buff, sizeof buff) != 0) {
  1624. +        *buff = CHAR_ERR;
  1625. +    }
  1626. +    /* If it was a command syntax error (not an unrecongnized command),
  1627. +    ** then they have the old LISTGROUP that requires a newsgroup name.
  1628. +    */
  1629. +    if (atoi(buff) == ERR_CMDSYN) {
  1630. +        extern char line[];
  1631. +        sprintf(buff, "LISTGROUP %s", line);
  1632. +        put_server(buff);
  1633. +        if (get_server(buff, sizeof buff) != 0) {
  1634. +        *buff = CHAR_ERR;
  1635. +        }
  1636. +    }
  1637. +    if (*buff != CHAR_OK) {
  1638. +        sprintf(buff, "XHDR message-id %ld-%ld",
  1639. +                (long)absfirst, (long)lastart);
  1640. +        put_server(buff);
  1641. +        if (get_server(buff, sizeof buff) != 0) {
  1642. +        *buff = CHAR_ERR;
  1643. +        }
  1644. +    }
  1645. +    if (*buff == CHAR_OK) {
  1646.          while (1) {
  1647.          if (get_server(buff, sizeof buff) < 0) {
  1648. @@ -535,5 +543,5 @@
  1649.  order_roots()
  1650.  {
  1651. -    register ROOT *root, *next, *search;
  1652. +    register ROOT *root, *next, *search, *link;
  1653.  
  1654.      /* If we don't have at least two roots, we're done! */
  1655. @@ -551,9 +559,11 @@
  1656.          root_root = root;
  1657.      } else {
  1658. -        while (search->link
  1659. -         && search->link->articles->date < root->articles->date) {
  1660. -        search = search->link;
  1661. +        register time_t radate = root->articles->date;
  1662. +
  1663. +        while ((link = search->link) != NULL
  1664. +         && link->articles->date < radate) {
  1665. +        search = link;
  1666.          }
  1667. -        root->link = search->link;
  1668. +        root->link = link;
  1669.          search->link = root;
  1670.      }
  1671. @@ -636,4 +646,337 @@
  1672.  }
  1673.  
  1674. +#ifndef OLD_AUTHOR_CODE
  1675. +/* Name-munging routines written by Ross Ridge.  Public Domain.
  1676. +** Enhanced by Wayne Davison.
  1677. +*/
  1678. +
  1679. +/* If necessary, compress a net user's full name by playing games with
  1680. +** initials and the middle name(s).  If we start with "Ross Douglas Ridge"
  1681. +** we try "Ross D Ridge", "Ross Ridge", "R D Ridge" and finally "R Ridge"
  1682. +** before simply truncating the thing.  We also turn "R. Douglas Ridge"
  1683. +** into "Douglas Ridge" if it fits, otherwise it goes through the normal
  1684. +** modification route.
  1685. +*/
  1686. +static char *
  1687. +compress_name(name, max)
  1688. +char *name;
  1689. +int max;
  1690. +{
  1691. +    register char *s, *last, *mid, *d;
  1692. +    register int len, namelen, midlen;
  1693. +    int notlast;
  1694. +
  1695. +    /* First remove white space from both ends. */
  1696. +    while (isspace(*name)) {
  1697. +    name++;
  1698. +    }
  1699. +    if ((len = strlen(name)) == 0) {
  1700. +    return name;
  1701. +    }
  1702. +    s = name + len - 1;
  1703. +    while (isspace(*s)) {
  1704. +    s--;
  1705. +    }
  1706. +    s[1] = '\0';
  1707. +    if (s - name + 1 <= max) {
  1708. +    return name;
  1709. +    }
  1710. +
  1711. +    /* Look for characters that likely mean the end of the name
  1712. +    ** and the start of some hopefully uninteresting additional info.
  1713. +    ** Spliting at a comma is somewhat questionalble, but since
  1714. +    ** "Ross Ridge, The Great HTMU" comes up much more often than 
  1715. +    ** "Ridge, Ross" and since "R HTMU" is worse than "Ridge" we do
  1716. +    ** it anyways.
  1717. +    */
  1718. +    for (d = name + 1; *d; d++) {
  1719. +    if (*d == ',' || *d == ';' || *d == '(' || *d == '@'
  1720. +     || (*d == '-' && (d[1] == '-' || d[1] == ' '))) {
  1721. +        *d-- = '\0';
  1722. +        s = d;
  1723. +        break;
  1724. +    }
  1725. +    }
  1726. +
  1727. +    /* Find the last name */
  1728. +    do {
  1729. +    notlast = 0;
  1730. +    while (isspace(*s)) {
  1731. +        s--;
  1732. +    }
  1733. +    s[1] = '\0';
  1734. +    len = s - name + 1;
  1735. +    if (len <= max) {
  1736. +        return name;
  1737. +    }
  1738. +    while (!isspace(*s)) {
  1739. +        if (s == name) {    /* only one name */
  1740. +        name[max] = '\0';
  1741. +        return name;
  1742. +        }
  1743. +        if (isdigit(*s)) {    /* probably a phone number */
  1744. +        notlast = 1;    /* so chuck it */
  1745. +        }
  1746. +        s--;
  1747. +    }
  1748. +    } while (notlast);
  1749. +
  1750. +    last = s-- + 1;
  1751. +
  1752. +    /* Look for a middle name */
  1753. +    while (isspace(*s)) {    /* get rid of any extra space */
  1754. +    len--;    
  1755. +    s--;
  1756. +    }
  1757. +    mid = name;
  1758. +    while (!isspace(*mid)) {
  1759. +    mid++;
  1760. +    }
  1761. +    namelen = mid - name + 1;
  1762. +    if (mid == s+1) {    /* no middle name */
  1763. +    mid = 0;
  1764. +    } else {
  1765. +    *mid++ = '\0';
  1766. +    while (isspace(*mid)) {
  1767. +        len--;
  1768. +        mid++;
  1769. +    }
  1770. +    midlen = s - mid + 2;
  1771. +    /* If first name is an initial and middle isn't and it all fits
  1772. +    ** without the first initial, drop it. */
  1773. +    if (len > max && mid != s && mid[1] != '.'
  1774. +     && (!name[1] || (name[1] == '.' && !name[2]))
  1775. +     && len - namelen <= max) {
  1776. +        len -= namelen;
  1777. +        name = mid;
  1778. +        mid = 0;
  1779. +    }
  1780. +    }
  1781. +    s[1] = '\0';
  1782. +    if (mid && len > max) {
  1783. +    /* Turn middle names into intials */
  1784. +    len -= s - mid + 2;
  1785. +    d = s = mid;
  1786. +    while (*s) {
  1787. +        if (isalpha(*s)) {
  1788. +        if (d != mid) {
  1789. +            *d++ = ' ';
  1790. +        }
  1791. +        *d++ = *s++;
  1792. +        }
  1793. +        while (*s && !isspace(*s)) {
  1794. +        s++;
  1795. +        }
  1796. +        while (isspace(*s)) {
  1797. +        s++;
  1798. +        }
  1799. +    }
  1800. +    if (d != mid) {
  1801. +        *d = '\0';
  1802. +        midlen = d - mid + 1;
  1803. +        len += midlen;
  1804. +    } else {
  1805. +        mid = 0;
  1806. +    }
  1807. +    }
  1808. +    if (len > max) {
  1809. +    /* If the first name fits without the middle initials, drop them */
  1810. +    if (mid && len - midlen <= max) {
  1811. +        len -= midlen;
  1812. +        mid = 0;
  1813. +    } else {
  1814. +        /* Turn the first name into an initial */
  1815. +        len -= namelen - 2;
  1816. +        name[1] = '\0';
  1817. +        namelen = 2;
  1818. +        if (len > max) {
  1819. +        /* Dump the middle initials (if present) */
  1820. +        if (mid) {
  1821. +            len -= midlen;
  1822. +            mid = 0;
  1823. +        }
  1824. +        if (len > max) {
  1825. +            /* Finally just truncate the last name */
  1826. +            last[max - 2] = '\0';
  1827. +        }
  1828. +        }
  1829. +    }
  1830. +    }
  1831. +
  1832. +    /* Paste the names back together */
  1833. +    d = name + namelen;
  1834. +    if (mid) {
  1835. +    d[-1] = ' ';
  1836. +    strcpy(d, mid);
  1837. +    d += midlen;
  1838. +    }
  1839. +    d[-1] = ' ';
  1840. +    strcpy(d, last);
  1841. +    return name;
  1842. +}
  1843. +
  1844. +/* Compress an email address, trying to keep as much of the local part of
  1845. +** the addresses as possible.  The order of precence is @ ! %, but
  1846. +** @ % ! may be better...
  1847. +*/
  1848. +static char *
  1849. +compress_address(name, max)
  1850. +char *name;
  1851. +int max;
  1852. +{
  1853. +    char *s, *at, *bang, *hack, *start;
  1854. +    int len;
  1855. +
  1856. +    /* Remove white space from both ends. */
  1857. +    while (isspace(*name)) {
  1858. +    name++;
  1859. +    }
  1860. +    if ((len = strlen(name)) == 0) {
  1861. +    return name;
  1862. +    }
  1863. +    s = name + len - 1;
  1864. +    while (isspace(*s)) {
  1865. +    s--;
  1866. +    }
  1867. +    s[1] = '\0';
  1868. +    if (*name == '<') {
  1869. +    name++;
  1870. +    if (*s == '>') {
  1871. +        *s-- = '\0';
  1872. +    }
  1873. +    }
  1874. +    if ((len = s - name + 1) <= max) {
  1875. +    return name;
  1876. +    }
  1877. +
  1878. +    at = bang = hack = NULL;
  1879. +    for (s = name + 1; *s; s++) {
  1880. +    /* If there's whitespace in the middle then it's probably not
  1881. +    ** really an email address. */
  1882. +    if (isspace(*s)) {
  1883. +        name[max] = '\0';
  1884. +        return name;
  1885. +    }
  1886. +    switch (*s) {
  1887. +    case '@':
  1888. +        if (at == NULL) {
  1889. +        at = s;
  1890. +        }
  1891. +        break;
  1892. +    case '!':
  1893. +        if (at == NULL) {
  1894. +        bang = s;
  1895. +        hack = NULL;
  1896. +        }
  1897. +        break;
  1898. +    case '%':
  1899. +        if (at == NULL && hack == NULL) {
  1900. +        hack = s;
  1901. +        }
  1902. +        break;
  1903. +    }
  1904. +    }
  1905. +    if (at == NULL) {
  1906. +    at = name + len;
  1907. +    }
  1908. +
  1909. +    if (hack != NULL) {
  1910. +    if (bang != NULL) {
  1911. +        if (at - bang - 1 >= max) {
  1912. +        start = bang + 1;
  1913. +        } else if (at - name >= max) {
  1914. +        start = at - max;
  1915. +        } else {
  1916. +        start = name;
  1917. +        }
  1918. +    } else {
  1919. +        start = name;
  1920. +    }
  1921. +    } else if (bang != NULL) {
  1922. +    if (at - name >= max) {
  1923. +        start = at - max;
  1924. +    } else {
  1925. +        start = name;
  1926. +    }
  1927. +    } else {
  1928. +    start = name;
  1929. +    }
  1930. +    if (len - (start - name) > max) {
  1931. +    start[max] = '\0';
  1932. +    }
  1933. +    return start;
  1934. +}
  1935. +
  1936. +/* Extract the full-name part of an email address, returning NULL if not
  1937. +** found.
  1938. +*/
  1939. +static char *
  1940. +extract_name(name)
  1941. +char *name;
  1942. +{
  1943. +    char *s;
  1944. +    char *lparen, *rparen;
  1945. +    char *langle;
  1946. +
  1947. +    while (isspace(*name)) {
  1948. +    name++;
  1949. +    }
  1950. +
  1951. +    lparen = index(name, '(');
  1952. +    rparen = rindex(name, ')');
  1953. +    langle = index(name, '<');
  1954. +    if (!lparen && !langle) {
  1955. +    return NULL;
  1956. +    } else
  1957. +    if (langle && (!lparen || !rparen || lparen > langle || rparen < langle)) {
  1958. +    if (langle == name) {
  1959. +        return NULL;
  1960. +    }
  1961. +    *langle = '\0';
  1962. +    } else {
  1963. +    name = lparen;
  1964. +    *name++ = '\0';
  1965. +    while (isspace(*name)) {
  1966. +        name++;
  1967. +    }
  1968. +    if (name == rparen) {
  1969. +        return NULL;
  1970. +    }
  1971. +    if (rparen != NULL) {
  1972. +        *rparen = '\0';
  1973. +    }
  1974. +    }
  1975. +
  1976. +    if (*name == '"') {
  1977. +    name++;
  1978. +    while (isspace(*name)) {
  1979. +        name++;
  1980. +    }
  1981. +    if ((s = rindex(name, '"')) != NULL) {
  1982. +        *s = '\0';
  1983. +    }
  1984. +    }
  1985. +    return name;
  1986. +}
  1987. +
  1988. +/* Try to fit the author name in 16 bytes.  Use the comment portion if
  1989. +** present.
  1990. +*/
  1991. +void
  1992. +get_author_str(addr)
  1993. +char *addr;
  1994. +{
  1995. +    char *s;
  1996. +
  1997. +    if ((s = extract_name(addr)) != NULL) {
  1998. +    s = compress_name(s, 16);
  1999. +    } else {
  2000. +    s = compress_address(addr, 16);
  2001. +    }
  2002. +    strcpy(author_str, s);
  2003. +}
  2004. +
  2005. +#else  /* Here's the old, simple method in case someone wants it. */
  2006. +
  2007.  /* Try to fit the author name in 16 bytes.  Use the comment portion in
  2008.  ** parenthesis if present.  Cut off non-commented names at the '@' or '%'.
  2009. @@ -640,5 +983,4 @@
  2010.  ** Then, put as many characters as we can into the 16 bytes, packing multiple
  2011.  ** whitespace characters into a single space.
  2012. -** We might want to implement a nice name shortening algorithm sometime.
  2013.  */
  2014.  void
  2015. @@ -676,4 +1018,5 @@
  2016.      *cp2 = '\0';
  2017.  }
  2018. +#endif
  2019.  
  2020.  /* Take a message-id and see if we already know about it.  If so, return it.
  2021. @@ -836,6 +1179,7 @@
  2022.      ** chain and process our references as usual.
  2023.      */
  2024. -    for (node = article->parent; node; node = node->parent) {
  2025. +    for (node = article->parent; node; node = last) {
  2026.          unlink_child(node);
  2027. +        last = node->parent;
  2028.          free_article(node);
  2029.      }
  2030. @@ -1102,5 +1446,5 @@
  2031.  void
  2032.  make_root(article)
  2033. -ARTICLE *article;
  2034. +register ARTICLE *article;
  2035.  {
  2036.      register ROOT *new, *node;
  2037. Index:rn.c
  2038. @@ -1,3 +1,3 @@
  2039. -/*  trn -- threaded readnews program
  2040. +/*  trn -- threaded readnews program based on rn 4.4
  2041.   *
  2042.   *  Author/Maintainer of trn: davison@borland.com (Wayne Davison)
  2043. @@ -8,9 +8,14 @@
  2044.   *  Organization: System Development Corporation, Santa Monica
  2045.   *
  2046. - *  begun:   01/14/83
  2047. - *    1.0: 04/08/83
  2048. - *      2.0: 09/01/83
  2049. - *      RRN/RN: 11/01/89
  2050. - *      4.4  07/04/91
  2051. + *  History:
  2052. + *    01/14/83 - rn begun
  2053. + *    04/08/83 - rn 1.0
  2054. + *    09/01/83 - rn 2.0
  2055. + *    05/01/85 - rn 4.3
  2056. + *    11/01/89 - rn/rrn integration
  2057. + *    11/25/89 - trn begun
  2058. + *    07/21/90 - trn 1.0
  2059. + *    07/04/91 - rn 4.4
  2060. + *    11/25/91 - trn 2.0
  2061.   */
  2062.  /* This software is Copyright 1991 by Stan Barber. 
  2063. @@ -28,7 +33,13 @@
  2064.  
  2065.  static char rnid[] = "@(#)$Id: rn.c,v 4.4.3.1 1991/11/22 04:12:14 davison Trn $";
  2066. -static char patchlevel[] = "Trn 2.2 based on rn 4.4 pl 2";
  2067. +static char patchlevel[] = "Trn-2.3 based on rn-4.4PL4";
  2068.  
  2069.  /* $Log: rn.c,v $
  2070. + * Revision 4.4.4.1  1992/02/23  21:25:39  sob
  2071. + * Patch level 4
  2072. + *
  2073. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  2074. + * Release 4.4 Patchlevel 3
  2075. + *
  2076.   * Revision 4.4.2.1  1991/12/01  18:05:42  sob
  2077.   * Patchlevel 2 changes
  2078. @@ -39,8 +50,4 @@
  2079.   * Revision 4.4  1991/09/09  20:27:37  sob
  2080.   * release 4.4
  2081. - *
  2082. - *
  2083. - *
  2084. - * 
  2085.   */
  2086.  
  2087. @@ -259,4 +266,5 @@
  2088.      do_command:
  2089.          direction = 1;        /* default to forward motion */
  2090. +        addnewbydefault = 0;
  2091.          switch (*buf) {
  2092.          case 'P':        /* goto previous newsgroup */
  2093. @@ -361,8 +369,12 @@
  2094.              strcpy(s,ngname);
  2095.  #endif
  2096. -            if (isalpha(*s)) 
  2097. -            set_ngname(s);
  2098. -            else {
  2099. -            if (isdigit(*s)) {
  2100. +            if (isalnum(*s)) {
  2101. +                char *_s;
  2102. +            for (_s=s; isdigit(*_s); _s++)
  2103. +                ;
  2104. +                if (*_s && !isspace(*_s))
  2105. +                /* found non-digit before hitting end */
  2106. +                set_ngname(s);
  2107. +            else {
  2108.                  int rcnum;
  2109.                  rcnum = atoi(s);
  2110. @@ -375,9 +387,9 @@
  2111.                  }
  2112.              }
  2113. -            else {
  2114. -                printf("\nPlease specify a newsgroup.\n") FLUSH;
  2115. -                goto reask_newsgroup;
  2116. -            }
  2117.              }
  2118. +            else {
  2119. +            printf("\nPlease specify a newsgroup.\n") FLUSH;
  2120. +            goto reask_newsgroup;
  2121. +            }
  2122.  #ifdef RELOCATE
  2123.              if (!get_ng(ngname,*buf=='m'))
  2124. @@ -405,36 +417,6 @@
  2125.          case 'c':        /* catch up */
  2126.  #ifdef CATCHUP
  2127. -reask_catchup:
  2128. -#ifdef VERBOSE
  2129. -            IF(verbose)
  2130. -            in_char("\nDo you really want to mark everything as read? [yn] ", 'C');
  2131. -            ELSE
  2132. -#endif
  2133. -#ifdef TERSE
  2134. -            in_char("\nReally? [ynh] ", 'C');
  2135. -#endif
  2136. -            setdef(buf,"y");
  2137. -#ifdef VERIFY
  2138. -            printcmd();
  2139. -#endif
  2140. -            putchar('\n') FLUSH;
  2141. -            if (*buf == 'h') {
  2142. -#ifdef VERBOSE
  2143. -            printf("Type y or SP to mark all articles as read.\n");
  2144. -            printf("Type n to leave articles marked as they are.\n");
  2145. -#else
  2146. -            printf("y or SP to mark all read.\n");
  2147. -            printf("n to forget it.\n");
  2148. -#endif
  2149. -            goto reask_catchup;
  2150. -            }
  2151. -            else if (*buf != 'y' && *buf != 'n' && *buf != 'q') {
  2152. -            printf(hforhelp);
  2153. -            settle_down();
  2154. -            goto reask_catchup;
  2155. -            } else if (*buf == 'y' && ng<nextrcline)
  2156. -            catch_up(ng);
  2157. -            else
  2158. -            retry = TRUE;
  2159. +            if (ng < nextrcline)
  2160. +            ask_catchup();
  2161.              ng++;
  2162.  #else
  2163. @@ -516,5 +498,4 @@
  2164.              goto reask_newsgroup;
  2165.  #else
  2166. -            addnewbydefault = 0;
  2167.              /* FALL THROUGH */
  2168.  #endif
  2169. Index:mt-read.c
  2170. @@ -1,8 +1,3 @@
  2171. -/* $Id: mt-read.c,v 4.4.3.1 1991/11/22 04:12:15 davison Trn $
  2172. -**
  2173. -** $Log: mt-read.c,v $
  2174. -** Revision 4.4.3.1  1991/11/22  04:12:15  davison
  2175. -** Trn Release 2.0
  2176. -** 
  2177. +/* $Id: mt-read.c,v 2.3 1992/12/14 00:14:04 davison Trn $
  2178.  */
  2179.  
  2180. @@ -495,5 +490,5 @@
  2181.          article = unk_domain.ids;
  2182.          while (article) {
  2183. -            safefree(article->id);
  2184. +            safefree(&article->id);
  2185.              article = article->id_link;
  2186.          }
  2187. @@ -503,5 +498,5 @@
  2188.              article = domain->ids;
  2189.              while (article) {
  2190. -            safefree(article->id);
  2191. +            safefree(&article->id);
  2192.              article = article->id_link;
  2193.              }
  2194. Index:mt-write.c
  2195. @@ -1,8 +1,3 @@
  2196. -/* $Id: mt-write.c,v 4.4.3.1 1991/11/22 04:12:15 davison Trn $
  2197. -**
  2198. -** $Log: mt-write.c,v $
  2199. -** Revision 4.4.3.1  1991/11/22  04:12:15  davison
  2200. -** Trn Release 2.0
  2201. -** 
  2202. +/* $Id: mt-write.c,v 2.3 1992/12/14 00:14:05 davison Trn $
  2203.  */
  2204.  
  2205. Index:mthreads.8
  2206. @@ -1,3 +1,3 @@
  2207. -.\" $Id: mthreads.8,v 4.4.3.1 1991/11/22 04:13:39 davison Trn $
  2208. +.\" $Id: mthreads.8,v 2.3 1992/12/14 00:14:11 davison Trn $
  2209.  .\" 
  2210.  .de Sh
  2211. @@ -303,4 +303,6 @@
  2212.  .br
  2213.  $MTLIB/LOCKmthreads
  2214. +.br
  2215. +$MTLIB/LOCKmtdaemon
  2216.  .br
  2217.  Lots of thread data files.
  2218. Index:mthreads.c
  2219. @@ -1,8 +1,3 @@
  2220. -/* $Id: mthreads.c,v 4.4.3.1 1991/11/22 04:12:15 davison Trn $
  2221. -**
  2222. -** $Log: mthreads.c,v $
  2223. -** Revision 4.4.3.1  1991/11/22  04:12:15  davison
  2224. -** Trn Release 2.0
  2225. -** 
  2226. +/* $Id: mthreads.c,v 2.3 1992/12/14 00:14:06 davison Trn $
  2227.  */
  2228.  
  2229. @@ -28,11 +23,4 @@
  2230.  #include "mthreads.h"
  2231.  
  2232. -#ifdef TZSET
  2233. -#include <time.h>
  2234. -#else
  2235. -#include <sys/time.h>
  2236. -#include <sys/timeb.h>
  2237. -#endif
  2238. -
  2239.  #if !defined(FTRUNCATE) && !defined(CHSIZE)
  2240.  # ifdef F_FREESP
  2241. @@ -534,4 +522,5 @@
  2242.  {
  2243.      mt_unlock(locked);
  2244. +    (void) chdir(MTLIB);        /* for *mon.out files, etc. */
  2245.      exit(ret);
  2246.  }
  2247. Index:mthreads.h
  2248. @@ -1,8 +1,3 @@
  2249. -/* $Id: mthreads.h,v 4.4.3.1 1991/11/22 04:12:15 davison Trn $
  2250. -**
  2251. -** $Log: mthreads.h,v $
  2252. -** Revision 4.4.3.1  1991/11/22  04:12:15  davison
  2253. -** Trn Release 2.0
  2254. -** 
  2255. +/* $Id: mthreads.h,v 2.3 1992/12/14 00:14:07 davison Trn $
  2256.  */
  2257.  
  2258. Index:ndir.h.SH
  2259. @@ -8,10 +8,10 @@
  2260.   * running Configure.
  2261.   */
  2262. -/* $Id: ndir.h.SH,v 4.4 1991/09/09 20:23:31 sob Exp sob $
  2263. +/* $Id: ndir.h.SH,v 4.4 1991/09/09 20:23:31 sob Exp $
  2264.   *
  2265.   * $Log: ndir.h.SH,v $
  2266. -# Revision 4.4  1991/09/09  20:23:31  sob
  2267. -# release 4.4
  2268. -#
  2269. + *Revision 4.4  1991/09/09  20:23:31  sob
  2270. + *release 4.4
  2271. + *
  2272.   *
  2273.   * 
  2274. Index:newsetup.1
  2275. @@ -1,5 +1,8 @@
  2276. -.\" $Id: newsetup.1,v 4.4.1.1 1991/09/25 19:36:48 sob Exp sob $
  2277. +.\" $Id: newsetup.1,v 4.4.3.1 1992/02/01 03:17:20 sob PATCH_3 sob $
  2278.  .\" 
  2279.  .\" $Log: newsetup.1,v $
  2280. +.\" Revision 4.4.3.1  1992/02/01  03:17:20  sob
  2281. +.\" Version 4.4 Patchlevel 3
  2282. +.\"
  2283.  .\" Revision 4.4.1.1  1991/09/25  19:36:48  sob
  2284.  .\" Changed quote macro to "standard" one
  2285. Index:newsetup.SH
  2286. @@ -6,7 +6,10 @@
  2287.  $startsh
  2288.  #
  2289. -# $Id: newsetup.SH,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
  2290. +# $Id: newsetup.SH,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  2291.  # 
  2292.  # $Log: newsetup.SH,v $
  2293. +# Revision 4.4.3.1  1992/02/01  03:09:32  sob
  2294. +# Release 4.4 Patchlevel 3
  2295. +#
  2296.  # Revision 4.4.2.1  1991/12/01  18:05:42  sob
  2297.  # Fixed problems with CTRLA flag.
  2298. Index:newsgroups.1
  2299. @@ -1,5 +1,8 @@
  2300. -.\" $Id: newsgroups.1,v 4.4.1.1 1991/09/25 19:36:48 sob Exp sob $
  2301. +.\" $Id: newsgroups.1,v 4.4.3.1 1992/02/01 03:17:20 sob PATCH_3 sob $
  2302.  .\" 
  2303.  .\" $Log: newsgroups.1,v $
  2304. +.\" Revision 4.4.3.1  1992/02/01  03:17:20  sob
  2305. +.\" Version 4.4 Patchlevel 3
  2306. +.\"
  2307.  .\" Revision 4.4.1.1  1991/09/25  19:36:48  sob
  2308.  .\" Changed quote macro to "standard" one
  2309. Index:newsgroups.SH
  2310. @@ -5,7 +5,10 @@
  2311.  $spitshell >newsgroups <<!GROK!THIS!
  2312.  $startsh
  2313. -# $Id: newsgroups.SH,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
  2314. +# $Id: newsgroups.SH,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  2315.  # 
  2316.  # $Log: newsgroups.SH,v $
  2317. +# Revision 4.4.3.1  1992/02/01  03:09:32  sob
  2318. +# Release 4.4 Patchlevel 3
  2319. +#
  2320.  # Revision 4.4.2.1  1991/12/01  18:05:42  sob
  2321.  # Patchlevel 2 changes
  2322. Index:ng.c
  2323. @@ -1,5 +1,8 @@
  2324. -/* $Id: ng.c,v 4.4 1991/09/09 20:23:31 sob Exp sob $
  2325. +/* $Id: ng.c,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  2326.   *
  2327.   * $Log: ng.c,v $
  2328. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  2329. + * Release 4.4 Patchlevel 3
  2330. + *
  2331.   * Revision 4.4  1991/09/09  20:23:31  sob
  2332.   * release 4.4
  2333. @@ -143,4 +146,13 @@
  2334.      exit_code = NG_NORM;
  2335.  
  2336. +    if (extractdest) {
  2337. +    free(extractdest);
  2338. +    extractdest = Nullch;
  2339. +    }
  2340. +    if (extractprog) {
  2341. +    free(extractprog);
  2342. +    extractprog = Nullch;
  2343. +    }
  2344. +
  2345.  #ifdef SERVER
  2346.      sprintf(ser_line, "GROUP %s", ngname);
  2347. @@ -835,15 +847,19 @@
  2348.  #ifdef VERBOSE
  2349.              IF(verbose)
  2350. -            fprintf(stdout,"\n\
  2351. -There is no %s article prior to this one.\n",cp) FLUSH;
  2352. +            printf("\nThere is no %s article prior to this one.\n",
  2353. +                cp) FLUSH;
  2354.              ELSE
  2355.  #endif
  2356.  #ifdef TERSE
  2357. -            fprintf(stdout,"\nNo prior %s.\n",cp) FLUSH;
  2358. +            printf("\nNo prior %s.\n",cp) FLUSH;
  2359.  #endif
  2360.              return AS_ASK;
  2361.          }
  2362. -        *buf = '{';
  2363. -        p_art--;
  2364. +        if (*buf == '{')
  2365. +            p_art = p_articles + p_roots[p_art->root].articles;
  2366. +        else {
  2367. +            *buf = '{';
  2368. +            p_art--;
  2369. +        }
  2370.          }
  2371.          else
  2372. @@ -917,4 +933,31 @@
  2373.      }
  2374.      goto not_threaded;
  2375. +    case '(':            /* goto previous sibling */
  2376. +    case ')':            /* goto next sibling */
  2377. +    if (p_art) {
  2378. +        PACKED_ARTICLE *ta;
  2379. +        if (*buf == '(') {
  2380. +        ta = find_prev_sib();
  2381. +        } else {
  2382. +        ta = find_next_sib();
  2383. +        }
  2384. +        if (!ta) {
  2385. +        register char *cp = (*buf == '(' ? "previous" : "next");
  2386. +#ifdef VERBOSE
  2387. +        IF(verbose)
  2388. +            printf("\nThis article has no %s sibling.\n",cp) FLUSH;
  2389. +        ELSE
  2390. +#endif
  2391. +#ifdef TERSE
  2392. +            printf("\nNo %s sibling.\n",cp) FLUSH;
  2393. +#endif
  2394. +        return AS_ASK;
  2395. +        }
  2396. +        p_art = ta;
  2397. +        art = p_art->num;
  2398. +        reread = TRUE;
  2399. +        return AS_NORM;
  2400. +    }
  2401. +    goto not_threaded;
  2402.      case 'T':
  2403.      if (p_art) {
  2404. @@ -938,5 +981,6 @@
  2405.      goto normal_search;
  2406.      case ',':        /* kill this node and all descendants */
  2407. -    mark_as_read();
  2408. +    if (art >= absfirst && art <= lastart)
  2409. +        mark_as_read();
  2410.      *buf = 'K';
  2411.      case 'k':        /* kill current subject # (e.g. [1]) */
  2412. @@ -1232,5 +1276,5 @@
  2413.      return AS_ASK;
  2414.      case 'm':
  2415. -    if (art <= lastart) {
  2416. +    if (art >= absfirst && art <= lastart) {
  2417.          unmark_as_read();
  2418.          printf("\nArticle %ld marked as still unread.\n",(long)art) FLUSH;
  2419. @@ -1238,58 +1282,8 @@
  2420.      return AS_ASK;
  2421.      case 'c':            /* catch up */
  2422. -      reask_catchup:
  2423. -#ifdef VERBOSE
  2424. -    IF(verbose)
  2425. -        in_char("\nDo you really want to mark everything as read? [yn] ",
  2426. -        'C');
  2427. -    ELSE
  2428. -#endif
  2429. -#ifdef TERSE
  2430. -        in_char("\nReally? [ynh] ", 'C');
  2431. -#endif
  2432. -    setdef(buf,"y");
  2433. -#ifdef VERIFY
  2434. -    printcmd();
  2435. -#endif
  2436. -    putchar('\n') FLUSH;
  2437. -    if (*buf == 'h') {
  2438. -#ifdef VERBOSE
  2439. -        IF(verbose)
  2440. -        fputs("\
  2441. -Type y or SP to mark all articles as read.\n\
  2442. -Type n to leave articles marked as they are.\n\
  2443. -Type u to mark everything read and unsubscribe.\n\
  2444. -",stdout) FLUSH;
  2445. -        ELSE
  2446. -#endif
  2447. -#ifdef TERSE
  2448. -        fputs("\
  2449. -y or SP to mark all read.\n\
  2450. -n to forget it.\n\
  2451. -u to mark all and unsubscribe.\n\
  2452. -",stdout) FLUSH;
  2453. -#endif
  2454. -        goto reask_catchup;
  2455. -    }
  2456. -    else if (*buf == 'n' || *buf == 'q') {
  2457. +    switch (ask_catchup()) {
  2458. +    case 'n':
  2459.          return AS_ASK;
  2460. -    }
  2461. -    else if (*buf != 'y' && *buf != 'u') {
  2462. -        fputs(hforhelp,stdout) FLUSH;
  2463. -        settle_down();
  2464. -        goto reask_catchup;
  2465. -    }
  2466. -    for (i = firstart; i <= lastart; i++) {
  2467. -        oneless(i);        /* mark as read */
  2468. -    }
  2469. -#ifdef USETHREADS
  2470. -    selected_count = selected_root_cnt = unthreaded = 0;
  2471. -#endif
  2472. -#ifdef DELAYMARK
  2473. -    if (dmfp)
  2474. -        yankback();
  2475. -#endif
  2476. -    if (*buf == 'u') {
  2477. -        rcchar[ng] = NEGCHAR;
  2478. +    case 'u':
  2479.          return AS_CLEAN;
  2480.      }
  2481. @@ -1307,5 +1301,5 @@
  2482.      case 'j':
  2483.      putchar('\n') FLUSH;
  2484. -    if (art <= lastart)
  2485. +    if (art >= absfirst && art <= lastart)
  2486.          mark_as_read();
  2487.      return AS_ASK;
  2488. @@ -1504,4 +1498,5 @@
  2489.      return AS_ASK;
  2490.      }
  2491. +    case 'Z':
  2492.      case 'z': {
  2493.      supersede_article();    /* supersedes */
  2494. @@ -1599,3 +1594,87 @@
  2495.          dfltcmd = "npq";
  2496.      }
  2497. +}
  2498. +
  2499. +/* Ask the user about catching-up the current group.  Returns 'y' if yes,
  2500. +** 'n' or 'N' if no ('N' means we used one line when in the thread selector),
  2501. +** or 'u' for yes with unsubscribe.  Actually performs the catchup and
  2502. +** unsubscription as needed.
  2503. +*/
  2504. +char
  2505. +ask_catchup()
  2506. +{
  2507. +    bool use_one_line;
  2508. +
  2509. +    if (mode == 't')
  2510. +    use_one_line = TRUE;
  2511. +    else {
  2512. +    putchar('\n') FLUSH;
  2513. +    use_one_line = FALSE;
  2514. +    }
  2515. +reask_catchup:
  2516. +#ifdef VERBOSE
  2517. +    IF(verbose)
  2518. +    in_char("Do you really want to mark everything as read? [yn] ", 'C');
  2519. +    ELSE
  2520. +#endif
  2521. +#ifdef TERSE
  2522. +    in_char("Really? [ynh] ", 'C');
  2523. +#endif
  2524. +    setdef(buf,"y");
  2525. +#ifdef VERIFY
  2526. +    printcmd();
  2527. +#endif
  2528. +    if (*buf == 'h') {
  2529. +    use_one_line = FALSE;
  2530. +#ifdef VERBOSE
  2531. +    IF(verbose)
  2532. +        fputs("\n\
  2533. +Type y or SP to mark all articles as read.\n\
  2534. +Type n to leave articles marked as they are.\n\
  2535. +Type u to mark everything read and unsubscribe.\n\n\
  2536. +",stdout) FLUSH;
  2537. +    ELSE
  2538. +#endif
  2539. +#ifdef TERSE
  2540. +        fputs("\n\
  2541. +y or SP to mark all read.\n\
  2542. +n to forget it.\n\
  2543. +u to mark all and unsubscribe.\n\n\
  2544. +",stdout) FLUSH;
  2545. +#endif
  2546. +    goto reask_catchup;
  2547. +    }
  2548. +    if (*buf == 'n' || *buf == 'q') {
  2549. +    if (use_one_line)
  2550. +        return 'N';
  2551. +    putchar('\n') FLUSH;
  2552. +    return 'n';
  2553. +    }
  2554. +    if (*buf != 'y' && *buf != 'u') {
  2555. +    use_one_line = FALSE;
  2556. +    printf("\n%s\n", hforhelp) FLUSH;
  2557. +    settle_down();
  2558. +    goto reask_catchup;
  2559. +    }
  2560. +    if (mode == 'n') {
  2561. +    putchar('\n') FLUSH;
  2562. +    catch_up(ng);
  2563. +    }
  2564. +    else {
  2565. +    int i;
  2566. +
  2567. +    for (i = firstart; i <= lastart; i++)
  2568. +        oneless(i);        /* mark as read */
  2569. +#ifdef USETHREADS
  2570. +    selected_count = selected_root_cnt = unthreaded = 0;
  2571. +#endif
  2572. +#ifdef DELAYMARK
  2573. +    if (dmfp)
  2574. +        yankback();
  2575. +#endif
  2576. +    putchar('\n') FLUSH;
  2577. +    }
  2578. +    if (*buf == 'u')
  2579. +    rcchar[ng] = NEGCHAR;
  2580. +    return *buf;
  2581.  }
  2582. Index:ng.h
  2583. @@ -53,2 +53,3 @@
  2584.  #endif
  2585.  void    setdfltcmd ANSI((void));
  2586. +char    ask_catchup ANSI((void));
  2587. Index:ngdata.c
  2588. @@ -1,5 +1,8 @@
  2589. -/* $Id: ngdata.c,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
  2590. +/* $Id: ngdata.c,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  2591.   *
  2592.   * $Log: ngdata.c,v $
  2593. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  2594. + * Release 4.4 Patchlevel 3
  2595. + *
  2596.   * Revision 4.4.2.1  1991/12/01  18:05:42  sob
  2597.   * Patchlevel 2 changes
  2598. @@ -93,15 +96,5 @@
  2599.      }
  2600.  #else /* not SERVER */
  2601. -
  2602. -    cp = filexp(ACTIVE);
  2603. -    actfp = fopen(cp,"r");
  2604. -    if (actfp == Nullfp) {
  2605. -    printf(cantopen,cp) FLUSH;
  2606. -    finalize(1);
  2607. -    }
  2608. -    activeitems = 0;
  2609. -    /* count entries */
  2610. -    while(fgets(buf,LBUFLEN,actfp) != NULL)
  2611. -    activeitems++;
  2612. +    ngdatansrv_init();
  2613.  #endif
  2614.      if (fseek(actfp,0L,0) == -1) {    /* just get to the beginning */
  2615. @@ -198,55 +191,4 @@
  2616.  }
  2617.  
  2618. -ACT_POS
  2619. -findact(outbuf,nam,len,suggestion)
  2620. -char *outbuf;
  2621. -char *nam;
  2622. -int len;
  2623. -long suggestion;
  2624. -{
  2625. -    ACT_POS retval;
  2626. -
  2627. -    fseek(actfp,100000L,1);    /* hopefully this forces a reread */
  2628. -    if (suggestion == 0L || fseek(actfp,suggestion,0) < 0 ||
  2629. -      fgets(outbuf,80,actfp) == Nullch ||
  2630. -      outbuf[len] != ' ' ||
  2631. -      strnNE(outbuf,nam,len)) {
  2632. -#ifdef DEBUGGING
  2633. -    if (debug & DEB_SOFT_POINTERS)
  2634. -        printf("Missed, looking for %s in %sLen = %d\n",nam,outbuf,len)
  2635. -          FLUSH;
  2636. -#endif
  2637. -    fseek(actfp,0L,0);
  2638. -#ifndef lint
  2639. -    retval = (ACT_POS)ftell(actfp);
  2640. -#else
  2641. -    retval = Null(ACT_POS);
  2642. -#endif /* lint */
  2643. -    while (fgets(outbuf,80,actfp) != Nullch) {
  2644. -        if (outbuf[len] == ' ' && strnEQ(outbuf,nam,len))
  2645. -        return retval;
  2646. -#ifndef lint
  2647. -        retval = (ACT_POS) ftell(actfp);
  2648. -#endif /* lint */
  2649. -        if (ferror(actfp)) {
  2650. -        perror("error on active file"); /* something is wrong */
  2651. -        sig_catcher(0);
  2652. -        }
  2653. -    }
  2654. -    if(ferror(actfp)) {
  2655. -        perror("error on active file");
  2656. -        sig_catcher(0);
  2657. -    }
  2658. -    return (ACT_POS) -1;
  2659. -    }
  2660. -    else
  2661. -#ifndef lint
  2662. -    return (ACT_POS) suggestion;
  2663. -#else
  2664. -    return retval;
  2665. -#endif /* lint */
  2666. -    /*NOTREACHED*/
  2667. -}
  2668. -
  2669.  /* determine the absolutely first existing article number */
  2670.  #ifdef SERVER
  2671. @@ -355,5 +297,5 @@
  2672.      register DIR *dirp;
  2673.      register struct DIRTYPE *dp;
  2674. -    register ART_NUM min = 1000000;
  2675. +    register ART_NUM min = 0;
  2676.      register ART_NUM maybe;
  2677.      register char *p;
  2678. @@ -366,5 +308,5 @@
  2679.      return 0;
  2680.      while ((dp = readdir(dirp)) != Null(struct DIRTYPE *)) {
  2681. -    if ((maybe = atol(dp->d_name)) < min && maybe > floor) {
  2682. +    if (((maybe = atol(dp->d_name)) < min || !min) && maybe > floor) {
  2683.          for (p = dp->d_name; *p; p++)
  2684.          if (!isdigit(*p))
  2685. @@ -393,5 +335,5 @@
  2686.      }
  2687.      closedir(dirp);
  2688. -    return min==1000000 ? 0 : min;
  2689. +    return min;
  2690.  }
  2691.  #endif
  2692. Index:ngdata.h
  2693. @@ -1,5 +1,8 @@
  2694. -/* $Id: ngdata.h,v 4.4 1991/09/09 20:23:31 sob Exp sob $
  2695. +/* $Id: ngdata.h,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  2696.   *
  2697.   * $Log: ngdata.h,v $
  2698. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  2699. + * Release 4.4 Patchlevel 3
  2700. + *
  2701.   * Revision 4.4  1991/09/09  20:23:31  sob
  2702.   * release 4.4
  2703. @@ -28,5 +31,5 @@
  2704.      EXT char active_name[MAXFILENAME];
  2705.      EXT time_t lastactfetch INIT(0);
  2706. -#define MINFETCHTIME (5 * 60)
  2707. +#define MINFETCHTIME (2 * 60 * 60)
  2708.  #endif
  2709.  
  2710. Index:nghash.c
  2711. @@ -0,0 +1,140 @@
  2712. +/* $Id: nghash.c,v 3.0 1992/02/01 03:09:32 davison Trn $
  2713. + */
  2714. +/*
  2715. + * This software is Copyright 1991 by Stan Barber.
  2716. + *
  2717. + * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  2718. + * use this software as long as: there is no monetary profit gained
  2719. + * specifically from the use or reproduction of this software, it is not
  2720. + * sold, rented, traded or otherwise marketed, and this copyright notice is
  2721. + * included prominently in any copy made.
  2722. + *
  2723. + * The author make no claims as to the fitness or correctness of this software
  2724. + * for any use whatsoever, and it is provided as is. Any use of this software
  2725. + * is at the user's own risk.
  2726. + */
  2727. +
  2728. +#include "EXTERN.h"
  2729. +#include "common.h"
  2730. +#include "ndir.h"
  2731. +#include "rcstuff.h"
  2732. +#include "rn.h"
  2733. +#include "intrp.h"
  2734. +#include "final.h"
  2735. +#include "rcln.h"
  2736. +#include "util.h"
  2737. +#ifdef SERVER
  2738. +#include "server.h"
  2739. +#endif
  2740. +#include "ngdata.h"
  2741. +
  2742. +#include <string.h>
  2743. +#include "hdbm.h"
  2744. +
  2745. +static HASHTABLE *acthash;
  2746. +static char *actfile;
  2747. +
  2748. +void
  2749. +ngdatansrv_init()        /* non-SERVER initialisation */
  2750. +{
  2751. +    register long offset = 0;
  2752. +    char *cp = filexp(ACTIVE);
  2753. +    struct stat actstat;
  2754. +
  2755. +    actfp = fopen(cp, "r");
  2756. +    if (actfp == Nullfp) {
  2757. +    printf(cantopen, cp) FLUSH;
  2758. +    finalize(1);
  2759. +    }
  2760. +
  2761. +    /* rn was being a slug about rereading the active file over and
  2762. +     * over; try using a really big buffer to keep it in core. */
  2763. +    (void) fstat(fileno(actfp), &actstat);
  2764. +    actfile = safemalloc(actstat.st_size + 1);
  2765. +    rewind(actfp);
  2766. +    /*
  2767. +     * NOTE: this won't work on machines with ints too small to hold
  2768. +     * the size of the active file.
  2769. +     */
  2770. +    if (fread(actfile, 1, (int)actstat.st_size, actfp) != actstat.st_size) {
  2771. +    fprintf(stderr, "active file not read\n");
  2772. +    actfile[0] = '\0';
  2773. +    }
  2774. +    rewind(actfp);
  2775. +    actfile[actstat.st_size] = '\0';
  2776. +
  2777. +    acthash = hdbmcreate((int)(actstat.st_size/40), (unsigned (*)())NULL);
  2778. +    if (acthash == NULL) {
  2779. +    fprintf(stderr, "can't hash %s\n", filexp(ACTIVE));
  2780. +    finalize(1);
  2781. +    }
  2782. +
  2783. +    /* count entries */
  2784. +    rewind(actfp);
  2785. +    for (activeitems = 0; fgets(buf, LBUFLEN, actfp) != NULL; activeitems++) {
  2786. +    register char *p = strchr(buf, ' ');
  2787. +    HDBMDATUM key, data;
  2788. +
  2789. +    /* key.dat_ptr must be allocated to make it permanent for hashstore */
  2790. +    if (p == NULL)
  2791. +        p = buf;
  2792. +    data.dat_ptr = key.dat_ptr = actfile + offset;
  2793. +    key.dat_len = p - buf;
  2794. +    data.dat_len = strlen(buf);
  2795. +    if (!hdbmstore(acthash, key, data)) {
  2796. +        fprintf(stderr, "can't install hash key %s\n", key.dat_ptr);
  2797. +        finalize(1);
  2798. +    }
  2799. +    offset += data.dat_len;
  2800. +    }
  2801. +}
  2802. +
  2803. +ACT_POS
  2804. +findact(outbuf, nam, len, suggestion)
  2805. +register char *outbuf;
  2806. +register char *nam;
  2807. +register int len;
  2808. +register long suggestion;
  2809. +{
  2810. +    register ACT_POS retval;
  2811. +    extern int debug;
  2812. +
  2813. +    /* see if we know the right place and can just return */
  2814. +    if (suggestion != 0 && fseek(actfp, suggestion, 0) >= 0
  2815. +     && fgets(outbuf, 80, actfp) != NULL && outbuf[len] == ' '
  2816. +     && strnEQ(outbuf, nam, len))
  2817. +    return suggestion;
  2818. +
  2819. +    /* hmm, apparently not, gotta look it up. */
  2820. +    if (debug & DEB_SOFT_POINTERS)
  2821. +    printf("Missed, looking for %s in %sLen = %d\n",nam,outbuf,len) FLUSH;
  2822. +    /* can we just do a quick hashed lookup? */
  2823. +    if (acthash != NULL) {
  2824. +    HDBMDATUM key, data;
  2825. +
  2826. +    outbuf[0] = '\0';
  2827. +    key.dat_ptr = nam;
  2828. +    key.dat_len = len;
  2829. +    data = hdbmfetch(acthash, key);
  2830. +    if (data.dat_ptr == NULL)
  2831. +        return -1;
  2832. +    else {
  2833. +        (void) memcpy(outbuf, data.dat_ptr, (int)data.dat_len);
  2834. +        outbuf[data.dat_len] = '\0';
  2835. +        return data.dat_ptr - actfile;
  2836. +    }
  2837. +    }
  2838. +
  2839. +    /* apparently not.  gotta do it the slow way. */
  2840. +    (void) fseek(actfp, 0L, 0);
  2841. +    for (retval = 0; fgets(outbuf,80,actfp) != NULL; retval += strlen(outbuf))
  2842. +    if (outbuf[len] == ' ' && strnEQ(outbuf, nam, len))
  2843. +        break;
  2844. +    if (ferror(actfp)) {
  2845. +    perror("error on active file");
  2846. +    sig_catcher(0);
  2847. +    /* NOTREACHED */
  2848. +    } else if (feof(actfp))
  2849. +    return -1;    /* no such group */
  2850. +    return retval;
  2851. +}
  2852. Index:ngsrch.c
  2853. @@ -1,5 +1,8 @@
  2854. -/* $Id: ngsrch.c,v 4.4 1991/09/09 20:23:31 sob Exp sob $
  2855. +/* $Id: ngsrch.c,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  2856.   *
  2857.   * $Log: ngsrch.c,v $
  2858. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  2859. + * Release 4.4 Patchlevel 3
  2860. + *
  2861.   * Revision 4.4  1991/09/09  20:23:31  sob
  2862.   * release 4.4
  2863. Index:ngsrch.h
  2864. @@ -1,5 +1,8 @@
  2865. -/* $Id: ngsrch.h,v 4.4 1991/09/09 20:23:31 sob Exp sob $
  2866. +/* $Id: ngsrch.h,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  2867.   *
  2868.   * $Log: ngsrch.h,v $
  2869. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  2870. + * Release 4.4 Patchlevel 3
  2871. + *
  2872.   * Revision 4.4  1991/09/09  20:23:31  sob
  2873.   * release 4.4
  2874. Index:nntp/xthread-11t.to.11t2
  2875. @@ -0,0 +1,233 @@
  2876. +This patch takes NNTP 1.5.11t up to my current release of 1.5.11t2.
  2877. +
  2878. +..wayne..
  2879. +
  2880. +Index:common/version.c
  2881. +Prereq: "1.5.11t
  2882. +@@ -3,3 +3,3 @@
  2883. +  */
  2884. +-char    nntp_version[] = "1.5.11t (16 November 1991)";
  2885. ++char    nntp_version[] = "1.5.11t2 (14 December 1992)";
  2886. +Index:common/clientlib.c
  2887. +@@ -606,74 +606,4 @@
  2888. +-static    long    rawbytes = -1;    /* bytes remaining to be transfered */
  2889. +-
  2890. +-/*
  2891. +- * rawcheck_server -- get a line of text from the server, interpreting
  2892. +- * it as a status message for a raw (binary) command.  Call this once
  2893. +- * before calling rawget_server() for the actual data transfer.
  2894. +- *
  2895. +- *    Parameters:    "string" has the buffer space for the
  2896. +- *            line received.
  2897. +- *            "size" is the size of the buffer.
  2898. +- *
  2899. +- *    Returns:    -1 on error, otherwise the length of the raw data.
  2900. +- *
  2901. +- *    Side effects:    Talks to server, changes contents of "string".
  2902. +- */
  2903. +-long
  2904. +-rawcheck_server(string, size)
  2905. +-char    *string;
  2906. +-int    size;
  2907. +-{
  2908. +-    /* try to get the status line and the status code */
  2909. +-    if (get_server(string, size) || *string != CHAR_OK)
  2910. +-        return rawbytes = -1;
  2911. +-
  2912. +-    /* try to get the number of bytes being transfered */
  2913. +-    if (sscanf(string, "%*d%ld", &rawbytes) != 1)
  2914. +-        return rawbytes = -1;
  2915. +-    return rawbytes;
  2916. +-}
  2917. +-
  2918. +-
  2919. +-/*
  2920. +- * rawget_server -- read data from the server in raw format.  This call must
  2921. +- * follow an appropriate put_server command and a rawcheck_server call.
  2922. +- *
  2923. +- *    Parameters:    "buf" is the buffer for the data to receive.
  2924. +- *            "n" is the size of the buffer.
  2925. +- *
  2926. +- *    Returns:    0 on EOF, otherwise the length of the read.
  2927. +- *
  2928. +- *    Side effects:    Talks to server, changes contents of "buf".
  2929. +- */
  2930. +-long
  2931. +-rawget_server(buf, n)
  2932. +-void    *buf;
  2933. +-long    n;
  2934. +-{
  2935. +-    /* if no bytes to read, then just return EOF */
  2936. +-    if (rawbytes < 0)
  2937. +-        return 0;
  2938. +-
  2939. +-    /* try to read some data from the server */
  2940. +-    if (rawbytes) {
  2941. +-        n = fread(buf, 1, n > rawbytes ? rawbytes : n, ser_rd_fp);
  2942. +-        rawbytes -= n;
  2943. +-    } else
  2944. +-        n = 0;
  2945. +-
  2946. +-    /* if no more left, then fetch the end-of-command signature */
  2947. +-    if (!rawbytes)
  2948. +-    {
  2949. +-        char buf[5];    /* "\r\n.\r\n" */
  2950. +-
  2951. +-        fread(buf, 1, 5, ser_rd_fp);
  2952. +-        rawbytes = -1;
  2953. +-    }
  2954. +-    return n;
  2955. +-}
  2956. +-
  2957. +-
  2958. + /*
  2959. +  * close_server -- close the connection to the server, after sending
  2960. +Index:common/clientlib.h
  2961. +@@ -9,5 +9,3 @@
  2962. + extern    void    put_server();
  2963. + extern    int    get_server();
  2964. +-extern    long    rawcheck_server();
  2965. +-extern    long    rawget_server();
  2966. + extern    void    close_server();
  2967. +Index:server/group.c
  2968. +@@ -117,2 +117,63 @@
  2969. +     (void) fflush(stdout);
  2970. + }
  2971. ++
  2972. ++#ifdef LISTGROUP
  2973. ++/*
  2974. ++ * LISTGROUP [group]
  2975. ++ *
  2976. ++ * Lists all article numbers (filenames) in the given group. Used by
  2977. ++ * newsreaders such as nn and trn for fast validation of a database.
  2978. ++ * If a group name is given it becomes the current group.
  2979. ++ *
  2980. ++ * This command is an extention, and not included in RFC 977.
  2981. ++ */
  2982. ++
  2983. ++listgroup(argc, argv)
  2984. ++    int        argc;
  2985. ++    char        *argv[];
  2986. ++{
  2987. ++    register int i;
  2988. ++
  2989. ++    if (argc == 2) {
  2990. ++        ingroup = 0;
  2991. ++        /* This will output a success or failure message */
  2992. ++        group(argc, argv);
  2993. ++        if (!ingroup) {
  2994. ++            return;
  2995. ++        }
  2996. ++    } else if (argc > 2) {
  2997. ++        printf("%d Usage: LISTGROUP [newsgroup].\r\n", ERR_CMDSYN);
  2998. ++        (void) fflush(stdout);
  2999. ++        return;
  3000. ++    } else if (!ingroup) {
  3001. ++        printf("%d You are not currently in a newsgroup.\r\n",
  3002. ++            ERR_NCING);
  3003. ++        (void) fflush(stdout);
  3004. ++        return;
  3005. ++    } else if (!canread) {
  3006. ++        printf("%d You only have permission to transfer, sorry.\r\n",
  3007. ++            ERR_ACCESS);
  3008. ++        (void) fflush(stdout);
  3009. ++        return;
  3010. ++    } else {
  3011. ++        /* output a success message when no group name is given */
  3012. ++        printf("%d %d %d %d (current group)\r\n",
  3013. ++            OK_GROUP,
  3014. ++            num_arts,
  3015. ++            (num_arts > 0 ? art_array[0] : 0),
  3016. ++            (num_arts > 0 ? art_array[num_arts-1] : 0));
  3017. ++    }
  3018. ++
  3019. ++#ifdef LOG
  3020. ++    syslog(LOG_INFO, "%s listgroup", hostname);
  3021. ++#endif
  3022. ++    for (i = 0; i < num_arts; i++) {
  3023. ++        printf("%d\r\n", art_array[i]);
  3024. ++    }
  3025. ++    putchar('.');
  3026. ++    putchar('\r');
  3027. ++    putchar('\n');
  3028. ++    (void) fflush(stdout);
  3029. ++}
  3030. ++
  3031. ++#endif /* LISTGROUP */
  3032. +Index:server/help.c
  3033. +@@ -22,6 +22,9 @@
  3034. +     printf("STAT        NEWGROUPS    HELP\r\n");
  3035. +     printf("IHAVE       NEWNEWS      SLAVE\r\n");
  3036. +-#if defined(XHDR) || defined(XTHREAD)
  3037. +-    printf("\r\nAdditionally, the following extentions are supported:\r\n\r\n");
  3038. ++#if defined(XHDR) || defined(XTHREAD) || defined(LISTGROUP)
  3039. ++    printf("\r\nAdditionally, the following extensions are supported:\r\n\r\n");
  3040. ++# ifdef LISTGROUP
  3041. ++    printf("LISTGROUP   Retrieve a list of valid article-numbers.\r\n");
  3042. ++# endif LISTGROUP
  3043. + # ifdef    XHDR
  3044. +     printf("XHDR        Retrieve a single header line from a range of articles.\r\n");
  3045. +Index:server/newgroups.c
  3046. +@@ -24,4 +24,5 @@
  3047. +     long        date;
  3048. +     register FILE    *date_fp;
  3049. ++    char        *reqlist[2];
  3050. +     if (argc < 3) {
  3051. +@@ -97,4 +98,20 @@
  3052. +         if (distcount == 0) {
  3053. ++#ifdef ACTIVE_TIMES_FILE
  3054. ++            reqlist[0] = line;
  3055. ++#else
  3056. ++            reqlist[0] = cp + 1;
  3057. ++#endif
  3058. ++            reqlist[1] = NULL;
  3059. ++
  3060. ++            if (ngpermcount) {
  3061. ++                if (ngmatch(s1strneql, ALLBUT,
  3062. ++                    ngpermlist, ngpermcount, reqlist, 1) == 0) {
  3063. ++                     continue;
  3064. ++                }
  3065. ++            } else if (ALLBUT == 0) {
  3066. ++                continue;
  3067. ++            }
  3068. ++
  3069. + #ifdef ACTIVE_TIMES_FILE
  3070. +             putline(line);
  3071. +Index:server/serve.c
  3072. +@@ -27,5 +27,5 @@
  3073. + extern    int    ahbs(), group(), help(), ihave();
  3074. + extern    int    list(), newgroups(), newnews(), nextlast(), post();
  3075. +-extern    int    slave(), stat(), xhdr(), xthread();
  3076. ++extern    int    slave(), stat(), listgroup(), xhdr(), xthread();
  3077. + extern int errno;
  3078. +@@ -53,4 +53,7 @@
  3079. +     "last",        0,    nextlast,
  3080. +     "list",        0,    list,
  3081. ++#ifdef LISTGROUP
  3082. ++    "listgroup",    0,    listgroup,
  3083. ++#endif LISTGROUP
  3084. +     "newgroups",    0,    newgroups,
  3085. +     "newnews",    0,    newnews,
  3086. +Index:server/xthread.c
  3087. +@@ -131,5 +131,5 @@
  3088. + {
  3089. +     static char name_buff[MAXPATHLEN];
  3090. +-#ifndef LONG_THREAD_NAMES
  3091. ++#ifdef LONG_THREAD_NAMES
  3092. +     char group_buff[512];
  3093. +     register char *ptr;
  3094. +@@ -137,6 +137,6 @@
  3095. +     strcpy(group_buff, group);
  3096. +     ptr = group = group_buff;
  3097. +-    while ((ptr = index(ptr, '.'))) {
  3098. +-        *ptr = '/';
  3099. ++    while ((ptr = index(ptr, '/'))) {
  3100. ++        *ptr = '.';
  3101. +     }
  3102. + #endif
  3103. Index:nntp/xthread.patch
  3104. @@ -29,10 +29,8 @@
  3105.  
  3106.  Tim can be contacted at:  iverson@xstor.com -/- uunet!xstor!iverson
  3107. --- 
  3108. - \  /| / /|\/ /| /(_)     Wayne Davison
  3109. -(_)/ |/ /\|/ / |/  \      davison@borland.com
  3110. -   (W   A  Y   N   e)
  3111.  
  3112. -Index: common/version.c
  3113. +..wayne..
  3114. +
  3115. +Index:common/version.c
  3116.  Prereq: "1.5.11
  3117.  @@ -3,3 +3,3 @@
  3118. @@ -40,93 +38,6 @@
  3119.   
  3120.  -char    nntp_version[] = "1.5.11 (10 February 1991)";
  3121. -+char    nntp_version[] = "1.5.11t (16 November 1991)";
  3122. -Index: common/clientlib.c
  3123. -@@ -606,4 +606,74 @@
  3124. -+static    long    rawbytes = -1;    /* bytes remaining to be transfered */
  3125. -+
  3126. -+/*
  3127. -+ * rawcheck_server -- get a line of text from the server, interpreting
  3128. -+ * it as a status message for a raw (binary) command.  Call this once
  3129. -+ * before calling rawget_server() for the actual data transfer.
  3130. -+ *
  3131. -+ *    Parameters:    "string" has the buffer space for the
  3132. -+ *            line received.
  3133. -+ *            "size" is the size of the buffer.
  3134. -+ *
  3135. -+ *    Returns:    -1 on error, otherwise the length of the raw data.
  3136. -+ *
  3137. -+ *    Side effects:    Talks to server, changes contents of "string".
  3138. -+ */
  3139. -+long
  3140. -+rawcheck_server(string, size)
  3141. -+char    *string;
  3142. -+int    size;
  3143. -+{
  3144. -+    /* try to get the status line and the status code */
  3145. -+    if (get_server(string, size) || *string != CHAR_OK)
  3146. -+        return rawbytes = -1;
  3147. -+
  3148. -+    /* try to get the number of bytes being transfered */
  3149. -+    if (sscanf(string, "%*d%ld", &rawbytes) != 1)
  3150. -+        return rawbytes = -1;
  3151. -+    return rawbytes;
  3152. -+}
  3153. -+
  3154. -+
  3155. -+/*
  3156. -+ * rawget_server -- read data from the server in raw format.  This call must
  3157. -+ * follow an appropriate put_server command and a rawcheck_server call.
  3158. -+ *
  3159. -+ *    Parameters:    "buf" is the buffer for the data to receive.
  3160. -+ *            "n" is the size of the buffer.
  3161. -+ *
  3162. -+ *    Returns:    0 on EOF, otherwise the length of the read.
  3163. -+ *
  3164. -+ *    Side effects:    Talks to server, changes contents of "buf".
  3165. -+ */
  3166. -+long
  3167. -+rawget_server(buf, n)
  3168. -+void    *buf;
  3169. -+long    n;
  3170. -+{
  3171. -+    /* if no bytes to read, then just return EOF */
  3172. -+    if (rawbytes < 0)
  3173. -+        return 0;
  3174. -+
  3175. -+    /* try to read some data from the server */
  3176. -+    if (rawbytes) {
  3177. -+        n = fread(buf, 1, n > rawbytes ? rawbytes : n, ser_rd_fp);
  3178. -+        rawbytes -= n;
  3179. -+    } else
  3180. -+        n = 0;
  3181. -+
  3182. -+    /* if no more left, then fetch the end-of-command signature */
  3183. -+    if (!rawbytes)
  3184. -+    {
  3185. -+        char buf[5];    /* "\r\n.\r\n" */
  3186. -+
  3187. -+        fread(buf, 1, 5, ser_rd_fp);
  3188. -+        rawbytes = -1;
  3189. -+    }
  3190. -+    return n;
  3191. -+}
  3192. -+
  3193. -+
  3194. - /*
  3195. -  * close_server -- close the connection to the server, after sending
  3196. -@@ -633,3 +703,2 @@
  3197. -     (void) fclose(ser_rd_fp);
  3198. - }
  3199. --
  3200. -Index: common/clientlib.h
  3201. -@@ -9,3 +9,5 @@
  3202. - extern    void    put_server();
  3203. - extern    int    get_server();
  3204. -+extern    long    rawcheck_server();
  3205. -+extern    long    rawget_server();
  3206. - extern    void    close_server();
  3207. -Index: common/conf.h.dist
  3208. ++char    nntp_version[] = "1.5.11t2 (14 December 1992)";
  3209. +Index:common/conf.h.dist
  3210.  @@ -95,4 +95,19 @@
  3211.               /* loaded already, defining this may be a bad idea */
  3212. @@ -172,5 +83,5 @@
  3213.   #endif
  3214.   
  3215. -Index: common/nntp.h
  3216. +Index:common/nntp.h
  3217.  @@ -49,4 +49,5 @@
  3218.   #define    OK_AUTHSYS    280    /* Authorization system ok */
  3219. @@ -179,5 +90,5 @@
  3220.   
  3221.   #define    CONT_XFER    335    /* Continue to send article */
  3222. -Index: server/Makefile
  3223. +Index:server/Makefile
  3224.  @@ -7,5 +7,5 @@
  3225.       newgroups.o newnews.o nextlast.o ngmatch.o post.o parsit.o scandir.o \
  3226. @@ -194,5 +105,5 @@
  3227.   
  3228.   SRVRINC = common.h ../common/conf.h ../common/nntp.h timer.h
  3229. -Index: server/common.h
  3230. +Index:server/common.h
  3231.  @@ -164,4 +164,9 @@
  3232.   extern    char    inews[];
  3233. @@ -205,5 +116,5 @@
  3234.   
  3235.   extern    char    **group_array;
  3236. -Index: server/globals.c
  3237. +Index:server/globals.c
  3238.  @@ -27,4 +27,9 @@
  3239.   char    rnews[] = RNEWS;
  3240. @@ -216,5 +127,5 @@
  3241.   /*
  3242.    * Other random externals.
  3243. -Index: server/group.c
  3244. +Index:server/group.c
  3245.  @@ -5,4 +5,8 @@
  3246.   #include "common.h"
  3247. @@ -226,20 +137,87 @@
  3248.   /*
  3249.    * GROUP newsgroup
  3250. -@@ -97,4 +101,8 @@
  3251. +@@ -98,4 +102,8 @@
  3252.       ingroup = 1;
  3253. -+
  3254.  +#ifdef    XTHREAD
  3255.  +    threadfile = thread_name(argv[1]);
  3256.  +#endif
  3257. ++
  3258.       while ((cp = index(argv[1], '/')) != (char *) NULL)
  3259. -Index: server/help.c
  3260. -@@ -22,6 +22,13 @@
  3261. +         *cp = '.';
  3262. +@@ -109,2 +117,63 @@
  3263. +     (void) fflush(stdout);
  3264. + }
  3265. ++
  3266. ++#ifdef LISTGROUP
  3267. ++/*
  3268. ++ * LISTGROUP [group]
  3269. ++ *
  3270. ++ * Lists all article numbers (filenames) in the given group. Used by
  3271. ++ * newsreaders such as nn and trn for fast validation of a database.
  3272. ++ * If a group name is given it becomes the current group.
  3273. ++ *
  3274. ++ * This command is an extention, and not included in RFC 977.
  3275. ++ */
  3276. ++
  3277. ++listgroup(argc, argv)
  3278. ++    int        argc;
  3279. ++    char        *argv[];
  3280. ++{
  3281. ++    register int i;
  3282. ++
  3283. ++    if (argc == 2) {
  3284. ++        ingroup = 0;
  3285. ++        /* This will output a success or failure message */
  3286. ++        group(argc, argv);
  3287. ++        if (!ingroup) {
  3288. ++            return;
  3289. ++        }
  3290. ++    } else if (argc > 2) {
  3291. ++        printf("%d Usage: LISTGROUP [newsgroup].\r\n", ERR_CMDSYN);
  3292. ++        (void) fflush(stdout);
  3293. ++        return;
  3294. ++    } else if (!ingroup) {
  3295. ++        printf("%d You are not currently in a newsgroup.\r\n",
  3296. ++            ERR_NCING);
  3297. ++        (void) fflush(stdout);
  3298. ++        return;
  3299. ++    } else if (!canread) {
  3300. ++        printf("%d You only have permission to transfer, sorry.\r\n",
  3301. ++            ERR_ACCESS);
  3302. ++        (void) fflush(stdout);
  3303. ++        return;
  3304. ++    } else {
  3305. ++        /* output a success message when no group name is given */
  3306. ++        printf("%d %d %d %d (current group)\r\n",
  3307. ++            OK_GROUP,
  3308. ++            num_arts,
  3309. ++            (num_arts > 0 ? art_array[0] : 0),
  3310. ++            (num_arts > 0 ? art_array[num_arts-1] : 0));
  3311. ++    }
  3312. ++
  3313. ++#ifdef LOG
  3314. ++    syslog(LOG_INFO, "%s listgroup", hostname);
  3315. ++#endif
  3316. ++    for (i = 0; i < num_arts; i++) {
  3317. ++        printf("%d\r\n", art_array[i]);
  3318. ++    }
  3319. ++    putchar('.');
  3320. ++    putchar('\r');
  3321. ++    putchar('\n');
  3322. ++    (void) fflush(stdout);
  3323. ++}
  3324. ++
  3325. ++#endif /* LISTGROUP */
  3326. +Index:server/help.c
  3327. +@@ -22,6 +22,16 @@
  3328.       printf("STAT        NEWGROUPS    HELP\r\n");
  3329.       printf("IHAVE       NEWNEWS      SLAVE\r\n");
  3330.  -    printf("\r\nAdditionally, the following extention is supported:\r\n\r\n");
  3331. -+#if defined(XHDR) || defined(XTHREAD)
  3332. -+    printf("\r\nAdditionally, the following extentions are supported:\r\n\r\n");
  3333. ++#if defined(XHDR) || defined(XTHREAD) || defined(LISTGROUP)
  3334. ++    printf("\r\nAdditionally, the following extensions are supported:\r\n\r\n");
  3335. ++# ifdef LISTGROUP
  3336. ++    printf("LISTGROUP   Retrieve a list of valid article-numbers.\r\n");
  3337. ++# endif LISTGROUP
  3338.  +# ifdef    XHDR
  3339.       printf("XHDR        Retrieve a single header line from a range of articles.\r\n");
  3340. @@ -251,5 +229,33 @@
  3341.       printf("\r\n");
  3342.       printf("Bugs to Stan Barber (Internet: nntp@tmc.edu; UUCP: ...!bcm!nntp)\r\n");
  3343. -Index: server/serve.c
  3344. +Index:server/newgroups.c
  3345. +@@ -24,4 +24,5 @@
  3346. +     long        date;
  3347. +     register FILE    *date_fp;
  3348. ++    char        *reqlist[2];
  3349. +     if (argc < 3) {
  3350. +@@ -97,4 +98,20 @@
  3351. +         if (distcount == 0) {
  3352. ++#ifdef ACTIVE_TIMES_FILE
  3353. ++            reqlist[0] = line;
  3354. ++#else
  3355. ++            reqlist[0] = cp + 1;
  3356. ++#endif
  3357. ++            reqlist[1] = NULL;
  3358. ++
  3359. ++            if (ngpermcount) {
  3360. ++                if (ngmatch(s1strneql, ALLBUT,
  3361. ++                    ngpermlist, ngpermcount, reqlist, 1) == 0) {
  3362. ++                     continue;
  3363. ++                }
  3364. ++            } else if (ALLBUT == 0) {
  3365. ++                continue;
  3366. ++            }
  3367. ++
  3368. + #ifdef ACTIVE_TIMES_FILE
  3369. +             putline(line);
  3370. +Index:server/serve.c
  3371.  @@ -27,5 +27,5 @@
  3372.   extern    int    ahbs(), group(), help(), ihave();
  3373. @@ -256,8 +262,16 @@
  3374.   extern    int    list(), newgroups(), newnews(), nextlast(), post();
  3375.  -extern    int    slave(), stat(), xhdr();
  3376. -+extern    int    slave(), stat(), xhdr(), xthread();
  3377. ++extern    int    slave(), stat(), listgroup(), xhdr(), xthread();
  3378.   
  3379.   extern int errno;
  3380. -@@ -62,4 +62,7 @@
  3381. +@@ -53,4 +53,7 @@
  3382. +     "last",        0,    nextlast,
  3383. +     "list",        0,    list,
  3384. ++#ifdef LISTGROUP
  3385. ++    "listgroup",    0,    listgroup,
  3386. ++#endif LISTGROUP
  3387. +     "newgroups",    0,    newgroups,
  3388. +     "newnews",    0,    newnews,
  3389. +@@ -62,4 +65,7 @@
  3390.       "xhdr",        0,    xhdr,
  3391.   #endif XHDR
  3392. @@ -267,5 +281,5 @@
  3393.   };
  3394.   #define NUMCMDS (sizeof(cmdtbl) / sizeof(struct cmdent))
  3395. -Index: server/xthread.c
  3396. +Index:server/xthread.c
  3397.  @@ -0,0 +1,152 @@
  3398.  +/* This file (and only this file - not the entire nntp distribution) is
  3399. @@ -401,5 +415,5 @@
  3400.  +{
  3401.  +    static char name_buff[MAXPATHLEN];
  3402. -+#ifndef LONG_THREAD_NAMES
  3403. ++#ifdef LONG_THREAD_NAMES
  3404.  +    char group_buff[512];
  3405.  +    register char *ptr;
  3406. @@ -407,6 +421,6 @@
  3407.  +    strcpy(group_buff, group);
  3408.  +    ptr = group = group_buff;
  3409. -+    while ((ptr = index(ptr, '.'))) {
  3410. -+        *ptr = '/';
  3411. ++    while ((ptr = index(ptr, '/'))) {
  3412. ++        *ptr = '.';
  3413.  +    }
  3414.  +#endif
  3415. Index:rcln.c
  3416. @@ -1,5 +1,8 @@
  3417. -/* $Id: rcln.c,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
  3418. +/* $Id: rcln.c,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  3419.   *
  3420.   * $Log: rcln.c,v $
  3421. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  3422. + * Release 4.4 Patchlevel 3
  3423. + *
  3424.   * Revision 4.4.2.1  1991/12/01  18:05:42  sob
  3425.   * Patchlevel 2 changes
  3426. Index:rcln.h
  3427. @@ -1,5 +1,8 @@
  3428. -/* $Id: rcln.h,v 4.4 1991/09/09 20:27:37 sob Exp sob $
  3429. +/* $Id: rcln.h,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  3430.   *
  3431.   * $Log: rcln.h,v $
  3432. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  3433. + * Release 4.4 Patchlevel 3
  3434. + *
  3435.   * Revision 4.4  1991/09/09  20:27:37  sob
  3436.   * release 4.4
  3437. Index:rcstuff.c
  3438. @@ -1,5 +1,8 @@
  3439. -/* $Id: rcstuff.c,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
  3440. +/* $Id: rcstuff.c,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  3441.   *
  3442.   * $Log: rcstuff.c,v $
  3443. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  3444. + * Release 4.4 Patchlevel 3
  3445. + *
  3446.   * Revision 4.4.2.1  1991/12/01  18:05:42  sob
  3447.   * Patchlevel 2 changes
  3448. Index:rcstuff.h
  3449. @@ -1,5 +1,8 @@
  3450. -/* $Id: rcstuff.h,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
  3451. +/* $Id: rcstuff.h,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  3452.   *
  3453.   * $Log: rcstuff.h,v $
  3454. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  3455. + * Release 4.4 Patchlevel 3
  3456. + *
  3457.   * Revision 4.4.2.1  1991/12/01  18:05:42  sob
  3458.   * Patchlevel 2 changes
  3459. Index:respond.c
  3460. @@ -1,5 +1,8 @@
  3461. -/* $Id: respond.c,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
  3462. +/* $Id: respond.c,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  3463.   *
  3464.   * $Log: respond.c,v $
  3465. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  3466. + * Release 4.4 Patchlevel 3
  3467. + *
  3468.   * Revision 4.4.2.1  1991/12/01  18:05:42  sob
  3469.   * Patchlevel 2 changes
  3470. @@ -314,5 +317,5 @@
  3471.      safecpy(altbuf,filexp(s),sizeof altbuf);
  3472.      s = altbuf;
  3473. -    if (! index(s,'/')) {
  3474. +    if (*s != '/') {
  3475.          interp(buf, (sizeof buf), getval("SAVEDIR",SAVEDIR));
  3476.          if (makedir(buf,MD_DIR))    /* ensure directory exists */
  3477. @@ -531,4 +534,5 @@
  3478.      int myuid = getuid();
  3479.      int r = -1;
  3480. +    bool incl_body = (*buf == 'Z');
  3481.  
  3482.      if (artopen(art) == Nullfp) {
  3483. @@ -578,4 +582,13 @@
  3484.      interp(buf, (sizeof buf), getval("SUPERSEDEHEADER",SUPERSEDEHEADER));
  3485.      fputs(buf,tmpfp);
  3486. +    if (incl_body && artfp != Nullfp) {
  3487. +#ifdef ASYNC_PARSE
  3488. +        parse_maybe(art);
  3489. +#endif
  3490. +        fseek(artfp,(long)htype[PAST_HEADER].ht_minpos,0);
  3491. +        while (fgets(buf,LBUFLEN,artfp) != Nullch) {
  3492. +        fputs(buf,tmpfp);
  3493. +        }
  3494. +    }
  3495.      fclose(tmpfp);
  3496.          safecpy(cmd_buf,filexp(getval("NEWSPOSTER",NEWSPOSTER)),
  3497. Index:respond.h
  3498. @@ -1,5 +1,8 @@
  3499. -/* $Id: respond.h,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
  3500. +/* $Id: respond.h,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  3501.   *
  3502.   * $Log: respond.h,v $
  3503. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  3504. + * Release 4.4 Patchlevel 3
  3505. + *
  3506.   * Revision 4.4.2.1  1991/12/01  18:05:42  sob
  3507.   * Patchlevel 2 changes
  3508. Index:rt-rn.c
  3509. @@ -1,8 +1,3 @@
  3510. -/* $Id: rt-rn.c,v 4.4.3.1 1991/11/22 04:12:18 davison Trn $
  3511. -**
  3512. -** $Log: rt-rn.c,v $
  3513. -** Revision 4.4.3.1  1991/11/22  04:12:18  davison
  3514. -** Trn Release 2.0
  3515. -** 
  3516. +/* $Id: rt-rn.c,v 2.3 1992/12/14 00:14:00 davison Trn $
  3517.  */
  3518.  
  3519. @@ -26,4 +21,5 @@
  3520.  
  3521.  static void find_depth(), cache_tree(), display_tree();
  3522. +static PACKED_ARTICLE *first_sib(), *last_sib();
  3523.  static char letter();
  3524.  
  3525. @@ -340,4 +336,7 @@
  3526.          header_indent = ++cp - line;
  3527.          line = cp;
  3528. +        if (!*line) {
  3529. +            *--line = ' ';
  3530. +        }
  3531.          }
  3532.          i = 0;
  3533. @@ -664,5 +663,4 @@
  3534.  **   u - mark entire thread as "unread".
  3535.  **   U - mark this article and its descendants as "unread".
  3536. -**   x - go through the unread articles and just chase their xrefs.
  3537.  **   f - follow the thread (like 'n'), but don't attempt to find a new thread
  3538.  **     if we run off the end.
  3539. @@ -676,9 +674,6 @@
  3540.      bool subthread_flag, chase_flag;
  3541.  
  3542. -    reread = FALSE;
  3543. +    reread = (cmd == 'N');
  3544.  
  3545. -    if (cmd == 'N') {
  3546. -    reread = TRUE;
  3547. -    }
  3548.      if (!p_art) {
  3549.      if (ThreadedGroup && art > lastart) {
  3550. @@ -705,5 +700,5 @@
  3551.  
  3552.      /* Some commands encompass the entire thread */
  3553. -    if (cmd == 'k' || cmd == 'j' || cmd == 'J' || cmd == 'u' || cmd == 'x') {
  3554. +    if (cmd == 'k' || cmd == 'j' || cmd == 'J' || cmd == 'u') {
  3555.      p_art = p_articles + p_roots[p_art->root].articles;
  3556.      art = p_art->num;
  3557. @@ -727,12 +722,4 @@
  3558.      scan_all_roots = FALSE;
  3559.      }
  3560. -    if (cmd == 'x') {
  3561. -    if (olden_days) {
  3562. -        return;
  3563. -    }
  3564. -    if ((p_art->flags & HAS_XREFS) && !was_read(art)) {
  3565. -        chase_xrefs(art, TRUE);
  3566. -    }
  3567. -    }
  3568.    follow_again:
  3569.      selected = (selected_roots[p_art->root] & 1);
  3570. @@ -739,5 +726,9 @@
  3571.      root_limit = upper_limit(p_art, subthread_flag);
  3572.      for (;;) {
  3573. -    if (++p_art == root_limit) {
  3574. +    if (Ctl(cmd) == Ctl('n') || cmd == 'f')
  3575. +        next_art();
  3576. +    else
  3577. +        p_art++;
  3578. +    if (p_art == root_limit) {
  3579.          break;
  3580.      }
  3581. @@ -752,8 +743,4 @@
  3582.      } else if (cmd == 'U') {
  3583.          set_unread(art, selected);
  3584. -    } else if (cmd == 'x') {
  3585. -        if ((p_art->flags & HAS_XREFS) && !was_read(art)) {
  3586. -        chase_xrefs(art, TRUE);
  3587. -        }
  3588.      } else if (!was_read(art)
  3589.          && (curr_subj < 0 || curr_subj == p_art->subject)) {
  3590. @@ -815,4 +802,40 @@
  3591.  }
  3592.  
  3593. +/* Bump p_art to the next article.  Honors the breadth_first flag.
  3594. +*/
  3595. +void
  3596. +next_art()
  3597. +{
  3598. +    if (breadth_first) {
  3599. +    for (;;) {
  3600. +        if (p_art->siblings) {
  3601. +        p_art += p_art->siblings;
  3602. +        return;                    /* RETURN */
  3603. +        }
  3604. +        if (p_art->parent) {
  3605. +        p_art += p_art->parent + 1;
  3606. +        } else {
  3607. +        p_art = p_articles + p_roots[p_art->root].articles;
  3608. +        }
  3609. +        for (;;) {
  3610. +        if (p_art->child_cnt) {
  3611. +            p_art++;
  3612. +            return;                /* RETURN */
  3613. +        }
  3614. +        while (!p_art->siblings) {
  3615. +            if (!p_art->parent) {
  3616. +            p_art = upper_limit(p_art, FALSE);
  3617. +            return;                /* RETURN */
  3618. +            }
  3619. +            p_art += p_art->parent;
  3620. +        }
  3621. +        p_art += p_art->siblings;
  3622. +        }/* for */
  3623. +    }/* for */
  3624. +    } else {
  3625. +    p_art++;
  3626. +    }
  3627. +}
  3628. +
  3629.  /* Go backward in the article tree.  Options match commands in article mode:
  3630.  **    p - previous unread article.
  3631. @@ -986,4 +1009,114 @@
  3632.      return p_articles + (artp->root == total.root-1 ?
  3633.      total.article : p_roots[artp->root+1].articles);
  3634. +}
  3635. +
  3636. +/* Find the next "sibling" of this article, including cousins that are
  3637. +** the same distance from the root as we are.
  3638. +*/
  3639. +PACKED_ARTICLE *
  3640. +find_next_sib()
  3641. +{
  3642. +    PACKED_ARTICLE *ta, *tb;
  3643. +    int ascent;
  3644. +
  3645. +    ascent = 0;
  3646. +    ta = p_art;
  3647. +    for (;;) {
  3648. +    while (ta->siblings) {
  3649. +        ta += ta->siblings;
  3650. +        if (tb = first_sib(ta, ascent)) {
  3651. +        return tb;
  3652. +        }
  3653. +    }
  3654. +    if (!ta->parent) {
  3655. +        break;
  3656. +    }
  3657. +    ta += ta->parent;
  3658. +    ascent++;
  3659. +    }
  3660. +    return Nullart;
  3661. +}
  3662. +
  3663. +/* A recursive routine to find the first node at the proper depth.  This
  3664. +** article is at depth 0.
  3665. +*/
  3666. +static PACKED_ARTICLE *
  3667. +first_sib(ta, depth)
  3668. +PACKED_ARTICLE *ta;
  3669. +int depth;
  3670. +{
  3671. +    PACKED_ARTICLE *tb;
  3672. +
  3673. +    if (!depth) {
  3674. +    return ta;
  3675. +    }
  3676. +    for (;;) {
  3677. +    if (ta->child_cnt && (tb = first_sib(ta+1, depth-1))) {
  3678. +        return tb;
  3679. +    }
  3680. +    if (!ta->siblings) {
  3681. +        return Nullart;
  3682. +    }
  3683. +    ta += ta->siblings;
  3684. +    }
  3685. +}
  3686. +
  3687. +/* Find the previous "sibling" of this article, including cousins that are
  3688. +** the same distance from the root as we are.
  3689. +*/
  3690. +PACKED_ARTICLE *
  3691. +find_prev_sib()
  3692. +{
  3693. +    PACKED_ARTICLE *ta, *tb;
  3694. +    int i, ascent;
  3695. +
  3696. +    ascent = 0;
  3697. +    ta = p_art;
  3698. +    for (;;) {
  3699. +    tb = ta;
  3700. +    if (ta->parent) {
  3701. +        ta += ta->parent + 1;
  3702. +    } else {
  3703. +        ta = p_articles + p_roots[ta->root].articles;
  3704. +    }
  3705. +    if (tb = last_sib(ta, ascent, tb)) {
  3706. +        return tb;
  3707. +    }
  3708. +    if (!ta->parent) {
  3709. +        break;
  3710. +    }
  3711. +    ta += ta->parent;
  3712. +    ascent++;
  3713. +    }
  3714. +    return Nullart;
  3715. +}
  3716. +
  3717. +/* A recursive routine to find the last node at the proper depth.  This
  3718. +** article is at depth 0.
  3719. +*/
  3720. +static PACKED_ARTICLE *
  3721. +last_sib(ta, depth, limit)
  3722. +PACKED_ARTICLE *ta;
  3723. +int depth;
  3724. +PACKED_ARTICLE *limit;
  3725. +{
  3726. +    PACKED_ARTICLE *tb, *tc;
  3727. +
  3728. +    if (ta == limit) {
  3729. +    return Nullart;
  3730. +    }
  3731. +    if (ta->siblings) {
  3732. +    tc = ta+ta->siblings;
  3733. +    if (tc != limit && (tb = last_sib(tc,depth,limit))) {
  3734. +        return tb;
  3735. +    }
  3736. +    }
  3737. +    if (!depth) {
  3738. +    return ta;
  3739. +    }
  3740. +    if (ta->child_cnt) {
  3741. +    return last_sib(ta+1, depth-1, limit);
  3742. +    }
  3743. +    return Nullart;
  3744.  }
  3745.  
  3746. Index:rt-select.c
  3747. @@ -1,8 +1,3 @@
  3748. -/* $Id: rt-select.c,v 4.4.3.1 1991/11/22 04:12:18 davison Trn $
  3749. -**
  3750. -** $Log: rt-select.c,v $
  3751. -** Revision 4.4.3.1  1991/11/22  04:12:18  davison
  3752. -** Trn Release 2.0
  3753. -** 
  3754. +/* $Id: rt-select.c,v 2.3 1992/12/14 00:14:12 davison Trn $
  3755.  */
  3756.  
  3757. @@ -426,6 +421,22 @@
  3758.              putchar('\n');
  3759.          }
  3760. -        printf("Type ? for help.");
  3761. -        settle_down();
  3762. +        if (ch == 'c') {
  3763. +            if ((ch = ask_catchup()) == 'y' || ch == 'u') {
  3764. +            ch = 'q';
  3765. +            break;
  3766. +            }
  3767. +            if (ch != 'N') {
  3768. +            ch = Ctl('l');
  3769. +            break;
  3770. +            }
  3771. +            if (can_home) {
  3772. +            carriage_return();
  3773. +            erase_eol();
  3774. +            }
  3775. +            printf("Aborted.");
  3776. +        } else {
  3777. +            printf("Type ? for help.");
  3778. +            settle_down();
  3779. +        }
  3780.          displayed_status = TRUE;
  3781.  
  3782. @@ -499,5 +510,4 @@
  3783.                  p_art = p_articles + p_roots[r].articles;
  3784.                  art = 0;
  3785. -                follow_thread('x');
  3786.              }
  3787.              /* FALL THROUGH */
  3788. @@ -585,5 +595,5 @@
  3789.                  p_art = p_articles + p_roots[j].articles;
  3790.                  art = 0;
  3791. -                follow_thread('j');
  3792. +                follow_thread('J');
  3793.                  }
  3794.              }
  3795. @@ -617,6 +627,11 @@
  3796.  
  3797.          running_total = 0;
  3798. +        last_running = 0;
  3799.          if (article_count) {
  3800.              for (j = 0; j < page_root; j++) {
  3801. +            last_running += root_article_cnts[j];
  3802. +            }
  3803. +            running_total = last_running;
  3804. +            for ( ; j < i; j++) {
  3805.              running_total += root_article_cnts[j];
  3806.              }
  3807. @@ -680,5 +695,5 @@
  3808.              p_art = p_articles + p_roots[j].articles;
  3809.              art = 0;
  3810. -            follow_thread((selected_roots[j] & 4) ? 'j' : 'J');
  3811. +            follow_thread('J');
  3812.          }
  3813.          }
  3814. @@ -693,6 +708,4 @@
  3815.          cur_root = 0;
  3816.          } else {
  3817. -        if (!output_chase_phrase)
  3818. -            ch = 'o';
  3819.          break;
  3820.          }
  3821. @@ -737,13 +750,12 @@
  3822.          if (!selected_root_cnt) {
  3823.            register r = root_hold[cur_root];
  3824. -        selected_roots[r] = mask;
  3825. -        selected_root_cnt++;
  3826. -        selected_count += root_article_cnts[r];
  3827. +        if (unread_selector || !(selected_roots[r] & 4)) {
  3828. +            selected_roots[r] = mask;
  3829. +            selected_root_cnt++;
  3830. +            selected_count += root_article_cnts[r];
  3831. +        }
  3832.          }
  3833.      }
  3834.      } while ((ch == '>' && i < max_root) || ch == '<');
  3835. -    if (ch != 'o') {
  3836. -    putchar('\n') FLUSH;
  3837. -    }
  3838.  
  3839.      if (unread_selector) {
  3840. @@ -771,7 +783,10 @@
  3841.          p_art = p_articles + p_roots[j].articles;
  3842.          art = 0;
  3843. -        follow_thread('j');
  3844. +        follow_thread('J');
  3845.          }
  3846.      }
  3847. +    }
  3848. +    if (!output_chase_phrase) {
  3849. +    putchar('\n') FLUSH;
  3850.      }
  3851.      if (ch == 'U') {
  3852. Index:rthreads.c
  3853. @@ -1,8 +1,3 @@
  3854. -/* $Id: rthreads.c,v 4.4.3.1 1991/11/22 04:12:18 davison Trn $
  3855. -**
  3856. -** $Log: rthreads.c,v $
  3857. -** Revision 4.4.3.1  1991/11/22  04:12:18  davison
  3858. -** Trn Release 2.0
  3859. -** 
  3860. +/* $Id: rthreads.c,v 2.3 1992/12/14 00:14:13 davison Trn $
  3861.  */
  3862.  
  3863. @@ -59,5 +54,5 @@
  3864.  # endif
  3865.      put_server(ser_line);
  3866. -    rawcheck_server(ser_line, sizeof ser_line);
  3867. +    size = rawcheck_server(ser_line, sizeof ser_line);
  3868.  # ifdef DEBUGGING
  3869.      if (debug & DEB_NNTP) {
  3870. @@ -65,5 +60,10 @@
  3871.      }
  3872.  # endif
  3873. -    size = rawget_server((char*)&mt_bmap, sizeof (BMAP));
  3874. +    if (size < 0) {
  3875. +    printf("\nYour NNTP server isn't XTHREAD-compliant.\n") FLUSH;
  3876. +    use_threads = FALSE;
  3877. +    return;
  3878. +    }
  3879. +    size = rawget_server((char*)&mt_bmap, (long)sizeof (BMAP));
  3880.      if (size >= sizeof (BMAP) - 1) {
  3881.  #else /* !XTHREAD */
  3882. @@ -91,5 +91,5 @@
  3883.      }
  3884.  #ifdef XTHREAD
  3885. -    while (rawget_server(ser_line, sizeof ser_line)) {
  3886. +    while (rawget_server(ser_line, (long)sizeof ser_line)) {
  3887.      ;        /* trash any extraneous bytes */
  3888.      }
  3889. @@ -240,15 +240,4 @@
  3890.      }
  3891.  
  3892. -    if (total.last > lastart) {
  3893. -#ifdef SERVER
  3894. -    if (time(Null(time_t*)) - lastactfetch > MINFETCHTIME) {
  3895. -        fclose(actfp);
  3896. -        ngdata_init();    /* re-grab the active file */
  3897. -    }
  3898. -#endif
  3899. -    grow_ctl(total.last);    /* sets lastart */
  3900. -    ngmax[ng] = lastart;    /* ensure getngsize() knows the new maximum */
  3901. -    }
  3902. -
  3903.      if (!read_item(&author_cnts, (MEM_SIZE)total.author * sizeof (WORD))
  3904.       || !read_item(&strings, (MEM_SIZE)total.string1) 
  3905. @@ -309,4 +298,15 @@
  3906.          }
  3907.      }
  3908. +    }
  3909. +
  3910. +    if (total.last > lastart) {
  3911. +#ifdef SERVER
  3912. +    if (time(Null(time_t*)) - lastactfetch > MINFETCHTIME) {
  3913. +        fclose(actfp);
  3914. +        ngdata_init();    /* re-grab the active file */
  3915. +    }
  3916. +#endif
  3917. +    grow_ctl(total.last);    /* sets lastart */
  3918. +    ngmax[ng] = lastart;    /* ensure getngsize() knows the new maximum */
  3919.      }
  3920.      count_roots(!saved_selections);
  3921. Index:rthreads.h
  3922. @@ -1,8 +1,3 @@
  3923. -/* $Id: rthreads.h,v 4.4.3.1 1991/11/22 04:12:18 davison Trn $
  3924. -**
  3925. -** $Log: rthreads.h,v $
  3926. -** Revision 4.4.3.1  1991/11/22  04:12:18  davison
  3927. -** Trn Release 2.0
  3928. -** 
  3929. +/* $Id: rthreads.h,v 2.3 1992/12/14 00:14:15 davison Trn $
  3930.  */
  3931.  
  3932. @@ -47,4 +42,5 @@
  3933.  int finish_tree ANSI((ART_LINE));
  3934.  void first_art ANSI((void));
  3935. +void next_art ANSI((void));
  3936.  void follow_thread ANSI((char_int));
  3937.  void backtrack_thread ANSI((char_int));
  3938. @@ -51,4 +47,5 @@
  3939.  void next_root ANSI((void));
  3940.  void prev_root ANSI((void));
  3941. +void next_article ANSI((void));
  3942.  char select_thread ANSI((char_int));
  3943.  int count_roots ANSI((bool_int));
  3944. @@ -55,4 +52,6 @@
  3945.  int count_one_root ANSI((int));
  3946.  PACKED_ARTICLE *upper_limit ANSI((PACKED_ARTICLE *,bool_int));
  3947. +PACKED_ARTICLE *find_prev_sib ANSI((void));
  3948. +PACKED_ARTICLE *find_next_sib ANSI((void));
  3949.  
  3950.  #define Nullart Null(PACKED_ARTICLE*)
  3951. Index:search.c
  3952. @@ -1,5 +1,8 @@
  3953. -/* $Id: search.c,v 4.4 1991/09/09 20:27:37 sob Exp sob $
  3954. +/* $Id: search.c,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  3955.   *
  3956.   * $Log: search.c,v $
  3957. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  3958. + * Release 4.4 Patchlevel 3
  3959. + *
  3960.   * Revision 4.4  1991/09/09  20:27:37  sob
  3961.   * release 4.4
  3962. @@ -388,4 +391,5 @@
  3963.          p1++;
  3964.      } while (*p1 && !err);
  3965. +    if (err) err = 0;
  3966.      return Nullch;
  3967.      }
  3968. @@ -399,4 +403,5 @@
  3969.          p1++;
  3970.      } while (*p1 && !err);
  3971. +    if (err) err = 0;
  3972.      return Nullch;
  3973.      }
  3974. Index:server.c
  3975. @@ -37,4 +37,75 @@
  3976.  }
  3977.  
  3978. -#endif /* SERVER */
  3979. +# ifdef XTHREAD
  3980. +
  3981. +extern FILE *ser_rd_fp;
  3982. +
  3983. +static    long    rawbytes = -1;    /* bytes remaining to be transfered */
  3984. +
  3985. +/*
  3986. + * rawcheck_server -- get a line of text from the server, interpreting
  3987. + * it as a status message for a raw (binary) command.  Call this once
  3988. + * before calling rawget_server() for the actual data transfer.
  3989. + *
  3990. + *    Parameters:    "string" has the buffer space for the
  3991. + *            line received.
  3992. + *            "size" is the size of the buffer.
  3993. + *
  3994. + *    Returns:    -1 on error, otherwise the length of the raw data.
  3995. + *
  3996. + *    Side effects:    Talks to server, changes contents of "string".
  3997. + */
  3998. +long
  3999. +rawcheck_server(string, size)
  4000. +char    *string;
  4001. +int    size;
  4002. +{
  4003. +    /* try to get the status line and the status code */
  4004. +    if (get_server(string, size) || *string != CHAR_OK)
  4005. +    return rawbytes = -1;
  4006. +
  4007. +    /* try to get the number of bytes being transfered */
  4008. +    if (sscanf(string, "%*d%ld", &rawbytes) != 1)
  4009. +    return rawbytes = -1;
  4010. +    return rawbytes;
  4011. +}
  4012.  
  4013. +/*
  4014. + * rawget_server -- read data from the server in raw format.  This call must
  4015. + * follow an appropriate put_server command and a rawcheck_server call.
  4016. + *
  4017. + *    Parameters:    "buf" is the buffer for the data to receive.
  4018. + *            "n" is the size of the buffer.
  4019. + *
  4020. + *    Returns:    0 on EOF, otherwise the length of the read.
  4021. + *
  4022. + *    Side effects:    Talks to server, changes contents of "buf".
  4023. + */
  4024. +long
  4025. +rawget_server(buf, n)
  4026. +void    *buf;
  4027. +long    n;
  4028. +{
  4029. +    /* if no bytes to read, then just return EOF */
  4030. +    if (rawbytes < 0)
  4031. +    return 0;
  4032. +
  4033. +    /* try to read some data from the server */
  4034. +    if (rawbytes) {
  4035. +    n = fread(buf, 1, n > rawbytes ? rawbytes : n, ser_rd_fp);
  4036. +    rawbytes -= n;
  4037. +    } else
  4038. +    n = 0;
  4039. +
  4040. +    /* if no more left, then fetch the end-of-command signature */
  4041. +    if (!rawbytes) {
  4042. +    char buf[5];    /* "\r\n.\r\n" */
  4043. +
  4044. +    fread(buf, 1, 5, ser_rd_fp);
  4045. +    rawbytes = -1;
  4046. +    }
  4047. +    return n;
  4048. +}
  4049. +# endif
  4050. +
  4051. +#endif /* SERVER */
  4052. Index:server.h.SH
  4053. @@ -39,8 +39,12 @@
  4054.  EXT     char ser_line[NNTP_STRLEN];
  4055.  
  4056. -# if defined(XTHREAD) && !defined(OK_BIN)
  4057. -     ??????  /* This version of NNTP doesn't have XTHREAD support */
  4058. +# ifdef HAVE_INN    /* if so, map NNTP defines into INN defines */
  4059. +#  define CHAR_OK    NNTP_CLASS_OK
  4060. +#  define CHAR_FATAL    NNTP_CLASS_FATAL
  4061. +#  define ERR_NOGROUP    NNTP_NOSUCHGROUP_VAL
  4062. +#  define OK_NOPOST    NNTP_NOPOSTOK_VAL
  4063. +#  define OK_CANPOST    NNTP_POSTOK_VAL
  4064. +#  define ERR_ACCESS    NNTP_ACCESS_VAL
  4065.  # endif
  4066. -
  4067.  #endif
  4068.  !GROK!THIS!
  4069. Index:sw.c
  4070. @@ -1,5 +1,8 @@
  4071. -/* $Id: sw.c,v 4.4 1991/09/09 20:27:37 sob Exp sob $
  4072. +/* $Id: sw.c,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  4073.   *
  4074.   * $Log: sw.c,v $
  4075. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  4076. + * Release 4.4 Patchlevel 3
  4077. + *
  4078.   * Revision 4.4  1991/09/09  20:27:37  sob
  4079.   * release 4.4
  4080. @@ -45,7 +48,5 @@
  4081.      sw_file(tcbufptr,FALSE);
  4082.  #ifdef USETHREADS
  4083. -    if (use_threads)
  4084. -    safecpy(*tcbufptr,getval("TRNINIT",getenv("RNINIT")),1024);
  4085. -    else
  4086. +    if (!use_threads || !*safecpy(*tcbufptr,getenv("TRNINIT"),1024))
  4087.  #endif
  4088.      safecpy(*tcbufptr,getenv("RNINIT"),1024);
  4089. @@ -199,6 +200,10 @@
  4090.  #endif
  4091.          break;
  4092. -    case 'c':
  4093. -        checkflag = upordown;
  4094. +    case 'b':
  4095. +#ifdef USETHREADS
  4096. +        breadth_first = upordown;
  4097. +#else
  4098. +        notincl("-b");
  4099. +#endif
  4100.          break;
  4101.      case 'C':
  4102. @@ -291,4 +296,7 @@
  4103.          initlines_specified = TRUE;
  4104.          break;
  4105. +    case 'j':
  4106. +        dont_filter_control = TRUE;
  4107. +        break;
  4108.      case 'l':
  4109.          muck_up_clear = upordown;
  4110. @@ -452,4 +460,5 @@
  4111.      printf("%c/ ", mp[strEQ(getval("SAVEDIR",SAVEDIR),"%p/%c")]);
  4112.      printf("%ca ", mp[thread_always]);
  4113. +    printf("%cb ", mp[breadth_first]);
  4114.      printf("%cc ", mp[checkflag]);
  4115.      printf("-C%d ", docheckwhen);
  4116. @@ -474,4 +483,5 @@
  4117.  #endif
  4118.      printf("-i%d ", initlines);
  4119. +    printf("%cj ", mp[dont_filter_control]);
  4120.      printf("%cl ", mp[muck_up_clear]);
  4121.  #ifdef CLEAREOL
  4122. Index:sw.h
  4123. @@ -1,5 +1,8 @@
  4124. -/* $Id: sw.h,v 4.4 1991/09/09 20:27:37 sob Exp sob $
  4125. +/* $Id: sw.h,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  4126.   *
  4127.   * $Log: sw.h,v $
  4128. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  4129. + * Release 4.4 Patchlevel 3
  4130. + *
  4131.   * Revision 4.4  1991/09/09  20:27:37  sob
  4132.   * release 4.4
  4133. Index:term.c
  4134. @@ -1,5 +1,8 @@
  4135. -/* $Id: term.c,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
  4136. +/* $Id: term.c,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  4137.   *
  4138.   * $Log: term.c,v $
  4139. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  4140. + * Release 4.4 Patchlevel 3
  4141. + *
  4142.   * Revision 4.4.2.1  1991/12/01  18:05:42  sob
  4143.   * Patchlevel 2 changes
  4144. Index:term.h
  4145. @@ -1,5 +1,8 @@
  4146. -/* $Id: term.h,v 4.4 1991/09/09 20:27:37 sob Exp sob $
  4147. +/* $Id: term.h,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  4148.   *
  4149.   * $Log: term.h,v $
  4150. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  4151. + * Release 4.4 Patchlevel 3
  4152. + *
  4153.   * Revision 4.4  1991/09/09  20:27:37  sob
  4154.   * release 4.4
  4155. Index:threads.c
  4156. @@ -1,8 +1,3 @@
  4157. -/* $Id: threads.c,v 4.4.3.1 1991/11/22 04:12:21 davison Trn $
  4158. -**
  4159. -** $Log:    threads.c,v $
  4160. -** Revision 4.4.3.1  1991/11/22  04:12:21  davison
  4161. -** Trn Release 2.0
  4162. -** 
  4163. +/* $Id: threads.c,v 2.3 1992/12/14 00:14:08 davison Trn $
  4164.  */
  4165.  
  4166. Index:threads.h
  4167. @@ -1,8 +1,3 @@
  4168. -/* $Id: threads.h,v 4.4.3.1 1991/11/22 04:12:21 davison Trn $
  4169. -**
  4170. -** $Log:    threads.h,v $
  4171. -** Revision 4.4.3.1  1991/11/22  04:12:21  davison
  4172. -** Trn Release 2.0
  4173. -** 
  4174. +/* $Id: threads.h,v 2.3 1992/12/14 00:14:09 davison Trn $
  4175.  */
  4176.  
  4177. Index:tm-process.c
  4178. @@ -1,8 +1,3 @@
  4179. -/* $Id: tm-process.c,v 4.4.3.1 1991/11/22 04:12:21 davison Trn $
  4180. -**
  4181. -** $Log: tm-process.c,v $
  4182. -** Revision 4.4.3.1  1991/11/22  04:12:21  davison
  4183. -** Trn Release 2.0
  4184. -** 
  4185. +/* $Id: tm-process.c,v 2.3 1992/12/14 00:14:16 davison Trn $
  4186.  */
  4187.  
  4188. Index:tm-read.c
  4189. @@ -1,8 +1,3 @@
  4190. -/* $Id: tm-read.c,v 4.4.3.1 1991/11/22 04:12:21 davison Trn $
  4191. -**
  4192. -** $Log: tm-read.c,v $
  4193. -** Revision 4.4.3.1  1991/11/22  04:12:21  davison
  4194. -** Trn Release 2.0
  4195. -** 
  4196. +/* $Id: tm-read.c,v 2.3 1992/12/14 00:14:17 davison Trn $
  4197.  */
  4198.  
  4199. Index:tm-write.c
  4200. @@ -1,8 +1,3 @@
  4201. -/* $Id: tm-write.c,v 4.4.3.1 1991/11/22 04:12:21 davison Trn $
  4202. -**
  4203. -** $Log: tm-write.c,v $
  4204. -** Revision 4.4.3.1  1991/11/22  04:12:21  davison
  4205. -** Trn Release 2.0
  4206. -** 
  4207. +/* $Id: tm-write.c,v 2.3 1992/12/14 00:14:18 davison Trn $
  4208.  */
  4209.  
  4210. Index:tmpthread.c
  4211. @@ -1,8 +1,3 @@
  4212. -/* $Id: tmpthread.c,v 4.4.3.1 1991/11/22 04:12:21 davison Trn $
  4213. -**
  4214. -** $Log: tmpthread.c,v $
  4215. -** Revision 4.4.3.1  1991/11/22  04:12:21  davison
  4216. -** Trn Release 2.0
  4217. -** 
  4218. +/* $Id: tmpthread.c,v 2.3 1992/12/14 00:14:19 davison Trn $
  4219.  */
  4220.  
  4221. @@ -22,11 +17,4 @@
  4222.  #include "mthreads.h"
  4223.  
  4224. -#ifdef TZSET
  4225. -#include <time.h>
  4226. -#else
  4227. -#include <sys/time.h>
  4228. -#include <sys/timeb.h>
  4229. -#endif
  4230. -
  4231.  struct stat filestat;
  4232.  
  4233. @@ -176,5 +164,5 @@
  4234.      put_server("XTHREAD DBINIT");
  4235.      rawcheck_server(buf, sizeof buf);
  4236. -    size = rawget_server((char*)&mt_bmap, sizeof (BMAP));
  4237. +    size = rawget_server((char*)&mt_bmap, (long)sizeof (BMAP));
  4238.      if (size < sizeof (BMAP) - 1) {
  4239.  #else
  4240. @@ -204,5 +192,5 @@
  4241.      }
  4242.  #ifdef XTHREAD
  4243. -    while (rawget_server(buf, sizeof buf)) {
  4244. +    while (rawget_server(buf, (long)sizeof buf)) {
  4245.          ;        /* trash any extraneous bytes */
  4246.      }
  4247. Index:trn.1
  4248. @@ -1,3 +1,3 @@
  4249. -.\" $Id: trn.1,v 4.4.3.1 1991/11/22 04:13:39 davison Trn $
  4250. +.\" $Id: trn.1,v 2.3 1992/12/14 00:14:10 davison Trn $
  4251.  .\" 
  4252.  .\" This software is Copyright 1991 by Stan Barber. 
  4253. @@ -396,5 +396,5 @@
  4254.  Select the discussion thread by its letter or number;
  4255.  press again to deselect.
  4256. -By default the letters h, k, n, p, q, and y are omitted to allow them
  4257. +By default the letters c, h, k, n, p, q, and y are omitted to allow them
  4258.  to be typed as commands.
  4259.  See the variable SELECTCHARS to customize this.
  4260. @@ -439,4 +439,7 @@
  4261.  Mark unselected articles on the current page as read.
  4262.  Begin reading if articles are selected, otherwise go to the next page.
  4263. +.Ip c 8
  4264. +Catch up\*(--marks ALL articles as read without affecting their cross-posted
  4265. +counterparts.
  4266.  .Ip ^K 8
  4267.  Edit the local KILL file for this newsgroup.
  4268. @@ -463,5 +466,5 @@
  4269.  searching in the Article Selection section.
  4270.  .Sp
  4271. -One example:  to scan all the unread articles looking for \*(L"topic\*(L"
  4272. +One example:  to scan all the unread articles looking for \*(L"topic\*(R"
  4273.  anywhere in the article and then select its thread and save the article to
  4274.  the files topic.1, topic.2, etc. use \*(L"/topic/a:+:s topic.%#\*(R".
  4275. @@ -563,4 +566,6 @@
  4276.  Proceeds to the very first/last node if you're already at a root/leaf in
  4277.  a multi-root thread.
  4278. +.Ip "(,)" 8
  4279. +Go to the previous/next sibling in the thread, including \*(L"cousin\*(R" siblings.
  4280.  .Ip t 8
  4281.  Display the entire article tree and all its associated subjects.
  4282. @@ -596,5 +601,5 @@
  4283.  Applicable commands include \*(L'm\*(R' (mark as unread), \*(L'M\*(R'
  4284.  (delayed mark as unread), \*(L'j\*(R' (mark as read), \*(L"s dest\*(R"
  4285. -(save to a destination), \*(L"e dir"\*(R" (extract to directory),
  4286. +(save to a destination), \*(L"e dir\*(R" (extract to directory),
  4287.  \&\*(L"!command\*(R" (shell escape), \*(L"=\*(R" (print the subject),
  4288.  \&\*(L'T\*(R' (trash the thread into the local KILL file), \*(L'+\*(R'
  4289. @@ -650,5 +655,5 @@
  4290.  Applicable commands include \*(L'm\*(R' (mark as unread), \*(L'M\*(R'
  4291.  (delayed mark as unread), \*(L'j\*(R' (mark as read), \*(L"s dest\*(R"
  4292. -(save to a destination), \*(L"e dir"\*(R" (extract to directory),
  4293. +(save to a destination), \*(L"e dir\*(R" (extract to directory),
  4294.  \&\*(L"!command\*(R" (shell escape), \*(L"=\*(R" (print the subject),
  4295.  \&\*(L'T\*(R' (trash the associated thread and put it in the local KILL
  4296. @@ -1083,4 +1088,8 @@
  4297.  if no thread file for the group exists.
  4298.  .TP 5
  4299. +.B \-b
  4300. +will force trn to read each thread in a breadth-first order, rather than
  4301. +depth-first.
  4302. +.TP 5
  4303.  .B \-c
  4304.  checks for news without reading news.
  4305. @@ -1227,4 +1236,7 @@
  4306.  switch.)
  4307.  .TP 5
  4308. +.B \-j
  4309. +forces trn to leave control characters unmolested in messages.
  4310. +.TP 5
  4311.  .B \-l
  4312.  disables the clearing of the screen at the beginning of each
  4313. @@ -1848,5 +1860,5 @@
  4314.  Default:
  4315.  .Sp
  4316. -To: %T
  4317. +To: %t
  4318.  .br
  4319.  Subject: %(%i=^$?:Re: %S
  4320. @@ -1878,8 +1890,8 @@
  4321.  Default: %X/mbox.saver %A %P %c %a %B %C "%b" \e
  4322.  .br
  4323. -"From: %T %`date`"
  4324. +"From %T %`date`"
  4325.  .Sp
  4326.  Explanation: the first seven arguments are the same as for NORMSAVER.
  4327. -The eighth argument to the shell script is the new From: line
  4328. +The eighth argument to the shell script is the new From line
  4329.  for the article, including the posting date,
  4330.  derived either directly from the Posted: line, or not-so-directly from
  4331. Index:util.c
  4332. @@ -1,5 +1,11 @@
  4333. -/* $Id: util.c,v 4.4 1991/09/09 20:27:37 sob Exp sob $
  4334. +/* $Id: util.c,v 4.4.4.1 1992/02/23 21:25:39 sob PATCH_4 sob $
  4335.   *
  4336.   * $Log: util.c,v $
  4337. + * Revision 4.4.4.1  1992/02/23  21:25:39  sob
  4338. + * Patch level 4
  4339. + *
  4340. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  4341. + * Release 4.4 Patchlevel 3
  4342. + *
  4343.   * Revision 4.4  1991/09/09  20:27:37  sob
  4344.   * release 4.4
  4345. @@ -27,11 +33,4 @@
  4346.  #include "util.h"
  4347.  
  4348. -#ifdef TZSET
  4349. -#include <time.h>
  4350. -#else
  4351. -#include <sys/time.h>
  4352. -#include <sys/timeb.h>
  4353. -#endif
  4354. -
  4355.  void
  4356.  util_init()
  4357. @@ -78,4 +77,5 @@
  4358.      signal(SIGQUIT, SIG_IGN);
  4359.  #endif 
  4360. +    termlib_reset();
  4361.      waiting = TRUE;
  4362.      while ((w = wait(&status)) != pid)
  4363. @@ -84,4 +84,5 @@
  4364.      if (w == -1)
  4365.      status = -1;
  4366. +    termlib_init();
  4367.      waiting = FALSE;
  4368.      sigset(SIGINT, int_catcher);    /* always catch interrupts */
  4369. @@ -512,5 +513,5 @@
  4370.  #endif
  4371.  
  4372. -#ifndef STRFTIME
  4373. +#if defined(USETHREADS) && !defined(STRFTIME)
  4374.  /*
  4375.   * strftime: print formatted information about a given time.
  4376. @@ -706,5 +707,5 @@
  4377.          break;
  4378.      case 't':    /* same as \t */
  4379. -        putstr = "\n";
  4380. +        putstr = "\t";
  4381.          break;
  4382.      default:
  4383. @@ -727,3 +728,3 @@
  4384.      return num;
  4385.  }
  4386. -#endif /* no STRFTIME */
  4387. +#endif /* USETHREADS && no STRFTIME */
  4388. Index:uudecode.c
  4389. @@ -1,5 +1,8 @@
  4390. -/* $Id: uudecode.c,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
  4391. +/* $Id: uudecode.c,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
  4392.   *
  4393.   * $Log: uudecode.c,v $
  4394. + * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  4395. + * Release 4.4 Patchlevel 3
  4396. + *
  4397.   * Revision 4.4.2.1  1991/12/01  18:05:42  sob
  4398.   * Patchlevel 2 changes
  4399. ---8<------8<------8<------8<---cut here--->8------>8------>8------>8---
  4400.