Subject: v23i065: Complete reposting of TRN at patchlevel 1, Part06/14 Newsgroups: comp.sources.unix Approved: rsalz@uunet.UU.NET X-Checksum-Snefru: 32633444 e8615b27 fae2f921 4692796a Submitted-by: Wayne Davison <0004475895@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@uunet.uu.net if you want that tool. # Contents: common.h intrp.c term.h # Wrapped by rsalz@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@cd.SFSU.EDU. X * X * Revision 4.3.2.7 89/12/08 22:43:12 sob X * Corrected typo pointed out by weening@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 * 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 X#endif X X#include X#include X#include X#include X X#ifndef isalnum X# define isalnum(c) (isalpha(c) || isdigit(c)) X#endif X X#include X#include X#ifdef IOCTL X#include X#endif X X#ifdef FCNTL X# include X#endif X X#ifdef TERMIO X# include X#else X# include X#endif X X#ifdef GETPWENT X# include 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 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 . 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 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@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...