home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / unix / volume27 / mthreads / part01 < prev    next >
Encoding:
Text File  |  1993-11-20  |  93.6 KB  |  3,509 lines

  1. Newsgroups: comp.sources.unix
  2. From: davison@borland.com (Wayne Davison)
  3. Subject: v27i090: mthreads - netnews database generator/manager, V3.1, Part01/04
  4. Message-id: <1.753873779.13611@gw.home.vix.com>
  5. Sender: unix-sources-moderator@gw.home.vix.com
  6. Approved: vixie@gw.home.vix.com
  7.  
  8. Submitted-By: davison@borland.com (Wayne Davison)
  9. Posting-Number: Volume 27, Issue 90
  10. Archive-Name: mthreads/part01
  11.  
  12. [ Tomorrow i'm going to post trn-3.3, and this package is a prerequisite
  13.   for any site who wishes to use TRN in thread mode and does not have INN.
  14.   The text below is from the README file.                --vix ]
  15.  
  16. What is mthreads?
  17. -------------------
  18. Mthreads is a news database manager that processes one or more newsgroups
  19. into a tree-structured list of articles related by their References and
  20. Subject lines.  The result for each group you enable is a .thread file
  21. that trn (i.e. Threaded Read News) can read in to get a quick summary of
  22. the articles in the group and how they are releated.  Mthreads takes up
  23. about 3 - 5% of your news-spool if you enable all groups.
  24.  
  25. Where to send bug reports
  26. -------------------------
  27. Mail your bug reports to Wayne Davison <davison@borland.com>.  If you type
  28. "mthreads -V" you will be reminded of this address should you forget.
  29.  
  30. #! /bin/sh
  31. # This is a shell archive.  Remove anything before this line, then unpack
  32. # it by saving it into a file and typing "sh file".  To overwrite existing
  33. # files, type "sh file -c".  You can also feed this as standard input via
  34. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  35. # will see the following message at the end:
  36. #        "End of archive 1 (of 4)."
  37. # Contents:  EXTERN.h INSTALL INTERN.h MANIFEST Makefile.SH NEW README
  38. #   common.h config.h.SH dependencies hints hints/aix_rs.sh
  39. #   hints/altos486.sh hints/convexos.sh hints/dec_osf1.sh
  40. #   hints/dgux.sh hints/domainos.sh hints/dynix.sh hints/hp9000_800.sh
  41. #   hints/hpux.sh hints/i386.sh hints/isc_2_2_1.sh hints/isc_3_2_2.sh
  42. #   hints/isc_3_2_3.sh hints/mc6000.sh hints/mips.sh hints/next.sh
  43. #   hints/osf1.sh hints/sco_3.sh hints/sco_3_2_4.sh hints/sco_xenix.sh
  44. #   hints/sgi.sh hints/solaris_2_0.sh hints/solaris_2_1.sh
  45. #   hints/solaris_2_2.sh hints/sunos_4_1.sh hints/svr4.sh
  46. #   makedepend.SH makedir.SH mt-misc.c mt-write.c mt.check.SH
  47. #   mthreads.h ndir.c ndir.h nntpclient.c nntpclient.h nntpinit.c
  48. #   patchlevel.h thread.h unipatch.c
  49. # Wrapped by vixie@gw.home.vix.com on Sun Nov 21 01:11:59 1993
  50. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  51. if test -f 'EXTERN.h' -a "${1}" != "-c" ; then 
  52.   echo shar: Will not clobber existing file \"'EXTERN.h'\"
  53. else
  54. echo shar: Extracting \"'EXTERN.h'\" \(725 characters\)
  55. sed "s/^X//" >'EXTERN.h' <<'END_OF_FILE'
  56. X/* $Id: EXTERN.h,v 3.0 1991/09/09 20:18:23 davison Trn $
  57. X */
  58. X/* This software is Copyright 1991 by Stan Barber. 
  59. X *
  60. X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  61. X * use this software as long as: there is no monetary profit gained
  62. X * specifically from the use or reproduction of this software, it is not
  63. X * sold, rented, traded or otherwise marketed, and this copyright notice is
  64. X * included prominently in any copy made. 
  65. X *
  66. X * The authors make no claims as to the fitness or correctness of this software
  67. X * for any use whatsoever, and it is provided as is. Any use of this software
  68. X * is at the user's own risk. 
  69. X */
  70. X
  71. X#undef EXT
  72. X#define EXT extern
  73. X
  74. X#undef INIT
  75. X#define INIT(x)
  76. X
  77. X#undef DOINIT
  78. END_OF_FILE
  79. if test 725 -ne `wc -c <'EXTERN.h'`; then
  80.     echo shar: \"'EXTERN.h'\" unpacked with wrong size!
  81. fi
  82. # end of 'EXTERN.h'
  83. fi
  84. if test -f 'INSTALL' -a "${1}" != "-c" ; then 
  85.   echo shar: Will not clobber existing file \"'INSTALL'\"
  86. else
  87. echo shar: Extracting \"'INSTALL'\" \(2142 characters\)
  88. sed "s/^X//" >'INSTALL' <<'END_OF_FILE'
  89. XInstallation Instructions for mthreads 3.0:
  90. X
  91. X1)  Run Configure.  This will figure out various things about your system.
  92. X    Some things Configure will figure out for itself, other things it will
  93. X    ask you about.  It will then proceed to make config.h, config.sh, the
  94. X    Makefile, and a few shell scripts.  You might possibly have to trim
  95. X    # comments from the front of Configure if your sh doesn't handle them,
  96. X    but all other # comments will be taken care of.
  97. X
  98. X2)  Glance through config.h and common.h to make sure system dependencies
  99. X    are correct.  Most of them should have been taken care of by running
  100. X    the Configure script.
  101. X
  102. X    If you have any additional changes to make to the C definitions, they
  103. X    can be done in the Makefile, in config.h, or in common.h.
  104. X
  105. X3)  make
  106. X
  107. X    This will attempt to make mthreads in the current directory.
  108. X
  109. X4)  make install
  110. X
  111. X    This will put mthreads and its support files into the directory
  112. X    of your choosing.  It also tries to put the mthreads man page in
  113. X    a reasonable place.
  114. X
  115. X5)  Read the manual entry before running mthreads to familiarize yourself
  116. X    with its operation and options.
  117. X
  118. X6)  IMPORTANT!  Help save the world!  Communicate any problems and suggested
  119. X    patches to Wayne Davison <davison@borland.com> so we can keep the world
  120. X    in sync.  If you have a problem, there's someone else out there who
  121. X    either has had or will have the same problem.
  122. X
  123. X    If possible, send in patches such that the patch program will apply them.
  124. X    Unified or regular context diffs are the best, then normal diffs.  Don't
  125. X    send ed scripts--I've probably changed my copy since the version you have.
  126. X
  127. X    Watch for mthreads patches in news.software.readers.  Patches will be
  128. X    in the unified context diff format, for application by the patch program.
  129. X    If you don't have a patch program that handles unified context diffs,
  130. X    you'll probably want to get one (such as patch version 12g8).  Otherwise,
  131. X    you can use the (included) filter "unipatch", which can be generated with
  132. X    the command "make unipatch".  To apply patches, use the command:
  133. X
  134. X    unipatch <patchfile | patch -p
  135. END_OF_FILE
  136. if test 2142 -ne `wc -c <'INSTALL'`; then
  137.     echo shar: \"'INSTALL'\" unpacked with wrong size!
  138. fi
  139. # end of 'INSTALL'
  140. fi
  141. if test -f 'INTERN.h' -a "${1}" != "-c" ; then 
  142.   echo shar: Will not clobber existing file \"'INTERN.h'\"
  143. else
  144. echo shar: Extracting \"'INTERN.h'\" \(768 characters\)
  145. sed "s/^X//" >'INTERN.h' <<'END_OF_FILE'
  146. X/* $Id: INTERN.h,v 3.0 1991/09/09 20:18:23 davison Trn $
  147. X */
  148. X/* This software is Copyright 1991 by Stan Barber. 
  149. X *
  150. X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  151. X * use this software as long as: there is no monetary profit gained
  152. X * specifically from the use or reproduction of this software, it is not
  153. X * sold, rented, traded or otherwise marketed, and this copyright notice is
  154. X * included prominently in any copy made. 
  155. X *
  156. X * The authors make no claims as to the fitness or correctness of this software
  157. X * for any use whatsoever, and it is provided as is. Any use of this software
  158. X * is at the user's own risk. 
  159. X */
  160. X
  161. X#undef EXT
  162. X#define EXT
  163. X
  164. X#undef INIT
  165. X#ifdef xenix
  166. X#define INIT(x) =x
  167. X#else
  168. X#define INIT(x) = x
  169. X#endif
  170. X
  171. X#define DOINIT
  172. END_OF_FILE
  173. if test 768 -ne `wc -c <'INTERN.h'`; then
  174.     echo shar: \"'INTERN.h'\" unpacked with wrong size!
  175. fi
  176. # end of 'INTERN.h'
  177. fi
  178. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  179.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  180. else
  181. echo shar: Extracting \"'MANIFEST'\" \(1863 characters\)
  182. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  183. X   File Name        Archive #    Description
  184. X-----------------------------------------------------------
  185. X Configure                  4    
  186. X EXTERN.h                   1    
  187. X INSTALL                    1    
  188. X INTERN.h                   1    
  189. X MANIFEST                   1    
  190. X Makefile.SH                1    
  191. X NEW                        1    
  192. X README                     1    
  193. X common.h                   1    
  194. X config.h.SH                1    
  195. X dependencies               1    
  196. X hints                      1    
  197. X hints/aix_rs.sh            1    
  198. X hints/altos486.sh          1    
  199. X hints/convexos.sh          1    
  200. X hints/dec_osf1.sh          1    
  201. X hints/dgux.sh              1    
  202. X hints/domainos.sh          1    
  203. X hints/dynix.sh             1    
  204. X hints/hp9000_800.sh        1    
  205. X hints/hpux.sh              1    
  206. X hints/i386.sh              1    
  207. X hints/isc_2_2_1.sh         1    
  208. X hints/isc_3_2_2.sh         1    
  209. X hints/isc_3_2_3.sh         1    
  210. X hints/mc6000.sh            1    
  211. X hints/mips.sh              1    
  212. X hints/next.sh              1    
  213. X hints/osf1.sh              1    
  214. X hints/sco_3.sh             1    
  215. X hints/sco_3_2_4.sh         1    
  216. X hints/sco_xenix.sh         1    
  217. X hints/sgi.sh               1    
  218. X hints/solaris_2_0.sh       1    
  219. X hints/solaris_2_1.sh       1    
  220. X hints/solaris_2_2.sh       1    
  221. X hints/sunos_4_1.sh         1    
  222. X hints/svr4.sh              1    
  223. X makedepend.SH              1    
  224. X makedir.SH                 1    
  225. X mt-misc.c                  1    
  226. X mt-process.c               3    
  227. X mt-read.c                  2    
  228. X mt-write.c                 1    
  229. X mt.check.SH                1    
  230. X mthreads.8                 2    
  231. X mthreads.c                 2    
  232. X mthreads.h                 1    
  233. X ndir.c                     1    
  234. X ndir.h                     1    
  235. X nntpclient.c               1    
  236. X nntpclient.h               1    
  237. X nntpinit.c                 1    
  238. X parsedate.y                2    
  239. X patchlevel.h               1    
  240. X thread.h                   1    
  241. X unipatch.c                 1    
  242. END_OF_FILE
  243. if test 1863 -ne `wc -c <'MANIFEST'`; then
  244.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  245. fi
  246. # end of 'MANIFEST'
  247. fi
  248. if test -f 'Makefile.SH' -a "${1}" != "-c" ; then 
  249.   echo shar: Will not clobber existing file \"'Makefile.SH'\"
  250. else
  251. echo shar: Extracting \"'Makefile.SH'\" \(2482 characters\)
  252. sed "s/^X//" >'Makefile.SH' <<'END_OF_FILE'
  253. Xcase $CONFIG in
  254. X    '') . ./config.sh ;;
  255. Xesac
  256. Xecho "Extracting Makefile (with variable substitutions)"
  257. X$cat >Makefile <<!GROK!THIS!
  258. X# $Id: Makefile.SH,v 3.0 1992/03/01 02:13:32 davison Trn $
  259. X
  260. XCC = $cc
  261. Xmtlib = $installprivlib
  262. Xmansrc = $installmansrc
  263. Xmanext = $manext
  264. XCFLAGS = $optimize $ccflags
  265. XLDFLAGS = $ldflags
  266. X#NNTPNNTPFLAGS = $nntpflags
  267. Xndirc = $ndirc
  268. Xndiro = $ndiro
  269. X
  270. Xlibs = $libndir $jobslib -lm $libs
  271. X!GROK!THIS!
  272. X$cat >>Makefile <<'!NO!SUBS!'
  273. X
  274. Xpublic = mthreads mt.check
  275. Xprivate = makedir filexp
  276. Xmanpages = mthreads.8
  277. Xutil = Makefile makedepend
  278. X#NNTPnntpsrc=nntpinit.c nntpclient.c
  279. X#NNTPnntpobj=nntpinit.o nntpclient.o
  280. X
  281. Xh = common.h mthreads.h threads.h
  282. X
  283. Xc = mthreads.c mt-read.c mt-process.c mt-write.c mt-misc.c $(ndirc) $(nntpsrc)
  284. X
  285. Xobj = mthreads.o mt-read.o mt-process.o mt-write.o mt-misc.o parsedate.o \
  286. X    $(ndiro) $(nntpobj)
  287. X
  288. Xaddedbymake = Makefile.old mt.check config.h makedepend makedir mthreads all
  289. X
  290. X# grrr
  291. XSHELL = /bin/sh
  292. X
  293. X.c.o:
  294. X    $(CC) -c $(CFLAGS) $*.c
  295. X
  296. Xall: $(public) $(private) $(util)
  297. X    touch all
  298. X
  299. Xmthreads: $(obj)
  300. X    $(CC) $(LDFLAGS) $(obj) $(libs) -o mthreads
  301. X#NNTP
  302. X#NNTPnntpinit.o:
  303. X#NNTP    $(CC) -c $(CFLAGS) $(NNTPFLAGS) $*.c
  304. X
  305. Xunipatch: unipatch.o
  306. X    $(CC) $(LDFLAGS) unipatch.o -o unipatch
  307. X
  308. X# if a .h file depends on another .h file...
  309. X$(h):
  310. X    -touch $@
  311. X
  312. Xinstall: $(public) $(private) $(manpages)
  313. X# won't work with csh
  314. X    export PATH || exit 1
  315. X    - ./makedir `./filexp $(mtlib)`
  316. X    - cd `./filexp $(mtlib)`; mv mthreads mthreads.old
  317. X    - if test `pwd` != `./filexp $(mtlib)`; then cp $(public) `./filexp $(mtlib)`; fi
  318. X    - if test `pwd` != `./filexp $(mtlib)`; then cp $(private) `./filexp $(mtlib)`; fi
  319. X    - if test `pwd` != `./filexp $(mtlib)`; then strip `./filexp $(mtlib)`/mthreads ; fi
  320. X    - if test "X$(mansrc)" != "X" -a "X`pwd`" != X$(mansrc); then \
  321. Xfor page in $(manpages); do \
  322. Xdest=$(mansrc)/`basename $$page .8`.$(manext); \
  323. Xrm -f $$dest; cp $$page $$dest; chmod 444 $$dest; \
  324. Xdone; \
  325. Xfi
  326. X
  327. Xclean:
  328. X    @ echo 'Use "make realclean" to remove the executables and Configure droppings.'
  329. X    @ echo 'Use "make spotless" to also remove config.sh'
  330. X    rm -f *.o
  331. X
  332. Xrealclean: clean
  333. X    rm -f core $(addedbymake)
  334. X
  335. Xspotless: realclean
  336. X    rm -f config.sh
  337. X
  338. Xdepend: config.h Makefile
  339. X    ./makedepend
  340. X
  341. X# AUTOMATICALLY GENERATED MAKE DEPENDENCIES--PUT NOTHING BELOW THIS LINE
  342. X!NO!SUBS!
  343. X$cat dependencies >>Makefile
  344. Xcase "$d_nntp" in
  345. Xdefine)    sed < Makefile -e '/^#NNTP/s/^#NNTP//' > Makefile.new ;;
  346. X*)    sed < Makefile -e '/^#NNTP/d' > Makefile.new ;;
  347. Xesac
  348. Xmv Makefile.new Makefile
  349. X$eunicefix Makefile
  350. END_OF_FILE
  351. if test 2482 -ne `wc -c <'Makefile.SH'`; then
  352.     echo shar: \"'Makefile.SH'\" unpacked with wrong size!
  353. fi
  354. # end of 'Makefile.SH'
  355. fi
  356. if test -f 'NEW' -a "${1}" != "-c" ; then 
  357.   echo shar: Will not clobber existing file \"'NEW'\"
  358. else
  359. echo shar: Extracting \"'NEW'\" \(320 characters\)
  360. sed "s/^X//" >'NEW' <<'END_OF_FILE'
  361. XThe only major differences between mthreads 2.5 and mthreads 3.0 is the
  362. Xseparation of the mthreads package from the trn package and the use of
  363. Xthe new Configure and nntp client library routines from trn 3.0.
  364. X
  365. XNew for mthreads 3.1, a better Configure script, easier installation, and
  366. Xmore forgiving NNTP server handling.
  367. END_OF_FILE
  368. if test 320 -ne `wc -c <'NEW'`; then
  369.     echo shar: \"'NEW'\" unpacked with wrong size!
  370. fi
  371. # end of 'NEW'
  372. fi
  373. if test -f 'README' -a "${1}" != "-c" ; then 
  374.   echo shar: Will not clobber existing file \"'README'\"
  375. else
  376. echo shar: Extracting \"'README'\" \(1147 characters\)
  377. sed "s/^X//" >'README' <<'END_OF_FILE'
  378. X            Mthreads Kit, Version 3.1
  379. X
  380. X            Copyright (c) 1993, Wayne Davison
  381. X
  382. XYou may copy the mthreads kit in whole or in part as long as you don't try
  383. Xto make money off it, or pretend that you wrote it.
  384. X--------------------------------------------------------------------------
  385. X
  386. XSee the file INSTALL for installation instructions.  Failure to do so
  387. Xmay void your warranty. :-)
  388. X
  389. XAfter you have unpacked your kit, you should have all the files listed
  390. Xin MANIFEST (Configure checks this for you).
  391. X
  392. X
  393. XWhat is mthreads?
  394. X-------------------
  395. XMthreads is a news database manager that processes one or more newsgroups
  396. Xinto a tree-structured list of articles related by their References and
  397. XSubject lines.  The result for each group you enable is a .thread file
  398. Xthat trn (i.e. Threaded Read News) can read in to get a quick summary of
  399. Xthe articles in the group and how they are releated.  Mthreads takes up
  400. Xabout 3 - 5% of your news-spool if you enable all groups.
  401. X
  402. XWhere to send bug reports
  403. X-------------------------
  404. XMail your bug reports to Wayne Davison <davison@borland.com>.  If you type
  405. X"mthreads -V" you will be reminded of this address should you forget.
  406. END_OF_FILE
  407. if test 1147 -ne `wc -c <'README'`; then
  408.     echo shar: \"'README'\" unpacked with wrong size!
  409. fi
  410. # end of 'README'
  411. fi
  412. if test -f 'common.h' -a "${1}" != "-c" ; then 
  413.   echo shar: Will not clobber existing file \"'common.h'\"
  414. else
  415. echo shar: Extracting \"'common.h'\" \(4804 characters\)
  416. sed "s/^X//" >'common.h' <<'END_OF_FILE'
  417. X/* $Id: common.h,v 3.0 1992/02/23 21:25:39 davison $
  418. X */
  419. X/* The authors make no claims as to the fitness or correctness of this software
  420. X * for any use whatsoever, and it is provided as is. Any use of this software
  421. X * is at the user's own risk. 
  422. X */
  423. X
  424. X#include <stdio.h>
  425. X#include <sys/types.h>
  426. X#include <sys/stat.h>
  427. X#include <ctype.h>
  428. X#include "config.h"    /* generated by installation script */
  429. X
  430. X#include <errno.h>
  431. X#include <signal.h>
  432. X#ifdef I_VFORK
  433. X#  include <vfork.h>
  434. X#endif
  435. X
  436. X#ifdef I_UNISTD
  437. X#include <unistd.h>
  438. X#endif
  439. X#ifdef I_STDLIB
  440. X#include <stdlib.h>
  441. X#else
  442. Xchar    *malloc();
  443. Xchar    *realloc();
  444. Xchar    *getenv();
  445. X#endif
  446. X
  447. X#ifdef I_STRING
  448. X#include <string.h>
  449. X#else
  450. X#include <strings.h>
  451. X#endif
  452. X
  453. X#ifdef I_TIME
  454. X#include <time.h>
  455. X#endif
  456. X#ifdef I_SYS_TIME
  457. X#include <sys/time.h>
  458. X#endif
  459. X
  460. X#define BITSPERBYTE 8
  461. X#define LBUFLEN 1024    /* line buffer length */
  462. X#define MAXFILENAME 512
  463. X
  464. X/* some handy defs */
  465. X
  466. X#define bool char
  467. X#define bool_int int
  468. X#define char_int int
  469. X#ifndef TRUE
  470. X#define TRUE (1)
  471. X#endif
  472. X#ifndef FALSE
  473. X#define FALSE (0)
  474. X#endif
  475. X#define Null(t) ((t)0)
  476. X#define Nullch Null(char *)
  477. X#define Nullfp Null(FILE *)
  478. X
  479. X#define Ctl(ch) (ch & 037)
  480. X
  481. X#define strNE(s1,s2) (strcmp(s1,s2))
  482. X#define strEQ(s1,s2) (!strcmp(s1,s2))
  483. X#define strnNE(s1,s2,l) (strncmp(s1,s2,l))
  484. X#define strnEQ(s1,s2,l) (!strncmp(s1,s2,l))
  485. X
  486. X/* Things we can figure out ourselves */
  487. X
  488. X#ifdef EUNICE
  489. X#   define LINKART        /* add 1 level of possible indirection */
  490. X#   define UNLINK(victim) while (!unlink(victim))
  491. X#else
  492. X#   define UNLINK(victim) unlink(victim)
  493. X#endif
  494. X
  495. X/* *** System Dependent Stuff *** */
  496. X
  497. X#define MAKEDIR        /* use our makedir() instead of shell script */
  498. X
  499. X/* NOTE: many of these are defined in the config.h file */
  500. X
  501. X#ifdef NORMSIG
  502. X#   define sigset signal
  503. X#endif
  504. X
  505. X/* news library */
  506. X#ifndef NEWSLIB        /* ~ and %l only ("~%l" is permissable) */
  507. X#   define NEWSLIB "/usr/lib/news"
  508. X#endif
  509. X
  510. X/* path to private executables */
  511. X#ifndef PRIVLIB        /* ~, %x and %l only */
  512. X#   define PRIVLIB "%x/trn"
  513. X#endif
  514. X
  515. X/* where to find news files */
  516. X#ifndef NEWSSPOOL        /* % and ~ */
  517. X#   define NEWSSPOOL "/usr/spool/news"
  518. X#endif
  519. X
  520. X# ifndef NEW_THREAD
  521. X#   define NEW_THREAD ".new"
  522. X# endif
  523. X
  524. X/* file containing list of active newsgroups and max article numbers */
  525. X#ifndef ACTIVE            /* % and ~ */
  526. X#   define ACTIVE "%x/active"
  527. X#endif
  528. X#ifdef USE_NNTP
  529. X#   ifndef ACTIVE1
  530. X#    define ACTIVE1 "%X/active1"
  531. X#   endif
  532. X#endif
  533. X#ifndef ACTIVE2
  534. X#   define ACTIVE2 "%X/active2"
  535. X#endif
  536. X#ifndef DBINIT
  537. X#   define DBINIT "%W/db.init"
  538. X#endif
  539. X#ifndef MTPRELOCK
  540. X#   define MTPRELOCK "%X/LOCK"
  541. X#endif
  542. X#ifndef MTLOCK
  543. X#   define MTLOCK "%X/LOCKmthreads"
  544. X#endif
  545. X#ifndef MTDLOCK
  546. X#   define MTDLOCK "%X/LOCKmtdaemon"
  547. X#endif
  548. X#ifndef MTLOG
  549. X#   define MTLOG "%X/mt.log"
  550. X#endif
  551. X
  552. X/* path to fastest starting shell */
  553. X#ifndef SH
  554. X#   define SH "/bin/sh"
  555. X#endif
  556. X
  557. X#ifndef MAKEDIR
  558. X/* shell script to make n-deep subdirectories */
  559. X#   ifndef DIRMAKER        /* % and ~ */
  560. X#    define DIRMAKER "%X/makedir"
  561. X#   endif
  562. X#endif
  563. X
  564. X/* how to open binary format files */
  565. X#ifndef FOPEN_RB
  566. X#   define FOPEN_RB "r"
  567. X#endif
  568. X#ifndef FOPEN_WB
  569. X#   define FOPEN_WB "w"
  570. X#endif
  571. X
  572. X/* what to do with ansi prototypes -- '()' == ignore, 'x' == use */
  573. X#ifndef _
  574. X#   ifdef __STDC__
  575. X#    define _(x) x
  576. X#   else
  577. X#    define _(x) ()
  578. X#   endif
  579. X#endif
  580. X
  581. X/* some important types */
  582. X
  583. Xtypedef long        ART_NUM;    /* article number */
  584. Xtypedef unsigned int    MEM_SIZE;    /* for passing to malloc */
  585. X
  586. X/* some slight-of-hand for compatibility issues */
  587. X
  588. X#ifdef HAS_STRCHR
  589. X# ifndef index
  590. X#   define index strchr
  591. X# endif
  592. X# ifndef rindex
  593. X#   define rindex strrchr
  594. X# endif
  595. X#endif
  596. X#ifdef HAS_MEMCMP
  597. X# ifndef bcmp
  598. X#   define bcmp(s,d,l) memcmp((s),(d),(l))
  599. X# endif
  600. X#endif
  601. X#ifdef HAS_MEMCPY
  602. X# ifndef bcopy
  603. X#   define bcopy(s,d,l) memcpy((d),(s),(l))
  604. X# endif
  605. X#endif
  606. X#ifdef HAS_MEMSET
  607. X# ifndef bzero
  608. X#   define bzero(s,l) memset((s),0,(l))
  609. X# endif
  610. X#endif
  611. X
  612. X#ifndef HAS_VFORK
  613. X#   define vfork fork
  614. X#endif
  615. X
  616. X/* *** end of the machine dependent stuff *** */
  617. X
  618. X/* GLOBAL THINGS */
  619. X
  620. X/* file statistics area */
  621. X
  622. XEXT struct stat filestat;
  623. X
  624. X/* various things of type char */
  625. X
  626. X#ifdef SUPPLEMENT_STRING_H
  627. Xchar    *index();
  628. Xchar    *rindex();
  629. Xchar    *strcat();
  630. Xchar    *strcpy();
  631. X#endif
  632. X
  633. XEXT char buf[LBUFLEN+1];    /* general purpose line buffer */
  634. X
  635. X/* miscellania */
  636. X
  637. X#ifndef __STDC__
  638. Xint fseek();
  639. Xlong atol(), ftell();
  640. Xextern int errno;
  641. X#endif
  642. X
  643. XEXT char nullstr[1] INIT("");
  644. X
  645. X/* if subscripting is faster than shifting on your machine, define this */
  646. X#undef USESUBSCRIPT
  647. X#ifdef USESUBSCRIPT
  648. XEXT char powerof2[] INIT({1,2,4,8,16,32,64,128});
  649. X#define pow2(x) powerof2[x]
  650. X#else
  651. X#define pow2(x) (1 << (x))
  652. X#endif
  653. X#define OFFSET(a) ((a)-absfirst)
  654. X
  655. X#define ctl_set(a) (ctlarea[(OFFSET(a)) / BITSPERBYTE] |= pow2((OFFSET(a)) % BITSPERBYTE))
  656. X#define ctl_check(a) ((ctlarea[(OFFSET(a)) / BITSPERBYTE] & pow2((OFFSET(a)) % BITSPERBYTE)) != 0)
  657. X
  658. X#define advise(str)
  659. X#define report_error(str) log_entry(str)
  660. END_OF_FILE
  661. if test 4804 -ne `wc -c <'common.h'`; then
  662.     echo shar: \"'common.h'\" unpacked with wrong size!
  663. fi
  664. # end of 'common.h'
  665. fi
  666. if test -f 'config.h.SH' -a "${1}" != "-c" ; then 
  667.   echo shar: Will not clobber existing file \"'config.h.SH'\"
  668. else
  669. echo shar: Extracting \"'config.h.SH'\" \(6750 characters\)
  670. sed "s/^X//" >'config.h.SH' <<'END_OF_FILE'
  671. Xcase $CONFIG in
  672. X'') . ./config.sh ;;
  673. Xesac
  674. Xcase "$0" in
  675. X*/*) cd `expr X$0 : 'X\(.*\)/'` ;;
  676. Xesac
  677. Xecho "Extracting config.h (with variable substitutions)"
  678. Xsed <<!GROK!THIS! >config.h -e 's!^#undef!/\*#define!'
  679. X/*
  680. X * This file was produced by running the config.h.SH script, which
  681. X * gets its values from config.sh, which is generally produced by
  682. X * running Configure.
  683. X *
  684. X * Feel free to modify any of this as the need arises.  Note, however,
  685. X * that running config.h.SH again will wipe out any changes you've made.
  686. X * For a more permanent change edit config.sh and rerun config.h.SH.
  687. X *
  688. X * \$Id: Config_h.U,v 3.0.1.2 1993/08/24 12:13:20 ram Exp $
  689. X */
  690. X
  691. X/* Configuration time: $cf_time
  692. X * Configured by: $cf_by
  693. X * Target system: $myuname
  694. X */
  695. X
  696. X#ifndef _config_h_
  697. X#define _config_h_
  698. X
  699. X/* EUNICE:
  700. X *    This symbol, if defined, indicates that the program is being compiled
  701. X *    under the EUNICE package under VMS.  The program will need to handle
  702. X *    things like files that don't go away the first time you unlink them,
  703. X *    due to version numbering.  It will also need to compensate for lack
  704. X *    of a respectable link() command.
  705. X */
  706. X#$d_eunice EUNICE        /**/
  707. X
  708. X/* HAS_CHSIZE:
  709. X *    This symbol, if defined, indicates that the chsize routine is available
  710. X *    to truncate files.  You might need a -lx to get this routine.
  711. X */
  712. X#$d_chsize    HAS_CHSIZE        /**/
  713. X
  714. X/* HAS_FTRUNCATE:
  715. X *    This symbol, if defined, indicates that the ftruncate() subroutine
  716. X *    exists.
  717. X */
  718. X#$d_ftrncate HAS_FTRUNCATE    /**/
  719. X
  720. X/* HAS_MEMCMP:
  721. X *    This symbol, if defined, indicates that the memcmp routine is available
  722. X *    to compare blocks of memory.
  723. X */
  724. X#$d_memcmp HAS_MEMCMP    /**/
  725. X
  726. X/* HAS_MEMCPY:
  727. X *    This symbol, if defined, indicates that the memcpy routine is available
  728. X *    to copy blocks of memory.
  729. X */
  730. X#$d_memcpy HAS_MEMCPY    /**/
  731. X
  732. X/* HAS_MEMSET:
  733. X *    This symbol, if defined, indicates that the memset routine is available
  734. X *    to set blocks of memory.
  735. X */
  736. X#$d_memset HAS_MEMSET    /**/
  737. X
  738. X/* NORMSIG:
  739. X *    This symbol, if defined, indicates that normal signal handling routines
  740. X *    should be used, as opposed to the ones in 4.1bsd (sigset, etc.).
  741. X */
  742. X#$d_normsig NORMSIG        /**/
  743. X
  744. X/* HAS_RENAME:
  745. X *    This symbol, if defined, indicates that the rename routine is available
  746. X *    to rename files.  Otherwise you should do the unlink(), link(), unlink()
  747. X *    trick.
  748. X */
  749. X#$d_rename HAS_RENAME    /**/
  750. X
  751. X/* HAS_SIGHOLD:
  752. X *    This symbol, if defined, indicates that the sighold routine is
  753. X *    available to hold signals.
  754. X */
  755. X#$d_sighold HAS_SIGHOLD    /**/
  756. X
  757. X/* HAS_STRCHR:
  758. X *    This symbol is defined to indicate that the strchr()/strrchr()
  759. X *    functions are available for string searching. If not, try the
  760. X *    index()/rindex() pair.
  761. X */
  762. X#$d_strchr HAS_STRCHR    /**/
  763. X
  764. X/* HAS_USLEEP:
  765. X *    This symbol, if defined, indicates that the usleep routine is
  766. X *    available to let the process sleep on a sub-second accuracy.
  767. X */
  768. X#$d_usleep HAS_USLEEP        /**/
  769. X
  770. X/* HAS_VFORK:
  771. X *    This symbol, if defined, indicates that vfork() exists.
  772. X */
  773. X#$d_vfork HAS_VFORK    /**/
  774. X
  775. X/* Signal_t:
  776. X *    This symbol's value is either "void" or "int", corresponding to the
  777. X *    appropriate return type of a signal handler.  Thus, you can declare
  778. X *    a signal handler using "Signal_t (*handler)()", and define the
  779. X *    handler using "Signal_t handler(sig)".
  780. X */
  781. X#define Signal_t $signal_t    /* Signal handler's return type */
  782. X
  783. X/* I_DIRENT:
  784. X *    This symbol, if defined, indicates to the C program that it should
  785. X *    include <dirent.h>.
  786. X */
  787. X#$i_dirent I_DIRENT        /**/
  788. X
  789. X/* I_STDLIB:
  790. X *    This symbol, if defined, indicates that <stdlib.h> exists and should
  791. X *    be included.
  792. X */
  793. X#$i_stdlib I_STDLIB        /**/
  794. X
  795. X/* I_STRING:
  796. X *    This symbol, if defined, indicates to the C program that it should
  797. X *    include <string.h> (USG systems) instead of <strings.h> (BSD systems).
  798. X */
  799. X#$i_string I_STRING        /**/
  800. X
  801. X/* I_SYS_DIR:
  802. X *    This symbol, if defined, indicates to the C program that it should
  803. X *    include <sys/dir.h>.
  804. X */
  805. X#$i_sysdir I_SYS_DIR        /**/
  806. X
  807. X/* I_SYS_NDIR:
  808. X *    This symbol, if defined, indicates to the C program that it should
  809. X *    include <sys/ndir.h>.
  810. X */
  811. X#$i_sysndir I_SYS_NDIR    /**/
  812. X
  813. X/* I_UNISTD:
  814. X *    This symbol, if defined, indicates to the C program that it should
  815. X *    include <unistd.h>.
  816. X */
  817. X#$i_unistd I_UNISTD        /**/
  818. X
  819. X/* I_VFORK:
  820. X *    This symbol, if defined, indicates to the C program that it should
  821. X *    include vfork.h.
  822. X */
  823. X#$i_vfork I_VFORK    /**/
  824. X
  825. X/* ACTIVE:
  826. X *    The name of the active file for the news system.  This file contains
  827. X *    the list of active newsgroups.  The name may have ~ on the front.
  828. X */
  829. X/* ACTIVE_TIMES:
  830. X *    The name of the active.times file for the news system.
  831. X */
  832. X#define ACTIVE "$active"        /**/
  833. X#$d_acttimes ACTIVE_TIMES "$acttimes"        /**/
  834. X
  835. X/* USE_NNTP:
  836. X *    This symbol, if defined, indicates that NNTP should be used.
  837. X */
  838. X/* SERVER_NAME:
  839. X *    When using NNTP, this symbol indicates the server name or a
  840. X *    file to open to read the server name.
  841. X */
  842. X#$d_nntp    USE_NNTP    /**/
  843. X#define SERVER_NAME "$servername"      /**/
  844. X
  845. X/* void:
  846. X *    This symbol is used for void functions.  On implementations which
  847. X *    support void appropriately, its value is "void".  Otherwise, its
  848. X *    value should be set to "int".
  849. X */
  850. X#$d_novoid void int    /**/
  851. X
  852. X/* USE_SYSLOG:
  853. X *    This symbol, if defined, indicates that syslog should be used.
  854. X */
  855. X/* SYSLOG_PRIORITY:
  856. X *    This symbol defines the syslog priority when using syslog.
  857. X */
  858. X#$d_syslog USE_SYSLOG    /**/
  859. X#$d_syslog SYSLOG_PRIORITY $syslog    /**/
  860. X
  861. X/* EMULATE_NDIR:
  862. X *    This symbol, if defined, indicates that the program should compile
  863. X *    the ndir.c code provided with the package.
  864. X */
  865. X/* I_NDIR:
  866. X *    This symbol, if defined, indicates that the program should include the
  867. X *    system's version of ndir.h, rather than the one with this package.
  868. X */
  869. X#$d_usendir    EMULATE_NDIR        /**/
  870. X#$d_libndir    I_NDIR        /**/
  871. X
  872. X/* I_TIME:
  873. X *    This symbol, if defined, indicates to the C program that it should
  874. X *    include <time.h>.
  875. X */
  876. X/* I_SYS_TIME:
  877. X *    This symbol, if defined, indicates to the C program that it should
  878. X *    include <sys/time.h>.
  879. X */
  880. X#$i_time I_TIME        /**/
  881. X#$i_systime I_SYS_TIME        /**/
  882. X
  883. X/* NEWSLIB:
  884. X *    This symbol contains the name of the directory serving as the news
  885. X *    library.  The program must be prepared to do ~ expansion on it.
  886. X */
  887. X#define NEWSLIB "$newslib"        /**/
  888. X
  889. X/* NEWSSPOOL:
  890. X *    This symbol contains the directory name where news articles are
  891. X *    spooled.  The program must be prepared to do ~ expansion on it.
  892. X */
  893. X#define NEWSSPOOL "$newsspool"        /**/
  894. X
  895. X/* PRIVLIB:
  896. X *    This symbol contains the name of the private library for this package.
  897. X *    The library is private in the sense that it needn't be in anyone's
  898. X *    execution path, but it should be accessible by the world.  The program
  899. X *    should be prepared to do ~ expansion.
  900. X */
  901. X#define PRIVLIB "$privlib"        /**/
  902. X
  903. X/* THREAD_DIR:
  904. X *    This symbol indicates where the thread files go.
  905. X */
  906. X#define THREAD_DIR    "$threaddir"        /**/
  907. X
  908. X#endif
  909. X!GROK!THIS!
  910. END_OF_FILE
  911. if test 6750 -ne `wc -c <'config.h.SH'`; then
  912.     echo shar: \"'config.h.SH'\" unpacked with wrong size!
  913. fi
  914. # end of 'config.h.SH'
  915. fi
  916. if test -f 'dependencies' -a "${1}" != "-c" ; then 
  917.   echo shar: Will not clobber existing file \"'dependencies'\"
  918. else
  919. echo shar: Extracting \"'dependencies'\" \(1479 characters\)
  920. sed "s/^X//" >'dependencies' <<'END_OF_FILE'
  921. Xmt-misc.o: EXTERN.h
  922. Xmt-misc.o: common.h
  923. Xmt-misc.o: config.h
  924. Xmt-misc.o: mt-misc.c
  925. Xmt-misc.o: mthreads.h
  926. Xmt-misc.o: thread.h
  927. Xmt-process.o: EXTERN.h
  928. Xmt-process.o: common.h
  929. Xmt-process.o: config.h
  930. Xmt-process.o: mt-process.c
  931. Xmt-process.o: mthreads.h
  932. Xmt-process.o: ndir.h
  933. Xmt-process.o: nntpclient.h
  934. Xmt-process.o: thread.h
  935. Xmt-read.o: EXTERN.h
  936. Xmt-read.o: common.h
  937. Xmt-read.o: config.h
  938. Xmt-read.o: mt-read.c
  939. Xmt-read.o: mthreads.h
  940. Xmt-read.o: thread.h
  941. Xmt-write.o: EXTERN.h
  942. Xmt-write.o: common.h
  943. Xmt-write.o: config.h
  944. Xmt-write.o: mt-write.c
  945. Xmt-write.o: mthreads.h
  946. Xmt-write.o: thread.h
  947. Xmthreads.o: EXTERN.h
  948. Xmthreads.o: INTERN.h
  949. Xmthreads.o: common.h
  950. Xmthreads.o: config.h
  951. Xmthreads.o: mthreads.c
  952. Xmthreads.o: mthreads.h
  953. Xmthreads.o: nntpclient.h
  954. Xmthreads.o: patchlevel.h
  955. Xmthreads.o: thread.h
  956. Xndir.o: EXTERN.h
  957. Xndir.o: INTERN.h
  958. Xndir.o: common.h
  959. Xndir.o: config.h
  960. Xndir.o: ndir.c
  961. Xndir.o: ndir.h
  962. Xnntpclient.o: EXTERN.h
  963. Xnntpclient.o: common.h
  964. Xnntpclient.o: config.h
  965. Xnntpclient.o: nntpclient.c
  966. Xnntpinit.o: EXTERN.h
  967. Xnntpinit.o: common.h
  968. Xnntpinit.o: config.h
  969. Xnntpinit.o: nntpclient.h
  970. Xnntpinit.o: nntpinit.c
  971. Xparsedate.o: config.h
  972. Xparsedate.o: parsedate.y
  973. Xunipatch.o: unipatch.c
  974. XMakefile: Makefile.SH config.sh ; /bin/sh Makefile.SH
  975. Xconfig.h: config.h.SH config.sh ; /bin/sh config.h.SH
  976. Xmakedepend: makedepend.SH config.sh ; /bin/sh makedepend.SH
  977. Xmakedir: makedir.SH config.sh ; /bin/sh makedir.SH
  978. Xmt.check: mt.check.SH config.sh ; /bin/sh mt.check.SH
  979. X# WARNING: Put nothing here or make depend will gobble it up!
  980. END_OF_FILE
  981. if test 1479 -ne `wc -c <'dependencies'`; then
  982.     echo shar: \"'dependencies'\" unpacked with wrong size!
  983. fi
  984. # end of 'dependencies'
  985. fi
  986. if test ! -d 'hints' ; then
  987.     echo shar: Creating directory \"'hints'\"
  988.     mkdir 'hints'
  989. fi
  990. if test -f 'hints/aix_rs.sh' -a "${1}" != "-c" ; then 
  991.   echo shar: Will not clobber existing file \"'hints/aix_rs.sh'\"
  992. else
  993. echo shar: Extracting \"'hints/aix_rs.sh'\" \(58 characters\)
  994. sed "s/^X//" >'hints/aix_rs.sh' <<'END_OF_FILE'
  995. Xcppstdin='/lib/cpp -D_AIX -D_IBMR2 -U__STR__'
  996. Xcppminus=''
  997. END_OF_FILE
  998. if test 58 -ne `wc -c <'hints/aix_rs.sh'`; then
  999.     echo shar: \"'hints/aix_rs.sh'\" unpacked with wrong size!
  1000. fi
  1001. # end of 'hints/aix_rs.sh'
  1002. fi
  1003. if test -f 'hints/altos486.sh' -a "${1}" != "-c" ; then 
  1004.   echo shar: Will not clobber existing file \"'hints/altos486.sh'\"
  1005. else
  1006. echo shar: Extracting \"'hints/altos486.sh'\" \(111 characters\)
  1007. sed "s/^X//" >'hints/altos486.sh' <<'END_OF_FILE'
  1008. X: have heard of problems with -lc_s on Altos 486
  1009. Xset `echo " $libswanted " | sed "s/ c_s / /"`
  1010. Xlibswanted="$*"
  1011. END_OF_FILE
  1012. if test 111 -ne `wc -c <'hints/altos486.sh'`; then
  1013.     echo shar: \"'hints/altos486.sh'\" unpacked with wrong size!
  1014. fi
  1015. # end of 'hints/altos486.sh'
  1016. fi
  1017. if test -f 'hints/convexos.sh' -a "${1}" != "-c" ; then 
  1018.   echo shar: Will not clobber existing file \"'hints/convexos.sh'\"
  1019. else
  1020. echo shar: Extracting \"'hints/convexos.sh'\" \(139 characters\)
  1021. sed "s/^X//" >'hints/convexos.sh' <<'END_OF_FILE'
  1022. Xi_sgtty=undef
  1023. Xi_termios=define
  1024. Xccflags="-D__STDC__ -ext -tm c1"
  1025. Xd_voidsig='define'
  1026. Xsignal_t='void'
  1027. Xd_strchr='undef'
  1028. Xlibc='/usr/lib/libc.a'
  1029. END_OF_FILE
  1030. if test 139 -ne `wc -c <'hints/convexos.sh'`; then
  1031.     echo shar: \"'hints/convexos.sh'\" unpacked with wrong size!
  1032. fi
  1033. # end of 'hints/convexos.sh'
  1034. fi
  1035. if test -f 'hints/dec_osf1.sh' -a "${1}" != "-c" ; then 
  1036.   echo shar: Will not clobber existing file \"'hints/dec_osf1.sh'\"
  1037. else
  1038. echo shar: Extracting \"'hints/dec_osf1.sh'\" \(132 characters\)
  1039. sed "s/^X//" >'hints/dec_osf1.sh' <<'END_OF_FILE'
  1040. Xlibpth="$libpth /usr/shlib" # Use the shared libraries if possible
  1041. Xlibc='/usr/shlib/libc.so'   # The archive version is /lib/libc.a
  1042. END_OF_FILE
  1043. if test 132 -ne `wc -c <'hints/dec_osf1.sh'`; then
  1044.     echo shar: \"'hints/dec_osf1.sh'\" unpacked with wrong size!
  1045. fi
  1046. # end of 'hints/dec_osf1.sh'
  1047. fi
  1048. if test -f 'hints/dgux.sh' -a "${1}" != "-c" ; then 
  1049.   echo shar: Will not clobber existing file \"'hints/dgux.sh'\"
  1050. else
  1051. echo shar: Extracting \"'hints/dgux.sh'\" \(60 characters\)
  1052. sed "s/^X//" >'hints/dgux.sh' <<'END_OF_FILE'
  1053. Xcppstdin='/lib/cpp'
  1054. Xlibs='-ldgc'
  1055. Xd_strchr='define'
  1056. Xcc='gcc'
  1057. END_OF_FILE
  1058. if test 60 -ne `wc -c <'hints/dgux.sh'`; then
  1059.     echo shar: \"'hints/dgux.sh'\" unpacked with wrong size!
  1060. fi
  1061. # end of 'hints/dgux.sh'
  1062. fi
  1063. if test -f 'hints/domainos.sh' -a "${1}" != "-c" ; then 
  1064.   echo shar: Will not clobber existing file \"'hints/domainos.sh'\"
  1065. else
  1066. echo shar: Extracting \"'hints/domainos.sh'\" \(40 characters\)
  1067. sed "s/^X//" >'hints/domainos.sh' <<'END_OF_FILE'
  1068. Xccflags='-A nansi'
  1069. Xd_ignoreorg='define'
  1070. END_OF_FILE
  1071. if test 40 -ne `wc -c <'hints/domainos.sh'`; then
  1072.     echo shar: \"'hints/domainos.sh'\" unpacked with wrong size!
  1073. fi
  1074. # end of 'hints/domainos.sh'
  1075. fi
  1076. if test -f 'hints/dynix.sh' -a "${1}" != "-c" ; then 
  1077.   echo shar: Will not clobber existing file \"'hints/dynix.sh'\"
  1078. else
  1079. echo shar: Extracting \"'hints/dynix.sh'\" \(69 characters\)
  1080. sed "s/^X//" >'hints/dynix.sh' <<'END_OF_FILE'
  1081. Xlibswanted=`echo $libswanted | sed -e 's/socket /socket seq inet /'`
  1082. END_OF_FILE
  1083. if test 69 -ne `wc -c <'hints/dynix.sh'`; then
  1084.     echo shar: \"'hints/dynix.sh'\" unpacked with wrong size!
  1085. fi
  1086. # end of 'hints/dynix.sh'
  1087. fi
  1088. if test -f 'hints/hp9000_800.sh' -a "${1}" != "-c" ; then 
  1089.   echo shar: Will not clobber existing file \"'hints/hp9000_800.sh'\"
  1090. else
  1091. echo shar: Extracting \"'hints/hp9000_800.sh'\" \(66 characters\)
  1092. sed "s/^X//" >'hints/hp9000_800.sh' <<'END_OF_FILE'
  1093. Xlibswanted=`echo $libswanted | sed -e 's/malloc //' -e 's/BSD //`
  1094. END_OF_FILE
  1095. if test 66 -ne `wc -c <'hints/hp9000_800.sh'`; then
  1096.     echo shar: \"'hints/hp9000_800.sh'\" unpacked with wrong size!
  1097. fi
  1098. # end of 'hints/hp9000_800.sh'
  1099. fi
  1100. if test -f 'hints/hpux.sh' -a "${1}" != "-c" ; then 
  1101.   echo shar: Will not clobber existing file \"'hints/hpux.sh'\"
  1102. else
  1103. echo shar: Extracting \"'hints/hpux.sh'\" \(114 characters\)
  1104. sed "s/^X//" >'hints/hpux.sh' <<'END_OF_FILE'
  1105. Xcase `(uname -r) 2>/dev/null` in
  1106. X*2.1*) libswanted=`echo $libswanted | sed 's/malloc //'` ;;
  1107. Xesac
  1108. Xd_strchr=define
  1109. END_OF_FILE
  1110. if test 114 -ne `wc -c <'hints/hpux.sh'`; then
  1111.     echo shar: \"'hints/hpux.sh'\" unpacked with wrong size!
  1112. fi
  1113. # end of 'hints/hpux.sh'
  1114. fi
  1115. if test -f 'hints/i386.sh' -a "${1}" != "-c" ; then 
  1116.   echo shar: Will not clobber existing file \"'hints/i386.sh'\"
  1117. else
  1118. echo shar: Extracting \"'hints/i386.sh'\" \(24 characters\)
  1119. sed "s/^X//" >'hints/i386.sh' <<'END_OF_FILE'
  1120. Xldflags='-L/usr/ucblib'
  1121. END_OF_FILE
  1122. if test 24 -ne `wc -c <'hints/i386.sh'`; then
  1123.     echo shar: \"'hints/i386.sh'\" unpacked with wrong size!
  1124. fi
  1125. # end of 'hints/i386.sh'
  1126. fi
  1127. if test -f 'hints/isc_2_2_1.sh' -a "${1}" != "-c" ; then 
  1128.   echo shar: Will not clobber existing file \"'hints/isc_2_2_1.sh'\"
  1129. else
  1130. echo shar: Extracting \"'hints/isc_2_2_1.sh'\" \(14 characters\)
  1131. sed "s/^X//" >'hints/isc_2_2_1.sh' <<'END_OF_FILE'
  1132. Xd_ftime=undef
  1133. END_OF_FILE
  1134. if test 14 -ne `wc -c <'hints/isc_2_2_1.sh'`; then
  1135.     echo shar: \"'hints/isc_2_2_1.sh'\" unpacked with wrong size!
  1136. fi
  1137. # end of 'hints/isc_2_2_1.sh'
  1138. fi
  1139. if test -f 'hints/isc_3_2_2.sh' -a "${1}" != "-c" ; then 
  1140.   echo shar: Will not clobber existing file \"'hints/isc_3_2_2.sh'\"
  1141. else
  1142. echo shar: Extracting \"'hints/isc_3_2_2.sh'\" \(86 characters\)
  1143. sed "s/^X//" >'hints/isc_3_2_2.sh' <<'END_OF_FILE'
  1144. Xset `echo $libswanted | sed -e 's/ x//' -e 's/malloc //'`
  1145. Xlibswanted="inet malloc $*"
  1146. END_OF_FILE
  1147. if test 86 -ne `wc -c <'hints/isc_3_2_2.sh'`; then
  1148.     echo shar: \"'hints/isc_3_2_2.sh'\" unpacked with wrong size!
  1149. fi
  1150. # end of 'hints/isc_3_2_2.sh'
  1151. fi
  1152. if test -f 'hints/isc_3_2_3.sh' -a "${1}" != "-c" ; then 
  1153.   echo shar: Will not clobber existing file \"'hints/isc_3_2_3.sh'\"
  1154. else
  1155. echo shar: Extracting \"'hints/isc_3_2_3.sh'\" \(69 characters\)
  1156. sed "s/^X//" >'hints/isc_3_2_3.sh' <<'END_OF_FILE'
  1157. Xset `echo $libswanted | sed -e 's/ socket / inet /'`
  1158. Xlibswanted="$*"
  1159. END_OF_FILE
  1160. if test 69 -ne `wc -c <'hints/isc_3_2_3.sh'`; then
  1161.     echo shar: \"'hints/isc_3_2_3.sh'\" unpacked with wrong size!
  1162. fi
  1163. # end of 'hints/isc_3_2_3.sh'
  1164. fi
  1165. if test -f 'hints/mc6000.sh' -a "${1}" != "-c" ; then 
  1166.   echo shar: Will not clobber existing file \"'hints/mc6000.sh'\"
  1167. else
  1168. echo shar: Extracting \"'hints/mc6000.sh'\" \(87 characters\)
  1169. sed "s/^X//" >'hints/mc6000.sh' <<'END_OF_FILE'
  1170. X# defaults for the masscomp (concurrent) 6000 series running RTU 5.0
  1171. Xcppstdin=/lib/cpp
  1172. END_OF_FILE
  1173. if test 87 -ne `wc -c <'hints/mc6000.sh'`; then
  1174.     echo shar: \"'hints/mc6000.sh'\" unpacked with wrong size!
  1175. fi
  1176. # end of 'hints/mc6000.sh'
  1177. fi
  1178. if test -f 'hints/mips.sh' -a "${1}" != "-c" ; then 
  1179.   echo shar: Will not clobber existing file \"'hints/mips.sh'\"
  1180. else
  1181. echo shar: Extracting \"'hints/mips.sh'\" \(19 characters\)
  1182. sed "s/^X//" >'hints/mips.sh' <<'END_OF_FILE'
  1183. Xcc=cc
  1184. Xnm_opts='-B'
  1185. END_OF_FILE
  1186. if test 19 -ne `wc -c <'hints/mips.sh'`; then
  1187.     echo shar: \"'hints/mips.sh'\" unpacked with wrong size!
  1188. fi
  1189. # end of 'hints/mips.sh'
  1190. fi
  1191. if test -f 'hints/next.sh' -a "${1}" != "-c" ; then 
  1192.   echo shar: Will not clobber existing file \"'hints/next.sh'\"
  1193. else
  1194. echo shar: Extracting \"'hints/next.sh'\" \(19 characters\)
  1195. sed "s/^X//" >'hints/next.sh' <<'END_OF_FILE'
  1196. Xlibswanted='sys_s'
  1197. END_OF_FILE
  1198. if test 19 -ne `wc -c <'hints/next.sh'`; then
  1199.     echo shar: \"'hints/next.sh'\" unpacked with wrong size!
  1200. fi
  1201. # end of 'hints/next.sh'
  1202. fi
  1203. if test -f 'hints/osf1.sh' -a "${1}" != "-c" ; then 
  1204.   echo shar: Will not clobber existing file \"'hints/osf1.sh'\"
  1205. else
  1206. echo shar: Extracting \"'hints/osf1.sh'\" \(13 characters\)
  1207. sed "s/^X//" >'hints/osf1.sh' <<'END_OF_FILE'
  1208. Xlibswanted=m
  1209. END_OF_FILE
  1210. if test 13 -ne `wc -c <'hints/osf1.sh'`; then
  1211.     echo shar: \"'hints/osf1.sh'\" unpacked with wrong size!
  1212. fi
  1213. # end of 'hints/osf1.sh'
  1214. fi
  1215. if test -f 'hints/sco_3.sh' -a "${1}" != "-c" ; then 
  1216.   echo shar: Will not clobber existing file \"'hints/sco_3.sh'\"
  1217. else
  1218. echo shar: Extracting \"'hints/sco_3.sh'\" \(72 characters\)
  1219. sed "s/^X//" >'hints/sco_3.sh' <<'END_OF_FILE'
  1220. Xlibswanted=`echo $libswanted | sed 's/ x//'`
  1221. Xcppminus=''
  1222. Xd_rename=undef
  1223. END_OF_FILE
  1224. if test 72 -ne `wc -c <'hints/sco_3.sh'`; then
  1225.     echo shar: \"'hints/sco_3.sh'\" unpacked with wrong size!
  1226. fi
  1227. # end of 'hints/sco_3.sh'
  1228. fi
  1229. if test -f 'hints/sco_3_2_4.sh' -a "${1}" != "-c" ; then 
  1230.   echo shar: Will not clobber existing file \"'hints/sco_3_2_4.sh'\"
  1231. else
  1232. echo shar: Extracting \"'hints/sco_3_2_4.sh'\" \(62 characters\)
  1233. sed "s/^X//" >'hints/sco_3_2_4.sh' <<'END_OF_FILE'
  1234. Xxlibpth=''
  1235. Xmailer='/usr/lib/mail/execmail'
  1236. Xlibc='/lib/libc.a'
  1237. END_OF_FILE
  1238. if test 62 -ne `wc -c <'hints/sco_3_2_4.sh'`; then
  1239.     echo shar: \"'hints/sco_3_2_4.sh'\" unpacked with wrong size!
  1240. fi
  1241. # end of 'hints/sco_3_2_4.sh'
  1242. fi
  1243. if test -f 'hints/sco_xenix.sh' -a "${1}" != "-c" ; then 
  1244.   echo shar: Will not clobber existing file \"'hints/sco_xenix.sh'\"
  1245. else
  1246. echo shar: Extracting \"'hints/sco_xenix.sh'\" \(60 characters\)
  1247. sed "s/^X//" >'hints/sco_xenix.sh' <<'END_OF_FILE'
  1248. Xi_dirent=undef
  1249. Xlibswanted=`echo $libswanted | sed 's/ x//'`
  1250. END_OF_FILE
  1251. if test 60 -ne `wc -c <'hints/sco_xenix.sh'`; then
  1252.     echo shar: \"'hints/sco_xenix.sh'\" unpacked with wrong size!
  1253. fi
  1254. # end of 'hints/sco_xenix.sh'
  1255. fi
  1256. if test -f 'hints/sgi.sh' -a "${1}" != "-c" ; then 
  1257.   echo shar: Will not clobber existing file \"'hints/sgi.sh'\"
  1258. else
  1259. echo shar: Extracting \"'hints/sgi.sh'\" \(48 characters\)
  1260. sed "s/^X//" >'hints/sgi.sh' <<'END_OF_FILE'
  1261. Xd_voidsig=define
  1262. Xd_vfork=undef
  1263. Xd_sigblock=undef
  1264. END_OF_FILE
  1265. if test 48 -ne `wc -c <'hints/sgi.sh'`; then
  1266.     echo shar: \"'hints/sgi.sh'\" unpacked with wrong size!
  1267. fi
  1268. # end of 'hints/sgi.sh'
  1269. fi
  1270. if test -f 'hints/solaris_2_0.sh' -a "${1}" != "-c" ; then 
  1271.   echo shar: Will not clobber existing file \"'hints/solaris_2_0.sh'\"
  1272. else
  1273. echo shar: Extracting \"'hints/solaris_2_0.sh'\" \(14 characters\)
  1274. sed "s/^X//" >'hints/solaris_2_0.sh' <<'END_OF_FILE'
  1275. Xd_vfork=undef
  1276. END_OF_FILE
  1277. if test 14 -ne `wc -c <'hints/solaris_2_0.sh'`; then
  1278.     echo shar: \"'hints/solaris_2_0.sh'\" unpacked with wrong size!
  1279. fi
  1280. # end of 'hints/solaris_2_0.sh'
  1281. fi
  1282. if test -f 'hints/solaris_2_1.sh' -a "${1}" != "-c" ; then 
  1283.   echo shar: Will not clobber existing file \"'hints/solaris_2_1.sh'\"
  1284. else
  1285. echo shar: Extracting \"'hints/solaris_2_1.sh'\" \(96 characters\)
  1286. sed "s/^X//" >'hints/solaris_2_1.sh' <<'END_OF_FILE'
  1287. X#d_vfork=undef
  1288. Xi_dirent=define
  1289. Xi_sysdir=undef
  1290. Xlibs='-lmalloc -lsocket -lnls -lnsl -lintl -lucb'
  1291. END_OF_FILE
  1292. if test 96 -ne `wc -c <'hints/solaris_2_1.sh'`; then
  1293.     echo shar: \"'hints/solaris_2_1.sh'\" unpacked with wrong size!
  1294. fi
  1295. # end of 'hints/solaris_2_1.sh'
  1296. fi
  1297. if test -f 'hints/solaris_2_2.sh' -a "${1}" != "-c" ; then 
  1298.   echo shar: Will not clobber existing file \"'hints/solaris_2_2.sh'\"
  1299. else
  1300. echo shar: Extracting \"'hints/solaris_2_2.sh'\" \(97 characters\)
  1301. sed "s/^X//" >'hints/solaris_2_2.sh' <<'END_OF_FILE'
  1302. Xd_sigblock='undef'
  1303. Xd_getcwd='define'
  1304. Xd_getwd='undef'
  1305. Xlibs='-lmalloc -lsocket -lnls -lnsl -lintl'
  1306. END_OF_FILE
  1307. if test 97 -ne `wc -c <'hints/solaris_2_2.sh'`; then
  1308.     echo shar: \"'hints/solaris_2_2.sh'\" unpacked with wrong size!
  1309. fi
  1310. # end of 'hints/solaris_2_2.sh'
  1311. fi
  1312. if test -f 'hints/sunos_4_1.sh' -a "${1}" != "-c" ; then 
  1313.   echo shar: Will not clobber existing file \"'hints/sunos_4_1.sh'\"
  1314. else
  1315. echo shar: Extracting \"'hints/sunos_4_1.sh'\" \(31 characters\)
  1316. sed "s/^X//" >'hints/sunos_4_1.sh' <<'END_OF_FILE'
  1317. Xi_sgtty=define
  1318. Xi_termios=undef
  1319. END_OF_FILE
  1320. if test 31 -ne `wc -c <'hints/sunos_4_1.sh'`; then
  1321.     echo shar: \"'hints/sunos_4_1.sh'\" unpacked with wrong size!
  1322. fi
  1323. # end of 'hints/sunos_4_1.sh'
  1324. fi
  1325. if test -f 'hints/svr4.sh' -a "${1}" != "-c" ; then 
  1326.   echo shar: Will not clobber existing file \"'hints/svr4.sh'\"
  1327. else
  1328. echo shar: Extracting \"'hints/svr4.sh'\" \(125 characters\)
  1329. sed "s/^X//" >'hints/svr4.sh' <<'END_OF_FILE'
  1330. Xcc='/bin/cc'
  1331. Xtest -f $cc || cc='/usr/ccs/bin/cc'
  1332. Xmansrc='/usr/share/man/man1'
  1333. Xlibswanted='malloc socket nsl'
  1334. Xd_strchr=define
  1335. END_OF_FILE
  1336. if test 125 -ne `wc -c <'hints/svr4.sh'`; then
  1337.     echo shar: \"'hints/svr4.sh'\" unpacked with wrong size!
  1338. fi
  1339. # end of 'hints/svr4.sh'
  1340. fi
  1341. if test -f 'makedepend.SH' -a "${1}" != "-c" ; then 
  1342.   echo shar: Will not clobber existing file \"'makedepend.SH'\"
  1343. else
  1344. echo shar: Extracting \"'makedepend.SH'\" \(2446 characters\)
  1345. sed "s/^X//" >'makedepend.SH' <<'END_OF_FILE'
  1346. Xcase $CONFIG in
  1347. X    '') . ./config.sh ;;
  1348. Xesac
  1349. Xecho "Extracting makedepend (with variable substitutions)"
  1350. X$spitshell >makedepend <<!GROK!THIS!
  1351. X$startsh
  1352. X# $Id: makedepend.SH,v 3.0 1991/09/09 20:23:31 davison Trn $
  1353. X# 
  1354. X# This software is Copyright 1991 by Stan Barber. 
  1355. X#
  1356. X# Permission is hereby granted to copy, reproduce, redistribute or otherwise
  1357. X# use this software as long as: there is no monetary profit gained
  1358. X# specifically from the use or reproduction of this software, it is not
  1359. X# sold, rented, traded or otherwise marketed, and this copyright notice is
  1360. X# included prominently in any copy made. 
  1361. X#
  1362. X# The author make no claims as to the fitness or correctness of this software
  1363. X# for any use whatsoever, and it is provided as is. Any use of this software
  1364. X# is at the user's own risk. 
  1365. Xexport PATH || (echo "OOPS, this isn't sh.  Desperation time.  I will feed myself to sh."; sh \$0; kill \$\$)
  1366. X
  1367. X$cat /dev/null >.deptmp
  1368. X$echo "(Note: this is going to take a while.)"
  1369. Xfor file in *.[cy]; do
  1370. X    case "\$file" in
  1371. X    *.c) filebase=\`basename \$file .c\`;;
  1372. X    *.y) filebase=\`basename \$file .y\`;;
  1373. X    esac
  1374. X    $echo "Finding dependencies for \$filebase.o."
  1375. X    $sed -n <\$file \\
  1376. X    -e "/^\${filebase}_init(/q" \\
  1377. X    -e '/^#/{' \\
  1378. X    -e 's|/\*.*$||' \\
  1379. X    -e 's/\\\\[     ]*$//' \\
  1380. X    -e p \\
  1381. X    -e '}' | $cppstdin -I/usr/local/include | $sed \\
  1382. X    -e '/^# *line/s/line//' \
  1383. X    -e '/^# *[0-9]/!d' \\
  1384. X    -e 's/^.*"\(.*\)".*\$/'\$filebase'.o: \1/' \\
  1385. X    -e 's|: \./|: |' \\
  1386. X    -e 's/: .*\.c/: '\$file'/' | \\
  1387. X    $uniq | $sort | $uniq >> .deptmp
  1388. Xdone
  1389. X
  1390. Xfor file in *.SH; do
  1391. X    $echo \`basename \$file .SH\`: \$file config.sh \; /bin/sh \$file >> .deptmp
  1392. Xdone
  1393. X
  1394. X$sed <Makefile >Makefile.new -e '1,/^# AUTOMATICALLY/!d'
  1395. X
  1396. Xif $test -s .deptmp; then
  1397. X    echo "Updating Makefile..."
  1398. X    $sed -e 's/\\\$/\$\$/g' .deptmp | $egrep -v $usrinc >dependencies
  1399. Xelse
  1400. X    $echo "You don't seem to have a proper C preprocessor.  Using grep instead."
  1401. X    $egrep '^#include ' *.[cyh] ?.[cyh] >.deptmp
  1402. X    echo "Updating Makefile..."
  1403. X    <.deptmp $sed -n 's|c:#include "\(.*\)".*\$\$|o: \1|p' > dependencies
  1404. X    <.deptmp $sed -n 's|y:#include "\(.*\)".*\$\$|o: \1|p' >> dependencies
  1405. X    <.deptmp $sed -n 's|h:#include "\(.*\)".*\$\$|h: \1|p' >> dependencies
  1406. Xfi
  1407. X$echo "# WARNING: Put nothing here or make depend will gobble it up!" >> dependencies
  1408. X$mv Makefile Makefile.old
  1409. X$mv Makefile.new Makefile
  1410. X$cat dependencies >>Makefile
  1411. Xrm .deptmp
  1412. X!GROK!THIS!
  1413. X$eunicefix makedepend
  1414. Xchmod 755 makedepend
  1415. END_OF_FILE
  1416. if test 2446 -ne `wc -c <'makedepend.SH'`; then
  1417.     echo shar: \"'makedepend.SH'\" unpacked with wrong size!
  1418. fi
  1419. chmod +x 'makedepend.SH'
  1420. # end of 'makedepend.SH'
  1421. fi
  1422. if test -f 'makedir.SH' -a "${1}" != "-c" ; then 
  1423.   echo shar: Will not clobber existing file \"'makedir.SH'\"
  1424. else
  1425. echo shar: Extracting \"'makedir.SH'\" \(1082 characters\)
  1426. sed "s/^X//" >'makedir.SH' <<'END_OF_FILE'
  1427. Xcase $CONFIG in
  1428. X'') . ./config.sh ;;
  1429. Xesac
  1430. Xecho "Extracting makedir (with variable substitutions)"
  1431. X$spitshell >makedir <<!GROK!THIS!
  1432. X$startsh
  1433. X# $Id: makedir.SH,v 2.11 90/09/17 17:03:55 hokey Exp Locker: hokey $
  1434. X# 
  1435. X# $Log:    makedir.SH,v $
  1436. X# Revision 2.11  90/09/17  17:03:55  hokey
  1437. X# 2.11 alpha baseline
  1438. X# 
  1439. X
  1440. Xexport PATH || (echo "OOPS, this isn't sh.  Desperation time.  I will feed myself to sh."; sh \$0; kill \$\$)
  1441. X
  1442. Xcase \$# in
  1443. X  0)
  1444. X    $echo "makedir pathname filenameflag"
  1445. X    exit 1
  1446. X    ;;
  1447. Xesac
  1448. X
  1449. X: guarantee one slash before 1st component
  1450. Xcase \$1 in
  1451. X  /*) ;;
  1452. X  *)  set ./\$1 \$2 ;;
  1453. Xesac
  1454. X
  1455. X: strip last component if it is to be a filename
  1456. Xcase X\$2 in
  1457. X  X1) set \`$echo \$1 | $sed 's:\(.*\)/[^/]*\$:\1:'\` ;;
  1458. X  *)  set \$1 ;;
  1459. Xesac
  1460. X
  1461. X: return reasonable status if nothing to be created
  1462. Xif $test -d "\$1" ; then
  1463. X    exit 0
  1464. Xfi
  1465. X
  1466. Xlist=''
  1467. Xwhile true ; do
  1468. X    case \$1 in
  1469. X    */*)
  1470. X    list="\$1 \$list"
  1471. X    set \`echo \$1 | $sed 's:\(.*\)/:\1 :'\`
  1472. X    ;;
  1473. X    *)
  1474. X    break
  1475. X    ;;
  1476. X    esac
  1477. Xdone
  1478. X
  1479. Xset \$list
  1480. X
  1481. Xfor dir do
  1482. X    $mkdir \$dir >/dev/null 2>&1
  1483. Xdone
  1484. X!GROK!THIS!
  1485. X$eunicefix makedir
  1486. Xchmod +x makedir
  1487. END_OF_FILE
  1488. if test 1082 -ne `wc -c <'makedir.SH'`; then
  1489.     echo shar: \"'makedir.SH'\" unpacked with wrong size!
  1490. fi
  1491. chmod +x 'makedir.SH'
  1492. # end of 'makedir.SH'
  1493. fi
  1494. if test -f 'mt-misc.c' -a "${1}" != "-c" ; then 
  1495.   echo shar: Will not clobber existing file \"'mt-misc.c'\"
  1496. else
  1497. echo shar: Extracting \"'mt-misc.c'\" \(7528 characters\)
  1498. sed "s/^X//" >'mt-misc.c' <<'END_OF_FILE'
  1499. X/* $Id: mt-misc.c,v 3.0 1993/10/01 00:14:02 davison Trn $
  1500. X*/
  1501. X/* The authors make no claims as to the fitness or correctness of this software
  1502. X * for any use whatsoever, and it is provided as is. Any use of this software
  1503. X * is at the user's own risk. 
  1504. X */
  1505. X
  1506. X#include "EXTERN.h"
  1507. X#include "common.h"
  1508. X#include "thread.h"
  1509. X#include "mthreads.h"
  1510. X
  1511. Xchar *newslib, *privlib, *spool, *threaddir, *homedir;
  1512. Xint locked = 0, cron_locking = 0;
  1513. X
  1514. Xvoid
  1515. Xmt_init()
  1516. X{
  1517. X    /* Set up a nice friendly umask. */
  1518. X    umask(002);
  1519. X
  1520. X    /* Init the directory strings, possibly translating them into real paths */
  1521. X    homedir = getenv("HOME");
  1522. X    if (homedir == Nullch) {
  1523. X    homedir = getenv("LOGDIR");
  1524. X    }
  1525. X    spool = savestr(file_exp(NEWSSPOOL));
  1526. X    newslib = savestr(file_exp(NEWSLIB));
  1527. X    privlib = savestr(file_exp(PRIVLIB));
  1528. X    threaddir = file_exp(THREAD_DIR);
  1529. X    if (strEQ(threaddir,spool))
  1530. X    threaddir = spool;
  1531. X    else
  1532. X    threaddir = savestr(threaddir);
  1533. X}
  1534. X
  1535. X/* Make sure we're not already running by creating a lock file. */
  1536. Xlong
  1537. Xmt_lock(which_lock, sig)
  1538. Xint which_lock;
  1539. Xint sig;
  1540. X{
  1541. X    char buff[LBUFLEN], *filename;
  1542. X    FILE *fp;
  1543. X
  1544. X    sprintf(buff, "%s.%ld", file_exp(MTPRELOCK), (long)getpid());
  1545. X    if ((fp = fopen(buff, "w")) == Nullfp) {
  1546. X    log_entry("Unable to create lock temporary `%s'.\n", buff);
  1547. X    wrap_it_up(1);
  1548. X    }
  1549. X    fprintf(fp, "%s%ld\n", which_lock == DAEMON_LOCK ? "pid " : nullstr,
  1550. X    (long)getpid());
  1551. X    fclose(fp);
  1552. X
  1553. X    /* Try to link to lock file. */
  1554. X    if (which_lock == DAEMON_LOCK) {
  1555. X    filename = file_exp(MTDLOCK);
  1556. X    } else {
  1557. X    filename = file_exp(MTLOCK);
  1558. X    }
  1559. X  dolink:
  1560. X    while (link(buff, filename) < 0) {
  1561. X      long otherpid;
  1562. X    if ((fp = fopen(filename, "r")) == Nullfp) {
  1563. X        log_entry("unable to open %s\n", filename);
  1564. X        if (cron_locking) {
  1565. X        goto Sleep;
  1566. X        }
  1567. X        unlink(buff);
  1568. X        wrap_it_up(1);
  1569. X    }
  1570. X    if (fscanf(fp, "%ld", &otherpid) != 1) { 
  1571. X        log_entry("unable to read pid from %s\n", filename);
  1572. X        fclose(fp);
  1573. X        if (cron_locking) {
  1574. X        goto Sleep;
  1575. X        }
  1576. X        unlink(buff);
  1577. X        wrap_it_up(1);
  1578. X    }
  1579. X    fclose(fp);
  1580. X    if (kill(otherpid, sig) == -1 && errno == ESRCH) {
  1581. X        if (unlink(filename) == -1) {
  1582. X        log_entry("unable to unlink lockfile %s\n", filename);
  1583. X        unlink(buff);
  1584. X        wrap_it_up(1);
  1585. X        }
  1586. X        goto dolink;
  1587. X    }
  1588. X    if (cron_locking) {
  1589. X      Sleep:
  1590. X        sleep(60);
  1591. X        continue;
  1592. X    }
  1593. X    unlink(buff);
  1594. X    return otherpid;
  1595. X    }
  1596. X    unlink(buff);            /* remove temporary LOCK.<pid> file */
  1597. X    locked |= which_lock;
  1598. X    return 0;                /* return success */
  1599. X}
  1600. X
  1601. Xvoid
  1602. Xmt_unlock(which_lock)
  1603. Xint which_lock;
  1604. X{
  1605. X    which_lock &= locked;
  1606. X    if (which_lock & PASS_LOCK) {
  1607. X    unlink(file_exp(MTLOCK));        /* remove single-pass lock */
  1608. X    }
  1609. X    if (which_lock & DAEMON_LOCK) {
  1610. X    unlink(file_exp(MTDLOCK));        /* remove daemon lock */
  1611. X    }
  1612. X    locked &= ~which_lock;
  1613. X}
  1614. X
  1615. X/* Interpret rn's %x prefixes and ~name expansions without including tons
  1616. X** of useless source.  NOTE:  names that don't start with '/', '%' or '~'
  1617. X** are prefixed with the SPOOL directory.  (Note that ~'s don't work yet.)
  1618. X*/
  1619. Xchar *
  1620. Xfile_exp(name)
  1621. Xchar *name;
  1622. X{
  1623. X    static char namebuf[MAXFILENAME];
  1624. X
  1625. X    if (*name == '/') {    /* fully qualified names are left alone */
  1626. X    return name;
  1627. X    }
  1628. X    switch (name[0]) {
  1629. X    case '%':            /* interpret certain %x values */
  1630. X    switch (name[1]) {
  1631. X    case 'P':
  1632. X        strcpy(namebuf, spool);
  1633. X        break;
  1634. X    case 'W':
  1635. X        strcpy(namebuf, threaddir);
  1636. X        break;
  1637. X    case 'x':
  1638. X        strcpy(namebuf, newslib);
  1639. X        break;
  1640. X    case 'X':
  1641. X        strcpy(namebuf, privlib);
  1642. X        break;
  1643. X    default:
  1644. X        log_entry("Unknown expansion: %s\n", name);
  1645. X        wrap_it_up(1);
  1646. X    }
  1647. X    strcat(namebuf, name+2);
  1648. X    break;
  1649. X    case '~':
  1650. X    {
  1651. X    char *s = name + 1;
  1652. X
  1653. X    if (!*s || *s == '/') {
  1654. X        sprintf(namebuf, "%s%s", homedir, s);
  1655. X    } else {
  1656. X        log_entry("~name expansions not implemented.");
  1657. X        wrap_it_up(1);
  1658. X    }
  1659. X    break;
  1660. X    }
  1661. X    default:            /* all "normal" names are relative to SPOOL */
  1662. X    sprintf(namebuf, "%s/%s", spool, name);
  1663. X    break;
  1664. X    }
  1665. X    return namebuf;
  1666. X}
  1667. X
  1668. X/* Change a newsgroup name into the name of the thread data file.  We
  1669. X** subsitute any '.'s in the group name into '/'s (unless LONG_THREAD_NAMES
  1670. X** is defined), prepend the path, and append the '/.thread' (or '.th') on to
  1671. X** the end.
  1672. X*/
  1673. Xchar *
  1674. Xthread_name(group)
  1675. Xchar *group;
  1676. X{
  1677. X    static char name_buf[MAXFILENAME];
  1678. X#ifdef LONG_THREAD_NAMES
  1679. X    sprintf(name_buf, "%s/%s", threaddir, group);
  1680. X#else
  1681. X    register char *cp;
  1682. X
  1683. X    cp = strcpy(name_buf, threaddir) + strlen(threaddir);
  1684. X    *cp++ = '/';
  1685. X    strcpy(cp, group);
  1686. X    while ((cp = index(cp, '.')))
  1687. X    *cp = '/';
  1688. X    if (threaddir == spool)
  1689. X    strcat(name_buf, "/.thread");
  1690. X    else
  1691. X    strcat(name_buf, ".th");
  1692. X#endif
  1693. X    return name_buf;
  1694. X}
  1695. X
  1696. X#ifndef lint
  1697. X/* A malloc that bombs-out when memory is exhausted. */
  1698. Xchar *
  1699. Xsafemalloc(amount)
  1700. XMEM_SIZE amount;
  1701. X{
  1702. X    register char *cp;
  1703. X
  1704. X    if ((cp = malloc(amount)) == Nullch) {
  1705. X    log_error("malloc(%ld) failed.\n", (long)amount);
  1706. X    wrap_it_up(1);
  1707. X    }
  1708. X    return cp;
  1709. X}
  1710. X
  1711. X/* paranoid version of realloc */
  1712. Xchar *
  1713. Xsaferealloc(where,size)
  1714. Xchar *where;
  1715. XMEM_SIZE size;
  1716. X{
  1717. X    char *ptr;
  1718. X
  1719. X    ptr = realloc(where,size?size:1);    /* realloc(0) is NASTY on our system */
  1720. X    if (ptr == Nullch) {
  1721. X    log_error("realloc(..., %ld) failed.\n", (long)size);
  1722. X    wrap_it_up(1);
  1723. X    }
  1724. X    return ptr;
  1725. X}
  1726. X#endif
  1727. X
  1728. X/* Create a malloc'ed copy of a string. */
  1729. Xchar *
  1730. Xsavestr(str)
  1731. Xchar *str;
  1732. X{
  1733. X    register MEM_SIZE len = strlen(str) + 1;
  1734. X    register char *newaddr = safemalloc(len);
  1735. X
  1736. X    bcopy(str, newaddr, (int)len);
  1737. X
  1738. X    return newaddr;
  1739. X}
  1740. X
  1741. X#ifndef lint
  1742. X/* Free some memory if it hasn't already been freed. */
  1743. Xvoid
  1744. Xsafefree(pp)
  1745. Xchar **pp;
  1746. X{
  1747. X    if (*pp) {
  1748. X    free(*pp);
  1749. X    *pp = Nullch;
  1750. X    }
  1751. X}
  1752. X#endif
  1753. X
  1754. X/* Determine this machine's byte map for WORDs and LONGs.  A byte map is an
  1755. X** array of BYTEs (sizeof (WORD) or sizeof (LONG) of them) with the 0th BYTE
  1756. X** being the byte number of the high-order byte in my <type>, and so forth.
  1757. X*/
  1758. Xvoid
  1759. Xmybytemap(map)
  1760. XBMAP *map;
  1761. X{
  1762. X    union {
  1763. X    BYTE b[sizeof (LONG)];
  1764. X    WORD w;
  1765. X    LONG l;
  1766. X    } u;
  1767. X    register BYTE *mp;
  1768. X    register int i, j;
  1769. X
  1770. X    mp = &map->w[sizeof (WORD)];
  1771. X    u.w = 1;
  1772. X    for (i = sizeof (WORD); i > 0; i--) {
  1773. X    for (j = 0; j < sizeof (WORD); j++) {
  1774. X        if (u.b[j] != 0) {
  1775. X        break;
  1776. X        }
  1777. X    }
  1778. X    if (j == sizeof (WORD)) {
  1779. X        goto bad_news;
  1780. X    }
  1781. X    *--mp = j;
  1782. X    while (u.b[j] != 0 && u.w) {
  1783. X        u.w <<= 1;
  1784. X    }
  1785. X    }
  1786. X
  1787. X    mp = &map->l[sizeof (LONG)];
  1788. X    u.l = 1;
  1789. X    for (i = sizeof (LONG); i > 0; i--) {
  1790. X    for (j = 0; j < sizeof (LONG); j++) {
  1791. X        if (u.b[j] != 0) {
  1792. X        break;
  1793. X        }
  1794. X    }
  1795. X    if (j == sizeof (LONG)) {
  1796. X      bad_news:
  1797. X        /* trouble -- set both to *something* consistent */
  1798. X        for (j = 0; j < sizeof (WORD); j++) {
  1799. X        map->w[j] = j;
  1800. X        }
  1801. X        for (j = 0; j < sizeof (LONG); j++) {
  1802. X        map->l[j] = j;
  1803. X        }
  1804. X        return;
  1805. X    }
  1806. X    *--mp = j;
  1807. X    while (u.b[j] != 0 && u.l) {
  1808. X        u.l <<= 1;
  1809. X    }
  1810. X    }
  1811. X}
  1812. X
  1813. X/* Transform each WORD's byte-ordering in a buffer of the designated length.
  1814. X*/
  1815. Xvoid
  1816. Xwp_bmap(buf, len)
  1817. XWORD *buf;
  1818. Xint len;
  1819. X{
  1820. X    union {
  1821. X    BYTE b[sizeof (WORD)];
  1822. X    WORD w;
  1823. X    } in, out;
  1824. X    register int i;
  1825. X
  1826. X    if (word_same) {
  1827. X    return;
  1828. X    }
  1829. X    while (len--) {
  1830. X    in.w = *buf;
  1831. X    for (i = 0; i < sizeof (WORD); i++) {
  1832. X        out.b[my_bmap.w[i]] = in.b[mt_bmap.w[i]];
  1833. X    }
  1834. X    *buf++ = out.w;
  1835. X    }
  1836. X}
  1837. X
  1838. X/* Transform each LONG's byte-ordering in a buffer of the designated length.
  1839. X*/
  1840. Xvoid
  1841. Xlp_bmap(buf, len)
  1842. XLONG *buf;
  1843. Xint len;
  1844. X{
  1845. X    union {
  1846. X    BYTE b[sizeof (LONG)];
  1847. X    LONG l;
  1848. X    } in, out;
  1849. X    register int i;
  1850. X
  1851. X    if (long_same) {
  1852. X    return;
  1853. X    }
  1854. X    while (len--) {
  1855. X    in.l = *buf;
  1856. X    for (i = 0; i < sizeof (LONG); i++) {
  1857. X        out.b[my_bmap.l[i]] = in.b[mt_bmap.l[i]];
  1858. X    }
  1859. X    *buf++ = out.l;
  1860. X    }
  1861. X}
  1862. END_OF_FILE
  1863. if test 7528 -ne `wc -c <'mt-misc.c'`; then
  1864.     echo shar: \"'mt-misc.c'\" unpacked with wrong size!
  1865. fi
  1866. # end of 'mt-misc.c'
  1867. fi
  1868. if test -f 'mt-write.c' -a "${1}" != "-c" ; then 
  1869.   echo shar: Will not clobber existing file \"'mt-write.c'\"
  1870. else
  1871. echo shar: Extracting \"'mt-write.c'\" \(9773 characters\)
  1872. sed "s/^X//" >'mt-write.c' <<'END_OF_FILE'
  1873. X/* $Id: mt-write.c,v 3.0 1990/10/01 00:14:05 davison Trn $
  1874. X*/
  1875. X/* The authors make no claims as to the fitness or correctness of this software
  1876. X * for any use whatsoever, and it is provided as is. Any use of this software
  1877. X * is at the user's own risk. 
  1878. X */
  1879. X
  1880. X#include "EXTERN.h"
  1881. X#include "common.h"
  1882. X#include "thread.h"
  1883. X#include "mthreads.h"
  1884. X
  1885. Xstatic FILE *fp_out;
  1886. Xstatic int seq;
  1887. Xstatic int article_seq;
  1888. X
  1889. Xstatic int failure;
  1890. X
  1891. Xvoid write_subjects(), write_authors(), write_roots(), write_ids();
  1892. Xvoid write_articles(), write_thread(), write_item();
  1893. Xvoid enumerate_articles(), enumerate_thread();
  1894. Xvoid free_leftovers();
  1895. Xint ensure_path _((char *));
  1896. X
  1897. X/* Write out all the data in a packed format that is easy for our newsreader
  1898. X** to use.  We free things as we go, when we don't need them any longer.  If
  1899. X** we encounter any write errors, the write_item routine sets a failure flag
  1900. X** to halt our writing of the file, but we keep on plugging away to free
  1901. X** everything up.
  1902. X*/
  1903. Xint
  1904. Xwrite_data(filename)
  1905. Xchar *filename;
  1906. X{
  1907. X    if (filename == Nullch) {
  1908. X    failure = 2;    /* A NULL filename indicates just free the data */
  1909. X    } else if ((fp_out = fopen(filename, FOPEN_WB)) == Nullfp) {
  1910. X    if (ensure_path(filename)) {
  1911. X        if ((fp_out = fopen(filename, FOPEN_WB)) == Nullfp) {
  1912. X        log_error("Unable to create file: `%s'.\n", filename);
  1913. X        failure = 2;
  1914. X        }
  1915. X    } else {
  1916. X        log_error("Unable to create path: `%s'.\n", filename);
  1917. X        failure = 2;
  1918. X    }
  1919. X    } else {
  1920. X    failure = 0;
  1921. X#ifdef SETBUFFER
  1922. X    setbuffer(fp_out, rwbuf, RWBUFSIZ);
  1923. X#else
  1924. X# ifdef SETVBUF
  1925. X    setvbuf(fp_out, rwbuf, _IOFBF, RWBUFSIZ);
  1926. X# endif
  1927. X#endif
  1928. X    }
  1929. X
  1930. X    /* If there's no roots, there's no data.  Leave the file with no length. */
  1931. X    if (!failure && total.last < total.first) {
  1932. X    failure = -1;
  1933. X    }
  1934. X
  1935. X    write_item(&total, sizeof (TOTAL));
  1936. X
  1937. X    enumerate_articles();
  1938. X
  1939. X    write_authors();
  1940. X    write_subjects();
  1941. X    write_roots();
  1942. X    write_articles();
  1943. X    write_ids();
  1944. X    free_leftovers();
  1945. X    bzero(&total, sizeof (TOTAL));
  1946. X
  1947. X    if (failure != 2) {
  1948. X    fclose(fp_out);
  1949. X    }
  1950. X    if (failure == 1) {
  1951. X    log_error("Write failed!  Removing `%s'.\n", filename);
  1952. X    unlink(filename);
  1953. X    }
  1954. X    return failure <= 0;
  1955. X}
  1956. X
  1957. X/* Recursively descend the article tree, enumerating the articles as we go.
  1958. X** This way we can output the article sequence numbers into the data file.
  1959. X*/
  1960. Xvoid
  1961. Xenumerate_articles()
  1962. X{
  1963. X    register ROOT *root;
  1964. X
  1965. X    seq = article_seq = 0;
  1966. X
  1967. X    for (root = root_root; root; root = root->link) {
  1968. X    root->seq = seq++;
  1969. X    if (!root->articles) {
  1970. X        log_error("** No articles on this root??\n");
  1971. X        continue;
  1972. X    }
  1973. X    enumerate_thread(root->articles);
  1974. X    }
  1975. X    if (seq != total.root) {
  1976. X    log_error("** Wrote %d roots instead of %d **\n", seq, total.root);
  1977. X    }
  1978. X    if (article_seq != total.article) {
  1979. X    log_error("** Wrote %d articles instead of %d **\n", article_seq, total.article);
  1980. X    }
  1981. X}
  1982. X
  1983. X/* Recursive routine for above-mentioned enumeration. */
  1984. Xvoid
  1985. Xenumerate_thread(article)
  1986. XARTICLE *article;
  1987. X{
  1988. X    while (article) {
  1989. X    article->seq = article_seq++;
  1990. X    if (article->children) {
  1991. X        enumerate_thread(article->children);
  1992. X    }
  1993. X    article = article->siblings;
  1994. X    }
  1995. X}
  1996. X
  1997. X#define write_and_free(str_ptr)    /* Comment for makedepend to     \
  1998. X                    ** ignore the backslash above */ \
  1999. X{\
  2000. X    register int len = strlen(str_ptr) + 1;\
  2001. X    write_item(str_ptr, len);\
  2002. X    free(str_ptr);\
  2003. X    string_offset += len;\
  2004. X}
  2005. X
  2006. XMEM_SIZE string_offset;
  2007. X
  2008. X/* Write out the author information:  first the use-counts, then the
  2009. X** name strings all packed together.
  2010. X*/
  2011. Xvoid
  2012. Xwrite_authors()
  2013. X{
  2014. X    register AUTHOR *author;
  2015. X
  2016. X    seq = 0;
  2017. X    for (author = author_root; author; author = author->link) {
  2018. X    write_item(&author->count, sizeof (WORD));
  2019. X    author->seq = seq++;
  2020. X    }
  2021. X    if (seq != total.author) {
  2022. X    log_error("** Wrote %d authors instead of %d **\n",
  2023. X        seq, total.author);
  2024. X    }
  2025. X
  2026. X    string_offset = 0;
  2027. X
  2028. X    for (author = author_root; author; author = author->link) {
  2029. X    write_and_free(author->name);
  2030. X    }
  2031. X}
  2032. X
  2033. X/* Write out the subject information: first the packed string data, then
  2034. X** the use-counts.  The order is important -- it is the order required
  2035. X** by the roots for their subject structures.
  2036. X*/
  2037. Xvoid
  2038. Xwrite_subjects()
  2039. X{
  2040. X    register ROOT *root;
  2041. X    register SUBJECT *subject;
  2042. X
  2043. X    for (root = root_root; root; root = root->link) {
  2044. X    for (subject = root->subjects; subject; subject = subject->link) {
  2045. X        write_and_free(subject->str);
  2046. X    }
  2047. X    }
  2048. X    if (string_offset != total.string1) {
  2049. X    log_error("** Author/subject strings were %ld bytes instead of %ld **\n",
  2050. X        string_offset, total.string1);
  2051. X    }
  2052. X
  2053. X    seq = 0;
  2054. X    for (root = root_root; root; root = root->link) {
  2055. X    for (subject = root->subjects; subject; subject = subject->link) {
  2056. X        write_item(&subject->count, sizeof (WORD));
  2057. X        subject->seq = seq++;
  2058. X    }
  2059. X    }
  2060. X    if (seq != total.subject) {
  2061. X    log_error("** Wrote %d subjects instead of %d **\n",
  2062. X        seq, total.subject);
  2063. X    }
  2064. X}
  2065. X
  2066. X/* Write the roots in a packed format.  Interpret the pointers into
  2067. X** sequence numbers as we go.
  2068. X*/
  2069. Xvoid
  2070. Xwrite_roots()
  2071. X{
  2072. X    register ROOT *root;
  2073. X
  2074. X    for (root = root_root; root; root = root->link) {
  2075. X    p_root.articles = root->articles->seq;
  2076. X    p_root.root_num = root->root_num;
  2077. X    p_root.thread_cnt = root->thread_cnt;
  2078. X    p_root.subject_cnt = root->subject_cnt;
  2079. X    write_item(&p_root, sizeof (PACKED_ROOT));
  2080. X    }
  2081. X}
  2082. X
  2083. X#define rel_article(article, rseq)    ((article)? (article)->seq - (rseq) : 0)
  2084. X#define valid_seq(ptr)        ((ptr)? (ptr)->seq : -1)
  2085. X
  2086. X/* Write all the articles in the same order that we sequenced them. */
  2087. Xvoid
  2088. Xwrite_articles()
  2089. X{
  2090. X    register ROOT *root;
  2091. X
  2092. X    for (root = root_root; root; root = root->link) {
  2093. X    write_thread(root->articles);
  2094. X    }
  2095. X}
  2096. X
  2097. X/* Recursive routine to write the articles in thread order.  We depend on
  2098. X** the fact that our first child is the very next article written (if we
  2099. X** have children).
  2100. X*/
  2101. Xvoid
  2102. Xwrite_thread(article)
  2103. Xregister ARTICLE *article;
  2104. X{
  2105. X    while (article) {
  2106. X    p_article.num = article->num;
  2107. X    p_article.date = article->date;
  2108. X    p_article.subject = valid_seq(article->subject);
  2109. X    p_article.author = valid_seq(article->author);
  2110. X    p_article.flags = article->flags;
  2111. X    p_article.child_cnt = article->child_cnt;
  2112. X    p_article.parent = rel_article(article->parent, article->seq);
  2113. X    p_article.siblings = rel_article(article->siblings, article->seq);
  2114. X    p_article.root = article->root->seq;
  2115. X    write_item(&p_article, sizeof (PACKED_ARTICLE));
  2116. X    if (article->children) {
  2117. X        write_thread(article->children);
  2118. X    }
  2119. X    article = article->siblings;
  2120. X    }
  2121. X}
  2122. X
  2123. XWORD minus_one = -1;
  2124. X
  2125. X/* Write the message-id strings:  each domain name (not including the
  2126. X** ".unknown." domain) followed by all of its associated unique ids.
  2127. X** Then output the article sequence numbers they belong to.  This stuff
  2128. X** is last because the newsreader doesn't need to read it.
  2129. X*/
  2130. Xvoid
  2131. Xwrite_ids()
  2132. X{
  2133. X    register DOMAIN *domain;
  2134. X    register ARTICLE *id;
  2135. X    register DOMAIN *next_domain;
  2136. X    register ARTICLE *next_id;
  2137. X
  2138. X    string_offset = 0;
  2139. X
  2140. X    for (domain = &unk_domain; domain; domain = domain->link) {
  2141. X    if (domain != &unk_domain) {
  2142. X        write_and_free(domain->name);
  2143. X        if (!domain->ids) {
  2144. X        log_error("** Empty domain name!! **\n");
  2145. X        }
  2146. X    }
  2147. X    for (id = domain->ids; id; id = id->id_link) {
  2148. X        write_and_free(id->id);
  2149. X    }
  2150. X    }
  2151. X    if (string_offset != total.string2) {
  2152. X    log_error("** Message-id strings were %ld bytes (%ld) **\n",
  2153. X        string_offset, total.string2);
  2154. X    }
  2155. X    for (domain = &unk_domain; domain; domain = next_domain) {
  2156. X    next_domain = domain->link;
  2157. X    for (id = domain->ids; id; id = next_id) {
  2158. X        next_id = id->id_link;
  2159. X        write_item(&id->seq, sizeof (WORD));
  2160. X        free(id);
  2161. X    }
  2162. X    write_item(&minus_one, sizeof (WORD));
  2163. X    if (domain != &unk_domain) {
  2164. X        free(domain);
  2165. X    }
  2166. X    }
  2167. X    unk_domain.ids = Nullart;
  2168. X    unk_domain.link = Null(DOMAIN*);
  2169. X}
  2170. X
  2171. X/* Free everything that's left to free.
  2172. X*/
  2173. Xvoid
  2174. Xfree_leftovers()
  2175. X{
  2176. X    register ROOT *root, *next_root;
  2177. X    register SUBJECT *subj, *next_subj;
  2178. X    register AUTHOR *author, *next_author;
  2179. X
  2180. X    for (root = root_root; root; root = next_root) {
  2181. X    next_root = root->link;
  2182. X    for (subj = root->subjects; subj; subj = next_subj) {
  2183. X        next_subj = subj->link;
  2184. X        free(subj);
  2185. X    }
  2186. X    free(root);
  2187. X    }
  2188. X    for (author = author_root; author; author = next_author) {
  2189. X    next_author = author->link;
  2190. X    free(author);
  2191. X    }
  2192. X    root_root = Null(ROOT*);
  2193. X    author_root = Null(AUTHOR*);
  2194. X}
  2195. X
  2196. X/* This routine will check to be sure that the required path exists for
  2197. X** the data file, and if not it will attempt to create it.
  2198. X*/
  2199. Xint
  2200. Xensure_path(filename)
  2201. Xregister char *filename;
  2202. X{
  2203. X    int status, pid, w;
  2204. X    char tmpbuf[1024];
  2205. X#ifdef MAKEDIR
  2206. X    register char *cp, *last;
  2207. X    register char *tbptr = tmpbuf+5;
  2208. X
  2209. X    if (!(last = rindex(filename, '/'))) {    /* find filename portion */
  2210. X    return 1;                /* no path, we're fine */
  2211. X    }
  2212. X    *last = '\0';                /* truncate path at filename */
  2213. X    strcpy(tmpbuf, "mkdir");
  2214. X
  2215. X    for (cp = last;;) {
  2216. X    if (stat(filename, &filestat) >= 0 && (filestat.st_mode & S_IFDIR)) {
  2217. X        *cp = '/';
  2218. X        break;
  2219. X    }
  2220. X    if (!(cp = rindex(filename, '/'))) {/* find something that exists */
  2221. X        break;
  2222. X    }
  2223. X    *cp = '\0';
  2224. X    }
  2225. X    
  2226. X    for (cp = filename; cp <= last; cp++) {
  2227. X    if (!*cp) {
  2228. X        sprintf(tbptr, " %s", filename);
  2229. X        tbptr += strlen(tbptr);        /* set up for mkdir call */
  2230. X        *cp = '/';
  2231. X    }
  2232. X    }
  2233. X    if (tbptr == tmpbuf+5) {
  2234. X    return 1;
  2235. X    }
  2236. X#else
  2237. X    sprintf(tmpbuf,"%s %s %d", file_exp(DIRMAKER), filename, 1);
  2238. X#endif
  2239. X
  2240. X    if ((pid = vfork()) == 0) {
  2241. X    execl(SH, SH, "-c", tmpbuf, Nullch);
  2242. X    _exit(127);
  2243. X    }
  2244. X    while ((w = wait(&status)) != pid && w != -1) {
  2245. X    ;
  2246. X    }
  2247. X    if (w == -1) {
  2248. X    status = -1;
  2249. X    }
  2250. X    return !status;
  2251. X}
  2252. X
  2253. X/* A simple routine to output some data only if we haven't failed any
  2254. X** previous writes.
  2255. X*/
  2256. Xvoid
  2257. Xwrite_item(buff, len)
  2258. Xchar *buff;
  2259. Xint len;
  2260. X{
  2261. X    if (!failure) {
  2262. X    if (fwrite(buff, 1, len, fp_out) < len) {
  2263. X        failure = 1;
  2264. X    }
  2265. X    }
  2266. X}
  2267. END_OF_FILE
  2268. if test 9773 -ne `wc -c <'mt-write.c'`; then
  2269.     echo shar: \"'mt-write.c'\" unpacked with wrong size!
  2270. fi
  2271. # end of 'mt-write.c'
  2272. fi
  2273. if test -f 'mt.check.SH' -a "${1}" != "-c" ; then 
  2274.   echo shar: Will not clobber existing file \"'mt.check.SH'\"
  2275. else
  2276. echo shar: Extracting \"'mt.check.SH'\" \(1287 characters\)
  2277. sed "s/^X//" >'mt.check.SH' <<'END_OF_FILE'
  2278. Xcase $CONFIG in
  2279. X    '') . ./config.sh ;;
  2280. Xesac
  2281. Xecho "Extracting mt.check (with variable substitutions)"
  2282. Xset `cat patchlevel.h`
  2283. Xversion=$4
  2284. X$spitshell >mt.check <<!GROK!THIS!
  2285. X$startsh
  2286. X# $Id: mt.check.SH,v 3.0 1993/09/22 04:11:10 davison Trn $
  2287. X#
  2288. X# mt.check - daily maintenance for mt.log
  2289. X#
  2290. X# Check mt.log for earth-shattering errors, and mail them to \$gurus if found.
  2291. X# Then move the mt.log file into a week-long history chain.
  2292. X#
  2293. X# Usage: mt.check
  2294. X#
  2295. X
  2296. Xgurus="$newsadmin"
  2297. Xtmp="/tmp/mt.c\$\$"
  2298. X
  2299. XPATH=/bin:/usr/bin
  2300. Xexport PATH
  2301. X
  2302. Xumask 002
  2303. X
  2304. Xtrap "rm -f \$tmp ; exit 0" 0 1 2 15
  2305. X
  2306. Xcd $privlib
  2307. X
  2308. X$egrep " \\*\\*\$" mt.log >\$tmp
  2309. X
  2310. Xif test -s \$tmp ; then
  2311. X    (cat <<EOT
  2312. XTo: \$gurus
  2313. XSubject: mthreads error!
  2314. X
  2315. XThe following errors were reported in mt.log.  If the error pertains to
  2316. Xthe active file,  you should lock down your news system and fix it.  If
  2317. Xit is a thread-releated bug and it persists, please report this fact to
  2318. XWayne Davison (davison@borland.com).  Mention version "$version".
  2319. X
  2320. XEOT
  2321. X    cat \$tmp) | mail \$gurus
  2322. Xfi
  2323. X
  2324. Xtest -f mt.log.6 && mv mt.log.6 mt.log.7
  2325. Xtest -f mt.log.5 && mv mt.log.5 mt.log.6
  2326. Xtest -f mt.log.4 && mv mt.log.4 mt.log.5
  2327. Xtest -f mt.log.3 && mv mt.log.3 mt.log.4
  2328. Xtest -f mt.log.2 && mv mt.log.2 mt.log.3
  2329. Xtest -f mt.log   && mv mt.log   mt.log.2
  2330. Xtouch mt.log
  2331. X
  2332. Xexit 0
  2333. X!GROK!THIS!
  2334. END_OF_FILE
  2335. if test 1287 -ne `wc -c <'mt.check.SH'`; then
  2336.     echo shar: \"'mt.check.SH'\" unpacked with wrong size!
  2337. fi
  2338. # end of 'mt.check.SH'
  2339. fi
  2340. if test -f 'mthreads.h' -a "${1}" != "-c" ; then 
  2341.   echo shar: Will not clobber existing file \"'mthreads.h'\"
  2342. else
  2343. echo shar: Extracting \"'mthreads.h'\" \(1797 characters\)
  2344. sed "s/^X//" >'mthreads.h' <<'END_OF_FILE'
  2345. X/* $Id: mthreads.h,v 3.0 1993/10/01 00:14:07 davison Trn $
  2346. X*/
  2347. X/* The authors make no claims as to the fitness or correctness of this software
  2348. X * for any use whatsoever, and it is provided as is. Any use of this software
  2349. X * is at the user's own risk. 
  2350. X */
  2351. X
  2352. X#define RWBUFSIZ 8192
  2353. X
  2354. X#define PASS_LOCK 1
  2355. X#define DAEMON_LOCK 2
  2356. X
  2357. X#define NO_LISTGROUP    0
  2358. X#define GOOD_LISTGROUP    1
  2359. X#define BAD_LISTGROUP    2
  2360. X#define CHECK_LISTGROUP    3
  2361. X
  2362. XEXT char rwbuf[RWBUFSIZ];
  2363. X
  2364. XEXT TOTAL total;
  2365. X
  2366. XEXT int added_articles INIT(0);
  2367. XEXT int expired_articles INIT(0);
  2368. XEXT int added_count;
  2369. XEXT int expired_count;
  2370. XEXT bool extra_expire INIT(FALSE);
  2371. X
  2372. XEXT char *strings INIT(0);
  2373. XEXT WORD *subject_cnts INIT(0);
  2374. XEXT WORD *author_cnts INIT(0);
  2375. XEXT WORD *ids INIT(0);
  2376. X
  2377. XEXT SUBJECT **subject_array;
  2378. XEXT ROOT **root_array;
  2379. XEXT AUTHOR **author_array;
  2380. XEXT ARTICLE **article_array;
  2381. X
  2382. XEXT PACKED_ROOT p_root;
  2383. XEXT PACKED_ARTICLE p_article;
  2384. X
  2385. XEXT ROOT *root_root;
  2386. XEXT AUTHOR *author_root;
  2387. X
  2388. X#ifndef DOINIT
  2389. XEXT DOMAIN unk_domain;
  2390. X#else
  2391. XDOMAIN unk_domain = {
  2392. X    ".unknown.", NULL, NULL
  2393. X};
  2394. X#endif
  2395. X
  2396. XEXT bool word_same, long_same;
  2397. XEXT BMAP my_bmap, mt_bmap;
  2398. X
  2399. Xchar *thread_name _((char *));
  2400. Xvoid mybytemap _((BMAP *));
  2401. Xvoid wp_bmap(), lp_bmap(), swap_bmaps();
  2402. X
  2403. Xint ngmatch _((char *,char *));
  2404. Xint onepatmatch _((char *,char *));
  2405. X
  2406. Xvoid mt_init _((void));
  2407. Xlong mt_lock _((int, int));
  2408. Xvoid mt_unlock _((int));
  2409. Xvoid wrap_it_up _((int));
  2410. Xvoid log_entry();
  2411. Xvoid log_error();
  2412. X
  2413. Xint init_data _((char *));
  2414. Xint read_data _((void));
  2415. Xint write_data _((char *));
  2416. Xvoid dont_read_data _((int));
  2417. X
  2418. Xvoid process_articles _((ART_NUM,ART_NUM));
  2419. X
  2420. Xchar *file_exp _((char *));
  2421. Xchar *savestr _((char *));
  2422. X
  2423. Xtime_t parsedate _((char *));
  2424. X
  2425. X#ifndef lint
  2426. Xchar *safemalloc _((MEM_SIZE));
  2427. Xvoid safefree();
  2428. X#endif
  2429. X
  2430. Xtime_t get_date _((char *,time_t,long));
  2431. X
  2432. X#define Nullart Null(ARTICLE*)
  2433. END_OF_FILE
  2434. if test 1797 -ne `wc -c <'mthreads.h'`; then
  2435.     echo shar: \"'mthreads.h'\" unpacked with wrong size!
  2436. fi
  2437. # end of 'mthreads.h'
  2438. fi
  2439. if test -f 'ndir.c' -a "${1}" != "-c" ; then 
  2440.   echo shar: Will not clobber existing file \"'ndir.c'\"
  2441. else
  2442. echo shar: Extracting \"'ndir.c'\" \(2375 characters\)
  2443. sed "s/^X//" >'ndir.c' <<'END_OF_FILE'
  2444. X/* $Id: ndir.c,v 3.0 1991/09/09 20:23:31 davison Trn $
  2445. X */
  2446. X/* This software is Copyright 1991 by Stan Barber. 
  2447. X *
  2448. X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  2449. X * use this software as long as: there is no monetary profit gained
  2450. X * specifically from the use or reproduction of this software, it is not
  2451. X * sold, rented, traded or otherwise marketed, and this copyright notice is
  2452. X * included prominently in any copy made. 
  2453. X *
  2454. X * The authors make no claims as to the fitness or correctness of this software
  2455. X * for any use whatsoever, and it is provided as is. Any use of this software
  2456. X * is at the user's own risk. 
  2457. X */
  2458. X
  2459. X#include "EXTERN.h"
  2460. X#include "common.h"
  2461. X#include "INTERN.h"
  2462. X#include "ndir.h"
  2463. X
  2464. X#ifdef EMULATE_NDIR
  2465. X/*
  2466. X * support for Berkeley directory reading routine on a V7 file system
  2467. X */
  2468. X
  2469. X/*
  2470. X * open a directory.
  2471. X */
  2472. XDIR *
  2473. Xopendir(name)
  2474. Xchar *name;
  2475. X{
  2476. X    register DIR *dirp;
  2477. X    register int fd;
  2478. X    char *malloc();
  2479. X
  2480. X    if ((fd = open(name, 0)) == -1)
  2481. X        return NULL;
  2482. X    if ((dirp = (DIR *)malloc(sizeof(DIR))) == NULL) {
  2483. X        close (fd);
  2484. X        return NULL;
  2485. X    }
  2486. X    dirp->dd_fd = fd;
  2487. X    dirp->dd_loc = 0;
  2488. X    return dirp;
  2489. X}
  2490. X
  2491. X/*
  2492. X * read an old style directory entry and present it as a new one
  2493. X */
  2494. X#ifndef pyr
  2495. X#define    ODIRSIZ    14
  2496. X
  2497. Xstruct    olddirect {
  2498. X    ino_t    od_ino;
  2499. X    char    od_name[ODIRSIZ];
  2500. X};
  2501. X#else    /* an Pyramid in the ATT universe */
  2502. X#define    ODIRSIZ    248
  2503. X
  2504. Xstruct    olddirect {
  2505. X    long    od_ino;
  2506. X    short    od_fill1, od_fill2;
  2507. X    char    od_name[ODIRSIZ];
  2508. X};
  2509. X#endif
  2510. X
  2511. X/*
  2512. X * get next entry in a directory.
  2513. X */
  2514. Xstruct direct *
  2515. Xreaddir(dirp)
  2516. Xregister DIR *dirp;
  2517. X{
  2518. X    register struct olddirect *dp;
  2519. X    static struct direct dir;
  2520. X
  2521. X    for (;;) {
  2522. X        if (dirp->dd_loc == 0) {
  2523. X            dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf,
  2524. X                DIRBLKSIZ);
  2525. X            if (dirp->dd_size <= 0)
  2526. X                return NULL;
  2527. X        }
  2528. X        if (dirp->dd_loc >= dirp->dd_size) {
  2529. X            dirp->dd_loc = 0;
  2530. X            continue;
  2531. X        }
  2532. X        dp = (struct olddirect *)(dirp->dd_buf + dirp->dd_loc);
  2533. X        dirp->dd_loc += sizeof(struct olddirect);
  2534. X        if (dp->od_ino == 0)
  2535. X            continue;
  2536. X        dir.d_ino = dp->od_ino;
  2537. X        strncpy(dir.d_name, dp->od_name, ODIRSIZ);
  2538. X        dir.d_name[ODIRSIZ] = '\0'; /* insure null termination */
  2539. X        dir.d_namlen = strlen(dir.d_name);
  2540. X        dir.d_reclen = DIRSIZ(&dir);
  2541. X        return (&dir);
  2542. X    }
  2543. X}
  2544. X
  2545. X/*
  2546. X * close a directory.
  2547. X */
  2548. Xvoid
  2549. Xclosedir(dirp)
  2550. Xregister DIR *dirp;
  2551. X{
  2552. X    close(dirp->dd_fd);
  2553. X    dirp->dd_fd = -1;
  2554. X    dirp->dd_loc = 0;
  2555. X    free(dirp);
  2556. X}
  2557. X
  2558. X#endif /* EMULATE_NDIR */
  2559. END_OF_FILE
  2560. if test 2375 -ne `wc -c <'ndir.c'`; then
  2561.     echo shar: \"'ndir.c'\" unpacked with wrong size!
  2562. fi
  2563. # end of 'ndir.c'
  2564. fi
  2565. if test -f 'ndir.h' -a "${1}" != "-c" ; then 
  2566.   echo shar: Will not clobber existing file \"'ndir.h'\"
  2567. else
  2568. echo shar: Extracting \"'ndir.h'\" \(2045 characters\)
  2569. sed "s/^X//" >'ndir.h' <<'END_OF_FILE'
  2570. X/* $Id: ndir.h,v 3.0 1991/09/09 20:23:31 davison Trn $
  2571. X */
  2572. X/* This software is Copyright 1991 by Stan Barber. 
  2573. X *
  2574. X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  2575. X * use this software as long as: there is no monetary profit gained
  2576. X * specifically from the use or reproduction of this software, it is not
  2577. X * sold, rented, traded or otherwise marketed, and this copyright notice is
  2578. X * included prominently in any copy made. 
  2579. X *
  2580. X * The authors make no claims as to the fitness or correctness of this software
  2581. X * for any use whatsoever, and it is provided as is. Any use of this software
  2582. X * is at the user's own risk. 
  2583. X */
  2584. X
  2585. X#ifdef I_NDIR
  2586. X#include <ndir.h>
  2587. X#else
  2588. X#ifdef I_DIRENT
  2589. X#include <dirent.h>
  2590. X#ifndef direct
  2591. X#define direct dirent
  2592. X#endif
  2593. X#else
  2594. X#ifdef I_SYS_NDIR
  2595. X#include <sys/ndir.h>
  2596. X#else
  2597. X#ifdef I_SYS_DIR
  2598. X#include <sys/dir.h>
  2599. X#else
  2600. X
  2601. X#ifndef DEV_BSIZE
  2602. X#define    DEV_BSIZE    512
  2603. X#endif
  2604. X#define DIRBLKSIZ    DEV_BSIZE
  2605. X#define    MAXNAMLEN    255
  2606. X
  2607. Xstruct    direct {
  2608. X    long    d_ino;            /* inode number of entry */
  2609. X    short    d_reclen;        /* length of this record */
  2610. X    short    d_namlen;        /* length of string in d_name */
  2611. X    char    d_name[MAXNAMLEN + 1];    /* name must be no longer than this */
  2612. X};
  2613. X
  2614. X/*
  2615. X * The DIRSIZ macro gives the minimum record length which will hold
  2616. X * the directory entry.  This requires the amount of space in struct direct
  2617. X * without the d_name field, plus enough space for the name with a terminating
  2618. X * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
  2619. X */
  2620. X#undef DIRSIZ
  2621. X#define DIRSIZ(dp)     ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
  2622. X
  2623. X/*
  2624. X * Definitions for library routines operating on directories.
  2625. X */
  2626. Xtypedef struct _dirdesc {
  2627. X    int    dd_fd;
  2628. X    long    dd_loc;
  2629. X    long    dd_size;
  2630. X    char    dd_buf[DIRBLKSIZ];
  2631. X} DIR;
  2632. X#ifndef NULL
  2633. X#define NULL 0
  2634. X#endif
  2635. Xextern    DIR *opendir _((char*));
  2636. Xextern    struct direct *readdir _((DIR*));
  2637. Xextern    long telldir _((DIR*));
  2638. Xextern    void seekdir _((DIR*));
  2639. X#define rewinddir(dirp)    seekdir((dirp), (long)0)
  2640. Xextern    void closedir _((DIR*));
  2641. X
  2642. X#endif
  2643. X#endif
  2644. X#endif
  2645. X#endif
  2646. END_OF_FILE
  2647. if test 2045 -ne `wc -c <'ndir.h'`; then
  2648.     echo shar: \"'ndir.h'\" unpacked with wrong size!
  2649. fi
  2650. # end of 'ndir.h'
  2651. fi
  2652. if test -f 'nntpclient.c' -a "${1}" != "-c" ; then 
  2653.   echo shar: Will not clobber existing file \"'nntpclient.c'\"
  2654. else
  2655. echo shar: Extracting \"'nntpclient.c'\" \(3661 characters\)
  2656. sed "s/^X//" >'nntpclient.c' <<'END_OF_FILE'
  2657. X/* $Id: nntpclient.c,v 3.0 1991/11/22 04:12:21 davison Trn $
  2658. X*/
  2659. X/* The authors make no claims as to the fitness or correctness of this software
  2660. X * for any use whatsoever, and it is provided as is. Any use of this software
  2661. X * is at the user's own risk. 
  2662. X */
  2663. X
  2664. X#include "EXTERN.h"
  2665. X#include "common.h"
  2666. X
  2667. X#ifdef USE_NNTP
  2668. X
  2669. X#include "INTERN.h"
  2670. X#include "nntpclient.h"
  2671. X
  2672. X#define CANTPOST    \
  2673. X    "NOTE:  This machine does not have permission to post articles.\n"
  2674. X#define CANTUSE        \
  2675. X    "This machine does not have permission to use the %s news server.\n"
  2676. X
  2677. Xint
  2678. Xnntp_connect()
  2679. X{
  2680. X    char *server, filebuf[128];
  2681. X    int response;
  2682. X
  2683. X    if ((server = getenv("NNTPSERVER")) == Nullch)
  2684. X    server = SERVER_NAME;
  2685. X    if (server[0] == '/') {
  2686. X    register FILE *fp;
  2687. X    if ((fp = fopen(server, "r")) != Nullfp) {
  2688. X        server = Nullch;
  2689. X        while (fgets(filebuf, sizeof filebuf, fp) != Nullch) {
  2690. X        if (*filebuf == '\n' || *filebuf == '#')
  2691. X            continue;
  2692. X        if ((server = index(filebuf, '\n')) != Nullch)
  2693. X            *server = '\0';
  2694. X        server = filebuf;
  2695. X        break;
  2696. X        }
  2697. X        fclose(fp);
  2698. X    } else
  2699. X        server = Nullch;
  2700. X    if (server == Nullch) {
  2701. X        sprintf(ser_line, "\
  2702. XCouldn't get name of news server from %s\n\
  2703. XEither fix this file, or put NNTPSERVER in your environment.\n", SERVER_NAME);
  2704. X        report_error(ser_line);
  2705. X        return 0;
  2706. X    }
  2707. X    }
  2708. X
  2709. X    switch (response = server_init(server)) {
  2710. X    case NNTP_GOODBYE_VAL:
  2711. X    if (atoi(ser_line) == response) {
  2712. X        char tmpbuf[LBUFLEN];
  2713. X        sprintf(tmpbuf,"News server %s unavailable: %s\n",server,&ser_line[4]);
  2714. X        report_error(tmpbuf);
  2715. X        return 0;
  2716. X    }
  2717. X    case -1:
  2718. X    sprintf(ser_line,"News server %s unavailable, try again later.\n",server);
  2719. X    report_error(ser_line);
  2720. X    return 0;
  2721. X    case NNTP_ACCESS_VAL:
  2722. X    sprintf(ser_line,CANTUSE,server);
  2723. X    report_error(ser_line);
  2724. X    return 0;
  2725. X    case NNTP_NOPOSTOK_VAL:
  2726. X    advise(CANTPOST);
  2727. X    /* FALL THROUGH */
  2728. X    case NNTP_POSTOK_VAL:
  2729. X    break;
  2730. X    default:
  2731. X    sprintf(ser_line,"Unknown response code %d from %s.\n", response, server);
  2732. X    report_error(ser_line);
  2733. X    return 0;
  2734. X    }
  2735. X    return 1;
  2736. X}
  2737. X
  2738. Xvoid
  2739. Xnntp_command(buf)
  2740. Xchar *buf;
  2741. X{
  2742. X#if defined(DEBUG) && defined(FLUSH)
  2743. X    if (debug & DEB_NNTP)
  2744. X    printf(">%s\n", buf) FLUSH;
  2745. X#endif
  2746. X    fprintf(ser_wr_fp, "%s\r\n", buf);
  2747. X    fflush(ser_wr_fp);
  2748. X}
  2749. X
  2750. Xchar
  2751. Xnntp_check(strict)
  2752. Xbool_int strict;
  2753. X{
  2754. X    int n;
  2755. X
  2756. X#ifdef HAS_SIGHOLD
  2757. X    sighold(SIGINT);
  2758. X#endif
  2759. X    n = (fgets(ser_line, sizeof ser_line, ser_rd_fp) == NULL)? -1 : 0;
  2760. X#ifdef HAS_SIGHOLD
  2761. X    sigrelse(SIGINT);
  2762. X#endif
  2763. X    if (n < 0)
  2764. X#ifdef fatal_error
  2765. X    fatal_error("\nUnexpected close of server socket.\n");
  2766. X#else
  2767. X    return NNTP_CLASS_FATAL;
  2768. X#endif
  2769. X    n = strlen(ser_line);
  2770. X    if (n >= 2 && ser_line[n-1] == '\n' && ser_line[n-2] == '\r')
  2771. X    ser_line[n-2] = '\0';
  2772. X#if defined(DEBUG) && defined(FLUSH)
  2773. X    if (debug & DEB_NNTP)
  2774. X    printf("<%s\n", ser_line) FLUSH;
  2775. X#endif
  2776. X#ifdef fatal_error
  2777. X    if (strict && *ser_line == NNTP_CLASS_FATAL) {    /* Fatal error */
  2778. X    char tmpbuf[LBUFLEN];
  2779. X    sprintf(tmpbuf,"\n%s\n",ser_line);
  2780. X    fatal_error(tmpbuf);
  2781. X    }
  2782. X#endif
  2783. X    return *ser_line;
  2784. X}
  2785. X
  2786. Xint
  2787. Xnntp_gets(buf, len)
  2788. Xchar *buf;
  2789. Xint  len;
  2790. X{
  2791. X    int n;
  2792. X
  2793. X#ifdef HAS_SIGHOLD
  2794. X    sighold(SIGINT);
  2795. X#endif
  2796. X    n = (fgets(buf, len, ser_rd_fp) == NULL)? -1 : 0;
  2797. X#ifdef HAS_SIGHOLD
  2798. X    sigrelse(SIGINT);
  2799. X#endif
  2800. X    if (n < 0)
  2801. X#ifdef fatal_error
  2802. X    fatal_error("\nUnexpected close of server socket.\n");
  2803. X#else
  2804. X    return -1;
  2805. X#endif
  2806. X    n = strlen(buf);
  2807. X    if (n >= 2 && buf[n-1] == '\n' && buf[n-2] == '\r')
  2808. X    buf[n-2] = '\0';
  2809. X    return 0;
  2810. X}
  2811. X
  2812. Xvoid
  2813. Xnntp_close()
  2814. X{
  2815. X    if (ser_wr_fp != NULL && ser_rd_fp != NULL) {
  2816. X    nntp_command("QUIT");
  2817. X    fclose(ser_wr_fp);
  2818. X    ser_wr_fp = NULL;
  2819. X
  2820. X    nntp_check(FALSE);
  2821. X    fclose(ser_rd_fp);
  2822. X    ser_rd_fp = NULL;
  2823. X    }
  2824. X}
  2825. X
  2826. X#endif /* USE_NNTP */
  2827. END_OF_FILE
  2828. if test 3661 -ne `wc -c <'nntpclient.c'`; then
  2829.     echo shar: \"'nntpclient.c'\" unpacked with wrong size!
  2830. fi
  2831. # end of 'nntpclient.c'
  2832. fi
  2833. if test -f 'nntpclient.h' -a "${1}" != "-c" ; then 
  2834.   echo shar: Will not clobber existing file \"'nntpclient.h'\"
  2835. else
  2836. echo shar: Extracting \"'nntpclient.h'\" \(1475 characters\)
  2837. sed "s/^X//" >'nntpclient.h' <<'END_OF_FILE'
  2838. X/* $Id: nntpclient.h,v 3.0 1992/12/14 00:14:55 davison Trn $
  2839. X*/ 
  2840. X/* The authors make no claims as to the fitness or correctness of this software
  2841. X * for any use whatsoever, and it is provided as is. Any use of this software
  2842. X * is at the user's own risk. 
  2843. X */
  2844. X
  2845. X#ifdef USE_NNTP
  2846. X
  2847. Xint    server_init _((char*));
  2848. X
  2849. Xint    nntp_connect _((void));
  2850. Xvoid    nntp_command _((char*));
  2851. Xchar    nntp_check _((bool_int));
  2852. Xint    nntp_gets _((char*, int));
  2853. Xvoid    nntp_close _((void));
  2854. X
  2855. X/* RFC 977 defines these, so don't change them */
  2856. X
  2857. X#define    NNTP_CLASS_INF      '1'
  2858. X#define NNTP_CLASS_OK       '2'
  2859. X#define    NNTP_CLASS_CONT     '3'
  2860. X#define    NNTP_CLASS_ERR      '4'
  2861. X#define    NNTP_CLASS_FATAL    '5'
  2862. X
  2863. X#define    NNTP_POSTOK_VAL     200    /* Hello -- you can post */
  2864. X#define    NNTP_NOPOSTOK_VAL    201    /* Hello -- you can't post */
  2865. X
  2866. X#define NNTP_GOODBYE_VAL    400    /* Have to hang up for some reason */
  2867. X#define    NNTP_NOSUCHGROUP_VAL    411    /* No such newsgroup */
  2868. X
  2869. X#define    NNTP_AUTH_NEEDED_VAL     480    /* Authorization Failed */
  2870. X#define    NNTP_AUTH_REJECT_VAL    482    /* Authorization data rejected */
  2871. X
  2872. X#define    NNTP_BAD_COMMAND_VAL    500    /* Command not recognized */
  2873. X#define    NNTP_SYNTAX_VAL        501    /* Command syntax error */
  2874. X#define    NNTP_ACCESS_VAL     502    /* Access to server denied */
  2875. X#define    NNTP_TMPERR_VAL      503    /* Program fault, command not performed */
  2876. X#define    NNTP_AUTH_BAD_VAL     580    /* Authorization Failed */
  2877. X
  2878. X#define    NNTP_STRLEN    512
  2879. X
  2880. XEXT FILE *ser_rd_fp INIT(NULL);
  2881. XEXT FILE *ser_wr_fp INIT(NULL);
  2882. XEXT char ser_line[NNTP_STRLEN];
  2883. X
  2884. X#endif /* USE_NNTP */
  2885. END_OF_FILE
  2886. if test 1475 -ne `wc -c <'nntpclient.h'`; then
  2887.     echo shar: \"'nntpclient.h'\" unpacked with wrong size!
  2888. fi
  2889. # end of 'nntpclient.h'
  2890. fi
  2891. if test -f 'nntpinit.c' -a "${1}" != "-c" ; then 
  2892.   echo shar: Will not clobber existing file \"'nntpinit.c'\"
  2893. else
  2894. echo shar: Extracting \"'nntpinit.c'\" \(9720 characters\)
  2895. sed "s/^X//" >'nntpinit.c' <<'END_OF_FILE'
  2896. X/* $Id: nntpinit.c,v 3.0 1991/11/22 04:12:21 davison Trn $
  2897. X*/
  2898. X/* This software is Copyright 1992 by Stan Barber. 
  2899. X *
  2900. X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  2901. X * use this software as long as: there is no monetary profit gained
  2902. X * specifically from the use or reproduction or this software, it is not
  2903. X * sold, rented, traded or otherwise marketed, and this copyright notice is
  2904. X * included prominently in any copy made. 
  2905. X *
  2906. X * The authors make no claims as to the fitness or correctness of this software
  2907. X * for any use whatsoever, and it is provided as is. Any use of this software
  2908. X * is at the user's own risk. 
  2909. X */
  2910. X
  2911. X#undef    DECNET    /* If you want decnet support */
  2912. X#undef    EXCELAN   /* Excelan EXOS 205 support */
  2913. X#undef    NONETDB      /* Define if you're missing netdb.h */
  2914. X
  2915. X#include "EXTERN.h"
  2916. X#include "common.h"
  2917. X#include "nntpclient.h"
  2918. X
  2919. X#ifdef USE_NNTP
  2920. X
  2921. X#include <sys/socket.h>
  2922. X#include <netinet/in.h>
  2923. X#ifdef NONETDB
  2924. X# define IPPORT_NNTP    ((unsigned short) 119)
  2925. X#else
  2926. X# include <netdb.h>
  2927. X#endif /* !EXCELAN */
  2928. X
  2929. X#ifdef EXCELAN
  2930. Xint connect _((int, struct sockaddr *));
  2931. Xunsigned short htons _((unsigned short));
  2932. Xunsigned long rhost _((char **));
  2933. Xint rresvport p((int));
  2934. Xint socket _((int, struct sockproto *, struct sockaddr_in *, int));
  2935. X#endif /* EXCELAN */
  2936. X
  2937. X#ifdef DECNET
  2938. X#include <netdnet/dn.h>
  2939. X#include <netdnet/dnetdb.h>
  2940. X#endif /* DECNET */
  2941. X
  2942. Xunsigned long inet_addr _((char *x));
  2943. Xint get_tcp_socket _((char *machine));
  2944. X
  2945. Xint
  2946. Xserver_init(server)
  2947. Xchar *server;
  2948. X{
  2949. X    char line2[NNTP_STRLEN];
  2950. X    int sockt_rd, sockt_wr;
  2951. X#ifdef DECNET
  2952. X    char *cp;
  2953. X
  2954. X    cp = index(server, ':');
  2955. X
  2956. X    if (cp && cp[1] == ':') {
  2957. X    *cp = '\0';
  2958. X    sockt_rd = get_dnet_socket(server);
  2959. X    } else
  2960. X    sockt_rd = get_tcp_socket(server);
  2961. X#else /* !DECNET */
  2962. X    sockt_rd = get_tcp_socket(server);
  2963. X#endif
  2964. X
  2965. X    if (sockt_rd < 0)
  2966. X    return -1;
  2967. X    sockt_wr = dup(sockt_rd);
  2968. X
  2969. X    /* Now we'll make file pointers (i.e., buffered I/O) out of
  2970. X    ** the socket file descriptor.  Note that we can't just
  2971. X    ** open a fp for reading and writing -- we have to open
  2972. X    ** up two separate fp's, one for reading, one for writing. */
  2973. X    if ((ser_rd_fp = fdopen(sockt_rd, "r")) == NULL) {
  2974. X    perror("server_init: fdopen #1");
  2975. X    return -1;
  2976. X    }
  2977. X    if ((ser_wr_fp = fdopen(sockt_wr, "w")) == NULL) {
  2978. X    perror("server_init: fdopen #2");
  2979. X    ser_rd_fp = NULL;
  2980. X    return -1;
  2981. X    }
  2982. X
  2983. X    /* Now get the server's signon message */
  2984. X    nntp_check(FALSE);
  2985. X
  2986. X    if (*ser_line == NNTP_CLASS_OK) {
  2987. X    /* Send a MODE READER command in case we're talking to innd.
  2988. X    ** If understood, use that reply. */
  2989. X    nntp_command("MODE READER");
  2990. X    nntp_gets(line2, sizeof line2);
  2991. X    if (atoi(line2) != NNTP_BAD_COMMAND_VAL)
  2992. X        strcpy(ser_line, line2);
  2993. X    }
  2994. X    return atoi(ser_line);
  2995. X}
  2996. X
  2997. Xint
  2998. Xget_tcp_socket(server)
  2999. Xchar *server;
  3000. X{
  3001. X    int portno;    
  3002. X    int s;
  3003. X    struct sockaddr_in sin;
  3004. X#ifdef __hpux
  3005. X    int socksize = 0;
  3006. X    int socksizelen = sizeof socksize;
  3007. X#endif
  3008. X#ifdef NONETDB
  3009. X    bzero((char *) &sin, sizeof(sin));
  3010. X    sin.sin_family = AF_INET;
  3011. X#else
  3012. X    struct servent *getservbyname(), *sp;
  3013. X    struct hostent *gethostbyname(), *hp;
  3014. X#ifdef h_addr
  3015. X    int x = 0;
  3016. X    register char **cp;
  3017. X    static char *alist[1];
  3018. X#endif /* h_addr */
  3019. X    static struct hostent def;
  3020. X    static struct in_addr defaddr;
  3021. X    static char namebuf[ 256 ];
  3022. X
  3023. X    if ((sp = getservbyname("nntp", "tcp")) ==  NULL) {
  3024. X    fprintf(stderr, "nntp/tcp: Unknown service.\n");
  3025. X    return -1;
  3026. X    }
  3027. X    portno = sp->s_port;
  3028. X    /* If not a raw ip address, try nameserver */
  3029. X    if (!isdigit(*server)
  3030. X     || (long)(defaddr.s_addr = inet_addr(server)) == -1)
  3031. X    hp = gethostbyname(server);
  3032. X    else {
  3033. X    /* Raw ip address, fake  */
  3034. X    (void) strcpy(namebuf, server);
  3035. X    def.h_name = namebuf;
  3036. X#ifdef h_addr
  3037. X    def.h_addr_list = alist;
  3038. X#endif
  3039. X    def.h_addr = (char *)&defaddr;
  3040. X    def.h_length = sizeof(struct in_addr);
  3041. X    def.h_addrtype = AF_INET;
  3042. X    def.h_aliases = 0;
  3043. X    hp = &def;
  3044. X    }
  3045. X    if (hp == NULL) {
  3046. X    fprintf(stderr, "%s: Unknown host.\n", server);
  3047. X    return -1;
  3048. X    }
  3049. X
  3050. X    bzero((char *) &sin, sizeof(sin));
  3051. X    sin.sin_family = hp->h_addrtype;
  3052. X    sin.sin_port = portno;
  3053. X#endif /* !NONETDB */
  3054. X
  3055. X    /* The following is kinda gross.  The name server under 4.3
  3056. X    ** returns a list of addresses, each of which should be tried
  3057. X    ** in turn if the previous one fails.  However, 4.2 hostent
  3058. X    ** structure doesn't have this list of addresses.
  3059. X    ** Under 4.3, h_addr is a #define to h_addr_list[0].
  3060. X    ** We use this to figure out whether to include the NS specific
  3061. X    ** code... */
  3062. X#ifdef h_addr
  3063. X    /* get a socket and initiate connection -- use multiple addresses */
  3064. X    for (cp = hp->h_addr_list; cp && *cp; cp++) {
  3065. X    s = socket(hp->h_addrtype, SOCK_STREAM, 0);
  3066. X    if (s < 0) {
  3067. X        perror("socket");
  3068. X        return -1;
  3069. X    }
  3070. X        bcopy(*cp, (char *)&sin.sin_addr, hp->h_length);
  3071. X        
  3072. X    if (x < 0)
  3073. X        fprintf(stderr, "trying %s\n", inet_ntoa(sin.sin_addr));
  3074. X    x = connect(s, (struct sockaddr *)&sin, sizeof (sin));
  3075. X    if (x == 0)
  3076. X        break;
  3077. X        fprintf(stderr, "connection to %s: ", inet_ntoa(sin.sin_addr));
  3078. X    perror("");
  3079. X    (void) close(s);
  3080. X    }
  3081. X    if (x < 0) {
  3082. X    fprintf(stderr, "giving up...\n");
  3083. X    return -1;
  3084. X    }
  3085. X#else /* no name server */
  3086. X#ifdef EXCELAN
  3087. X    s = socket(SOCK_STREAM, (struct sockproto *)NULL, &sin, SO_KEEPALIVE);
  3088. X    if (s < 0) {
  3089. X    /* Get the socket */
  3090. X    perror("socket");
  3091. X    return -1;
  3092. X    }
  3093. X    bzero((char *) &sin, sizeof(sin));
  3094. X    sin.sin_family = AF_INET;
  3095. X    sin.sin_port = htons(IPPORT_NNTP);
  3096. X
  3097. X    /* set up addr for the connect */
  3098. X    if ((sin.sin_addr.s_addr = rhost(&server)) == -1) {
  3099. X    fprintf(stderr, "%s: Unknown host.\n", server);
  3100. X    return -1;
  3101. X    }
  3102. X
  3103. X    /* And then connect */
  3104. X    if (connect(s, (struct sockaddr *)&sin) < 0) {
  3105. X    perror("connect");
  3106. X    (void) close(s);
  3107. X    return -1;
  3108. X    }
  3109. X#else /* not EXCELAN */
  3110. X    if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
  3111. X    perror("socket");
  3112. X    return -1;
  3113. X    }
  3114. X
  3115. X    /* And then connect */
  3116. X
  3117. X    bcopy(hp->h_addr, (char *) &sin.sin_addr, hp->h_length);
  3118. X    if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
  3119. X    perror("connect");
  3120. X    (void) close(s);
  3121. X    return -1;
  3122. X    }
  3123. X
  3124. X#endif /* !EXCELAN */
  3125. X#endif /* !h_addr */
  3126. X#ifdef __hpux    /* recommended by raj@cup.hp.com */
  3127. X#define    HPSOCKSIZE 0x8000
  3128. X    getsockopt(s, SOL_SOCKET, SO_SNDBUF, (caddr_t)&socksize, (caddr_t)&socksizelen);
  3129. X    if (socksize < HPSOCKSIZE) {
  3130. X    socksize = HPSOCKSIZE;
  3131. X    setsockopt(s, SOL_SOCKET, SO_SNDBUF, (caddr_t)&socksize, sizeof(socksize));
  3132. X    }
  3133. X    socksize = 0;
  3134. X    socksizelen = sizeof(socksize);
  3135. X    getsockopt(s, SOL_SOCKET, SO_RCVBUF, (caddr_t)&socksize, (caddr_t)&socksizelen);
  3136. X    if (socksize < HPSOCKSIZE) {
  3137. X    socksize = HPSOCKSIZE;
  3138. X    setsockopt(s, SOL_SOCKET, SO_RCVBUF, (caddr_t)&socksize, sizeof(socksize));
  3139. X    }
  3140. X#endif
  3141. X    return s;
  3142. X}
  3143. X
  3144. X#ifdef DECNET
  3145. Xint
  3146. Xget_dnet_socket(server)
  3147. Xchar *server;
  3148. X{
  3149. X    int s, area, node;
  3150. X    struct sockaddr_dn sdn;
  3151. X    struct nodeent *getnodebyname(), *np;
  3152. X
  3153. X    bzero((char *) &sdn, sizeof(sdn));
  3154. X
  3155. X    switch (s = sscanf(server, "%d%*[.]%d", &area, &node)) {
  3156. X    case 1: 
  3157. X    node = area;
  3158. X    area = 0;
  3159. X    case 2: 
  3160. X    node += area*1024;
  3161. X    sdn.sdn_add.a_len = 2;
  3162. X    sdn.sdn_family = AF_DECnet;
  3163. X    sdn.sdn_add.a_addr[0] = node % 256;
  3164. X    sdn.sdn_add.a_addr[1] = node / 256;
  3165. X    break;
  3166. X    default:
  3167. X    if ((np = getnodebyname(server)) == NULL) {
  3168. X        fprintf(stderr, "%s: Unknown host.\n", server);
  3169. X        return -1;
  3170. X    } else {
  3171. X        bcopy(np->n_addr, (char *) sdn.sdn_add.a_addr, np->n_length);
  3172. X        sdn.sdn_add.a_len = np->n_length;
  3173. X        sdn.sdn_family = np->n_addrtype;
  3174. X    }
  3175. X    break;
  3176. X    }
  3177. X    sdn.sdn_objnum = 0;
  3178. X    sdn.sdn_flags = 0;
  3179. X    sdn.sdn_objnamel = strlen("NNTP");
  3180. X    bcopy("NNTP", &sdn.sdn_objname[0], sdn.sdn_objnamel);
  3181. X
  3182. X    if ((s = socket(AF_DECnet, SOCK_STREAM, 0)) < 0) {
  3183. X    nerror("socket");
  3184. X    return -1;
  3185. X    }
  3186. X
  3187. X    /* And then connect */
  3188. X    if (connect(s, (struct sockaddr *) &sdn, sizeof(sdn)) < 0) {
  3189. X    nerror("connect");
  3190. X    close(s);
  3191. X    return -1;
  3192. X    }
  3193. X    return s;
  3194. X}
  3195. X#endif /* DECNET */
  3196. X
  3197. X#ifdef EXCELAN
  3198. X/*
  3199. X * inet_addr for EXCELAN (which does not have it!)
  3200. X *
  3201. X */
  3202. Xunsigned long
  3203. Xinet_addr(cp)
  3204. Xregister char   *cp;
  3205. X{
  3206. X    unsigned long val, base, n;
  3207. X    register char c;
  3208. X    unsigned long octet[4], *octetptr = octet;
  3209. X#ifndef htonl
  3210. X    extern  unsigned long   htonl();
  3211. X#endif  /* htonl */
  3212. Xagain:
  3213. X    /*
  3214. X     * Collect number up to ``.''.
  3215. X     * Values are specified as for C:
  3216. X     * 0x=hex, 0=octal, other=decimal.
  3217. X     */
  3218. X    val = 0; base = 10;
  3219. X    if (*cp == '0')
  3220. X        base = 8, cp++;
  3221. X    if (*cp == 'x' || *cp == 'X')
  3222. X        base = 16, cp++;
  3223. X    while (c = *cp) {
  3224. X        if (isdigit(c)) {
  3225. X            val = (val * base) + (c - '0');
  3226. X            cp++;
  3227. X            continue;
  3228. X        }
  3229. X        if (base == 16 && isxdigit(c)) {
  3230. X            val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
  3231. X            cp++;
  3232. X            continue;
  3233. X        }
  3234. X        break;
  3235. X    }
  3236. X    if (*cp == '.') {
  3237. X        /*
  3238. X         * Internet format:
  3239. X         *      a.b.c.d
  3240. X         *      a.b.c   (with c treated as 16-bits)
  3241. X         *      a.b     (with b treated as 24 bits)
  3242. X         */
  3243. X        if (octetptr >= octet + 4)
  3244. X            return (-1);
  3245. X        *octetptr++ = val, cp++;
  3246. X        goto again;
  3247. X    }
  3248. X    /*
  3249. X     * Check for trailing characters.
  3250. X     */
  3251. X    if (*cp && !isspace(*cp))
  3252. X        return (-1);
  3253. X    *octetptr++ = val;
  3254. X    /*
  3255. X     * Concoct the address according to
  3256. X     * the number of octet specified.
  3257. X     */
  3258. X    n = octetptr - octet;
  3259. X    switch (n) {
  3260. X
  3261. X    case 1:                         /* a -- 32 bits */
  3262. X        val = octet[0];
  3263. X        break;
  3264. X
  3265. X    case 2:                         /* a.b -- 8.24 bits */
  3266. X        val = (octet[0] << 24) | (octet[1] & 0xffffff);
  3267. X        break;
  3268. X
  3269. X    case 3:                         /* a.b.c -- 8.8.16 bits */
  3270. X        val = (octet[0] << 24) | ((octet[1] & 0xff) << 16) |
  3271. X            (octet[2] & 0xffff);
  3272. X        break;
  3273. X
  3274. X    case 4:                         /* a.b.c.d -- 8.8.8.8 bits */
  3275. X        val = (octet[0] << 24) | ((octet[1] & 0xff) << 16) |
  3276. X              ((octet[2] & 0xff) << 8) | (octet[3] & 0xff);
  3277. X        break;
  3278. X
  3279. X    default:
  3280. X        return (-1);
  3281. X    }
  3282. X    val = htonl(val);
  3283. X    return (val);
  3284. X}
  3285. X#endif /* EXCELAN */
  3286. X
  3287. X#endif /* USE_NNTP */
  3288. END_OF_FILE
  3289. if test 9720 -ne `wc -c <'nntpinit.c'`; then
  3290.     echo shar: \"'nntpinit.c'\" unpacked with wrong size!
  3291. fi
  3292. # end of 'nntpinit.c'
  3293. fi
  3294. if test -f 'patchlevel.h' -a "${1}" != "-c" ; then 
  3295.   echo shar: Will not clobber existing file \"'patchlevel.h'\"
  3296. else
  3297. echo shar: Extracting \"'patchlevel.h'\" \(35 characters\)
  3298. sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE'
  3299. X#define PATCHLEVEL "Version: 3.1 "
  3300. END_OF_FILE
  3301. if test 35 -ne `wc -c <'patchlevel.h'`; then
  3302.     echo shar: \"'patchlevel.h'\" unpacked with wrong size!
  3303. fi
  3304. # end of 'patchlevel.h'
  3305. fi
  3306. if test -f 'thread.h' -a "${1}" != "-c" ; then 
  3307.   echo shar: Will not clobber existing file \"'thread.h'\"
  3308. else
  3309. echo shar: Extracting \"'thread.h'\" \(2045 characters\)
  3310. sed "s/^X//" >'thread.h' <<'END_OF_FILE'
  3311. X/* $Id: thread.h,v 3.0 1993/10/01 00:14:09 davison Trn $
  3312. X*/
  3313. X/* The authors make no claims as to the fitness or correctness of this software
  3314. X * for any use whatsoever, and it is provided as is. Any use of this software
  3315. X * is at the user's own risk. 
  3316. X */
  3317. X
  3318. X#define DB_VERSION    2
  3319. X
  3320. Xtypedef char        BYTE;
  3321. Xtypedef short        WORD;
  3322. X#ifndef __alpha
  3323. Xtypedef long        LONG;
  3324. X#else
  3325. Xtypedef int        LONG;
  3326. X#endif
  3327. X
  3328. X#define ROOT_ARTICLE    0x0001        /* article flag definitions */
  3329. X#define HAS_XREFS    0x0004        /* article has an xref line */
  3330. X
  3331. Xtypedef struct Article {
  3332. X    ART_NUM num;
  3333. X    char *id;
  3334. X    struct Domain *domain;
  3335. X    struct Subject *subject;
  3336. X    struct Author *author;
  3337. X    struct Article *parent, *children, *siblings;
  3338. X    struct Root *root;
  3339. X    struct Article *id_link;
  3340. X    time_t date;
  3341. X    WORD child_cnt;
  3342. X    WORD flags;
  3343. X    WORD seq;
  3344. X} ARTICLE;
  3345. X
  3346. Xtypedef struct Domain {
  3347. X    char *name;
  3348. X    ARTICLE *ids;
  3349. X    struct Domain *link;
  3350. X} DOMAIN;
  3351. X
  3352. Xtypedef struct Author {
  3353. X    struct Author *link;        /* this link MUST be first */
  3354. X    char *name;
  3355. X    WORD seq;
  3356. X    WORD count;
  3357. X} AUTHOR;
  3358. X
  3359. Xtypedef struct Subject {
  3360. X    struct Subject *link;        /* this link MUST be first */
  3361. X    char *str;
  3362. X    WORD seq;
  3363. X    WORD count;
  3364. X} SUBJECT;
  3365. X
  3366. Xtypedef struct Root {
  3367. X    struct Root *link;            /* this link MUST be first */
  3368. X    ARTICLE *articles;
  3369. X    SUBJECT *subjects;
  3370. X    ART_NUM root_num;
  3371. X    WORD thread_cnt;
  3372. X    WORD subject_cnt;
  3373. X    WORD seq;
  3374. X} ROOT;
  3375. X
  3376. Xtypedef struct {
  3377. X    LONG root_num;
  3378. X    WORD articles;
  3379. X    WORD thread_cnt;
  3380. X    WORD subject_cnt;
  3381. X    WORD pad_hack;
  3382. X} PACKED_ROOT;
  3383. X
  3384. Xtypedef struct {
  3385. X    LONG num;
  3386. X    LONG date;
  3387. X    WORD subject, author;
  3388. X    WORD flags;
  3389. X    WORD child_cnt;
  3390. X    WORD parent;
  3391. X    WORD padding;
  3392. X    WORD siblings;
  3393. X    WORD root;
  3394. X} PACKED_ARTICLE;
  3395. X
  3396. Xtypedef struct Total {
  3397. X    LONG first, last;
  3398. X    LONG string1;
  3399. X    LONG string2;
  3400. X    WORD root;
  3401. X    WORD article;
  3402. X    WORD subject;
  3403. X    WORD author;
  3404. X    WORD domain;
  3405. X    WORD pad_hack;
  3406. X} TOTAL;
  3407. X
  3408. Xtypedef struct {
  3409. X    BYTE l[sizeof (LONG)];
  3410. X    BYTE w[sizeof (WORD)];
  3411. X    BYTE version;
  3412. X    BYTE pad_hack;
  3413. X} BMAP;
  3414. END_OF_FILE
  3415. if test 2045 -ne `wc -c <'thread.h'`; then
  3416.     echo shar: \"'thread.h'\" unpacked with wrong size!
  3417. fi
  3418. # end of 'thread.h'
  3419. fi
  3420. if test -f 'unipatch.c' -a "${1}" != "-c" ; then 
  3421.   echo shar: Will not clobber existing file \"'unipatch.c'\"
  3422. else
  3423. echo shar: Extracting \"'unipatch.c'\" \(1507 characters\)
  3424. sed "s/^X//" >'unipatch.c' <<'END_OF_FILE'
  3425. X/*
  3426. XA filter to turn a unified diff into a degenerate context diff (no '!'s)
  3427. Xfor patch. Version 1.1. Author: davison@borland.com
  3428. X*/
  3429. X#include <stdio.h>
  3430. X#define ERR(a) {fputs(a,stderr);exit(1);}
  3431. X#define NUM(x) {for(x=0;*cp<='9'&&*cp>='0';)x=x*10+*cp++-'0';ch= *cp++;}
  3432. Xstruct Ln {struct Ln *lk; char t; char s[1];} r,*h,*ln;
  3433. Xchar bf[2048],*cp,ch,*malloc();
  3434. Xlong os,ol,ns,nl,ne,lncnt;
  3435. Xmain()
  3436. X{
  3437. X for(;;){
  3438. X  for(;;){
  3439. X   if(!fgets(bf,sizeof bf,stdin)) exit(0);
  3440. X   lncnt++;
  3441. X   if(!strncmp(bf,"@@ -",4)) break;
  3442. X   fputs(bf,stdout);
  3443. X  }
  3444. X  ol=nl=1, cp=bf+4;
  3445. X  NUM(os)
  3446. X  if(ch==',') NUM(ol)
  3447. X  if(*cp++!='+') goto bad;
  3448. X  NUM(ns)
  3449. X  if(ch==',') NUM(nl)
  3450. X  if(*cp!='@') goto bad;
  3451. X  r.lk=0, h= &r, ne=ns+nl-1;
  3452. X  printf("***************\n*** %ld,%ld ****\n",os,os+ol-(os>0));
  3453. X  while(ol||nl){
  3454. X   if(!fgets(bf,sizeof bf,stdin)){
  3455. X    if(nl>2) ERR("Unexpected end of file.\n")
  3456. X    strcpy(bf," \n");
  3457. X   }
  3458. X   lncnt++;
  3459. X   if(*bf=='\t'||*bf=='\n') ch=' ', cp=bf;
  3460. X   else ch= *bf, cp=bf+1;
  3461. X   switch(ch){
  3462. X   case'-':if(!ol--) goto bad;
  3463. X    printf("- %s",cp);
  3464. X    break;
  3465. X   case'=':ch=' ';
  3466. X   case' ':if(!ol--) goto bad;
  3467. X    printf("  %s",cp);
  3468. X   case'+':if(!nl--) goto bad;
  3469. X    ln = (struct Ln*)malloc(sizeof(*ln)+strlen(cp));
  3470. X    if(!ln) ERR("Out of memory!\n")
  3471. X    ln->lk=0, ln->t=ch, strcpy(ln->s,cp);
  3472. X    h->lk=ln, h=ln;
  3473. X    break;
  3474. X   default:
  3475. Xbad:    fprintf(stderr,"Malformed unified diff at line %ld: ",lncnt);
  3476. X    ERR(bf)
  3477. X   }
  3478. X  }
  3479. X  printf("--- %ld,%ld ----\n",ns,ne);
  3480. X  for(ln=r.lk;ln;ln=h){
  3481. X   printf("%c %s",ln->t,ln->s);
  3482. X   h=ln->lk; free(ln);
  3483. X  }
  3484. X }
  3485. X}
  3486. END_OF_FILE
  3487. if test 1507 -ne `wc -c <'unipatch.c'`; then
  3488.     echo shar: \"'unipatch.c'\" unpacked with wrong size!
  3489. fi
  3490. # end of 'unipatch.c'
  3491. fi
  3492. echo shar: End of archive 1 \(of 4\).
  3493. cp /dev/null ark1isdone
  3494. MISSING=""
  3495. for I in 1 2 3 4 ; do
  3496.     if test ! -f ark${I}isdone ; then
  3497.     MISSING="${MISSING} ${I}"
  3498.     fi
  3499. done
  3500. if test "${MISSING}" = "" ; then
  3501.     echo You have unpacked all 4 archives.
  3502.     rm -f ark[1-9]isdone
  3503. else
  3504.     echo You still need to unpack the following archives:
  3505.     echo "        " ${MISSING}
  3506. fi
  3507. ##  End of shell archive.
  3508. exit 0
  3509.