v23i065: Complete reposting of TRN at patchlevel 1, Part06/14

Rich Salz rsalz at bbn.com
Fri Jan 4 04:54:13 AEST 1991


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

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then feed it
# into a shell via "sh file" or similar.  To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix at uunet.uu.net if you want that tool.
# Contents:  common.h intrp.c term.h
# Wrapped by rsalz at litchi.bbn.com on Thu Dec 27 11:34:05 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo '          "shar: End of archive 6 (of 14)."'
if test -f 'common.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'common.h'\"
else
  echo shar: Extracting \"'common.h'\" \(26231 characters\)
  sed "s/^X//" >'common.h' <<'END_OF_FILE'
X/* $Header: common.h,v 4.3.3.2 90/08/20 16:28:32 davison Trn $
X * 
X * $Log:	common.h,v $
X * Revision 4.3.3.2  90/08/20  16:28:32  davison
X * Tweaked a couple rn's into trn's.
X * 
X * Revision 4.3.3.1  90/07/21  20:15:23  davison
X * Initial Trn Release
X * 
X * Revision 4.3.2.13  90/05/08  22:05:37  sob
X * Added quick startup (-q) flag.
X * 
X * Revision 4.3.2.12  90/04/23  00:32:04  sob
X * More cleanup.
X * 
X * Revision 4.3.2.11  90/04/14  19:37:07  sob
X * Added better support for the NeXT.
X * 
X * Revision 4.3.2.10  90/04/06  20:54:12  sob
X * Corrected forward definition of fseek()
X * 
X * Revision 4.3.2.9  90/03/17  21:19:04  sob
X * Removed the incorrect forward definition of sprintf().
X * 
X * Revision 4.3.2.8  89/12/20  20:40:03  sob
X * Changed ACT_POS from short to long per suggestion from eps at cd.SFSU.EDU.
X * 
X * Revision 4.3.2.7  89/12/08  22:43:12  sob
X * Corrected typo pointed out by weening at gang-of-four.stanford.edu
X * 
X * Revision 4.3.2.6  89/11/28  01:57:31  sob
X * Added initlines_specified variable for use with SIGWINCH support.
X * 
X * Revision 4.3.2.5  89/11/28  00:30:56  sob
X * Reversed the CANCELHEADER definitions.
X * 
X * Revision 4.3.2.4  89/11/27  01:29:23  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  19:32:06  sob
X * Increased the size of MAXRCLINE from 1000 to 1500
X * Increated HASHSIZ from 1103 to 1693
X * 
X * Revision 4.3.2.2  89/11/07  23:18:49  sob
X * Repaired NEWSHEADER and CANCEL to work correctly with NNTP and INTERNET.
X * 
X * Revision 4.3.2.1  89/11/06  00:12:33  sob
X * Added RRN support from NNTP 1.5
X * 
X * Revision 4.3.1.4  86/10/31  15:46:09  lwall
X * Expanded maximum number of .newsrc lines for net reorganization.
X * 
X * Revision 4.3.1.3  85/05/23  17:19:32  lwall
X * Now allows 'r' and 'f' on null articles.
X * 
X * Revision 4.3.1.2  85/05/13  09:30:39  lwall
X * Added CUSTOMLINES option.
X * 
X * Revision 4.3.1.1  85/05/10  11:32:04  lwall
X * Branch for patches.
X * 
X * Revision 4.3  85/05/01  11:37:11  lwall
X * Baseline for release with 4.3bsd.
X * 
X */
X
X#include "config.h"	/* generated by installation script */
X#ifdef WHOAMI
X#    include <whoami.h>
X#endif
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <ctype.h>
X
X#ifndef isalnum
X#   define isalnum(c) (isalpha(c) || isdigit(c))
X#endif
X
X#include <errno.h>
X#include <signal.h>
X#ifdef IOCTL
X#include <sys/ioctl.h>
X#endif
X
X#ifdef FCNTL
X#   include <fcntl.h>
X#endif
X
X#ifdef TERMIO
X#   include <termio.h>
X#else
X#   include <sgtty.h>
X#endif
X
X#ifdef GETPWENT
X#   include <pwd.h>
X#endif
X
X#define BITSPERBYTE 8
X#define LBUFLEN 512	/* line buffer length */
X			/* (don't worry, .newsrc lines can exceed this) */
X#ifdef pdp11
X#   define CBUFLEN 256	/* command buffer length */
X#   define PUSHSIZE 128
X#else
X#   define CBUFLEN 512	/* command buffer length */
X#   define PUSHSIZE 256
X#endif
X#ifdef pdp11
X#   define MAXFILENAME 128
X#else
X#   define MAXFILENAME 512
X#endif
X#define LONGKEY 15	/* longest keyword: currently "posting-version" */
X#define FINISHCMD 0177
X
X/* some handy defs */
X
X#define bool char
X#define TRUE (1)
X#define FALSE (0)
X#define Null(t) ((t)0)
X#define Nullch Null(char *)
X#define Nullfp Null(FILE *)
X
X#define Ctl(ch) (ch & 037)
X
X#define strNE(s1,s2) (strcmp(s1,s2))
X#define strEQ(s1,s2) (!strcmp(s1,s2))
X#define strnNE(s1,s2,l) (strncmp(s1,s2,l))
X#define strnEQ(s1,s2,l) (!strncmp(s1,s2,l))
X
X/* Things we can figure out ourselves */
X
X#ifdef SIGTSTP
X#   define BERKELEY 	/* include job control signals? */
X#endif
X
X#ifdef FIONREAD
X#   define PENDING
X#else
X#   ifdef O_NDELAY
X#	define PENDING
X#   endif
X#endif
X
X#ifdef EUNICE
X#   define LINKART		/* add 1 level of possible indirection */
X#   define UNLINK(victim) while (!unlink(victim))
X#else
X#   define UNLINK(victim) unlink(victim)
X#endif
X
X/* Valid substitutions for strings marked with % comment are:
X *	%a	Current article number
X *	%A	Full name of current article (%P/%c/%a)
X *		(if LINKART defined, is the name of the real article)
X *	%b	Destination of a save command, a mailbox or command
X *	%B	The byte offset to the beginning of the article for saves
X *		with or without the header
X *	%c	Current newsgroup, directory form
X *	%C	Current newsgroup, dot form
X *	%d	%P/%c
X *	%D	Old Distribution: line
X *	%f	Old From: line or Reply-To: line
X *	%F	Newsgroups to followup to from Newsgroups: and Followup-To:
X *	%h	Name of header file to pass to mail or news poster
X *	%H	Host name (yours)
X *	%i	Old Message-I.D.: line, with <>
X *	%I	Inclusion indicator
X *	%l	News administrator login name
X *	%L	Login name (yours)
X *	%M	Number of articles markd with M
X *	%n	Newsgroups from source article
X *	%N	Full name (yours)
X *	%o	Organization (yours)
X *	%O	Original working directory (where you ran rn from)
X *	%p	Your private news directory (-d switch)
X *	%P	Public news spool directory (SPOOLDIR)
X *	%r	Last reference (parent article id)
X *	%R	New references list
X *	%s	Subject, with all Re's and (nf)'s stripped off
X *	%S	Subject, with one Re stripped off
X *	%t	New To: line derived from From: and Reply-To (Internet always)
X *	%T	New To: line derived from Path:
X *	%u	Number of unread articles
X *	%U	Number of unread articles disregarding current article
X *	%x	News library directory, usually /usr/lib/news
X *	%X	Rn library directory, usually %x/rn
X *	%z	Size of current article in bytes.
X *	%~	Home directory
X *	%.	Directory containing . files
X *	%$	current process number
X *	%{name} Environment variable "name".  %{name-default} form allowed.
X *	%[name]	Header line beginning with "Name: ", without "Name: " 
X *	%"prompt"
X *		Print prompt and insert what is typed.
X *	%`command`
X *		Insert output of command.
X *	%(test_text=pattern?if_text:else_text)
X *		Substitute if_text if test_text matches pattern, otherwise
X *		substitute else_text.  Use != for negated match.
X *		% substitutions are done on test_text, if_text, and else_text.
X *		(Note: %() only works if CONDSUB defined.)
X *	%digit	Substitute the text matched by the nth bracket in the last
X *		pattern that had brackets.  %0 matches the last bracket
X *		matched, in case you had alternatives.
X *
X *	Put ^ in the middle to capitalize the first letter: %^C = Net.jokes
X *	Put _ in the middle to capitalize last component: %_c = net/Jokes
X *
X *	~ interpretation in filename expansion happens after % expansion, so
X *	you could put ~%{NEWSLOGNAME-news} and it will expand correctly.
X */
X
X/* *** System Dependent Stuff *** */
X
X/* NOTE: many of these are defined in the config.h file */
X
X/* name of organization */
X#ifndef ORGNAME
X#   define ORGNAME "ACME Widget Company, Widget Falls, Southern North Dakota"
X#endif
X
X#ifndef MBOXCHAR
X#   define MBOXCHAR 'F'	/* how to recognize a mailbox by 1st char */
X#endif
X
X#ifndef ROOTID
X#   define ROOTID 0        /* uid of superuser */
X#endif
X
X#ifdef NORMSIG
X#   define sigset signal
X#   define sigignore(sig) signal(sig,SIG_IGN)
X#endif
X
X#ifndef LOGDIRFIELD
X#   define LOGDIRFIELD 6		/* Which field (origin 1) is the */
X					/* login directory in /etc/passwd? */
X					/* (If it is not kept in passwd, */
X					/* but getpwnam() returns it, */
X					/* define the symbol GETPWENT) */
X#endif
X#ifndef GCOSFIELD
X#   define GCOSFIELD 5
X#endif
X
X#ifndef NEGCHAR
X#   define NEGCHAR '!'
X#endif
X
X/* Space conservation section */
X
X/* To save D space, cut down size of MAXRCLINE, NGMAX, VARYSIZE. */
X#define MAXRCLINE 1500	/* number of lines allowed in .newsrc */
X			/* several parallel arrays affected. */
X			/* (You can have more lines in the active file, */
X			/* just not in the .newsrc) */
X#define HASHSIZ 1693	/* should be prime, and at least MAXRCLINE + 10% */
X#define NGMAX 100	/* number of newsgroups allowed on command line */
X			/* undefine ONLY symbol to disable "only" feature */
X#define VARYSIZE 256	/* this makes a block 1024 bytes long in DECville */
X			/* (used by virtual array routines) */
X
X/* Undefine any of the following features to save both I and D space */
X/* In general, earlier ones are easier to get along without */
X/* Pdp11's without split I and D may have to undefine them all */
X#define DEBUGGING	/* include debugging code */
X#define USETHREADS	/* Add article-thread following */
X#define CUSTOMLINES	/* include code for HIDELINE and PAGESTOP */
X#define PUSHBACK	/* macros and keymaps using pushback buffer */
X#define SPEEDOVERMEM	/* use more memory to run faster */
X#define WORDERASE	/* enable ^W to erase a word */
X#define MAILCALL	/* check periodically for mail */
X#define CLEAREOL	/* use clear to end-of-line instead of clear screen */
X#define NOFIREWORKS	/* keep whole screen from flashing on certain */
X			/* terminals such as older Televideos */
X#define VERIFY		/* echo the command they just typed */
X#define HASHNG		/* hash newsgroup lines for fast lookup-- */
X			/* linear search used if not defined */
X#define CONDSUB		/* allow %(cond?text:text) */
X#define BACKTICK	/* allow %`command` */
X#define PROMPTTTY	/* allow %"prompt" */
X#define ULSMARTS	/* catch _^H in text and do underlining */
X#define TERMMOD		/* allow terminal type modifier on switches */
X#define BAUDMOD		/* allow baudrate modifier on switches */
X#define GETLOGIN	/* use getlogin() routine as backup to environment */
X			/* variables USER or LOGNAME */
X#define ORGFILE		/* if organization begins with /, look up in file */
X#define TILDENAME	/* allow ~logname expansion */
X#define SETENV		/* allow command line environment variable setting */
X#define GETWD		/* use our getwd() instead of piped in pwd */
X#define MAKEDIR		/* use our makedir() instead of shell script */
X#define MEMHELP		/* keep help messages in memory */
X#define VERBOSE		/* compile in more informative messages */
X#define TERSE		/* compile in shorter messages */
X			/* (Note: both VERBOSE and TERSE can be defined; -t
X			 * sets terse mode.  One or the other MUST be defined.
X			 */
X#ifndef pdp11
X#   define CACHESUBJ	/* cache subject lines in memory */
X			/* without this ^N still works but runs really slow */
X			/* but you save lots and lots of D space */
X#   define CACHEFIRST	/* keep absolute first article numbers in memory */
X			/* cost: about 2k */
X#endif
X#define ROTATION	/* enable x, X and ^X commands to work */
X#define DELBOGUS	/* ask if bogus newsgroups should be deleted */
X#define RELOCATE	/* allow newsgroup rearranging */
X#define ESCSUBS		/* escape substitutions in multi-character commands */
X#define DELAYMARK	/* allow articles to be temporarily marked as read */
X			/* until exit from current newsgroup or Y command */
X#define MCHASE		/* unmark xrefed articles on m or M */
X#define MUNGHEADER	/* allow alternate header formatting via */
X			/* environment variable ALTHEADER (not impl) */
X#define ASYNC_PARSE	/* allow parsing headers asyncronously to reading */
X			/* used by MCHASE and MUNGHEADER */
X#define FINDNEWNG	/* check for new newsgroups on startup */
X#define FASTNEW		/* do optimizations on FINDNEWNG for faster startup */
X			/* (this optimization can make occasional mistakes */
X			/* if a group is removed and another group of the */
X			/* same length is added, and if no softpointers are */
X			/* affected by said change.) */
X#define INNERSEARCH	/* search command 'g' with article */
X#define CATCHUP		/* catchup command at newsgroup level */
X#define NGSEARCH	/* newsgroup pattern matching */
X#define ONLY		/* newsgroup restrictions by pattern */
X#define KILLFILES	/* automatic article killer files */
X#define ARTSEARCH	/* pattern searches among articles */
X			/* /, ?, ^N, ^P, k, K */
X
X/* some dependencies among options */
X
X#ifndef ARTSEARCH
X#   undef KILLFILES
X#   undef INNERSEARCH
X#   undef CACHESUBJ
X#endif
X
X#ifndef DELAYMARK
X#   ifndef MCHASE
X#	ifndef MUNGHEADER
X#	    undef ASYNC_PARSE
X#	endif
X#   endif
X#endif
X
X#ifndef SETUIDGID
X#   define eaccess access
X#endif
X
X#ifdef ONLY				/* idiot lint doesn't grok #if */
X#   define NGSORONLY
X#else
X#   ifdef NGSEARCH
X#	define NGSORONLY
X#   endif
X#endif
X
X#ifdef VERBOSE
X#   ifdef TERSE
X#	define IF(c) if (c)
X#	define ELSE else
X#   else
X#	define IF(c)
X#	define ELSE
X#   endif
X#else /* !VERBOSE */
X#   ifndef TERSE
X#	define TERSE
X#   endif
X#   define IF(c) "IF" outside of VERBOSE???
X#   define ELSE "ELSE" outside of VERBOSE???
X#endif
X
X#ifdef DEBUGGING
X#   define assert(ex) {if (!(ex)){fprintf(stderr,"Assertion failed: file %s, line %d\n", __FILE__, __LINE__);sig_catcher(0);}}
X#else
X#   define assert(ex) ;
X#endif
X
X#ifdef SPEEDOVERMEM
X#   define OFFSET(x) (x)
X#else
X#   define OFFSET(x) ((x)-absfirst)
X#endif
X
X/* If you're strapped for space use the help messages in shell scripts */
X/* if {NG,ART,PAGER,SUBS}HELP is undefined, help messages are in memory */
X#ifdef MEMHELP  /* undef MEMHELP above to get them all as sh scripts */
X#   undef NGHELP
X#   undef ARTHELP
X#   undef PAGERHELP
X#   undef SUBSHELP
X#else
X#   ifndef NGHELP			/* % and ~ */
X#	define NGHELP "%X/ng.help"
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/trn"
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 trn.\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
END_OF_FILE
  if test 26231 -ne `wc -c <'common.h'`; then
    echo shar: \"'common.h'\" unpacked with wrong size!
  fi
  # end of 'common.h'
fi
if test -f 'intrp.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'intrp.c'\"
else
  echo shar: Extracting \"'intrp.c'\" \(25527 characters\)
  sed "s/^X//" >'intrp.c' <<'END_OF_FILE'
X/* $Header: intrp.c,v 4.3.3.2 90/08/20 16:29:08 davison Trn $
X *
X * $Log:	intrp.c,v $
X * Revision 4.3.3.2  90/08/20  16:29:08  davison
X * Added HOSTFILE handling.  Add OURDOMAIN if site has no '.'
X * 
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 HOSTFILE
X    if ((tmpfp = fopen(HOSTFILE,"r")) == NULL) {
X	hostname = "unknown";
X	printf("Warning: Couldn't open %s to determine hostname!\n", HOSTFILE); 
X    } else {
X	fgets(buf, sizeof(buf), tmpfp);
X	buf[strlen(buf)-1] = 0;
X	hostname = savestr(buf);
X	fclose(tmpfp);
X    }
X#else
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#endif
X#ifdef OURDOMAIN
X    if (index(SITENAME,'.') == NULL) {
X	sprintf(buf, "%s.%s", SITENAME, OURDOMAIN);
X	sitename = savestr(buf);
X    } else
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}
END_OF_FILE
  if test 25527 -ne `wc -c <'intrp.c'`; then
    echo shar: \"'intrp.c'\" unpacked with wrong size!
  fi
  # end of 'intrp.c'
fi
if test -f 'term.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'term.h'\"
else
  echo shar: Extracting \"'term.h'\" \(7622 characters\)
  sed "s/^X//" >'term.h' <<'END_OF_FILE'
X/* $Header: term.h,v 4.3.3.1 90/06/20 22:40:34 davison Trn $
X *
X * $Log:	term.h,v $
X * Revision 4.3.3.1  90/06/20  22:40:34  davison
X * Initial Trn Release
X * 
X * Revision 4.3.2.2  90/04/06  20:35:34  sob
X * Added fixes for SCO Xenix sent by ronald at robobar.co.uk.
X * 
X * Revision 4.3.2.1  89/11/28  01:54:03  sob
X * Added better support for SIGWINCH.
X * 
X * Revision 4.3.1.2  85/05/13  15:52:05  lwall
X * Declared devtty on TERMIO system.
X * 
X * Revision 4.3.1.1  85/05/10  11:41:24  lwall
X * Branch for patches.
X * 
X * Revision 4.3  85/05/01  11:51:36  lwall
X * Baseline for release with 4.3bsd.
X * 
X */
X
X#ifdef PUSHBACK
XEXT char circlebuf[PUSHSIZE];
XEXT int nextin INIT(0);
XEXT int nextout INIT(0);
X#ifdef PENDING
X#ifdef FIONREAD
XEXT long iocount INIT(0);
X#ifndef lint
X#define input_pending() (nextin!=nextout || (ioctl(0, FIONREAD, &iocount),(int)iocount))
X#else
X#define input_pending() bizarre
X#endif /* lint */
X#else /* FIONREAD */
X#ifdef RDCHK
X#define input_pending() (rdchk(0) > 0)		/* boolean only */
X#else /*  RDCHK */
Xint circfill();
XEXT int devtty INIT(0);
X#ifndef lint
X#define input_pending() (nextin!=nextout || circfill())
X#else
X#define input_pending() bizarre
X#endif /* lint */
X#endif /* RDCHK */
X#endif /* FIONREAD */
X#else /* PENDING */
X#ifndef lint
X#define input_pending() (nextin!=nextout)
X#else
X#define input_pending() bizarre
X#endif /* lint */
X#endif /* PENDING */
X#else /* PUSHBACK */
X#ifdef PENDING
X#ifdef FIONREAD	/* must have FIONREAD or O_NDELAY for input_pending() */
X#define read_tty(addr,size) read(0,addr,size)
X#ifndef lint
X#define input_pending() (ioctl(0, FIONREAD, &iocount),(int)iocount)
X#else
X#define input_pending() bizarre
X#endif /* lint */
XEXT long iocount INIT(0);
X
X#else /* FIONREAD */
X
X#ifdef RDCHK
X#define input_pending() (rdchk(0) > 0)		/* boolean only */
X#else /*  RDCHK */
X
XEXT int devtty INIT(0);
XEXT bool is_input INIT(FALSE);
XEXT char pending_ch INIT(0);
X#ifndef lint
X#define input_pending() (is_input || (is_input=read(devtty,&pending_ch,1)))
X#else
X#define input_pending() bizarre
X#endif /* lint */
X#endif /*  RDCHK */
X#endif /* FIONREAD */
X#else /* PENDING */
X#define read_tty(addr,size) read(0,addr,size)
X#define input_pending() (FALSE)
X#endif /* PENDING */
X#endif /* PUSHBACK */
X
X/* stuff wanted by terminal mode diddling routines */
X
X#ifdef TERMIO
XEXT struct termio _tty, _oldtty;
X#else
XEXT struct sgttyb _tty;
XEXT int _res_flg INIT(0);
X#endif
X
XEXT int _tty_ch INIT(2);
XEXT bool bizarre INIT(FALSE);			/* do we need to restore terminal? */
X
X/* terminal mode diddling routines */
X
X#ifdef TERMIO
X
X#define crmode() ((bizarre=1),_tty.c_lflag &=~ICANON,_tty.c_cc[VMIN] = 1,ioctl(_tty_ch,TCSETAF,&_tty))
X#define nocrmode() ((bizarre=1),_tty.c_lflag |= ICANON,_tty.c_cc[VEOF] = CEOF,stty(_tty_ch,&_tty))
X#define echo()	 ((bizarre=1),_tty.c_lflag |= ECHO, ioctl(_tty_ch, TCSETA, &_tty))
X#define noecho() ((bizarre=1),_tty.c_lflag &=~ECHO, ioctl(_tty_ch, TCSETA, &_tty))
X#define nl()	 ((bizarre=1),_tty.c_iflag |= ICRNL,_tty.c_oflag |= ONLCR,ioctl(_tty_ch, TCSETAW, &_tty))
X#define nonl()	 ((bizarre=1),_tty.c_iflag &=~ICRNL,_tty.c_oflag &=~ONLCR,ioctl(_tty_ch, TCSETAW, &_tty))
X#define	savetty() (ioctl(_tty_ch, TCGETA, &_oldtty),ioctl(_tty_ch, TCGETA, &_tty))
X#define	resetty() ((bizarre=0),ioctl(_tty_ch, TCSETAF, &_oldtty))
X#define unflush_output()
X
X#else
X
X#define raw()	 ((bizarre=1),_tty.sg_flags|=RAW, stty(_tty_ch,&_tty))
X#define noraw()	 ((bizarre=1),_tty.sg_flags&=~RAW,stty(_tty_ch,&_tty))
X#define crmode() ((bizarre=1),_tty.sg_flags |= CBREAK, stty(_tty_ch,&_tty))
X#define nocrmode() ((bizarre=1),_tty.sg_flags &= ~CBREAK,stty(_tty_ch,&_tty))
X#define echo()	 ((bizarre=1),_tty.sg_flags |= ECHO, stty(_tty_ch, &_tty))
X#define noecho() ((bizarre=1),_tty.sg_flags &= ~ECHO, stty(_tty_ch, &_tty))
X#define nl()	 ((bizarre=1),_tty.sg_flags |= CRMOD,stty(_tty_ch, &_tty))
X#define nonl()	 ((bizarre=1),_tty.sg_flags &= ~CRMOD, stty(_tty_ch, &_tty))
X#define	savetty() (gtty(_tty_ch, &_tty), _res_flg = _tty.sg_flags)
X#define	resetty() ((bizarre=0),_tty.sg_flags = _res_flg, stty(_tty_ch, &_tty))
X#ifdef LFLUSHO
X#ifndef lint
XEXT int lflusho INIT(LFLUSHO);
X#else
XEXT long lflusho INIT(LFLUSHO);
X#endif /* lint */
X#define unflush_output() (ioctl(_tty_ch,TIOCLBIC,&lflusho))
X#else
X#define unflush_output()
X#endif /* LFLUSHO */
X#endif /* TERMIO */
X
X#ifdef TIOCSTI
X#ifdef lint
X#define forceme(c) ioctl(_tty_ch,TIOCSTI,Null(long*))	/* ghad! */
X#else
X#define forceme(c) ioctl(_tty_ch,TIOCSTI,c) /* pass character in " " */
X#endif /* lint */
X#else
X#define forceme(c)
X#endif
X
X/* termcap stuff */
X
X/*
X * NOTE: if you don't have termlib you'll either have to define these strings
X *    and the tputs routine, or you'll have to redefine the macros below
X */
X
X#ifdef HAVETERMLIB
XEXT char *BC INIT(Nullch);		/* backspace character */
XEXT char *UP INIT(Nullch);		/* move cursor up one line */
XEXT char *CR INIT(Nullch);		/* get to left margin, somehow */
XEXT char *VB INIT(Nullch);		/* visible bell */
XEXT char *CL INIT(Nullch);		/* home and clear screen */
XEXT char *CE INIT(Nullch);		/* clear to end of line */
X#ifdef CLEAREOL
XEXT char *CM INIT(Nullch);		/* cursor motion -- PWP */
XEXT char *HO INIT(Nullch);		/* home cursor -- PWP */
XEXT char *CD INIT(Nullch);		/* clear to end of display -- PWP */
X#endif /* CLEAREOL */
XEXT char *SO INIT(Nullch);		/* begin standout mode */
XEXT char *SE INIT(Nullch);		/* end standout mode */
XEXT int SG INIT(0);		/* blanks left by SO and SE */
XEXT char *US INIT(Nullch);		/* start underline mode */
XEXT char *UE INIT(Nullch);		/* end underline mode */
XEXT char *UC INIT(Nullch);		/* underline a character, if that's how it's done */
XEXT int UG INIT(0);		/* blanks left by US and UE */
XEXT bool AM INIT(FALSE);		/* does terminal have automatic margins? */
XEXT bool XN INIT(FALSE);		/* does it eat 1st newline after automatic wrap? */
XEXT char PC INIT(0);		/* pad character for use by tputs() */
XEXT short ospeed INIT(0);	/* terminal output speed, for use by tputs() */
XEXT int LINES INIT(0), COLS INIT(0);	/* size of screen */
XEXT int just_a_sec INIT(960);			/* 1 sec at current baud rate */
X					/* (number of nulls) */
X
X/* define a few handy macros */
X
X#define backspace() tputs(BC,0,putchr) FLUSH
X#define clear() tputs(CL,LINES,putchr) FLUSH
X#define erase_eol() tputs(CE,1,putchr) FLUSH
X#ifdef CLEAREOL
X#define clear_rest() tputs(CD,LINES,putchr) FLUSH	/* PWP */
X#define maybe_eol() if(erase_screen&&can_home_clear)tputs(CE,1,putchr) FLUSH
X#endif /* CLEAREOL */
X#define underline() tputs(US,1,putchr) FLUSH
X#define un_underline() tputs(UE,1,putchr) FLUSH
X#define underchar() tputs(UC,0,putchr) FLUSH
X#define standout() tputs(SO,1,putchr) FLUSH
X#define un_standout() tputs(SE,1,putchr) FLUSH
X#define up_line() tputs(UP,1,putchr) FLUSH
X#define carriage_return() tputs(CR,1,putchr) FLUSH
X#define dingaling() tputs(VB,1,putchr) FLUSH
X#else
X  ????????		/* up to you */
X#endif
X
XEXT int page_line INIT(1);	/* line number for paging in print_line (origin 1) */
X
Xvoid	term_init();
Xvoid	term_set();
X#ifdef PUSHBACK
Xvoid	pushchar();
Xvoid	mac_init();
Xvoid	mac_line();
Xvoid	show_macros();
X#endif
Xchar	putchr();	/* routine for tputs to call */
Xbool	finish_command();
Xvoid	eat_typeahead();
Xvoid	settle_down();
X#ifndef read_tty
X    int		read_tty();
X#endif
Xvoid	underprint();
X#ifdef NOFIREWORKS
X    void	no_sofire();
X    void	no_ulfire();
X#endif
Xvoid	getcmd();
Xint	get_anything();
Xvoid	in_char();
Xint	print_lines();
Xvoid	page_init();
Xvoid	pad();
Xvoid	printcmd();
Xvoid	rubout();
Xvoid	reprint();
X#if defined(CLEAREOL) || defined(USETHREADS)
Xvoid	home_cursor();
X#endif
X#ifdef USETHREADS
Xvoid	goto_line();
X#endif
X#ifdef SIGWINCH
Xint	winch_catcher();
X#endif /* SIGWINCH */
END_OF_FILE
  if test 7622 -ne `wc -c <'term.h'`; then
    echo shar: \"'term.h'\" unpacked with wrong size!
  fi
  # end of 'term.h'
fi
echo shar: End of archive 6 \(of 14\).
cp /dev/null ark6isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 14 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still must unpack the following archives:
    echo "        " ${MISSING}
fi
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