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