1: /* $Header: common.h,v 4.3.1.3 85/05/23 17:19:32 lwall Exp $
2: *
3: * $Log: common.h,v $
4: * Revision 4.3.1.3 85/05/23 17:19:32 lwall
5: * Now allows 'r' and 'f' on null articles.
6: *
7: * Revision 4.3.1.2 85/05/13 09:30:39 lwall
8: * Added CUSTOMLINES option.
9: *
10: * Revision 4.3.1.1 85/05/10 11:32:04 lwall
11: * Branch for patches.
12: *
13: * Revision 4.3 85/05/01 11:37:11 lwall
14: * Baseline for release with 4.3bsd.
15: *
16: */
17:
18: #include "config.h" /* generated by installation script */
19: #ifdef WHOAMI
20: # include <whoami.h>
21: #endif
22:
23: #include <stdio.h>
24: #include <sys/types.h>
25: #include <sys/stat.h>
26: #include <ctype.h>
27:
28: #ifndef isalnum
29: # define isalnum(c) (isalpha(c) || isdigit(c))
30: #endif
31:
32: #include <errno.h>
33: #include <signal.h>
34: #ifdef IOCTL
35: #include <sys/ioctl.h>
36: #endif IOCTL
37:
38: #ifdef FCNTL
39: # include <fcntl.h>
40: #endif
41:
42: #ifdef TERMIO
43: # include <termio.h>
44: #else
45: # include <sgtty.h>
46: #endif
47:
48: #ifdef GETPWENT
49: # include <pwd.h>
50: #endif
51:
52: #define BITSPERBYTE 8
53: #define LBUFLEN 512 /* line buffer length */
54: /* (don't worry, .newsrc lines can exceed this) */
55: #ifdef pdp11
56: # define CBUFLEN 256 /* command buffer length */
57: # define PUSHSIZE 128
58: #else
59: # define CBUFLEN 512 /* command buffer length */
60: # define PUSHSIZE 256
61: #endif
62: #ifdef pdp11
63: # define MAXFILENAME 128
64: #else
65: # define MAXFILENAME 512
66: #endif
67: #define LONGKEY 15 /* longest keyword: currently "posting-version" */
68: #define FINISHCMD 0177
69:
70: /* some handy defs */
71:
72: #define bool char
73: #define TRUE (1)
74: #define FALSE (0)
75: #define Null(t) ((t)0)
76: #define Nullch Null(char *)
77: #define Nullfp Null(FILE *)
78:
79: #define Ctl(ch) (ch & 037)
80:
81: #define strNE(s1,s2) (strcmp(s1,s2))
82: #define strEQ(s1,s2) (!strcmp(s1,s2))
83: #define strnNE(s1,s2,l) (strncmp(s1,s2,l))
84: #define strnEQ(s1,s2,l) (!strncmp(s1,s2,l))
85:
86: /* Things we can figure out ourselves */
87:
88: #ifdef SIGTSTP
89: # define BERKELEY /* include job control signals? */
90: #endif
91:
92: #ifdef SIGPROF
93: # define BSD42 /* do we have Berkeley 4.2? */
94: #endif
95:
96: #ifdef FIONREAD
97: # define PENDING
98: #else
99: # ifdef O_NDELAY
100: # define PENDING
101: # endif
102: #endif
103:
104: #ifdef EUNICE
105: # define LINKART /* add 1 level of possible indirection */
106: # define UNLINK(victim) while (!unlink(victim))
107: #else
108: # define UNLINK(victim) unlink(victim)
109: #endif
110:
111: /* Valid substitutions for strings marked with % comment are:
112: * %a Current article number
113: * %A Full name of current article (%P/%c/%a)
114: * (if LINKART defined, is the name of the real article)
115: * %b Destination of a save command, a mailbox or command
116: * %B The byte offset to the beginning of the article for saves
117: * with or without the header
118: * %c Current newsgroup, directory form
119: * %C Current newsgroup, dot form
120: * %d %P/%c
121: * %D Old Distribution: line
122: * %f Old From: line or Reply-To: line
123: * %F Newsgroups to followup to from Newsgroups: and Followup-To:
124: * %h Name of header file to pass to mail or news poster
125: * %H Host name (yours)
126: * %i Old Message-I.D.: line, with <>
127: * %I Inclusion indicator
128: * %l News administrator login name
129: * %L Login name (yours)
130: * %M Number of articles markd with M
131: * %n Newsgroups from source article
132: * %N Full name (yours)
133: * %o Organization (yours)
134: * %O Original working directory (where you ran rn from)
135: * %p Your private news directory (-d switch)
136: * %P Public news spool directory (SPOOLDIR)
137: * %r Last reference (parent article id)
138: * %R New references list
139: * %s Subject, with all Re's and (nf)'s stripped off
140: * %S Subject, with one Re stripped off
141: * %t New To: line derived from From: and Reply-To (Internet always)
142: * %T New To: line derived from Path:
143: * %u Number of unread articles
144: * %U Number of unread articles disregarding current article
145: * %x News library directory, usually /usr/lib/news
146: * %X Rn library directory, usually %x/rn
147: * %z Size of current article in bytes.
148: * %~ Home directory
149: * %. Directory containing . files
150: * %$ current process number
151: * %{name} Environment variable "name". %{name-default} form allowed.
152: * %[name] Header line beginning with "Name: ", without "Name: "
153: * %"prompt"
154: * Print prompt and insert what is typed.
155: * %`command`
156: * Insert output of command.
157: * %(test_text=pattern?if_text:else_text)
158: * Substitute if_text if test_text matches pattern, otherwise
159: * substitute else_text. Use != for negated match.
160: * % substitutions are done on test_text, if_text, and else_text.
161: * (Note: %() only works if CONDSUB defined.)
162: * %digit Substitute the text matched by the nth bracket in the last
163: * pattern that had brackets. %0 matches the last bracket
164: * matched, in case you had alternatives.
165: *
166: * Put ^ in the middle to capitalize the first letter: %^C = Net.jokes
167: * Put _ in the middle to capitalize last component: %_c = net/Jokes
168: *
169: * ~ interpretation in filename expansion happens after % expansion, so
170: * you could put ~%{NEWSLOGNAME-news} and it will expand correctly.
171: */
172:
173: /* *** System Dependent Stuff *** */
174:
175: /* NOTE: many of these are defined in the config.h file */
176:
177: /* name of organization */
178: #ifndef ORGNAME
179: # define ORGNAME "ACME Widget Company, Widget Falls, Southern North Dakota"
180: #endif
181:
182: #ifndef MBOXCHAR
183: # define MBOXCHAR 'F' /* how to recognize a mailbox by 1st char */
184: #endif
185:
186: #ifndef ROOTID
187: # define ROOTID 0 /* uid of superuser */
188: #endif
189:
190: #ifdef NORMSIG
191: # define sigset signal
192: # define sigignore(sig) signal(sig,SIG_IGN)
193: #endif
194:
195: #ifndef LOGDIRFIELD
196: # define LOGDIRFIELD 6 /* Which field (origin 1) is the */
197: /* login directory in /etc/passwd? */
198: /* (If it is not kept in passwd, */
199: /* but getpwnam() returns it, */
200: /* define the symbol GETPWENT) */
201: #endif
202: #ifndef GCOSFIELD
203: # define GCOSFIELD 5
204: #endif
205:
206: #ifndef NEGCHAR
207: # define NEGCHAR '!'
208: #endif
209:
210: /* Space conservation section */
211:
212: /* To save D space, cut down size of MAXRCLINE, NGMAX, VARYSIZE. */
213: #define MAXRCLINE 500 /* number of lines allowed in .newsrc */
214: /* several parallel arrays affected. */
215: /* (You can have more lines in the active file, */
216: /* just not in the .newsrc) */
217: #define HASHSIZ 547 /* should be prime, and at least MAXRCLINE + 10% */
218: #define NGMAX 100 /* number of newsgroups allowed on command line */
219: /* undefine ONLY symbol to disable "only" feature */
220: #define VARYSIZE 256 /* this makes a block 1024 bytes long in DECville */
221: /* (used by virtual array routines) */
222:
223: /* Undefine any of the following features to save both I and D space */
224: /* In general, earlier ones are easier to get along without */
225: /* Pdp11's without split I and D may have to undefine them all */
226: #define DEBUGGING /* include debugging code */
227: #define CUSTOMLINES /* include code for HIDELINE and PAGESTOP */
228: #define PUSHBACK /* macros and keymaps using pushback buffer */
229: #define SPEEDOVERMEM /* use more memory to run faster */
230: #define WORDERASE /* enable ^W to erase a word */
231: #define MAILCALL /* check periodically for mail */
232: #define CLEAREOL /* use clear to end-of-line instead of clear screen */
233: #define NOFIREWORKS /* keep whole screen from flashing on certain */
234: /* terminals such as older Televideos */
235: #define VERIFY /* echo the command they just typed */
236: #define HASHNG /* hash newsgroup lines for fast lookup-- */
237: /* linear search used if not defined */
238: #define CONDSUB /* allow %(cond?text:text) */
239: #define BACKTICK /* allow %`command` */
240: #define PROMPTTTY /* allow %"prompt" */
241: #define ULSMARTS /* catch _^H in text and do underlining */
242: #define TERMMOD /* allow terminal type modifier on switches */
243: #define BAUDMOD /* allow baudrate modifier on switches */
244: #define GETLOGIN /* use getlogin() routine as backup to environment */
245: /* variables USER or LOGNAME */
246: #define ORGFILE /* if organization begins with /, look up in file */
247: #define TILDENAME /* allow ~logname expansion */
248: #define SETENV /* allow command line environment variable setting */
249: #define GETWD /* use our getwd() instead of piped in pwd */
250: #ifndef BSD42 /* 4.2 sites should just use groups for this */
251: #define SETUIDGID /* substitute eaccess() for access() so that rn */
252: /* can run setuid or setgid */
253: /* if not setuid or setgid, you don't need it */
254: #endif
255: #define MAKEDIR /* use our makedir() instead of shell script */
256: #define MEMHELP /* keep help messages in memory */
257: #define VERBOSE /* compile in more informative messages */
258: #define TERSE /* compile in shorter messages */
259: /* (Note: both VERBOSE and TERSE can be defined; -t
260: * sets terse mode. One or the other MUST be defined.
261: */
262: #ifndef pdp11
263: # define CACHESUBJ /* cache subject lines in memory */
264: /* without this ^N still works but runs really slow */
265: /* but you save lots and lots of D space */
266: # define CACHEFIRST /* keep absolute first article numbers in memory */
267: /* cost: about 2k */
268: #endif
269: #define ROTATION /* enable x, X and ^X commands to work */
270: #define DELBOGUS /* ask if bogus newsgroups should be deleted */
271: #define RELOCATE /* allow newsgroup rearranging */
272: #define ESCSUBS /* escape substitutions in multi-character commands */
273: #define DELAYMARK /* allow articles to be temporarily marked as read */
274: /* until exit from current newsgroup or Y command */
275: #define MCHASE /* unmark xrefed articles on m or M */
276: #define /* allow alternate header formatting via */
277: /* environment variable ALTHEADER (not impl) */
278: #define ASYNC_PARSE /* allow parsing headers asyncronously to reading */
279: /* used by MCHASE and MUNGHEADER */
280: #define FINDNEWNG /* check for new newsgroups on startup */
281: #define FASTNEW /* do optimizations on FINDNEWNG for faster startup */
282: /* (this optimization can make occasional mistakes */
283: /* if a group is removed and another group of the */
284: /* same length is added, and if no softpointers are */
285: /* affected by said change.) */
286: #define INNERSEARCH /* search command 'g' with article */
287: #define CATCHUP /* catchup command at newsgroup level */
288: #define NGSEARCH /* newsgroup pattern matching */
289: #define ONLY /* newsgroup restrictions by pattern */
290: #define KILLFILES /* automatic article killer files */
291: #define ARTSEARCH /* pattern searches among articles */
292: /* /, ?, ^N, ^P, k, K */
293:
294: /* some dependencies among options */
295:
296: #ifndef ARTSEARCH
297: # undef KILLFILES
298: # undef INNERSEARCH
299: # undef CACHESUBJ
300: #endif
301:
302: #ifndef DELAYMARK
303: # ifndef MCHASE
304: # ifndef MUNGHEADER
305: # undef ASYNC_PARSE
306: # endif
307: # endif
308: #endif
309:
310: #ifndef SETUIDGID
311: # define eaccess access
312: #endif
313:
314: #ifdef ONLY /* idiot lint doesn't grok #if */
315: # define NGSORONLY
316: #else
317: # ifdef NGSEARCH
318: # define NGSORONLY
319: # endif
320: #endif
321:
322: #ifdef VERBOSE
323: # ifdef TERSE
324: # define IF(c) if (c)
325: # define ELSE else
326: # else !TERSE
327: # define IF(c)
328: # define ELSE
329: # endif
330: #else !VERBOSE
331: # ifndef TERSE
332: # define TERSE
333: # endif
334: # define IF(c) "IF" outside of VERBOSE???
335: # define ELSE "ELSE" outside of VERBOSE???
336: #endif
337:
338: #ifdef DEBUGGING
339: # define assert(ex) {if (!(ex)){fprintf(stderr,"Assertion failed: file %s, line %d\n", __FILE__, __LINE__);sig_catcher(0);}}
340: #else
341: # define assert(ex) ;
342: #endif
343:
344: #ifdef SPEEDOVERMEM
345: # define OFFSET(x) (x)
346: #else
347: # define OFFSET(x) ((x)-absfirst)
348: #endif
349:
350: /* If you're strapped for space use the help messages in shell scripts */
351: /* if {NG,ART,PAGER,SUBS}HELP is undefined, help messages are in memory */
352: #ifdef MEMHELP /* undef MEMHELP above to get them all as sh scripts */
353: # undef NGHELP
354: # undef ARTHELP
355: # undef PAGERHELP
356: # undef SUBSHELP
357: #else
358: # ifndef NGHELP /* % and ~ */
359: # define NGHELP "%X/ng.help"
360: # endif
361: # ifndef ARTHELP /* % and ~ */
362: # define ARTHELP "%X/art.help"
363: # endif
364: # ifndef PAGERHELP /* % and ~ */
365: # define "%X/pager.help"
366: # endif
367: # ifndef SUBSHELP /* % and ~ */
368: # define SUBSHELP "%X/subs.help"
369: # endif
370: #endif
371:
372: #ifdef CLEAREOL
373: # define TCSIZE 512 /* capacity for termcap strings */
374: #else
375: # ifdef pdp11
376: # define TCSIZE 256 /* capacity for termcap strings */
377: # else
378: # define TCSIZE 512 /* capacity for termcap srings */
379: # endif
380: #endif
381:
382: /* Additional ideas:
383: * Make the do_newsgroup() routine a separate process.
384: * Keep .newsrc on disk instead of in memory.
385: * Overlays, if you have them.
386: * Get a bigger machine.
387: */
388:
389: /* End of Space Conservation Section */
390:
391: /* More System Dependencies */
392:
393: /* news library */
394: #ifndef LIB /* ~ and %l only ("~%l" is permissable) */
395: # define LIB "/usr/lib/news"
396: #endif
397:
398: /* path to private executables */
399: #ifndef RNLIB /* ~, %x and %l only */
400: # define RNLIB "%x/rn"
401: #endif
402:
403: /* system-wide RNINIT switches */
404: #ifndef GLOBINIT
405: # define GLOBINIT "%X/INIT"
406: #endif
407:
408: /* where to find news files */
409: #ifndef SPOOL /* % and ~ */
410: # define SPOOL "/usr/spool/news"
411: #endif
412:
413: /* file containing list of active newsgroups and max article numbers */
414: #ifndef ACTIVE /* % and ~ */
415: # define ACTIVE "%x/active"
416: #endif
417:
418: /* location of history file */
419: #ifndef ARTFILE /* % and ~ */
420: # define ARTFILE "%x/history"
421: #endif
422:
423: /* command to setup a new .newsrc */
424: #ifndef NEWSETUP /* % and ~ */
425: # define NEWSETUP "newsetup"
426: #endif
427:
428: /* command to display a list of un-subscribed-to newsgroups */
429: #ifndef NEWSGROUPS /* % and ~ */
430: # define NEWSGROUPS "newsgroups"
431: #endif
432:
433: /* preferred shell for use in doshell routine */
434: /* ksh or sh would be okay here */
435: #ifndef PREFSHELL
436: # define PREFSHELL "/bin/csh"
437: #endif
438:
439: /* path to fastest starting shell */
440: #ifndef SH
441: # define SH "/bin/sh"
442: #endif
443:
444: /* path to default editor */
445: #ifndef DEFEDITOR
446: # define DEFEDITOR "/usr/ucb/vi"
447: #endif
448:
449: /* location of macro file */
450: #ifndef RNMACRO
451: # ifdef PUSHBACK
452: # define RNMACRO "%./.rnmac"
453: # endif
454: #endif
455:
456: /* location of full name */
457: #ifndef FULLNAMEFILE
458: # ifndef PASSNAMES
459: # define FULLNAMEFILE "%./.fullname"
460: # endif
461: #endif
462:
463: /* virtual array file name template */
464: #ifndef VARYNAME /* % and ~ */
465: # define VARYNAME "/tmp/rnvary.%$"
466: #endif
467:
468: /* file to pass header to followup article poster */
469: #ifndef HEADNAME /* % and ~ */
470: # define HEADNAME "%./.rnhead"
471: /* or alternately #define HEADNAME "/tmp/rnhead.%$" */
472: #endif
473:
474: #ifndef MAKEDIR
475: /* shell script to make n-deep subdirectories */
476: # ifndef DIRMAKER /* % and ~ */
477: # define DIRMAKER "%X/makedir"
478: # endif
479: #endif
480:
481: /* location of newsrc file */
482: #ifndef RCNAME /* % and ~ */
483: # define RCNAME "%./.newsrc"
484: #endif
485:
486: /* temporary newsrc file in case we crash while writing out */
487: #ifndef RCTNAME /* % and ~ */
488: # define RCTNAME "%./.newnewsrc"
489: #endif
490:
491: /* newsrc file at the beginning of this session */
492: #ifndef RCBNAME /* % and ~ */
493: # define RCBNAME "%./.oldnewsrc"
494: #endif
495:
496: /* if existent, contains process number of current or crashed rn */
497: #ifndef LOCKNAME /* % and ~ */
498: # define LOCKNAME "%./.rnlock"
499: #endif
500:
501: /* information from last invocation of rn */
502: #ifndef LASTNAME /* % and ~ */
503: # define LASTNAME "%./.rnlast"
504: #endif
505:
506: /* file with soft pointers into the active file */
507: #ifndef SOFTNAME /* % and ~ */
508: # define SOFTNAME "%./.rnsoft"
509: #endif
510:
511: /* list of article numbers to mark as unread later (see M and Y cmmands) */
512: #ifndef RNDELNAME /* % and ~ */
513: # define RNDELNAME "%./.rndelay"
514: #endif
515:
516: /* a motd-like file for rn */
517: #ifndef NEWSNEWSNAME /* % and ~ */
518: # define NEWSNEWSNAME "%X/newsnews"
519: #endif
520:
521: /* command to send a reply */
522: #ifndef MAILPOSTER /* % and ~ */
523: # define MAILPOSTER "Rnmail -h %h"
524: #endif
525:
526: #ifdef INTERNET
527: # ifndef MAILHEADER /* % */
528: # ifdef CONDSUB
529: # define "To: %t\nSubject: Re: %S\nNewsgroups: %n\nIn-Reply-To: %i\n%(%[references]!=^$?References\\: %[references]\n)Organization: %o\nCc: \nBcc: \n\n"
530: # else
531: # define MAILHEADER "To: %t\nSubject: Re: %S\nNewsgroups: %n\nIn-Reply-To: %i\nReferences: %[references]\nCc: \nBcc: \n\n"
532: # endif
533: # endif
534: #else
535: # ifndef MAILHEADER /* % */
536: # ifdef CONDSUB
537: # 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"
538: # else
539: # define MAILHEADER "To: %T\nSubject: Re: %S\nNewsgroups: %n\nIn-Reply-To: %i\nReferences: %[references]\nCc: \nBcc: \n\n"
540: # endif
541: # endif
542: #endif
543:
544: #ifndef YOUSAID /* % */
545: # define YOUSAID "In article %i you write:"
546: #endif
547:
548: /* command to submit a followup article */
549: #ifndef NEWSPOSTER /* % and ~ */
550: # define NEWSPOSTER "Pnews -h %h"
551: #endif
552:
553: #ifndef NEWSHEADER /* % */
554: # ifdef CONDSUB
555: # define "Newsgroups: %(%F=^$?%C:%F)\nSubject: %(%S=^$?%\"\n\nSubject: \":Re: %S)\nSummary: \nExpires: \n%(%R=^$?:References: %R\n)Sender: \nReply-To: %L@%H.UUCP (%N)\nFollowup-To: \nDistribution: %(%i=^$?%\"Distribution: \":%D)\nOrganization: %o\nKeywords: %[keywords]\n\n"
556: # else
557: # define NEWSHEADER "Newsgroups: %F\nSubject: Re: %S\nSummary: \nExpires: \nReferences: %R\nSender: \nReply-To: %L@%H.UUCP (%N)\nFollowup-To: \nDistribution: %D\nOrganization: %o\nKeywords: %[keywords]\n\n"
558: # endif
559: #endif
560:
561: #ifndef ATTRIBUTION /* % */
562: # define ATTRIBUTION "In article %i %f writes:"
563: #endif
564:
565: #ifndef PIPESAVER /* % */
566: # ifdef CONDSUB
567: # ifdef SERVER
568: # define PIPESAVER "%(%B=^0$?<%P/rrn%a.%$:tail +%Bc %A |) %b"
569: # else
570: # define PIPESAVER "%(%B=^0$?<%A:tail +%Bc %A |) %b"
571: # endif
572: # else
573: # ifdef SERVER
574: # define PIPESAVER "tail +%Bc %P/rrn%a.%$ | %b"
575: # else
576: # define PIPESAVER "tail +%Bc %A | %b"
577: # endif
578: # endif
579: #endif
580:
581: #ifndef NORMSAVER /* % and ~ */
582: # ifdef SERVER
583: # define NORMSAVER "%X/norm.saver %P/rrn%a.%$ %P %c %a %B %C \"%b\""
584: # else
585: # define NORMSAVER "%X/norm.saver %A %P %c %a %B %C \"%b\""
586: # endif
587: #endif
588:
589: #ifndef MBOXSAVER /* % and ~ */
590: # ifdef MININACT /* 2.10.2 site? */
591: # ifdef SERVER
592: # define MBOXSAVER "%X/mbox.saver %P/rrn%a.%$ %P %c %a %B %C \"%b\" \"From %T %`date`\""
593: # else
594: # define MBOXSAVER "%X/mbox.saver %A %P %c %a %B %C \"%b\" \"From %T %`date`\""
595: # endif
596: # else
597: # ifdef CONDSUB
598: # ifdef SERVER
599: # 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)\""
600: # else
601: # 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)\""
602: # endif
603: /* header munging with a vengeance */
604: # else
605: # ifdef SERVER
606: # define MBOXSAVER "%X/mbox.saver %P/rrn%a.%$ %P %c %a %B %C \"%b\" \"From %T %[posted]\""
607: # else
608: # define MBOXSAVER "%X/mbox.saver %A %P %c %a %B %C \"%b\" \"From %T %[posted]\""
609: # endif
610: # endif
611: # endif
612: #endif
613:
614: #ifdef MKDIRS
615:
616: # ifndef SAVEDIR /* % and ~ */
617: # define SAVEDIR "%p/%c"
618: # endif
619: # ifndef SAVENAME /* % */
620: # define SAVENAME "%a"
621: # endif
622:
623: #else
624:
625: # ifndef SAVEDIR /* % and ~ */
626: # define SAVEDIR "%p"
627: # endif
628: # ifndef SAVENAME /* % */
629: # define SAVENAME "%^C"
630: # endif
631:
632: #endif
633:
634: #ifndef KILLGLOBAL /* % and ~ */
635: # define KILLGLOBAL "%p/KILL"
636: #endif
637:
638: #ifndef KILLLOCAL /* % and ~ */
639: # define KILLLOCAL "%p/%c/KILL"
640: #endif
641:
642: /* how to cancel an article */
643: #ifndef CANCEL
644: # ifdef MININACT /* 2.10.2 ? */
645: # define CANCEL "%x/inews -h < %h"
646: # else
647: # define CANCEL "inews -h < %h"
648: # endif
649: #endif
650:
651: /* how to cancel an article, continued */
652: #ifndef CANCELHEADER
653: # define "Newsgroups: %n\nSubject: cmsg cancel %i\nReferences: %R\nReply-To: %L@%H.UUCP (%N)\nDistribution: %D\nOrganization: %o\n"
654: #endif
655:
656: /* where to find the mail file */
657: #ifndef MAILFILE
658: # define MAILFILE "/usr/spool/mail/%L"
659: #endif
660:
661: /* some important types */
662:
663: typedef int NG_NUM; /* newsgroup number */
664: typedef long ART_NUM; /* article number */
665: #ifdef pdp11
666: typedef short ART_UNREAD; /* ordinarily this should be long */
667: /* like ART_NUM, but assuming that */
668: /* we stay less than 32767 articles */
669: /* behind saves a lot of space. */
670: /* NOTE: do not make unsigned. */
671: #else
672: typedef long ART_UNREAD;
673: #endif
674: typedef long ART_POS; /* char position in article file */
675: typedef int ART_LINE; /* line position in article file */
676: typedef short ACT_POS; /* char position in active file */
677: typedef unsigned int MEM_SIZE; /* for passing to malloc */
678:
679: /* *** end of the machine dependent stuff *** */
680:
681: /* GLOBAL THINGS */
682:
683: /* file statistics area */
684:
685: EXT struct stat filestat;
686:
687: /* various things of type char */
688:
689: char *index();
690: char *rindex();
691: char *getenv();
692: char *strcat();
693: char *strcpy();
694: char *sprintf();
695:
696: EXT char buf[LBUFLEN+1]; /* general purpose line buffer */
697: EXT char cmd_buf[CBUFLEN]; /* buffer for formatting system commands */
698:
699: EXT char *indstr INIT(">"); /* indent for old article embedded in followup */
700:
701: EXT char *cwd INIT(Nullch); /* current working directory */
702: EXT char *dfltcmd INIT(Nullch); /* 1st char is default command */
703:
704: /* switches */
705:
706: #ifdef DEBUGGING
707: EXT int debug INIT(0); /* -D */
708: # define DEB_INNERSRCH 32
709: # define DEB_FILEXP 64
710: # define DEB_HASH 128
711: # define DEB_XREF_MARKER 256
712: # define DEB_CTLAREA_BITMAP 512
713: # define DEB_SOFT_POINTERS 1024
714: # define DEB_NEWSRC_LINE 2048
715: # define DEB_SEARCH_AHEAD 4096
716: # define DEB_CHECKPOINTING 8192
717: # define DEB_FEED_XREF 16384
718: #endif
719:
720: #ifdef ARTSEARCH
721: EXT int scanon INIT(0); /* -S */
722: #endif
723:
724: EXT bool mbox_always INIT(FALSE); /* -M */
725: EXT bool norm_always INIT(FALSE); /* -N */
726: EXT bool checkflag INIT(FALSE); /* -c */
727: EXT bool suppress_cn INIT(FALSE); /* -s */
728: EXT int countdown INIT(5); /* how many lines to list before invoking -s */
729: EXT bool muck_up_clear INIT(FALSE); /* -loco */
730: EXT bool erase_screen INIT(FALSE); /* -e */
731: #ifdef CLEAREOL
732: EXT bool can_home_clear INIT(FALSE); /* fancy -e -- PWP */
733: #endif CLEAREOL
734: EXT bool findlast INIT(FALSE); /* -r */
735: EXT bool typeahead INIT(FALSE); /* -T */
736: #ifdef VERBOSE
737: # ifdef TERSE
738: EXT bool verbose INIT(TRUE); /* +t */
739: # endif
740: #endif
741: #ifdef VERIFY
742: EXT bool verify INIT(FALSE); /* -v */
743: #endif
744:
745: #define NOMARKING 0
746: #define STANDOUT 1
747: #define UNDERLINE 2
748: EXT int marking INIT(NOMARKING); /* -m */
749:
750: EXT ART_LINE initlines INIT(0); /* -i */
751:
752: /* miscellania */
753:
754: long atol(), fseek(), ftell();
755: EXT bool in_ng INIT(FALSE); /* current state of rn */
756: EXT char mode INIT('i'); /* current state of rn */
757:
758: EXT FILE *tmpfp INIT(Nullfp); /* scratch fp used for .rnlock, .rnlast, etc. */
759:
760: EXT NG_NUM nextrcline INIT(0); /* 1st unused slot in rcline array */
761: /* startup to avoid checking twice in a row */
762:
763: extern errno;
764:
765: /* Factored strings */
766:
767: EXT char nullstr[] INIT("");
768: EXT char sh[] INIT(SH);
769: EXT char defeditor[] INIT(DEFEDITOR);
770: EXT char hforhelp[] INIT("Type h for help.\n");
771: #ifdef STRICTCR
772: EXT char badcr[] INIT("\nUnnecessary CR ignored.\n");
773: #endif
774: EXT char readerr[] INIT("rn read error");
775: EXT char unsubto[] INIT("\n\nUnsubscribed to newsgroup %s\n");
776: EXT char cantopen[] INIT("Can't open %s\n");
777: EXT char cantcreate[] INIT("Can't create %s\n");
778:
779: #ifdef VERBOSE
780: EXT char nocd[] INIT("Can't chdir to directory %s\n");
781: #else
782: EXT char nocd[] INIT("Can't find %s\n");
783: #endif
784:
785: #ifdef NOLINEBUF
786: #define FLUSH ,fflush(stdout)
787: #else
788: #define FLUSH
789: #endif
790:
791: #ifdef lint
792: #undef FLUSH
793: #define FLUSH
794: #undef putchar
795: #define putchar(c)
796: #endif