home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-03-27 | 50.4 KB | 1,839 lines |
- Newsgroups: comp.sources.misc
- From: iain%anl433.uucp@germany.eu.net (Iain J. Lea)
- Subject: v29i021: tin - threaded full screen newsreader v1.1P1, Part03/12
- Message-ID: <1992Mar27.033012.2189@sparky.imd.sterling.com>
- X-Md4-Signature: 7ac252288dcd0d07398f2b1d1636718c
- Date: Fri, 27 Mar 1992 03:30:12 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: iain%anl433.uucp@germany.eu.net (Iain J. Lea)
- Posting-number: Volume 29, Issue 21
- Archive-name: tin/part03
- Environment: BSD, SCO, ISC, SUNOS, SYSVR3, SYSVR4, ULTRIX, XENIX
- Supersedes: tin: Volume 28, Issue 45-55
-
- #!/bin/sh
- # this is tin.shar.03 (part 3 of tin1.1)
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file tin.nrf continued
- #
- if test ! -r _shar_seq_.tmp; then
- echo 'Please unpack part 1 first!'
- exit 1
- fi
- (read Scheck
- if test "$Scheck" != 3; then
- echo Please unpack part "$Scheck" next!
- exit 1
- else
- exit 0
- fi
- ) < _shar_seq_.tmp || exit 1
- if test ! -f _shar_wnt_.tmp; then
- echo 'x - still skipping tin.nrf'
- else
- echo 'x - continuing file tin.nrf'
- sed 's/^X//' << 'SHAR_EOF' >> 'tin.nrf' &&
- X
- X KK Mark thread as read and advance to next unread thread.
- X
- X mm Mail current article / thread / articles matching pattern
- X / tagged articles to someone.
- X
- X MM User configurable options menu (for more information see
- X section Options Menu).
- X
- X nn Go to the next article.
- X
- X NN Go to the next unread article.
- X
- X oo Output current article / thread / articles matching
- X pattern / tagged articles to printer.
- X
- X oo Output article/thread/tagged articles to printer.
- X
- X pp Go to the previous article.
- X
- X PP Go to the previous unread article.
- X
- X qq Quit tin.
- X
- X rr Reply through mail to author.
- X
- X RR Reply through mail to author with a copy of the current
- X
- X
- X
- X
- 10 Release 4.1R NEWS-OS
- X
- X
- X
- X
- X
- TIN(1) LOCAL TIN(1)
- X
- X
- X
- X article included.
- X
- X ss Save current article / thread / articles matching pattern
- X / tagged articles to file / files / mailbox. To save to a
- X mailbox enter '=' or '=mailbox' when asked for filename
- X to save to. To save in <newsgroup name>/<filename> format
- X enter '+filename'. Environment variables are allowed
- X within a filename (ie. $SOURCES/dir/filename).
- X
- X tt Return to group selection index.
- X
- X vv Print tin version number.
- X
- X ww Post an article to current group.
- X
- X WW List articles posted by user. The date posted, the
- X newsgroup and the subject are listed.
- X
- X zz Mark article as unread.
- X
- X // Article forward search.
- X
- X ?? Article backward search
- X
- X || Pipe current article / thread / articles matching pattern
- X / tagged articles into command.
- X
- X << Goto the first article in the current thread.
- X
- X >> Goto the last article in the current thread.
- X
- OOPPTTIIOONNSS MMEENNUU
- X This menu is accessed by pressing 'M' at all levels. It allows the
- X user to customize the behaviour of tin. The options are saved to
- X the file $_H_O_M_E/._t_i_n/_t_i_n_r_c. Use <SPACE> to toggle the required
- X option and <CR> to set.
- X
- X AAuuttoo ssaavvee
- X Automatically save articles/threads by Archive-name: line in
- X article header. This is useful to set ON in conjunction with
- X 'Save separate'.
- X
- X SSaavvee sseeppaarraattee
- X Save articles/threads to separate files. Set ON if saving
- X source code. Set OFF if saving a conversational thread.
- X
- X MMaarrkk ssaavveedd rreeaadd
- X This allows saved articles/threads to be automatically marked
- X as having been read.
- X
- X KKiillll aarrttiicclleess
- X This allows the user to kill articles that match entries in the
- X
- X
- X
- X
- NEWS-OS Release 4.1R 11
- X
- X
- X
- X
- X
- TIN(1) LOCAL TIN(1)
- X
- X
- X
- X kill file $_H_O_M_E/._t_i_n/_k_i_l_l.
- X
- X DDrraaww aarrrrooww
- X Allows groups/articles to be selected by an arrow '->' if set
- X ON or by an highlighted bar if set OFF.
- X
- X PPrriinntt hheeaaddeerr
- X This allows the complete mail header or only the Siubject: and
- X From: fields to be output when printing articles.
- X
- X GGoottoo 11sstt uunnrreeaadd
- X This allows the cursor to be placed at the first / last unread
- X article upon entering a newsgroup with unread news.
- X
- X SSccrroollll ffuullll ppaaggee
- X If set ON scrolling of groups/articles will be a full page at a
- X time, otherwise half a page at a time.
- X
- X CCaattcchhuupp oonn qquuiitt
- X If set ON the user is asked when quitting if all groups read
- X during the current session should be marked read.
- X
- X TThhrreeaadd aarrttiicclleess
- X If set ON articles will be threaded in all groups (default),
- X otherwise articles will be shown unthreaded. If set ON but
- X certain user specified groups are in $_H_O_M_E/._t_i_n/_u_n_t_h_r_e_a_d, the
- X specified groups will be unthreaded and the rest will be
- X threaded.
- X
- X SShhooww oonnllyy uunnrreeaadd
- X If set ON show only new/unread articles, otherwise show all
- X articles.
- X
- X SShhooww AAuutthhoorr
- X If set 'None' only the Subject: line will be displayed. If set
- X 'Addr' Subject: line & the address part of the From: line are
- X displayed. If set 'Name' Subject: line & the authors full name
- X part of the From: line are displayed. If set 'Both' Subject:
- X line & all of the From: line are displayed.
- X
- X PPrroocceessss ttyyppee
- X This specifies the default type of post processing to perform
- X on saved articles. The following types of processing are
- X allowed:
- X -none.
- X -unpacking of multi-part shell archives.
- X -unpacking of multi-part uuencoded files.
- X -unpacking of multi-part uuencoded files that produce a
- X *.zoo archive whose contents is listed.
- X -unpacking of multi-part uuencoded files that produce a
- X *.zoo archive whose contents is extracted.
- X
- X
- X
- X
- X
- 12 Release 4.1R NEWS-OS
- X
- X
- X
- X
- X
- TIN(1) LOCAL TIN(1)
- X
- X
- X
- X SSoorrtt aarrttiicclleess bbyy
- X This specifies how articles should be sorted. The following
- X sort types are allowed:
- X -don't sort articles (default).
- X -sort articles by Subject: field (ascending & descending).
- X -sort articles by From: field (ascending & descending).
- X -sort articles by Date: field (ascending & descending).
- X
- X SSaavvee ddiirreeccttoorryy
- X The directory where articles/threads are to be saved. Default
- X is $_H_O_M_E/_N_e_w_s.
- X
- X MMaaiill ddiirreeccttoorryy
- X The directory where articles/threads are to be saved in mailbox
- X format. This feature is mainly for use with the Elm mail
- X program. It allows the user to save articles/threads/groups
- X simply by giving '=' as the filename to save to.
- X
- X PPrriinntteerr
- X The printer program with options that is to be used to print
- X articles. Default is lpr for BSD machines and lp for SysV
- X machines.
- X
- KKIILLLL AARRTTIICCLLEE MMEENNUU
- X This menu is accessed by pressing '^K' at the group and page
- X levels. It allows the user to kill an article that matches the
- X current Subject: line, From: line or a string entered by the user.
- X The user entered string can be applied to the Subject: or From:
- X lines of an article. The kill description can be limited to the
- X current newsgroup or it can apply to all newsgroups. Once entered
- X the user can abort the command and not save the kill description,
- X edit the kill file or save the kill description.
- X
- X On starting tin the users killfile $_H_O_M_E/._t_i_n/_k_i_l_l is read and on
- X entering a newsgroup any kill descriptions are applied. Articles
- X that match a kill description are marked killed and are not
- X displayed.
- X
- X The 'Kill articles' option needs to be set ON in the Options Menu
- X (selected by 'M' at any level) to activate this command.
- X
- PPOOSSTTIINNGG AARRTTIICCLLEESS
- X Tin allows posting of articles, follow-up to already posted
- X articles and replying direct through mail to the author of an
- X article.
- X
- X Use the 'w' command to post an article to a newsgroup. After
- X entering the post subject the default editor (ie. vi) or the editor
- X specified by the $VISUAL environment variable will be started and
- X the article can be entered. To crosspost articles simply add a
- X comma and the name of the newsgroup(s) to the end of the
- X Newsgroups: line at the beginning of the article. After saving and
- X
- X
- X
- X
- NEWS-OS Release 4.1R 13
- X
- X
- X
- X
- X
- TIN(1) LOCAL TIN(1)
- X
- X
- X
- X exiting the editor you are asked if you wish to a)bort posting the
- X article, e)dit the article again or p)ost the article to the
- X specified newsgroup(s).
- X
- X Use the 'W' command to display a history of the articles you have
- X posted. The date the article was posted, which newsgroups the
- X article was posted to and the articles subject line are displayed.
- X
- X Use the 'f' / 'F' command to post a follow-up article to an already
- X posted article. The 'F' command will copy the text of the original
- X article into the editor. The editing procedure is the same as when
- X posting an article with the 'w' command.
- X
- X Use the 'r' / 'R' command to reply direct through mail to the
- X author of an already posted article. The 'R' command will copy the
- X text of the original article into the editor. The editing procedure
- X is the same as when posting an article with the 'w' command. After
- X saving and exiting the editor you are asked if you wish to a)bort
- X sending the article, e)dit the article again or s)end the article
- X to the author.
- X
- MMAAIILLIINNGG PPIIPPIINNGG PPRRIINNTTIINNGG AANNDD SSAAVVIINNGG AARRTTIICCLLEESS
- X The command interface to mail ('m'), pipe ('|'), print ('o') and
- X save ('s') articles is the same for ease of use.
- X
- X The initial command will ask you to select which a)rticle, t)hread,
- X r)egex pattern, t)agged articles you wish to mail, pipe etc.
- X
- X Tagged articles must have already been tagged with the 'T' command.
- X All tagged articles can be untagged by the 'U' untag command.
- X
- X If regex pattern matching is selected you are asked to enter a
- X regular expression (ie. to match all articles subject lines
- X containing 'net News' you must enter '*net News*'). Any articles
- X that match the entered expression will be mailed, piped etc.
- X
- X To save articles to a mailbox with the name of the current
- X newsgroup (ie. Alt.sources) enter '=' or '=<mailbox name>' when
- X asked for the save filename.
- X
- X To save articles in <newsgroup name>/<filename> format enter
- X '+<filename>'.
- X
- X When saving articles you can specify whether the saved files should
- X be post processed (ie. unshar shell archive, uudecode multiple
- X parts etc). A default process type can be set by the 'Process
- X type:' in the 'M' options menu.
- X
- AAUUTTOOMMAATTIICC MMAAIILLIINNGG AANNDD SSAAVVIINNGG NNEEWW NNEEWWSS
- X Tin allows new/unread news articles to be mailed (-M option)/saved
- X (-S option) in batch mode for later reading. Useful when going on
- X holiday and you don't want to return and find that expire has
- X
- X
- X
- X
- 14 Release 4.1R NEWS-OS
- X
- X
- X
- X
- X
- TIN(1) LOCAL TIN(1)
- X
- X
- X
- X removed a whole load of unread articles. Best to run from crontab
- X everyday while away, after which you will be mailed a report of
- X which articles were mailed/saved from which newsgroups and the
- X total number of articles mailed/saved. Articles are saved in a
- X private news structure under your <savedir> directory (default is
- X $_H_O_M_E/_N_e_w_s). Be careful of using this option if you read a lot of
- X groups because you could overflow your filesystem. If you only want
- X to save a few groups it would be best to backup your full
- X $_H_O_M_E/._n_e_w_s_r_c and create a new one that only contains the
- X newsgroups you want to mail/save. Saved news can be read later by
- X starting tin with the -R option.
- X
- X tin -M iain -f newsrc.mail (mail any unread articles in newgroups
- X specified in file newsrc.mail)
- X
- X tin -S -f newsrc.save (save any unread articles in newgroups
- X specified in file newsrc.save)
- X
- X tin -R (read any unread articles saved by tin -S option)
- X
- SSIIGGNNAATTUURREESS
- X Tin will recognize a signature in either $_H_O_M_E/._s_i_g_n_a_t_u_r_e or
- X $_H_O_M_E/._S_i_g. If $_H_O_M_E/._s_i_g_n_a_t_u_r_e exists, then the signature will be
- X pulled into the editor for Tin mail commands. A signature in
- X $_H_O_M_E/._s_i_g_n_a_t_u_r_e will not be pulled into the editor for posting
- X commands since the inews program will append the signature itself.
- X
- X A signature in $_H_O_M_E/._S_i_g will be pulled into the editor for both
- X posting and mailing commands.
- X
- X The following is an example of a $_H_O_M_E/._S_i_g file:
- X NAME Iain Lea
- X EMAIL iain%anl433.uucp@germany.eu.net
- X SNAIL Bruecken Strasse 12, 8500 Nuernberg 90, Germany
- X PHONE +49-911-331963 (home) +49-911-3089-407 (work)
- X
- EENNVVIIRROOMMEENNTT VVAARRIIAABBLLEESS
- X TTIINNDDIIRR
- X Define this variable if you do not want tin's .tin directory
- X in $HOME/.tin. (ie. if you want all tin's private files in
- X /tmp/.tin you would set TINDIR to contain /tmp.
- X
- X NNNNTTPPSSEERRVVEERR
- X The default NNTP server to remotely read news from. This
- X variable only needs to be set if the -r command line option is
- X specified and the file /_e_t_c/_n_n_t_p_s_e_r_v_e_r does not exist.
- X
- X OORRGGAANNIIZZAATTIIOONN
- X Set the mail header field Organization: to the contents of the
- X variable instead of the system default. This variable has
- X precedence over the file $_H_O_M_E/._t_i_n/_o_r_g_a_n_i_z_a_t_i_o_n that may also
- X contain an organization string.
- X
- X
- X
- X
- NEWS-OS Release 4.1R 15
- X
- X
- X
- X
- X
- TIN(1) LOCAL TIN(1)
- X
- X
- X
- X RREEPPLLYYTTOO
- X Set the mail header field Reply-To: to the return address
- X specified by the variable. This is useful if the machine is
- X not registered in the UUCP mail maps or if you wish to recieve
- X replies at a different machine. This variable has precedence
- X over the file $_H_O_M_E/._t_i_n/_r_e_p_l_y_t_o that may also contain a
- X return address.
- X
- X AADDDD_AADDDDRREESSSS
- X This can contain an address to append to the return address
- X when replying directly through mail to somebody whose mail
- X address is not directly recognized by the local host. For
- X example say the return address is _u_s_e_r@_b_i_g_v_a_x, but _b_i_g_v_a_x is
- X not recognized by your host, so therfore the mail will not
- X reach _u_s_e_r. But the host _l_i_t_t_e_v_a_x is known to recognize your
- X host and _b_i_g_v_a_x, so if ADD_ADDRESS is set (ie. 'setenv
- X ADD_ADDRESS @littevax' for csh or 'set ADD_ADDRESS @littevax'
- X and 'export ADD_ADDRESS' for sh) the address
- X _u_s_e_r@_b_i_g_v_a_x@_l_i_t_t_l_e_v_a_x will be used and the mail will reach
- X _u_s_e_r@_b_i_g_v_a_x. This variable has precedence over the file
- X $_H_O_M_E/._t_i_n/_a_d_d__a_d_d_r_e_s_s that may also contain an address.
- X
- X BBUUGG_AADDDDRREESSSS
- X If the 'B' command bug report mail address is not correct this
- X variable should be set to the correct mail address. This
- X variable has precedence over the file $_H_O_M_E/._t_i_n/_b_u_g__a_d_d_r_e_s_s
- X that may also contain a mail address.
- X
- X VVIISSUUAALL
- X This variable has precedence over the default editor (ie. vi)
- X that is used in all editing operations within tin (ie. posting
- X 'w', replying 'rR', follow-ups 'fF' and bug reports 'B').
- X
- TTIIPPSS AANNDD TTRRIICCKKSS
- X The following newsgroups provide useful information concerning news
- X software:
- X -news.software.readers (info. about news user agents
- X tin,rn,nn,vn etc.)
- X -news.software.nntp (info. about NNTP)
- X -news.software.b (info. about news transport agents Bnews &
- X Cnews)
- X
- X Many prompts (ie. 'Mark everything as read? (y/n): y') within tin
- X offer a default choice that the cursor is positioned on. By
- X pressing <CR> the default value is taken.
- X
- X When tin is run in an xterm window it will resize itself each time
- X the xterm is resized.
- X
- X Tin will reread the active file at set intervals to show any new
- X news.
- X
- X
- X
- X
- X
- 16 Release 4.1R NEWS-OS
- X
- X
- X
- X
- X
- TIN(1) LOCAL TIN(1)
- X
- X
- X
- FFIILLEESS
- X $_H_O_M_E/._n_e_w_s_r_c subscribed to newgroups.
- X $_H_O_M_E/._t_i_n/_t_i_n_r_c options.
- X $_H_O_M_E/._t_i_n/._i_n_d_e_x newsgroup index files directory.
- X $_H_O_M_E/._t_i_n/_a_d_d__a_d_d_r_e_s_s address to add to when replying through mail.
- X $_H_O_M_E/._t_i_n/_a_c_t_i_v_e used by -n option for notifying user of new groups.
- X $_H_O_M_E/._t_i_n/_b_u_g__a_d_d_r_e_s_s address to send bug reports to.
- X $_H_O_M_E/._t_i_n/_k_i_l_l kill file.
- X $_H_O_M_E/._t_i_n/_o_r_g_a_n_i_z_a_t_i_o_n string to replace default organization.
- X $_H_O_M_E/._t_i_n/_p_o_s_t_e_d history of articles posted by user.
- X $_H_O_M_E/._t_i_n/_r_e_p_l_y_t_o host address to use in Reply-To: mail header.
- X $_H_O_M_E/._t_i_n/_u_n_t_h_r_e_a_d contains groups that are not to be threaded.
- X $_H_O_M_E/._s_i_g_n_a_t_u_r_e signature.
- X $_H_O_M_E/._S_i_g signature.
- X
- BBUUGGSS
- X There are bugs somewhere among the creeping featurism. Any bugs
- X found should be reported by the 'B' (bug report) command.
- X
- X There is a bug when article killing is switched ON/OFF at article
- X page level and the 't' command is used to return to group selection
- X index.
- X
- X When articles have been unkilled, all articles will be marked
- X unread even if they have already been read.
- X
- X Killing articles when tin is setuid causes strange behaviour.
- X
- X Will not uudecode some of the images in alt.binaries.pictures
- X because more than one image is in the multi-part file to uudecode.
- X Only the first image will be uudecoded.
- X
- X Does not yet handle Xref: headers for cross-posted articles.
- X
- HHIISSTTOORRYY
- X Based on the tass newsreader that was developed by Rich Skrenta and
- X posted to alt.sources in March 1991. Tass was itself heavily
- X infleuenced by NOTES which was developed at the University of
- X Illinois in the early 1980's.
- X
- X Tin v1.00 (full distribution) was posted in 8 parts to alt.sources
- X on 23 Aug 1991.
- X Tin v1.0 PL1 (full distribution) was posted in 8 parts to
- X alt.sources on 03 Sep 1991.
- X Tin v1.0 PL2 (full distribution) was posted in 9 parts to
- X alt.sources on 24 Sep 1991.
- X Tin v1.0 PL3 (patch) was posted in 4 parts to alt.sources on 30 Sep
- X 1991.
- X Tin v1.0 PL4 (patch) was posted in 2 parts to alt.sources on 02 Oct
- X 1991.
- X Tin v1.0 PL5 (patch) was posted in 4 parts to alt.sources on 17 Oct
- X 1991.
- X
- X
- X
- X
- NEWS-OS Release 4.1R 17
- X
- X
- X
- X
- X
- TIN(1) LOCAL TIN(1)
- X
- X
- X
- X Tin v1.0 PL6 (patch) was posted in 5 parts to alt.sources on 27 Nov
- X 1991.
- X Tin v1.0 PL7 (patch) was posted in 2 parts to alt.sources on 27 Nov
- X 1991.
- X Tin v1.1 PL0 (full distribution) was posted in 11 parts to
- X alt.sources on 13 Feb 1992.
- X Tin v1.1 PL1 (full distribution) was posted in 12 parts to
- X alt.sources on 24 Mar 1992.
- X
- CCRREEDDIITTSS
- X Rich Skrenta
- X author of tass v3.2 which this newsreader used as its base.
- X
- X Dave Taylor
- X author of curses.c from the elm mailreader.
- X
- X Rich Salz
- X author of wildmat.c pattern matching routine.
- X
- X Chris Thewalt
- X author of getline.c emacs style editing routine.
- X
- X Dieter Becker
- X for generously posting certain versions and patches for me
- X when my net connection was removed by a group of very short
- X sighted people.
- X
- X I wish to thank the following people for supplying patchs:
- X
- X Anton Aylward, Dieter Becker, Dan Berry, Marc Boucher, Robert
- X Claeson, Steven Cogswell, Ned Danieley, Brent Ermlick, Carl Hage,
- X Ed Hanway, Torsten Homeyer, Nelson Kading, Fritz Kleeman, Karl-
- X Koenig Koenigsson, Kris Kugel, Hakan Lennestal, Clifford Luke,
- X Michael Faurot, David MacKenzie, Bill Poitras, Jim Robinson,
- X Nickolay Saukh, Rich Salz, John Sauter, Bart Sears, Karl-Olav
- X Serrander, Doug Sewell, Cliff Stanford, Adri Verhoef, Cary Whitney
- X
- X I wish to thank the following people for bug reports/comments:
- X
- X Klaus Arzig, Scott Babb, Reiner Balling, Volker Beyer, Roger Binns,
- X Georg Biehler, Ian Brown, Andreas Brosig, Leila Burrell-Davis, Tom
- X Czarnik, David Donovan, Peter Dressler, Gerhard Ermer, Hugh Fader,
- X Joachim Feld, Paul Fox, Bernhard Gmelch, Viet Hoang, Andy Jackson,
- X Joe Johnson, Cyrill Jung, Hans-Juergen Knopp, Per Lindqvist, Bob
- X Lukas, Phillip Molloy, Toni Metz, Greg Miller, Klaus Neuberger,
- X Otto Niesser, Reiner Oelhaf, Wolf Paul, John Palkovic, Andrew
- X Phillips, Ted Richards, Fredy Schwatz, Bernd Schwerin, Klamer
- X Schutte, Chris Smith, Daniel Smith, Steve Spearman, Hironobu
- X Takahashi, Sven Werner
- X
- AAUUTTHHOORR
- X Iain Lea
- X
- X
- X
- X
- 18 Release 4.1R NEWS-OS
- X
- X
- X
- X
- X
- TIN(1) LOCAL TIN(1)
- X
- X
- X
- X (iain%anl433.uucp@germany.eu.net)
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- NEWS-OS Release 4.1R 19
- X
- X
- SHAR_EOF
- echo 'File tin.nrf is complete' &&
- chmod 0600 tin.nrf ||
- echo 'restore of tin.nrf failed'
- Wc_c="`wc -c < 'tin.nrf'`"
- test 44431 -eq "$Wc_c" ||
- echo 'tin.nrf: original size 44431, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= active.c ==============
- if test -f 'active.c' -a X"$1" != X"-c"; then
- echo 'x - skipping active.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting active.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'active.c' &&
- /*
- X * Project : tin - a threaded Netnews reader
- X * Module : active.c
- X * Author : I.Lea
- X * Created : 16-02-92
- X * Updated : 01-03-92
- X * Notes :
- X * Copyright : (c) Copyright 1991-92 by Iain Lea
- X * You may freely copy or redistribute this software,
- X * so long as there is no profit made from its use, sale
- X * trade or reproduction. You may not change this copy-
- X * right notice, and it must be included in any copy made
- X */
- X
- #include "tin.h"
- X
- int group_hash[TABLE_SIZE]; /* group name --> active[] */
- int reread_active_file = FALSE;
- X
- X
- int test_reread = 0;
- X
- X
- /*
- X * Resync active file when SIGALRM signal reeived that
- X * is triggered by alarm (RESYNC_ACTIVE_SECS) call.
- X */
- X
- void resync_active_file ()
- {
- #ifndef NO_RESYNC_ACTIVE_FILE
- X if (reread_active_file) {
- X wait_message (txt_reading_active_file);
- X free_active_arrays ();
- X max_active = DEFAULT_ACTIVE_NUM;
- X expand_active ();
- X read_active_file ();
- X read_newsrc (TRUE);
- X reread_active_file = FALSE;
- X alarm (RESYNC_ACTIVE_SECS); /* reset alarm clock */
- X group_selection_page ();
- X test_reread++;
- X }
- #endif
- }
- X
- /*
- X * Load the active file into active[] and create copy of active ~/.tin/active
- X */
- X
- int read_active_file ()
- {
- X FILE *fp;
- X char *p, *q, *r;
- X char buf[LEN];
- X char moderated;
- X int created, i;
- X long h;
- X
- X num_active = 0;
- X
- X if ((fp = open_active_fp ()) == NULL) {
- X if (compiled_with_nntp) {
- X sprintf (msg, txt_cannot_open_active_file, active_file, progname);
- X wait_message (msg);
- X } else {
- X printf (txt_cannot_open, active_file);
- X putchar ('\n');
- X fflush (stdout);
- X }
- X exit (1);
- X }
- X
- X if (reread_active_file == FALSE && (read_news_via_nntp && update == FALSE)) {
- X wait_message (txt_reading_active_file);
- X }
- X
- X for (i = 0; i < TABLE_SIZE; i++) {
- X group_hash[i] = -1;
- X }
- X
- X while (fgets (buf, sizeof (buf), fp) != NULL) {
- X for (p = buf; *p && *p != ' '; p++)
- X continue;
- X if (*p != ' ') {
- X error_message (txt_bad_active_file, buf);
- X continue;
- X }
- X *p++ = '\0';
- X
- X if (num_active >= max_active) {
- X expand_active ();
- X }
- X
- X h = hash_groupname (buf);
- X
- X if (group_hash[h] == -1) {
- X group_hash[h] = num_active;
- X } else { /* hash linked list chaining */
- X for (i=group_hash[h]; active[i].next >= 0; i=active[i].next) {
- X if (strcmp(active[i].name, buf) == 0) {
- X goto read_active_continue; /* kill dups */
- X }
- X }
- X if (strcmp(active[i].name, buf) == 0)
- X goto read_active_continue;
- X active[i].next = num_active;
- X }
- X
- X for (q = p; *q && *q != ' '; q++)
- X continue;
- X if (*q != ' ') {
- X error_message (txt_bad_active_file, buf);
- X continue;
- X }
- X *q++ = '\0';
- X
- X for (r = q; *r && *r != '\n'; r++) {
- X if (*r == 'y' || *r == 'm') {
- X moderated = *r;
- X break;
- X }
- X }
- X
- X active[num_active].name = str_dup (buf);
- X active[num_active].max = (long) atol (p);
- X active[num_active].min = (long) atol (q);
- X active[num_active].moderated = moderated;
- X active[num_active].next = -1; /* hash chaining */
- X active[num_active].flag = UNSUBSCRIBED; /* not in my_group[] yet */
- X active[num_active].read = FALSE; /* read/unread */
- X active[num_active].thread = TRUE; /* thread articles */
- X
- X num_active++;
- X
- read_active_continue:;
- X
- X }
- X fclose (fp);
- X
- X /*
- X * exit if active file is empty
- X */
- X if (! num_active) {
- X error_message (txt_active_file_is_empty, active_file);
- X exit (1);
- X }
- X
- X /*
- X * create backup of LIBDIR/active for use by -n option to notify new groups
- X */
- X created = backup_active (TRUE);
- X
- X debug_print_active ();
- X
- X if (cmd_line || (read_news_via_nntp && update == FALSE)) {
- X wait_message ("\n");
- X }
- X
- X return (created);
- }
- X
- /*
- X * create ~/.tin/active from LIBDIR/active if it does not exist
- X */
- X
- int backup_active (create)
- X int create;
- {
- X char buf[LEN];
- X FILE *fp;
- X int created = FALSE;
- X int i;
- X struct stat sb;
- X
- X set_real_uid_gid ();
- X
- X sprintf (buf, "%s/active", rcdir);
- X
- X if (create) {
- X if (stat (buf, &sb) != -1) {
- X goto backup_active_done;
- X }
- X }
- X
- X if ((fp = fopen (buf, "w")) != NULL) {
- X for (i = 0; i < num_active ; i++) { /* for each group */
- X fprintf (fp, "%s\n", active[i].name);
- X }
- X fclose (fp);
- X chmod (buf, 0644);
- X created = TRUE;
- X }
- X
- backup_active_done:
- X set_tin_uid_gid ();
- X return (created);
- }
- X
- /*
- X * Option -n to check for any newly created newsgroups.
- X */
- X
- #if 0 /* MY VERSION IAIN LEA */
- void notify_groups ()
- {
- X char buf[LEN];
- X FILE *fp;
- X int group_not_found;
- X int i, j, index;
- X int num = 0;
- X int update_old_active = FALSE;
- X struct notify_t {
- X char name[LEN];
- X int len;
- X } *old_active;
- X
- X set_real_uid_gid ();
- X
- X sprintf (buf, "%s/active", rcdir);
- X
- X if ((fp = fopen (buf, "r")) == NULL) {
- X error_message (txt_cannot_open, buf);
- X goto notify_groups_done;
- X }
- X
- X Raw (FALSE);
- X
- X wait_message (txt_checking_active_file);
- X
- X old_active = (struct notify_t *) my_malloc ((unsigned) sizeof (struct notify_t) * num_active);
- X if (old_active == (struct notify_t *) 0) {
- X error_message (txt_out_of_memory, progname);
- X goto notify_groups_done;
- X }
- X
- X while (fgets (old_active[num].name, sizeof (old_active[num].name), fp) != NULL) {
- X old_active[num].len = strlen (old_active[num].name)-1;
- X old_active[num].name[old_active[num].len] = '\0';
- X num++;
- X if (num == num_active) {
- X break;
- X }
- X }
- X
- X for (i = 0 ; i < num_active ; i++) {
- X group_not_found = TRUE;
- X for (j=0; j < num ; j++) {
- X if (strncmp (old_active[j].name, active[i].name, old_active[j].len) == 0) {
- X group_not_found = FALSE; /* found it so read in next group */
- X break;
- X }
- X }
- X
- X if (group_not_found) {
- X update_old_active = TRUE;
- X sprintf (msg, txt_subscribe_to_new_group, active[i].name);
- X wait_message (msg);
- X scanf ("%s", buf);
- X if (buf[0] == 'y') {
- X index = add_group (active[i].name, TRUE);
- X subscribe (active[my_group[index]].name, ':',
- X my_group[index], FALSE);
- X }
- X wait_message (txt_checking);
- X }
- X }
- X fclose (fp);
- X
- X if (old_active != (struct notify_t *) 0) {
- X free ((char *) old_active);
- X old_active = (struct notify_t *) 0;
- X }
- X
- X Raw (TRUE);
- X
- X /*
- X * write active[] to ~/.tin/active
- X */
- X if (update_old_active) {
- X backup_active (FALSE);
- X }
- X
- notify_groups_done:
- X set_tin_uid_gid ();
- }
- X
- #endif
- X
- void notify_groups ()
- {
- X char buf[LEN];
- X FILE *fp;
- X int group_not_found;
- X int i, j, index;
- X int num = 0;
- X int update_old_active = FALSE;
- X int max_old_active;
- X struct notify_t {
- X char name[LEN];
- X int len;
- X int visited;
- X } *old_active;
- X
- X set_real_uid_gid ();
- X
- X sprintf (buf, "%s/active", rcdir);
- X
- X if ((fp = fopen (buf, "r")) == NULL) {
- X error_message (txt_cannot_open, buf);
- X goto notify_groups_done;
- X }
- X
- X Raw (FALSE);
- X
- X wait_message (txt_checking_active_file);
- X
- X max_old_active = num_active;
- X
- X old_active = (struct notify_t *) my_malloc ((unsigned) sizeof (struct notify_t) * max_old_active);
- X if (old_active == (struct notify_t *) 0) {
- X error_message (txt_out_of_memory, progname);
- X goto notify_groups_done;
- X }
- X
- X while (fgets (old_active[num].name, sizeof (old_active[num].name), fp) != NULL) {
- X old_active[num].len = strlen (old_active[num].name)-1;
- X old_active[num].name[old_active[num].len] = '\0';
- X old_active[num].visited = FALSE;
- X num++;
- X if (num >= max_old_active) {
- X max_old_active= max_old_active + (max_old_active / 2);
- X old_active= (struct notify_t*) my_realloc(
- X (struct notify_t*) old_active,
- X (unsigned) sizeof(struct notify_t) * max_old_active);
- X if (old_active == (struct notify_t *) 0) {
- X error_message (txt_out_of_memory, progname);
- X goto notify_groups_done;
- X }
- X }
- X }
- X
- X for (i = 0 ; i < num_active ; i++) {
- X group_not_found = TRUE;
- X for (j=0; j < num ; j++) {
- X if (strcmp (old_active[j].name, active[i].name) == 0) {
- X group_not_found = FALSE; /* found it so read in next group */
- X old_active[j].visited = TRUE;
- X break;
- X }
- X }
- X
- X if (group_not_found) {
- X update_old_active = TRUE;
- X printf ("\r\nSubscribe to %s (y/n): ", active[i].name);
- X fflush (stdout);
- X scanf ("%s", buf);
- X if (buf[0] == 'y') {
- X index = add_group (active[i].name, TRUE);
- X subscribe (active[my_group[index]].name, ':',
- X my_group[index], FALSE);
- X }
- X printf ("Checking...");
- X fflush (stdout);
- X }
- X }
- X fclose (fp);
- X
- X /*
- X * Look for bogus groups
- X */
- X for (j = 0 ; j < num ; j++) {
- X if (! old_active[j].visited) {
- X update_old_active= 1;
- X printf ("\nRemove bogus group %s (y/n): ", old_active[j].name);
- X fflush (stdout);
- X scanf ("%s", buf);
- X if (buf[0] == 'y')
- X delete_group (old_active[j].name);
- X }
- X }
- X
- X if (old_active != (struct notify_t *) 0) {
- X free ((char *) old_active);
- X old_active = (struct notify_t *) 0;
- X }
- X
- X Raw (TRUE);
- X
- X /*
- X * write active[] to ~/.tin/active
- X */
- X if (update_old_active) {
- X backup_active (FALSE);
- X }
- X
- notify_groups_done:
- X set_tin_uid_gid ();
- }
- SHAR_EOF
- chmod 0600 active.c ||
- echo 'restore of active.c failed'
- Wc_c="`wc -c < 'active.c'`"
- test 8707 -eq "$Wc_c" ||
- echo 'active.c: original size 8707, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= art.c ==============
- if test -f 'art.c' -a X"$1" != X"-c"; then
- echo 'x - skipping art.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting art.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'art.c' &&
- /*
- X * Project : tin - a threaded Netnews reader
- X * Module : art.c
- X * Author : I.Lea & R.Skrenta
- X * Created : 01-04-91
- X * Updated : 21-03-92
- X * Notes :
- X * Copyright : (c) Copyright 1991-92 by Iain Lea & Rich Skrenta
- X * You may freely copy or redistribute this software,
- X * so long as there is no profit made from its use, sale
- X * trade or reproduction. You may not change this copy-
- X * right notice, and it must be included in any copy made
- X */
- X
- #include "tin.h"
- X
- char index_file[LEN];
- char *glob_art_group;
- int index_file_killed = FALSE;
- long last_read_article;
- X
- X
- /*
- X * Construct the pointers to the basenotes of each thread
- X * arts[] contains every article in the group. inthread is
- X * set on each article that is after the first article in the
- X * thread. Articles which have been expired have their thread
- X * set to -2 (ART_EXPIRED).
- X */
- X
- void find_base (only_unread)
- X int only_unread;
- {
- X register int i;
- X register int j;
- X
- X top_base = 0;
- X
- X debug_print_arts ();
- X
- X if (only_unread) {
- X for (i = 0; i < top; i++) {
- X if (arts[i].thread != ART_EXPIRED && arts[i].inthread == FALSE) {
- X if (top_base >= max_art) {
- X expand_art ();
- X }
- X if (arts[i].unread == ART_UNREAD) {
- X base[top_base++] = i;
- X } else {
- X for (j = i ; j >= 0 ; j = arts[j].thread) {
- X if (arts[j].unread) {
- X base[top_base++] = i;
- X break;
- X }
- X }
- X }
- X }
- X }
- X } else {
- X for (i = 0; i < top; i++) {
- X if (! arts[i].inthread && arts[i].thread != ART_EXPIRED) {
- X if (top_base >= max_art) {
- X expand_art ();
- X }
- X base[top_base++] = i;
- X }
- X }
- X }
- }
- X
- /*
- X * Count the number of non-expired and non-killed articles in arts[]
- X */
- X
- int num_of_arts ()
- {
- X int sum = 0;
- X register int i;
- X
- X for (i = 0; i < top; i++) {
- X if (arts[i].thread != ART_EXPIRED && arts[i].killed == FALSE) {
- X sum++;
- X }
- X }
- X
- X return sum;
- }
- X
- /*
- X * Do we have an entry for article art?
- X */
- X
- int valid_artnum (art)
- X long art;
- {
- X register int i;
- X
- X for (i = 0; i < top; i++)
- X if (arts[i].artnum == art)
- X return i;
- X
- X return -1;
- }
- X
- /*
- X * Return TRUE if arts[] contains any expired articles
- X * (articles we have an entry for which don't have a corresponding
- X * article file in the spool directory)
- X */
- X
- int purge_needed ()
- {
- X register int i;
- X
- X for (i = 0; i < top; i++)
- X if (arts[i].thread == ART_EXPIRED)
- X return TRUE;
- X
- X return FALSE;
- }
- X
- /*
- X * Main group indexing routine. Group should be the name of the
- X * newsgroup, i.e. "comp.unix.amiga". group_path should be the
- X * same but with the .'s turned into /'s: "comp/unix/amiga"
- X *
- X * Will read any existing index, create or incrementally update
- X * the index by looking at the articles in the spool directory,
- X * and attempt to write a new index if necessary.
- X */
- X
- void index_group (group, group_path)
- X char *group;
- X char *group_path;
- {
- X int killed = FALSE;
- X int modified = FALSE;
- X glob_art_group = group;
- X
- X set_signals_art ();
- X
- X if (! update) {
- X sprintf (msg, txt_group, group);
- X wait_message (msg);
- X }
- X
- X hash_reclaim ();
- X free_art_array ();
- X
- X /*
- X * load articles from index file if it exists
- X */
- X load_index_file (group);
- X
- X /*
- X * load killed articles into arts[] because kill arts is OFF
- X */
- X if (! kill_articles && index_file_killed) {
- X index_file_killed = FALSE;
- X last_read_article = 0L;
- X }
- X
- X /*
- X * add any articles to arts[] that are new or were killed
- X */
- X modified = read_group (group, group_path);
- X
- X /*
- X * compare kill descriptions to arts[] and kill mark any that match
- X */
- X killed = kill_any_articles (group);
- X
- X if (modified || killed || purge_needed()) {
- X if (local_index) { /* writing index in home directory */
- X set_real_uid_gid (); /* so become them */
- X }
- X
- X if (killed) {
- X reload_index_file (group, killed);
- X } else {
- X dump_index_file (group, FALSE);
- X read_newsrc_line (group);
- X make_threads (FALSE);
- X find_base (show_only_unread);
- X }
- X
- X if (local_index) {
- X set_tin_uid_gid ();
- X }
- X } else {
- X read_newsrc_line (group);
- X make_threads (FALSE);
- X find_base (show_only_unread);
- X }
- X
- X if ((modified || killed) && ! update) {
- X clear_message ();
- X }
- }
- X
- /*
- X * Index a group. Assumes any existing index has already been
- X * loaded.
- X */
- X
- int read_group (group, group_path)
- X char *group;
- X char *group_path;
- {
- X int fd;
- X long art;
- X int count = 0;
- X int modified = FALSE;
- X int respnum;
- X register int i;
- X
- X setup_base (group, group_path); /* load article numbers into base[] */
- X
- X for (i = 0; i < top_base; i++) { /* for each article # */
- X art = base[i];
- X
- /*
- X * Do we already have this article in our index? Change thread from
- X * (ART_EXPIRED) to (ART_NORMAL) if so and skip the header eating.
- X */
- X
- X if ((respnum = valid_artnum (art)) >= 0 || art <= last_read_article) {
- X if (respnum >= 0) {
- X arts[respnum].thread = ART_NORMAL;
- X arts[respnum].unread = ART_UNREAD;
- X }
- X continue;
- X }
- X
- X if (! modified) {
- X modified = TRUE; /* we've modified the index */
- X /* it will need to be re-written */
- X }
- X
- X if ((fd = open_header_fd (group_path, art)) < 0) {
- X continue;
- X }
- X
- X /*
- X * Add article to arts[]
- X */
- X if (top >= max_art)
- X expand_art();
- X
- X arts[top].artnum = art;
- X arts[top].thread = ART_NORMAL;
- X
- X set_article (&arts[top]);
- X
- X if (! parse_headers (fd, &arts[top])) {
- X continue;
- X }
- X close (fd);
- X last_read_article = arts[top].artnum; /* used if arts are killed */
- X top++;
- X
- X if (++count % MODULO_COUNT_NUM == 0 && ! update) {
- #ifndef SLOW_SCREEN_UPDATE
- X sprintf (msg, txt_indexing_num, group, count);
- #else
- X sprintf (msg, txt_indexing, group);
- #endif
- X wait_message (msg);
- X }
- X }
- X
- X return modified;
- }
- X
- X
- /*
- X * Go through the articles in arts[] and use .thread to snake threads
- X * through them. Use the subject line to construct threads. The
- X * first article in a thread should have .inthread set to FALSE, the
- X * rest TRUE. Only do unexprired articles we haven't visited yet
- X * (arts[].thread == -1 ART_NORMAL).
- X */
- X
- void make_threads (rethread)
- X int rethread;
- {
- X extern int cur_groupnum;
- X register int i;
- X register int j;
- X
- X /*
- X * .thread & .inthread need to be reset if re-threading arts[]
- X */
- X if (rethread && active[my_group[cur_groupnum]].thread) {
- X for (i=0 ; i < top ; i++) {
- X arts[i].thread = ART_NORMAL;
- X arts[i].inthread = FALSE;
- X }
- X }
- X
- X switch (sort_art_type) {
- X case SORT_BY_NOTHING: /* don't sort at all */
- X qsort ((char *) arts, top, sizeof (struct article_t), artnum_comp);
- X break;
- X case SORT_BY_SUBJ_DESCEND:
- X case SORT_BY_SUBJ_ASCEND:
- X qsort ((char *) arts, top, sizeof (struct article_t), subj_comp);
- X break;
- X case SORT_BY_FROM_DESCEND:
- X case SORT_BY_FROM_ASCEND:
- X qsort ((char *) arts, top, sizeof (struct article_t), from_comp);
- X break;
- X case SORT_BY_DATE_DESCEND:
- X case SORT_BY_DATE_ASCEND:
- X qsort ((char *) arts, top, sizeof (struct article_t), date_comp);
- X break;
- X default:
- X break;
- X }
- X
- X if (thread_arts && active[my_group[cur_groupnum]].thread) {
- X for (i = 0; i < top; i++) {
- X if (arts[i].thread == ART_NORMAL) {
- X for (j = i+1; j < top; j++) {
- X if (arts[j].thread != ART_EXPIRED &&
- X ((arts[i].subject == arts[j].subject) ||
- X ((arts[i].part || arts[i].patch) &&
- X arts[i].archive == arts[j].archive))) {
- X arts[i].thread = j;
- X arts[j].inthread = TRUE;
- X break;
- X }
- X }
- X }
- X }
- X }
- }
- X
- X
- int parse_headers (fd, h)
- X int fd;
- X struct article_t *h;
- {
- X char buf[HEADER_LEN];
- X char buf2[HEADER_LEN];
- X char art_from_addr[LEN];
- X char art_full_name[LEN];
- X char *ptr, *ptrline, *s;
- X int n = 0, len = 0, lineno = 0;
- X int flag;
- X int got_subject = FALSE;
- X int got_from = FALSE;
- X int got_date = FALSE;
- X int got_archive = FALSE;
- X
- X if ((n = read (fd, buf, HEADER_LEN)) <= 0) {
- X return FALSE;
- X }
- X
- X buf[n-1] = '\0';
- X
- X ptr = buf;
- X
- X while (1) {
- X for (ptrline = ptr; *ptr && *ptr != '\n'; ptr++) {
- X if (((*ptr) & 0xFF) < ' ') {
- X *ptr = ' ';
- X }
- X }
- X flag = *ptr;
- X *ptr++ = '\0';
- X lineno++;
- X
- X if (! got_from && match_header (ptrline, "From", buf2, HEADER_LEN)) {
- X parse_from (buf2, art_from_addr, art_full_name);
- X h->from = hash_str (art_from_addr);
- X h->name = hash_str (art_full_name);
- X got_from = TRUE;
- X } else if (! got_subject && match_header (ptrline, "Subject", buf2, HEADER_LEN)) {
- X s = eat_re (buf2);
- X h->subject = hash_str (eat_re (s));
- X got_subject = TRUE;
- X } else if (! got_date && match_header (ptrline, "Date", buf2, HEADER_LEN)) {
- X parse_date (buf2, h->date);
- X got_date = TRUE;
- X } else if (match_header (ptrline, "Archive-name", buf2, HEADER_LEN) ||
- X match_header (ptrline, "Archive-Name", buf2, HEADER_LEN)) {
- X if ((s = (char *) strchr (buf2, '/')) != NULL) {
- X if (strncmp (s+1,"part",4) == 0 ||
- X strncmp (s+1,"Part",4) == 0) {
- X h->part = str_dup (s+5);
- X len = (int) strlen (h->part);
- X if (h->part[len-1] == '\n') {
- X h->part[len-1] = '\0';
- X }
- X } else {
- X if (strncmp (s+1,"patch",5) == 0 ||
- X strncmp (s+1,"Patch",5) == 0) {
- X h->patch = str_dup (s+6);
- X len = (int) strlen (h->patch);
- X if (h->patch[len-1] == '\n') {
- X h->patch[len-1] = '\0';
- X }
- X }
- X }
- X if (h->part || h->patch) {
- X s = buf2;
- X while (*s && *s != '/')
- X s++;
- X *s = '\0';
- X s = buf2;
- X h->archive = hash_str (s);
- X got_archive = TRUE;
- X }
- X }
- X }
- X
- X if (! flag || lineno > 25 || got_archive) {
- X debug_print_header (h);
- X return TRUE;
- X }
- X }
- X /* NOTREACHED */
- }
- X
- /*
- X * Write out an index file. Write the group name first so if
- X * local indexing is done we can disambiguate between group name
- X * hash collisions by looking at the index file.
- X */
- X
- void dump_index_file (group, killed)
- X char *group;
- X int killed;
- {
- X char nam[LEN];
- X FILE *fp;
- X int *iptr;
- X int realnum;
- X register int i;
- X
- X sprintf (nam, "%s.%d", index_file, process_id);
- X if ((fp = fopen (nam, "w")) == NULL) {
- X error_message (txt_cannot_open, nam);
- X return;
- X }
- X
- X /*
- X * dump group header info.
- X */
- X if (sort_art_type != SORT_BY_NOTHING) {
- X qsort ((char *) arts, top, sizeof (struct article_t), artnum_comp);
- X }
- X fprintf (fp, "%s\n", group);
- X fprintf (fp, "%d\n", num_of_arts ());
- X if (top <= 0) {
- X fprintf (fp, "0\n");
- X } else {
- X if (last_read_article > arts[top-1].artnum) {
- X fprintf (fp, "%ld\n", last_read_article);
- X } else {
- X fprintf (fp, "%ld\n", arts[top-1].artnum);
- X }
- X }
- X if (index_file_killed && killed) {
- X fprintf (fp, "KILLED\n");
- X } else {
- X fprintf (fp, "COMPLETE\n");
- X }
- X
- X /*
- X * dump articles
- X */
- X realnum = 0;
- X for (i = 0; i < top; i++) {
- X if (arts[i].thread != ART_EXPIRED && arts[i].killed == FALSE) {
- X debug_print_header (&arts[i]);
- X
- X fprintf(fp, "%ld\n", arts[i].artnum);
- X
- X iptr = (int *) arts[i].subject;
- X iptr--;
- X
- X if (! arts[i].subject) {
- X fprintf(fp, " \n");
- X } else if (*iptr < 0 || *iptr > top) {
- X fprintf(fp, " %s\n", arts[i].subject);
- X *iptr = realnum;
- X } else if (killed || *iptr == i) {
- X fprintf(fp, " %s\n", arts[i].subject);
- X } else {
- X fprintf(fp, "%%%d\n", *iptr);
- X }
- X
- X iptr = (int *) arts[i].from;
- X iptr--;
- X
- X if (! arts[i].from) {
- X fprintf (fp, " \n");
- X } else if (*iptr < 0 || *iptr > top) {
- X fprintf (fp, " %s\n", arts[i].from);
- X *iptr = realnum;
- X } else if (killed || *iptr == i) {
- X fprintf(fp, " %s\n", arts[i].from);
- X } else {
- X fprintf(fp, "%%%d\n", *iptr);
- X }
- X
- X iptr = (int *) arts[i].name;
- X iptr--;
- X
- X if (! arts[i].name) {
- X fprintf (fp, " \n");
- X } else if (*iptr < 0 || *iptr > top) {
- X fprintf (fp, " %s\n", arts[i].name);
- X *iptr = realnum;
- X } else if (killed || *iptr == i) {
- X fprintf(fp, " %s\n", arts[i].name);
- X } else {
- X fprintf(fp, "%%%d\n", *iptr);
- X }
- X
- X fprintf (fp, "%s\n", arts[i].date);
- X
- X iptr = (int *) arts[i].archive;
- X iptr--;
- X
- X if (! arts[i].archive) {
- X fprintf (fp, "\n");
- X } else if (*iptr < 0 || *iptr > top) {
- X fprintf (fp, " %s\n", arts[i].archive);
- X *iptr = realnum;
- X } else if (arts[i].part || arts[i].patch) {
- X if (killed || *iptr == i) {
- X fprintf(fp, " %s\n", arts[i].archive);
- X } else {
- X fprintf (fp, "%%%d\n", *iptr);
- X }
- X } else {
- X fprintf (fp, "\n");
- X }
- X
- X if (! arts[i].part) {
- X fprintf (fp, " \n");
- X } else {
- X fprintf (fp, "%s\n", arts[i].part);
- X }
- X
- X if (! arts[i].patch) {
- X fprintf (fp, " \n");
- X } else {
- X fprintf (fp, "%s\n", arts[i].patch);
- X }
- X
- X realnum++;
- X }
- X }
- X fclose (fp);
- X chmod (index_file, 0644);
- X rename_file (nam, index_file);
- X if (debug == 2) {
- X sprintf (msg, "cp %s INDEX", index_file);
- X system (msg);
- X }
- }
- X
- /*
- X * Read in an index file.
- X *
- X * index file header
- X * 1. newsgroup name (ie. alt.sources)
- X * 2. number of articles (ie. 26)
- X * 3. number of last read article (ie. 210)
- X * 4. Is this a complete/killed index file (ie. COMPLETE/KILLED)
- X *
- X * index file record
- X * 1. article number (ie. 183) [mandatory]
- X * 2. Subject: line (ie. Which newsreader?) [mandatory]
- X * 3. From: line (addr) (ie. iain@norisc) [mandatory]
- X * 4. From: line (name) (ie. Iain Lea) [mandatory]
- X * 5. Date: of posting (ie. 911231125959) [mandatory]
- X * 6. Archive: name (ie. compiler) [optional]
- X * 7. Part number of Archive: name (ie. 01) [optional]
- X * 8. Patch number of Archive: name (ie. 01) [optional]
- X */
- X
- int load_index_file (group_name)
- X char *group_name;
- {
- X int error = 0;
- X int i, n;
- X char buf[LEN], *p;
- X FILE *fp;
- X
- X top = 0;
- X last_read_article = 0L;
- X
- X if ((fp = open_index_fp (group_name)) == NULL) {
- X return FALSE;
- X }
- X
- X /*
- X * load header - discard group name, num. of arts in index file after any arts were killed
- X */
- X if (fgets(buf, sizeof buf, fp) == NULL ||
- X fgets(buf, sizeof buf, fp) == NULL) {
- X error = 0;
- X goto corrupt_index;
- X }
- X i = atoi (buf);
- X
- X /*
- X * num. of last_read_article including any that were killed
- X */
- X if (fgets(buf, sizeof buf, fp) == NULL) {
- X error = 1;
- X goto corrupt_index;
- X }
- X last_read_article = (long) atol (buf);
- X
- X /*
- X * is index file complete or were articles killed when it was dumped
- X */
- X if (fgets(buf, sizeof buf, fp) == NULL) {
- X error = 2;
- X goto corrupt_index;
- X }
- X index_file_killed = (buf[0] == 'K' ? TRUE : FALSE);
- X
- X /*
- X * load articles
- X */
- X for (; top < i ; top++) {
- X if (top >= max_art) {
- X expand_art ();
- X }
- X
- X arts[top].thread = ART_EXPIRED;
- X set_article (&arts[top]);
- X
- X /*
- X * Article no.
- X */
- X if (fgets(buf, sizeof buf, fp) == NULL) {
- X error = 3;
- X goto corrupt_index;
- X }
- X arts[top].artnum = (long) atol (buf);
- X
- X /*
- X * Subject:
- X */
- X if (fgets(buf, sizeof buf, fp) == NULL) {
- X error = 4;
- X goto corrupt_index;
- X }
- X
- X if (buf[0] == '%') {
- X n = atoi (&buf[1]);
- X if (n >= top || n < 0) {
- X error = 5;
- X goto corrupt_index;
- X }
- X arts[top].subject = arts[n].subject;
- X } else if (buf[0] == ' ') {
- X for (p = &buf[1]; *p && *p != '\n'; p++)
- X continue;
- X *p = '\0';
- X arts[top].subject = hash_str (&buf[1]);
- X } else {
- X error = 6;
- X goto corrupt_index;
- X }
- X
- X /*
- X * From: (addr part)
- X */
- X if (fgets(buf, sizeof buf, fp) == NULL) {
- X error = 7;
- X goto corrupt_index;
- X }
- X
- X if (buf[0] == '%') {
- X n = atoi (&buf[1]);
- X if (n >= top || n < 0) {
- X error = 8;
- X goto corrupt_index;
- X }
- X arts[top].from = arts[n].from;
- X } else if (buf[0] == ' ') {
- X for (p = &buf[1]; *p && *p != '\n'; p++)
- X continue;
- X *p = '\0';
- X arts[top].from = hash_str (&buf[1]);
- X } else {
- X error = 9;
- X goto corrupt_index;
- X }
- X
- X /*
- X * From: (full name)
- X */
- X if (fgets(buf, sizeof buf, fp) == NULL) {
- X error = 10;
- X goto corrupt_index;
- X }
- X
- X if (buf[0] == '%') {
- X n = atoi (&buf[1]);
- X if (n > top || n < 0) {
- X error = 11;
- X goto corrupt_index;
- X }
- X if (n == top) { /* no full name so .name = .from */
- X arts[top].name = arts[top].from;
- X } else {
- X arts[top].name = arts[n].name;
- X }
- X } else if (buf[0] == ' ') {
- X for (p = &buf[1]; *p && *p != '\n'; p++)
- X continue;
- X *p = '\0';
- X arts[top].name = hash_str (&buf[1]);
- SHAR_EOF
- true || echo 'restore of art.c failed'
- fi
- echo 'End of tin1.1 part 3'
- echo 'File art.c is continued in part 4'
- echo 4 > _shar_seq_.tmp
- exit 0
-
- --
- NAME Iain Lea
- EMAIL iain%anl433.uucp@germany.eu.net
- SNAIL Siemens AG, ANL A433SZ, Gruendlacher Str. 248, 8510 Fuerth, Germany.
- PHONE +49-911-3089-407 (work) +49-911-331963 (home) +49-911-3089-290 (FAX)
- --
- Dr. med. dipl.-math Dieter Becker Tel.: (0 / +49) 6841 - 16 3046
- Medizinische Universitaets- und Poliklinik Fax.: (0 / +49) 6841 - 16 3369
- Innere Medizin III
- D - 6650 Homburg / Saar Email: becker@med-in.uni-sb.de
- exit 0 # Just in case...
-