v23i065: TRN, version of RN that follows conversation threads, Part06/14

Rich Salz rsalz at bbn.com
Sat Dec 1 08:40:24 AEST 1990


Submitted-by: Wayne Davison <davison at dri.com>
Posting-number: Volume 23, Issue 65
Archive-name: trn/part06

---- Cut Here and unpack ----
#!/bin/sh
# this is part 6 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file common.h continued
#
CurArch=6
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
     exit 1; fi
( read Scheck
  if test "$Scheck" != $CurArch
  then echo "Please unpack part $Scheck next!"
       exit 1;
  else exit 0; fi
) < s2_seq_.tmp || exit 1
echo "x - Continuing file common.h"
sed 's/^X//' << 'SHAR_EOF' >> common.h
X#   endif
X#   ifndef ARTHELP			/* % and ~ */
X#	define ARTHELP "%X/art.help"
X#   endif
X#   ifndef PAGERHELP		/* % and ~ */
X#	define PAGERHELP "%X/pager.help"
X#   endif
X#   ifndef SUBSHELP		/* % and ~ */
X#	define SUBSHELP "%X/subs.help"
X#   endif
X#endif
X
X#ifdef CLEAREOL
X#   define TCSIZE 512	/* capacity for termcap strings */
X#else
X#   ifdef pdp11
X#	define TCSIZE 256	/* capacity for termcap strings */
X#   else
X#	define TCSIZE 512	/* capacity for termcap srings */
X#   endif
X#endif
X
X/* Additional ideas:
X *	Make the do_newsgroup() routine a separate process.
X *	Keep .newsrc on disk instead of in memory.
X *	Overlays, if you have them.
X *	Get a bigger machine.
X */
X
X/* End of Space Conservation Section */
X
X/* More System Dependencies */
X
X/* news library */
X#ifndef LIB		/* ~ and %l only ("~%l" is permissable) */
X#   define LIB "/usr/lib/news"
X#endif
X
X/* path to private executables */
X#ifndef RNLIB		/* ~, %x and %l only */
X#   define RNLIB "%x/rn"
X#endif
X
X/* system-wide RNINIT switches */
X#ifndef GLOBINIT
X#   define GLOBINIT "%X/INIT"
X#endif
X
X/* where to find news files */
X#ifndef SPOOL			/* % and ~ */
X#   define SPOOL "/usr/spool/news"
X#endif
X
X#ifdef THREAD_DIR
X#   ifdef LONG_THREAD_NAMES
X#	undef SUFFIX
X#   else
X#	define SUFFIX ".th"
X#   endif
X#else
X#   define THREAD_DIR	SPOOL
X#   define SUFFIX	"/.thread"
X#   undef LONG_THREAD_NAMES
X#endif
X
X/* default characters to use in the selection menu */
X#ifndef SELECTCHARS
X#   define SELECTCHARS "abcdefgijlorstuvwxz1234567890"
X#endif
X
X/* file containing list of active newsgroups and max article numbers */
X#ifndef ACTIVE			/* % and ~ */
X#   define ACTIVE "%x/active"
X#endif
X#ifdef SERVER
X#   ifndef ACTIVE1
X#	define ACTIVE1 "%X/active1"
X#   endif
X#endif
X#ifndef ACTIVE2
X#   define ACTIVE2 "%X/active2"
X#endif
X
X/* location of history file */
X#ifndef ARTFILE			/* % and ~ */
X#    define ARTFILE "%x/history"
X#endif
X
X/* command to setup a new .newsrc */
X#ifndef NEWSETUP		/* % and ~ */
X#   define NEWSETUP "newsetup"
X#endif
X
X/* command to display a list of un-subscribed-to newsgroups */
X#ifndef NEWSGROUPS		/* % and ~ */
X#   define NEWSGROUPS "newsgroups"
X#endif
X
X/* preferred shell for use in doshell routine */
X/*  ksh or sh would be okay here */
X#ifndef PREFSHELL
X#   define PREFSHELL "/bin/csh"
X#endif
X
X/* path to fastest starting shell */
X#ifndef SH
X#   define SH "/bin/sh"
X#endif
X
X/* default unshar'ing program */
X#ifndef UNSHAR
X#   define UNSHAR "/bin/sh"
X#endif
X
X/* path to default editor */
X#ifndef DEFEDITOR
X#   define DEFEDITOR "/usr/ucb/vi"
X#endif
X
X/* location of macro file */
X#ifndef RNMACRO
X#   ifdef PUSHBACK
X#	define RNMACRO "%./.rnmac"
X#   endif
X#endif
X
X/* location of full name */
X#ifndef FULLNAMEFILE
X#   ifndef PASSNAMES
X#	define FULLNAMEFILE "%./.fullname"
X#   endif
X#endif
X
X/* virtual array file name template */
X#ifndef VARYNAME		/* % and ~ */
X#   define VARYNAME "/tmp/rnvary.%$"
X#endif
X
X/* file to pass header to followup article poster */
X#ifndef HEADNAME		/* % and ~ */
X#   define HEADNAME "%./.rnhead"
X/* or alternately #define HEADNAME "/tmp/rnhead.%$" */
X#endif
X
X#ifndef MAKEDIR
X/* shell script to make n-deep subdirectories */
X#   ifndef DIRMAKER		/* % and ~ */
X#	define DIRMAKER "%X/makedir"
X#   endif
X#endif
X
X/* location of newsrc file */
X#ifndef RCNAME		/* % and ~ */
X#   define RCNAME "%./.newsrc"
X#endif
X
X/* temporary newsrc file in case we crash while writing out */
X#ifndef RCTNAME		/* % and ~ */
X#   define RCTNAME "%./.newnewsrc"
X#endif
X
X/* newsrc file at the beginning of this session */
X#ifndef RCBNAME		/* % and ~ */
X#   define RCBNAME "%./.oldnewsrc"
X#endif
X
X/* if existent, contains process number of current or crashed rn */
X#ifndef LOCKNAME		/* % and ~ */
X#   define LOCKNAME "%./.rnlock"
X#endif
X
X/* information from last invocation of rn */
X#ifndef LASTNAME		/* % and ~ */
X#   define LASTNAME "%./.rnlast"
X#endif
X
X/* file with soft pointers into the active file */
X#ifndef SOFTNAME		/* % and ~ */
X#   define SOFTNAME "%./.rnsoft"
X#endif
X
X/* list of article numbers to mark as unread later (see M and Y cmmands) */
X#ifndef RNDELNAME		/* % and ~ */
X#   define RNDELNAME "%./.rndelay"
X#endif
X
X/* a motd-like file for rn */
X#ifndef NEWSNEWSNAME		/* % and ~ */
X#   define NEWSNEWSNAME "%X/newsnews"
X#endif
X
X/* command to send a reply */
X#ifndef MAILPOSTER		/* % and ~ */
X#   define MAILPOSTER "Rnmail -h %h"
X#endif
X
X#ifdef INTERNET
X#   ifndef MAILHEADER		/* % */
X#	ifdef CONDSUB
X#	    define MAILHEADER "To: %t\nSubject: Re: %S\nNewsgroups: %n\nIn-Reply-To: %i\n%(%[references]!=^$?References\\: %[references]\n)Organization: %o\nCc: \nBcc: \n\n"
X#	else
X#	    define MAILHEADER "To: %t\nSubject: Re: %S\nNewsgroups: %n\nIn-Reply-To: %i\nReferences: %[references]\nCc: \nBcc: \n\n"
X#	endif
X#   endif
X#else
X#   ifndef MAILHEADER		/* % */
X#	ifdef CONDSUB
X#	    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"
X#	else
X#	    define MAILHEADER "To: %T\nSubject: Re: %S\nNewsgroups: %n\nIn-Reply-To: %i\nReferences: %[references]\nCc: \nBcc: \n\n"
X#	endif
X#   endif
X#endif
X
X#ifndef YOUSAID			/* % */
X#   define YOUSAID "In article %i you write:"
X#endif
X
X/* command to submit a followup article */
X#ifndef NEWSPOSTER		/* % and ~ */
X#   define NEWSPOSTER "Pnews -h %h"
X#endif
X
X#ifndef NEWSHEADER		/* % */
X#   ifdef CONDSUB
X#ifdef INTERNET
X#	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"
X#else
X#	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"
X#endif
X#   else
X#	ifdef INTERNET
X#	    define NEWSHEADER "Newsgroups: %F\nSubject: Re: %S\nSummary: \nExpires: \nReferences: %R\nSender: \nFollowup-To: \nDistribution: %D\nOrganization: %o\nKeywords: %[keywords]\n\n"
X#	else
X#	    define NEWSHEADER "Newsgroups: %F\nSubject: Re: %S\nSummary: \nExpires: \nReferences: %R\nSender: \nFollowup-To: \nDistribution: %D\nOrganization: %o\nKeywords: %[keywords]\n\n"
X#	endif
X#   endif
X#endif
X
X#ifndef ATTRIBUTION		/* % */
X#   define ATTRIBUTION "In article %i %f writes:"
X#endif
X
X#ifndef PIPESAVER		/* % */
X#   ifdef CONDSUB
X#       ifdef SERVER
X#               define PIPESAVER "%(%B=^0$?<%P/rrn%a.%$:tail +%Bc %P/rrn%a.%$ |) %b"
X#       else
X#		define PIPESAVER "%(%B=^0$?<%A:tail +%Bc %A |) %b"
X#	endif
X#   else
X#       ifdef SERVER
X#               define PIPESAVER "tail +%Bc %P/rrn%a.%$ | %b"
X#       else
X#		define PIPESAVER "tail +%Bc %A | %b"
X#	endif
X#   endif
X#endif
X
X#ifndef EXSAVER
X#    ifdef SERVER
X#	define EXSAVER "tail +%Bc %P/rrn%a.%$ | %e"
X#    else
X#	define EXSAVER "tail +%Bc %A | %e"
X#    endif
X#endif
X
X#ifndef NORMSAVER		/* % and ~ */
X#    ifdef SERVER
X#	define NORMSAVER "%X/norm.saver %P/rrn%a.%$ %P %c %a %B %C \"%b\""
X#    else
X#   	define NORMSAVER "%X/norm.saver %A %P %c %a %B %C \"%b\""
X#    endif
X#endif
X
X#ifndef MBOXSAVER		/* % and ~ */
X#   ifdef MININACT		/* 2.10.2 site? */
X#       ifdef SERVER
X#           define MBOXSAVER "%X/mbox.saver %P/rrn%a.%$ %P %c %a %B %C \"%b\" \"From %T %`date`\""
X#       else
X#	    define MBOXSAVER "%X/mbox.saver %A %P %c %a %B %C \"%b\" \"From %T %`date`\""
X#	endif
X#   else
X#	ifdef CONDSUB
X#           ifdef SERVER
X#               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)\""
X#           else
X#	        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)\""
X#	    endif
X					/* header munging with a vengeance */
X#	else
X#           ifdef SERVER
X#               define MBOXSAVER "%X/mbox.saver %P/rrn%a.%$ %P %c %a %B %C \"%b\" \"From %T %[posted]\""
X#           else
X#	        define MBOXSAVER "%X/mbox.saver %A %P %c %a %B %C \"%b\" \"From %T %[posted]\""
X#	    endif
X#	endif
X#   endif
X#endif
X
X#ifdef MKDIRS
X
X#   ifndef SAVEDIR			/* % and ~ */
X#	define SAVEDIR "%p/%c"
X#   endif
X#   ifndef SAVENAME		/* % */
X#	define SAVENAME "%a"
X#   endif
X
X#else
X
X#   ifndef SAVEDIR			/* % and ~ */
X#	define SAVEDIR "%p"
X#   endif
X#   ifndef SAVENAME		/* % */
X#	define SAVENAME "%^C"
X#   endif
X
X#endif
X
X#ifndef KILLGLOBAL		/* % and ~ */
X#   define KILLGLOBAL "%p/KILL"
X#endif
X
X#ifndef KILLLOCAL		/* % and ~ */
X#   define KILLLOCAL "%p/%c/KILL"
X#endif
X
X/* how to cancel an article */
X#ifndef CANCEL
X#   ifdef MININACT			/* 2.10.2 ? */
X#	define CANCEL "%x/inews -h < %h"
X#   else
X#	define CANCEL "inews -h < %h"
X#   endif
X#endif
X
X/* how to cancel an article, continued */
X#ifndef CANCELHEADER
X#ifdef INTERNET
X#   define CANCELHEADER "Newsgroups: %n\nSubject: cmsg cancel %i\nReferences: %R\nDistribution: %D\nOrganization: %o\n\nThis message was cancelled from within rn.\n"
X#else
X#   define CANCELHEADER "Newsgroups: %n\nSubject: cmsg cancel %i\nReferences: %R\nDistribution: %D\nOrganization: %o\n"
X#endif
X#endif
X
X/* where to find the mail file */
X#ifndef MAILFILE
X#   define MAILFILE "/usr/spool/mail/%L"
X#endif
X
X/* some important types */
X
Xtypedef int		NG_NUM;		/* newsgroup number */
Xtypedef long		ART_NUM;	/* article number */
X#ifdef pdp11
X    typedef short	ART_UNREAD;	/* ordinarily this should be long */
X					/* like ART_NUM, but assuming that */
X					/* we stay less than 32767 articles */
X					/* behind saves a lot of space. */
X					/* NOTE: do not make unsigned. */
X#else
X    typedef long	ART_UNREAD;
X#endif
X#ifdef SERVER
Xtypedef int		ART_PART;	/* for passing to nntpopen() */
X#endif
Xtypedef long		ART_POS;	/* char position in article file */
Xtypedef int		ART_LINE;	/* line position in article file */
Xtypedef long		ACT_POS;	/* char position in active file */
Xtypedef unsigned int	MEM_SIZE;	/* for passing to malloc */
X
X
X/* *** end of the machine dependent stuff *** */
X
X/* GLOBAL THINGS */
X
X/* file statistics area */
X
XEXT struct stat filestat;
X
X/* various things of type char */
X
Xchar	*index();
Xchar	*rindex();
Xchar	*getenv();
Xchar	*strcat();
Xchar	*strcpy();
X
XEXT char buf[LBUFLEN+1];	/* general purpose line buffer */
XEXT char cmd_buf[CBUFLEN];	/* buffer for formatting system commands */
X
XEXT char *indstr INIT(">");	/* indent for old article embedded in followup */
X
XEXT char *cwd INIT(Nullch);		/* current working directory */
XEXT char *dfltcmd INIT(Nullch);	/* 1st char is default command */
X
X/* switches */
X
X#ifdef DEBUGGING
X    EXT int debug INIT(0);				/* -D */
X#   define DEB_INNERSRCH 32 
X#   define DEB_FILEXP 64 
X#   define DEB_HASH 128
X#   define DEB_XREF_MARKER 256
X#   define DEB_CTLAREA_BITMAP 512
X#   define DEB_SOFT_POINTERS 1024
X#   define DEB_NEWSRC_LINE 2048
X#   define DEB_SEARCH_AHEAD 4096
X#   define DEB_CHECKPOINTING 8192
X#   define DEB_FEED_XREF 16384
X#endif
X
X#ifdef ARTSEARCH
X    EXT int scanon INIT(0);				/* -S */
X#endif
X
X#ifdef USETHREADS
X    EXT bool use_threads INIT(THREAD_INIT);		/* -x */
X    EXT int max_tree_lines INIT(6);
X    EXT char select_order[4] INIT("lsm");
X    EXT int select_on INIT(SELECT_INIT);		/* -X */
X    EXT char end_select INIT('Z');
X    EXT char page_select INIT('>');
X#endif
X
XEXT bool mbox_always INIT(FALSE);			/* -M */
XEXT bool norm_always INIT(FALSE);			/* -N */
XEXT bool checkflag INIT(FALSE);			/* -c */
XEXT bool suppress_cn INIT(FALSE);			/* -s */
XEXT int countdown INIT(5);	/* how many lines to list before invoking -s */
XEXT bool muck_up_clear INIT(FALSE);			/* -loco */
XEXT bool erase_screen INIT(FALSE);			/* -e */
X#if defined(CLEAREOL) || defined(USETHREADS)
XEXT bool can_home INIT(FALSE);
X#endif
X#ifdef CLEAREOL
XEXT bool can_home_clear INIT(FALSE);		/* fancy -e -- PWP */
X#endif
XEXT bool findlast INIT(FALSE);			/* -r */
XEXT bool typeahead INIT(FALSE);			/* -T */
X#ifdef VERBOSE
X#   ifdef TERSE
X	EXT bool verbose INIT(TRUE);			/* +t */
X#   endif
X#endif
X#ifdef VERIFY
X    EXT bool verify INIT(FALSE);			/* -v */
X#endif
X    EXT bool quickstart INIT(FALSE);			/* -q */
X
X#define NOMARKING 0
X#define STANDOUT 1
X#define UNDERLINE 2
XEXT int marking INIT(NOMARKING);			/* -m */
X
XEXT ART_LINE initlines INIT(0);		/* -i */
XEXT bool initlines_specified INIT(FALSE);
X
X/* miscellania */
X
Xint fseek();
Xlong atol(), ftell();
XEXT bool in_ng INIT(FALSE);		/* current state of rn */
XEXT char mode INIT('i');		/* current state of rn */
X
XEXT FILE *tmpfp INIT(Nullfp);	/* scratch fp used for .rnlock, .rnlast, etc. */
X
XEXT NG_NUM nextrcline INIT(0);	/* 1st unused slot in rcline array */
X			/* startup to avoid checking twice in a row */
X
Xextern errno;
X
X/* Factored strings */
X
XEXT char nullstr[] INIT("");
XEXT char sh[] INIT(SH);
XEXT char defeditor[] INIT(DEFEDITOR);
XEXT char hforhelp[] INIT("Type h for help.\n");
X#ifdef STRICTCR
XEXT char badcr[] INIT("\nUnnecessary CR ignored.\n");
X#endif
XEXT char readerr[] INIT("rn read error");
XEXT char unsubto[] INIT("\n\nUnsubscribed to newsgroup %s\n");
XEXT char cantopen[] INIT("Can't open %s\n");
XEXT char cantcreate[] INIT("Can't create %s\n");
X
X#ifdef VERBOSE
X    EXT char nocd[] INIT("Can't chdir to directory %s\n");
X#else
X    EXT char nocd[] INIT("Can't find %s\n");
X#endif
X
X#ifdef NOLINEBUF
X#define FLUSH ,fflush(stdout)
X#else
X#define FLUSH
X#endif
X
X#ifdef lint
X#undef FLUSH
X#define FLUSH
X#undef putchar
X#define putchar(c)
X#endif
SHAR_EOF
echo "File common.h is complete"
chmod 0660 common.h || echo "restore of common.h fails"
echo "x - extracting final.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > final.c &&
X/* $Header: final.c,v 4.3.3.1 90/06/20 22:36:57 davison Trn $
X *
X * $Log:	final.c,v $
X * Revision 4.3.3.1  90/06/20  22:36:57  davison
X * Initial Trn Release
X * 
X * Revision 4.3.2.8  90/04/14  19:37:14  sob
X * Added better support for the NeXT.
X * 
X * Revision 4.3.2.7  90/03/17  21:33:49  sob
X * cleaned up a bit
X * 
X * Revision 4.3.2.6  90/03/17  16:48:25  sob
X * Added changes to insure that rrn cleans up its temporary files when
X * exiting.
X * 
X * Revision 4.3.2.5  89/11/28  01:51:28  sob
X * Now handles SIGWINCH correctly.
X * 
X * Revision 4.3.2.4  89/11/27  01:30:24  sob
X * Altered NNTP code per ideas suggested by Bela Lubkin
X * <filbo at gorn.santa-cruz.ca.us>
X * 
X * Revision 4.3.2.3  89/11/08  02:25:07  sob
X * Integrated modifications from other RRN patches colleceted from USENET
X * 
X * Revision 4.3.2.2  89/11/07  23:26:31  sob
X * Added some fixes that relate to SIGSTP
X * 
X * Revision 4.3.2.1  89/11/06  00:16:08  sob
X * Added RRN support from NNTP 1.5
X *
X * Revision 4.3  85/05/01  11:38:08  lwall
X * Baseline for release with 4.3bsd.
X * 
X */
X
X#include "EXTERN.h"
X#include "common.h"
X#include "util.h"
X#include "term.h"
X#include "ng.h"
X#include "init.h"
X#include "bits.h"
X#include "last.h"
X#include "rcstuff.h"
X#include "ngdata.h"
X#include "artio.h"
X#include "INTERN.h"
X#include "final.h"
X
Xvoid
Xfinal_init()
X{
X#ifdef SIGTSTP
X    sigset(SIGTSTP, stop_catcher);	/* job control signals */
X    sigset(SIGTTOU, stop_catcher);	/* job control signals */
X    sigset(SIGTTIN, stop_catcher);	/* job control signals */
X#endif
X
X    sigset(SIGINT, int_catcher);	/* always catch interrupts */
X    sigset(SIGHUP, sig_catcher);	/* and hangups */
X#ifndef lint
X    sigignore(SIGEMT);
X#endif /* lint */
X
X    sigset(SIGILL, sig_catcher);
X    sigset(SIGTRAP, sig_catcher);
X    sigset(SIGFPE, sig_catcher);
X    sigset(SIGBUS, sig_catcher);
X    sigset(SIGSEGV, sig_catcher);
X    sigset(SIGSYS, sig_catcher);
X    sigset(SIGTERM, sig_catcher);
X#ifdef SIGXCPU
X    sigset(SIGXCPU, sig_catcher);
X#endif
X#ifdef SIGXFSZ
X    sigset(SIGXFSZ, sig_catcher);
X#endif
X#ifdef SIGWINCH
X    sigset(SIGWINCH, winch_catcher);
X#endif
X}
X
Xvoid					/* very much void */
Xfinalize(status)
Xint status;
X{
X#ifdef SERVER
X    char artname[32];
X#endif /* SERVER */
X
X    if (bizarre)
X	resetty();
X    if (lockname && *lockname)
X 	UNLINK(lockname);
X#ifdef SERVER
X    if (*active_name)
X	UNLINK(active_name);
X    if (openart) {
X 	char artname[32];
X 	sprintf(artname, "/tmp/rrn%ld.%d", (long)openart, getpid());
X 	UNLINK(artname);
X    }
X    close_server();
X#endif /* SERVER */
X    if (status < 0) {
X	chdir("/usr/tmp");
X	sigset(SIGILL,SIG_DFL);
X	abort();
X    }
X    exit(status);
X}
X
X/* come here on interrupt */
X
Xint
Xint_catcher()
X{
X    sigset(SIGINT,int_catcher);
X#ifdef DEBUGGING
X    if (debug)
X	write(2,"int_catcher\n",12);
X#endif
X    if (!waiting) {
X	if (int_count) {		/* was there already an interrupt? */
X	    write(2,"\nBye-bye.\n",10);
X	    sig_catcher(0);		/* emulate the other signals */
X	}
X	int_count++;
X    }
X}
X
X/* come here on signal other than interrupt, stop, or cont */
X
Xint
Xsig_catcher(signo)
X{
X#ifdef VERBOSE
X    static char *signame[] = {
X	"",
X	"HUP",
X	"INT",
X	"QUIT",
X	"ILL",
X	"TRAP",
X	"IOT",
X	"EMT",
X	"FPE",
X	"KILL",
X	"BUS",
X	"SEGV",
X	"SYS",
X	"PIPE",
X	"ALRM",
X	"TERM",
X	"???"
X#ifdef SIGTSTP
X	,"STOP",
X	"TSTP",
X	"CONT",
X	"CHLD",
X	"TTIN",
X	"TTOU",
X	"TINT",
X	"XCPU",
X	"XFSZ"
X#ifdef SIGPROF
X	,"VTALARM",
X	"PROF"
X#endif
X#endif
X	};
X#endif
X
X#ifdef DEBUGGING
X    if (debug) {
X	printf("\nSIG%s--.newsrc not restored in debug\n",signame[signo]);
X	finalize(-1);
X    }
X#endif
X    if (panic)
X	abort();
X    (void) sigset(SIGILL,SIG_DFL);
X    panic = TRUE;			/* disable terminal I/O */
X    if (doing_ng) {			/* need we reconstitute rc line? */
X	yankback();
X	restore_ng();			/* then do so (hope this works) */
X    }
X    doing_ng = FALSE;
X    if (rc_changed)			/* need we write .newsrc out? */
X	write_rc();			/* then do so */
X    rc_changed = FALSE;
X    if (signo != SIGHUP)
X#ifdef VERBOSE
X	IF(verbose)
X	    printf("\nCaught %s%s--.newsrc restored\n",
X		signo ? "a SIG" : "an internal error", signame[signo]);
X	ELSE
X#endif
X#ifdef TERSE
X	    printf("\nSignal %d--bye bye\n",signo);
X#endif
X    switch (signo) {
X    case SIGBUS:
X    case SIGILL:
X    case SIGSEGV:
X	finalize(-signo);
X    }
X    finalize(1);				/* and blow up */
X}
X
X#ifdef SIGTSTP
X/* come here on stop signal */
X
Xint
Xstop_catcher(signo)
Xint signo;
X{
X    if (!waiting) {
X	checkpoint_rc();		/* good chance of crash while stopped */
X	if (clear_on_stop) {
X	    clear();
X	    putchar('\n') FLUSH;
X	}
X	resetty();			/* this is the point of all this */
X#ifdef DEBUGGING
X	if (debug)
X	    write(2,"stop_catcher\n",13);
X#endif
X	sigset(signo,SIG_DFL);	/* enable stop */
X#ifdef SIGBLOCK
X	sigsetmask(sigblock(0) & ~(1 << (signo-1)));
X#endif
X	kill(0,signo);		/* and do the stop */
X    	savetty();
X#ifdef MAILCALL
X    	mailcount = 0;			/* force recheck */
X#endif
X    	if (!panic) {
X	    if (!waiting) {
X	    	noecho();			/* set no echo */
X	    	crmode();			/* set cbreak mode */
X	    	forceme("\f");		/* cause a refresh */
X					/* (defined only if TIOCSTI defined) */
X		errno = 0;			/* needed for getcmd */
X	    }
X    	}
X    }
X    sigset(signo,stop_catcher);	/* unenable the stop */
X}
X#endif
SHAR_EOF
chmod 0660 final.c || echo "restore of final.c fails"
echo "x - extracting final.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > final.h &&
X/* $Header: final.h,v 4.3.3.1 90/06/20 22:37:04 davison Trn $
X * 
X * $Log:	final.h,v $
X * Revision 4.3.3.1  90/06/20  22:37:04  davison
X * Initial Trn Release
X * 
X * Revision 4.3  85/05/01  11:38:17  lwall
X * Baseline for release with 4.3bsd.
X * 
X */
X
X/* cleanup status for fast exits */
X
XEXT bool panic INIT(FALSE);		/* we got hung up or something-- */
X					/*  so leave tty alone */
XEXT bool rc_changed INIT(FALSE);	/* need we rewrite .newsrc? */
XEXT bool doing_ng INIT(FALSE);		/* do we need to reconstitute */
X					/* current rc line? */
X
XEXT char int_count INIT(0);		/* how many interrupts we've had */
X
XEXT bool clear_on_stop INIT(FALSE);	/* set when handling the stop signal */
X					/* would leave the screen a mess */
X
X/* signal catching routines */
X
Xint	int_catcher();
Xint	sig_catcher();
X#ifdef SIGTSTP
X    int	stop_catcher();
X    int	cont_catcher();
X#endif
X
Xvoid	final_init();
Xvoid	finalize();
SHAR_EOF
chmod 0660 final.h || echo "restore of final.h fails"
echo "x - extracting getactive.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > getactive.c &&
X/* $Header: getactive.c,v 1.2 89/11/28 01:50:22 sob Locked $
X *
X * $Log:	getactive.c,v $
X * Revision 1.2  89/11/28  01:50:22  sob
X * Changed so that it won't give makedepend problems with SERVER is not defined.
X * 
X * Revision 1.1  89/11/06  00:50:14  sob
X * Initial revision
X * 
X *
X */
X#include <stdio.h>
X#include "config.h"
X#include "EXTERN.h"
X#ifdef SERVER
X#include "server.h"
X#endif
X
Xmain(argc, argv)
X	int		argc;
X	char	 	*argv[];
X{
X	char		ser_line[256];
X	int		response;
X	register char	*server;
X	register FILE	*actfp;
X
X	if (argc != 2) {
X		fprintf(stderr, "Usage: getactive filename\n");
X		exit(1);
X	}
X
X	server = getserverbyfile(SERVER_FILE);
X	if (server == NULL) {
X		fprintf(stderr, "Couldn't get name of news server from %s\n",
X			SERVER_FILE);
X		fprintf(stderr,
X	  "Either fix this file, or put NNTPSERVER in your environment.\n");
X		exit(1);
X	}
X
X	response = server_init(server);
X	if (response < 0) {
X		fprintf(stderr,
X			"getactive: Can't get active file from server %s.\n",
X				server);
X		exit(1);
X	}
X
X	if (handle_server_response(response, server) < 0)
X		exit(1);
X
X	put_server("LIST");	/* tell server we want the active file */
X	(void) get_server(ser_line, sizeof(ser_line));
X	if (*ser_line != CHAR_OK) {		/* and then see if that's ok */
X		fprintf(stderr,
X			"getactive: Can't get active file from server.\n");
X		fprintf(stderr, "Server said: %s\n", ser_line);
X		exit(1);
X	}
X
X	actfp = fopen(argv[1], "w");		/* and get ready */
X	if (actfp == NULL) {
X		close_server();
X		perror(argv[1]);
X		exit(1);
X	}
X
X	while (get_server(ser_line, sizeof(ser_line)) >= 0) {  /* while */
X		if (ser_line[0] == '.')		/* there's another line */
X			break;			/* get it and write it to */
X		if (actfp != NULL) {		/* the temporary active file */
X			fputs(ser_line, actfp);
X			putc('\n', actfp);
X		}
X	}
X
X	(void) fclose(actfp);
X	close_server();
X}
SHAR_EOF
chmod 0660 getactive.c || echo "restore of getactive.c fails"
echo "x - extracting getdate.y (Text)"
sed 's/^X//' << 'SHAR_EOF' > getdate.y &&
X%token ID MONTH DAY MERIDIAN NUMBER UNIT MUNIT SUNIT ZONE DAYZONE AGO
X%{
X	/* 	Steven M. Bellovin (unc!smb)			*/
X	/*	Dept. of Computer Science			*/
X	/*	University of North Carolina at Chapel Hill	*/
X	/*	@(#)getdate.y	2.13	9/16/86 */
X
X#include <sys/types.h>
X#include <ctype.h>
X#include <time.h>
X
X#define	NULL	0
X
X#define daysec (24L*60L*60L)
X
X	static int timeflag, zoneflag, dateflag, dayflag, relflag;
X	static time_t relsec, relmonth;
X	static int hh, mm, ss, merid, daylight;
X	static int dayord, dayreq;
X	static int month, day, year;
X	static int ourzone;
X
X#define AM 1
X#define PM 2
X#define DAYLIGHT 1
X#define STANDARD 2
X#define MAYBE    3
X%}
X
X%%
Xtimedate: 		/* empty */
X	| timedate item;
X
Xitem:	tspec =
X		{timeflag++;}
X	| zone =
X		{zoneflag++;}
X	| dtspec =
X		{dateflag++;}
X	| dyspec =
X		{dayflag++;}
X	| rspec =
X		{relflag++;}
X	| nspec;
X
Xnspec:	NUMBER =
X		{if (timeflag && dateflag && !relflag) year = $1;
X		else {timeflag++;hh = $1/100;mm = $1%100;ss = 0;merid = 24;}};
X
Xtspec:	NUMBER MERIDIAN =
X		{hh = $1; mm = 0; ss = 0; merid = $2;}
X	| NUMBER ':' NUMBER =
X		{hh = $1; mm = $3; merid = 24;}
X	| NUMBER ':' NUMBER MERIDIAN =
X		{hh = $1; mm = $3; merid = $4;}
X	| NUMBER ':' NUMBER NUMBER =
X		{hh = $1; mm = $3; merid = 24;
X		daylight = STANDARD; ourzone = -($4%100 + 60*$4/100);}
X	| NUMBER ':' NUMBER ':' NUMBER =
X		{hh = $1; mm = $3; ss = $5; merid = 24;}
X	| NUMBER ':' NUMBER ':' NUMBER MERIDIAN =
X		{hh = $1; mm = $3; ss = $5; merid = $6;}
X	| NUMBER ':' NUMBER ':' NUMBER NUMBER =
X		{hh = $1; mm = $3; ss = $5; merid = 24;
X		daylight = STANDARD; ourzone = -($6%100 + 60*$6/100);};
X
Xzone:	ZONE =
X		{ourzone = $1; daylight = STANDARD;}
X	| DAYZONE =
X		{ourzone = $1; daylight = DAYLIGHT;};
X
Xdyspec:	DAY =
X		{dayord = 1; dayreq = $1;}
X	| DAY ',' =
X		{dayord = 1; dayreq = $1;}
X	| NUMBER DAY =
X		{dayord = $1; dayreq = $2;};
X
Xdtspec:	NUMBER '/' NUMBER =
X		{month = $1; day = $3;}
X	| NUMBER '/' NUMBER '/' NUMBER =
X		{month = $1; day = $3; year = $5;}
X	| MONTH NUMBER =
X		{month = $1; day = $2;}
X	| MONTH NUMBER ',' NUMBER =
X		{month = $1; day = $2; year = $4;}
X	| NUMBER MONTH =
X		{month = $2; day = $1;}
X	| NUMBER MONTH NUMBER =
X		{month = $2; day = $1; year = $3;};
X
X
Xrspec:	NUMBER UNIT =
X		{relsec +=  60L * $1 * $2;}
X	| NUMBER MUNIT =
X		{relmonth += $1 * $2;}
X	| NUMBER SUNIT =
X		{relsec += $1;}
X	| UNIT =
X		{relsec +=  60L * $1;}
X	| MUNIT =
X		{relmonth += $1;}
X	| SUNIT =
X		{relsec++;}
X	| rspec AGO =
X		{relsec = -relsec; relmonth = -relmonth;};
X%%
X
Xstatic int mdays[12] =
X	{31, 0, 31,  30, 31, 30,  31, 31, 30,  31, 30, 31};
X#define epoch 1970
X
Xextern struct tm *localtime();
Xtime_t dateconv(mm, dd, yy, h, m, s, mer, zone, dayflag)
Xint mm, dd, yy, h, m, s, mer, zone, dayflag;
X{
X	time_t tod, jdate;
X	register int i;
X	time_t timeconv();
X
X	if (yy < 0) yy = -yy;
X	if (yy < 100) yy += 1900;
X	mdays[1] = 28 + (yy%4 == 0 && (yy%100 != 0 || yy%400 == 0));
X	if (yy < epoch || yy > 1999 || mm < 1 || mm > 12 ||
X		dd < 1 || dd > mdays[--mm]) return (-1);
X	jdate = dd-1;
X        for (i=0; i<mm; i++) jdate += mdays[i];
X	for (i = epoch; i < yy; i++) jdate += 365 + (i%4 == 0);
X	jdate *= daysec;
X	jdate += zone * 60L;
X	if ((tod = timeconv(h, m, s, mer)) < 0) return (-1);
X	jdate += tod;
X	if (dayflag==DAYLIGHT || (dayflag==MAYBE&&localtime(&jdate)->tm_isdst))
X		jdate += -1*60*60;
X	return (jdate);
X}
X
Xtime_t dayconv(ord, day, now) int ord, day; time_t now;
X{
X	register struct tm *loctime;
X	time_t tod;
X	time_t daylcorr();
X
X	tod = now;
X	loctime = localtime(&tod);
X	tod += daysec * ((day - loctime->tm_wday + 7) % 7);
X	tod += 7*daysec*(ord<=0?ord:ord-1);
X	return daylcorr(tod, now);
X}
X
Xtime_t timeconv(hh, mm, ss, mer) register int hh, mm, ss, mer;
X{
X	if (mm < 0 || mm > 59 || ss < 0 || ss > 59) return (-1);
X	switch (mer) {
X		case AM: if (hh < 1 || hh > 12) return(-1);
X			 return (60L * ((hh%12)*60L + mm)+ss);
X		case PM: if (hh < 1 || hh > 12) return(-1);
X			 return (60L * ((hh%12 +12)*60L + mm)+ss);
X		case 24: if (hh < 0 || hh > 23) return (-1);
X			 return (60L * (hh*60L + mm)+ss);
X		default: return (-1);
X	}
X}
Xtime_t monthadd(sdate, relmonth) time_t sdate, relmonth;
X{
X	struct tm *ltime;
X	time_t dateconv();
X	time_t daylcorr();
X	int mm, yy;
X
X	if (relmonth == 0) return 0;
X	ltime = localtime(&sdate);
X	mm = 12*ltime->tm_year + ltime->tm_mon + relmonth;
X	yy = mm/12;
X	mm = mm%12 + 1;
X	return daylcorr(dateconv(mm, ltime->tm_mday, yy, ltime->tm_hour,
X		ltime->tm_min, ltime->tm_sec, 24, ourzone, MAYBE), sdate);
X}
X
Xtime_t daylcorr(future, now) time_t future, now;
X{
X	int fdayl, nowdayl;
X
X	nowdayl = (localtime(&now)->tm_hour+1) % 24;
X	fdayl = (localtime(&future)->tm_hour+1) % 24;
X	return (future-now) + 60L*60L*(nowdayl-fdayl);
X}
X
Xstatic char *lptr;
X
Xyylex()
X{
X	extern int yylval;
X	int sign;
X	register char c;
X	register char *p;
X	char idbuf[20];
X	int pcnt;
X
X	for (;;) {
X		while (isspace(*lptr)) lptr++;
X
X		if (isdigit(c = *lptr) || c == '-' || c == '+') {
X			if (c== '-' || c == '+') {
X				if (c=='-') sign = -1;
X				else sign = 1;
X				if (!isdigit(*++lptr)) {
X					/* yylval = sign; return (NUMBER); */
X					return yylex();	/* skip the '-' sign */
X				}
X			} else sign = 1;
X			yylval = 0;
X			while (isdigit(c = *lptr++)) yylval = 10*yylval + c - '0';
X			yylval *= sign;
X			lptr--;
X			return (NUMBER);
X
X		} else if (isalpha(c)) {
X			p = idbuf;
X			while (isalpha(c = *lptr++) || c=='.')
X				if (p < &idbuf[sizeof(idbuf)-1])
X					*p++ = c;
X			*p = '\0';
X			lptr--;
X			return (lookup(idbuf));
X		}
X
X		else if (c == '(') {
X			pcnt = 0;
X			do {
X				c = *lptr++;
X				if (c == '\0') return(c);
X				else if (c == '(') pcnt++;
X				else if (c == ')') pcnt--;
X			} while (pcnt > 0);
X		}
X
X		else return (*lptr++);
X	}
X}
X
Xstruct table {
X	char *name;
X	int type, value;
X};
X
Xstruct table mdtab[] = {
X	{"January", MONTH, 1},
X	{"February", MONTH, 2},
X	{"March", MONTH, 3},
X	{"April", MONTH, 4},
X	{"May", MONTH, 5},
X	{"June", MONTH, 6},
X	{"July", MONTH, 7},
X	{"August", MONTH, 8},
X	{"September", MONTH, 9},
X	{"Sept", MONTH, 9},
X	{"October", MONTH, 10},
X	{"November", MONTH, 11},
X	{"December", MONTH, 12},
X
X	{"Sunday", DAY, 0},
X	{"Monday", DAY, 1},
X	{"Tuesday", DAY, 2},
X	{"Tues", DAY, 2},
X	{"Wednesday", DAY, 3},
X	{"Wednes", DAY, 3},
X	{"Thursday", DAY, 4},
X	{"Thur", DAY, 4},
X	{"Thurs", DAY, 4},
X	{"Friday", DAY, 5},
X	{"Saturday", DAY, 6},
X	{0, 0, 0}};
X
X#define HRS *60
X#define HALFHR 30
Xstruct table mztab[] = {
X	{"a.m.", MERIDIAN, AM},
X	{"am", MERIDIAN, AM},
X	{"p.m.", MERIDIAN, PM},
X	{"pm", MERIDIAN, PM},
X	{"nst", ZONE, 3 HRS + HALFHR},		/* Newfoundland */
X	{"n.s.t.", ZONE, 3 HRS + HALFHR},
X	{"ast", ZONE, 4 HRS},		/* Atlantic */
X	{"a.s.t.", ZONE, 4 HRS},
X	{"adt", DAYZONE, 4 HRS},
X	{"a.d.t.", DAYZONE, 4 HRS},
X	{"est", ZONE, 5 HRS},		/* Eastern */
X	{"e.s.t.", ZONE, 5 HRS},
X	{"edt", DAYZONE, 5 HRS},
X	{"e.d.t.", DAYZONE, 5 HRS},
X	{"cst", ZONE, 6 HRS},		/* Central */
X	{"c.s.t.", ZONE, 6 HRS},
X	{"cdt", DAYZONE, 6 HRS},
X	{"c.d.t.", DAYZONE, 6 HRS},
X	{"mst", ZONE, 7 HRS},		/* Mountain */
X	{"m.s.t.", ZONE, 7 HRS},
X	{"mdt", DAYZONE, 7 HRS},
X	{"m.d.t.", DAYZONE, 7 HRS},
X	{"pst", ZONE, 8 HRS},		/* Pacific */
X	{"p.s.t.", ZONE, 8 HRS},
X	{"pdt", DAYZONE, 8 HRS},
X	{"p.d.t.", DAYZONE, 8 HRS},
X	{"yst", ZONE, 9 HRS},		/* Yukon */
X	{"y.s.t.", ZONE, 9 HRS},
X	{"ydt", DAYZONE, 9 HRS},
X	{"y.d.t.", DAYZONE, 9 HRS},
X	{"hst", ZONE, 10 HRS},		/* Hawaii */
X	{"h.s.t.", ZONE, 10 HRS},
X	{"hdt", DAYZONE, 10 HRS},
X	{"h.d.t.", DAYZONE, 10 HRS},
X
X	{"gmt", ZONE, 0 HRS},
X	{"g.m.t.", ZONE, 0 HRS},
X	{"bst", DAYZONE, 0 HRS},		/* British Summer Time */
X	{"b.s.t.", DAYZONE, 0 HRS},
X	{"eet", ZONE, 0 HRS},		/* European Eastern Time */
X	{"e.e.t.", ZONE, 0 HRS},
X	{"eest", DAYZONE, 0 HRS},	/* European Eastern Summer Time */
X	{"e.e.s.t.", DAYZONE, 0 HRS},
X	{"met", ZONE, -1 HRS},		/* Middle European Time */
X	{"m.e.t.", ZONE, -1 HRS},
X	{"mest", DAYZONE, -1 HRS},	/* Middle European Summer Time */
X	{"m.e.s.t.", DAYZONE, -1 HRS},
X	{"wet", ZONE, -2 HRS },		/* Western European Time */
X	{"w.e.t.", ZONE, -2 HRS },
X	{"west", DAYZONE, -2 HRS},	/* Western European Summer Time */
X	{"w.e.s.t.", DAYZONE, -2 HRS},
X
X	{"jst", ZONE, -9 HRS},		/* Japan Standard Time */
X	{"j.s.t.", ZONE, -9 HRS},	/* Japan Standard Time */
X					/* No daylight savings time */
X
X	{"aest", ZONE, -10 HRS},	/* Australian Eastern Time */
X	{"a.e.s.t.", ZONE, -10 HRS},
X	{"aesst", DAYZONE, -10 HRS},	/* Australian Eastern Summer Time */
X	{"a.e.s.s.t.", DAYZONE, -10 HRS},
X	{"acst", ZONE, -(9 HRS + HALFHR)},	/* Australian Central Time */
X	{"a.c.s.t.", ZONE, -(9 HRS + HALFHR)},
X	{"acsst", DAYZONE, -(9 HRS + HALFHR)},	/* Australian Central Summer */
X	{"a.c.s.s.t.", DAYZONE, -(9 HRS + HALFHR)},
X	{"awst", ZONE, -8 HRS},		/* Australian Western Time */
X	{"a.w.s.t.", ZONE, -8 HRS},	/* (no daylight time there, I'm told */
X	{0, 0, 0}};
X
Xstruct table unittb[] = {
X	{"year", MUNIT, 12},
X	{"month", MUNIT, 1},
X	{"fortnight", UNIT, 14*24*60},
X	{"week", UNIT, 7*24*60},
X	{"day", UNIT, 1*24*60},
X	{"hour", UNIT, 60},
X	{"minute", UNIT, 1},
X	{"min", UNIT, 1},
X	{"second", SUNIT, 1},
X	{"sec", SUNIT, 1},
X	{0, 0, 0}};
X
Xstruct table othertb[] = {
X	{"tomorrow", UNIT, 1*24*60},
X	{"yesterday", UNIT, -1*24*60},
X	{"today", UNIT, 0},
X	{"now", UNIT, 0},
X	{"last", NUMBER, -1},
X	{"this", UNIT, 0},
X	{"next", NUMBER, 2},
X	{"first", NUMBER, 1},
X	/* {"second", NUMBER, 2}, */
X	{"third", NUMBER, 3},
X	{"fourth", NUMBER, 4},
X	{"fifth", NUMBER, 5},
X	{"sixth", NUMBER, 6},
X	{"seventh", NUMBER, 7},
X	{"eigth", NUMBER, 8},
X	{"ninth", NUMBER, 9},
X	{"tenth", NUMBER, 10},
X	{"eleventh", NUMBER, 11},
X	{"twelfth", NUMBER, 12},
X	{"ago", AGO, 1},
X	{0, 0, 0}};
X
Xstruct table milzone[] = {
X	{"a", ZONE, 1 HRS},
X	{"b", ZONE, 2 HRS},
X	{"c", ZONE, 3 HRS},
X	{"d", ZONE, 4 HRS},
X	{"e", ZONE, 5 HRS},
X	{"f", ZONE, 6 HRS},
X	{"g", ZONE, 7 HRS},
X	{"h", ZONE, 8 HRS},
X	{"i", ZONE, 9 HRS},
X	{"k", ZONE, 10 HRS},
X	{"l", ZONE, 11 HRS},
X	{"m", ZONE, 12 HRS},
X	{"n", ZONE, -1 HRS},
X	{"o", ZONE, -2 HRS},
X	{"p", ZONE, -3 HRS},
X	{"q", ZONE, -4 HRS},
X	{"r", ZONE, -5 HRS},
X	{"s", ZONE, -6 HRS},
X	{"t", ZONE, -7 HRS},
X	{"u", ZONE, -8 HRS},
X	{"v", ZONE, -9 HRS},
X	{"w", ZONE, -10 HRS},
X	{"x", ZONE, -11 HRS},
X	{"y", ZONE, -12 HRS},
X	{"z", ZONE, 0 HRS},
X	{0, 0, 0}};
X
Xlookup(id) char *id;
X{
X#define gotit (yylval=i->value,  i->type)
X#define getid for(j=idvar, k=id; *j++ = *k++; )
X
X	char idvar[20];
X	register char *j, *k;
X	register struct table *i;
X	int abbrev;
X
X	getid;
X	if (strlen(idvar) == 3) abbrev = 1;
X	else if (strlen(idvar) == 4 && idvar[3] == '.') {
X		abbrev = 1;
X		idvar[3] = '\0';
X	}
X	else abbrev = 0;
X
X	if (islower(*idvar)) *idvar = toupper(*idvar);
X
X	for (i = mdtab; i->name; i++) {
X		k = idvar;
X		for (j = i->name; *j++ == *k++;) {
X			if (abbrev && j==i->name+3) return gotit;
X			if (j[-1] == 0) return gotit;
X		}
X	}
X
X	getid;
X	for (i = mztab; i->name; i++)
X		if (strcmp(i->name, idvar) == 0) return gotit;
X
X	for (j = idvar; *j; j++)
X		if (isupper(*j)) *j = tolower(*j);
X	for (i=mztab; i->name; i++)
X		if (strcmp(i->name, idvar) == 0) return gotit;
X
X	getid;
X	for (i=unittb; i->name; i++)
X		if (strcmp(i->name, idvar) == 0) return gotit;
X
X	if (idvar[strlen(idvar)-1] == 's')
X		idvar[strlen(idvar)-1] = '\0';
X	for (i=unittb; i->name; i++)
X		if (strcmp(i->name, idvar) == 0) return gotit;
X
X	getid;
X	for (i = othertb; i->name; i++)
X		if (strcmp(i->name, idvar) == 0) return gotit;
X
X	getid;
X	if (strlen(idvar) == 1 && isalpha(*idvar)) {
X		if (isupper(*idvar)) *idvar = tolower(*idvar);
X		for (i = milzone; i->name; i++)
X			if (strcmp(i->name, idvar) == 0) return gotit;
X	}
X
X	return(ID);
X}
X
Xtime_t getdate(p, now, zone) char *p; time_t now; long zone;
X{
X#define mcheck(f)	if (f>1) err++
X	time_t monthadd();
X	int err;
X	struct tm *lt;
X	time_t sdate, tod;
X
X	lptr = p;
X	if (now <= 0)
X		(void) time(&now);
X	lt = localtime(&now);
X	year = lt->tm_year;
X	month = lt->tm_mon+1;
X	day = lt->tm_mday;
X	relsec = 0; relmonth = 0;
X	timeflag=zoneflag=dateflag=dayflag=relflag=0;
X	daylight = MAYBE;
X	hh = mm = ss = 0;
X	merid = 24;
X	ourzone = zone;
X
X	if (err = yyparse()) return (-1);
X
X	mcheck(timeflag);
X	mcheck(zoneflag);
X	mcheck(dateflag);
X	mcheck(dayflag);
X
X	if (err) return (-1);
X	if (dateflag || timeflag || dayflag) {
X		sdate = dateconv(month,day,year,hh,mm,ss,merid,ourzone,daylight);
X		if (sdate < 0) return -1;
X	}
X	else {
X		sdate = now;
X		if (relflag == 0)
X			sdate -= (lt->tm_sec + lt->tm_min*60 +
X				lt->tm_hour*(60L*60L));
X	}
X
X	sdate += relsec;
X	sdate += monthadd(sdate, relmonth);
X
X	if (dayflag && !dateflag) {
X		tod = dayconv(dayord, dayreq, sdate);
X		sdate += tod;
X	}
X
X	return sdate;
X}
X
Xyyerror(s) char *s;
X{}
SHAR_EOF
chmod 0660 getdate.y || echo "restore of getdate.y fails"
echo "x - extracting head.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > head.c &&
X/* $Header: head.c,v 4.3.3.1 90/07/21 20:19:26 davison Trn $
X *
X * $Log:	head.c,v $
X * Revision 4.3.3.1  90/07/21  20:19:26  davison
X * Initial Trn Release
X * 
X * Revision 4.3.2.5  90/03/22  23:04:22  sob
X * Fixes provided by Wayne Davison <drivax!davison>
X * 
X * Revision 4.3.2.4  89/11/27  01:30:35  sob
X * Altered NNTP code per ideas suggested by Bela Lubkin
X * <filbo at gorn.santa-cruz.ca.us>
X * 
X * Revision 4.3.2.3  89/11/26  22:53:52  sob
X * Add new patches to make RRN be faster.
X * 
X * Revision 4.3.2.2  89/11/08  01:17:46  sob
X * Added changes to insure that this will compile for RN or RRN with no
X * changes to the source code.
X * 
X * Revision 4.3.2.1  89/11/06  00:37:18  sob
X * Added RRN support from NNTP 1.5
X * 
X * Revision 4.3.1.2  85/05/10  13:47:25  lwall
X * Added debugging stuff.
X * 
X * Revision 4.3.1.1  85/05/10  11:32:30  lwall
X * Branch for patches.
X * 
X * Revision 4.3  85/05/01  11:38:21  lwall
X * Baseline for release with 4.3bsd.
X * 
X */
X
X#include "EXTERN.h"
X#include "common.h"
X#include "artio.h"
X#include "bits.h"
X#ifdef SERVER
X#include "server.h"
X#endif
X#include "util.h"
X#include "INTERN.h"
X#include "head.h"
X
Xbool first_one;		/* is this the 1st occurance of this header line? */
X
Xstatic char htypeix[26] =
X    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
X
Xvoid
Xhead_init()
X{
X    register int i;
X
X    for (i=HEAD_FIRST+1; i<HEAD_LAST; i++)
X	htypeix[*htype[i].ht_name - 'a'] = i;
X}
X
X#ifdef DEBUGGING
Xdumpheader(where)
Xchar *where;
X{
X    register int i;
X
X    printf("header: %d %s", parsed_art, where);
X
X    for (i=0; i<HEAD_LAST; i++) {
X	printf("%15s %4d %4d %03o\n",htype[i].ht_name,
X	    htype[i].ht_minpos,
X	    htype[i].ht_maxpos,
X	    htype[i].ht_flags) FLUSH;
X    }
X}
X#endif
X
Xint
Xset_line_type(bufptr,colon)
Xchar *bufptr;
Xregister char *colon;
X{
X    char lc[LONGKEY+3];
X    register char *t, *f;
X    register int i, len;
X
X    if (colon-bufptr > LONGKEY+2)
X	return SOME_LINE;
X
X    for (t=lc,f=bufptr; f<colon; f++, t++) {
X	if (isspace(*f))
X	/* guard against space before : */
X	    break;
X	*t = isupper(*f) ? tolower(*f) : *f;
X    }
X    *t = '\0';
X    f = lc;				/* get lc into register */
X    len = t - f;
X
X    /* now scan the headtype table, backwards so we don't have to supply an
X     * extra terminating value, using first letter as index, and length as
X     * optimization to avoid calling subroutine strEQ unnecessarily.  Hauls.
X     */
X    
X    if (islower(*f)) {
X	for (i = htypeix[*f - 'a']; *htype[i].ht_name == *f; --i) {
X	    if (len == htype[i].ht_length && strEQ(f, htype[i].ht_name)) {
X		return i;
X	    }
X	}
X    }
X    return SOME_LINE;
X}
X
Xvoid
Xstart_header(artnum)
XART_NUM artnum;
X{
X    register int i;
X
X#ifdef DEBUGGING
X    if (debug & 4)
X	dumpheader("start_header\n");
X#endif
X    for (i=0; i<HEAD_LAST; i++) {
X	htype[i].ht_minpos = -1;
X	htype[i].ht_maxpos = 0;
X    }
X    in_header = SOME_LINE;
X    first_one = FALSE;
X#ifdef ASYNC_PARSE
X    parsed_art = artnum;
X#endif
X}
X
Xbool
Xparseline(art_buf,newhide,oldhide)
Xchar *art_buf;
Xint newhide, oldhide;
X{
X    if (*art_buf == ' ' || *art_buf == '\t')
X					/* header continuation line? */
X	return oldhide;
X    else {				/* maybe another header line */
X	char *s;
X
X	if (first_one) {		/* did we just pass 1st occurance? */
X	    first_one = FALSE;
X	    htype[in_header].ht_maxpos = artpos;
X					/* remember where line left off */
X	}
X	s = index(art_buf,':');
X	if (s == Nullch) {
X			    /* is it the end of the header? */
X	    htype[PAST_HEADER].ht_minpos =
X		(*art_buf == '\n') ? ftell(artfp) : artpos;
X			    /* remember where body starts */
X	    in_header = PAST_HEADER;
X	}
X	else {	/* it is a new header line */
X	    in_header = set_line_type(art_buf,s);
X	    first_one = (htype[in_header].ht_minpos < 0);
X	    if (first_one)
X		htype[in_header].ht_minpos = artpos;
X#ifdef DEBUGGING
X	    if (debug & 4)
X		dumpheader(art_buf);
X#endif
X	    if (htype[in_header].ht_flags & HT_HIDE)
X		return newhide;
X	}
X    }
X    return FALSE;			/* don't hide this line */
X}
X
X#ifdef ASYNC_PARSE
Xint
Xparse_maybe(artnum)
XART_NUM artnum;
X{
X    char tmpbuf[LBUFLEN];
X
X    if (parsed_art == artnum)
X	return 0;
X    /* no maybe about it now */
X#ifdef SERVER
X    if (nntpopen(artnum,GET_HEADER) == Nullfp) {
X#else
X    if (artopen(artnum) == Nullfp) {
X#endif
X	return -1;
X    }
X    start_header(artnum);
X    while (in_header) {
X	artpos = ftell(artfp);
X	if (fgets(tmpbuf,LBUFLEN,artfp) == Nullch)
X	    break;
X	parseline(tmpbuf,FALSE,FALSE);
X    }
X    in_header = PAST_HEADER;
X    return 0;
X}
X#endif
X
X/* get the subject line for an article */
X
Xchar *
Xfetchsubj(artnum,current_subject,copy)
XART_NUM artnum;				/* article to get subject from */
Xbool current_subject;			/* is it in a parsed header? */
Xbool copy;				/* do you want it savestr()ed? */
X{
X    char *s = Nullch, *t;
X#ifdef SERVER
X    static int xhdr = 1;		/* Can we use xhdr command? */
X    int eoo;				/* End of server output */
X    char ser_line[256];
X#endif /* SERVER */
X
X#ifdef CACHESUBJ
X    if (!subj_list) {
X	register ART_NUM i;
X	
X
X#ifndef lint
X	subj_list =
X	  (char**)safemalloc((MEM_SIZE)((OFFSET(lastart)+2)*sizeof(char *)));
X#endif /* lint */
X	for (i=0; i<=OFFSET(lastart); i++)
X	    subj_list[i] = Nullch;
X    }
X    if (!artnum || artnum > lastart)
X	s = nullstr;
X    else
X	s = subj_list[OFFSET(artnum)];
X#endif
X    if (s == Nullch) {
X	if (current_subject) {
X	    s = fetchlines(artnum,SUBJ_LINE);
X#ifdef CACHESUBJ
X	    subj_list[OFFSET(artnum)] = s;
X#endif
X	}
X	else {
X	    s = safemalloc((MEM_SIZE)256);
X	    *s = '\0';
X#ifdef SERVER
X	    if (xhdr) {
X	    	sprintf(ser_line, "XHDR subject %ld", artnum);
X	    	put_server(ser_line);
X		if (get_server(ser_line, sizeof (ser_line)) >= 0) {
X			if (ser_line[0] == CHAR_FATAL) {
X			    xhdr = 0;
X			} else {
X			    while (get_server(ser_line, sizeof (ser_line)) >= 0) {
X				if (ser_line[0] == '.')
X				    break;
X				else {
X				    t = index(ser_line, ' ');
X				    if (t++) {
X					strcpy(s, t);
X					if (t = index(s, '\r'))
X						*t = '\0';
X				    }
X				}
X			    }
X			}
X		} else {
X		    fprintf(stderr,
X			"rrn: Unexpected close of server socket.\n");
X		    finalize(1);
X		}
X	    }
X
X	    if (!xhdr) {
X		sprintf(ser_line, "HEAD %ld", artnum);
X		put_server(ser_line);
X		eoo = 0;
X		if (get_server(ser_line, 256) >= 0 && ser_line[0] == CHAR_OK) {
X		    do {
X			if (get_server(s, 256) < 0 || (*s == '.')) {
X			strcpy(s, "Title: \n");
X			eoo = 1;
X		        }
X		    } while (strnNE(s,"Title:",6) && strnNE(s,"Subject:",8));
X
X		    if (!eoo)
X			while (get_server(ser_line, sizeof (ser_line)) >= 0 &&
X				ser_line[0] != '.');
X		    t = index(s,':')+1;
X		    while (*t == ' ') t++;
X		    strcpy(s, t);
X	        }
X	    }
X#else /* not SERVER */
X	    if (artopen(artnum) != Nullfp) {
X		do {
X		    if (fgets(s,256,artfp) == Nullch)
X			strcpy(s, "Title: \n");
X		} while (strnNE(s,"Title:",6) && strnNE(s,"Subject:",8));
X
X		s[strlen(s)-1] = '\0';
X		t = index(s,':')+1;
X		while (*t == ' ') t++;
X		strcpy(s, t);
X	    }
X#endif
X	    s = saferealloc(s, (MEM_SIZE)strlen(s)+1);
X#ifdef CACHESUBJ
X	    subj_list[OFFSET(artnum)] = s;
X#endif 
X	}
X    }
X#ifdef CACHESUBJ
X    if (copy) {
X	t = savestr(s);
X	return t;
X    }
X    else
X	return s;
X#else
X    if (copy)
X	return s;
X    else {
X	safecpy(cmd_buf,s,CBUFLEN);	/* hope this is okay--we're */
X	free(s);
X	return cmd_buf;			/* really scraping for space here */
X    }
X#endif
X}
X
X/* get header lines from an article */
X
Xchar *
Xfetchlines(artnum,which_line)
XART_NUM artnum;				/* article to get line from */
Xint which_line;				/* type of line desired */
X{
X    char *newbuf, *t, tmp_buf[LBUFLEN];
X    register ART_POS curpos;
X    int size;
X    register ART_POS firstpos;
X    register ART_POS lastpos;
X    
X#ifdef ASYNC_PARSE
X    if (parse_maybe(artnum))
X	artnum = 0;
X#endif
X    firstpos = htype[which_line].ht_minpos;
X    lastpos = htype[which_line].ht_maxpos;
X#ifdef SERVER
X    if (!artnum || firstpos < 0 || nntpopen(artnum,GET_HEADER) == Nullfp) {
X#else
X    if (!artnum || firstpos < 0 || artopen(artnum) == Nullfp) {
X#endif
X	newbuf = safemalloc((unsigned int)1);
X	*newbuf = '\0';
X	return newbuf;
X    }
X#ifndef lint
X    size = lastpos - firstpos + 1;
X#else
X    size = Null(int);
X#endif /* lint */
X#ifdef DEBUGGING
X    if (debug && (size < 1 || size > 1000)) {
X	printf("Firstpos = %ld, lastpos = %ld\n",(long)firstpos,(long)lastpos);
X	gets(tmp_buf);
X    }
X#endif
X    newbuf = safemalloc((unsigned int)size);
X    *newbuf = '\0';
X    fseek(artfp,firstpos,0);
X    for (curpos = firstpos; curpos < lastpos; curpos = ftell(artfp)) {
X	if (fgets(tmp_buf,LBUFLEN,artfp) == Nullch)
X	    break;
X	if (*tmp_buf == ' ' || *tmp_buf == '\t')
X	    t = tmp_buf;
X	else
X	    t = index(tmp_buf,':')+1;
X	if (t == Nullch)
X	    break;
X	else {
X	    while (*t == ' ' || *t == '\t') t++;
X	    safecat(newbuf,t,size);
X	}
X    }
X    return newbuf;
X}
X
SHAR_EOF
chmod 0660 head.c || echo "restore of head.c fails"
echo "x - extracting head.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > head.h &&
X/* $Header: head.h,v 4.3.3.1 90/06/20 22:37:18 davison Trn $
X *
X * $Log:	head.h,v $
X * Revision 4.3.3.1  90/06/20  22:37:18  davison
X * Initial Trn Release
X * 
X * Revision 4.3  85/05/01  11:38:31  lwall
X * Baseline for release with 4.3bsd.
X * 
X */
X
X#define HEAD_FIRST 1
X
X/* types of header lines (if only C really believed in enums)
X * (These must stay in alphabetic order at least in the first letter.
X * Within each letter it helps to arrange in increasing likelihood.)
X */
X
X#define PAST_HEADER	0	/* body */
X#define SOME_LINE	1	/* unrecognized */
X#define ARTID_LINE	2	/* article-i.d. */
X#define APPR_LINE	3	/* approved */
X#define DIST_LINE	4	/* distribution */
X#define DATE_LINE	5	/* date */
X#define RECEIVED_LINE	6	/* date-received */
X#define EXPIR_LINE	7	/* expires */
X#define FOLLOW_LINE	8	/* followup-to */
X#define FROM_LINE	9	/* from */
X#define KEYW_LINE	10	/* keywords */
X#define LINES_LINE	11	/* lines */
X#define MESSID_LINE	12	/* message-id */
X#define NFFR_LINE	13	/* nf-from */
X#define NFID_LINE	14	/* nf-id */
X#define NGS_LINE	15	/* newsgroups */
X#define ORG_LINE	16	/* organization */
X#define PATH_LINE	17	/* path */
X#define POSTED_LINE	18	/* posted */
X#define PVER_LINE	19	/* posting-version */
X#define REPLY_LINE	20	/* reply-to */
X#define REFS_LINE	21	/* references */
X#define RVER_LINE	22	/* relay-version */
X#define SENDER_LINE	23	/* sender */
X#define SUMRY_LINE	24	/* summary */
X#define SUBJ_LINE	25	/* subject */
X#define XREF_LINE	26	/* xref */
X
X#define HEAD_LAST	27	/* one more than the last one above */
X
Xstruct headtype {
X    char *ht_name;		/* header line identifier */
X#ifdef pdp11
X    short ht_minpos;
X    short ht_maxpos;
X#else
X    ART_POS ht_minpos;		/* pointer to beginning of line in article */
X    ART_POS ht_maxpos;		/* pointer to end of line in article */
X#endif
X    char ht_length;		/* could make these into nybbles but */
X    char ht_flags;		/* it wouldn't save space normally */
X};				/* due to alignment considerations */
X
X#define HT_HIDE 1	/* -h on this line */
X#define HT_MAGIC 2	/* do any special processing on this line */
X
X/* This array must stay in the same order as the list above */
X
X#ifndef DOINIT
XEXT struct headtype htype[HEAD_LAST];
X#else
Xstruct headtype htype[HEAD_LAST] = {
X /* name             minpos   maxpos  length   flag */
X    {"BODY",		0,	0,	4,	0		},
X    {"unrecognized",	0,	0,	12,	0		},
X    {"article-i.d.",	0,	0,	12,	HT_HIDE		},
X    {"approved",	0,	0,	8,	HT_HIDE		},
X    {"distribution",	0,	0,	12,	0		},
X#ifdef USETHREADS
X    {"date",		0,	0,	4,	HT_MAGIC	},
X#else
X    {"date",		0,	0,	4,	0		},
X#endif
X    {"date-received",	0,	0,	13,	0		},
X    {"expires",		0,	0,	7,	HT_HIDE|HT_MAGIC},
X    {"followup-to",	0,	0,	11,	0		},
X    {"from",		0,	0,	4,	HT_MAGIC	},
X    {"keywords",	0,	0,	8,	0		},
X    {"lines",		0,	0,	5,	0		},
X    {"message-id",	0,	0,	10,	HT_HIDE		},
X    {"nf-from",		0,	0,	7,	HT_HIDE		},
X    {"nf-id",		0,	0,	5,	HT_HIDE		},
X    {"newsgroups",	0,	0,	10,	HT_MAGIC|HT_HIDE},
X    {"organization",	0,	0,	12,	0		},
X    {"path",		0,	0,	4,	HT_HIDE		},
X    {"posted",		0,	0,	6,	HT_HIDE		},
X    {"posting-version",	0,	0,	15,	HT_HIDE		},
X    {"reply-to",	0,	0,	8,	HT_HIDE		},
X    {"references",	0,	0,	10,	HT_HIDE		},
X    {"relay-version",	0,	0,	13,	HT_HIDE		},
X    {"sender",		0,	0,	6,	HT_HIDE		},
X    {"summary",		0,	0,	7,	0		},
X    {"subject",		0,	0,	7,	HT_MAGIC	},
X    {"xref",		0,	0,	4,	HT_HIDE		}
X};
X#endif
X
X#ifdef ASYNC_PARSE
XEXT ART_NUM parsed_art INIT(0);
X#endif
X
XEXT char in_header INIT(0);		/* are we decoding the header? */
X
X#ifdef CACHESUBJ
X    EXT char **subj_list INIT(Null(char **));
X#endif
X
Xvoid	head_init();
Xint	set_line_type();
Xvoid	start_header();
Xbool    parseline();
X#ifdef ASYNC_PARSE
X    int		parse_maybe();
X#endif
Xchar	*fetchsubj();
Xchar	*fetchlines();
SHAR_EOF
chmod 0660 head.h || echo "restore of head.h fails"
echo "x - extracting help.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > help.c &&
X/* $Header: help.c,v 4.3.3.1 90/07/24 21:52:37 davison Trn $
X *
X * $Log:	help.c,v $
X * Revision 4.3.3.1  90/07/24  21:52:37  davison
X * Initial Trn Release
X * 
X * Revision 4.3.1.2  85/09/10  11:05:39  lwall
X * Improved %m in in_char().
X * 
X * Revision 4.3.1.1  85/05/10  11:33:10  lwall
X * Branch for patches.
X * 
X * Revision 4.3  85/05/01  11:38:59  lwall
X * Baseline for release with 4.3bsd.
X * 
X */
X
X#include "EXTERN.h"
X#include "common.h"
X#include "rn.h"
X#include "term.h"
X#include "INTERN.h"
X#include "help.h"
X
Xvoid
Xhelp_init()
X{
X    ;
X}
X
Xint
Xhelp_page()
X{
X    int cmd;
X
X#ifdef PAGERHELP
X    doshell(sh,filexp(PAGERHELP));
X#else
X    page_init();
X    if ((cmd = print_lines("\
XPaging commands:\n\
X",STANDOUT)) ||
X    (cmd = print_lines("\n\
XSP	Display the next page.\n\
Xx	Display the next page decrypted (rot13).\n\
Xd	Display half a page more.\n\
XCR	Display one more line.\n\
X^R,v,^X	Restart the current article (v=verbose header, ^X=rot13).\n\
X",NOMARKING)) ||
X    (cmd = print_lines("\
Xb	Back up one page.\n\
X^L,X	Refresh the screen (X=rot13).\n\
X",NOMARKING)) ||
X#ifdef USETHREADS
X    (cmd = print_lines("\
Xt	Display the entire article tree and all its subjects.\n\
X",NOMARKING)) ||
X#endif
X    (cmd = print_lines("\
Xg pat	Go to (search forward within article for) pattern.\n\
XG	Search again for current pattern within article.\n\
X^G	Search for next line beginning with \"Subject:\".\n\
XTAB	Search for next line beginning with a different character.\n\
Xq	Quit the pager, go to end of article.  Leave article read or unread.\n\
Xj	Junk this article (mark it read).  Goes to end of article.\n\
X\n\
X",NOMARKING)) ||
X    (cmd = print_lines("\
XThe following commands skip the rest of the current article, then behave\n\
Xjust as if typed to the 'What next?' prompt at the end of the article:\n\
X",STANDOUT)) ||
X    (cmd = print_lines("\n\
Xn	Scan forward for next unread article.\n\
XN	Go to next article.\n\
X^N	Scan forward for next unread article with same title.\n\
Xp,P,^P	Same as n,N,^N, only going backwards.\n\
X-	Go to previously displayed article.\n\
X",NOMARKING)) ||
X#ifdef USETHREADS
X    (cmd = print_lines("\
X<,>	Browse the previous/next selected thread.  If no threads are selected,\n\
X	all threads that had unread news upon entry to the group are considered\n\
X	selected for browsing.  Entering an empty group browses all threads.\n\
X[,],{,} Go to parent/child/root/leaf in thread.\n\
X\n\
X",NOMARKING)) ||
X#endif
X    (cmd = print_lines("\
XThe following commands also take you to the end of the article.\n\
XType h at end of article for a description of these commands:\n\
X",STANDOUT)) ||
X#ifdef USETHREADS
X    (cmd = print_lines("\
X	# $ & / = ? c C f F k K ^K J , m M number e r R ^R s S u U v w W Y ^ |\n\
X\n\
X(To return to the middle of the article after one of these commands, type ^L.)\n\
X",NOMARKING)) )
X#else
X    (cmd = print_lines("\
X	# $ & / = ? c C f F k K ^K m M number e r R ^R s S u v w W Y ^ |\n\
X\n\
X(To return to the middle of the article after one of these commands, type ^L.)\n\
X",NOMARKING)) )
X#endif
X	return cmd;
X#endif
X    return 0;
X}
X
Xint
Xhelp_art()
X{
X    int cmd;
X#ifdef ARTHELP
X    doshell(sh,filexp(ARTHELP));
X#else
X    page_init();
X    if ((cmd = print_lines("\
XArticle Selection commands:\n\
X",STANDOUT)) ||
X#ifdef USETHREADS
X    (cmd = print_lines("\n\
Xn,SP	Find next unread article (follows discussion-tree in threaded groups).\n\
X",NOMARKING)) ||
X#else
X    (cmd = print_lines("\n\
Xn,SP	Scan forward for next unread article.\n\
X",NOMARKING)) ||
X#endif
X    (cmd = print_lines("\
XN	Go to next article.\n\
X^N	Scan forward for next unread article with same subject.\n\
Xp,P,^P	Same as n,N,^N, only going backwards.\n\
X-	Go to previously displayed article.\n\
X",NOMARKING)) ||
X#ifdef USETHREADS
X    (cmd = print_lines("\
X<,>	Browse the previous/next selected thread.  If no threads are selected,\n\
X	all threads that had unread news upon entry to the group are considered\n\
X	selected for browsing.  Entering an empty group browses all threads.\n\
X[,]	Go to article's parent/child.\n\
X{,}	Go to tree's root/leaf.\n\
Xt	Display the entire article tree and all its subjects.\n\
X",NOMARKING)) ||
X#endif
X    (cmd = print_lines("\
Xnumber	Go to specified article.\n\
Xrange{,range}:command{:command}\n\
X	Apply one or more commands to one or more ranges of articles.\n\
X	Ranges are of the form: number | number-number.  You may use . for\n\
X	the current article, and $ for the last article.\n\
X",NOMARKING)) ||
X#ifdef USETHREADS
X    (cmd = print_lines("\
X 	Valid commands are: e, j, m, M, s, S, t, T, |, +, and -.\n\
X:cmd	Perform a command on all the selected articles.\n\
X",NOMARKING)) ||
X#else
X    (cmd = print_lines("\
X 	Valid commands are: e, j, m, M, s, S, and |.\n\
X",NOMARKING)) ||
X#endif
X    (cmd = print_lines("\
X/pattern/modifiers\n\
X	Scan forward for article containing pattern in the subject line.\n\
X	(Use ?pat? to scan backwards; append h to scan headers, a to scan\n\
X	entire articles, r to scan read articles, c to make case sensitive.)\n\
X",NOMARKING)) ||
X    (cmd = print_lines("\
X/pattern/modifiers:command{:command}\n\
X	Apply one or more commands to the set of articles matching pattern.\n\
X	Use a K modifier to save entire command to the KILL file for this\n\
X	newsgroup.  Commands m and M, if first, imply an r modifier.\n\
X 	Valid commands are the same as for the range command.\n\
X",NOMARKING)) ||
X    (cmd = print_lines("\
Xf,F	Submit a followup article (F = include this article).\n\
Xr,R	Reply through net mail (R = include this article).\n\
Xe dir{|command}\n\
X	Extract to directory using /bin/sh, uudecode, or specified command.\n\
Xs ...	Save to file or pipe via sh.\n\
XS ...	Save via preferred shell.\n\
Xw,W	Like s and S but save without the header.\n\
X| ...	Same as s|...\n\
X",NOMARKING)) ||
X    (cmd = print_lines("\
XC	Cancel this article, if yours.\n\
X^R,v	Restart article (v=verbose).\n\
X^X	Restart article, rot13 mode.\n\
Xc	Catch up (mark all articles as read).\n\
Xb	Back up one page.\n\
X^L	Refresh the screen.  You can get back to the pager with this.\n\
XX	Refresh screen in rot13 mode.\n\
X",NOMARKING)) ||
X    (cmd = print_lines("\
X^	Go to first unread article.  Disables subject search mode.\n\
X$	Go to end of newsgroup.  Disables subject search mode.\n\
X",NOMARKING)) ||
X    (cmd = print_lines("#       Print last article number.\n\
X&	Print current values of command-line switches.\n\
X&switch {switch}\n\
X	Set or unset more switches.\n\
X&&	Print current macro definitions.\n\
X&&def	Define a new macro.\n\
Xj	Junk this article (mark it read).  Stays at end of article.\n\
X",NOMARKING)) ||
X    (cmd = print_lines("\
Xm	Mark article as still unread.\n\
XM	Mark article as still unread upon exiting newsgroup or Y command.\n\
XY	Yank back articles marked temporarily read via M.\n\
Xk	Kill current subject (mark articles as read).\n\
X",NOMARKING)) ||
X#ifdef USETHREADS
X    (cmd = print_lines("\
X,	Mark current article and its replies as read.\n\
XJ	Junk entire thread (mark all subjects as read in this thread).\n\
XT	Trash current thread (like 'J'), and save command in KILL file.\n\
X",NOMARKING)) ||
X#endif
X    (cmd = print_lines("\
XK	Mark current subject as read, and save command in KILL file.\n\
X^K	Edit local KILL file (the one for this newsgroup).\n\
X=	List subjects of unread articles.\n\
X",NOMARKING)) ||
X#ifdef USETHREADS
X    (cmd = print_lines("\
X+	Enter thread selection mode.\n\
XU	Unread some news -- prompts for thread, subthread, all, or select.\n\
X",NOMARKING)) ||
X#endif
X    (cmd = print_lines("\
Xu	Unsubscribe from this newsgroup.\n\
Xq	Quit this newsgroup for now.\n\
XQ	Quit newsgroup, staying at current newsgroup.\n\
X",NOMARKING)) )
X	return cmd;
X#endif
X    return 0;
X}
X
Xint
Xhelp_ng()
X{
X    int cmd;
X#ifdef NGHELP
X    doshell(sh,filexp(NGHELP));
X#else
X    page_init();
X    if (cmd = print_lines("\
XNewsgroup Selection commands:\n\
X",STANDOUT) )
X	return cmd;
X    if (ng != nextrcline) {
X	if ((cmd = print_lines("\
X\n\
Xy,SP	Do this newsgroup now.\n\
X.cmd	Do this newsgroup, executing cmd as first command.\n\
X",NOMARKING)) ||
X#ifdef USETHREADS
X    (cmd = print_lines("\
X+	Enter this newsgroup through the thread selector (like typing .+<CR>).\n\
X",NOMARKING)) ||
X#endif
X    (cmd = print_lines("\
X=	Start this newsgroup, but list subjects before reading articles.\n\
X",NOMARKING)) ||
X#ifdef USETHREADS
X    (cmd = print_lines("\
XU	Enter this newsgroup by way of the \"Set unread?\" prompt.\n\
X",NOMARKING)) ||
X#endif
X    (cmd = print_lines("\
Xu	Unsubscribe from this newsgroup.\n\
X",NOMARKING)) )
X	    return cmd;
X    }
X    if ((cmd = print_lines("\
Xc	Catch up (mark this newsgroup all read).\n\
X\n\
Xn	Go to the next newsgroup with unread news.\n\
XN	Go to the next newsgroup.\n\
Xp	Go to the previous newsgroup with unread news.\n\
XP	Go to the previous newsgroup.\n\
X",NOMARKING)) ||
X    (cmd = print_lines("\
X-	Go to the previously displayed newsgroup.\n\
X1	Go to the first newsgroup.\n\
X^	Go to the first newsgroup with unread news.\n\
X$	Go to the last newsgroup.\n\
X",NOMARKING)) ||
X    (cmd = print_lines("\
Xg name	Go to the named newsgroup.  Subscribe to new newsgroups this way too.\n\
X/pat	Search forward for newsgroup matching pattern.\n\
X?pat	Search backward for newsgroup matching pattern.\n\
X	(Use * and ? style patterns.  Append r to include read newsgroups.)\n\
X",NOMARKING)) ||
X    (cmd = print_lines("\
Xl pat	List unsubscribed newsgroups containing pattern.\n\
Xm name	Move named newsgroup elsewhere (no name moves current newsgroup).\n\
Xo pat	Only display newsgroups matching pattern.  Omit pat to unrestrict.\n\
Xa pat	Like o, but also scans for unsubscribed newsgroups matching pattern.\n\
XL	List current .newsrc.\n\
X",NOMARKING)) ||
X    (cmd = print_lines("\
X&	Print current command-line switch settings.\n\
X&switch {switch}\n\
X	Set (or unset) more command-line switches.\n\
X&&	Print current macro definitions.\n\
X&&def	Define a new macro.\n\
X!cmd	Shell escape.\n\
X",NOMARKING)) ||
X    (cmd = print_lines("\
Xq	Quit trn.\n\
Xx	Quit, restoring .newsrc to its state at startup of trn.\n\
X^K	Edit the global KILL file.  Use commands like /pattern/j to suppress\n\
X	pattern in every newsgroup.\n\
Xv	Print version.\n\
X",NOMARKING)) )
X	return cmd;
X#endif
X#ifdef PUSHBACK
X    if (cmd = get_anything())
X	return cmd;
X    show_macros();
X#endif
SHAR_EOF
echo "End of part 6"
echo "File help.c is continued in part 7"
echo "7" > s2_seq_.tmp
exit 0

exit 0 # Just in case...
-- 
Please send comp.sources.unix-related mail to rsalz at uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.



More information about the Comp.sources.unix mailing list