home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3957 < prev    next >
Encoding:
Internet Message Format  |  1991-09-04  |  49.1 KB

  1. Path: wupost!uunet!mcsun!unido!estevax!norisc!iain
  2. From: iain@norisc.UUCP (Iain Lea)
  3. Newsgroups: alt.sources
  4. Subject: tin v1.0 Patchlevel 1 Newsreader (part 01/08)
  5. Message-ID: <599@norisc.UUCP>
  6. Date: 3 Sep 91 10:56:29 GMT
  7. Sender: iain@norisc.UUCP (Iain Lea)
  8. Organization: What organization?
  9. Lines: 1717
  10.  
  11. Submitted-by: iain@estevax.uucp
  12. Archive-name: tin1.0/part01
  13.  
  14. #!/bin/sh
  15. # This is tin1.0, a shell archive (shar 3.24)
  16. # made 09/03/1991 08:02 UTC by iain@estevax.uucp
  17. # Source directory /piez/iain/.src/tin-1.01
  18. #
  19. # existing files WILL be overwritten
  20. #
  21. # This is part 1 of a multipart archive                                    
  22. # do not concatenate these parts, unpack them in order with /bin/sh        
  23. #
  24. # This shar contains:
  25. # length  mode       name
  26. # ------ ---------- ------------------------------------------
  27. #   6678 -rw------- CHANGES
  28. #   1090 -rw------- MANIFEST
  29. #  10717 -rw------- Makefile
  30. #   4492 -rw------- README
  31. #   1584 -rw------- TODO
  32. #    530 -rwx------ UPDATE_INDEX
  33. #   5457 -rw------- alloca.c
  34. #  23272 -rw------- art.c
  35. #   6065 -rw------- curses.c
  36. #   2276 -rw------- debug.c
  37. #   9921 -rw------- feed.c
  38. #  18741 -rw------- group.c
  39. #   2673 -rw------- hashstr.c
  40. #   4017 -rw------- help.c
  41. #   9118 -rw------- kill.c
  42. #  16989 -rw------- lang.c
  43. #   9222 -rw------- lang.h
  44. #   1121 -rw------- mail.c
  45. #   6370 -rw------- main.c
  46. #   5489 -rw------- memory.c
  47. #  14791 -rw------- misc.c
  48. #  17686 -rw------- newsrc.c
  49. #   3688 -rw------- nntp.h
  50. #   6732 -rw------- open.c
  51. #  23540 -rw------- page.c
  52. #     21 -rw------- patchlevel.h
  53. #  14484 -rw------- post.c
  54. #   3062 -rw------- prompt.c
  55. #  17093 -rw------- proto.h
  56. #  16801 -rw------- rcfile.c
  57. #  19762 -rw------- save.c
  58. #   2060 -rw------- screen.c
  59. #   7823 -rw------- search.c
  60. #  17955 -rw------- select.c
  61. #   7144 -rw------- signal.c
  62. #   1611 -rw------- time.c
  63. #   8685 -rw------- tin.h
  64. #   4749 -rw------- wildmat.c
  65. #  23350 -rw------- tin.1
  66. #
  67. if touch 2>&1 | fgrep '[-amc]' > /dev/null
  68.  then TOUCH=touch
  69.  else TOUCH=true
  70. fi
  71. if test -r shar3_seq_.tmp; then
  72.     echo "Must unpack archives in sequence!"
  73.     next=`cat shar3_seq_.tmp`; echo "Please unpack part $next next"
  74.     exit 1
  75. fi
  76. # ============= CHANGES ==============
  77. echo "x - extracting CHANGES (Text)"
  78. sed 's/^X//' << 'SHAR_EOF' > CHANGES &&
  79. XCHANGES tin v1.00 -> tin 1.0 PL1
  80. X--------------------------------
  81. X
  82. X1)  crs@siesoft.co.uk (Chris Smith)
  83. X    BUG. uudecoding multi-part archives sometimes does not work.
  84. X    FIX. Contibuted uuscram routine that was hacked into post_process_uud().
  85. X
  86. X2)  unido!mprgate.mpr.ca!lukas (Bob Lukas)
  87. X    BUG. The docs refer to various defaults as being $HOME/... In
  88. X         fact, they are relative to the pw_dir field from /etc/passwd,
  89. X         not the environment variable $HOME. (For obscure reasons, my
  90. X         $HOME is not pw_dir.)
  91. X    FIX. misc.c - init_selfinfo()
  92. X
  93. X3)  iain@estevax.uucp (Iain Lea)
  94. X    BUG. info string "Serching..." not cleared from bottom of screen
  95. X         when string is found.
  96. X    FIX. search.c - added clear_message() to various search routines.
  97. X
  98. X4)  unido!skuld.north.de!heimdall (Volker Beyer)
  99. X    BUG. Du versuchst den Vi aufzurufen, und zwar ind /usr/bin, bei
  100. X         Xenix steht er aber in /bin.Ausserdem sollte kein Editor
  101. X         definiert werden wenn die Shell-Variable EDITOR gesetzt ist
  102. X         (wird u.a. auch in vnews benutzt (der von bnews zumindestens)).
  103. X    FIX. tin.h - Added #ifdef M_XENIX #define DEFAULT_EDITOR /bin/vi #endif
  104. X
  105. X5)  rsalz@bbn.com (Rich Salz)
  106. X    Contributed newer version (June 91) of wildmat.c & wildmat.3 routines
  107. X
  108. X6)  v.hoang@att.com (Viet Hoang)
  109. X    BUG. <sys/types.h> defined in tin.h and open.c
  110. X    FIX. open.c - deleted <sys/types.h>
  111. X
  112. X7)  v.hoang@att.com (Viet Hoang)
  113. X    BUG. The entry for sysv in Makefile uses double backslash when it
  114. X         should only be single backslash.
  115. X    FIX. Makefile - changed \\ to \ in sysv entry.
  116. X
  117. X8)  kos@nd.se (Karl-Olov Serrander)
  118. X    BUG. If tin is suid news, it is not possible to create .tin and
  119. X         .tin/.tinrc when you use command M.
  120. X    FIX. rcfile.c - write_rcfile() now uses setuid() & setgid() routines.
  121. X
  122. X9)  iain@estevax.uucp (Iain Lea)
  123. X    BUG. If tin is suid news, it has problems creating files in users home
  124. X         dir.
  125. X    FIX. kill.c misc.c post.c - added setuid() & setgid() routines.
  126. X
  127. X10) unido!asd.tds.philips.se!kko (Karl-Koenig Koenigsson)
  128. X    BUG. If I do "tin -u" via cron, the job gets aborted due to the
  129. X         environment variable TERM not being defined.
  130. X    FIX. main.c - main() put do_update() before curses is initialized.
  131. X
  132. X11) iain@estevax.uucp (Iain Lea)
  133. X    BUG. Inverse video does not work correctly on sysV machines
  134. X    FIX. page.c group.c select.c screen.c - modified inverse routines.
  135. X
  136. X12) unido!gmdzi.gmd.de!brosig (Andreas Brosig)
  137. X    BUG. Ich hatte in TASS die Moeglichkeit mit !:kommando: shell-
  138. X         Kommandos abzugeben; gut, das geht mit TIN auch, aber nach
  139. X         der shell-Kommando Ausgabe wird direkt ein redraw des Screens
  140. X         gemacht, zu schnell fuer meine Augen. TASS wartete noch auf
  141. X         einen Tastendruck des Benutzers.
  142. X    FIX. misc.c - shell_escape() added continue_prompt() to wait for
  143. X         user input.
  144. X
  145. X13) cliff@norisc.uucp (Clifford Luke)
  146. X    BUG. When ^Z done in Options Menu 'M' incorrect screen is redrawn
  147. X         when process is restarted. Wrong signal handler set.
  148. X    FIX. signal.c rcfile.c - added signal handler for change_rcfile().
  149. X
  150. X14) cliff@norisc.uucp (Clifford Luke)
  151. X    BUG. When ^Z done under SysVR4 the screen goes into endless loop
  152. X         of redrawing itself. Many thanx for patches supplied.
  153. X    FIX. signal.c - added POSIX? signal handler code to all handlers.
  154. X
  155. X15) iain@estevax.uucp (Iain Lea)
  156. X    Added percentage info to bottom of group & select menus.
  157. X
  158. X16) rdb@oasis.icl.co.uk (Roger Binns)
  159. X    BUG. I would like it to do something about non-existent groups.
  160. X         It should delete them or something.
  161. X    FIX. newsrc.c - rewrite_newsrc() writes new newsrc with only
  162. X         newsgroups that are present in active file.
  163. X    
  164. X17) iain@estevax.uucp (Iain Lea)
  165. X    Rewrote mail,pipe,print & save commands to handle a)rticle, 
  166. X    t)thread r)egex pattern and T)agged articles.
  167. X
  168. X18) unido!tintin.rivm.nl!a3@estevax (Adri Verhoef)
  169. X    BUG. Failed posts don't get saved (to dead.article).
  170. X    FIX. post.c - changed post_base() & post_response()
  171. X
  172. X19) unido!tintin.rivm.nl!a3@estevax (Adri Verhoef)
  173. X    BUG. inews not found. (Mine is located in ~news/nntp)
  174. X         Thanx for the supplied patches.
  175. X    FIX. added INEWSDIR define. Set to inews dir otherwise
  176. X         defaults to LIBDIR.
  177. X
  178. X20) unido!tintin.rivm.nl!a3@estevax (Adri Verhoef)
  179. X    BUG. From the options menu it is not clear that you use a <CR> to
  180. X         leave the option that you are toggling.
  181. X    FIX. lang.c - rewrote text messages to mention <CR> being needed.
  182. X
  183. X21) unido!tintin.rivm.nl!a3@estevax (Adri Verhoef)
  184. X    BUG. Long newsgroup names cause troubles; when I jumped to the
  185. X         last newsgroup ($), the following appeared:
  186. X           191 alt.wpi.negativland.subgenii.for.rent
  187. X             2 general
  188. X           ^^
  189. X    FIX. select.c - changed max length of newsgroup name from 36 to 40.
  190. X
  191. X22) iain@estevax.uucp (Iain Lea)
  192. X    Finished man page.
  193. X
  194. X23) iain@estevax.uucp (Iain Lea)
  195. X    BUG. mail_setup () will not work if MAIL env varaible not set.
  196. X    FIX. mail.c - mail_setup() now checks mailbox path as well.
  197. X
  198. X24) crs@siesoft.co.uk (Chris Smith)
  199. X    BUG. help screens are hard coded for 25 line terminals so if 
  200. X         screen is bigger it cannot use the extra space.
  201. X    FIX. help.c - show_help_screen() rewrote to use maximum lines.
  202. X
  203. X25) bernd@norisc.uucp (Bernd Schwerin)
  204. X    BUG. Save operation doesnt ask for a base filename when saving
  205. X         tagged articles. After saving the tagged articles the
  206. X         pathnames are .01, .02 etc.
  207. X    FIX. feed.c - feed_articles () removed if () to allow tagged files
  208. X         sequence to ask for filename to save to.
  209. X
  210. XCHANGES tass v3.2 -> tin v1.00 
  211. X------------------------------
  212. X
  213. Xo  News can be read locally (ie. /usr/spool/news) or remotely by NNTP (-r option)
  214. Xo  User can config tin's options dynamically by 'M' command and have them
  215. X   saved to ~/.tin/tinrc.
  216. X
  217. Xo  Archive-name: mail header is used when saving and post processing 
  218. X   articles / threads.
  219. X
  220. Xo  Adjusts to size of screen for how much of Subject: & From: is displayed.
  221. X
  222. Xo  Post processes saved articles/threads. It will handle sh, uudecode,
  223. X   zoo, lharc, arc and zip (unzip) formats.
  224. X
  225. Xo  Articles can be sorted on Subject:, From:, Date: field or nothing. 
  226. X
  227. Xo  Killfile support (Not fully debugged). Kill articles at single group
  228. X   / all groups on Subject:,From: line or on user entered pattern.
  229. X
  230. Xo  Saves articles / threads to elm mailbox by pressing '=' when asked
  231. X   for name of saved file.
  232. X
  233. Xo  Displays history of user posted articles/replies & followups.
  234. X
  235. Xo  Higlighted bar / -> arrow can be used for selecting articles
  236. X
  237. Xo  Tagging of articles to save in a particular order
  238. X
  239. XAnd many other small changes.
  240. X
  241. SHAR_EOF
  242. $TOUCH -am 0903094991 CHANGES &&
  243. chmod 0600 CHANGES ||
  244. echo "restore of CHANGES failed"
  245. set `wc -c CHANGES`;Wc_c=$1
  246. if test "$Wc_c" != "6678"; then
  247.     echo original size 6678, current size $Wc_c
  248. fi
  249. # ============= MANIFEST ==============
  250. echo "x - extracting MANIFEST (Text)"
  251. sed 's/^X//' << 'SHAR_EOF' > MANIFEST &&
  252. XMANIFEST for tin v1.0 PL1
  253. X-------------------------
  254. XCHANGES            6678  
  255. XMANIFEST           1092  
  256. XMakefile          10717  
  257. XREADME             4492  
  258. XTODO               1584  
  259. XUPDATE_INDEX        530  
  260. Xalloca.c           5457  
  261. Xart.c             23272  
  262. Xcurses.c           6065  
  263. Xdebug.c            2276  
  264. Xfeed.c             9921  
  265. Xgroup.c           18741  
  266. Xhashstr.c          2673  
  267. Xhelp.c             4017  
  268. Xkill.c             9118  
  269. Xlang.c            16989  
  270. Xlang.h             9222  
  271. Xmail.c             1121  
  272. Xmain.c             6370  
  273. Xmemory.c           5489  
  274. Xmisc.c            14791  
  275. Xnewsrc.c          17686  
  276. Xnntp.h             3688  
  277. Xopen.c             6732  
  278. Xpage.c            23540  
  279. Xpatchlevel.h         21  
  280. Xpost.c            14484  
  281. Xprompt.c           3062  
  282. Xproto.h           17093  
  283. Xrcfile.c          16801  
  284. Xsave.c            19762  
  285. Xscreen.c           2060  
  286. Xsearch.c           7823  
  287. Xselect.c          17955  
  288. Xsignal.c           7144  
  289. Xtime.c             1611  
  290. Xtin.1             23350
  291. Xtin.h              8685  
  292. Xwildmat.3          2247  
  293. Xwildmat.c          4749  
  294. SHAR_EOF
  295. $TOUCH -am 0903100191 MANIFEST &&
  296. chmod 0600 MANIFEST ||
  297. echo "restore of MANIFEST failed"
  298. set `wc -c MANIFEST`;Wc_c=$1
  299. if test "$Wc_c" != "1090"; then
  300.     echo original size 1090, current size $Wc_c
  301. fi
  302. # ============= Makefile ==============
  303. echo "x - extracting Makefile (Text)"
  304. sed 's/^X//' << 'SHAR_EOF' > Makefile &&
  305. X# Makefile
  306. X
  307. X# name of executable file
  308. X#
  309. XEXE=tin
  310. X
  311. X# name of dir where base version is for use by diff program
  312. X#
  313. XBASE_DIR=../tin-1.01
  314. X# command line compile flags
  315. X#
  316. X#  -D LIBDIR=\"\"
  317. X#    defaults to /usr/lib/news if not defined.
  318. X#
  319. X#  -D INEWSDIR=\"\"
  320. X#    define if inews is not in LIBDIR. defaults to LIBDIR if not defined.
  321. X#
  322. X#  -D SPOOLDIR=\"\"
  323. X#    defaults to /usr/spool/news if not defined.
  324. X#
  325. X#  You only need to worry about the following three defines if you have
  326. X#  defined NNTP to build a version to access news locally & remotely
  327. X#
  328. X#  -D USE_NNTP
  329. X#    include -DUSE_NNTP if you want to allow reading of news locally 
  330. X#    and also remotely via the -r option over an NNTP server.
  331. X#
  332. X#  -D NNTPLIB=
  333. X#    point NNTPLIB at the nntp clientlib.o support library
  334. X#
  335. X#  -D NETLIBS=
  336. X#    NETLIBS should be the networking libraries you need to link with
  337. X#    the nntp clientlib.o
  338. X#
  339. X#  -D POSIX_JOB_CONTROL
  340. X#    define if your machine uses sigaction() POSIX signal handling.
  341. X#    This is defined as default for SysVR4 machines in this makefile.
  342. X#
  343. X#  -D USE_MKDIR
  344. X#    define if your machine does not have the mkdir() system call.
  345. X#
  346. X#  -D USE_LONG_FILENAMES
  347. X#    include -DUSE_LONG_FILENAMES if filesystem supports filenames
  348. X#    longer than 14 chars. (default for BSD type systems)
  349. X#
  350. X#  -D USE_INVERSE_HACK
  351. X#    define if you want inverse video and highlighted bar disabled.
  352. X#    (default for SCO Unix & SysVR4) Can be toggled in tin by the
  353. X#    'I' command & highlight bar by 'M' command.
  354. X#
  355. X#  -D USE_CLEARSCREEN
  356. X#    define if the you wish screen to use ClearScreen() and not MoveCursor()
  357. X#    and CleartoEOLN(). This is perhaps faster on slow terminals but I have
  358. X#    not really run any speed tests. Not sure this option works anymore.
  359. X#
  360. X#  -D DONT_USE_REGEX
  361. X#    don't match strings using regular expressions, just use strstr().
  362. X#
  363. X#  -D DONT_USE_START_LINE
  364. X#    stop editor being started with line offset into file
  365. X#
  366. X#  -D SLOW_SCREEN_UPDATE
  367. X#    useful if running over a low speed connection (ie. 2400baud).
  368. X#    1) stops percentage being shown at bottom of select and group menus.
  369. X#    2) stops group being written to screen as it is subscribed/unsubscribed.
  370. X#
  371. X
  372. XBINDIR = /piez/iain/bin
  373. XTROFF=drf
  374. XPRINT=-Pps0
  375. X
  376. XHFILES    =    tin.h lang.h nntp.h proto.h patchlevel.h
  377. X
  378. XCFILES    =    art.c curses.c debug.c feed.c group.c hashstr.c help.c kill.c \
  379. X        lang.c mail.c main.c memory.c misc.c newsrc.c open.c page.c post.c \
  380. X        prompt.c rcfile.c save.c screen.c search.c select.c signal.c time.c \
  381. X        wildmat.c
  382. X
  383. XOBJECTS    =    art.o curses.o debug.o feed.o group.o hashstr.o help.o kill.o \
  384. X        lang.o mail.o main.o memory.o misc.o newsrc.o open.o page.o post.o \
  385. X        prompt.o rcfile.o save.o screen.o search.o select.o signal.o time.o \
  386. X        wildmat.o
  387. X
  388. XLINTFLAGS=-a -c -h -n -x 
  389. X
  390. X.c.o:
  391. X    $(CC) $(CFLAGS) $*.c
  392. X
  393. Xall: 
  394. X    @echo "There is no default. Specify one of the following targets."
  395. X    @echo "    make bsd       (BSD/Ultrix)"
  396. X    @echo "    make sysv      (SysV)"
  397. X    @echo "    make sysvr4    (SysV R4)"
  398. X    @echo "    make sco       (SCO Unix)"
  399. X    @echo "    make xenix     (Xenix 386)"
  400. X    @echo "    make norisc    (Site specific)"
  401. X    @echo "    make estevax   (Site specific)"
  402. X    @echo "    make kommu     (Site specific)"
  403. X    @echo "    make sorix960  (Site specific)"
  404. X
  405. X# For Berkeley systems:
  406. Xbsd:
  407. X    @echo "Compiling for BSD/Ultrix..."
  408. X    @$(MAKE) CFLAGS='-c -O -DBSD -DLIBDIR=\"/usr/lib/news\" -DSPOOLDIR=\"/usr/spool/news\"' \
  409. X             LIBS="-lcurses -ltermcap" \
  410. X             STRIP=strip EXE=tin linkit
  411. X
  412. X# For System V:
  413. Xsysv:
  414. X    @echo "Compiling for System V..."
  415. X    @$(MAKE) CFLAGS='-c -O -DUSE_NNTP -DLIBDIR=\"/usr/lib/news\" -DSPOOLDIR=\"/usr/spool/news\"' \
  416. X             NNTPLIB="clientlib.o" \
  417. X             NETLIBS="-lnet -lnsl_s" \
  418. X             LIBS="-lcurses -ltermcap" \
  419. X             STRIP=strip EXE=tin linkit
  420. X
  421. X# For System V Release 4:
  422. Xsysvr4:
  423. X    @echo "Compiling for System V Release 4..."
  424. X    @$(MAKE) CFLAGS='-c -O -DUSE_NNTP -DPOSIX_JOB_CONTROL -DUSE_INVERSE_HACK -DLIBDIR=\"/usr/lib/news\" -DSPOOLDIR=\"/usr/spool/news\"' \
  425. X             NNTPLIB="./nntp/clientlib.o" \
  426. X             NETLIBS="-lnsl -lsocket" \
  427. X             LIBS="-lcurses -ltermcap -L/usr/ucblib -lucb" \
  428. X             STRIP=strip EXE=tin linkit
  429. X
  430. X# For SCO Unix:
  431. Xsco:
  432. X    @echo "Compiling for SCO Unix..."
  433. X    @$(MAKE) CFLAGS='-c -O -UM_XENIX -DUSE_INVERSE_HACK -DLIBDIR="\\"/usr/lib/news\\"" -DSPOOLDIR="\\"/usr/spool/news\\""' \
  434. X             LIBS="-lcurses -lgen -lc_s" \
  435. X             STRIP=strip EXE=tin linkit
  436. X
  437. X# For Xenix 386:
  438. X#             NNTPLIB=clientlib.o
  439. X#             NETLIBS="-lsocket"
  440. Xxenix:
  441. X    @echo "Compiling for Xenix 386..."
  442. X    @$(MAKE) CFLAGS='-c -Zi -DSYSV -DLIBDIR="\\"/usr/lib/news\\"" -DSPOOLDIR="\\"/usr/spool/news\\""' \
  443. X             LIBS="-lcurses -ltinfo -lx" \
  444. X             STRIP=echo EXE=tin linkit
  445. X
  446. X# SITE SPECIFIC - IGNORE
  447. Xnorisc:
  448. X    @echo "Compiling for NORISC with NNTP..."
  449. X    @$(MAKE) CFLAGS='-c -g -DBSD -DUSE_NNTP -DLIBDIR=\"/news/lib\" -DSPOOLDIR=\"/news/spool\"' \
  450. X             NNTPLIB=/news/nntp/clientlib.o \
  451. X             LIBS="-lcurses -ltermcap" \
  452. X             STRIP=echo EXE=tin linkit
  453. X
  454. X# SITE SPECIFIC - IGNORE
  455. Xestevax:
  456. X    @echo "Compiling for ESTEVAX with NNTP..."
  457. X    @$(MAKE) CFLAGS='-c -O -DBSD -DUSE_NNTP -DLIBDIR=\"/usr/lib/news\" -DSPOOLDIR=\"/usr/spool/news\"' \
  458. X             NNTPLIB=/others/mtz/bnews2/NNTP/common/clientlib.o \
  459. X             LIBS="-lcurses -ltermcap" \
  460. X             STRIP=strip EXE=tin linkit
  461. X
  462. X# SITE SPECIFIC - IGNORE
  463. Xkommu:
  464. X    @echo "Compiling for KOMMU with NNTP..."
  465. X    @$(MAKE) CFLAGS='-c -O -UM_XENIX -DUSE_INVERSE_HACK -DUSE_NNTP -DLIBDIR="\\"/usr/lib/news\\"" -DSPOOLDIR="\\"/usr/spool/news\\""' \
  466. X             NNTPLIB=/usr/spool/user/TONI/bnews2/NNTP/common/clientlib.o \
  467. X             NETLIBS="-lnsl_s -lsocket" \
  468. X             LIBS="-lcurses -lgen -lc_s" \
  469. X             STRIP=strip EXE=tin linkit
  470. X
  471. X# SITE SPECIFIC - IGNORE
  472. Xsorix960:
  473. X    @echo "Compiling for sorix960 with NNTP..."
  474. X    @$(MAKE) CC=ccp7 CFLAGS='-c -g -Dsorix960 -DSYSV -DUSE_NNTP -DLIBDIR="\"/usr/lib/news\"" -DSPOOLDIR="\"/usr/spool/news\""' \
  475. X             NNTPLIB=clientlib.o \
  476. X             NETLIBS="-lnsl_s -lsocket" \
  477. X             LIBS="-lcurses -lc_s" \
  478. X             STRIP=echo EXE=tin linkit
  479. X
  480. X
  481. Xlinkit: $(OBJECTS)
  482. X    @echo "Linking $(EXE)..."
  483. X#    $(CC) -o $(EXE) $(OBJECTS) alloca.o $(NNTPLIB) $(NETLIBS) $(LIBS) 
  484. X#    $(CC) -o -Zi $(EXE) $(OBJECTS) $(NNTPLIB) $(NETLIBS) $(LIBS) 
  485. X    $(CC) -o $(EXE) $(OBJECTS) $(NNTPLIB) $(NETLIBS) $(LIBS) 
  486. X    @$(STRIP) $(EXE)
  487. X    @ls -l $(EXE)
  488. X
  489. Xproto:
  490. X    @echo "generating function prototypes for proto.h..."
  491. X    @echo "#ifdef __STDC__" > PROTO.H
  492. X    @echo " " >> PROTO.H
  493. X    @cproto $(CFILES) >> PROTO.H
  494. X    @echo " " >> PROTO.H
  495. X    @echo "#else" >> PROTO.H
  496. X    @echo " " >> PROTO.H
  497. X    @cproto -f1 $(CFILES) >> PROTO.H
  498. X    @echo " " >> PROTO.H
  499. X    @echo "#endif" >> PROTO.H
  500. X    @-mv PROTO.H proto.h
  501. X
  502. Xinstall: all
  503. X    @echo "installing $(EXE)..."
  504. X    @-mv $(EXE) $(BINDIR)
  505. X    @chmod 755 $(BINDIR)/$(EXE)
  506. X
  507. Xshar:
  508. X    @echo "generating shell archive..."
  509. X    @shar -a -n $(EXE)1.0 -s iain@estevax.uucp -L50 -o ../$(EXE).shar [A-Z]* [A-Za-z0-9]*.[ch] $(EXE).1
  510. X
  511. Xdiff:
  512. X    @echo "generating diffs against $(BASE_DIR) (results in $(EXE).diff)..."
  513. X    @-mv -f $(EXE).diff $(EXE).diff-
  514. X    @diff $(BASE_DIR) . > $(EXE).diff
  515. X
  516. Xtar:
  517. X    @echo "archiving files to $(EXE).tar..."
  518. X    @-rm $(EXE).tar $(EXE).tar.Z > /dev/null 2>&1
  519. X    @tar cvf $(EXE).tar $(HFILES) $(CFILES) Makefile README TODO UPDATE_INDEX $(EXE).1 wildmat.3
  520. X    @echo "compressing $(EXE).tar..."
  521. X    @compress $(EXE).tar 
  522. X    @ls -l $(EXE).tar.Z
  523. X
  524. Xzoo:
  525. X    @echo "archiving files to $(EXE).zoo..."
  526. X    @-rm $(EXE).zoo > /dev/null 2>&1
  527. X    @zoo ah $(EXE).zoo $(HFILES) $(CFILES) Makefile README TODO UPDATE_INDEX $(EXE).1
  528. X    @ls -l $(EXE).zoo
  529. X
  530. Xtags:
  531. X    @echo "generating tags (results in ./tags)..."
  532. X    @-rm tags
  533. X    @ctags $(HFILES) $(CFILES) 
  534. X
  535. Xlint:
  536. X    @echo "linting source (results in ./LINT)..."
  537. X    @lint $(LINTFLAGS) $(CFILES) > LINT
  538. X
  539. Xclean:
  540. X    @echo "cleaning..."
  541. X    @-'rm' -rf *.o #* $(EXE).diff*
  542. X
  543. Xclobber:
  544. X    @echo "clobbering..."
  545. X    @-'rm' -rf *.o #* tags $(EXE) $(EXE).diff*
  546. X
  547. Xcflow:
  548. X    @echo "creating cflow for $(EXE)..."
  549. X    @cflow $(CFILES) > cflow.$(EXE) &
  550. X
  551. Xgrind:
  552. X    @echo "grinding tags index..."
  553. X    @ctags -v *.[ch] | sort -f > $(EXE).index
  554. X
  555. Xman:
  556. X    @echo "printing $(EXE) manual to $(PRINT)..."
  557. X    @+ $(TROFF) -F Helvetica -man3 $(PRINT) $(EXE).1
  558. X
  559. Xprint:
  560. X    @echo "printing to $(PRINT)..."
  561. X    @expand -4 tin.h     | enscript -2r -h -G $(PRINT) -b tin.h
  562. X    @expand -4 lang.h    | enscript -2r -h -G $(PRINT) -b lang.h
  563. X    @expand -4 proto.h   | enscript -2r -h -G $(PRINT) -b proto.h
  564. X    @expand -4 art.c     | enscript -2r -h -G $(PRINT) -b art.c
  565. X    @expand -4 curses.c  | enscript -2r -h -G $(PRINT) -b curses.c
  566. X    @expand -4 debug.c   | enscript -2r -h -G $(PRINT) -b debug.c
  567. X    @expand -4 group.c   | enscript -2r -h -G $(PRINT) -b group.c
  568. X    @expand -4 hashstr.c | enscript -2r -h -G $(PRINT) -b hashstr.c
  569. X    @expand -4 help.c    | enscript -2r -h -G $(PRINT) -b help.c
  570. X    @expand -4 kill.c    | enscript -2r -h -G $(PRINT) -b kill.c
  571. X    @expand -4 lang.c    | enscript -2r -h -G $(PRINT) -b lang.c
  572. X    @expand -4 mail.c    | enscript -2r -h -G $(PRINT) -b mail.c
  573. X    @expand -4 main.c    | enscript -2r -h -G $(PRINT) -b main.c 
  574. X    @expand -4 memory.c  | enscript -2r -h -G $(PRINT) -b memory.c
  575. X    @expand -4 misc.c    | enscript -2r -h -G $(PRINT) -b misc.c
  576. X    @expand -4 newsrc.c  | enscript -2r -h -G $(PRINT) -b newsrc.c
  577. X    @expand -4 nntp.h    | enscript -2r -h -G $(PRINT) -b nntp.h
  578. X    @expand -4 open.c    | enscript -2r -h -G $(PRINT) -b open.c
  579. X    @expand -4 page.c    | enscript -2r -h -G $(PRINT) -b page.c
  580. X    @expand -4 post.c    | enscript -2r -h -G $(PRINT) -b post.c
  581. X    @expand -4 prompt.c  | enscript -2r -h -G $(PRINT) -b prompt.c
  582. X    @expand -4 rcfile.c  | enscript -2r -h -G $(PRINT) -b rcfile.c
  583. X    @expand -4 save.c    | enscript -2r -h -G $(PRINT) -b save.c
  584. X    @expand -4 screen.c  | enscript -2r -h -G $(PRINT) -b screen.c
  585. X    @expand -4 search.c  | enscript -2r -h -G $(PRINT) -b search.c
  586. X    @expand -4 select.c  | enscript -2r -h -G $(PRINT) -b select.c
  587. X    @expand -4 signal.c  | enscript -2r -h -G $(PRINT) -b signal.c
  588. X    @expand -4 time.c    | enscript -2r -h -G $(PRINT) -b time.c
  589. X
  590. Xdist:
  591. X    @echo "copying to estevax..."
  592. X    @rcp $(CFILES) $(HFILES) Makefile estevax:.src/tin &
  593. X    @echo "copying to kommu..."
  594. X    @rcp $(CFILES) $(HFILES) Makefile kommu:.src/tin &
  595. X    @echo "copying to beperl..."
  596. X    @rcp $(CFILES) $(HFILES) Makefile beperl:tass &
  597. X    @echo "copying to tric..."
  598. X    @rcp $(CFILES) $(HFILES) Makefile beperl:/usr/tmp &
  599. X
  600. Xart.o:        art.c $(HFILES)
  601. Xcurses.o:    curses.c
  602. Xdebug.o:    debug.c $(HFILES)
  603. Xfeed.o:        feed.c $(HFILES)
  604. Xgroup.o:    group.c $(HFILES)
  605. Xhashstr.o:    hashstr.c $(HFILES)
  606. Xhelp.o:        help.c $(HFILES)
  607. Xkill.o:        kill.c $(HFILES)
  608. Xlang.o:        lang.c $(HFILES)
  609. Xmail.o:        mail.c
  610. Xmain.o:        main.c $(HFILES)
  611. Xmemory.o:    memory.c $(HFILES)
  612. Xmisc.o:        misc.c $(HFILES)
  613. Xnewsrc.o:    newsrc.c $(HFILES)
  614. Xopen.o:        open.c $(HFILES)
  615. Xpage.o:        page.c $(HFILES)
  616. Xpost.o:        post.c $(HFILES)
  617. Xprompt.o:    prompt.c $(HFILES)
  618. Xrcfile.o:    rcfile.c $(HFILES)
  619. Xsave.o:        save.c $(HFILES)
  620. Xscreen.o:    screen.c $(HFILES)
  621. Xsearch.o:    search.c $(HFILES)
  622. Xselect.o:    select.c $(HFILES)
  623. Xsignal.o:    signal.c $(HFILES)
  624. Xtime.o:        time.c
  625. Xwildmat.o:    wildmat.c $(HFILES)
  626. SHAR_EOF
  627. $TOUCH -am 0903100191 Makefile &&
  628. chmod 0600 Makefile ||
  629. echo "restore of Makefile failed"
  630. set `wc -c Makefile`;Wc_c=$1
  631. if test "$Wc_c" != "10717"; then
  632.     echo original size 10717, current size $Wc_c
  633. fi
  634. # ============= README ==============
  635. echo "x - extracting README (Text)"
  636. sed 's/^X//' << 'SHAR_EOF' > README &&
  637. XThis is an updated repost of the tin visual threaded NNTP newsreader v1.00.
  638. XThe new version is v1.0 PL1 (pathlevel 1). I am reposting instead of posting
  639. Xa patch file because the size difference was so small and I have recieved mail
  640. Xthat a few sites did not get all the original parts.
  641. X
  642. XIn the orignal posting I said it was a late beta release which shows how
  643. Xlittle I knew about how good the net is at finding bugs and giving suggestions.
  644. XI hope this version is a late beta release (Optimistic ?).
  645. X
  646. XI am still looking for people to test this and send me ideas/comments & bugs so
  647. Xthat I can correct any and then send it off to comp.sources.misc at the end of
  648. XSep/Oct 91.
  649. X
  650. XFrom this release onwards I will issue patches for use by the patch program.
  651. X
  652. XFor bugs, fixes, changes & additions read the CHANGES & TODO files.
  653. X
  654. XAnd now for a bit of blurb from the original version...
  655. X
  656. XTin is a full screen threaded newsreader that uses the tass newsreader as 
  657. Xits base. Tass was developed by Rich Skrenta (skrenta@blekko.commodore.com).
  658. XTin can read news locally and also via an NNTP server (-r option). Tin 
  659. Xcontains more features than tass but they are still accessable to the
  660. Xbeginner and expert alike. I tried to follow the tass UI conventions as 
  661. Xmuch as possible.
  662. X
  663. XThis is the only newsreader that I know of that threads on the Archive-name:
  664. Xfield as used in comp.sources.* groups as well as on the more normal Subject:
  665. Xfield. Before anyone comments on Subject: threading not being right and I 
  666. Xshould look at trn, I have and its threads are neat but I get more done with
  667. Xtin than trn. It is especially good at saving and processing saved articles
  668. X& threads.
  669. X
  670. Xo Organizes articles by threads.  Displays a really nice article selection
  671. X  page.
  672. X
  673. Xo Group selection page makes it easy to scan newsgroups, subscribe,
  674. X  unsubscribe, reorder your .newsrc.
  675. X
  676. Xo If you've ever used tass/notes, this is the program for you.
  677. X  Tin looks a lot like tass, but has many improvements.
  678. X
  679. XNewsreading style under tin tends to be different than with rn.  Instead of
  680. Xplowing through each group reading everything unread, you may find yourself
  681. Xreading fewer articles in more groups.  It's easier to skip about and only
  682. Xread interesting threads with tin.
  683. X
  684. XTin keeps an index file for each group.  The first time you enter a group,
  685. Xit will be a bit slow creating this file.  After that it will incrementally
  686. Xupdate the index file and there should be little delay.
  687. X
  688. XYou can run tin in "update mode" out of cron to update the indexes.
  689. X
  690. XI may be off the net for a couple of months at the end of September, but
  691. Xwill be contactable at the following address:
  692. X    Iain J. Lea
  693. X    BrueckenStr. 12
  694. X    8500 Nuernberg 90
  695. X    Germany.
  696. X    Phone. +49-911-331963   (home)
  697. X    Phone. +49-911-895-3853 (work until Sep 30)
  698. X    Phone. +49-911-3089-407 (work from Oct 1)
  699. X    Email. iain@estevax.uucp
  700. X
  701. XBuilt & used on the following machines
  702. X--------------------------------------
  703. X    1) Vax 8850 & Ultrix 4.1 (Developed & most tested platform)
  704. X    2) Vax 11/785 & BSD 4.3
  705. X    3) 386 PC & Xenix 386
  706. X    4) 386 PC & ATT SysVR4.0 (strange behaviour with inverse video)
  707. X    5) 386 PC & SCO SysVR3.2 (strange behaviour with inverse video)
  708. X    6) 386 PC & ISC SysVR3.2 with WINTCP (shakey ??)
  709. X    7) ICL DRS6000 (sparc) & SysVR4.0 
  710. X    7) Sparcstation & SunOS 4.1 
  711. X
  712. XBuilding Tin
  713. X------------
  714. X    1)  type make and a few system types will be displayed
  715. X    2)  edit Makefile if you want to add/change -D DEFINES
  716. X    3)  type 'make <system type>' for your system
  717. X    4)  NOTE. the mmakefile needs rewriting (Any takers?) 
  718. X
  719. X    Note: the supplied Makefile will not run directly on BSD. It 
  720. X    requires a little work (Any takers to write a good Makefile?)
  721. X
  722. XInstalling Tin
  723. X--------------
  724. X    1)  make install
  725. X
  726. XCredits
  727. X-------
  728. XI wish to give credit to the following people for the routines
  729. Xthat they have written and I have used in tin:
  730. X
  731. XRich Skrenta  - tass v3.2 that tin is based upon.
  732. XSyd Weinstein - curses.c is taken from the elm mailreader
  733. XRich Salz     - wildmat regex pattern matching routine
  734. XChris Smith   - multi-part uudecode routine 
  735. X
  736. XI wish to thank the following people for comments & bug reports:
  737. X
  738. XKlaus Arzig, Reiner Balling, Volker Beyer, Roger Binns, Georg Biehler,
  739. XAndreas Brosig, Peter Dressler, Gerhard Ermer, Joachim Feld,
  740. XBernhard Gmelch, Viet Hoang, Joe Johnson, Cyrill Jung,
  741. XKarl-Koenig Koenigsson, Bob Lukas, Clifford Luke, Toni Metz, 
  742. XKlaus Neuberger, Otto Niesser, Wolf Paul, Rich Salz, Fredy Schwatz,
  743. XBernd Schwerin, Karl-Olav Serrander, Chris Smith, Adri Verhoef
  744. SHAR_EOF
  745. $TOUCH -am 0903094991 README &&
  746. chmod 0600 README ||
  747. echo "restore of README failed"
  748. set `wc -c README`;Wc_c=$1
  749. if test "$Wc_c" != "4492"; then
  750.     echo original size 4492, current size $Wc_c
  751. fi
  752. # ============= TODO ==============
  753. echo "x - extracting TODO (Text)"
  754. sed 's/^X//' << 'SHAR_EOF' > TODO &&
  755. XFIX FEATURES
  756. X------------
  757. Xo  Fix SIGWINCH resize screen when ruuning on xterm. Its OK the
  758. X   first time but locks up the 2nd try. Perhaps same problem as
  759. X   ^Z suspend problem had on Sys5R4 so use sigaction() calls.
  760. X
  761. Xo  Fix uuscram code in uudecode.
  762. X
  763. Xo  Fix Makefile file to work on BSD & rewrite README.
  764. X
  765. Xo  Fix code to sort arts. At page level funny things happen.
  766. X
  767. Xo  Fix code to KILL articles. At page level funny things happen.
  768. X
  769. Xo  Fix code to KILL articles with 't' command.
  770. X
  771. Xo  Fix 'z' so that it stays unread even if a KILL is performed before
  772. X   leaving the group.
  773. X
  774. Xo  Fix -u -v -c that get malloc error sometimes on SysV+WINTCP machines
  775. X
  776. XADD FEATURES
  777. X------------
  778. Xo  Add 'C' command at group & page level to catchup present group and
  779. X   enter next group with unread news in it.
  780. X
  781. Xo  Sort .newsrc according to preference. (sort active file as it is read)
  782. X
  783. Xo  Add 'H' context senstive level help screens
  784. X
  785. Xo  Add code to do unpack patches
  786. X
  787. Xo  Add '+' for saving in MH mail format
  788. X
  789. Xo  Add time period kill article
  790. X
  791. Xo  Add -s <dir> option to save new news to specifed spool dir for when
  792. X   one goes on holiday so that it can be read later by giving -S <dir>.
  793. X
  794. Xo  Add code to allow user to specify routine for post processing
  795. X   articles
  796. X
  797. XPIPEDREAMS
  798. X----------
  799. Xo  Add rebindable keymaps and provide different terminal keymaps
  800. X   (ie. keymap.ansi, keymap.wy50 etc.)
  801. X
  802. Xo  Add support for german text messages.
  803. X
  804. Xo  Add Virtual newsgroups (combination of newsgroups ie. virtual.ibm
  805. X   consists of comp.sys.ibm.* groups).
  806. X
  807. Xo  Add threading on References like trn with mthreads database.
  808. SHAR_EOF
  809. $TOUCH -am 0903094991 TODO &&
  810. chmod 0600 TODO ||
  811. echo "restore of TODO failed"
  812. set `wc -c TODO`;Wc_c=$1
  813. if test "$Wc_c" != "1584"; then
  814.     echo original size 1584, current size $Wc_c
  815. fi
  816. # ============= UPDATE_INDEX ==============
  817. echo "x - extracting UPDATE_INDEX (Text)"
  818. sed 's/^X//' << 'SHAR_EOF' > UPDATE_INDEX &&
  819. X#! /bin/csh -f
  820. X#  Iain Lea, 21-08-91
  821. X#  Script to update tin indexes from the at queue 
  822. X
  823. X# required for at
  824. Xsetenv HOME  /piez/iain
  825. Xsetenv NAME  'Iain J. Lea'
  826. Xsetenv GROUP 'piez'
  827. Xsetenv PATH  :/usr/ucb:/bin:/usr/bin:/usr/local
  828. X
  829. X# specific for this script
  830. Xsetenv SCRIPT /piez/iain/bin/UPDATE_INDEX
  831. Xsetenv TIME 0700
  832. Xsetenv TINDIR /piez/iain/bin
  833. X
  834. X# hangs update indexes onto system batch queue
  835. X$TINDIR/tin -u > $HOME/UPDATE_LOG
  836. X
  837. X# sleeps and then submits this script again for tommorow
  838. X/usr/bin/sleep 1200
  839. X/usr/local/at $TIME $SCRIPT
  840. SHAR_EOF
  841. $TOUCH -am 0903094991 UPDATE_INDEX &&
  842. chmod 0700 UPDATE_INDEX ||
  843. echo "restore of UPDATE_INDEX failed"
  844. set `wc -c UPDATE_INDEX`;Wc_c=$1
  845. if test "$Wc_c" != "530"; then
  846.     echo original size 530, current size $Wc_c
  847. fi
  848. # ============= alloca.c ==============
  849. echo "x - extracting alloca.c (Text)"
  850. sed 's/^X//' << 'SHAR_EOF' > alloca.c &&
  851. X/*
  852. X    alloca -- (mostly) portable public-domain implementation -- D A Gwyn
  853. X
  854. X    last edit:    86/05/30    rms
  855. X       include config.h, since on VMS it renames some symbols.
  856. X       Use xmalloc instead of malloc.
  857. X
  858. X    This implementation of the PWB library alloca() function,
  859. X    which is used to allocate space off the run-time stack so
  860. X    that it is automatically reclaimed upon procedure exit, 
  861. X    was inspired by discussions with J. Q. Johnson of Cornell.
  862. X
  863. X    It should work under any C implementation that uses an
  864. X    actual procedure stack (as opposed to a linked list of
  865. X    frames).  There are some preprocessor constants that can
  866. X    be defined when compiling for your specific system, for
  867. X    improved efficiency; however, the defaults should be okay.
  868. X
  869. X    The general concept of this implementation is to keep
  870. X    track of all alloca()-allocated blocks, and reclaim any
  871. X    that are found to be deeper in the stack than the current
  872. X    invocation.  This heuristic does not reclaim storage as
  873. X    soon as it becomes invalid, but it will do so eventually.
  874. X
  875. X    As a special case, alloca(0) reclaims storage without
  876. X    allocating any.  It is a good idea to use alloca(0) in
  877. X    your main control loop, etc. to force garbage collection.
  878. X*/
  879. X
  880. X#ifndef lint
  881. Xstatic char    SCCSid[] = "@(#)alloca.c    1.1";    /* for the "what" utility */
  882. X#endif
  883. X
  884. X#ifdef emacs
  885. X#include "config.h"
  886. X#ifdef static
  887. X/* actually, only want this if static is defined as ""
  888. X   -- this is for usg, in which emacs must undefine static
  889. X   in order to make unexec workable
  890. X   */
  891. X#ifndef STACK_DIRECTION
  892. Xyou
  893. Xlose
  894. X-- must know STACK_DIRECTION at compile-time
  895. X#endif /* STACK_DIRECTION undefined */
  896. X#endif /* static */
  897. X#endif /* emacs */
  898. X
  899. X#ifdef X3J11
  900. Xtypedef void    *pointer;        /* generic pointer type */
  901. X#else
  902. Xtypedef char    *pointer;        /* generic pointer type */
  903. X#endif
  904. X
  905. X#define    NULL    0            /* null pointer constant */
  906. X
  907. Xextern void    free();
  908. Xextern pointer    xmalloc();
  909. X
  910. X/*
  911. X    Define STACK_DIRECTION if you know the direction of stack
  912. X    growth for your system; otherwise it will be automatically
  913. X    deduced at run-time.
  914. X
  915. X    STACK_DIRECTION > 0 => grows toward higher addresses
  916. X    STACK_DIRECTION < 0 => grows toward lower addresses
  917. X    STACK_DIRECTION = 0 => direction of growth unknown
  918. X*/
  919. X
  920. X#ifndef STACK_DIRECTION
  921. X#define    STACK_DIRECTION    0        /* direction unknown */
  922. X#endif
  923. X
  924. X#if STACK_DIRECTION != 0
  925. X
  926. X#define    STACK_DIR    STACK_DIRECTION    /* known at compile-time */
  927. X
  928. X#else    /* STACK_DIRECTION == 0; need run-time code */
  929. X
  930. Xstatic int    stack_dir;        /* 1 or -1 once known */
  931. X#define    STACK_DIR    stack_dir
  932. X
  933. Xstatic void
  934. Xfind_stack_direction (/* void */)
  935. X{
  936. X  static char    *addr = NULL;    /* address of first
  937. X                   `dummy', once known */
  938. X  auto char    dummy;        /* to get stack address */
  939. X
  940. X  if (addr == NULL)
  941. X    {                /* initial entry */
  942. X      addr = &dummy;
  943. X
  944. X      find_stack_direction ();    /* recurse once */
  945. X    }
  946. X  else                /* second entry */
  947. X    if (&dummy > addr)
  948. X      stack_dir = 1;        /* stack grew upward */
  949. X    else
  950. X      stack_dir = -1;        /* stack grew downward */
  951. X}
  952. X
  953. X#endif    /* STACK_DIRECTION == 0 */
  954. X
  955. X/*
  956. X    An "alloca header" is used to:
  957. X    (a) chain together all alloca()ed blocks;
  958. X    (b) keep track of stack depth.
  959. X
  960. X    It is very important that sizeof(header) agree with malloc()
  961. X    alignment chunk size.  The following default should work okay.
  962. X*/
  963. X
  964. X#ifndef    ALIGN_SIZE
  965. X#define    ALIGN_SIZE    sizeof(double)
  966. X#endif
  967. X
  968. Xtypedef union hdr
  969. X{
  970. X  char    align[ALIGN_SIZE];    /* to force sizeof(header) */
  971. X  struct
  972. X    {
  973. X      union hdr *next;        /* for chaining headers */
  974. X      char *deep;        /* for stack depth measure */
  975. X    } h;
  976. X} header;
  977. X
  978. X/*
  979. X    alloca( size ) returns a pointer to at least `size' bytes of
  980. X    storage which will be automatically reclaimed upon exit from
  981. X    the procedure that called alloca().  Originally, this space
  982. X    was supposed to be taken from the current stack frame of the
  983. X    caller, but that method cannot be made to work for some
  984. X    implementations of C, for example under Gould's UTX/32.
  985. X*/
  986. X
  987. Xstatic header *last_alloca_header = NULL; /* -> last alloca header */
  988. X
  989. Xpointer
  990. Xalloca (size)            /* returns pointer to storage */
  991. X     unsigned    size;        /* # bytes to allocate */
  992. X{
  993. X  auto char    probe;        /* probes stack depth: */
  994. X  register char    *depth = &probe;
  995. X
  996. X#if STACK_DIRECTION == 0
  997. X  if (STACK_DIR == 0)        /* unknown growth direction */
  998. X    find_stack_direction ();
  999. X#endif
  1000. X
  1001. X                /* Reclaim garbage, defined as all alloca()ed storage that
  1002. X                   was allocated from deeper in the stack than currently. */
  1003. X
  1004. X  {
  1005. X    register header    *hp;    /* traverses linked list */
  1006. X
  1007. X    for (hp = last_alloca_header; hp != NULL;)
  1008. X      if (STACK_DIR > 0 && hp->h.deep > depth
  1009. X      || STACK_DIR < 0 && hp->h.deep < depth)
  1010. X    {
  1011. X      register header    *np = hp->h.next;
  1012. X
  1013. X      free ((pointer) hp);    /* collect garbage */
  1014. X
  1015. X      hp = np;        /* -> next header */
  1016. X    }
  1017. X      else
  1018. X    break;            /* rest are not deeper */
  1019. X
  1020. X    last_alloca_header = hp;    /* -> last valid storage */
  1021. X  }
  1022. X
  1023. X  if (size == 0)
  1024. X    return NULL;        /* no allocation required */
  1025. X
  1026. X  /* Allocate combined header + user data storage. */
  1027. X
  1028. X  {
  1029. X    register pointer    new = xmalloc (sizeof (header) + size);
  1030. X    /* address of header */
  1031. X
  1032. X    ((header *)new)->h.next = last_alloca_header;
  1033. X    ((header *)new)->h.deep = depth;
  1034. X
  1035. X    last_alloca_header = (header *)new;
  1036. X
  1037. X    /* User storage begins just after header. */
  1038. X
  1039. X    return (pointer)((char *)new + sizeof(header));
  1040. X  }
  1041. X}
  1042. X
  1043. Xpointer xmalloc(n)
  1044. Xunsigned int n;
  1045. X{
  1046. X  extern pointer malloc();
  1047. X  pointer cp;
  1048. X  static char mesg[] = "xmalloc: no memory!\n";
  1049. X
  1050. X  cp = malloc(n);
  1051. X  if (! cp) {
  1052. X    write (2, mesg, sizeof(mesg) - 1);
  1053. X    exit(1);
  1054. X  }
  1055. X  return cp;
  1056. X}
  1057. SHAR_EOF
  1058. $TOUCH -am 0903095091 alloca.c &&
  1059. chmod 0600 alloca.c ||
  1060. echo "restore of alloca.c failed"
  1061. set `wc -c alloca.c`;Wc_c=$1
  1062. if test "$Wc_c" != "5457"; then
  1063.     echo original size 5457, current size $Wc_c
  1064. fi
  1065. # ============= art.c ==============
  1066. echo "x - extracting art.c (Text)"
  1067. sed 's/^X//' << 'SHAR_EOF' > art.c &&
  1068. X/*
  1069. X *  Project   : tin - a visual threaded usenet newsreader
  1070. X *  Module    : art.c
  1071. X *  Author    : R.Skrenta / I.Lea
  1072. X *  Created   : 01-04-91
  1073. X *  Updated   : 28-08-91
  1074. X *  Release   : 1.0
  1075. X *  Notes     :
  1076. X *  Copyright : (c) Copyright 1991 by Rich Skrenta & Iain Lea
  1077. X *                You may  freely  copy or  redistribute  this software,
  1078. X *              so  long as there is no profit made from its use, sale
  1079. X *              trade or  reproduction.  You may not change this copy-
  1080. X *              right notice, and it must be included in any copy made
  1081. X */
  1082. X
  1083. X#include    "tin.h"
  1084. X
  1085. X#define HEADER_LEN    1024
  1086. X
  1087. Xextern int errno;
  1088. X
  1089. Xchar index_file[LEN+1];
  1090. Xchar *glob_art_group;
  1091. Xint index_file_killed = FALSE;
  1092. Xlong last_read_article;
  1093. X
  1094. X
  1095. X/*
  1096. X *  Convert a string to a long, only look at first n characters
  1097. X */
  1098. X
  1099. Xlong my_atol (s, n)
  1100. X    char *s;
  1101. X    int n;
  1102. X{
  1103. X    long ret = 0;
  1104. X
  1105. X    while (*s && n--) {
  1106. X        if (*s >= '0' && *s <= '9')
  1107. X            ret = ret * 10 + (*s - '0');
  1108. X        else
  1109. X            return -1;
  1110. X        s++;
  1111. X    }
  1112. X
  1113. X    return ret;
  1114. X}
  1115. X
  1116. X
  1117. X/*
  1118. X *  Construct the pointers to the basenotes of each thread
  1119. X *  arts[] contains every article in the group.  inthread is
  1120. X *  set on each article that is after the first article in the
  1121. X *  thread.  Articles which have been expired have their thread
  1122. X *  set to -2 (ART_EXPIRED).
  1123. X */
  1124. X
  1125. Xvoid find_base ()
  1126. X{
  1127. X    int i;
  1128. X
  1129. X    top_base = 0;
  1130. X
  1131. X    for (i = 0; i < top; i++)
  1132. X        if (! arts[i].inthread && arts[i].thread != ART_EXPIRED) {
  1133. X            if (top_base >= max_art)
  1134. X                expand_art ();
  1135. X            base[top_base++] = i;
  1136. X        }
  1137. X}
  1138. X
  1139. X/* 
  1140. X *  Count the number of non-expired and non-killed articles in arts[]
  1141. X */
  1142. X
  1143. Xint num_of_arts ()
  1144. X{
  1145. X    int sum = 0;
  1146. X    register int i;
  1147. X
  1148. X    for (i = 0; i < top; i++) {
  1149. X        if (arts[i].thread != ART_EXPIRED && ! arts[i].tagged) {
  1150. X            sum++;
  1151. X        }
  1152. X    }
  1153. X
  1154. X    return sum;
  1155. X}
  1156. X
  1157. X/*
  1158. X *  Do we have an entry for article art?
  1159. X */
  1160. X
  1161. Xint valid_artnum (art)
  1162. X    long art;
  1163. X{
  1164. X    register int i;
  1165. X
  1166. X    for (i = 0; i < top; i++)
  1167. X        if (arts[i].artnum == art)
  1168. X            return i;
  1169. X
  1170. X    return -1;
  1171. X}
  1172. X
  1173. X
  1174. X/*
  1175. X *  Return TRUE if arts[] contains any expired articles
  1176. X *  (articles we have an entry for which don't have a corresponding
  1177. X *   article file in the spool directory)
  1178. X */
  1179. X
  1180. Xint purge_needed ()
  1181. X{
  1182. X    register int i;
  1183. X
  1184. X    for (i = 0; i < top; i++)
  1185. X        if (arts[i].thread == ART_EXPIRED)
  1186. X            return TRUE;
  1187. X
  1188. X    return FALSE;
  1189. X}
  1190. X
  1191. X
  1192. X/*
  1193. X *  Main group indexing routine.  Group should be the name of the
  1194. X *  newsgroup, i.e. "comp.unix.amiga".  group_path should be the
  1195. X *  same but with the .'s turned into /'s: "comp/unix/amiga"
  1196. X *
  1197. X *  Will read any existing index, create or incrementally update
  1198. X *  the index by looking at the articles in the spool directory,
  1199. X *  and attempt to write a new index if necessary.
  1200. X */
  1201. X
  1202. Xvoid index_group (group, group_path)
  1203. X    char *group;
  1204. X    char *group_path;
  1205. X{
  1206. X    int killed = FALSE;
  1207. X    int modified = FALSE;
  1208. X    glob_art_group = group;
  1209. X
  1210. X#ifdef SIGTSTP
  1211. X    if (do_sigtstp) {
  1212. X#ifdef POSIX_JOB_CONTROL
  1213. X        sigemptyset (&art_act.sa_mask);
  1214. X        art_act.sa_flags = SA_RESTART | SA_RESETHAND;
  1215. X        art_act.sa_handler = art_suspend;
  1216. X        sigaction (SIGTSTP, &art_act, 0L);
  1217. X#else
  1218. X        signal (SIGTSTP, art_suspend);
  1219. X#endif
  1220. X    }
  1221. X#endif
  1222. X
  1223. X#ifdef SIGWINCH
  1224. X    signal (SIGWINCH, art_resize);
  1225. X#endif
  1226. X
  1227. X    if (! update) {
  1228. X        sprintf (msg, txt_group, group);
  1229. X        wait_message (msg);
  1230. X    }
  1231. X
  1232. X    hash_reclaim ();
  1233. X    free_art_array ();
  1234. X
  1235. X    if (local_index)
  1236. X        find_local_index (group);
  1237. X    else
  1238. X        sprintf (index_file, "%s/%s/%s", spooldir, group_path, INDEXDIR);
  1239. X
  1240. X    /*
  1241. X     *  load articles from index file if it exists
  1242. X     */
  1243. X    load_index ();
  1244. X
  1245. X    /*
  1246. X     *  load killed articles into arts[] because kill arts is OFF
  1247. X     */
  1248. X    if (! kill_articles && index_file_killed) {
  1249. X        index_file_killed = FALSE;
  1250. X        last_read_article = 0L;
  1251. X    }
  1252. X
  1253. X    /*
  1254. X     *  add any articles to arts[] that are new or were killed
  1255. X     */
  1256. X    modified = read_group (group, group_path);
  1257. X
  1258. X    /*
  1259. X     *  compare kill descriptions to arts[] and kill mark any that match
  1260. X     */
  1261. X    killed = kill_any_articles (group);
  1262. X    
  1263. X    if (modified || killed || purge_needed()) {
  1264. X        if (local_index) {        /* writing index in home directory */
  1265. X            set_real_uid_gid ();    /* so become them */
  1266. X        }
  1267. X
  1268. X        if (killed) {
  1269. X            reload_index_file (group, killed);
  1270. X        } else {
  1271. X            dump_index (group, FALSE);
  1272. X            make_threads (FALSE);
  1273. X            find_base ();
  1274. X        }
  1275. X
  1276. X        if (local_index) {
  1277. X            set_tin_uid_gid ();
  1278. X        }
  1279. X    } else {
  1280. X        make_threads (FALSE);
  1281. X        find_base ();
  1282. X    }
  1283. X    
  1284. X    if ((modified || killed) && ! update) {
  1285. X        clear_message();
  1286. X    }
  1287. X}
  1288. X
  1289. X/*
  1290. X *  Index a group.  Assumes any existing index has already been
  1291. X *  loaded.
  1292. X */
  1293. X
  1294. Xint read_group (group, group_path)
  1295. X    char *group;
  1296. X    char *group_path;
  1297. X{
  1298. X    int fd;
  1299. X    long art;
  1300. X    int count;
  1301. X    int display_groupname = TRUE; 
  1302. X    int modified = FALSE;
  1303. X    int respnum;
  1304. X    register int i;
  1305. X    
  1306. X    setup_base (group, group_path);    /* load article numbers into base[] */
  1307. X    count = 0;
  1308. X
  1309. X    for (i = 0; i < top_base; i++) {    /* for each article # */
  1310. X        art = base[i];
  1311. X
  1312. X/*
  1313. X *  Do we already have this article in our index?  Change thread from
  1314. X *  -2 (ART_EXPIRED) to -1 (ART_NORMAL) if so and skip the header eating.
  1315. X */
  1316. X
  1317. X        if ((respnum = valid_artnum (art)) >= 0 || art <= last_read_article) {
  1318. X            arts[respnum].thread = ART_NORMAL;
  1319. X            arts[respnum].unread = ART_UNREAD;
  1320. X            continue;
  1321. X        }
  1322. X
  1323. X        if (! modified) {
  1324. X            modified = TRUE;   /* we've modified the index */
  1325. X                               /* it will need to be re-written */
  1326. X        }
  1327. X
  1328. X        if ((fd = open_header_fd (group_path, art)) < 0) {
  1329. X            continue;
  1330. X        }
  1331. X        
  1332. X        /*
  1333. X         *  Add article to arts[]
  1334. X         */
  1335. X        if (top >= max_art)
  1336. X            expand_art();
  1337. X
  1338. X        arts[top].artnum = art;
  1339. X        arts[top].thread = ART_NORMAL;
  1340. X
  1341. X        set_article (&arts[top]);
  1342. X
  1343. X        if (! parse_headers (fd, &arts[top])) {
  1344. X            continue;
  1345. X        }
  1346. X        close (fd);
  1347. X        last_read_article = arts[top].artnum;    /* used if arts are killed */
  1348. X        top++;
  1349. X
  1350. X        if (++count % 10 == 0 && ! update) {
  1351. X            if (display_groupname) {
  1352. X                MoveCursor (1, 0);
  1353. X                CleartoEOLN ();
  1354. X                center_line (1, TRUE, group);
  1355. X                display_groupname = FALSE;
  1356. X            }
  1357. X            sprintf (msg, txt_indexing, count);
  1358. X            wait_message (msg);
  1359. X        }
  1360. X    }
  1361. X
  1362. X    return modified;
  1363. X}
  1364. X
  1365. X
  1366. X/*
  1367. X *  Go through the articles in arts[] and use .thread to snake threads
  1368. X *  through them.  Use the subject line to construct threads.  The
  1369. X *  first article in a thread should have .inthread set to FALSE, the
  1370. X *  rest TRUE.  Only do unexprired articles we haven't visited yet
  1371. X *  (arts[].thread == -1 ART_NORMAL).
  1372. X */
  1373. X
  1374. Xvoid make_threads (rethread)
  1375. X    int rethread;
  1376. X{
  1377. X    register int i;
  1378. X    register int j;
  1379. X
  1380. X    /*
  1381. X     *  .thread & .inthread need to be reset if re-threading arts[]
  1382. X     */
  1383. X    if (rethread) {
  1384. X        for (i=0 ; i < top ; i++) {
  1385. X            arts[i].thread = ART_NORMAL;
  1386. X            arts[i].inthread = FALSE;
  1387. X        }
  1388. X    }
  1389. X
  1390. X    switch (sort_art_type) {
  1391. X        case SORT_BY_NONE:        /* don't sort at all */
  1392. X            qsort (arts, top, sizeof (struct header), artnum_comp);
  1393. X            break;
  1394. X        case SORT_BY_SUBJ:
  1395. X            qsort (arts, top, sizeof (struct header), subj_comp);
  1396. X            break;
  1397. X        case SORT_BY_FROM:
  1398. X            qsort (arts, top, sizeof (struct header), from_comp);
  1399. X            break;
  1400. X        case SORT_BY_DATE:
  1401. X            qsort (arts, top, sizeof (struct header), date_comp);
  1402. X            break;
  1403. X        default:
  1404. X            break;
  1405. X    }
  1406. X
  1407. X    for (i = 0; i < top; i++) {
  1408. X        if (arts[i].thread == ART_NORMAL) {
  1409. X            for (j = i+1; j < top; j++) {
  1410. X                if (arts[j].thread != ART_EXPIRED &&
  1411. X                    ((arts[i].subject == arts[j].subject) ||
  1412. X                    ((arts[i].part || arts[i].patch) &&
  1413. X                    arts[i].archive == arts[j].archive))) {
  1414. X                        arts[i].thread = j;
  1415. X                        arts[j].inthread = TRUE;
  1416. X                        break;
  1417. X                }
  1418. X            }
  1419. X        }
  1420. X    }
  1421. X}
  1422. X
  1423. X/*
  1424. X *  Return a pointer into s eliminating any leading Re:'s.  Example:
  1425. X *
  1426. X *      Re: Reorganization of misc.jobs
  1427. X *      ^   ^
  1428. X */
  1429. X
  1430. Xchar *eat_re (s)
  1431. X    char *s;
  1432. X{
  1433. X
  1434. X    while (*s == 'r' || *s == 'R') {
  1435. X        if ((*(s+1) == 'e' || *(s+1) == 'E')) {
  1436. X            if (*(s+2) == ':')
  1437. X                s += 3;
  1438. X            else if (*(s+2) == '^' && isdigit(*(s+3)) && *(s+4) == ':')
  1439. X                s += 5;            /* hurray nn */
  1440. X            else
  1441. X                break;
  1442. X        } else
  1443. X            break;
  1444. X        while (*s == ' ')
  1445. X            s++;
  1446. X    }
  1447. X
  1448. X    return s;
  1449. X}
  1450. X
  1451. X/*
  1452. X *  Hash the subjects (after eating the Re's off) for a quicker
  1453. X *  thread search later.  We store the hashes for subjects in the
  1454. X *  index file for speed.
  1455. X */
  1456. X
  1457. Xlong hash_s(s)
  1458. X    char *s;
  1459. X{
  1460. X    char *t;
  1461. X    long h = 0;
  1462. X
  1463. X    t = s;
  1464. X
  1465. X    while (*t)
  1466. X        h = h * 64 + *t++;
  1467. X
  1468. X    return h;
  1469. X}
  1470. X
  1471. X
  1472. Xint parse_headers (fd, h)
  1473. X    int fd;
  1474. X    struct header *h;
  1475. X{
  1476. X    char buf[HEADER_LEN];
  1477. X    char buf2[HEADER_LEN];
  1478. X    char *ptr, *ptrline, *s;
  1479. X    int n = 0, len = 0, lineno = 0;
  1480. X    int flag;
  1481. X    int got_subject = FALSE;
  1482. X    int got_from = FALSE;
  1483. X    int got_date = FALSE;
  1484. X    int got_archive = FALSE;
  1485. X    
  1486. X    if ((n = read(fd, buf, HEADER_LEN)) <= 0)
  1487. X        return FALSE;
  1488. X
  1489. X    buf[n-1] = '\0';
  1490. X
  1491. X    ptr = buf;
  1492. X
  1493. X    while (1) {
  1494. X        for (ptrline = ptr; *ptr && *ptr != '\n'; ptr++) {
  1495. X            if (((*ptr) & 0x7F) < 32) {
  1496. X                *ptr = ' ';
  1497. X            }
  1498. X        }
  1499. X        flag = *ptr;
  1500. X        *ptr++ = '\0';
  1501. X        lineno++;
  1502. X
  1503. X        if (! got_from && strncmp(ptrline, "From: ", 6) == 0) {
  1504. X            my_strncpy(buf2, ptrline+6, max_from+1);
  1505. X            buf2[max_from] = '\0';
  1506. X            h->from = hash_str (buf2);
  1507. X            got_from = TRUE;
  1508. X        } else if (! got_subject && strncmp(ptrline, "Subject: ", 9) == 0) {
  1509. X            my_strncpy (buf2, ptrline+9, max_subj+max_from+1);
  1510. X            s = eat_re (buf2);
  1511. X            s[max_subj+max_from] = '\0';
  1512. X            h->subject = hash_str (eat_re (s));
  1513. X            got_subject = TRUE;
  1514. X        } else if (! got_date && strncmp(ptrline, "Date: ", 6) == 0) {
  1515. X            my_strncpy (buf2, ptrline+6, 32);
  1516. X            parse_date (buf2 ,h->date);
  1517. X            got_date = TRUE;
  1518. X        } else if (strncmp(ptrline, "Archive-name: ", 14) == 0) {
  1519. X            if ((s = (char *) strchr (ptrline+14, '/')) != NULL) {
  1520. X                my_strncpy(buf2, ptrline+14, MAX_ARCH);
  1521. X                if (strncmp (s+1,"part",4) == 0 ||
  1522. X                    strncmp (s+1,"Part",4) == 0) {
  1523. X                    h->part = str_dup (s+5);
  1524. X                    len = (int) strlen (h->part);
  1525. X                    if (h->part[len-1] == '\n') {
  1526. X                        h->part[len-1] = '\0';
  1527. X                    }
  1528. X                } else {
  1529. X                    if (strncmp (s+1,"patch",5) == 0 ||
  1530. X                        strncmp (s+1,"Patch",5) == 0) {
  1531. X                        h->patch = str_dup (s+6);
  1532. X                        len = (int) strlen (h->patch);
  1533. X                        if (h->patch[len-1] == '\n') {
  1534. X                            h->patch[len-1] = '\0';
  1535. X                        }
  1536. X                    }
  1537. X                }
  1538. X                if (h->part || h->patch) {
  1539. X                    s = buf2;
  1540. X                    while (*s && *s != '/')
  1541. X                        s++;
  1542. X                    *s = '\0';    
  1543. X                    s = buf2;
  1544. X                    h->archive = hash_str (s);
  1545. X                    got_archive = TRUE;
  1546. X                }
  1547. X            }
  1548. X        }
  1549. X
  1550. X        if (! flag || lineno > 25 || got_archive) {
  1551. X            debug_print_header (h);
  1552. X            return TRUE;
  1553. X        }
  1554. X    }
  1555. X}
  1556. X
  1557. X/* 
  1558. X *  Write out an index file.  Write the group name first so if
  1559. X *  local indexing is done we can disambiguate between group name
  1560. X *  hash collisions by looking at the index file.
  1561. X *
  1562. X *  NOTE: check out the add_string routine in hashstr.c to
  1563. X *  understand what *iptr is doing in this routine.
  1564. X */
  1565. X
  1566. Xvoid dump_index (group, killed)
  1567. X    char *group;
  1568. X    int killed;
  1569. X{
  1570. X    char nam[LEN+1];
  1571. X    FILE *fp;
  1572. X    int *iptr;
  1573. X    int realnum;
  1574. X    register int i;
  1575. X
  1576. X    sprintf (nam, "%s.%d", index_file, getpid());
  1577. X    if ((fp = fopen (nam, "w")) == NULL) {
  1578. X        error_message (txt_cannot_open, nam);
  1579. X        return;
  1580. X    }
  1581. X
  1582. X    /*
  1583. X     *  dump group header info.
  1584. X     */
  1585. X    if (sort_art_type != SORT_BY_NONE) {
  1586. X        qsort (arts, top, sizeof (struct header), artnum_comp);
  1587. X    }
  1588. X    fprintf(fp, "%s\n", group);
  1589. X    fprintf(fp, "%d\n", num_of_arts ());
  1590. X    if (last_read_article > arts[top-1].artnum) {
  1591. X        fprintf(fp, "%ld\n", last_read_article);
  1592. X    } else {
  1593. X        fprintf(fp, "%ld\n", arts[top-1].artnum);
  1594. X    }
  1595. X    if (index_file_killed && killed) {
  1596. X        fprintf (fp, "KILLED\n");
  1597. X    } else {
  1598. X        fprintf (fp, "COMPLETE\n");
  1599. X    }
  1600. X
  1601. X    /*
  1602. X     *  dump articles
  1603. X     */
  1604. X    realnum = 0; 
  1605. X    for (i = 0; i < top; i++) {
  1606. X        if (arts[i].thread != ART_EXPIRED && ! arts[i].tagged) { 
  1607. X            debug_print_header (&arts[i]);
  1608. X
  1609. X            fprintf(fp, "%ld\n", arts[i].artnum);
  1610. X
  1611. X            iptr = (int *) arts[i].subject;
  1612. X            iptr--;
  1613. X
  1614. X            if (! arts[i].subject) {
  1615. X                fprintf(fp, " \n");
  1616. X            } else if (*iptr < 0 || *iptr > top) {
  1617. X                fprintf(fp, " %s\n", arts[i].subject);
  1618. X                *iptr = realnum;
  1619. X/*
  1620. X            } else if (arts[*iptr].tagged) {
  1621. X                fprintf(fp, " %s\n", arts[i].subject);
  1622. X                *iptr = realnum;
  1623. X            } else if (killed && *iptr == i) {
  1624. X*/
  1625. X            } else if (killed || *iptr == i) {
  1626. X                fprintf(fp, " %s\n", arts[i].subject);
  1627. X            } else {
  1628. X                fprintf(fp, "%%%d\n", *iptr);
  1629. X            }
  1630. X    
  1631. X            iptr = (int *) arts[i].from;
  1632. X            iptr--;
  1633. X
  1634. X            if (! arts[i].from) {
  1635. X                fprintf (fp, " \n");
  1636. X            } else if (*iptr < 0 || *iptr > top) {
  1637. X                fprintf (fp, " %s\n", arts[i].from);
  1638. X                *iptr = realnum;
  1639. X/*
  1640. X            } else if (arts[*iptr].tagged) {
  1641. X                fprintf(fp, " %s\n", arts[i].from);
  1642. X                *iptr = realnum;
  1643. X            } else if (killed && *iptr == i) {
  1644. X*/            
  1645. X            } else if (killed || *iptr == i) {
  1646. X                fprintf(fp, " %s\n", arts[i].from);
  1647. X            } else {
  1648. X                fprintf(fp, "%%%d\n", *iptr);
  1649. X            }
  1650. X
  1651. X            fprintf (fp, "%s\n", arts[i].date);
  1652. X            
  1653. X            iptr = (int *) arts[i].archive;
  1654. X            iptr--;
  1655. X
  1656. X            if (! arts[i].archive) {
  1657. X                fprintf (fp, "\n");
  1658. X            } else if (*iptr < 0 || *iptr > top) {
  1659. X                fprintf (fp, " %s\n", arts[i].archive);
  1660. X                *iptr = realnum;
  1661. X/*
  1662. X            } else if (arts[*iptr].tagged) {
  1663. X                fprintf (fp, " %s\n", arts[i].archive);
  1664. X                *iptr = realnum;
  1665. X*/                
  1666. X            } else if (arts[i].part || arts[i].patch) {
  1667. X/*
  1668. X                if (killed && *iptr == i) {
  1669. X*/                
  1670. X                if (killed || *iptr == i) {
  1671. X                    fprintf(fp, " %s\n", arts[i].archive);
  1672. X                } else {
  1673. X                    fprintf (fp, "%%%d\n", *iptr);
  1674. X                }
  1675. X            } else {
  1676. X                fprintf (fp, "\n");
  1677. X            }
  1678. X            
  1679. X            if (! arts[i].part) {
  1680. X                fprintf (fp, " \n");
  1681. X            } else {
  1682. X                fprintf (fp, "%s\n", arts[i].part);
  1683. X            }
  1684. X
  1685. X            if (! arts[i].patch) {
  1686. X                fprintf (fp, " \n");
  1687. X            } else {
  1688. X                fprintf (fp, "%s\n", arts[i].patch);
  1689. X            }
  1690. X
  1691. X            realnum++;
  1692. X        }
  1693. X    }
  1694. X    fclose (fp);
  1695. X    chmod (index_file, 0644);
  1696. X    rename_file (nam, index_file);
  1697. X    if (debug) {
  1698. X        sprintf (msg, "/bin/cp %s INDEX", index_file);
  1699. X        system (msg);
  1700. X    }
  1701. X}
  1702. X
  1703. X/*
  1704. X *  strncpy that stops at a newline and null terminates
  1705. X */
  1706. X
  1707. Xvoid my_strncpy(p, q, n)
  1708. X    char *p;
  1709. X    char *q;
  1710. X    int n;
  1711. X{
  1712. X    while (n--) {
  1713. X        if (!*q || *q == '\n')
  1714. SHAR_EOF
  1715. echo "End of tin1.0 part 1"
  1716. echo "File art.c is continued in part 2"
  1717. echo "2" > shar3_seq_.tmp
  1718. exit 0
  1719.  
  1720.  
  1721. --
  1722. NAME   Iain Lea
  1723. EMAIL  norisc!iain@estevax.UUCP  ...!unido!estevax!norisc!iain
  1724. SNAIL  Siemens AG, AUT 922C, Postfach 4848, Nuernberg, Germany
  1725. PHONE  +49-911-895-3853, +49-911-895-3877, +49-911-331963
  1726.