v23i066: TRN, version of RN that follows conversation threads, Part07/14

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


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

---- Cut Here and unpack ----
#!/bin/sh
# this is part 7 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file help.c continued
#
CurArch=7
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 help.c"
sed 's/^X//' << 'SHAR_EOF' >> help.c
X    return 0;
X}
X
X#ifdef ESCSUBS
Xint
Xhelp_subs()
X{
X    int cmd;
X#ifdef SUBSHELP
X    doshell(sh,filexp(SUBSHELP));
X#else
X    page_init();
X    if ((cmd = print_lines("\
XValid substitutions are:\n\
X",STANDOUT)) ||
X    (cmd = print_lines("\
X\n\
Xa	Current article number\n\
XA	Full name of current article (%P/%c/%a)\n\
Xb	Destination of last save command, often a mailbox\n\
XB	Bytes to ignore at beginning of last saved article\n\
X",NOMARKING)) ||
X    (cmd = print_lines("\
Xc	Current newsgroup, directory form\n\
XC	Current newsgroup, dot form\n\
Xd	Full name of newsgroup directory (%P/%c)\n\
XD	Distribution line from current article\n\
Xe	The last command executed to extract data from an article\n\
XE	The number of extra (unselected) articles, not counting the current\n\
X	one if it is unselected\n\
X",NOMARKING)) ||
X    (cmd = print_lines("\
Xf	Who the current article is from\n\
XF	Newsgroups to followup to (from Newsgroups and Followup-To)\n\
Xh	(This help message)\n\
XH	Host name (yours)\n\
Xi	Message-I.D. line from current article, with <>\n\
XI	Reference indicator mark (see -F switch)\n\
X",NOMARKING)) ||
X    (cmd = print_lines("\
Xl	News administrator's login name, if any\n\
XL	Login name (yours)\n\
X",NOMARKING)) ||
X#ifdef USETHREADS
X    (cmd = print_lines("\
Xm	Current mode, first letter of (init,newsgroup,thread,article,pager,\n\
X		unread,Add,Catchup,Delete-bogus,Mailbox,Resubscribe)\n\
X",NOMARKING)) ||
X#else
X    (cmd = print_lines("\
Xm	Current mode, first letter of (init, newsgroup, article, pager,\n\
X		Add, Catchup, Delete bogus, Mailbox, Resubscribe)\n\
X",NOMARKING)) ||
X#endif
X    (cmd = print_lines("\
XM	Number of article marked with M\n\
Xn	Newsgroups from current article\n\
XN	Full name (yours)\n\
X",NOMARKING)) ||
X    (cmd = print_lines("\
Xo	Organization (yours)\n\
XO	Original working directory (where you ran trn from)\n\
Xp	Your private news directory (from -d)\n\
XP	Public news spool directory\n\
X",NOMARKING)) ||
X    (cmd = print_lines("\
Xr	Last reference (parent article id)\n\
XR	References list for followup article\n\
Xs	Subject, with all Re's and (nf)'s stripped off\n\
XS	Subject, with one Re stripped off\
X",NOMARKING)) ||
X    (cmd = print_lines("\
Xt	New To line derived from From and Reply-To (Internet format)\n\
XT	New To line derived from Path\n\
Xu	Number of unread articles\n\
XU	Number of unread articles not counting the current article (when\n\
X	threads are selected, the count only reflects selected articles)\n\
Xx	News library directory\n\
XX	Trn library directory\n\
Xz	Length of current article in bytes\n\
XZ	Number of selected threads\n\
X",NOMARKING)) ||
X    (cmd = print_lines("\
X~	Your home directory\n\
X.	Directory containing . files\n\
X#	A counter in multiple-article commands\n\
X$	Current process number\n\
X/	Last search string\n\
XESC	Run preceding command through % interpretation\n\
X",NOMARKING)) )
X	return cmd;
X#endif
X    return 0;
X}
X#endif
X
X#ifdef USETHREADS
Xint
Xhelp_select()
X{
X    int cmd;
X
X    page_init();
X    if ((cmd = print_lines("\
XThread selection commands:\n\
X",STANDOUT)) ||
X    (cmd = print_lines("\n\
Xa-z,0-9	Select/deselect the discussion thread by its letter or number.  By\n\
X	default the letters h, k, m, n, p, q and y are omitted.\n\
XSP	Perform the default command (usually > or Z).\n\
XCR	Start reading.  Selects the current thread if none are selected.\n\
XZ,TAB	Start reading.  If no articles are selected, read everything.\n\
Xy, '.'	Toggle the current thread's selection.\n\
Xk, ','	Mark the current thread as killed.\n\
X",NOMARKING)) ||
X    (cmd = print_lines("\
Xm, \\	Unmark the current thread.\n\
X-	Set a range, as in 2 - 5.  Repeats the last marking action.\n\
X@	Toggle all visible thread selections.\n\
Xn, ]	Move down to the next thread.\n\
Xp, [	Move up to the previous thread.\n\
X<, >	Go to previous/next page.\n\
X^, $	Go to first/last page.\n\
X",NOMARKING)) ||
X    (cmd = print_lines("\
XX	Mark all unselected articles as read and start reading.\n\
XD	Mark unselected articles on the current page as read.  Start\n\
X	reading if articles were selected, else go to next page.\n\
XJ	Junk all selected articles (mark them as read).\n\
X^K	Edit local KILL file (the one for this newsgroup).\n\
X:cmd	Perform a command on all the selected articles.\n\
X",NOMARKING)) ||
X    (cmd = print_lines("\
X/pattern/modifiers\n\
X	Scan all articles for a subject containing pattern.\n\
X	(Append h to scan headers, a to scan entire articles, c to make case\n\
X	sensitive, r to scan read articles (assumed when you are selecting\n\
X	read articles to set unread.)\n\
X/pattern/modifiers:command{:command}\n\
X	Apply one or more commands to the set of articles matching pattern.\n\
X",NOMARKING)) ||
X    (cmd = print_lines("\
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: e, j, m, M, s, S, T, !, and the thread selection\n\
X	commands: + and -.\n\
XN	Leave this group as-is and go on to the next.\n\
XU	Switch between selecting read/unread articles.\n\
XL	Switch the current display mode between a terse mode without\n\
X	authors and a short and long mode with authors.\n\
X",NOMARKING)) ||
X    (cmd = print_lines("\
X&	View or set command line switches.\n\
X&&	View or set macro definitions.\n\
X!cmd	Escape to a subshell.\n\
Xq	Quit selection mode.\n\
XQ	Quit group and return to news group selection prompt for this group.\n\
X",NOMARKING)) )
X	return cmd;
X    return 0;
X}
X#endif
SHAR_EOF
echo "File help.c is complete"
chmod 0660 help.c || echo "restore of help.c fails"
echo "x - extracting help.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > help.h &&
X/* $Header: help.h,v 4.3.3.1 90/06/20 22:37:34 davison Trn $
X *
X * $Log:	help.h,v $
X * Revision 4.3.3.1  90/06/20  22:37:34  davison
X * Initial Trn Release
X * 
X * Revision 4.3  85/05/01  11:39:19  lwall
X * Baseline for release with 4.3bsd.
X * 
X */
X
Xvoid	help_init();
Xint	help_ng();
Xint	help_art();
Xint	help_page();
X#ifdef ESCSUBS
X    int	help_subs();
X#endif
X#ifdef USETHREADS
X    int help_select();
X#endif
SHAR_EOF
chmod 0660 help.h || echo "restore of help.h fails"
echo "x - extracting init.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > init.c &&
X/* $Header: init.c,v 4.3.3.1 90/06/20 22:37:39 davison Trn $
X *
X * $Log:	init.c,v $
X * Revision 4.3.3.1  90/06/20  22:37:39  davison
X * Initial Trn Release
X * 
X * Revision 4.3.2.6  90/05/08  22:05:55  sob
X * Added quick startup (-q) flag.
X * 
X * Revision 4.3.2.5  90/05/04  23:10:01  sob
X * Fix for exiting "second" rn such that tty will be left in correct state.
X * Provided by glenn at mathcs.emory.edu
X * 
X * Revision 4.3.2.4  90/03/22  23:04:32  sob
X * Fixes provided by Wayne Davison <drivax!davison>
X * 
X * Revision 4.3.2.3  90/03/17  21:34:04  sob
X * Cleaned up a bit.
X * 
X * Revision 4.3.2.2  89/11/08  01:17:48  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:39:14  sob
X * Added RRN support from NNTP 1.5
X * 
X * Revision 4.3.1.4  86/09/05  14:24:02  lwall
X * Removed net.announce dependency.
X * 
X * Revision 4.3.1.3  85/07/23  18:08:36  lwall
X * Fixed up NOLINEBUF option to work.
X * 
X * Revision 4.3.1.2  85/05/21  14:22:46  lwall
X * Sped up "rn -c" by avoiding unnecessary initialization.
X * 
X * Revision 4.3.1.1  85/05/10  11:33:39  lwall
X * Branch for patches.
X * 
X * Revision 4.3  85/05/01  16:16:13  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 "final.h"
X#include "term.h"
X#include "last.h"
X#include "rn.h"
X#include "rcstuff.h"
X#include "ngdata.h"
X#include "only.h"
X#include "intrp.h"
X#include "addng.h"
X#include "sw.h"
X#include "art.h"
X#include "artsrch.h"
X#include "artio.h"
X#include "backpage.h"
X#include "bits.h"
X#include "cheat.h"
X#include "head.h"
X#include "help.h"
X#include "kfile.h"
X#include "ngsrch.h"
X#include "ngstuff.h"
X#include "rcln.h"
X#include "respond.h"
X#ifdef SERVER
X#include "server.h"
X#endif
X#ifdef USETHREADS
X#include "rthreads.h"
X#endif
X#include "ng.h"
X#include "INTERN.h"
X#include "init.h"
X
Xbool
Xinitialize(argc,argv)
Xint argc;
Xchar *argv[];
X{
X    char *tcbuf;
X    register bool foundany = FALSE;
X    long time();
X#ifdef SERVER
X    char *server;
X    int response;
X#endif
X#ifdef NOLINEBUF
X    static char std_out_buf[BUFSIZ];	/* must be static or malloced */
X
X    setbuf(stdout, std_out_buf);
X#endif
X
X    tcbuf = safemalloc(1024);		/* make temp buffer for termcap and */
X					/* other initialization stuff */
X    
X    /* init terminal */
X    
X    term_init();			/* must precede sw_init() so that */
X					/* ospeed is set for baud-rate */
X					/* switches.  Actually terminal */
X					/* mode setting is in term_set() */
X
X    /* we have to know rnlib to look up global switches in %X/INIT */
X
X    lib = savestr(filexp(LIB));
X    rnlib = savestr(filexp(RNLIB));
X
X    /* decode switches */
X
X    sw_init(argc,argv,&tcbuf);          /* must not do % interps! */
X					/* (but may mung environment) */
X
X    /* init signals, status flags */
X
X    final_init();
X    
X    /* start up file expansion and the % interpreter */
X
X    intrp_init(tcbuf);
X    
X    /* now make sure we have a current working directory */
X
X    if (!checkflag)
X	cwd_check();
X    
X    /* now that we know where to save things, cd to news directory */
X
X    if (chdir(spool)) {
X	printf(nocd,spool) FLUSH;
X	finalize(1);
X    }
X
X    /* if we aren't just checking, turn off echo */
X
X    if (!checkflag)
X	term_set(tcbuf);
X
X    /* get info on last rn run, if any */
X
X    if (!checkflag)
X	last_init(tcbuf);
X
X    free(tcbuf);			/* recover 1024 bytes */
X
X    /* make sure we are the sole possessors of .newsrc */
X
X    if (!checkflag)
X	lock_check();
X
X    /* check for news news */
X
X    if (!checkflag)
X	newsnews_check();
X
X#ifdef SERVER
X
X    /* open connection to server if appropriate */
X
X    server = getserverbyfile(SERVER_FILE);
X    if (server == NULL) {
X	fprintf(stderr, "Can't get the name of the news server from %s\n",
X		SERVER_FILE);
X	fprintf(stderr,
X	  "Either fix this file, or put NNTPSERVER in your environment.\n");
X	finalize(1);
X    }
X
X    response = server_init(server);
X    if (response < 0) {
X	fprintf(stderr,
X	    "Couldn't connect to %s news server, try again later.\n",
X		server);
X	finalize(1);
X    }
X
X    if (handle_server_response(response, server) < 0)
X	finalize(1);
X
X#endif
X
X    /* open active file, etc. */
X
X    ngdata_init();
X
X    /* now read in the .newsrc file */
X
X    foundany = rcstuff_init();
X
X    /* it looks like we will actually read something, so init everything */
X
X    addng_init();
X    art_init();
X    artio_init();
X    artsrch_init();
X    backpage_init();
X    bits_init();
X    cheat_init();
X    head_init();
X    help_init();
X    kfile_init();
X    ng_init();
X    ngsrch_init();
X    ngstuff_init();
X    only_init();
X    rcln_init();
X    respond_init();
X    rn_init();
X    search_init();
X#ifdef USETHREADS
X    thread_init();
X#endif
X    util_init();
X
X#ifdef FINDNEWNG
X    fstat(actfp->_file,&filestat);	/* did active file grow? */
X	/*
X	 * Skip this check if the -q flag was given.
X	 */
X	
X    if (!quickstart && filestat.st_size != lastactsiz) {
X	long actsiz = filestat.st_size;	/* remember new size */
X	NG_NUM oldnext = nextrcline;	/* remember # lines in newsrc */
X#ifdef FASTNEW
X	bool munged = writesoft || !lastactsiz;
X					/* bad soft ptrs -> edited active */
X#else
X	bool munged = TRUE;		/* just assume .newsrc munged */
X#endif
X
X#ifdef VERBOSE
X	IF(verbose)
X	    fputs("\nChecking active list for new newsgroups...\n",stdout)
X	      FLUSH;
X	ELSE
X#endif
X#ifdef TERSE
X	    fputs("\nNew newsgroups:\n",stdout) FLUSH;
X#endif
X#ifdef FASTNEW
X	if (!munged) {			/* maybe just do tail of file? */
X	    fseek(actfp,lastactsiz-1,0);
X	    fgets(buf,LBUFLEN,actfp);
X	    munged = (*buf != '\n');
X	    if (!munged)
X		munged = newlist(munged,FALSE);
X	}
X#endif
X	if (munged) {			/* must we scan entire file? */
X	    fseek(actfp,0L,0);		/* rewind active file */
X	    newlist(munged,FALSE);      /* sure hope they use hashing... */
X	}
X	lastactsiz = actsiz;		/* remember for .rnlast */
X	if (nextrcline != oldnext) {	/* did we add any new groups? */
X	    foundany = TRUE;		/* let main() know */
X	    starthere = 0;              /* and start ng scan from the top */
X	}
X    }
X#endif
X    time(&lasttime);			/* remember when we inited-- */
X					/* ends up back in .rnlast */
X    writelast();                       /* in fact, put it there now */
X    
X#ifdef FINDNEWNG
X# ifdef ONLY
X    if (maxngtodo)			/* patterns on command line? */
X	foundany |= scanactive();
X# endif
X#endif
X
X    return foundany;
X}
X
X/* make sure there is no rn out there already */
X
Xvoid
Xlock_check()
X{
X    lockname = savestr(filexp(LOCKNAME));
X    if (!checkflag) {
X	tmpfp = fopen(lockname,"r");
X	if (tmpfp != Nullfp) {
X	    int processnum;
X    
X	    fgets(buf,LBUFLEN,tmpfp);
X	    fclose(tmpfp);
X	    processnum = atoi(buf);
X#ifdef VERBOSE
X	    IF(verbose)
X		printf("You seem to have left an rn running, process %d.\n",
X		    processnum) FLUSH;
X	    ELSE
X#endif
X#ifdef TERSE
X		printf("Rn left running, #%d.\n", processnum) FLUSH;
X#endif
X	    if (kill(processnum, SIGEMT)) {
X				    /* does process not exist? */
X				    /* (rn ignores SIGEMT) */
X		sleep(2);
X#ifdef VERBOSE
X		IF(verbose)
X		    fputs("\n\
XThat process does not seem to exist anymore.  The count of read articles\n\
Xmay be incorrect in the last newsgroup accessed by that other (defunct)\n\
Xprocess.\n\n",stdout) FLUSH;
X		ELSE
X#endif
X#ifdef TERSE
X		    fputs("\nProcess crashed.\n",stdout) FLUSH;
X#endif
X		if (*lastngname) {
X#ifdef VERBOSE
X		    IF(verbose)
X			printf("(The last newsgroup accessed was %s.)\n\n",
X			lastngname) FLUSH;
X		    ELSE
X#endif
X#ifdef TERSE
X			printf("(In %s.)\n\n",lastngname) FLUSH;
X#endif
X		}
X		get_anything();
X		putchar('\n') FLUSH;
X	    }
X	    else {
X#ifdef VERBOSE
X		IF(verbose)
X		    fputs("\n\
XYou may not have two copies of rn running simultaneously.  Goodbye.\n\
X",stdout) FLUSH;
X		ELSE
X#endif
X#ifdef TERSE
X		    fputs("\nCan't start another.\n",stdout) FLUSH;
X#endif
X               if (bizarre)
X                 resetty();
X		exit(0);
X	    }
X	}
X	tmpfp = fopen(lockname,"w");
X	if (tmpfp == Nullfp) {
X	    printf(cantcreate,lockname) FLUSH;
X	    sig_catcher(0);
X	}
X	fprintf(tmpfp,"%d\n",getpid());
X	fclose(tmpfp);
X    }
X}
X
Xvoid
Xnewsnews_check()
X{
X    char *newsnewsname = filexp(NEWSNEWSNAME);
X
X    if ((tmpfp = fopen(newsnewsname,"r")) != Nullfp) {
X	fstat(tmpfp->_file,&filestat);
X	if (filestat.st_mtime > lasttime) {
X	    while (fgets(buf,sizeof(buf),tmpfp) != Nullch)
X		fputs(buf,stdout) FLUSH;
X	    get_anything();
X	    putchar('\n') FLUSH;
X	}
X	fclose(tmpfp);
X    }
X}
SHAR_EOF
chmod 0660 init.c || echo "restore of init.c fails"
echo "x - extracting init.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > init.h &&
X/* $Header: init.h,v 4.3 85/05/01 11:40:46 lwall Exp $
X *
X * $Log:	init.h,v $
X * Revision 4.3  85/05/01  11:40:46  lwall
X * Baseline for release with 4.3bsd.
X * 
X */
X
XEXT char *lockname INIT(nullstr);
X
Xbool	initialize();
Xvoid	lock_check();
Xvoid	newsnews_check();
Xvoid	version_check();
SHAR_EOF
chmod 0660 init.h || echo "restore of init.h fails"
echo "x - extracting intrp.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > intrp.c &&
X/* $Header: intrp.c,v 4.3.3.1 90/07/21 20:20:13 davison Trn $
X *
X * $Log:	intrp.c,v $
X * Revision 4.3.3.1  90/07/21  20:20:13  davison
X * Initial Trn Release
X * 
X * Revision 4.3.2.4  90/04/23  00:31:20  sob
X * Removed unneeded atoi call.
X * 
X * Revision 4.3.2.3  90/03/22  23:04:35  sob
X * Fixes provided by Wayne Davison <drivax!davison>
X * 
X * Revision 4.3.2.2  90/03/17  17:03:12  sob
X * Fixed determination of the news superuser's id. Fix provided by Chip
X * Rosenthal <chip at chinacat.lonestar.org>.
X * 
X * Revision 4.3.2.1  89/12/17  02:54:55  sob
X * Removed redundant include directive.
X * 
X * Revision 4.3.1.5  85/05/23  17:21:24  lwall
X * Now allows 'r' and 'f' on null articles.
X * 
X * Revision 4.3.1.4  85/05/21  13:35:21  lwall
X * Sped up "rn -c" by not doing unnecessary initialization.
X * 
X * Revision 4.3.1.3  85/05/17  10:37:11  lwall
X * Fixed & substitution to capitalize last name too.
X * 
X * Revision 4.3.1.2  85/05/15  14:39:45  lwall
X * Spelled gecos right.
X * 
X * Revision 4.3.1.1  85/05/10  11:33:51  lwall
X * Branch for patches.
X * 
X * Revision 4.3  85/05/01  11:40:54  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 "search.h"
X#include "head.h"
X#include "rn.h"
X#include "artsrch.h"
X#include "ng.h"
X#include "respond.h"
X#include "rcstuff.h"
X#include "bits.h"
X#include "artio.h"
X#include "term.h"
X#include "final.h"
X#ifdef USETHREADS
X#include "rthreads.h"
X#endif
X#include "INTERN.h"
X#include "intrp.h"
X
Xchar orgname[] = ORGNAME;
X
X/* name of this site */
X#ifdef GETHOSTNAME
X    char *hostname;
X#   undef SITENAME
X#   define SITENAME hostname
X#else /* !GETHOSTNAME */
X#   ifdef DOUNAME
X#	include <sys/utsname.h>
X	struct utsname uts;
X#	undef SITENAME
X#	define SITENAME uts.nodename
X#   else /* !DOUNAME */
X#	ifdef PHOSTNAME
X	    char *hostname;
X#	    undef SITENAME
X#	    define SITENAME hostname
X#	else /* !PHOSTNAME */
X#	    ifdef WHOAMI
X#		undef SITENAME
X#		define SITENAME sysname
X#	    endif /* WHOAMI */
X#	endif /* PHOSTNAME */
X#   endif /* DOUNAME */
X#endif /* GETHOSTNAME */
X
X#ifdef TILDENAME
Xstatic char *tildename = Nullch;
Xstatic char *tildedir = Nullch;
X#endif
X
Xchar *realname INIT(Nullch);	/* real name of sender from /etc/passwd */
X
Xchar *dointerp();
Xchar *getrealname();
X#ifdef CONDSUB
Xchar *skipinterp();
X#endif
X
Xstatic void abort_interp();
X
Xvoid
Xintrp_init(tcbuf)
Xchar *tcbuf;
X{
X    char *getlogin();
X
X    spool = savestr(filexp(SPOOL));	/* usually /usr/spool/news */
X    
X    /* get environmental stuff */
X
X    /* get home directory */
X
X    homedir = getenv("HOME");
X    if (homedir == Nullch)
X	homedir = getenv("LOGDIR");
X
X    dotdir = getval("DOTDIR",homedir);
X
X    /* get login name */
X
X    logname = getenv("USER");
X    if (logname == Nullch)
X	logname = getenv("LOGNAME");
X#ifdef GETLOGIN
X    if (logname == Nullch)
X	logname = savestr(getlogin());
X#endif
X
X#ifdef NEWSADMIN
X    /* if this is the news admin than load his UID into newsuid */
X
X    if ( strEQ(logname,NEWSADMIN) )
X	newsuid = getuid();
X#endif
X
X    if (checkflag)			/* that getwd below takes ~1/3 sec. */
X	return;				/* and we do not need it for -c */
X    getwd(tcbuf);			/* find working directory name */
X    origdir = savestr(tcbuf);		/* and remember it */
X
X    /* get the real name of the person (%N) */
X    /* Must be done after logname is read in because BERKNAMES uses that */
X
X    strcpy(tcbuf,getrealname(getuid()));
X    realname = savestr(tcbuf);
X
X    /* name of header file (%h) */
X
X    headname = savestr(filexp(HEADNAME));
X
X    /* name of this site (%H) */
X
X#ifdef GETHOSTNAME
X    gethostname(buf,sizeof buf);
X    hostname = savestr(buf);
X#else
X#ifdef DOUNAME
X    /* get sysname */
X    uname(&uts);
X#else
X#ifdef PHOSTNAME
X    {
X	FILE *popen();
X	FILE *pipefp = popen(PHOSTNAME,"r");
X	
X	if (pipefp == Nullfp) {
X	    printf("Can't find hostname\n");
X	    sig_catcher(0);
X	}
X	fgets(buf,sizeof buf,pipefp);
X	buf[strlen(buf)-1] = '\0';	/* wipe out newline */
X	hostname = savestr(buf);
X	pclose(pipefp);
X    }
X#endif
X#endif
X#endif
X    sitename = savestr(SITENAME);
X}
X
X/* expand filename via %, ~, and $ interpretation */
X/* returns pointer to static area */
X/* Note that there is a 1-deep cache of ~name interpretation */
X
Xchar *
Xfilexp(s)
Xregister char *s;
X{
X    static char filename[CBUFLEN];
X    char scrbuf[CBUFLEN];
X    register char *d;
X
X#ifdef DEBUGGING
X    if (debug & DEB_FILEXP)
X	printf("< %s\n",s) FLUSH;
X#endif
X    interp(filename, (sizeof filename), s);			/* interpret any % escapes */
X#ifdef DEBUGGING
X    if (debug & DEB_FILEXP)
X	printf("%% %s\n",filename) FLUSH;
X#endif
X    s = filename;
X    if (*s == '~') {	/* does destination start with ~? */
X	if (!*(++s) || *s == '/') {
X	    sprintf(scrbuf,"%s%s",homedir,s);
X				/* swap $HOME for it */
X#ifdef DEBUGGING
X    if (debug & DEB_FILEXP)
X	printf("~ %s\n",scrbuf) FLUSH;
X#endif
X	    strcpy(filename,scrbuf);
X	}
X	else {
X#ifdef TILDENAME
X	    for (d=scrbuf; isalnum(*s); s++,d++)
X		*d = *s;
X	    *d = '\0';
X	    if (tildedir && strEQ(tildename,scrbuf)) {
X		strcpy(scrbuf,tildedir);
X		strcat(scrbuf, s);
X		strcpy(filename, scrbuf);
X#ifdef DEBUGGING
X		if (debug & DEB_FILEXP)
X		    printf("r %s %s\n",tildename,tildedir) FLUSH;
X#endif
X	    }
X	    else {
X		if (tildename) {
X		    free(tildename);
X		    free(tildedir);
X		}
X		tildedir = Nullch;
X		tildename = savestr(scrbuf);
X#ifdef GETPWENT		/* getpwnam() is not the paragon of efficiency */
X		{
X		    struct passwd *getpwnam();
X		    struct passwd *pwd = getpwnam(tildename);
X
X		    sprintf(scrbuf,"%s%s",pwd->pw_dir,s);
X		    tildedir = savestr(pwd->pw_dir);
X		    strcpy(filename,scrbuf);
X#ifdef GETPWENT
X		    endpwent();
X#endif
X		}
X#else			/* this will run faster, and is less D space */
X		{	/* just be sure LOGDIRFIELD is correct */
X		    FILE *pfp = fopen("/etc/passwd","r");
X		    char tmpbuf[512];
X		    int i;
X		    
X		    if (pfp == Nullfp) {
X			printf(cantopen,"passwd") FLUSH;
X			sig_catcher(0);
X		    }
X		    while (fgets(tmpbuf,512,pfp) != Nullch) {
X			d = cpytill(scrbuf,tmpbuf,':');
X#ifdef DEBUGGING
X			if (debug & DEB_FILEXP)
X			    printf("p %s\n",tmpbuf) FLUSH;
X#endif
X			if (strEQ(scrbuf,tildename)) {
X			    for (i=LOGDIRFIELD-2; i; i--) {
X				if (d)
X				    d = index(d+1,':');
X			    }
X			    if (d) {
X				cpytill(scrbuf,d+1,':');
X				tildedir = savestr(scrbuf);
X				strcat(scrbuf,s);
X				strcpy(filename,scrbuf);
X			    }
X			    break;
X			}
X		    }
X		    fclose(pfp);
X		}
X#endif
X	    }
X#else /* !TILDENAME */
X#ifdef VERBOSE
X	    IF(verbose)
X		fputs("~loginname not implemented.\n",stdout) FLUSH;
X	    ELSE
X#endif
X#ifdef TERSE
X		fputs("~login not impl.\n",stdout) FLUSH;
X#endif
X#endif
X	}
X    }
X    else if (*s == '$') {	/* starts with some env variable? */
X	d = scrbuf;
X	*d++ = '%';
X	if (s[1] == '{')
X	    strcpy(d,s+2);
X	else {
X	    *d++ = '{';
X	    for (s++; isalnum(*s); s++) *d++ = *s;
X				/* skip over token */
X	    *d++ = '}';
X	    strcpy(d,s);
X	}
X#ifdef DEBUGGING
X	if (debug & DEB_FILEXP)
X	    printf("$ %s\n",scrbuf) FLUSH;
X#endif
X	interp(filename, (sizeof filename), scrbuf);
X					/* this might do some extra '%'s but */
X					/* that is how the Mercedes Benz */
X    }
X#ifdef DEBUGGING
X    if (debug & DEB_FILEXP)
X	printf("> %s\n",filename) FLUSH;
X#endif
X    return filename;
X}
X
X#ifdef CONDSUB
X/* skip interpolations */
X
Xchar *
Xskipinterp(pattern,stoppers)
Xregister char *pattern;
Xchar *stoppers;
X{
X
X    while (*pattern && (!stoppers || !index(stoppers,*pattern))) {
X#ifdef DEBUGGING
X	if (debug & 8)
X	    printf("skipinterp till %s at %s\n",stoppers?stoppers:"",pattern);
X#endif
X	if (*pattern == '%' && pattern[1]) {
X	    switch (*++pattern) {
X	    case '{':
X		for (pattern++; *pattern && *pattern != '}'; pattern++)
X		    if (*pattern == '\\')
X			pattern++;
X		break;
X	    case '[':
X		for (pattern++; *pattern && *pattern != ']'; pattern++)
X		    if (*pattern == '\\')
X			pattern++;
X		break;
X#ifdef CONDSUB
X	    case '(': {
X		pattern = skipinterp(pattern+1,"!=");
X		if (!*pattern)
X		    goto getout;
X		for (pattern++; *pattern && *pattern != '?'; pattern++)
X		    if (*pattern == '\\')
X			pattern++;
X		if (!*pattern)
X		    goto getout;
X		pattern = skipinterp(pattern+1,":)");
X		if (*pattern == ':')
X		    pattern = skipinterp(pattern+1,")");
X		break;
X	    }
X#endif
X#ifdef BACKTICK
X	    case '`': {
X		pattern = skipinterp(pattern+1,"`");
X		break;
X	    }
X#endif
X#ifdef PROMPTTTY
X	    case '"':
X		pattern = skipinterp(pattern+1,"\"");
X		break;
X#endif
X	    default:
X		break;
X	    }
X	    pattern++;
X	}
X	else {
X	    if (*pattern == '^' && pattern[1])
X		pattern += 2;
X	    else if (*pattern == '\\' && pattern[1])
X		pattern += 2;
X	    else
X		pattern++;
X	}
X    }
Xgetout:
X    return pattern;			/* where we left off */
X}
X#endif
X
X/* interpret interpolations */
X
Xchar *
Xdointerp(dest,destsize,pattern,stoppers)
Xregister char *dest;
Xregister int destsize;
Xregister char *pattern;
Xchar *stoppers;
X{
X    char *subj_buf = Nullch;
X    char *ngs_buf = Nullch;
X    char *refs_buf = Nullch;
X    char *artid_buf = Nullch;
X    char *reply_buf = Nullch;
X    char *from_buf = Nullch;
X    char *path_buf = Nullch;
X    char *follow_buf = Nullch;
X    char *dist_buf = Nullch;
X    char *line_buf = Nullch;
X    register char *s, *h;
X    register int i;
X    char scrbuf[512];
X    bool upper = FALSE;
X    bool lastcomp = FALSE;
X    int metabit = 0;
X
X    while (*pattern && (!stoppers || !index(stoppers,*pattern))) {
X#ifdef DEBUGGING
X	if (debug & 8)
X	    printf("dointerp till %s at %s\n",stoppers?stoppers:"",pattern);
X#endif
X	if (*pattern == '%' && pattern[1]) {
X	    upper = FALSE;
X	    lastcomp = FALSE;
X	    for (s=Nullch; !s; ) {
X		switch (*++pattern) {
X		case '^':
X		    upper = TRUE;
X		    break;
X		case '_':
X		    lastcomp = TRUE;
X		    break;
X		case '/':
X#ifdef ARTSRCH
X		    s = scrbuf;
X		    if (!index("/?g",pattern[-2]))
X			*s++ = '/';
X		    strcpy(s,lastpat);
X		    s += strlen(s);
X		    if (pattern[-2] != 'g') {
X			if (index("/?",pattern[-2]))
X			    *s++ = pattern[-2];
X			else
X			    *s++ = '/';
X			if (art_howmuch == 1)
X			    *s++ = 'h';
X			else if (art_howmuch == 2)
X			    *s++ = 'a';
X			if (art_doread)
X			    *s++ = 'r';
X		    }
X		    *s = '\0';
X		    s = scrbuf;
X#else
X		    s = nullstr;
X#endif
X		    break;
X		case '{':
X		    pattern = cpytill(scrbuf,pattern+1,'}');
X		    if (s = index(scrbuf,'-'))
X			*s++ = '\0';
X		    else
X			s = nullstr;
X		    s = getval(scrbuf,s);
X		    break;
X		case '[':
X		    pattern = cpytill(scrbuf,pattern+1,']');
X		    i = set_line_type(scrbuf,scrbuf+strlen(scrbuf));
X		    if (line_buf)
X			free(line_buf);
X		    s = line_buf = fetchlines(art,i);
X		    break;
X#ifdef CONDSUB
X		case '(': {
X		    COMPEX *oldbra_compex = bra_compex;
X		    COMPEX cond_compex;
X		    char rch;
X		    bool matched;
X		    
X		    init_compex(&cond_compex);
X		    pattern = dointerp(dest,destsize,pattern+1,"!=");
X		    rch = *pattern;
X		    if (rch == '!')
X			pattern++;
X		    if (*pattern != '=')
X			goto getout;
X		    pattern = cpytill(scrbuf,pattern+1,'?');
X		    if (!*pattern)
X			goto getout;
X		    if (s = compile(&cond_compex,scrbuf,TRUE,TRUE)) {
X			printf("%s: %s\n",scrbuf,s) FLUSH;
X			pattern += strlen(pattern);
X			goto getout;
X		    }
X		    matched = (execute(&cond_compex,dest) != Nullch);
X		    if (cond_compex.nbra)	/* were there brackets? */
X			bra_compex = &cond_compex;
X		    if (matched==(rch == '=')) {
X			pattern = dointerp(dest,destsize,pattern+1,":)");
X			if (*pattern == ':')
X			    pattern = skipinterp(pattern+1,")");
X		    }
X		    else {
X			pattern = skipinterp(pattern+1,":)");
X			if (*pattern == ':')
X			    pattern++;
X			pattern = dointerp(dest,destsize,pattern,")");
X		    }
X		    s = dest;
X		    bra_compex = oldbra_compex;
X		    free_compex(&cond_compex);
X		    break;
X		}
X#endif
X#ifdef BACKTICK
X		case '`': {
X		    FILE *pipefp, *popen();
X
X		    pattern = dointerp(scrbuf,(sizeof scrbuf),pattern+1,"`");
X		    pipefp = popen(scrbuf,"r");
X		    if (pipefp != Nullfp) {
X			int len;
X
X			len = fread(scrbuf,sizeof(char),(sizeof scrbuf)-1,
X			    pipefp);
X			scrbuf[len] = '\0';
X			pclose(pipefp);
X		    }
X		    else {
X			printf("\nCan't run %s\n",scrbuf);
X			*scrbuf = '\0';
X		    }
X		    for (s=scrbuf; *s; s++) {
X			if (*s == '\n') {
X			    if (s[1])
X				*s = ' ';
X			    else
X				*s = '\0';
X			}
X		    }
X		    s = scrbuf;
X		    break;
X		}
X#endif
X#ifdef PROMPTTTY
X		case '"':
X		    pattern = dointerp(scrbuf,(sizeof scrbuf),pattern+1,"\"");
X		    fputs(scrbuf,stdout) FLUSH;
X		    resetty();
X		    gets(scrbuf);
X		    noecho();
X		    crmode();
X		    s = scrbuf;
X		    break;
X#endif
X		case '~':
X		    s = homedir;
X		    break;
X		case '.':
X		    s = dotdir;
X		    break;
X		case '$':
X		    s = scrbuf;
X		    sprintf(s,"%d",getpid());
X		    break;
X		case '#':
X		    s = scrbuf;
X		    sprintf(s,"%d",perform_cnt);
X		    break;
X		case '0': case '1': case '2': case '3': case '4':
X		case '5': case '6': case '7': case '8': case '9':
X#ifdef CONDSUB
X		    s = getbracket(bra_compex,*pattern - '0');
X#else
X		    s = nullstr;
X#endif
X		    break;
X		case 'a':
X		    s = scrbuf;
X		    sprintf(s,"%ld",(long)art);
X		    break;
X		case 'A':
X#ifdef LINKART
X		    s = linkartname;	/* so Eunice people get right file */
X#else
X		    s = scrbuf;
X		    sprintf(s,"%s/%s/%ld",spool,ngdir,(long)art);
X#endif
X		    break;
X		case 'b':
X		    s = savedest;
X		    break;
X		case 'B':
X		    s = scrbuf;
X		    sprintf(s,"%ld",(long)savefrom);
X		    break;
X		case 'c':
X		    s = ngdir;
X		    break;
X		case 'C':
X		    s = ngname;
X		    break;
X		case 'd':
X		    s = scrbuf;
X		    sprintf(s,"%s/%s",spool,ngdir);
X		    break;
X		case 'D':
X		    s = dist_buf = fetchlines(art,DIST_LINE);
X		    break;
X		case 'e':
X		    s = extractprog;
X		    break;
X#ifdef USETHREADS
X		case 'E': {
X		    int sel, unseen;
X
X		    sel = curr_p_art && (selected_roots[curr_p_art->root] & 1);
X		    unseen = (art <= lastart) && !was_read(art);
X		    sprintf(scrbuf,"%ld",(long)toread[ng]-selected_count
X						-unthreaded-(!sel && unseen));
X		    s = scrbuf;
X		    break;
X		}
X#endif
X		case 'f':			/* from line */
X#ifdef ASYNC_PARSE
X		    parse_maybe(art);
X#endif
X		    if (htype[REPLY_LINE].ht_minpos >= 0) {
X						/* was there a reply line? */
X			if (!(s=reply_buf))
X			    s = reply_buf = fetchlines(art,REPLY_LINE);
X		    }
X		    else if (!(s = from_buf))
X			s = from_buf = fetchlines(art,FROM_LINE);
X		    break;
X		case 'F':
X#ifdef ASYNC_PARSE
X		    parse_maybe(art);
X#endif
X		    if (htype[FOLLOW_LINE].ht_minpos >= 0)
X					/* is there a Followup-To line? */
X			s = follow_buf = fetchlines(art,FOLLOW_LINE);
X		    else {
X			int off;
X		
X			s = ngs_buf = fetchlines(art,NGS_LINE);
X			if (h = instr(s,"net.general")) {
X			    off = h-s;
X			    strncpy(scrbuf,s,off+4);
X			    strcpy(scrbuf+off+4,"followup");
X			    safecpy(scrbuf+off+12,h+11,sizeof(scrbuf));
X			    s = scrbuf;
X			}
X		    }
X		    break;
X		case 'h':			/* header file name */
X		    s = headname;
X		    break;
X		case 'H':			/* host name */
X		    s = sitename;
X		    break;
X		case 'i':
X		    if (!(s=artid_buf))
X			s = artid_buf = fetchlines(art,MESSID_LINE);
X		    if (*s && *s != '<') {
X			sprintf(scrbuf,"<%s>",artid_buf);
X			s = scrbuf;
X		    }
X		    break;
X		case 'I':			/* ref article indicator */
X		    s = scrbuf;
X		    sprintf(scrbuf,"'%s'",indstr);
X		    break;
X		case 'l':			/* rn library */
X#ifdef NEWSADMIN
X		    s = newsadmin;
X#else
X		    s = "???";
X#endif
X		    break;
X		case 'L':			/* login id */
X		    s = logname;
X		    break;
X		case 'm':		/* current mode */
X		    s = scrbuf;
X		    *s = mode;
X		    s[1] = '\0';
X		    break;
X		case 'M':
X#ifdef DELAYMARK
X		    sprintf(scrbuf,"%ld",(long)dmcount);
X		    s = scrbuf;
X#else
X		    s = nullstr;
X#endif
X		    break;
X		case 'n':			/* newsgroups */
X		    s = ngs_buf = fetchlines(art,NGS_LINE);
X		    break;
X		case 'N':			/* full name */
X		    s = getval("NAME",realname);
X		    break;
X		case 'o':			/* organization */
X		    s = getval("ORGANIZATION",orgname);
X#ifdef ORGFILE
X		    if (*s == '/') {
X			FILE *ofp = fopen(s,"r");
X
X			if (ofp) {
X			    fgets(scrbuf,sizeof scrbuf,ofp);
X			    fclose(ofp);
X			    s = scrbuf;
X			    s[strlen(s)-1] = '\0';
X			}
X		    }
X#endif
X		    break;
X		case 'O':
X		    s = origdir;
X		    break;
X		case 'p':
X		    s = cwd;
X		    break;
X		case 'P':
X		    s = spool;
X		    break;
X		case 'r':
X#ifdef ASYNC_PARSE
X		    parse_maybe(art);
X#endif
X		    if (htype[REFS_LINE].ht_minpos >= 0) {
X			refs_buf = fetchlines(art,REFS_LINE);
X			refscpy(scrbuf,(sizeof scrbuf),refs_buf);
X		    }
X		    else
X			*scrbuf = '\0';
X		    s = rindex(scrbuf,'<');
X		    break;
X		case 'R':
X#ifdef ASYNC_PARSE
X		    parse_maybe(art);
X#endif
X		    if (htype[REFS_LINE].ht_minpos >= 0) {
X			refs_buf = fetchlines(art,REFS_LINE);
X			refscpy(scrbuf,(sizeof scrbuf),refs_buf);
X			/* no more than 3 prior references allowed,
X			** including the one concatenated below */
X			if ((s = rindex(scrbuf,'<')) > scrbuf) {
X			    *s = '\0';
X			    h = rindex(scrbuf,'<');
X			    *s = '<';
X			    if (h > scrbuf)
X				strcpy(scrbuf,h);
X			}
X		    }
X		    else
X			*scrbuf = '\0';
X		    if (!artid_buf)
X			artid_buf = fetchlines(art,MESSID_LINE);
X		    if (artid_buf[0] == '<')
X			safecat(scrbuf,artid_buf,sizeof(scrbuf));
X		    else if (artid_buf[0]) {
X			char tmpbuf[64];
X    
X			sprintf(tmpbuf,"<%s>",artid_buf);
X			safecat(scrbuf,tmpbuf,sizeof(scrbuf));
X		    }
X		    s = scrbuf;
X		    break;
X		case 's':
X		    if (!(s=subj_buf))
X			s = subj_buf = fetchsubj(art,TRUE,TRUE);
X						/* get subject handy */
X		    while ((*s=='R'||*s=='r')&&(s[1]=='E'||s[1]=='e')&&s[2]==':') {
X						/* skip extra Re: */
X			s += 3;
X			if (*s == ' ')
X			    s++;
X		    }
X		    if (h = instr(s,"- (nf"))
X			*h = '\0';
X		    break;
X		case 'S':
X		    if (!(s=subj_buf))
X			s = subj_buf = fetchsubj(art,TRUE,TRUE);
X						/* get subject handy */
X		    if ((*s=='R'||*s=='r')&&(s[1]=='E'||s[1]=='e')&&s[2]==':') {
X						/* skip extra Re: */
X			s += 3;
X			if (*s == ' ')
X			    s++;
X		    }
X		    break;
X		case 't':
X		case 'T':
X#ifdef ASYNC_PARSE
X		    parse_maybe(art);
X#endif
X		    if (htype[REPLY_LINE].ht_minpos >= 0) {
X					/* was there a reply line? */
X			if (!(s=reply_buf))
X			    s = reply_buf = fetchlines(art,REPLY_LINE);
X		    }
X		    else if (!(s = from_buf))
X			s = from_buf = fetchlines(art,FROM_LINE);
X		    if (*pattern == 'T') {
X			if (htype[PATH_LINE].ht_minpos >= 0) {
X					/* should we substitute path? */
X			    s = path_buf = fetchlines(art,PATH_LINE);
X			}
X			i = strlen(sitename);
X			if (strnEQ(sitename,s,i) && s[i] == '!')
X			    s += i + 1;
X		    }
X		    if ((h=index(s,'(')) != Nullch)
X						/* strip garbage from end */
X			*(h-1) = '\0';
X		    else if ((h=index(s,'<')) != Nullch) {
X						/* or perhaps from beginning */
X			s = h+1;
X			if ((h=index(s,'>')) != Nullch)
X			    *h = '\0';
X		    }
X		    break;
X		case 'u':
X		    sprintf(scrbuf,"%ld",(long)toread[ng]);
X		    s = scrbuf;
X		    break;
X		case 'U': {
X		    int unseen;
X
X		    unseen = (art <= lastart) && !was_read(art);
X#ifdef USETHREADS
X		    if (selected_root_cnt) {
X			int sel;
X
X			sel = curr_p_art
X				&& (selected_roots[curr_p_art->root] & 1);
X			sprintf(scrbuf,"%ld",
X				(long)selected_count-(sel && unseen));
X		    }
X		    else
X			sprintf(scrbuf,"%ld",(long)toread[ng]-unthreaded
X						-unseen);
X#else
X		    sprintf(scrbuf,"%ld",(long)toread[ng]-unseen);
X#endif
X		    s = scrbuf;
X		    break;
X		}
X		case 'x':			/* news library */
X		    s = lib;
X		    break;
X		case 'X':			/* rn library */
X		    s = rnlib;
X		    break;
X		case 'z':
X#ifdef LINKART
X		    s = linkartname;	/* so Eunice people get right file */
X#else
X		    s = scrbuf;
X		    sprintf(s,"%ld",(long)art);
X#endif
X		    if (stat(s,&filestat) < 0)
X			filestat.st_size = 0L;
X		    sprintf(scrbuf,"%5ld",(long)filestat.st_size);
X		    s = scrbuf;
X		    break;
X#ifdef USETHREADS
X		case 'Z':
X		    sprintf(scrbuf,"%ld",(long)selected_count);
X		    s = scrbuf;
X		    break;
X#endif
X		default:
X		    if (--destsize <= 0)
X			abort_interp();
X		    *dest++ = *pattern | metabit;
X		    s = nullstr;
X		    break;
X		}
X	    }
X	    if (!s)
X		s = nullstr;
X	    pattern++;
X	    if (upper || lastcomp) {
X		char *t;
X
X		if (s != scrbuf) {
X		    safecpy(scrbuf,s,(sizeof scrbuf));
X		    s = scrbuf;
X		}
X		if (upper || !(t=rindex(s,'/')))
X		    t = s;
X		while (*t && !isalpha(*t))
X		    t++;
X		if (islower(*t))
X		    *t = toupper(*t);
X	    }
X	    i = metabit;		/* maybe get into register */
X	    if (s == dest) {
X		while (*dest) {
X		    if (--destsize <= 0)
X			abort_interp();
X		    *dest++ |= i;
X		}
X	    }
X	    else {
X		while (*s) {
X		    if (--destsize <= 0)
X			abort_interp();
X		    *dest++ = *s++ | i;
X		}
X	    }
X	}
X	else {
X	    if (--destsize <= 0)
X		abort_interp();
X	    if (*pattern == '^' && pattern[1]) {
X		++pattern;			/* skip uparrow */
X		i = *pattern;		/* get char into a register */
X		if (i == '?')
X		    *dest++ = '\177' | metabit;
X		else if (i == '(') {
X		    metabit = 0200;
X		    destsize++;
X		}
X		else if (i == ')') {
X		    metabit = 0;
X		    destsize++;
X		}
X		else
X		    *dest++ = i & 037 | metabit;
X		pattern++;
X	    }
X	    else if (*pattern == '\\' && pattern[1]) {
X		++pattern;			/* skip backslash */
X		i = *pattern;		/* get char into a register */
X    
X		/* this used to be a switch but the if may save space */
X		
X		if (i >= '0' && i <= '7') {
X		    i = 1;
X		    while (i < 01000 && *pattern >= '0' && *pattern <= '7') {
X			i <<= 3;
X			i += *pattern++ - '0';
X		    }
X		    *dest++ = i & 0377 | metabit;
X		    --pattern;
X		}
X		else if (i == 'b')
X		    *dest++ = '\b' | metabit;
X		else if (i == 'f')
X		    *dest++ = '\f' | metabit;
X		else if (i == 'n')
X		    *dest++ = '\n' | metabit;
X		else if (i == 'r')
X		    *dest++ = '\r' | metabit;
X		else if (i == 't')
X		    *dest++ = '\t' | metabit;
X		else
X		    *dest++ = i | metabit;
X		pattern++;
X	    }
X	    else
X		*dest++ = *pattern++ | metabit;
X	}
X    }
X    *dest = '\0';
Xgetout:
X    if (subj_buf != Nullch)	/* return any checked out storage */
X	free(subj_buf);
X    if (ngs_buf != Nullch)
X	free(ngs_buf);
X    if (refs_buf != Nullch)
X	free(refs_buf);
X    if (artid_buf != Nullch)
X	free(artid_buf);
X    if (reply_buf != Nullch)
X	free(reply_buf);
X    if (from_buf != Nullch)
X	free(from_buf);
X    if (path_buf != Nullch)
X	free(path_buf);
X    if (follow_buf != Nullch)
X	free(follow_buf);
X    if (dist_buf != Nullch)
X	free(dist_buf);
X    if (line_buf != Nullch)
X	free(line_buf);
X    return pattern;			/* where we left off */
X}
X
Xvoid
Xinterp(dest,destsize,pattern)
Xchar *dest;
Xint destsize;
Xchar *pattern;
X{
X    dointerp(dest,destsize,pattern,Nullch);
X#ifdef DEBUGGING
X    if (debug & DEB_FILEXP)
X	fputs(dest,stdout);
X#endif
X}
X
X/* copy a references line, normalizing as we go */
X
Xvoid
Xrefscpy(dest,destsize,src)
Xregister char *dest, *src;
Xregister int destsize;
X{
X    register char *dot, *at, *beg;
X    char tmpbuf[64];
X    
X    while (*src) {
X	if (*src != '<') {
X	    if (--destsize <= 0)
X		break;
X	    *dest++ = '<';
X	    at = dot = Nullch;
X	    beg = src;
X	    while (*src && *src != ' ' && *src != ',') {
X		if (*src == '.')
X		    dot = src;
X		else if (*src == '@')
X		    at = src;
X		if (--destsize <= 0)
X		    break;
X		*dest++ = *src++;
X	    }
X	    if (destsize <= 0)
X		break;
X	    if (dot && !at) {
X		int len;
X
X		*dest = *dot++ = '\0';
X		sprintf(tmpbuf,"%s@%s.UUCP",dot,beg);
X		len = strlen(tmpbuf);
X		if (destsize > len) {
X		    strcpy(dest,tmpbuf);
X		    dest = dest + len;
X		    destsize -= len;
X		}
X	    }
X	    if (--destsize <= 0)
X		break;
X	    *dest++ = '>';
X	}
X	else {
X	    while (*src && --destsize > 0 && (*dest++ = *src++) != '>') ;
X	    if (destsize <= 0)
X		break;
X	}
X	while (*src == ' ' || *src == ',') src++;
X	if (*src && --destsize > 0)
X	    *dest++ = ' ';
X    }
X    *dest = '\0';
X} 
X
X/* get the person's real name from /etc/passwd */
X/* (string is overwritten, so it must be copied) */
X
Xchar *
Xgetrealname(uid)
Xint uid;
X{
X    char *s, *c;
X
X#ifdef PASSNAMES
X#ifdef GETPWENT
X    struct passwd *pwd = getpwuid(uid);
X    
X    s = pwd->pw_gecos;
X#else
X    char tmpbuf[512];
X    int i;
X
X    getpw(uid, tmpbuf);
X    for (s=tmpbuf, i=GCOSFIELD-1; i; i--) {
X	if (s)
X	    s = index(s,':')+1;
X    }
X    if (!s)
X	return nullstr;
X    cpytill(tmpbuf,s,':');
X    s = tmpbuf;
X#endif
X#ifdef BERKNAMES
X#ifdef BERKJUNK
X    while (*s && !isalnum(*s) && *s != '&') s++;
X#endif
X    if ((c = index(s, ',')) != Nullch)
X	*c = '\0';
X    if ((c = index(s, ';')) != Nullch)
X	*c = '\0';
X    s = cpytill(buf,s,'&');
X    if (*s == '&') {			/* whoever thought this one up was */
X	c = buf + strlen(buf);		/* in the middle of the night */
X	strcat(c,logname);		/* before the morning after */
X	strcat(c,s+1);
X	if (islower(*c))
X	    *c = toupper(*c);		/* gack and double gack */
X    }
X#else
X    if ((c = index(s, '(')) != Nullch)
X	*c = '\0';
X    if ((c = index(s, '-')) != Nullch)
X	s = c;
X    strcpy(buf,tmpbuf);
X#endif
X#ifdef GETPWENT
X    endpwent();
X#endif
X    return buf;				/* return something static */
X#else
X    if ((tmpfp=fopen(filexp(FULLNAMEFILE),"r")) != Nullfp) {
X	fgets(buf,sizeof buf,tmpfp);
X	fclose(tmpfp);
X	buf[strlen(buf)-1] = '\0';
X	return buf;
X    }
X    return "PUT YOUR NAME HERE";
X#endif
X}
X
Xstatic void
Xabort_interp()
X{
X    fputs("\n% interp buffer overflow!\n",stdout) FLUSH;
X    sig_catcher(0);
X}
SHAR_EOF
chmod 0660 intrp.c || echo "restore of intrp.c fails"
echo "x - extracting intrp.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > intrp.h &&
X/* $Header: intrp.h,v 4.3.3.1 90/06/20 22:38:00 davison Trn $
X *
X * $Log:	intrp.h,v $
X * Revision 4.3.3.1  90/06/20  22:38:00  davison
X * Initial Trn Release
X * 
X * Revision 4.3  85/05/01  11:41:48  lwall
X * Baseline for release with 4.3bsd.
X * 
X */
X
XEXT char *lib INIT(Nullch);		/* news library */
XEXT char *rnlib INIT(Nullch);		/* private news program library */
XEXT char *origdir INIT(Nullch);		/* cwd when rn invoked */
XEXT char *homedir INIT(Nullch);		/* login directory */
XEXT char *dotdir INIT(Nullch);		/* where . files go */
XEXT char *logname INIT(Nullch);		/* login id */
XEXT char *sitename INIT(Nullch);	/* host name */
XEXT int perform_cnt;
X
X#ifdef NEWSADMIN
X    EXT char newsadmin[] INIT(NEWSADMIN);/* news administrator */
X    EXT int newsuid INIT(0);
X#endif
X
Xvoid    intrp_init();
Xchar	*filexp();
Xchar	*dointerp();
Xvoid	interp();
Xvoid	refscpy();
Xchar	*getrealname();
SHAR_EOF
chmod 0660 intrp.h || echo "restore of intrp.h fails"
echo "x - extracting kfile.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > kfile.c &&
X/* $Header: kfile.c,v 4.3.3.1 90/06/20 22:38:06 davison Trn $
X *
X * $Log:	kfile.c,v $
X * Revision 4.3.3.1  90/06/20  22:38:06  davison
X * Initial Trn Release
X * 
X * Revision 1.2  90/03/22  23:04:41  sob
X * Fixes provided by Wayne Davison <drivax!davison>
X * 
X * Revision 4.3.1.3  85/05/29  09:11:52  lwall
X * Suppressed some killing messages on -t.
X * 
X * Revision 4.3.1.2  85/05/10  14:21:29  lwall
X * Prevented THRU from setting art < absfirst.
X * 
X * Revision 4.3.1.1  85/05/10  11:34:33  lwall
X * Branch for patches.
X * 
X * Revision 4.3  85/05/01  11:41:53  lwall
X * Baseline for release with 4.3bsd.
X * 
X */
X
X#include "EXTERN.h"
X#include "common.h"
X#include "term.h"
X#include "util.h"
X#include "artsrch.h"
X#include "ng.h"
X#include "bits.h"
X#include "intrp.h"
X#include "ngstuff.h"
X#include "rcstuff.h"
X#include "rn.h"
X#ifdef USETHREADS
X#include "rthreads.h"
X#endif
X#include "INTERN.h"
X#include "kfile.h"
X
Xstatic bool exitcmds = FALSE;
X
Xvoid
Xkfile_init()
X{
X    ;
X}
X
X#ifndef KILLFILES
Xint
Xedit_kfile()
X{
X    notincl("^K");
X    return -1;
X}
X
X#else /* KILLFILES */
X
Xchar killglobal[] = KILLGLOBAL;
Xchar killlocal[] = KILLLOCAL;
X
Xvoid
Xmention(str)
Xchar *str;
X{
X#ifdef VERBOSE
X    IF(verbose) {
X#ifdef NOFIREWORKS
X	no_sofire();
X#endif
X	standout();
X	fputs(str,stdout);
X	un_standout();
X	putchar('\n');
X    }
X    ELSE
X#endif
X#ifdef TERSE
X	putchar('.');
X#endif
X    fflush(stdout);
X}
X
Xbool kill_mentioned;
X
Xint
Xdo_kfile(kfp,entering)
XFILE *kfp;
Xint entering;
X{
X#ifdef USETHREADS
X    int i;
X    ART_NUM kill_thread;
X#endif
X
X    art = lastart+1;
X    fseek(kfp,0L,0);			/* rewind file */
X    while (fgets(buf,LBUFLEN,kfp) != Nullch) {
X	buf[strlen(buf)-1] = '\0';
X	if (strnEQ(buf,"THRU",4)) {
X	    ART_NUM tmpart;
X
X	    tmpart = atol(buf+4)+1;
X	    if (tmpart < absfirst)
X		tmpart = absfirst;
X	    check_first(tmpart);
X	    firstart = tmpart;
X	    continue;
X	}
X	if (*buf == 'X') {		/* exit command? */
X	    if (entering) {
X		exitcmds = TRUE;
X		continue;
X	    }
X	    strcpy(buf,buf+1);
X	}
X	else {
X	    if (!entering)
X		continue;
X	}
X	if (*buf == '&') {
X	    mention(buf);
X	    switcheroo();
X	}
X	else if (*buf == '/' && firstart <= lastart) {
X	    mention(buf);
X	    kill_mentioned = TRUE;
X	    switch (art_search(buf, (sizeof buf), FALSE)) {
X	    case SRCH_ABORT:
X		continue;
X	    case SRCH_INTR:
X#ifdef VERBOSE
X		IF(verbose)
X		    printf("\n(Interrupted at article %ld)\n",(long)art)
X		      FLUSH;
X		ELSE
X#endif
X#ifdef TERSE
X		    printf("\n(Intr at %ld)\n",(long)art) FLUSH;
X#endif
X		return -1;
X	    case SRCH_DONE:
X		break;
X	    case SRCH_SUBJDONE:
X		fputs("\tsubject not found (???)\n",stdout) FLUSH;
X		break;
X	    case SRCH_NOTFOUND:
X		fputs("\tnot found\n",stdout) FLUSH;
X		break;
X	    case SRCH_FOUND:
X		fputs("\tfound\n",stdout) FLUSH;
X	    }
X	}
X#ifdef USETHREADS
X	else if (*buf == 'T' && firstart <= lastart && p_roots) {
X	    /* kill a thread by its root id number */
X	    kill_thread = atol(buf+1);
X	    for (i = 0; i < total.root; i++) {
X		if (p_roots[i].root_num == kill_thread) {
X		    if (count_one_root(i) != 0) {
X			mention(buf);
X			kill_mentioned = TRUE;
X			printf("%ldx%d ",(long)kill_thread,
X					 root_article_cnts[i]);
X			p_art = p_articles + p_roots[i].articles;
X			art = p_art->num;
X			follow_thread('k');
X		    }
X		    break;
X		}
X	    }
X	}
X#endif
X    }
X
X    return 0;
X}
X
Xvoid
Xkill_unwanted(starting,message,entering)
XART_NUM starting;
Xchar *message;
Xint entering;
X{
X    bool intr = FALSE;			/* did we get an interrupt? */
X    ART_NUM oldfirst;
X    bool anytokill = (toread[ng] > 0);
X
X    if (localkfp || globkfp) {
X	if (!entering && !exitcmds)
X	    return;
X	exitcmds = FALSE;
X	oldfirst = firstart;
X	firstart = starting;
X	clear();
X#ifdef VERBOSE
X# ifdef TERSE
X	if (message && (verbose || entering))
X# else
X	if (message)
X# endif
X#else
X	if (message && entering)
X#endif
X	    fputs(message,stdout) FLUSH;
X
X	kill_mentioned = FALSE;
X	if (localkfp)
X	    intr = do_kfile(localkfp,entering);
X	if (globkfp && !intr)
X	    intr = do_kfile(globkfp,entering);
X	if (entering && localkfp && !intr)
X	    setthru(lastart);
X	putchar('\n') FLUSH;
X	if (entering && kill_mentioned)
X#ifdef VERBOSE
X	    IF(verbose)
X		get_anything();
X	    ELSE
X#endif
X#ifdef TERSE
X		pad(just_a_sec);
X#endif
X	if (anytokill)			/* if there was anything to kill */
X	    forcelast = FALSE;		/* allow for having killed it all */
X	firstart = oldfirst;
X    }
X}
X
Xvoid
Xsetthru(thru)
XART_NUM thru;
X{
X    FILE *newkfp;
X    bool no_kills = 0;
X#ifdef USETHREADS
X    int i;
X    ART_NUM kill_thread;
X#endif
X
X    fseek(localkfp,0L,0);		/* rewind current file */
X    if (fgets(buf,LBUFLEN,localkfp) != Nullch
X     && (strnNE(buf,"THRU",4) || fgets(buf,LBUFLEN,localkfp) != Nullch))
X	fseek(localkfp,0L,0);
X    else
X	no_kills = 1;
X    strcpy(buf,filexp(getval("KILLLOCAL",killlocal)));
X    UNLINK(buf);			/* to prevent file reuse */
X    if (no_kills)
X	open_kfile(KF_LOCAL);		/* close file and reset open flag */
X    else if (newkfp = fopen(buf,"w")) {
X	fprintf(newkfp,"THRU %ld\n",(long)thru);
X	while (fgets(buf,LBUFLEN,localkfp) != Nullch) {
X	    if (strnEQ(buf,"THRU",4))
X		continue;
X#ifdef USETHREADS
X	    /* Leave out any outdated thread kills */
X	    if (*buf == 'T' && p_roots) {
X		kill_thread = atol(buf+1);
X		for (i = 0; i < total.root; i++) {
X		    if (p_roots[i].root_num == kill_thread) {
X			break;
X		    }
X		}
X		if (i == total.root)
X		    continue;
X	    }
X#endif
X	    fputs(buf,newkfp);
X	}
X	fclose(newkfp);
X	open_kfile(KF_LOCAL);		/* and reopen local file */
X    }
X    else
X	printf(cantcreate,buf) FLUSH;
X}
X
X/* edit KILL file for newsgroup */
X
Xint
Xedit_kfile()
X{
X    int r = -1;
X
X    if (in_ng)
X	strcpy(buf,filexp(getval("KILLLOCAL",killlocal)));
X    else
X	strcpy(buf,filexp(getval("KILLGLOBAL",killglobal)));
X    if ((r = makedir(buf,MD_FILE)) >= 0) {
X	sprintf(cmd_buf,"%s %s",
X	    filexp(getval("VISUAL",getval("EDITOR",defeditor))),buf);
X	printf("\nEditing %s KILL file:\n%s\n",
X	    (in_ng?"local":"global"),cmd_buf) FLUSH;
X	resetty();			/* make sure tty is friendly */
X	r = doshell(sh,cmd_buf);/* invoke the shell */
X	noecho();			/* and make terminal */
X	crmode();			/*   unfriendly again */
X	open_kfile(in_ng);
X    }
X    else
X	printf("Can't make %s\n",buf) FLUSH;
X    return r;
X}
X
Xvoid
Xopen_kfile(local)
Xint local;
X{
X    char *kname = filexp(local ?
X	getval("KILLLOCAL",killlocal) :
X	getval("KILLGLOBAL",killglobal)
X	);
X    
X    stat(kname,&filestat);
X    if (!filestat.st_size)		/* nothing in the file? */
X	UNLINK(kname);			/* delete the file */
X    if (local) {
X	if (localkfp)
X	    fclose(localkfp);
X	localkfp = fopen(kname,"r");
X    }
X    else {
X	if (globkfp)
X	    fclose(globkfp);
X	globkfp = fopen(kname,"r");
X    }
X}
X
Xvoid
Xkf_append(cmd)
Xchar *cmd;
X{
X    strcpy(cmd_buf,filexp(getval("KILLLOCAL",killlocal)));
X    if (makedir(cmd_buf,MD_FILE) >= 0) {
X#ifdef VERBOSE
X	IF(verbose)
X	    printf("\nDepositing command in %s...",cmd_buf);
X	ELSE
X#endif
X#ifdef TERSE
X	    printf("\n--> %s...",cmd_buf);
X#endif
X	fflush(stdout);
X	sleep(2);
X	if ((tmpfp = fopen(cmd_buf,"a")) != Nullfp) {
X	    fseek(tmpfp,0L,2);		/* get to EOF for sure */
X	    fprintf(tmpfp,"%s\n",cmd);
X	    fclose(tmpfp);
X	    fputs("done\n",stdout) FLUSH;
X	}
X	else
X	    printf(cantopen,cmd_buf) FLUSH;
X    }
X}
X#endif /* KILLFILES */
SHAR_EOF
chmod 0660 kfile.c || echo "restore of kfile.c fails"
echo "x - extracting kfile.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > kfile.h &&
X/* $Header: kfile.h,v 4.3 85/05/01 11:42:00 lwall Exp $
X *
X * $Log:	kfile.h,v $
X * Revision 4.3  85/05/01  11:42:00  lwall
X * Baseline for release with 4.3bsd.
X * 
X */
X
X#define KF_GLOBAL 0
X#define KF_LOCAL 1
X
X#ifdef KILLFILES
XEXT FILE *globkfp INIT(Nullfp);		/* global article killer file */
XEXT FILE *localkfp INIT(Nullfp);	/* local (for this newsgroup) */
X					/*  article killer file */
X#endif
X
Xvoid	kfile_init();
Xint	do_kfile();
Xvoid	kill_unwanted();
Xint	edit_kfile();
Xvoid	open_kfile();
Xvoid    kf_append();
Xvoid	setthru();
X
SHAR_EOF
chmod 0660 kfile.h || echo "restore of kfile.h fails"
echo "x - extracting last.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > last.c &&
X/* $Header: last.c,v 4.3.2.1 89/12/20 23:23:07 sob Exp $
X *
X * $Log:	last.c,v $
X * Revision 4.3.2.1  89/12/20  23:23:07  sob
X * .rnlast sometimes is a null file. This gives bogus information when
X * restarting rn following an abnormal termination. This bug was reported
X * by weening at gang-of-four.stanford.edu
X * 
X * Revision 4.3  85/05/01  11:42:16  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 "util.h"
X#include "intrp.h"
X#include "INTERN.h"
X#include "last.h"
X
Xchar *lastname = Nullch;	/* path name of .rnlast file */
X
Xvoid
Xlast_init(tcbuf)
Xchar *tcbuf;
X{
X    lastname = savestr(filexp(LASTNAME));
X    if ((tmpfp = fopen(lastname,"r")) != Nullfp &&
X	fgets(tcbuf,1024,tmpfp) != Nullch) {
X	tcbuf[strlen(tcbuf)-1] = '\0';
X	lastngname = savestr(tcbuf);
X	fgets(tcbuf,1024,tmpfp);
X	lasttime = atol(tcbuf);
X	fgets(tcbuf,1024,tmpfp);
X	lastactsiz = atol(tcbuf);
X	fclose(tmpfp);
X    }
X    else {
X	lastngname = nullstr;
X	lasttime = 0;
X	lastactsiz = 0;
X    }
X}
X
X/* put out certain values for next run of rn */
X
Xvoid
Xwritelast()
X{
X    if ((tmpfp = fopen(lastname,"w")) != Nullfp) {
X	fprintf(tmpfp,"%s\n%ld\n%ld\n",
X	    (ngname==Nullch?nullstr:ngname),(long)lasttime,(long)lastactsiz);
X	fclose(tmpfp);
X    }
X    else
X	printf(cantcreate,lastname) FLUSH;
X}
SHAR_EOF
chmod 0660 last.c || echo "restore of last.c fails"
echo "x - extracting last.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > last.h &&
X/* $Header: last.h,v 4.3 85/05/01 11:42:22 lwall Exp $
X *
X * $Log:	last.h,v $
X * Revision 4.3  85/05/01  11:42:22  lwall
X * Baseline for release with 4.3bsd.
X * 
X */
X
XEXT char *lastngname INIT(Nullch);	/* last newsgroup read, from .rnlast file */
XEXT long lasttime INIT(0);	/* time last rn was started up */
XEXT long lastactsiz INIT(0);	/* size of active file when rn last started up */
X
Xvoid	last_init();
Xvoid    writelast();
SHAR_EOF
chmod 0660 last.h || echo "restore of last.h fails"
echo "x - extracting makedepend.SH (Text)"
sed 's/^X//' << 'SHAR_EOF' > makedepend.SH &&
Xcase $CONFIG in
X    '') . ./config.sh ;;
Xesac
Xecho "Extracting makedepend (with variable substitutions)"
X$spitshell >makedepend <<!GROK!THIS!
X$startsh
X# $Header: makedepend.SH,v 4.3.3.1 90/06/20 22:38:14 davison Trn $
X#
X# $Log:	makedepend.SH,v $
X# Revision 4.3.3.1  90/06/20  22:38:14  davison
X# Initial Trn Release
X# 
X# Revision 4.3.2.2  90/04/21  14:24:58  sob
X# Added a fix to deal with XENIX cc -E output.
X# 
X# Revision 4.3.2.1  89/12/17  02:52:46  sob
X# Will only read config.sh from local directory.
X# 
X# Revision 4.3.1.2  85/05/13  15:53:42  lwall
X# Made cpp look in /usr/local/include too.
X# 
X# Revision 4.3.1.1  85/05/10  11:35:10  lwall
X# Branch for patches.
X# 
X# Revision 4.3  85/05/01  11:42:26  lwall
X# Baseline for release with 4.3bsd.
X# 
X
Xexport PATH || (echo "OOPS, this isn't sh.  Desperation time.  I will feed myself to sh."; sh \$0; kill \$\$)
X
X$cat /dev/null >.deptmp
X$echo "(Note: this is going to take a while.)"
X$rm -f X*.c
Xfor file in *.c; do
X    filebase=\`basename \$file .c\`
X    $echo "Finding dependencies for \$filebase.o."
X    $sed -n <\$file >X\$file \\
X	-e "/^\${filebase}_init(/q" \\
X	-e '/^#/{' \\
X	-e 's|/\*.*$||' \\
X	-e p \\
X	-e '}'
X    $cpp -I/usr/local/include X\$file | $sed  \\
X	-e '/^# *line/s/line//' \
X	-e '/^# *[0-9]/!d' \\
X	-e 's/^.*"\(.*\)".*\$/'\$filebase'.o: \1/' \\
X	-e 's|: \./|: |' \\
X	-e 's|: X|: |' | \\
X	$uniq | $sort | $uniq >> .deptmp
Xdone
X
Xfor file in *.SH; do
X    $echo \`basename \$file .SH\`: \$file config.sh \; /bin/sh \$file >> .deptmp
Xdone
X
X$sed <Makefile >Makefile.new -e '1,/^# AUTOMATICALLY/!d'
X
Xif $test -s .deptmp; then
X    echo "Updating Makefile..."
X    echo "# If this runs make out of memory, delete /usr/include lines." >>Makefile.new
X    $cat .deptmp >>Makefile.new
Xelse
X    $echo "You don't seem to have a proper C preprocessor.  Using grep instead."
X    $egrep '^#include ' *.c *.h >.deptmp
X    echo "Updating Makefile..."
X    <.deptmp $sed -n 's|c:#include "\(.*\)".*\$\$|o: \1|p' >> Makefile.new
X    <.deptmp $sed -n 's|c:#include <\(.*\)>.*\$\$|o: /usr/include/\1|p' >> Makefile.new
X    <.deptmp $sed -n 's|h:#include "\(.*\)".*\$\$|h: \1|p' >> Makefile.new
X    <.deptmp $sed -n 's|h:#include <\(.*\)>.*\$\$|h: /usr/include/\1|p' >> Makefile.new
Xfi
X$mv Makefile Makefile.old
X$mv Makefile.new Makefile
X$echo "# WARNING: Put nothing here or make depend will gobble it up!" >> Makefile
Xrm .deptmp X*.c
X
X!GROK!THIS!
X$eunicefix makedepend
Xchmod 755 makedepend
SHAR_EOF
chmod 0770 makedepend.SH || echo "restore of makedepend.SH fails"
echo "x - extracting makedir.SH (Text)"
sed 's/^X//' << 'SHAR_EOF' > makedir.SH &&
Xcase $CONFIG in
X    '') . ./config.sh ;;
Xesac
Xecho "Extracting makedir (with variable substitutions)"
X$spitshell >makedir <<!GROK!THIS!
X$startsh
X# $Header: makedir.SH,v 4.3 85/05/01 11:42:31 lwall Exp $
X# 
X# $Log:	makedir.SH,v $
X# Revision 4.3  85/05/01  11:42:31  lwall
X# Baseline for release with 4.3bsd.
X# 
X
Xexport PATH || (echo "OOPS, this isn't sh.  Desperation time.  I will feed myself to sh."; sh \$0; kill \$\$)
X
Xcase \$# in
X  0)
X    $echo "makedir pathname filenameflag"
X    exit 1
X    ;;
Xesac
X
X: guarantee one slash before 1st component
Xcase \$1 in
X  /*) ;;
X  *)  set ./\$1 \$2 ;;
Xesac
X
X: strip last component if it is to be a filename
Xcase X\$2 in
X  X1) set \`$echo \$1 | $sed 's:\(.*\)/[^/]*\$:\1:'\` ;;
X  *)  set \$1 ;;
Xesac
X
X: return reasonable status if nothing to be created
Xif $test -d "\$1" ; then
X    exit 0
Xfi
X
Xlist=''
Xwhile true ; do
X    case \$1 in
X    */*)
X	list="\$1 \$list"
X	set \`echo \$1 | $sed 's:\(.*\)/:\1 :'\`
X	;;
X    *)
X	break
X	;;
X    esac
Xdone
X
Xset \$list
X
Xfor dir do
X    $mkdir \$dir >/dev/null 2>&1
Xdone
X!GROK!THIS!
X$eunicefix makedir
Xchmod 755 makedir
SHAR_EOF
chmod 0770 makedir.SH || echo "restore of makedir.SH fails"
echo "x - extracting mbox.saver.SH (Text)"
sed 's/^X//' << 'SHAR_EOF' > mbox.saver.SH &&
Xcase $CONFIG in
X    '') . ./config.sh ;;
Xesac
Xecho "Extracting mbox.saver (with variable substitutions)"
X$spitshell >mbox.saver <<!GROK!THIS!
X$startsh
X# $Header: mbox.saver.SH,v 4.3.2.2 90/03/17 20:44:54 sob Exp $
X# 
X# $Log:	mbox.saver.SH,v $
X# Revision 4.3.2.2  90/03/17  20:44:54  sob
X# Modify Article header to place the colon after Article.
X# 
X# Revision 4.3.2.1  89/11/28  00:05:47  sob
X# Branch for RN/RRN combo patches
X# 
X# Revision 4.3.1.2  85/05/20  15:55:37  lwall
X# Turned $5 into \$5.
X# 
X# Revision 4.3.1.1  85/05/10  11:35:30  lwall
X# Branch for patches.
X# 
X# Revision 4.3  85/05/01  11:42:51  lwall
X# Baseline for release with 4.3bsd.
X# 
X# 
X#	Arguments:
X#	1 Full name of article (%A)
X#	2 Public news spool directory (%P)
X#	3 Directory of current newsgroup (%c)
X#	4 Article number (%a)
X#	5 Where in article to start (%B)
X#	6 Newsgroup name (%C)
X#	7 Save destination (%b)
X#	8 First line of message, normally From...
X#
Xexport PATH || (echo "OOPS, this isn't sh.  Desperation time.  I will feed myself to sh."; sh \$0; kill \$\$)
X
X( $echo "\$8"
X  case "\$5" in
X  0) $echo "Article: \$4 of \$6" ;;
X  esac
X  $tail +\$5c \$1 | $sed "s/^From />From /"
X  $echo ""
X  $echo "" ) >> \$7
X!GROK!THIS!
X$eunicefix mbox.saver
Xchmod 755 mbox.saver
SHAR_EOF
chmod 0770 mbox.saver.SH || echo "restore of mbox.saver.SH fails"
echo "x - extracting mt-lint.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > mt-lint.h &&
X/* $Header: mt-lint.h,v 4.3.3.1 90/06/20 22:55:11 davison Trn $
X**
X** $Log:	mt-lint.h,v $
X** Revision 4.3.3.1  90/06/20  22:55:11  davison
X** Initial Trn Release
X** 
X** Handle brain-dead lints that only have 6 significant-character names.
X*/
X
X#define subject_cnts		sucnts
X#define subject_array		suarra
X#define subject_strings		sustri
X#define subject_str		sustr
X#define author_cnts		aucnts
X#define author_array		auarra
X#define author_root		auroot
X#define author_str		austr
X#define valid_subject		vsubje
X#define valid_author		vautho
X#define valid_message_id	vmsgid
X#define read_authors		rautho
X#define read_articles		rartic
X#define read_ids		rids
X#define read_item		ritem
X#define processed_groups	pgroup
X#define process_articles	partic
X#define expired_articles	eartic
X#define unlink_child		uchild
X#define unlink_root		uroot
X#define free_article		fartic
X#define free_author		fautho
X#define enumerate_articles	enarti
X#define enumerate_thread	enthrd
X#define string_offset		soffst
X#define write_authors		wautho
X#define write_subjects		wsubje
X#define write_roots		wroots
X#define write_articles		wartic
SHAR_EOF
echo "End of part 7"
echo "File mt-lint.h is continued in part 8"
echo "8" > 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