1 /* $Id: common.h,v 3.0 1992/02/23 21:25:39 davison Trn $ 2 */ 3 /* This software is Copyright 1991 by Stan Barber. 4 * 5 * Permission is hereby granted to copy, reproduce, redistribute or otherwise 6 * use this software as long as: there is no monetary profit gained 7 * specifically from the use or reproduction of this software, it is not 8 * sold, rented, traded or otherwise marketed, and this copyright notice is 9 * included prominently in any copy made. 10 * 11 * The authors make no claims as to the fitness or correctness of this software 12 * for any use whatsoever, and it is provided as is. Any use of this software 13 * is at the user's own risk. 14 */ 15 16 #include <stdio.h> 17 #include <sys/types.h> 18 #include <sys/stat.h> 19 20 #ifndef S_ISDIR 21 #define S_ISDIR(m) ( ((m) & S_IFMT) == S_IFDIR ) 22 #endif 23 #ifndef S_ISCHR 24 #define S_ISCHR(m) ( ((m) & S_IFMT) == S_IFCHR ) 25 #endif 26 #ifndef S_ISREG 27 #define S_ISREG(m) ( ((m) & S_IFMT) == S_IFREG ) 28 #endif 29 30 #include <ctype.h> 31 #include "config.h" /* generated by installation script */ 32 #ifndef isalnum 33 # define isalnum(c) (isalpha(c) || isdigit(c)) 34 #endif 35 36 #include <errno.h> 37 #include <signal.h> 38 #ifdef I_SYS_FILIO 39 # include <sys/filio.h> 40 #else 41 # ifdef I_SYS_IOCTL 42 # include <sys/ioctl.h> 43 # endif 44 #endif 45 #ifdef I_VFORK 46 # include <vfork.h> 47 #endif 48 #include <fcntl.h> 49 50 #ifdef I_TERMIO 51 # include <termio.h> 52 #else 53 # ifdef I_TERMIOS 54 # include <termios.h> 55 # if !defined (O_NDELAY) 56 # define O_NDELAY O_NONBLOCK /* Posix-style non-blocking i/o */ 57 # endif 58 # else 59 # include <sgtty.h> 60 # endif 61 #endif 62 63 #ifdef HAS_GETPWENT 64 # include <pwd.h> 65 #endif 66 67 #ifdef I_PTEM 68 #include <sys/stream.h> 69 #include <sys/ptem.h> 70 #endif 71 72 #ifdef I_UNISTD 73 #include <unistd.h> 74 #endif 75 #ifdef I_STDLIB 76 #include <stdlib.h> 77 #else 78 char *malloc(); 79 char *realloc(); 80 char *getenv(); 81 #endif 82 83 #ifdef I_STRING 84 #include <string.h> 85 #else 86 #include <strings.h> 87 #endif 88 89 #ifdef I_TIME 90 #include <time.h> 91 #endif 92 #ifdef I_SYS_TIME 93 #include <sys/time.h> 94 #endif 95 96 #define BITSPERBYTE 8 97 #define LBUFLEN 1024 /* line buffer length */ 98 /* (don't worry, .newsrc lines can exceed this) */ 99 #define CBUFLEN 512 /* command buffer length */ 100 #define PUSHSIZE 256 101 #define MAXFILENAME 512 102 #define LONGKEY 25 /* longest keyword */ 103 /* (currently "Content-Transfer-Encoding") */ 104 #define FINISHCMD 0177 105 106 /* some handy defs */ 107 108 #define bool char 109 #define bool_int int 110 #define char_int int 111 #ifndef TRUE 112 #define TRUE (1) 113 #endif 114 #ifndef FALSE 115 #define FALSE (0) 116 #endif 117 #define Null(t) ((t)0) 118 #define Nullch Null(char*) 119 #define Nullfp Null(FILE*) 120 121 #define Ctl(ch) (ch & 037) 122 123 #define strNE(s1,s2) (strcmp(s1,s2)) 124 #define strEQ(s1,s2) (!strcmp(s1,s2)) 125 #define strnNE(s1,s2,l) (strncmp(s1,s2,l)) 126 #define strnEQ(s1,s2,l) (!strncmp(s1,s2,l)) 127 128 /* Things we can figure out ourselves */ 129 130 #ifdef SIGTSTP 131 # define BERKELEY /* include job control signals? */ 132 #endif 133 134 #if defined(FIONREAD) || defined(HAS_RDCHK) || defined(O_NDELAY) 135 # define PENDING 136 #endif 137 138 #ifdef EUNICE 139 # define LINKART /* add 1 level of possible indirection */ 140 # define UNLINK(victim) while (!unlink(victim)) 141 #else 142 # define UNLINK(victim) unlink(victim) 143 #endif 144 145 /* Valid substitutions for strings marked with % comment are: 146 * %a Current article number 147 * %A Full name of current article (%P/%c/%a) 148 * (if LINKART defined, is the name of the real article) 149 * %b Destination of a save command, a mailbox or command 150 * %B The byte offset to the beginning of the article for saves 151 * with or without the header 152 * %c Current newsgroup, directory form 153 * %C Current newsgroup, dot form 154 * %d %P/%c 155 * %D Old Distribution: line 156 * %e Extract program 157 * %E Extract destination directory 158 * %f Old From: line or Reply-To: line 159 * %F Newsgroups to followup to from Newsgroups: and Followup-To: 160 * %h Name of header file to pass to mail or news poster 161 * %H Host name (yours) 162 * %i Old Message-I.D.: line, with <> 163 * %I Inclusion indicator 164 * %l News administrator login name 165 * %L Login name (yours) 166 * %m The current mode of trn. 167 * %M Number of articles marked with M 168 * %n Newsgroups from source article 169 * %N Full name (yours) 170 * %o Organization (yours) 171 * %O Original working directory (where you ran trn from) 172 * %p Your private news directory (-d switch) 173 * %P Public news spool directory (NEWSSPOOL) 174 * %r Last reference (parent article id) 175 * %q The last quoted input (via %"). 176 * %R New references list 177 * %s Subject, with all Re's and (nf)'s stripped off 178 * %S Subject, with one Re stripped off 179 * %t New To: line derived from From: and Reply-To (Internet always) 180 * %T New To: line derived from Path: 181 * %u Number of unread articles 182 * %U Number of unread articles disregarding current article 183 * %v Number of unselected articles disregarding current article 184 * %W The thread directory root 185 * %x News library directory, usually /usr/lib/news 186 * %X Rn library directory, usually %x/rn 187 * %y The tmp directory to use 188 * %z Size of current article in bytes. 189 * %Z Number of selected threads. 190 * %~ Home directory 191 * %. Directory containing . files 192 * %# count of articles saved in current command (from 1 to n) 193 * %$ current process number 194 * %{name} Environment variable "name". %{name-default} form allowed. 195 * %[name] Header line beginning with "Name: ", without "Name: " 196 * %"prompt" 197 * Print prompt and insert what is typed. 198 * %`command` 199 * Insert output of command. 200 * %(test_text=pattern?if_text:else_text) 201 * Substitute if_text if test_text matches pattern, otherwise 202 * substitute else_text. Use != for negated match. 203 * % substitutions are done on test_text, if_text, and else_text. 204 * (Note: %() only works if CONDSUB defined.) 205 * %digit Substitute the text matched by the nth bracket in the last 206 * pattern that had brackets. %0 matches the last bracket 207 * matched, in case you had alternatives. 208 * %? Insert a space unless the entire result is > 79 chars, in 209 * which case the space becomes a newline. 210 * 211 * Put ^ in the middle to capitalize the first letter: %^C = Rec.humor 212 * Put _ in the middle to capitalize last component: %_c = net/Jokes 213 * Put \ in the middle to quote regexp and % characters in the result 214 * Put > in the middle to return the address portion of a name. 215 * Put ) in the middle to return the comment portion of a name. 216 * Put ' in the middle to protect "'"s in arguments you've put in "'"s. 217 * Put :FMT in the middle to format the result: %:-30.30t 218 * 219 * ~ interpretation in filename expansion happens after % expansion, so 220 * you could put ~%{NEWSLOGNAME-news} and it will expand correctly. 221 */ 222 223 /* *** System Dependent Stuff *** */ 224 225 /* NOTE: many of these are defined in the config.h file */ 226 227 /* name of organization */ 228 #ifndef ORGNAME 229 # define ORGNAME "ACME Widget Company, Widget Falls, Southern North Dakota" 230 #endif 231 232 #ifndef MBOXCHAR 233 # define MBOXCHAR 'F' /* how to recognize a mailbox by 1st char */ 234 #endif 235 236 #ifndef ROOTID 237 # define ROOTID 0 /* uid of superuser */ 238 #endif 239 240 #ifdef NORMSIG 241 # define sigset signal 242 # define sigignore(sig) signal(sig,SIG_IGN) 243 #endif 244 245 #ifndef LOGDIRFIELD 246 # define LOGDIRFIELD 6 /* Which field (origin 1) is the */ 247 /* login directory in /etc/passwd? */ 248 /* (If it is not kept in passwd, */ 249 /* but getpwnam() returns it, */ 250 /* define the symbol HAS_GETPWENT) */ 251 #endif 252 #ifndef GCOSFIELD 253 # define GCOSFIELD 5 254 #endif 255 256 #ifndef NEGCHAR 257 # define NEGCHAR '!' 258 #endif 259 260 /* Space conservation section */ 261 262 /* To save D space, cut down size of NGMAX and VARYSIZE. */ 263 #define NGMAX 100 /* number of newsgroups allowed on command line */ 264 /* undefine ONLY symbol to disable "only" feature */ 265 #define VARYSIZE 256 /* this makes a block 1024 bytes long in DECville */ 266 /* (used by virtual array routines) */ 267 268 /* Undefine any of the following features to save both I and D space */ 269 /* In general, earlier ones are easier to get along without */ 270 #define CUSTOMLINES /* include code for HIDELINE and PAGESTOP */ 271 #define WORDERASE /* enable ^W to erase a word */ 272 #define MAILCALL /* check periodically for mail */ 273 #define CLEAREOL /* use clear to end-of-line instead of clear screen */ 274 #define NOFIREWORKS /* keep whole screen from flashing on certain */ 275 /* terminals such as older Televideos */ 276 #define VERIFY /* echo the command they just typed */ 277 #define HASHNG /* hash newsgroup lines for fast lookup-- */ 278 /* linear search used if not defined */ 279 #define CONDSUB /* allow %(cond?text:text) */ 280 #define BACKTICK /* allow %`command` */ 281 #define PROMPTTTY /* allow %"prompt" */ 282 #define ULSMARTS /* catch _^H in text and do underlining */ 283 #define TERMMOD /* allow terminal type modifier on switches */ 284 #define BAUDMOD /* allow baudrate modifier on switches */ 285 #define GETLOGIN /* use getlogin() routine as backup to environment */ 286 /* variables USER or LOGNAME */ 287 #define ORGFILE /* if organization begins with /, look up in file */ 288 #define TILDENAME /* allow ~logname expansion */ 289 #define SETENV /* allow command line environment variable setting */ 290 #define MAKEDIR /* use our makedir() instead of shell script */ 291 #define MEMHELP /* keep help messages in memory */ 292 #define VERBOSE /* compile in more informative messages */ 293 #define TERSE /* compile in shorter messages */ 294 /* (Note: both VERBOSE and TERSE can be defined; -t 295 * sets terse mode. One or the other MUST be defined. 296 */ 297 #define ROTATION /* enable x, X and ^X commands to work */ 298 #define CHARSUBST /* enable the _C command */ 299 #define DELBOGUS /* ask if bogus newsgroups should be deleted */ 300 #define RELOCATE /* allow newsgroup rearranging */ 301 #define ESCSUBS /* escape substitutions in multi-character commands */ 302 #undef MCHASE /* unmark xrefed articles on m or M */ 303 #define MUNGHEADER /* allow alternate header formatting via */ 304 /* environment variable ALTHEADER (not impl) */ 305 #define ASYNC_PARSE /* allow parsing headers asyncronously to reading */ 306 /* used by MCHASE and MUNGHEADER */ 307 #define FINDNEWNG /* check for new newsgroups on startup */ 308 #define FASTNEW /* do optimizations on FINDNEWNG for faster startup */ 309 /* (this optimization can make occasional mistakes */ 310 /* if a group is removed and another group of the */ 311 /* same length is added, and if no softpointers are */ 312 /* affected by said change.) */ 313 #define INNERSEARCH /* search command 'g' with article */ 314 #define CATCHUP /* catchup command at newsgroup level */ 315 #define NGSEARCH /* newsgroup pattern matching */ 316 #define ONLY /* newsgroup restrictions by pattern */ 317 #define KILLFILES /* automatic article killer files */ 318 #define ARTSEARCH /* pattern searches among articles */ 319 /* /, ?, ^N, ^P, k, K */ 320 #define EDIT_DISTANCE /* Allow -G to specify a fuzzy 'go' command */ 321 #undef VALIDATE_XREF_SITE /* are xrefs possibly invalid? */ 322 323 /* some dependencies among options */ 324 325 #ifndef ARTSEARCH 326 # undef KILLFILES 327 # undef INNERSEARCH 328 #endif 329 330 #ifndef SETUIDGID 331 # define eaccess access 332 #endif 333 334 #ifdef ONLY /* idiot lint doesn't grok #if */ 335 # define NGSORONLY 336 #else 337 # ifdef NGSEARCH 338 # define NGSORONLY 339 # endif 340 #endif 341 342 #ifdef VERBOSE 343 # ifdef TERSE 344 # define IF(c) if (c) 345 # define ELSE else 346 # else 347 # define IF(c) 348 # define ELSE 349 # endif 350 #else /* !VERBOSE */ 351 # ifndef TERSE 352 # define TERSE 353 # endif 354 # define IF(c) "IF" outside of VERBOSE??? 355 # define ELSE "ELSE" outside of VERBOSE??? 356 #endif 357 358 #ifdef DEBUG 359 # define assert(ex) {if (!(ex)){fprintf(stderr,"Assertion failed: file %s, line %d\n", __FILE__, __LINE__);sig_catcher(0);}} 360 #else 361 # define assert(ex) ; 362 #endif 363 364 /* If you're strapped for space use the help messages in shell scripts */ 365 /* if {NG,ART,PAGER,SUBS}HELP is undefined, help messages are in memory */ 366 #ifdef MEMHELP /* undef MEMHELP above to get them all as sh scripts */ 367 # undef NGHELP 368 # undef ARTHELP 369 # undef PAGERHELP 370 # undef SUBSHELP 371 #else 372 # ifndef NGHELP /* % and ~ */ 373 # define NGHELP "%X/ng.help" 374 # endif 375 # ifndef ARTHELP /* % and ~ */ 376 # define ARTHELP "%X/art.help" 377 # endif 378 # ifndef PAGERHELP /* % and ~ */ 379 # define PAGERHELP "%X/pager.help" 380 # endif 381 # ifndef SUBSHELP /* % and ~ */ 382 # define SUBSHELP "%X/subs.help" 383 # endif 384 #endif 385 386 #define TCSIZE 512 /* capacity for termcap strings */ 387 388 #ifdef EDIT_DISTANCE 389 # define MIN_DIST 7 /* Maximum error count for acceptable match */ 390 #endif 391 392 /* Additional ideas: 393 * Make the do_newsgroup() routine a separate process. 394 * Keep .newsrc on disk instead of in memory. 395 * Overlays, if you have them. 396 * Get a bigger machine. 397 */ 398 399 /* End of Space Conservation Section */ 400 401 /* More System Dependencies */ 402 403 /* news library */ 404 #ifndef NEWSLIB /* ~ and %l only ("~%l" is permissable) */ 405 # define NEWSLIB "/usr/lib/news" 406 #endif 407 408 /* path to private executables */ 409 #ifndef PRIVLIB /* ~, %x and %l only */ 410 # define PRIVLIB "%x/trn" 411 #endif 412 413 /* system-wide RNINIT switches */ 414 #ifndef GLOBINIT 415 # define GLOBINIT "%X/INIT" 416 #endif 417 418 /* where to find news files */ 419 #ifndef NEWSSPOOL /* % and ~ */ 420 # define NEWSSPOOL "/usr/spool/news" 421 #endif 422 423 #ifndef THREAD_DIR 424 # undef LONG_THREAD_NAMES 425 #endif 426 427 /* default characters to use in the selection menu */ 428 #ifndef SELECTCHARS 429 # define SELECTCHARS "abdefgijlorstuvwxyz1234567890BCFGHIKVW" 430 #endif 431 432 /* file containing list of active newsgroups and max article numbers */ 433 #ifdef USE_NNTP 434 # undef ACTIVE 435 # define ACTIVE "%P/rrnact.%$" 436 #else 437 # ifndef ACTIVE /* % and ~ */ 438 # define ACTIVE "%x/active" 439 # endif 440 #endif 441 #ifndef DBINIT 442 # define DBINIT "%W/db.init" 443 #endif 444 445 #ifdef USE_NNTP 446 # ifndef ACTIVE_TIMES 447 # define APPEND_UNSUB 448 # endif 449 #else 450 # ifdef USE_XTHREAD 451 # undef USE_XTHREAD 452 # endif 453 # ifdef USE_XOVER 454 # undef USE_XOVER 455 # endif 456 #endif 457 458 /* location of history file */ 459 #ifndef ARTFILE /* % and ~ */ 460 # define ARTFILE "%x/history" 461 #endif 462 463 /* command to setup a new .newsrc */ 464 #ifndef NEWSETUP /* % and ~ */ 465 # define NEWSETUP "newsetup" 466 #endif 467 468 /* command to display a list of un-subscribed-to newsgroups */ 469 #ifndef NEWSGROUPS /* % and ~ */ 470 # define NEWSGROUPS "newsgroups" 471 #endif 472 473 /* preferred shell for use in doshell routine */ 474 /* ksh or sh would be okay here */ 475 #ifndef PREFSHELL 476 # define PREFSHELL "/bin/csh" 477 #endif 478 479 /* path to fastest starting shell */ 480 #ifndef SH 481 # define SH "/bin/sh" 482 #endif 483 484 /* default unshar'ing program */ 485 #ifndef UNSHAR 486 # define UNSHAR "/bin/sh" 487 #endif 488 489 /* path to default editor */ 490 #ifndef DEFEDITOR 491 # define DEFEDITOR "/usr/ucb/vi" 492 #endif 493 494 /* location of macro file for trn and rn modes */ 495 #ifndef TRNMACRO 496 # define TRNMACRO "%./.trnmac" 497 #endif 498 #ifndef RNMACRO 499 # define RNMACRO "%./.rnmac" 500 #endif 501 502 /* location of full name */ 503 #ifndef FULLNAMEFILE 504 # ifndef PASSNAMES 505 # define FULLNAMEFILE "%./.fullname" 506 # endif 507 #endif 508 509 /* virtual array file name template */ 510 #ifndef VARYNAME /* % and ~ */ 511 # define VARYNAME "%y/rnvary.%$" 512 #endif 513 514 /* where to compile a new newsgroup list */ 515 #ifndef RNEWNAME 516 # define RNEWNAME "%y/rnew.%$" 517 #endif 518 519 /* file to pass header to followup article poster */ 520 #ifndef HEADNAME /* % and ~ */ 521 # define HEADNAME "%./.rnhead" 522 /* or alternately #define HEADNAME "%y/rnhead.%$" */ 523 #endif 524 525 #ifndef MAKEDIR 526 /* shell script to make n-deep subdirectories */ 527 # ifndef DIRMAKER /* % and ~ */ 528 # define DIRMAKER "%X/makedir" 529 # endif 530 #endif 531 532 /* location of newsrc file */ 533 #ifndef RCNAME /* % and ~ */ 534 # define RCNAME "%./.newsrc" 535 #endif 536 537 /* temporary newsrc file in case we crash while writing out */ 538 #ifndef RCTNAME /* % and ~ */ 539 # define RCTNAME "%./.newnewsrc" 540 #endif 541 542 /* newsrc file at the beginning of this session */ 543 #ifndef RCBNAME /* % and ~ */ 544 # define RCBNAME "%./.oldnewsrc" 545 #endif 546 547 /* if existent, contains process number of current or crashed trn */ 548 #ifndef LOCKNAME /* % and ~ */ 549 # define LOCKNAME "%./.rnlock" 550 #endif 551 552 /* information from last invocation of trn */ 553 #ifndef LASTNAME /* % and ~ */ 554 # define LASTNAME "%./.rnlast" 555 #endif 556 557 /* file with soft pointers into the active file */ 558 #ifndef SOFTNAME /* % and ~ */ 559 # define SOFTNAME "%./.rnsoft" 560 #endif 561 562 /* list of article numbers to mark as unread later (see M and Y cmmands) */ 563 #ifndef RNDELNAME /* % and ~ */ 564 # define RNDELNAME "%./.rndelay" 565 #endif 566 567 /* a motd-like file for trn */ 568 #ifndef NEWSNEWSNAME /* % and ~ */ 569 # define NEWSNEWSNAME "%X/newsnews" 570 #endif 571 572 /* command to send a reply */ 573 #ifndef MAILPOSTER /* % and ~ */ 574 # define MAILPOSTER "QUOTECHARS=%I Rnmail -h %h" 575 #endif 576 577 #ifdef INTERNET 578 # ifndef MAILHEADER /* % */ 579 # ifdef CONDSUB 580 # define MAILHEADER "To: %t\nSubject: %(%i=^$?:Re: %S\n%(%{REPLYTO}=^$?:Reply-To: %{REPLYTO}\n)Newsgroups: %n\nIn-Reply-To: %i)\n%(%[references]=^$?:References: %[references]\n)Organization: %o\nCc: \nBcc: \n\n" 581 # else 582 # define MAILHEADER "To: %t\nSubject: Re: %S\nNewsgroups: %n\nIn-Reply-To: %i\nReferences: %[references]\nCc: \nBcc: \n\n" 583 # endif 584 # endif 585 #else 586 # ifndef MAILHEADER /* % */ 587 # ifdef CONDSUB 588 # define MAILHEADER "To: %T\nSubject: %(%i=^$?:Re: %S\n%(%{REPLYTO}=^$?:Reply-To: %{REPLYTO}\n)Newsgroups: %n\nIn-Reply-To: %i)\n%(%[references]=^$?:References: %[references]\n)Organization: %o\nCc: \nBcc: \n\n" 589 # else 590 # define MAILHEADER "To: %T\nSubject: Re: %S\nNewsgroups: %n\nIn-Reply-To: %i\nReferences: %[references]\nCc: \nBcc: \n\n" 591 # endif 592 # endif 593 #endif 594 595 #ifndef YOUSAID /* % */ 596 # define YOUSAID "In article %i you write:" 597 #endif 598 599 /* command to forward an article */ 600 #define FORWARDPOSTER MAILPOSTER 601 602 #ifdef INTERNET 603 # ifndef FORWARDHEADER /* % */ 604 # ifdef CONDSUB 605 # define FORWARDHEADER "To: %\"\n\nTo: \"\nSubject: %(%i=^$?:%[subject] (fwd\\)\n%(%{REPLYTO}=^$?:Reply-To: %{REPLYTO}\n)Newsgroups: %n\nIn-Reply-To: %i)\n%(%[references]=^$?:References: %[references]\n)Organization: %o\nCc: \nBcc: \n\n" 606 # else 607 # define FORWARDHEADER "To: \nSubject: %[subject] (fwd)\nNewsgroups: %n\nIn-Reply-To: %i\nReferences: %[references]\nCc: \nBcc: \n\n" 608 # endif 609 # endif 610 #else 611 # ifndef FORWARDHEADER /* % */ 612 # ifdef CONDSUB 613 # define FORWARDHEADER "To: %\"\n\nTo: \"\nSubject: %(%i=^$?:%[subject] (fwd\\)\n%(%{REPLYTO}=^$?:Reply-To: %{REPLYTO}\n)Newsgroups: %n\nIn-Reply-To: %i)\n%(%[references]=^$?:References: %[references]\n)Organization: %o\nCc: \nBcc: \n\n" 614 # else 615 # define FORWARDHEADER "To: \nSubject: %[subject] (fwd)\nNewsgroups: %n\nIn-Reply-To: %i\nReferences: %[references]\nCc: \nBcc: \n\n" 616 # endif 617 # endif 618 #endif 619 620 #ifndef FORWARDMSG /* % */ 621 # define FORWARDMSG "------- start of forwarded message -------" 622 #endif 623 624 #ifndef FORWARDMSGEND /* % */ 625 # define FORWARDMSGEND "------- end of forwarded message -------" 626 #endif 627 628 /* command to submit a followup article */ 629 #ifndef NEWSPOSTER /* % and ~ */ 630 # define NEWSPOSTER "QUOTECHARS=%I Pnews -h %h" 631 #endif 632 633 #ifndef NEWSHEADER /* % */ 634 # ifdef CONDSUB 635 # define NEWSHEADER "%(%[followup-to]=^$?:%(%[followup-to]=^%n$?:X-ORIGINAL-NEWSGROUPS: %n\n))Newsgroups: %(%F=^$?%C:%F)\nSubject: %(%S=^$?%\"\n\nSubject: \":Re: %S)\nSummary: \nExpires: \n%(%R=^$?:References: %R\n)Sender: \nFollowup-To: \n%(%{REPLYTO}=^$?:Reply-To: %{REPLYTO}\n)Distribution: %(%i=^$?%\"Distribution: \":%D)\nOrganization: %o\nKeywords: %[keywords]\nCc: %(%F=poster?%t:%(%F!=@?:%F))\n\n" 636 # else 637 # define NEWSHEADER "Newsgroups: %F\nSubject: Re: %S\nSummary: \nExpires: \nReferences: %R\nSender: \nFollowup-To: \nDistribution: %D\nOrganization: %o\nKeywords: %[keywords]\nCc: \n\n" 638 # endif 639 #endif 640 641 #ifndef ATTRIBUTION /* % */ 642 # define ATTRIBUTION "In article %i,%?%)f <%>f> wrote:" 643 #endif 644 645 #ifndef PIPESAVER /* % */ 646 # ifdef CONDSUB 647 # define PIPESAVER "%(%B=^0$?<%A:tail +%Bc %A |) %b" 648 # else 649 # define PIPESAVER "tail +%Bc %A | %b" 650 # endif 651 #endif 652 653 #ifndef EXSAVER 654 # define EXSAVER "tail +%Bc %A | %e" 655 #endif 656 657 #ifdef MIMESTORE 658 # ifndef EXMIMESAVER 659 # define EXMIMESAVER "%e %A" 660 # endif 661 #endif 662 663 #ifndef NORMSAVER /* % and ~ */ 664 # define NORMSAVER "%X/norm.saver %A %P %c %a %B %C \"%b\"" 665 #endif 666 667 #ifndef MBOXSAVER /* % and ~ */ 668 # ifndef ANCIENT_NEWS 669 # define MBOXSAVER "%X/mbox.saver %A %P %c %a %B %C \"%b\" \"From %t %`LANG= date`\"" 670 # else 671 # ifdef CONDSUB 672 # 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)\"" 673 /* header munging with a vengeance */ 674 # else 675 # define MBOXSAVER "%X/mbox.saver %A %P %c %a %B %C \"%b\" \"From %t %[posted]\"" 676 # endif 677 # endif 678 #endif 679 680 #ifdef MKDIRS 681 682 # ifndef SAVEDIR /* % and ~ */ 683 # define SAVEDIR "%p/%c" 684 # endif 685 # ifndef SAVENAME /* % */ 686 # define SAVENAME "%a" 687 # endif 688 689 #else 690 691 # ifndef SAVEDIR /* % and ~ */ 692 # define SAVEDIR "%p" 693 # endif 694 # ifndef SAVENAME /* % */ 695 # define SAVENAME "%^C" 696 # endif 697 698 #endif 699 700 #ifndef KILLGLOBAL /* % and ~ */ 701 # define KILLGLOBAL "%p/KILL" 702 #endif 703 704 #ifndef KILLLOCAL /* % and ~ */ 705 # define KILLLOCAL "%p/%c/KILL" 706 #endif 707 708 /* how to cancel an article */ 709 #ifndef CANCEL 710 # ifdef BNEWS 711 # define CANCEL "%x/inews -h < %h" 712 # else 713 # define CANCEL "inews -h < %h" 714 # endif 715 #endif 716 717 /* how to cancel an article, continued */ 718 #ifndef CANCELHEADER 719 # define CANCELHEADER "Newsgroups: %n\nSubject: cancel\nControl: cancel %i\nDistribution: %D\n\n%i was cancelled from within trn.\n" 720 #endif 721 722 /* how to supersede an article */ 723 #ifndef SUPERSEDEHEADER 724 # define SUPERSEDEHEADER "Newsgroups: %n\nSubject: %S\nSummary: %[summary]\nExpires: %[expires]\nReferences: %[references]\nSupersedes: %i\nSender: %[sender]\nFollowup-To: %[followup-to]\nDistribution: %D\nOrganization: %o\nKeywords: %[keywords]\n\n" 725 #endif 726 727 #ifndef LOCALTIMEFMT 728 # define LOCALTIMEFMT "%a %b %d %X %Z %Y" 729 #endif 730 731 /* where to find the mail file */ 732 #ifndef MAILFILE 733 # define MAILFILE "/usr/spool/mail/%L" 734 #endif 735 736 /* how to open binary format files */ 737 #ifndef FOPEN_RB 738 # define FOPEN_RB "r" 739 #endif 740 #ifndef FOPEN_WB 741 # define FOPEN_WB "w" 742 #endif 743 744 /* what to do with ansi prototypes -- '()' == ignore, 'x' == use */ 745 #ifndef _ 746 # ifdef __STDC__ 747 # define _(x) x 748 # ifndef CONST 749 # define CONST const 750 # endif 751 # else 752 # define _(x) () 753 # ifndef CONST 754 # define CONST 755 # endif 756 # endif 757 #endif 758 759 /* how many characters is a newline in a text file? */ 760 #ifndef NL_SIZE 761 # define NL_SIZE 1 762 #endif 763 764 /* some important types */ 765 766 typedef int NG_NUM; /* newsgroup number */ 767 typedef long ART_NUM; /* article number */ 768 typedef long ART_UNREAD; /* could be short to save space */ 769 typedef long ART_POS; /* char position in article file */ 770 typedef int ART_LINE; /* line position in article file */ 771 typedef long ACT_POS; /* char position in active file */ 772 typedef unsigned int MEM_SIZE; /* for passing to malloc */ 773 774 /* some slight-of-hand for compatibility issues */ 775 776 #ifdef HAS_STRCHR 777 # ifndef index 778 # define index strchr 779 # endif 780 # ifndef rindex 781 # define rindex strrchr 782 # endif 783 #endif 784 #ifdef HAS_MEMCMP 785 # ifndef bcmp 786 # define bcmp(s,d,l) memcmp((s),(d),(l)) 787 # endif 788 #endif 789 #ifdef HAS_MEMCPY 790 # ifndef bcopy 791 # define bcopy(s,d,l) memcpy((d),(s),(l)) 792 # endif 793 #endif 794 #ifdef HAS_MEMSET 795 # ifndef bzero 796 # define bzero(s,l) memset((s),0,(l)) 797 # endif 798 #endif 799 800 #ifndef HAS_VFORK 801 # define vfork fork 802 #endif 803 804 /* *** end of the machine dependent stuff *** */ 805 806 /* GLOBAL THINGS */ 807 808 /* file statistics area */ 809 810 EXT struct stat filestat; 811 812 /* various things of type char */ 813 814 #ifdef SUPPLEMENT_STRING_H 815 char *index(); 816 char *rindex(); 817 char *strcat(); 818 char *strcpy(); 819 #endif 820 821 EXT char buf[LBUFLEN+1]; /* general purpose line buffer */ 822 EXT char cmd_buf[CBUFLEN]; /* buffer for formatting system commands */ 823 EXT char *indstr INIT(">"); /* indent for old article embedded in followup */ 824 825 EXT char *cwd INIT(Nullch); /* current working directory */ 826 EXT char *dfltcmd INIT(Nullch); /* 1st char is default command */ 827 828 /* switches */ 829 830 #ifdef DEBUG 831 EXT int debug INIT(0); /* -D */ 832 # define DEB_COREDUMPSOK 2 833 # define DEB_HEADER 4 834 # define DEB_INTRP 8 835 # define DEB_NNTP 16 836 # define DEB_INNERSRCH 32 837 # define DEB_FILEXP 64 838 # define DEB_HASH 128 839 # define DEB_XREF_MARKER 256 840 # define DEB_CTLAREA_BITMAP 512 841 # define DEB_SOFT_POINTERS 1024 842 # define DEB_NEWSRC_LINE 2048 843 # define DEB_SEARCH_AHEAD 4096 844 # define DEB_CHECKPOINTING 8192 845 # define DEB_FEED_XREF 16384 846 #endif 847 848 #ifdef ARTSEARCH 849 EXT int scanon INIT(0); /* -S */ 850 #endif 851 852 EXT bool use_threads INIT(THREAD_INIT); /* -x */ 853 EXT int max_tree_lines INIT(6); 854 EXT char select_order[4] INIT("lms"); 855 EXT int select_on INIT(SELECT_INIT); /* -X */ 856 EXT char end_select INIT('Z'); 857 EXT char page_select INIT('>'); 858 859 EXT bool dont_filter_control INIT(FALSE); /* -j */ 860 EXT int join_subject_len INIT(0); /* -J */ 861 EXT bool kill_thru_kludge INIT(TRUE); /* -k */ 862 EXT bool keep_the_group_static INIT(FALSE); /* -K */ 863 EXT bool mbox_always INIT(FALSE); /* -M */ 864 EXT bool norm_always INIT(FALSE); /* -N */ 865 EXT bool thread_always INIT(FALSE); /* -a */ 866 EXT bool auto_arrow_macros INIT(TRUE); /* -B */ 867 EXT bool breadth_first INIT(FALSE); /* -b */ 868 EXT bool bkgnd_spinner INIT(FALSE); /* -B */ 869 EXT bool novice_delays INIT(TRUE); /* +f */ 870 EXT int olden_days INIT(FALSE); /* -o */ 871 EXT char auto_select_postings INIT(0); /* -p */ 872 EXT bool checkflag INIT(FALSE); /* -c */ 873 EXT bool suppress_cn INIT(FALSE); /* -s */ 874 EXT int countdown INIT(5); /* how many lines to list before invoking -s */ 875 EXT bool muck_up_clear INIT(FALSE); /* -loco */ 876 EXT bool erase_screen INIT(FALSE); /* -e */ 877 EXT bool can_home INIT(FALSE); 878 #ifdef CLEAREOL 879 EXT bool can_home_clear INIT(FALSE); /* fancy -e */ 880 #endif 881 EXT bool findlast INIT(FALSE); /* -r */ 882 EXT bool typeahead INIT(FALSE); /* -T */ 883 #ifdef EDIT_DISTANCE 884 EXT bool fuzzyGet INIT(FALSE); /* -G */ 885 #endif 886 #ifdef VERBOSE 887 # ifdef TERSE 888 EXT bool verbose INIT(TRUE); /* +t */ 889 # endif 890 #endif 891 EXT bool unbroken_subjects INIT(FALSE); /* -u */ 892 EXT bool unsafe_rc_saves INIT(FALSE); /* -U */ 893 #ifdef VERIFY 894 EXT bool verify INIT(FALSE); /* -v */ 895 #endif 896 EXT bool quickstart INIT(FALSE); /* -q */ 897 EXT time_t actFetchTime /* -z */ 898 #ifdef USE_NNTP 899 INIT(5*60); 900 #else 901 INIT(0); 902 #endif 903 EXT int try_ov /* -Z */ 904 #ifdef USE_OV 905 INIT(1); 906 #else 907 INIT(0); 908 #endif 909 EXT int try_mt 910 #ifdef USE_MT 911 INIT(1); 912 #else 913 INIT(0); 914 #endif 915 916 #define NOMARKING 0 917 #define STANDOUT 1 918 #define UNDERLINE 2 919 EXT int marking INIT(NOMARKING); /* -m */ 920 #define HALFPAGE_MARKING 1 921 #define BACKPAGE_MARKING 2 922 EXT int marking_areas INIT(HALFPAGE_MARKING); 923 924 EXT ART_LINE initlines INIT(0); /* -i */ 925 EXT bool initlines_specified INIT(FALSE); 926 #ifdef APPEND_UNSUB 927 EXT bool append_unsub INIT(1); /* -I */ 928 #else 929 EXT bool append_unsub INIT(0); 930 #endif 931 932 /* miscellania */ 933 934 #ifndef __STDC__ 935 int fseek(); 936 long atol(), ftell(); 937 extern int errno; 938 #endif 939 940 EXT bool in_ng INIT(FALSE); /* current state of trn */ 941 EXT char mode INIT('i'); /* current state of trn */ 942 943 EXT FILE *tmpfp INIT(Nullfp); /* scratch fp used for .rnlock, .rnlast, etc. */ 944 945 EXT NG_NUM nextrcline INIT(0); /* 1st unused slot in rcline array */ 946 /* startup to avoid checking twice in a row */ 947 948 /* Factored strings */ 949 950 EXT char nullstr[1] INIT(""); 951 EXT char sh[] INIT(SH); 952 EXT char defeditor[] INIT(DEFEDITOR); 953 EXT char hforhelp[] INIT("Type h for help.\n"); 954 #ifdef STRICTCR 955 EXT char badcr[] INIT("\nUnnecessary CR ignored.\n"); 956 #endif 957 EXT char readerr[] INIT("rn read error"); 958 EXT char unsubto[] INIT("\n\nUnsubscribed to newsgroup %s\n"); 959 EXT char cantopen[] INIT("Can't open %s\n"); 960 EXT char cantcreate[] INIT("Can't create %s\n"); 961 EXT char cantrecreate[] INIT("Can't recreate %s -- restoring older version.\n"); 962 963 #ifdef VERBOSE 964 EXT char nocd[] INIT("Can't chdir to directory %s\n"); 965 #else 966 EXT char nocd[] INIT("Can't find %s\n"); 967 #endif 968 969 #if defined(MIMESHOW) || defined(MIMESTORE) 970 EXT bool mime_article INIT(FALSE); 971 #endif 972 973 #ifdef NOLINEBUF 974 #define FLUSH ,fflush(stdout) 975 #else 976 #define FLUSH 977 #endif 978 979 #ifdef lint 980 #undef FLUSH 981 #define FLUSH 982 #undef putchar 983 #define putchar(c) 984 #endif 985 986 #define nntp_advise(str) fputs(str,stdout) 987 #define nntp_init_error(str) fputs(str,stderr) 988 #define nntp_error(str) fputs(str,stderr) 989 #define NNTP_ERROR_IS_FATAL 990 #define NNTP_HANDLE_TIMEOUT 991 #define NNTP_HANDLE_AUTH_ERR 992