home *** CD-ROM | disk | FTP | other *** search
- From: sob@lib.tmc.edu (Stan Barber)
- Newsgroups: alt.sources
- Subject: rrn/rn combo kit part 3 of 9
- Message-ID: <429@lib.tmc.edu>
- Date: 14 Jun 90 03:27:08 GMT
-
- #! /bin/sh
-
- # Make a new directory for the rn sources, cd to it, and run kits 1 thru 9
- # through sh. When all 9 kits have been run, read README.
-
- echo "This is rn kit 3 (of 9). If kit 3 is complete, the line"
- echo '"'"End of kit 3 (of 9)"'" will echo at the end.'
- echo ""
- export PATH || (echo "You didn't use sh, you clunch." ; kill $$)
- echo Extracting common.h
- cat >common.h <<'!STUFFY!FUNK!'
- /* $Header: common.h,v 4.3.2.13 90/05/08 22:05:37 sob Exp $
- *
- * $Log: common.h,v $
- * Revision 4.3.2.13 90/05/08 22:05:37 sob
- * Added quick startup (-q) flag.
- *
- * Revision 4.3.2.12 90/04/23 00:32:04 sob
- * More cleanup.
- *
- * Revision 4.3.2.11 90/04/14 19:37:07 sob
- * Added better support for the NeXT.
- *
- * Revision 4.3.2.10 90/04/06 20:54:12 sob
- * Corrected forward definition of fseek()
- *
- * Revision 4.3.2.9 90/03/17 21:19:04 sob
- * Removed the incorrect forward definition of sprintf().
- *
- * Revision 4.3.2.8 89/12/20 20:40:03 sob
- * Changed ACT_POS from short to long per suggestion from eps@cd.SFSU.EDU.
- *
- * Revision 4.3.2.7 89/12/08 22:43:12 sob
- * Corrected typo pointed out by weening@gang-of-four.stanford.edu
- *
- * Revision 4.3.2.6 89/11/28 01:57:31 sob
- * Added initlines_specified variable for use with SIGWINCH support.
- *
- * Revision 4.3.2.5 89/11/28 00:30:56 sob
- * Reversed the CANCELHEADER definitions.
- *
- * Revision 4.3.2.4 89/11/27 01:29:23 sob
- * Altered NNTP code per ideas suggested by Bela Lubkin
- * <filbo@gorn.santa-cruz.ca.us>
- *
- * Revision 4.3.2.3 89/11/26 19:32:06 sob
- * Increased the size of MAXRCLINE from 1000 to 1500
- * Increated HASHSIZ from 1103 to 1693
- *
- * Revision 4.3.2.2 89/11/07 23:18:49 sob
- * Repaired NEWSHEADER and CANCEL to work correctly with NNTP and INTERNET.
- *
- * Revision 4.3.2.1 89/11/06 00:12:33 sob
- * Added RRN support from NNTP 1.5
- *
- * Revision 4.3.1.4 86/10/31 15:46:09 lwall
- * Expanded maximum number of .newsrc lines for net reorganization.
- *
- * Revision 4.3.1.3 85/05/23 17:19:32 lwall
- * Now allows 'r' and 'f' on null articles.
- *
- * Revision 4.3.1.2 85/05/13 09:30:39 lwall
- * Added CUSTOMLINES option.
- *
- * Revision 4.3.1.1 85/05/10 11:32:04 lwall
- * Branch for patches.
- *
- * Revision 4.3 85/05/01 11:37:11 lwall
- * Baseline for release with 4.3bsd.
- *
- */
-
- #include "config.h" /* generated by installation script */
- #ifdef WHOAMI
- # include <whoami.h>
- #endif
-
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <ctype.h>
-
- #ifndef isalnum
- # define isalnum(c) (isalpha(c) || isdigit(c))
- #endif
-
- #include <errno.h>
- #include <signal.h>
- #ifdef IOCTL
- #include <sys/ioctl.h>
- #endif IOCTL
-
- #ifdef FCNTL
- # include <fcntl.h>
- #endif
-
- #ifdef TERMIO
- # include <termio.h>
- #else
- # include <sgtty.h>
- #endif
-
- #ifdef GETPWENT
- # include <pwd.h>
- #endif
-
- #define BITSPERBYTE 8
- #define LBUFLEN 512 /* line buffer length */
- /* (don't worry, .newsrc lines can exceed this) */
- #ifdef pdp11
- # define CBUFLEN 256 /* command buffer length */
- # define PUSHSIZE 128
- #else
- # define CBUFLEN 512 /* command buffer length */
- # define PUSHSIZE 256
- #endif
- #ifdef pdp11
- # define MAXFILENAME 128
- #else
- # define MAXFILENAME 512
- #endif
- #define LONGKEY 15 /* longest keyword: currently "posting-version" */
- #define FINISHCMD 0177
-
- /* some handy defs */
-
- #define bool char
- #define TRUE (1)
- #define FALSE (0)
- #define Null(t) ((t)0)
- #define Nullch Null(char *)
- #define Nullfp Null(FILE *)
-
- #define Ctl(ch) (ch & 037)
-
- #define strNE(s1,s2) (strcmp(s1,s2))
- #define strEQ(s1,s2) (!strcmp(s1,s2))
- #define strnNE(s1,s2,l) (strncmp(s1,s2,l))
- #define strnEQ(s1,s2,l) (!strncmp(s1,s2,l))
-
- /* Things we can figure out ourselves */
-
- #ifdef SIGTSTP
- # define BERKELEY /* include job control signals? */
- #endif
-
- #ifdef FIONREAD
- # define PENDING
- #else
- # ifdef O_NDELAY
- # define PENDING
- # endif
- #endif
-
- #ifdef EUNICE
- # define LINKART /* add 1 level of possible indirection */
- # define UNLINK(victim) while (!unlink(victim))
- #else
- # define UNLINK(victim) unlink(victim)
- #endif
-
- /* Valid substitutions for strings marked with % comment are:
- * %a Current article number
- * %A Full name of current article (%P/%c/%a)
- * (if LINKART defined, is the name of the real article)
- * %b Destination of a save command, a mailbox or command
- * %B The byte offset to the beginning of the article for saves
- * with or without the header
- * %c Current newsgroup, directory form
- * %C Current newsgroup, dot form
- * %d %P/%c
- * %D Old Distribution: line
- * %f Old From: line or Reply-To: line
- * %F Newsgroups to followup to from Newsgroups: and Followup-To:
- * %h Name of header file to pass to mail or news poster
- * %H Host name (yours)
- * %i Old Message-I.D.: line, with <>
- * %I Inclusion indicator
- * %l News administrator login name
- * %L Login name (yours)
- * %M Number of articles markd with M
- * %n Newsgroups from source article
- * %N Full name (yours)
- * %o Organization (yours)
- * %O Original working directory (where you ran rn from)
- * %p Your private news directory (-d switch)
- * %P Public news spool directory (SPOOLDIR)
- * %r Last reference (parent article id)
- * %R New references list
- * %s Subject, with all Re's and (nf)'s stripped off
- * %S Subject, with one Re stripped off
- * %t New To: line derived from From: and Reply-To (Internet always)
- * %T New To: line derived from Path:
- * %u Number of unread articles
- * %U Number of unread articles disregarding current article
- * %x News library directory, usually /usr/lib/news
- * %X Rn library directory, usually %x/rn
- * %z Size of current article in bytes.
- * %~ Home directory
- * %. Directory containing . files
- * %$ current process number
- * %{name} Environment variable "name". %{name-default} form allowed.
- * %[name] Header line beginning with "Name: ", without "Name: "
- * %"prompt"
- * Print prompt and insert what is typed.
- * %`command`
- * Insert output of command.
- * %(test_text=pattern?if_text:else_text)
- * Substitute if_text if test_text matches pattern, otherwise
- * substitute else_text. Use != for negated match.
- * % substitutions are done on test_text, if_text, and else_text.
- * (Note: %() only works if CONDSUB defined.)
- * %digit Substitute the text matched by the nth bracket in the last
- * pattern that had brackets. %0 matches the last bracket
- * matched, in case you had alternatives.
- *
- * Put ^ in the middle to capitalize the first letter: %^C = Net.jokes
- * Put _ in the middle to capitalize last component: %_c = net/Jokes
- *
- * ~ interpretation in filename expansion happens after % expansion, so
- * you could put ~%{NEWSLOGNAME-news} and it will expand correctly.
- */
-
- /* *** System Dependent Stuff *** */
-
- /* NOTE: many of these are defined in the config.h file */
-
- /* name of organization */
- #ifndef ORGNAME
- # define ORGNAME "ACME Widget Company, Widget Falls, Southern North Dakota"
- #endif
-
- #ifndef MBOXCHAR
- # define MBOXCHAR 'F' /* how to recognize a mailbox by 1st char */
- #endif
-
- #ifndef ROOTID
- # define ROOTID 0 /* uid of superuser */
- #endif
-
- #ifdef NORMSIG
- # define sigset signal
- # define sigignore(sig) signal(sig,SIG_IGN)
- #endif
-
- #ifndef LOGDIRFIELD
- # define LOGDIRFIELD 6 /* Which field (origin 1) is the */
- /* login directory in /etc/passwd? */
- /* (If it is not kept in passwd, */
- /* but getpwnam() returns it, */
- /* define the symbol GETPWENT) */
- #endif
- #ifndef GCOSFIELD
- # define GCOSFIELD 5
- #endif
-
- #ifndef NEGCHAR
- # define NEGCHAR '!'
- #endif
-
- /* Space conservation section */
-
- /* To save D space, cut down size of MAXRCLINE, NGMAX, VARYSIZE. */
- #define MAXRCLINE 1500 /* number of lines allowed in .newsrc */
- /* several parallel arrays affected. */
- /* (You can have more lines in the active file, */
- /* just not in the .newsrc) */
- #define HASHSIZ 1693 /* should be prime, and at least MAXRCLINE + 10% */
- #define NGMAX 100 /* number of newsgroups allowed on command line */
- /* undefine ONLY symbol to disable "only" feature */
- #define VARYSIZE 256 /* this makes a block 1024 bytes long in DECville */
- /* (used by virtual array routines) */
-
- /* Undefine any of the following features to save both I and D space */
- /* In general, earlier ones are easier to get along without */
- /* Pdp11's without split I and D may have to undefine them all */
- #define DEBUGGING /* include debugging code */
- #define CUSTOMLINES /* include code for HIDELINE and PAGESTOP */
- #define PUSHBACK /* macros and keymaps using pushback buffer */
- #define SPEEDOVERMEM /* use more memory to run faster */
- #define WORDERASE /* enable ^W to erase a word */
- #define MAILCALL /* check periodically for mail */
- #define CLEAREOL /* use clear to end-of-line instead of clear screen */
- #define NOFIREWORKS /* keep whole screen from flashing on certain */
- /* terminals such as older Televideos */
- #define VERIFY /* echo the command they just typed */
- #define HASHNG /* hash newsgroup lines for fast lookup-- */
- /* linear search used if not defined */
- #define CONDSUB /* allow %(cond?text:text) */
- #define BACKTICK /* allow %`command` */
- #define PROMPTTTY /* allow %"prompt" */
- #define ULSMARTS /* catch _^H in text and do underlining */
- #define TERMMOD /* allow terminal type modifier on switches */
- #define BAUDMOD /* allow baudrate modifier on switches */
- #define GETLOGIN /* use getlogin() routine as backup to environment */
- /* variables USER or LOGNAME */
- #define ORGFILE /* if organization begins with /, look up in file */
- #define TILDENAME /* allow ~logname expansion */
- #define SETENV /* allow command line environment variable setting */
- #define GETWD /* use our getwd() instead of piped in pwd */
- #define MAKEDIR /* use our makedir() instead of shell script */
- #define MEMHELP /* keep help messages in memory */
- #define VERBOSE /* compile in more informative messages */
- #define TERSE /* compile in shorter messages */
- /* (Note: both VERBOSE and TERSE can be defined; -t
- * sets terse mode. One or the other MUST be defined.
- */
- #ifndef pdp11
- # define CACHESUBJ /* cache subject lines in memory */
- /* without this ^N still works but runs really slow */
- /* but you save lots and lots of D space */
- # define CACHEFIRST /* keep absolute first article numbers in memory */
- /* cost: about 2k */
- #endif
- #define ROTATION /* enable x, X and ^X commands to work */
- #define DELBOGUS /* ask if bogus newsgroups should be deleted */
- #define RELOCATE /* allow newsgroup rearranging */
- #define ESCSUBS /* escape substitutions in multi-character commands */
- #define DELAYMARK /* allow articles to be temporarily marked as read */
- /* until exit from current newsgroup or Y command */
- #define MCHASE /* unmark xrefed articles on m or M */
- #define MUNGHEADER /* allow alternate header formatting via */
- /* environment variable ALTHEADER (not impl) */
- #define ASYNC_PARSE /* allow parsing headers asyncronously to reading */
- /* used by MCHASE and MUNGHEADER */
- #define FINDNEWNG /* check for new newsgroups on startup */
- #define FASTNEW /* do optimizations on FINDNEWNG for faster startup */
- /* (this optimization can make occasional mistakes */
- /* if a group is removed and another group of the */
- /* same length is added, and if no softpointers are */
- /* affected by said change.) */
- #define INNERSEARCH /* search command 'g' with article */
- #define CATCHUP /* catchup command at newsgroup level */
- #define NGSEARCH /* newsgroup pattern matching */
- #define ONLY /* newsgroup restrictions by pattern */
- #define KILLFILES /* automatic article killer files */
- #define ARTSEARCH /* pattern searches among articles */
- /* /, ?, ^N, ^P, k, K */
-
- /* some dependencies among options */
-
- #ifndef ARTSEARCH
- # undef KILLFILES
- # undef INNERSEARCH
- # undef CACHESUBJ
- #endif
-
- #ifndef DELAYMARK
- # ifndef MCHASE
- # ifndef MUNGHEADER
- # undef ASYNC_PARSE
- # endif
- # endif
- #endif
-
- #ifndef SETUIDGID
- # define eaccess access
- #endif
-
- #ifdef ONLY /* idiot lint doesn't grok #if */
- # define NGSORONLY
- #else
- # ifdef NGSEARCH
- # define NGSORONLY
- # endif
- #endif
-
- #ifdef VERBOSE
- # ifdef TERSE
- # define IF(c) if (c)
- # define ELSE else
- # else !TERSE
- # define IF(c)
- # define ELSE
- # endif
- #else !VERBOSE
- # ifndef TERSE
- # define TERSE
- # endif
- # define IF(c) "IF" outside of VERBOSE???
- # define ELSE "ELSE" outside of VERBOSE???
- #endif
-
- #ifdef DEBUGGING
- # define assert(ex) {if (!(ex)){fprintf(stderr,"Assertion failed: file %s, line %d\n", __FILE__, __LINE__);sig_catcher(0);}}
- #else
- # define assert(ex) ;
- #endif
-
- #ifdef SPEEDOVERMEM
- # define OFFSET(x) (x)
- #else
- # define OFFSET(x) ((x)-absfirst)
- #endif
-
- /* If you're strapped for space use the help messages in shell scripts */
- /* if {NG,ART,PAGER,SUBS}HELP is undefined, help messages are in memory */
- #ifdef MEMHELP /* undef MEMHELP above to get them all as sh scripts */
- # undef NGHELP
- # undef ARTHELP
- # undef PAGERHELP
- # undef SUBSHELP
- #else
- # ifndef NGHELP /* % and ~ */
- # define NGHELP "%X/ng.help"
- # endif
- # ifndef ARTHELP /* % and ~ */
- # define ARTHELP "%X/art.help"
- # endif
- # ifndef PAGERHELP /* % and ~ */
- # define PAGERHELP "%X/pager.help"
- # endif
- # ifndef SUBSHELP /* % and ~ */
- # define SUBSHELP "%X/subs.help"
- # endif
- #endif
-
- #ifdef CLEAREOL
- # define TCSIZE 512 /* capacity for termcap strings */
- #else
- # ifdef pdp11
- # define TCSIZE 256 /* capacity for termcap strings */
- # else
- # define TCSIZE 512 /* capacity for termcap srings */
- # endif
- #endif
-
- /* Additional ideas:
- * Make the do_newsgroup() routine a separate process.
- * Keep .newsrc on disk instead of in memory.
- * Overlays, if you have them.
- * Get a bigger machine.
- */
-
- /* End of Space Conservation Section */
-
- /* More System Dependencies */
-
- /* news library */
- #ifndef LIB /* ~ and %l only ("~%l" is permissable) */
- # define LIB "/usr/lib/news"
- #endif
-
- /* path to private executables */
- #ifndef RNLIB /* ~, %x and %l only */
- # define RNLIB "%x/rn"
- #endif
-
- /* system-wide RNINIT switches */
- #ifndef GLOBINIT
- # define GLOBINIT "%X/INIT"
- #endif
-
- /* where to find news files */
- #ifndef SPOOL /* % and ~ */
- # define SPOOL "/usr/spool/news"
- #endif
-
- /* file containing list of active newsgroups and max article numbers */
- #ifndef ACTIVE /* % and ~ */
- # define ACTIVE "%x/active"
- #endif
-
- /* location of history file */
- #ifndef ARTFILE /* % and ~ */
- # define ARTFILE "%x/history"
- #endif
-
- /* command to setup a new .newsrc */
- #ifndef NEWSETUP /* % and ~ */
- # define NEWSETUP "newsetup"
- #endif
-
- /* command to display a list of un-subscribed-to newsgroups */
- #ifndef NEWSGROUPS /* % and ~ */
- # define NEWSGROUPS "newsgroups"
- #endif
-
- /* preferred shell for use in doshell routine */
- /* ksh or sh would be okay here */
- #ifndef PREFSHELL
- # define PREFSHELL "/bin/csh"
- #endif
-
- /* path to fastest starting shell */
- #ifndef SH
- # define SH "/bin/sh"
- #endif
-
- /* path to default editor */
- #ifndef DEFEDITOR
- # define DEFEDITOR "/usr/ucb/vi"
- #endif
-
- /* location of macro file */
- #ifndef RNMACRO
- # ifdef PUSHBACK
- # define RNMACRO "%./.rnmac"
- # endif
- #endif
-
- /* location of full name */
- #ifndef FULLNAMEFILE
- # ifndef PASSNAMES
- # define FULLNAMEFILE "%./.fullname"
- # endif
- #endif
-
- /* virtual array file name template */
- #ifndef VARYNAME /* % and ~ */
- # define VARYNAME "/tmp/rnvary.%$"
- #endif
-
- /* file to pass header to followup article poster */
- #ifndef HEADNAME /* % and ~ */
- # define HEADNAME "%./.rnhead"
- /* or alternately #define HEADNAME "/tmp/rnhead.%$" */
- #endif
-
- #ifndef MAKEDIR
- /* shell script to make n-deep subdirectories */
- # ifndef DIRMAKER /* % and ~ */
- # define DIRMAKER "%X/makedir"
- # endif
- #endif
-
- /* location of newsrc file */
- #ifndef RCNAME /* % and ~ */
- # define RCNAME "%./.newsrc"
- #endif
-
- /* temporary newsrc file in case we crash while writing out */
- #ifndef RCTNAME /* % and ~ */
- # define RCTNAME "%./.newnewsrc"
- #endif
-
- /* newsrc file at the beginning of this session */
- #ifndef RCBNAME /* % and ~ */
- # define RCBNAME "%./.oldnewsrc"
- #endif
-
- /* if existent, contains process number of current or crashed rn */
- #ifndef LOCKNAME /* % and ~ */
- # define LOCKNAME "%./.rnlock"
- #endif
-
- /* information from last invocation of rn */
- #ifndef LASTNAME /* % and ~ */
- # define LASTNAME "%./.rnlast"
- #endif
-
- /* file with soft pointers into the active file */
- #ifndef SOFTNAME /* % and ~ */
- # define SOFTNAME "%./.rnsoft"
- #endif
-
- /* list of article numbers to mark as unread later (see M and Y cmmands) */
- #ifndef RNDELNAME /* % and ~ */
- # define RNDELNAME "%./.rndelay"
- #endif
-
- /* a motd-like file for rn */
- #ifndef NEWSNEWSNAME /* % and ~ */
- # define NEWSNEWSNAME "%X/newsnews"
- #endif
-
- /* command to send a reply */
- #ifndef MAILPOSTER /* % and ~ */
- # define MAILPOSTER "Rnmail -h %h"
- #endif
-
- #ifdef INTERNET
- # ifndef MAILHEADER /* % */
- # ifdef CONDSUB
- # define MAILHEADER "To: %t\nSubject: Re: %S\nNewsgroups: %n\nIn-Reply-To: %i\n%(%[references]!=^$?References\\: %[references]\n)Organization: %o\nCc: \nBcc: \n\n"
- # else
- # define MAILHEADER "To: %t\nSubject: Re: %S\nNewsgroups: %n\nIn-Reply-To: %i\nReferences: %[references]\nCc: \nBcc: \n\n"
- # endif
- # endif
- #else
- # ifndef MAILHEADER /* % */
- # ifdef CONDSUB
- # define MAILHEADER "To: %T\nSubject: %(%i=^$?:Re: %S\nNewsgroups: %n\nIn-Reply-To: %i)\n%(%[references]!=^$?References\\: %[references]\n)Organization: %o\nCc: \nBcc: \n\n"
- # else
- # define MAILHEADER "To: %T\nSubject: Re: %S\nNewsgroups: %n\nIn-Reply-To: %i\nReferences: %[references]\nCc: \nBcc: \n\n"
- # endif
- # endif
- #endif
-
- #ifndef YOUSAID /* % */
- # define YOUSAID "In article %i you write:"
- #endif
-
- /* command to submit a followup article */
- #ifndef NEWSPOSTER /* % and ~ */
- # define NEWSPOSTER "Pnews -h %h"
- #endif
-
- #ifndef NEWSHEADER /* % */
- # ifdef CONDSUB
- #ifdef INTERNET
- # define NEWSHEADER "Newsgroups: %(%F=^$?%C:%F)\nSubject: %(%S=^$?%\"\n\nSubject: \":Re: %S)\nSummary: \nExpires: \n%(%R=^$?:References: %R\n)Sender: \nFollowup-To: \nDistribution: %(%i=^$?%\"Distribution: \":%D)\nOrganization: %o\nKeywords: %[keywords]\n\n"
- #else
- # define NEWSHEADER "Newsgroups: %(%F=^$?%C:%F)\nSubject: %(%S=^$?%\"\n\nSubject: \":Re: %S)\nSummary: \nExpires: \n%(%R=^$?:References: %R\n)Sender: \nReply-To: %L@%H.UUCP (%N)\nFollowup-To: \nDistribution: %(%i=^$?%\"Distribution: \":%D)\nOrganization: %o\nKeywords: %[keywords]\n\n"
- #endif
- # else
- # ifdef INTERNET
- # define NEWSHEADER "Newsgroups: %F\nSubject: Re: %S\nSummary: \nExpires: \nReferences: %R\nSender: \nFollowup-To: \nDistribution: %D\nOrganization: %o\nKeywords: %[keywords]\n\n"
- # else
- # define NEWSHEADER "Newsgroups: %F\nSubject: Re: %S\nSummary: \nExpires: \nReferences: %R\nSender: \nReply-To:%L@%H.UUCP (%N)\nFollowup-To: \nDistribution: %D\nOrganization: %o\nKeywords: %[keywords]\n\n"
- # endif
- # endif
- #endif
-
- #ifndef ATTRIBUTION /* % */
- # define ATTRIBUTION "In article %i %f writes:"
- #endif
-
- #ifndef PIPESAVER /* % */
- # ifdef CONDSUB
- # ifdef SERVER
- # define PIPESAVER "%(%B=^0$?<%P/rrn%a.%$:tail +%Bc %P/rrn%a.%$ |) %b"
- # else
- # define PIPESAVER "%(%B=^0$?<%A:tail +%Bc %A |) %b"
- # endif
- # else
- # ifdef SERVER
- # define PIPESAVER "tail +%Bc %P/rrn%a.%$ | %b"
- # else
- # define PIPESAVER "tail +%Bc %A | %b"
- # endif
- # endif
- #endif
-
- #ifndef NORMSAVER /* % and ~ */
- # ifdef SERVER
- # define NORMSAVER "%X/norm.saver %P/rrn%a.%$ %P %c %a %B %C \"%b\""
- # else
- # define NORMSAVER "%X/norm.saver %A %P %c %a %B %C \"%b\""
- # endif
- #endif
-
- #ifndef MBOXSAVER /* % and ~ */
- # ifdef MININACT /* 2.10.2 site? */
- # ifdef SERVER
- # define MBOXSAVER "%X/mbox.saver %P/rrn%a.%$ %P %c %a %B %C \"%b\" \"From %T %`date`\""
- # else
- # define MBOXSAVER "%X/mbox.saver %A %P %c %a %B %C \"%b\" \"From %T %`date`\""
- # endif SERVER
- # else
- # ifdef CONDSUB
- # ifdef SERVER
- # define MBOXSAVER "%X/mbox.saver %P/rrn%a.%$ %P %c %a %B %C \"%b\
- " \"From %T %(%[date]=^\\(\\w*\\), \\(\\w*\\)-\\(\\w*\\)-\\(\\w*\\) \\([^ ]*\\)?
- %1 %3 %(%2=..?%2: %2) %5 19%4)\""
- # else
- # define MBOXSAVER "%X/mbox.saver %A %P %c %a %B %C \"%b\" \"From %T %(%[date]=^\\(\\w*\\), \\(\\w*\\)-\\(\\w*\\)-\\(\\w*\\) \\([^ ]*\\)?%1 %3 %(%2=..?%2: %2) %5 19%4)\""
- # endif
- /* header munging with a vengeance */
- # else
- # ifdef SERVER
- # define MBOXSAVER "%X/mbox.saver %P/rrn%a.%$ %P %c %a %B %C \"%b\" \"From %T %[posted]\""
- # else
- # define MBOXSAVER "%X/mbox.saver %A %P %c %a %B %C \"%b\" \"From %T %[posted]\""
- # endif
- # endif
- # endif
- #endif
-
- #ifdef MKDIRS
-
- # ifndef SAVEDIR /* % and ~ */
- # define SAVEDIR "%p/%c"
- # endif
- # ifndef SAVENAME /* % */
- # define SAVENAME "%a"
- # endif
-
- #else
-
- # ifndef SAVEDIR /* % and ~ */
- # define SAVEDIR "%p"
- # endif
- # ifndef SAVENAME /* % */
- # define SAVENAME "%^C"
- # endif
-
- #endif
-
- #ifndef KILLGLOBAL /* % and ~ */
- # define KILLGLOBAL "%p/KILL"
- #endif
-
- #ifndef KILLLOCAL /* % and ~ */
- # define KILLLOCAL "%p/%c/KILL"
- #endif
-
- /* how to cancel an article */
- #ifndef CANCEL
- # ifdef MININACT /* 2.10.2 ? */
- # define CANCEL "%x/inews -h < %h"
- # else
- # define CANCEL "inews -h < %h"
- # endif
- #endif
-
- /* how to cancel an article, continued */
- #ifndef CANCELHEADER
- #ifdef INTERNET
- # define CANCELHEADER "Newsgroups: %n\nSubject: cmsg cancel %i\nReferences: %R\nDistribution: %D\nOrganization: %o\n\nThis message was cancelled from within rn.\n"
- #else
- # define CANCELHEADER "Newsgroups: %n\nSubject: cmsg cancel %i\nReferences: %R\nReply-To: %L@%H.UUCP (%N)\nDistribution: %D\nOrganization: %o\n"
- #endif
- #endif
-
- /* where to find the mail file */
- #ifndef MAILFILE
- # define MAILFILE "/usr/spool/mail/%L"
- #endif
-
- /* some important types */
-
- typedef int NG_NUM; /* newsgroup number */
- typedef long ART_NUM; /* article number */
- #ifdef pdp11
- typedef short ART_UNREAD; /* ordinarily this should be long */
- /* like ART_NUM, but assuming that */
- /* we stay less than 32767 articles */
- /* behind saves a lot of space. */
- /* NOTE: do not make unsigned. */
- #else
- typedef long ART_UNREAD;
- #endif
- #ifdef SERVER
- typedef int ART_PART; /* for passing to nntpopen() */
- #endif
- typedef long ART_POS; /* char position in article file */
- typedef int ART_LINE; /* line position in article file */
- typedef long ACT_POS; /* char position in active file */
- typedef unsigned int MEM_SIZE; /* for passing to malloc */
-
-
- /* *** end of the machine dependent stuff *** */
-
- /* GLOBAL THINGS */
-
- /* file statistics area */
-
- EXT struct stat filestat;
-
- /* various things of type char */
-
- char *index();
- char *rindex();
- char *getenv();
- char *strcat();
- char *strcpy();
-
- EXT char buf[LBUFLEN+1]; /* general purpose line buffer */
- EXT char cmd_buf[CBUFLEN]; /* buffer for formatting system commands */
-
- EXT char *indstr INIT(">"); /* indent for old article embedded in followup */
-
- EXT char *cwd INIT(Nullch); /* current working directory */
- EXT char *dfltcmd INIT(Nullch); /* 1st char is default command */
-
- /* switches */
-
- #ifdef DEBUGGING
- EXT int debug INIT(0); /* -D */
- # define DEB_INNERSRCH 32
- # define DEB_FILEXP 64
- # define DEB_HASH 128
- # define DEB_XREF_MARKER 256
- # define DEB_CTLAREA_BITMAP 512
- # define DEB_SOFT_POINTERS 1024
- # define DEB_NEWSRC_LINE 2048
- # define DEB_SEARCH_AHEAD 4096
- # define DEB_CHECKPOINTING 8192
- # define DEB_FEED_XREF 16384
- #endif
-
- #ifdef ARTSEARCH
- EXT int scanon INIT(0); /* -S */
- #endif
-
- EXT bool mbox_always INIT(FALSE); /* -M */
- EXT bool norm_always INIT(FALSE); /* -N */
- EXT bool checkflag INIT(FALSE); /* -c */
- EXT bool suppress_cn INIT(FALSE); /* -s */
- EXT int countdown INIT(5); /* how many lines to list before invoking -s */
- EXT bool muck_up_clear INIT(FALSE); /* -loco */
- EXT bool erase_screen INIT(FALSE); /* -e */
- #ifdef CLEAREOL
- EXT bool can_home_clear INIT(FALSE); /* fancy -e -- PWP */
- #endif CLEAREOL
- EXT bool findlast INIT(FALSE); /* -r */
- EXT bool typeahead INIT(FALSE); /* -T */
- #ifdef VERBOSE
- # ifdef TERSE
- EXT bool verbose INIT(TRUE); /* +t */
- # endif
- #endif
- #ifdef VERIFY
- EXT bool verify INIT(FALSE); /* -v */
- #endif
- EXT bool quickstart INIT(FALSE); /* -q */
-
- #define NOMARKING 0
- #define STANDOUT 1
- #define UNDERLINE 2
- EXT int marking INIT(NOMARKING); /* -m */
-
- EXT ART_LINE initlines INIT(0); /* -i */
- EXT bool initlines_specified INIT(FALSE);
-
- /* miscellania */
-
- int fseek();
- long atol(), ftell();
- EXT bool in_ng INIT(FALSE); /* current state of rn */
- EXT char mode INIT('i'); /* current state of rn */
-
- EXT FILE *tmpfp INIT(Nullfp); /* scratch fp used for .rnlock, .rnlast, etc. */
-
- EXT NG_NUM nextrcline INIT(0); /* 1st unused slot in rcline array */
- /* startup to avoid checking twice in a row */
-
- extern errno;
-
- /* Factored strings */
-
- EXT char nullstr[] INIT("");
- EXT char sh[] INIT(SH);
- EXT char defeditor[] INIT(DEFEDITOR);
- EXT char hforhelp[] INIT("Type h for help.\n");
- #ifdef STRICTCR
- EXT char badcr[] INIT("\nUnnecessary CR ignored.\n");
- #endif
- EXT char readerr[] INIT("rn read error");
- EXT char unsubto[] INIT("\n\nUnsubscribed to newsgroup %s\n");
- EXT char cantopen[] INIT("Can't open %s\n");
- EXT char cantcreate[] INIT("Can't create %s\n");
-
- #ifdef VERBOSE
- EXT char nocd[] INIT("Can't chdir to directory %s\n");
- #else
- EXT char nocd[] INIT("Can't find %s\n");
- #endif
-
- #ifdef NOLINEBUF
- #define FLUSH ,fflush(stdout)
- #else
- #define FLUSH
- #endif
-
- #ifdef lint
- #undef FLUSH
- #define FLUSH
- #undef putchar
- #define putchar(c)
- #endif
- !STUFFY!FUNK!
- echo Extracting ng.c
- cat >ng.c <<'!STUFFY!FUNK!'
- /* $Header: ng.c,v 4.3.2.7 90/04/21 14:44:23 sob Exp $
- *
- * $Log: ng.c,v $
- * Revision 4.3.2.7 90/04/21 14:44:23 sob
- * Revised previous patch insure that it does not decrement below zero.
- *
- * Revision 4.3.2.6 90/03/22 23:04:49 sob
- * Fixes provided by Wayne Davison <drivax!davison>
- *
- * Revision 4.3.2.5 89/12/09 01:18:42 sob
- * Fixed a bad call to nntpopen().
- *
- * Revision 4.3.2.4 89/11/28 01:51:20 sob
- * Removed redundant #include directive.
- *
- * Revision 4.3.2.3 89/11/27 01:31:03 sob
- * Altered NNTP code per ideas suggested by Bela Lubkin
- * <filbo@gorn.santa-cruz.ca.us>
- *
- * Revision 4.3.2.2 89/11/26 22:53:35 sob
- * Add new patches to make RRN be faster.
- *
- * Revision 4.3.2.1 89/11/06 00:54:27 sob
- * Added RRN support from NNTP 1.5
- *
- * Revision 4.3.1.6 85/09/10 11:03:42 lwall
- * Improved %m in in_char().
- *
- * Revision 4.3.1.5 85/09/05 12:34:37 lwall
- * Catchup command could make unread article count too big.
- *
- * Revision 4.3.1.4 85/07/23 18:19:46 lwall
- * Added MAILCALL environment variable.
- *
- * Revision 4.3.1.3 85/05/16 16:48:09 lwall
- * Fixed unsubsubscribe.
- *
- * Revision 4.3.1.2 85/05/13 09:29:28 lwall
- * Added CUSTOMLINES option.
- *
- * Revision 4.3.1.1 85/05/10 11:36:00 lwall
- * Branch for patches.
- *
- * Revision 4.3 85/05/01 11:43:43 lwall
- * Baseline for release with 4.3bsd.
- *
- */
-
- #include "EXTERN.h"
- #include "common.h"
- #include "rn.h"
- #include "term.h"
- #include "final.h"
- #include "util.h"
- #include "artsrch.h"
- #include "cheat.h"
- #include "help.h"
- #include "kfile.h"
- #include "rcstuff.h"
- #include "head.h"
- #include "bits.h"
- #include "art.h"
- #include "artio.h"
- #include "ngstuff.h"
- #include "intrp.h"
- #include "respond.h"
- #include "ngdata.h"
- #include "backpage.h"
- #include "rcln.h"
- #include "last.h"
- #include "search.h"
- #ifdef SERVER
- #include "server.h"
- #endif
- #include "INTERN.h"
- #include "ng.h"
- #include "artstate.h" /* somebody has to do it */
-
- /* art_switch() return values */
-
- #define AS_NORM 0
- #define AS_INP 1
- #define AS_ASK 2
- #define AS_CLEAN 3
-
- ART_NUM recent_art = 0; /* previous article # for '-' command */
- ART_NUM curr_art = 0; /* current article # */
- int exit_code = NG_NORM;
-
- void
- ng_init()
- {
-
- #ifdef KILLFILES
- open_kfile(KF_GLOBAL);
- #endif
- #ifdef CUSTOMLINES
- init_compex(&hide_compex);
- init_compex(&page_compex);
- #endif
- }
-
- /* do newsgroup on line ng with name ngname */
-
- /* assumes that we are chdir'ed to SPOOL, and assures that that is
- * still true upon return, but chdirs to SPOOL/ngname in between
- *
- * If you can understand this routine, you understand most of the program.
- * The basic structure is:
- * for each desired article
- * for each desired page
- * for each line on page
- * if we need another line from file
- * get it
- * if it's a header line
- * do special things
- * for each column on page
- * put out a character
- * end loop
- * end loop
- * end loop
- * end loop
- *
- * (Actually, the pager is in another routine.)
- *
- * The chief problem is deciding what is meant by "desired". Most of
- * the messiness of this routine is due to the fact that people want
- * to do unstructured things all the time. I have used a few judicious
- * goto's where I thought it improved readability. The rest of the messiness
- * arises from trying to be both space and time efficient. Have fun.
- */
-
- int
- do_newsgroup(start_command)
- char *start_command; /* command to fake up first */
- {
- #ifdef SERVER
- char ser_line[256];
- char artname[32];
- static long our_pid;
- #endif SERVER
- char oldmode = mode;
- register long i; /* scratch */
- int skipstate; /* how many unavailable articles */
- /* have we skipped already? */
-
- char *whatnext = "%sWhat next? [%s]";
-
- #ifdef SERVER
- if (our_pid == 0) /* Agreed, this is gross */
- our_pid = getpid();
- #endif SERVER
-
- #ifdef ARTSEARCH
- srchahead = (scanon && ((ART_NUM)toread[ng]) >= scanon ? -1 : 0);
- /* did they say -S? */
- #endif
-
- mode = 'a';
- recent_art = curr_art = 0;
- exit_code = NG_NORM;
-
- #ifdef SERVER
- sprintf(ser_line, "GROUP %s", ngname);
- put_server(ser_line);
- if (get_server(ser_line, sizeof(ser_line)) < 0) {
- fprintf(stderr, "rrn: Unexpected close of server socket.\n");
- finalize(1);
- }
- if (*ser_line != CHAR_OK) {
- if (atoi(ser_line) != ERR_NOGROUP)
- fprintf(stderr, "rrn: server response to GROUP %s:\n%s\n",
- ngname, ser_line);
- return (-1);
- }
- #else not SERVER
- if (eaccess(ngdir,5)) { /* directory read protected? */
- if (eaccess(ngdir,0)) {
- #ifdef VERBOSE
- IF(verbose)
- printf("\nNewsgroup %s does not have a spool directory!\n",
- ngname) FLUSH;
- ELSE
- #endif
- #ifdef TERSE
- printf("\nNo spool for %s!\n",ngname) FLUSH;
- #endif
- #ifdef CATCHUP
- catch_up(ng);
- #endif
- toread[ng] = TR_NONE;
- }
- else {
- #ifdef VERBOSE
- IF(verbose)
- printf("\nNewsgroup %s is not currently accessible.\n",
- ngname) FLUSH;
- ELSE
- #endif
- #ifdef TERSE
- printf("\n%s not readable.\n",ngname) FLUSH;
- #endif
- toread[ng] = TR_NONE; /* make this newsgroup invisible */
- /* (temporarily) */
- }
- mode = oldmode;
- return -1;
- }
-
- /* chdir to newsgroup subdirectory */
-
- if (chdir(ngdir)) {
- printf(nocd,ngdir) FLUSH;
- mode = oldmode;
- return -1;
- }
- #endif SERVER
-
- #ifdef CACHESUBJ
- subj_list = Null(char **); /* no subject list till needed */
- #endif
-
- /* initialize control bitmap */
-
- if (initctl()) {
- mode = oldmode;
- return -1;
- }
-
- /* FROM HERE ON, RETURN THRU CLEANUP OR WE ARE SCREWED */
-
- in_ng = TRUE; /* tell the world we are here */
- forcelast = TRUE; /* if 0 unread, do not bomb out */
- art=firstart;
-
- /* remember what newsgroup we were in for sake of posterity */
-
- writelast();
-
- /* see if there are any special searches to do */
-
- #ifdef KILLFILES
- open_kfile(KF_LOCAL);
- #ifdef VERBOSE
- IF(verbose)
- kill_unwanted(firstart,"Looking for articles to kill...\n\n",TRUE);
- ELSE
- #endif
- #ifdef TERSE
- kill_unwanted(firstart,"Killing...\n\n",TRUE);
- #endif
- #endif
-
- /* do they want a special top line? */
-
- firstline = getval("FIRSTLINE",Nullch);
-
- /* custom line suppression, custom page ending */
-
- #ifdef CUSTOMLINES
- if (hideline = getval("HIDELINE",Nullch))
- compile(&hide_compex,hideline,TRUE,TRUE);
- if (pagestop = getval("PAGESTOP",Nullch))
- compile(&page_compex,pagestop,TRUE,TRUE);
- #endif
-
- /* now read each unread article */
-
- rc_changed = doing_ng = TRUE; /* enter the twilight zone */
- skipstate = 0; /* we have not skipped anything (yet) */
- checkcount = 0; /* do not checkpoint for a while */
- do_fseek = FALSE; /* start 1st article at top */
- if (art > lastart)
- art=firstart; /* init the for loop below */
- for (; art<=lastart+1; ) { /* for each article */
-
- /* do we need to "grow" the newsgroup? */
-
- if (art > lastart || forcegrow)
- grow_ctl();
- check_first(art); /* make sure firstart is still 1st */
- if (start_command) { /* fake up an initial command? */
- prompt = whatnext;
- strcpy(buf,start_command);
- free(start_command);
- start_command = Nullch;
- art = lastart+1;
- goto article_level;
- }
- if (art>lastart) { /* are we off the end still? */
- ART_NUM ucount = 0; /* count of unread articles left */
-
- for (i=firstart; i<=lastart; i++)
- if (!(ctl_read(i)))
- ucount++; /* count the unread articles */
- #ifdef DEBUGGING
- /*NOSTRICT*/
- if (debug && ((ART_NUM)toread[ng]) != ucount)
- printf("(toread=%ld sb %ld)",(long)toread[ng],(long)ucount)
- FLUSH;
- #endif
- /*NOSTRICT*/
- toread[ng] = (ART_UNREAD)ucount; /* this is perhaps pointless */
- art = lastart + 1; /* keep bitmap references sane */
- if (art != curr_art) {
- recent_art = curr_art;
- /* remember last article # (for '-') */
- curr_art = art; /* remember this article # */
- }
- if (erase_screen)
- clear(); /* clear the screen */
- else
- fputs("\n\n",stdout) FLUSH;
- #ifdef VERBOSE
- IF(verbose)
- printf("End of newsgroup %s.",ngname);
- /* print pseudo-article */
- ELSE
- #endif
- #ifdef TERSE
- printf("End of %s",ngname);
- #endif
- if (ucount) {
- printf(" (%ld article%s still unread)",
- (long)ucount,ucount==1?nullstr:"s");
- }
- else {
- if (!forcelast)
- goto cleanup; /* actually exit newsgroup */
- }
- prompt = whatnext;
- #ifdef ARTSEARCH
- srchahead = 0; /* no more subject search mode */
- #endif
- fputs("\n\n",stdout) FLUSH;
- skipstate = 0; /* back to none skipped */
- }
- else if (!reread && was_read(art)) {
- /* has this article been read? */
- art++; /* then skip it */
- continue;
- }
- else if
- (!reread && !was_read(art)
- #ifdef SERVER
- && nntpopen(art,HEAD) == Nullfp) {
- #else
- && artopen(art) == Nullfp) { /* never read it, & cannot find it? */
- if (errno != ENOENT) { /* has it not been deleted? */
- #ifdef VERBOSE
- IF(verbose)
- printf("\n(Article %ld exists but is unreadable.)\n",
- (long)art) FLUSH;
- ELSE
- #endif
- #ifdef TERSE
- printf("\n(%ld unreadable.)\n",(long)art) FLUSH;
- #endif
- skipstate = 0;
- sleep(2);
- }
- #endif
- switch(skipstate++) {
- case 0:
- clear();
- #ifdef VERBOSE
- IF(verbose)
- fputs("Skipping unavailable article",stdout);
- ELSE
- #endif
- #ifdef TERSE
- fputs("Skipping",stdout);
- #endif
- for (i = just_a_sec/3; i; --i)
- putchar(PC);
- fflush(stdout);
- sleep(1);
- break;
- case 1:
- fputs("..",stdout);
- fflush(stdout);
- break;
- default:
- putchar('.');
- fflush(stdout);
- #ifndef SERVER
- #define READDIR
- #ifdef READDIR
- { /* fast skip patch */
- ART_NUM newart;
-
- if (! (newart=getngmin(".",art)))
- newart = lastart+1;
- for (i=art; i<newart; i++)
- oneless(i);
- art = newart - 1;
- }
- #endif
- #else
- {
- char ser_line[256];
- ART_NUM newart;
-
- put_server("NEXT");
- if (get_server(ser_line, sizeof (ser_line)) < 0) {
- fprintf(stderr,
- "rrn: unexpected close of server socket.\n");
- finalize(1);
- }
- if (ser_line[0] != CHAR_OK)
- newart = lastart + 1;
- else
- newart = atoi(ser_line+4);
- for (i=art; i<newart; i++)
- oneless(i);
- art = newart - 1;
- }
- #endif SERVER
- break;
- }
- oneless(art); /* mark deleted as read */
- art++; /* try next article */
- continue;
- }
- else { /* we have a real live article */
- skipstate = 0; /* back to none skipped */
- if (art != curr_art) {
- recent_art = curr_art;
- /* remember last article # (for '-') */
- curr_art = art; /* remember this article # */
- }
- if (!do_fseek) { /* starting at top of article? */
- artline = 0; /* start at the beginning */
- topline = -1; /* and remember top line of screen */
- /* (line # within article file) */
- }
- clear(); /* clear screen */
- artopen(art); /* make sure article file is open */
- if (artfp == Nullfp) { /* could not find article? */
- printf("Article %ld of %s is not available.\n\n",
- (long)art,ngname) FLUSH;
- prompt = whatnext;
- #ifdef ARTSEARCH
- srchahead = 0;
- #endif
- }
- else { /* found it, so print it */
- switch (do_article()) {
- case DA_CLEAN: /* quit newsgroup */
- goto cleanup;
- case DA_TOEND: /* do not mark as read */
- goto reask_article;
- case DA_RAISE: /* reparse command at end of art */
- goto article_level;
- case DA_NORM: /* normal end of article */
- break;
- }
- }
- mark_as_read(art); /* mark current article as read */
- reread = FALSE;
- do_hiding = TRUE;
- #ifdef ROTATION
- rotate = FALSE;
- #endif
- }
-
- /* if these gotos bother you, think of this as a little state machine */
-
- reask_article:
- #ifdef MAILCALL
- setmail();
- #endif
- setdfltcmd();
- #ifdef CLEAREOL
- if (erase_screen && can_home_clear)
- clear_rest();
- #endif CLEAREOL
- unflush_output(); /* disable any ^O in effect */
- standout(); /* enter standout mode */
- printf(prompt,mailcall,dfltcmd);/* print prompt, whatever it is */
- un_standout(); /* leave standout mode */
- putchar(' ');
- fflush(stdout);
- reinp_article:
- eat_typeahead();
- #ifdef PENDING
- look_ahead(); /* see what we can do in advance */
- if (!input_pending())
- collect_subjects(); /* loads subject cache until */
- /* input is pending */
- #endif
- getcmd(buf);
- if (errno || *buf == '\f') {
- if (LINES < 100 && !int_count)
- *buf = '\f'; /* on CONT fake up refresh */
- else {
- putchar('\n') FLUSH; /* but only on a crt */
- goto reask_article;
- }
- }
- article_level:
-
- /* parse and process article level command */
-
- switch (art_switch()) {
- case AS_INP: /* multichar command rubbed out */
- goto reinp_article;
- case AS_ASK: /* reprompt "End of article..." */
- goto reask_article;
- case AS_CLEAN: /* exit newsgroup */
- goto cleanup;
- case AS_NORM: /* display article art */
- break;
- }
- } /* end of article selection loop */
-
- /* shut down newsgroup */
-
- cleanup:
- #ifdef KILLFILES
- kill_unwanted(firstart,"\nCleaning up...\n\n",FALSE);
- /* do cleanup from KILL file, if any */
- #endif
- in_ng = FALSE; /* leave newsgroup state */
- if (artfp != Nullfp) { /* article still open? */
- fclose(artfp); /* close it */
- artfp = Nullfp; /* and tell the world */
- #ifdef SERVER
- sprintf(artname, "/tmp/rrn%ld.%ld", (long) openart, our_pid);
- UNLINK(artname);
- #endif SERVER
- openart = 0;
- }
- putchar('\n') FLUSH;
- yankback(); /* do a Y command */
- restore_ng(); /* reconstitute .newsrc line */
- doing_ng = FALSE; /* tell sig_catcher to cool it */
- free(ctlarea); /* return the control area */
- #ifdef CACHESUBJ
- if (subj_list) {
- for (i=OFFSET(lastart); i>=0; --i)
- if (subj_list[i])
- free(subj_list[i]);
- #ifndef lint
- free((char*)subj_list);
- #endif lint
- }
- #endif
- write_rc(); /* and update .newsrc */
- rc_changed = FALSE; /* tell sig_catcher it is ok */
- if (chdir(spool)) {
- printf(nocd,spool) FLUSH;
- sig_catcher(0);
- }
- #ifdef KILLFILES
- if (localkfp) {
- fclose(localkfp);
- localkfp = Nullfp;
- }
- #endif
- mode = oldmode;
- return exit_code;
- } /* Whew! */
-
- /* decide what to do at the end of an article */
-
- int
- art_switch()
- {
- register ART_NUM i;
-
- setdef(buf,dfltcmd);
- #ifdef VERIFY
- printcmd();
- #endif
- switch (*buf) {
- case 'p': /* find previous unread article */
- do {
- if (art <= firstart)
- break;
- art--;
- #ifdef SERVER
- } while (was_read(art) || nntpopen(art,HEAD) == Nullfp);
- #else
- } while (was_read(art) || artopen(art) == Nullfp);
- #endif
- #ifdef ARTSEARCH
- srchahead = 0;
- #endif
- return AS_NORM;
- case 'P': /* goto previous article */
- if (art > absfirst)
- art--;
- else {
- #ifdef VERBOSE
- IF(verbose)
- fputs("\n\
- There are no articles prior to this one.\n\
- ",stdout) FLUSH;
- ELSE
- #endif
- #ifdef TERSE
- fputs("\nNo previous articles\n",stdout) FLUSH;
- #endif
- return AS_ASK;
- }
- reread = TRUE;
- #ifdef ARTSEARCH
- srchahead = 0;
- #endif
- return AS_NORM;
- case '-':
- if (recent_art) {
- art = recent_art;
- reread = TRUE;
- #ifdef ARTSEARCH
- srchahead = -(srchahead != 0);
- #endif
- return AS_NORM;
- }
- else {
- exit_code = NG_MINUS;
- return AS_CLEAN;
- }
- case 'n': /* find next unread article? */
- if (art > lastart) {
- if (toread[ng])
- art = firstart;
- else
- return AS_CLEAN;
- }
- #ifdef ARTSEARCH
- else if (scanon && srchahead) {
- *buf = Ctl('n');
- goto normal_search;
- }
- #endif
- else
- art++;
- #ifdef ARTSEARCH
- srchahead = 0;
- #endif
- return AS_NORM;
- case 'N': /* goto next article */
- if (art > lastart)
- art = absfirst;
- else
- art++;
- if (art <= lastart)
- reread = TRUE;
- #ifdef ARTSEARCH
- srchahead = 0;
- #endif
- return AS_NORM;
- case '$':
- art = lastart+1;
- forcelast = TRUE;
- #ifdef ARTSEARCH
- srchahead = 0;
- #endif
- return AS_NORM;
- case '1': case '2': case '3': /* goto specified article */
- case '4': case '5': case '6': /* or do something with a range */
- case '7': case '8': case '9': case '.':
- forcelast = TRUE;
- switch (numnum()) {
- case NN_INP:
- return AS_INP;
- case NN_ASK:
- return AS_ASK;
- case NN_REREAD:
- reread = TRUE;
- #ifdef ARTSEARCH
- if (srchahead)
- srchahead = -1;
- #endif
- break;
- case NN_NORM:
- if (was_read(art)) {
- art = firstart;
- pad(just_a_sec/3);
- }
- else
- return AS_ASK;
- break;
- }
- return AS_NORM;
- case Ctl('k'):
- edit_kfile();
- return AS_ASK;
- case 'K':
- case 'k':
- case Ctl('n'): case Ctl('p'):
- case '/': case '?':
- #ifdef ARTSEARCH
- normal_search:
- { /* search for article by pattern */
- char cmd = *buf;
-
- reread = TRUE; /* assume this */
- switch (art_search(buf, (sizeof buf), TRUE)) {
- case SRCH_ERROR:
- return AS_ASK;
- case SRCH_ABORT:
- return AS_INP;
- case SRCH_INTR:
- #ifdef VERBOSE
- IF(verbose)
- printf("\n(Interrupted at article %ld)\n",(long)art) FLUSH;
- ELSE
- #endif
- #ifdef TERSE
- printf("\n(Intr at %ld)\n",(long)art) FLUSH;
- #endif
- art = curr_art;
- /* restore to current article */
- return AS_ASK;
- case SRCH_DONE:
- fputs("done\n",stdout) FLUSH;
- pad(just_a_sec/3); /* 1/3 second */
- if (srchahead)
- art = firstart;
- else
- art = curr_art;
- reread = FALSE;
- return AS_NORM;
- case SRCH_SUBJDONE:
- #ifdef UNDEF
- fputs("\n\n\n\nSubject not found.\n",stdout) FLUSH;
- pad(just_a_sec/3); /* 1/3 second */
- #endif
- art = firstart;
- reread = FALSE;
- return AS_NORM;
- case SRCH_NOTFOUND:
- fputs("\n\n\n\nNot found.\n",stdout) FLUSH;
- art = curr_art; /* restore to current article */
- return AS_ASK;
- case SRCH_FOUND:
- if (cmd == Ctl('n') || cmd == Ctl('p'))
- oldsubject = TRUE;
- break;
- }
- return AS_NORM;
- }
- #else
- buf[1] = '\0';
- notincl(buf);
- return AS_ASK;
- #endif
- case 'u': /* unsubscribe from this newsgroup? */
- rcchar[ng] = NEGCHAR;
- return AS_CLEAN;
- case 'M':
- #ifdef DELAYMARK
- if (art <= lastart) {
- delay_unmark(art);
- printf("\nArticle %ld will return.\n",(long)art) FLUSH;
- }
- #else
- notincl("M");
- #endif
- return AS_ASK;
- case 'm':
- if (art <= lastart) {
- unmark_as_read(art);
- printf("\nArticle %ld marked as still unread.\n",(long)art) FLUSH;
- }
- return AS_ASK;
- case 'c': /* catch up */
- reask_catchup:
- #ifdef VERBOSE
- IF(verbose)
- in_char("\nDo you really want to mark everything as read? [yn] ",
- 'C');
- ELSE
- #endif
- #ifdef TERSE
- in_char("\nReally? [ynh] ", 'C');
- #endif
- putchar('\n') FLUSH;
- setdef(buf,"y");
- #ifdef VERIFY
- printcmd();
- #endif
- if (*buf == 'h') {
- #ifdef VERBOSE
- IF(verbose)
- fputs("\
- Type y or SP to mark all articles as read.\n\
- Type n to leave articles marked as they are.\n\
- Type u to mark everything read and unsubscribe.\n\
- ",stdout) FLUSH;
- ELSE
- #endif
- #ifdef TERSE
- fputs("\
- y or SP to mark all read.\n\
- n to forget it.\n\
- u to mark all and unsubscribe.\n\
- ",stdout) FLUSH;
- #endif
- goto reask_catchup;
- }
- else if (*buf == 'n' || *buf == 'q') {
- return AS_ASK;
- }
- else if (*buf != 'y' && *buf != 'u') {
- fputs(hforhelp,stdout) FLUSH;
- settle_down();
- goto reask_catchup;
- }
- for (i = firstart; i <= lastart; i++) {
- oneless(i); /* mark as read */
- }
- #ifdef DELAYMARK
- if (dmfp)
- yankback();
- #endif
- if (*buf == 'u') {
- rcchar[ng] = NEGCHAR;
- return AS_CLEAN;
- }
- art = lastart+1;
- forcelast = FALSE;
- return AS_NORM;
- case 'Q':
- exit_code = NG_ASK;
- /* FALL THROUGH */
- case 'q': /* go back up to newsgroup level? */
- return AS_CLEAN;
- case 'j':
- putchar('\n') FLUSH;
- if (art <= lastart)
- mark_as_read(art);
- return AS_ASK;
- case 'h': { /* help? */
- int cmd;
-
- if ((cmd = help_art()) > 0)
- pushchar(cmd);
- return AS_ASK;
- }
- case '&':
- if (switcheroo()) /* get rest of command */
- return AS_INP; /* if rubbed out, try something else */
- return AS_ASK;
- case '#':
- #ifdef VERBOSE
- IF(verbose)
- printf("\nThe last article is %ld.\n",(long)lastart) FLUSH;
- ELSE
- #endif
- #ifdef TERSE
- printf("\n%ld\n",(long)lastart) FLUSH;
- #endif
- return AS_ASK;
- case '=': {
- char tmpbuf[256];
- ART_NUM oldart = art;
- int cmd;
- char *subjline = getval("SUBJLINE",Nullch);
- #ifndef CACHESUBJ
- char *s;
- #endif
-
- page_init();
- #ifdef CACHESUBJ
- if (!subj_list)
- fetchsubj(art,TRUE,FALSE);
- #endif
- for (i=firstart; i<=lastart && !int_count; i++) {
- #ifdef CACHESUBJ
- if (!was_read(i) &&
- (subj_list[OFFSET(i)] != Nullch || fetchsubj(i,FALSE,FALSE)) &&
- *subj_list[OFFSET(i)] ) {
- sprintf(tmpbuf,"%5ld ", i);
- if (subjline) {
- art = i;
- interp(tmpbuf + 6, (sizeof tmpbuf) - 6, subjline);
- }
- else
- safecpy(tmpbuf + 6, subj_list[OFFSET(i)],
- (sizeof tmpbuf) - 6);
- if (cmd = print_lines(tmpbuf,NOMARKING)) {
- if (cmd > 0)
- pushchar(cmd);
- break;
- }
- }
- #else
- if (!was_read(i) && (s = fetchsubj(i,FALSE,FALSE)) && *s) {
- sprintf(tmpbuf,"%5ld ", i);
- if (subjline) { /* probably fetches it again! */
- art = i;
- interp(tmpbuf + 6, (sizeof tmpbuf) - 6, subjline);
- }
- else
- safecpy(tmpbuf + 6, s, (sizeof tmpbuf) - 6);
- if (cmd = print_lines(tmpbuf,NOMARKING)) {
- if (cmd > 0)
- pushchar(cmd);
- break;
- }
- }
- #endif
- }
- int_count = 0;
- art = oldart;
- return AS_ASK;
- }
- case '^':
- art = firstart;
- #ifdef ARTSEARCH
- srchahead = 0;
- #endif
- return AS_NORM;
- #if defined(CACHESUBJ) && defined(DEBUGGING)
- case 'D':
- printf("\nFirst article: %ld\n",(long)firstart) FLUSH;
- if (!subj_list)
- fetchsubj(art,TRUE,FALSE);
- if (subj_list != Null(char **)) {
- for (i=1; i<=lastart && !int_count; i++) {
- if (subj_list[OFFSET(i)])
- printf("%5ld %c %s\n",
- i, (was_read(i)?'y':'n'), subj_list[OFFSET(i)]) FLUSH;
- }
- }
- int_count = 0;
- return AS_ASK;
- #endif
- case 'v':
- if (art <= lastart) {
- reread = TRUE;
- do_hiding = FALSE;
- }
- return AS_NORM;
- #ifdef ROTATION
- case Ctl('x'):
- #endif
- case Ctl('r'):
- #ifdef ROTATION
- rotate = (*buf==Ctl('x'));
- #endif
- if (art <= lastart)
- reread = TRUE;
- return AS_NORM;
- #ifdef ROTATION
- case 'X':
- rotate = !rotate;
- /* FALL THROUGH */
- #else
- case Ctl('x'):
- case 'x':
- case 'X':
- notincl("x");
- return AS_ASK;
- #endif
- case 'l': case Ctl('l'): /* refresh screen */
- if (art <= lastart) {
- reread = TRUE;
- clear();
- do_fseek = TRUE;
- artline = topline;
- if (artline < 0)
- artline = 0;
- }
- return AS_NORM;
- case 'b': case Ctl('b'): /* back up a page */
- if (art <= lastart) {
- ART_LINE target;
-
- reread = TRUE;
- clear();
- do_fseek = TRUE;
- target = topline - (LINES - 2);
- artline = topline;
- if (artline > 0) do {
- artline--;
- } while (artline >= 0 && artline > target &&
- vrdary(artline-1) >= 0);
- topline = artline;
- if (artline < 0)
- artline = 0;
- }
- return AS_NORM;
- case '!': /* shell escape */
- if (escapade())
- return AS_INP;
- return AS_ASK;
- case 'C': {
- cancel_article();
- return AS_ASK;
- }
- case 'R':
- case 'r': { /* reply? */
- reply();
- return AS_ASK;
- }
- case 'F':
- case 'f': { /* followup command */
- followup();
- forcegrow = TRUE; /* recalculate lastart */
- return AS_ASK;
- }
- case '|':
- case 'w': case 'W':
- case 's': case 'S': /* save command */
- if (save_article() == SAVE_ABORT)
- return AS_INP;
- return AS_ASK;
- #ifdef DELAYMARK
- case 'Y': /* yank back M articles */
- yankback();
- art = firstart; /* from the beginning */
- return AS_NORM; /* pretend nothing happened */
- #endif
- #ifdef STRICTCR
- case '\n':
- fputs(badcr,stdout) FLUSH;
- return AS_ASK;
- #endif
- default:
- printf("\n%s",hforhelp) FLUSH;
- settle_down();
- return AS_ASK;
- }
- }
-
- #ifdef MAILCALL
- /* see if there is any mail */
-
- void
- setmail()
- {
- if (! (mailcount++)) {
- char *mailfile = filexp(getval("MAILFILE",MAILFILE));
-
- if (stat(mailfile,&filestat) < 0 || !filestat.st_size
- || filestat.st_atime > filestat.st_mtime)
- mailcall = nullstr;
- else
- mailcall = getval("MAILCALL","(Mail) ");
- }
- mailcount %= 10; /* check every 10 articles */
- }
- #endif
-
- void
- setdfltcmd()
- {
- if (toread[ng]) {
- #ifdef ARTSEARCH
- if (srchahead)
- dfltcmd = "^Nnpq";
- else
- #endif
- dfltcmd = "npq";
- }
- else {
- if (art > lastart)
- dfltcmd = "qnp";
- else
- dfltcmd = "npq";
- }
- }
-
- !STUFFY!FUNK!
- echo Extracting rcln.c
- cat >rcln.c <<'!STUFFY!FUNK!'
- /* $Header: rcln.c,v 4.3.2.1 90/04/23 00:22:22 sob Exp $
- *
- * $Log: rcln.c,v $
- * Revision 4.3.2.1 90/04/23 00:22:22 sob
- * Changed atoi to atol and fixed RCS information.
- *
- * Revision 4.3.1.2 85/07/23 17:39:08 lwall
- * Oops, was freeing a static buf on -c in checkexpired.
- *
- * Revision 4.3.1.1 85/05/10 11:37:08 lwall
- * Branch for patches.
- *
- * Revision 4.3 85/05/01 11:45:36 lwall
- * Baseline for release with 4.3bsd.
- *
- */
-
- #include "EXTERN.h"
- #include "common.h"
- #include "util.h"
- #include "rcstuff.h"
- #include "ngdata.h"
- #include "INTERN.h"
- #include "rcln.h"
-
- void
- rcln_init()
- {
- ;
- }
-
- #ifdef CATCHUP
- void
- catch_up(ngx)
- NG_NUM ngx;
- {
- char tmpbuf[128];
- char *tmpp;
-
- #ifdef VERBOSE
- IF(verbose)
- printf("\nMarking %s as all read.\n",rcline[ngx]) FLUSH;
- ELSE
- #endif
- #ifdef TERSE
- fputs("\nMarked read\n",stdout) FLUSH;
- #endif
- sprintf(tmpbuf,"%s: 1-%ld", rcline[ngx],(long)getngsize(ngx));
- free(rcline[ngx]);
- rcline[ngx] = savestr(tmpbuf);
- tmpp = rcline[ngx] + rcnums[ngx] - 1;
- *tmpp = '\0';
- write_rc();
- }
- #endif
-
- /* add an article number to a newsgroup, if it isn't already read */
-
- int
- addartnum(artnum,ngnam)
- ART_NUM artnum;
- char *ngnam;
- {
- register NG_NUM ngnum = find_ng(ngnam);
- register char *s, *t, *maxt = Nullch;
- ART_NUM min = 0, max = -1, lastnum = 0;
- char *mbuf;
- bool morenum;
-
- if (!artnum)
- return 0;
- if (ngnum == nextrcline || !rcnums[ngnum])
- /* not found in newsrc? */
- return 0;
- #ifdef CACHEFIRST
- if (!abs1st[ngnum])
- #else
- if (!toread[ngnum])
- #endif
- /* now is a good time to trim down */
- set_toread(ngnum); /* the list due to expires if we */
- /* have not yet. */
- #ifdef DEBUGGING
- if (artnum > ngmax[ngnum] + 10 /* allow for incoming articles */
- ) {
- printf("\nCorrupt Xref line!!! %ld --> %s(1..%ld)\n",
- artnum,ngnam,
- ngmax[ngnum]) FLUSH;
- paranoid = TRUE; /* paranoia reigns supreme */
- return -1; /* hope this was the first newsgroup */
- }
- #endif
-
- if (toread[ngnum] == TR_BOGUS)
- return 0;
- #ifdef DEBUGGING
- if (debug & DEB_XREF_MARKER) {
- printf("%ld->\n%s%c%s\n",(long)artnum,rcline[ngnum],rcchar[ngnum],
- rcline[ngnum] + rcnums[ngnum]) FLUSH;
- }
- #endif
- s = rcline[ngnum] + rcnums[ngnum];
- while (*s == ' ') s++; /* skip spaces */
- t = s;
- while (isdigit(*s) && artnum >= (min = atol(s))) {
- /* while it might have been read */
- for (t = s; isdigit(*t); t++) ; /* skip number */
- if (*t == '-') { /* is it a range? */
- t++; /* skip to next number */
- if (artnum <= (max = atol(t)))
- return 0; /* it is in range => already read */
- lastnum = max; /* remember it */
- maxt = t; /* remember position in case we */
- /* want to overwrite the max */
- while (isdigit(*t)) t++; /* skip second number */
- }
- else {
- if (artnum == min) /* explicitly a read article? */
- return 0;
- lastnum = min; /* remember what the number was */
- maxt = Nullch; /* last one was not a range */
- }
- while (*t && !isdigit(*t)) t++; /* skip comma and any spaces */
- s = t;
- }
-
- /* we have not read it, so insert the article number before s */
-
- morenum = isdigit(*s); /* will it need a comma after? */
- *(rcline[ngnum] + rcnums[ngnum] - 1) = rcchar[ngnum];
- mbuf = safemalloc((MEM_SIZE)(strlen(s) + (s-rcline[ngnum]) + 8));
- strcpy(mbuf,rcline[ngnum]); /* make new rc line */
- if (maxt && lastnum && artnum == lastnum+1)
- /* can we just extend last range? */
- t = mbuf + (maxt-rcline[ngnum]);/* then overwrite previous max */
- else {
- t = mbuf + (t-rcline[ngnum]); /* point t into new line instead */
- if (lastnum) { /* have we parsed any line? */
- if (!morenum) /* are we adding to the tail? */
- *t++ = ','; /* supply comma before */
- if (!maxt && artnum == lastnum+1 && *(t-1) == ',')
- /* adjacent singletons? */
- *(t-1) = '-'; /* turn them into a range */
- }
- }
- if (morenum) { /* is there more to life? */
- if (min == artnum+1) { /* can we consolidate further? */
- bool range_before = (*(t-1) == '-');
- bool range_after;
- char *nextmax;
-
- for (nextmax = s; isdigit(*nextmax); nextmax++) ;
- range_after = *nextmax++ == '-';
-
- if (range_before)
- *t = '\0'; /* artnum is redundant */
- else
- sprintf(t,"%ld-",(long)artnum);/* artnum will be new min */
-
- if (range_after)
- s = nextmax; /* *s is redundant */
- /* else
- s = s */ /* *s is new max */
- }
- else
- sprintf(t,"%ld,",(long)artnum); /* put the number and comma */
- }
- else
- sprintf(t,"%ld",(long)artnum); /* put the number there (wherever) */
- strcat(t,s); /* copy remainder of line */
- #ifdef DEBUGGING
- if (debug & DEB_XREF_MARKER) {
- printf("%s\n",mbuf) FLUSH;
- }
- #endif
- free(rcline[ngnum]);
- rcline[ngnum] = mbuf; /* pull the switcheroo */
- *(rcline[ngnum] + rcnums[ngnum] - 1) = '\0';
- /* wipe out : or ! */
- if (toread[ngnum] > TR_NONE) /* lest we turn unsub into bogus */
- --toread[ngnum];
- return 0;
- }
-
- #ifdef MCHASE
- /* delete an article number from a newsgroup, if it is there */
-
- void
- subartnum(artnum,ngnam)
- register ART_NUM artnum;
- char *ngnam;
- {
- register NG_NUM ngnum = find_ng(ngnam);
- register char *s, *t;
- register ART_NUM min, max;
- char *mbuf;
- int curlen;
-
- if (!artnum)
- return;
- if (ngnum == nextrcline || !rcnums[ngnum])
- return; /* not found in newsrc? */
- #ifdef DEBUGGING
- if (debug & DEB_XREF_MARKER) {
- printf("%ld<-\n%s%c%s\n",(long)artnum,rcline[ngnum],rcchar[ngnum],
- rcline[ngnum] + rcnums[ngnum]) FLUSH;
- }
- #endif
- s = rcline[ngnum] + rcnums[ngnum];
- while (*s == ' ') s++; /* skip spaces */
-
- /* a little optimization, since it is almost always the last number */
-
- for (t=s; *t; t++) ; /* find end of string */
- curlen = t-rcline[ngnum];
- for (t--; isdigit(*t); t--) ; /* find previous delim */
- if (*t == ',' && atol(t+1) == artnum) {
- *t = '\0';
- if (toread[ngnum] >= TR_NONE)
- ++toread[ngnum];
- #ifdef DEBUGGING
- if (debug & DEB_XREF_MARKER)
- printf("%s%c %s\n",rcline[ngnum],rcchar[ngnum],s) FLUSH;
- #endif
- return;
- }
-
- /* not the last number, oh well, we may need the length anyway */
-
- while (isdigit(*s) && artnum >= (min = atol(s))) {
- /* while it might have been read */
- for (t = s; isdigit(*t); t++) ; /* skip number */
- if (*t == '-') { /* is it a range? */
- t++; /* skip to next number */
- max = atol(t);
- while (isdigit(*t)) t++; /* skip second number */
- if (artnum <= max) {
- /* it is in range => already read */
- if (artnum == min) {
- min++;
- artnum = 0;
- }
- else if (artnum == max) {
- max--;
- artnum = 0;
- }
- *(rcline[ngnum] + rcnums[ngnum] - 1) = rcchar[ngnum];
- mbuf = safemalloc((MEM_SIZE)(curlen + (artnum?15:2)));
- *s = '\0';
- strcpy(mbuf,rcline[ngnum]); /* make new rc line */
- s = mbuf + (s-rcline[ngnum]);
- /* point s into mbuf now */
- if (artnum) { /* split into two ranges? */
- prange(s,min,artnum-1);
- s += strlen(s);
- *s++ = ',';
- prange(s,artnum+1,max);
- }
- else /* only one range */
- prange(s,min,max);
- s += strlen(s);
- strcpy(s,t); /* copy remainder over */
- #ifdef DEBUGGING
- if (debug & DEB_XREF_MARKER) {
- printf("%s\n",mbuf) FLUSH;
- }
- #endif
- free(rcline[ngnum]);
- rcline[ngnum] = mbuf; /* pull the switcheroo */
- *(rcline[ngnum] + rcnums[ngnum] - 1) = '\0';
- /* wipe out : or ! */
- if (toread[ngnum] >= TR_NONE)
- ++toread[ngnum];
- return;
- }
- }
- else {
- if (artnum == min) { /* explicitly a read article? */
- if (*t == ',') /* pick a comma, any comma */
- t++;
- else if (s[-1] == ',')
- s--;
- else if (s[-2] == ',') /* (in case of space) */
- s -= 2;
- strcpy(s,t); /* no need to realloc */
- if (toread[ngnum] >= TR_NONE)
- ++toread[ngnum];
- #ifdef DEBUGGING
- if (debug & DEB_XREF_MARKER) {
- printf("%s%c%s\n",rcline[ngnum],rcchar[ngnum],
- rcline[ngnum] + rcnums[ngnum]) FLUSH;
- }
- #endif
- return;
- }
- }
- while (*t && !isdigit(*t)) t++; /* skip comma and any spaces */
- s = t;
- }
- }
-
- void
- prange(where,min,max)
- char *where;
- ART_NUM min,max;
- {
- if (min == max)
- sprintf(where,"%ld",(long)min);
- else
- sprintf(where,"%ld-%ld",(long)min,(long)max);
- }
- #endif
-
- /* calculate the number of unread articles for a newsgroup */
-
- void
- set_toread(ngnum)
- register NG_NUM ngnum;
- {
- register char *s, *c, *h;
- char tmpbuf[64], *mybuf = tmpbuf;
- char *nums;
- int length;
- #ifdef CACHEFIRST
- bool virgin_ng = (!abs1st[ngnum]);
- #endif
- ART_NUM ngsize = getngsize(ngnum);
- ART_NUM unread = ngsize;
- ART_NUM newmax;
-
- #ifdef DEBUGGING
- ngmax[ngnum] = ngsize; /* for checking out-of-range Xrefs */
- #endif
- if (ngsize == TR_BOGUS) {
- printf("Warning! Bogus newsgroup: %s\n",rcline[ngnum]) FLUSH;
- paranoid = TRUE;
- toread[ngnum] = TR_BOGUS;
- return;
- }
- #ifdef CACHEFIRST
- if (virgin_ng)
- #else
- if (!toread[ngnum])
- #endif
- {
- sprintf(tmpbuf," 1-%ld",(long)ngsize);
- if (strNE(tmpbuf,rcline[ngnum]+rcnums[ngnum]))
- checkexpired(ngnum,ngsize); /* this might realloc rcline */
- }
- nums = rcline[ngnum]+rcnums[ngnum];
- length = strlen(nums);
- if (length >= 60)
- mybuf = safemalloc((MEM_SIZE)(length+5));
- strcpy(mybuf,nums);
- mybuf[length++] = ',';
- mybuf[length] = '\0';
- for (s = mybuf; isspace(*s); s++)
- ;
- for ( ; (c = index(s,',')) != Nullch ; s = ++c) {
- /* for each range */
- *c = '\0'; /* keep index from running off */
- if ((h = index(s,'-')) != Nullch) /* find - in range, if any */
- unread -= (newmax = atol(h+1)) - atol(s) + 1;
- else if (newmax = atol(s))
- unread--; /* recalculate length */
- if (newmax > ngsize) { /* paranoia check */
- unread = -1;
- break;
- }
- }
- if (unread >= 0) /* reasonable number? */
- toread[ngnum] = (ART_UNREAD)unread;
- /* remember how many are left */
- else { /* SOMEONE RESET THE NEWSGROUP!!! */
- toread[ngnum] = (ART_UNREAD)ngsize;
- /* assume nothing carried over */
- printf("Warning! Somebody reset %s--assuming nothing read.\n",
- rcline[ngnum]) FLUSH;
- *(rcline[ngnum] + rcnums[ngnum]) = '\0';
- paranoid = TRUE; /* enough to make a guy paranoid */
- }
- if (mybuf != tmpbuf)
- free(mybuf);
- if (rcchar[ngnum] == NEGCHAR)
- toread[ngnum] = TR_UNSUB;
- }
-
- /* make sure expired articles are marked as read */
-
- void
- checkexpired(ngnum,ngsize)
- register NG_NUM ngnum;
- ART_NUM ngsize;
- {
- register ART_NUM a1st = getabsfirst(ngnum,ngsize);
- register char *s, *t;
- register ART_NUM num, lastnum = 0;
- char *mbuf, *newnum;
-
- if (a1st<=1)
- return;
- #ifdef DEBUGGING
- if (debug & DEB_XREF_MARKER) {
- printf("1-%ld->\n%s%c%s\n",(long)(a1st-1),rcline[ngnum],rcchar[ngnum],
- rcline[ngnum] + rcnums[ngnum]) FLUSH;
- }
- #endif
- for (s = rcline[ngnum] + rcnums[ngnum]; isspace(*s); s++);
- while (*s && (num = atol(s)) <= a1st) {
- while (isdigit(*s)) s++;
- while (*s && !isdigit(*s)) s++;
- lastnum = num;
- }
- if (*s) {
- if (s[-1] == '-') { /* landed in a range? */
- if (lastnum != 1) {
- if (3 + strlen(s) > strlen(rcline[ngnum]+rcnums[ngnum])) {
- mbuf = safemalloc((MEM_SIZE)(rcnums[ngnum] + 3 +
- strlen(s) + 1));
- strcpy(mbuf, rcline[ngnum]);
- sprintf(mbuf+rcnums[ngnum]," 1-%s",s);
- free(rcline[ngnum]);
- rcline[ngnum] = mbuf;
- } else {
- sprintf(rcline[ngnum]+rcnums[ngnum]," 1-%s",s);
- }
- }
- goto ret;
- }
- }
- /* s now points to what should follow first range */
- if (s - rcline[ngnum] > rcnums[ngnum] + 10)
- mbuf = rcline[ngnum];
- else {
- mbuf = safemalloc((MEM_SIZE)(rcnums[ngnum] + strlen(s) + 10));
- strcpy(mbuf,rcline[ngnum]);
- }
- newnum = t = mbuf+rcnums[ngnum];
- sprintf(t," 1-%ld",(long)(a1st - (lastnum != a1st)));
- if (*s) {
- t += strlen(t);
- *t++ = ',';
- strcpy(t,s);
- }
- if (!checkflag && mbuf == rcline[ngnum]) {
- rcline[ngnum] = saferealloc(rcline[ngnum],
- (MEM_SIZE)(rcnums[ngnum] + strlen(newnum) + 1));
- }
- else {
- if (!checkflag)
- free(rcline[ngnum]);
- rcline[ngnum] = mbuf;
- }
-
- ret:; /* semicolon in case DEBUGGING undefined */
- #ifdef DEBUGGING
- if (debug & DEB_XREF_MARKER) {
- printf("%s%c%s\n",rcline[ngnum],rcchar[ngnum],
- rcline[ngnum] + rcnums[ngnum]) FLUSH;
- }
- #endif
- }
-
- !STUFFY!FUNK!
- echo Extracting ngstuff.h
- cat >ngstuff.h <<'!STUFFY!FUNK!'
- /* $Header: ngstuff.h,v 4.3 85/05/01 11:45:12 lwall Exp $
- *
- * $Log: ngstuff.h,v $
- * Revision 4.3 85/05/01 11:45:12 lwall
- * Baseline for release with 4.3bsd.
- *
- */
-
- #define NN_NORM 0
- #define NN_INP 1
- #define NN_REREAD 2
- #define NN_ASK 3
-
- void ngstuff_init();
- int escapade();
- int switcheroo();
- int numnum();
- int perform();
- !STUFFY!FUNK!
- echo ""
- echo "End of kit 3 (of 9)"
- cat /dev/null >kit3isdone
- config=true
- for iskit in 1 2 3 4 5 6 7 8 9 ; do
- if test -f kit${iskit}isdone; then
- echo "You have run kit ${iskit}."
- else
- echo "You still need to run kit ${iskit}."
- config=false
- fi
- done
- case $config in
- true)
- echo "You have run all your kits. Please read README and then type Configure."
- chmod 755 Configure
- ;;
- esac
- : I do not append .signature, but someone might mail this.
- exit
-