1 /* common.h 2 */ 3 /* This software is copyrighted as detailed in the LICENSE file. */ 4 5 6 #include <stdio.h> 7 #include <sys/types.h> 8 #include <sys/stat.h> 9 10 #include <ctype.h> 11 #include "config.h" /* generated by installation script */ 12 #include "config2.h" 13 14 #include <errno.h> 15 #include <signal.h> 16 #ifdef I_SYS_FILIO 17 # include <sys/filio.h> 18 #else 19 # ifdef I_SYS_IOCTL 20 # include <sys/ioctl.h> 21 # endif 22 #endif 23 #ifdef I_VFORK 24 # include <vfork.h> 25 #endif 26 #include <fcntl.h> 27 28 #ifdef I_TERMIO 29 # include <termio.h> 30 #else 31 # ifdef I_TERMIOS 32 # include <termios.h> 33 # if !defined (O_NDELAY) 34 # define O_NDELAY O_NONBLOCK /* Posix-style non-blocking i/o */ 35 # endif 36 # else 37 # ifdef I_SGTTY 38 # include <sgtty.h> 39 # endif 40 # endif 41 #endif 42 43 #ifdef I_PTEM 44 #include <sys/stream.h> 45 #include <sys/ptem.h> 46 #endif 47 48 #ifdef I_TIME 49 #include <time.h> 50 #endif 51 #ifdef I_SYS_TIME 52 #include <sys/time.h> 53 #endif 54 55 #include "typedef.h" 56 57 #define BITSPERBYTE 8 58 #define LBUFLEN 1024 /* line buffer length */ 59 /* (don't worry, .newsrc lines can exceed this) */ 60 #define CBUFLEN 512 /* command buffer length */ 61 #define PUSHSIZE 256 62 #define MAXFILENAME 512 63 #define FINISHCMD 0177 64 #define OV_MAX_FIELDS 9 65 66 /* Things we can figure out ourselves */ 67 68 #ifdef SIGTSTP 69 # define BERKELEY /* include job control signals? */ 70 #endif 71 72 #if defined(FIONREAD) || defined(HAS_RDCHK) || defined(O_NDELAY) || defined(MSDOS) 73 # define PENDING 74 #endif 75 76 #ifdef EUNICE 77 # define LINKART /* add 1 level of possible indirection */ 78 # define UNLINK(victim) while (!unlink(victim)) 79 #else 80 # define UNLINK(victim) unlink(victim) 81 #endif 82 83 #ifdef HAS_RENAME 84 # define RENAME(from,to) rename(from,to) 85 #else 86 # define RENAME(from,to) safelink(from,to), UNLINK(from) 87 #endif 88 89 #ifdef HAS_STRSTR 90 # define STRSTR(s1,s2) strstr((s1),(s2)) 91 #else 92 # define STRSTR(s1,s2) trn_strstr((s1),(s2)) 93 #endif 94 95 /* Valid substitutions for strings marked with % comment are: 96 * %a Current article number 97 * %A Full name of current article (%P/%c/%a) 98 * (if LINKART defined, is the name of the real article) 99 * %b Destination of a save command, a mailbox or command 100 * %B The byte offset to the beginning of the article for saves 101 * with or without the header 102 * %c Current newsgroup, directory form 103 * %C Current newsgroup, dot form 104 * %d %P/%c 105 * %D Old Distribution: line 106 * %e Extract program 107 * %E Extract destination directory 108 * %f Old From: line or Reply-To: line 109 * %F Newsgroups to followup to from Newsgroups: and Followup-To: 110 * %h Name of header file to pass to mail or news poster 111 * %H Host name (yours) 112 * %i Old Message-I.D.: line, with <> 113 * %j The terminal speed (e.g. 9600) 114 * %I Inclusion indicator 115 * %l News administrator login name 116 * %L Login name (yours) 117 * %m The current mode of trn. 118 * %M Number of articles marked with M 119 * %n Newsgroups from source article 120 * %N Full name (yours) 121 * %o Organization (yours) 122 * %O Original working directory (where you ran trn from) 123 * %p Your private news directory (-d switch) 124 * %P Public news spool directory (NEWSSPOOL) 125 * %r Last reference (parent article id) 126 * %q The last quoted input (via %"). 127 * %R New references list 128 * %s Subject, with all Re's and (nf)'s stripped off 129 * %S Subject, with one Re stripped off 130 * %t New To: line derived from From: and Reply-To (Internet always) 131 * %T New To: line derived from Path: 132 * %u Number of unread articles 133 * %U Number of unread articles disregarding current article 134 * %v Number of unselected articles disregarding current article 135 * %W The thread directory root 136 * %x News library directory, usually /usr/lib/news 137 * %X Trn's private library directory, usually %x/trn 138 * %y From line with domain shortening (name@*.domain.nam) 139 * %Y The tmp directory to use 140 * %z Size of current article in bytes. 141 * %Z Number of selected threads. 142 * %~ Home directory 143 * %. Directory containing . files, usually %~ 144 * %+ Directory containing a user's init files, usually %./.trn 145 * %# count of articles saved in current command (from 1 to n) 146 * %^# ever-increasing number (from 1 to n) 147 * %$ current process number 148 * %{name} Environment variable "name". %{name-default} form allowed. 149 * %[name] Header line beginning with "Name: ", without "Name: " 150 * %"prompt" 151 * Print prompt and insert what is typed. 152 * %`command` 153 * Insert output of command. 154 * %(test_text=pattern?if_text:else_text) 155 * Substitute if_text if test_text matches pattern, otherwise 156 * substitute else_text. Use != for negated match. 157 * % substitutions are done on test_text, if_text, and else_text. 158 * %digit Substitute the text matched by the nth bracket in the last 159 * pattern that had brackets. %0 matches the last bracket 160 * matched, in case you had alternatives. 161 * %? Insert a space unless the entire result is > 79 chars, in 162 * which case the space becomes a newline. 163 * 164 * Put ^ in the middle to capitalize the first letter: %^C = Rec.humor 165 * Put _ in the middle to capitalize last component: %_c = net/Jokes 166 * Put \ in the middle to quote regexp and % characters in the result 167 * Put > in the middle to return the address portion of a name. 168 * Put ) in the middle to return the comment portion of a name. 169 * Put ' in the middle to protect "'"s in arguments you've put in "'"s. 170 * Put :FMT in the middle to format the result: %:-30.30t 171 * 172 * ~ interpretation in filename expansion happens after % expansion, so 173 * you could put ~%{NEWSLOGNAME-news} and it will expand correctly. 174 */ 175 176 /* *** System Dependent Stuff *** */ 177 178 /* NOTE: many of these are defined in the config.h file */ 179 180 /* name of organization */ 181 #ifndef ORGNAME 182 # define ORGNAME "ACME Widget Company, Widget Falls, Southern North Dakota" 183 #endif 184 185 #ifndef MBOXCHAR 186 # define MBOXCHAR 'F' /* how to recognize a mailbox by 1st char */ 187 #endif 188 189 #ifndef ROOTID 190 # define ROOTID 0 /* uid of superuser */ 191 #endif 192 193 #ifdef NORMSIG 194 # define sigset signal 195 # define sigignore(sig) signal(sig,SIG_IGN) 196 #endif 197 198 #ifndef PASSFILE 199 # ifdef LIMITED_FILENAMES 200 # define PASSFILE "%X/passwd" 201 # else 202 # define PASSFILE "/etc/passwd" 203 # endif 204 #endif 205 206 #ifndef LOGDIRFIELD 207 # define LOGDIRFIELD 6 /* Which field (origin 1) is the */ 208 /* login directory in /etc/passwd? */ 209 /* (If it is not kept in passwd, */ 210 /* but getpwnam() returns it, */ 211 /* define the symbol HAS_GETPWENT) */ 212 #endif 213 #ifndef GCOSFIELD 214 # define GCOSFIELD 5 215 #endif 216 217 #ifndef NEGCHAR 218 # define NEGCHAR '!' 219 #endif 220 221 /* Space conservation section */ 222 223 /* To save D space, cut down size of MAXNGTODO and VARYSIZE. */ 224 #define MAXNGTODO 512 /* number of newsgroups allowed on command line */ 225 #define VARYSIZE 256 /* this makes a block 1024 bytes long in DECville */ 226 /* (used by virtual array routines) */ 227 228 /* Undefine any of the following features to save both I and D space */ 229 /* In general, earlier ones are easier to get along without */ 230 #define USE_FILTER /* external kill/score filter */ 231 #define CUSTOMLINES /* include code for HIDELINE and PAGESTOP */ 232 #define WORDERASE /* enable ^W to erase a word */ 233 #define MAILCALL /* check periodically for mail */ 234 #define NOFIREWORKS /* keep whole screen from flashing on certain */ 235 /* terminals such as older Televideos */ 236 #define VERIFY /* echo the command they just typed */ 237 #define BACKTICK /* allow %`command` */ 238 #define PROMPTTTY /* allow %"prompt" */ 239 #define ULSMARTS /* catch _^H in text and do underlining */ 240 #define TERMMOD /* allow terminal type modifier on switches */ 241 #define BAUDMOD /* allow baudrate modifier on switches */ 242 #define ORGFILE /* if organization begins with /, look up in file */ 243 #define TILDENAME /* allow ~logname expansion */ 244 #define SETENV /* allow command line environment variable setting */ 245 #define MAKEDIR /* use our makedir() instead of shell script */ 246 #define MEMHELP /* keep help messages in memory */ 247 #define VERBOSE /* compile in more informative messages */ 248 #define TERSE /* compile in shorter messages */ 249 /* (Note: both VERBOSE and TERSE can be defined; -t 250 * sets terse mode. One or the other MUST be defined. 251 */ 252 #define CHARSUBST /* enable the _C command */ 253 #define DELBOGUS /* ask if bogus newsgroups should be deleted */ 254 #define RELOCATE /* allow newsgroup rearranging */ 255 #define ESCSUBS /* escape substitutions in multi-character commands */ 256 #undef MCHASE /* unmark xrefed articles on m or M */ 257 #define MUNGHEADER /* allow alternate header formatting via */ 258 /* environment variable ALTHEADER (not impl) */ 259 #define ASYNC_PARSE /* allow parsing headers asyncronously to reading */ 260 /* used by MCHASE and MUNGHEADER */ 261 #define FINDNEWNG /* check for new newsgroups on startup */ 262 #define FASTNEW /* do optimizations on FINDNEWNG for faster startup */ 263 #define INNERSEARCH /* search command 'g' with article */ 264 #define CATCHUP /* catchup command at newsgroup level */ 265 #define NGSEARCH /* newsgroup pattern matching */ 266 #define KILLFILES /* automatic article killer files */ 267 #define ARTSEARCH /* pattern searches among articles */ 268 /* /, ?, ^N, ^P, k, K */ 269 #define EDIT_DISTANCE /* Allow -G to specify a fuzzy 'go' command */ 270 #undef VALIDATE_XREF_SITE /* are xrefs possibly invalid? */ 271 272 /*#define LONG_THREAD_NAMES *//**/ 273 274 /* USEURL may soon become a Configure script option */ 275 /*#define USEURL *//* allow trn to fetch/use WWW URLs */ 276 277 /* if USEFTP is defined, trn will use the ftpgrab script for ftp: URLs 278 * USEFTP is not very well tested, and the ftpgrab script is not 279 * installed with make install. May go away later 280 */ 281 /*#define USEFTP *//**/ 282 283 /* The NICEBG functions are probably only useful now for *slow* systems */ 284 /*#define NICEBG *//* use some kind of nice-background call */ 285 /* the specific type of NICEBG is used only if NICBG is defined */ 286 /* select() call for nice background. */ 287 #define NBG_SELECT /**/ 288 /* TERMIO(S) style of nice background available. Second choice */ 289 /*#define NBG_TERMIO *//**/ 290 /* SIGIO style of nice background (last resort) */ 291 /*#define NBG_SIGIO *//**/ 292 293 /* SHORTSCORENAMES has not been tested recently */ 294 /*#define SHORTSCORENAMES *//* foo/bar/baz/SCORE instead of foo.bar.baz */ 295 296 /* if SCOREFILE_CACHE is defined, scorefiles will be kept in memory. */ 297 #define SCOREFILE_CACHE 298 299 /* some dependencies among options */ 300 301 #ifdef SCAN 302 # define SCAN_ART 303 #else 304 # ifdef SCAN_ART 305 # undef SCAN_ART 306 # endif 307 #endif /* SCAN */ 308 309 #ifndef SCORE 310 # ifdef USE_FILTER 311 # undef USE_FILTER 312 # endif 313 #endif /* SCORE */ 314 315 #ifndef ARTSEARCH 316 # undef KILLFILES 317 # undef INNERSEARCH 318 #endif 319 320 #ifndef SETUIDGID 321 # define eaccess access 322 #endif 323 324 #ifdef VERBOSE 325 # ifdef TERSE 326 # define IF(c) if (c) 327 # define ELSE else 328 # else 329 # define IF(c) 330 # define ELSE 331 # endif 332 #else /* !VERBOSE */ 333 # ifndef TERSE 334 # define TERSE 335 # endif 336 # define IF(c) ..."IF" outside of VERBOSE 337 # define ELSE ..."ELSE" outside of VERBOSE 338 #endif 339 340 #ifdef SUPPORT_NNTP 341 #define ElseIf else if 342 #else 343 #define ElseIf if 344 #endif 345 346 #ifdef DEBUG 347 # define assert(ex) {if (!(ex)){fprintf(stderr,"Assertion failed: file %s, line %d\n", __FILE__, __LINE__);sig_catcher(0);}} 348 #else 349 # define assert(ex) ; 350 #endif 351 352 /* If you're strapped for space use the help messages in shell scripts */ 353 /* if {NG,ART,PAGER,SUBS}HELP is undefined, help messages are in memory */ 354 #ifdef MEMHELP /* undef MEMHELP above to get them all as sh scripts */ 355 # undef NGHELP 356 # undef ARTHELP 357 # undef PAGERHELP 358 # undef SUBSHELP 359 #else 360 # ifndef NGHELP /* % and ~ */ 361 # define NGHELP "%X/ng.help" 362 # endif 363 # ifndef ARTHELP /* % and ~ */ 364 # define ARTHELP "%X/art.help" 365 # endif 366 # ifndef PAGERHELP /* % and ~ */ 367 # define PAGERHELP "%X/pager.help" 368 # endif 369 # ifndef SUBSHELP /* % and ~ */ 370 # define SUBSHELP "%X/subs.help" 371 # endif 372 #endif 373 374 #define TCSIZE 512 /* capacity for termcap strings */ 375 376 #ifdef EDIT_DISTANCE 377 # define MIN_DIST 7 /* Maximum error count for acceptable match */ 378 #endif 379 380 /* Additional ideas: 381 * Make the do_newsgroup() routine a separate process. 382 * Keep .newsrc on disk instead of in memory. 383 * Overlays, if you have them. 384 * Get a bigger machine. 385 */ 386 387 /* End of Space Conservation Section */ 388 389 /* More System Dependencies */ 390 391 /* news library */ 392 #ifndef NEWSLIB /* ~ and %l only ("~%l" is permissable) */ 393 # define NEWSLIB "/usr/lib/news" 394 #endif 395 396 /* path to private executables */ 397 #ifndef PRIVLIB /* ~, %x and %l only */ 398 # define PRIVLIB "%x/trn" 399 #endif 400 401 /* system-wide RNINIT switches */ 402 #ifndef GLOBINIT 403 # define GLOBINIT "%X/INIT" 404 #endif 405 406 /* where to find news files */ 407 #ifndef NEWSSPOOL /* % and ~ */ 408 # define NEWSSPOOL "/usr/spool/news" 409 #endif 410 411 #ifndef THREAD_DIR 412 # undef LONG_THREAD_NAMES 413 #endif 414 415 /* default characters to use in the selection menu */ 416 #ifndef SELECTCHARS 417 # define SELECTCHARS "abdefgijlorstuvwxyz1234567890BCFGIKVW" 418 #endif 419 420 /* file containing list of active newsgroups and max article numbers */ 421 #ifndef ACTIVE /* % and ~ */ 422 # define ACTIVE "%x/active" 423 #endif 424 #ifndef ACTIVE_TIMES 425 # define ACTIVE_TIMES "none" 426 #endif 427 #ifndef GROUPDESC 428 # define GROUPDESC "%x/newsgroups" 429 #endif 430 #ifndef DBINIT 431 # define DBINIT "%W/db.init" 432 #endif 433 434 /* location of history file */ 435 #ifndef ARTFILE /* % and ~ */ 436 # define ARTFILE "%x/history" 437 #endif 438 439 /* preferred shell for use in doshell routine */ 440 /* ksh or sh would be okay here */ 441 #ifndef PREFSHELL 442 # define PREFSHELL "/bin/csh" 443 #endif 444 445 /* path to fastest starting shell */ 446 #ifndef SH 447 # define SH "/bin/sh" 448 #endif 449 450 /* path to default editor */ 451 #ifndef DEFEDITOR 452 # define DEFEDITOR "/usr/ucb/vi" 453 #endif 454 455 /* the user's init files */ 456 #ifndef TRNDIR 457 # ifdef LIMITED_FILENAMES 458 # define TRNDIR "%./trn" 459 # else 460 # define TRNDIR "%./.trn" 461 # endif 462 #endif 463 464 /* location of macro file for trn and rn modes */ 465 #ifndef TRNMACRO 466 # define TRNMACRO "%+/macros" 467 #endif 468 #ifndef RNMACRO 469 # ifdef LIMITED_FILENAMES 470 # define RNMACRO "%./rnmac" 471 # else 472 # define RNMACRO "%./.rnmac" 473 # endif 474 #endif 475 476 /* location of full name */ 477 #ifndef FULLNAMEFILE 478 # ifndef PASSNAMES 479 # ifdef LIMITED_FILENAMES 480 # define FULLNAMEFILE "%./fullname" 481 # else 482 # define FULLNAMEFILE "%./.fullname" 483 # endif 484 # endif 485 #endif 486 487 /* The name to append to the directory name to read an overview file. */ 488 #ifndef OV_FILE_NAME 489 # ifdef LIMITED_FILENAMES 490 # define OV_FILE_NAME "/overview" 491 # else 492 # define OV_FILE_NAME "/.overview" 493 # endif 494 #endif 495 496 /* The name to append to the directory name to read a thread file. */ 497 #ifndef MT_FILE_NAME 498 # ifdef LIMITED_FILENAMES 499 # define MT_FILE_NAME "/thread" 500 # else 501 # define MT_FILE_NAME "/.thread" 502 # endif 503 #endif 504 505 /* virtual array file name template */ 506 #ifndef VARYNAME /* % and ~ */ 507 # define VARYNAME "%Y/rnvary.%$" 508 #endif 509 510 /* file to pass header to followup article poster */ 511 #ifndef HEADNAME /* % and ~ */ 512 # ifdef LIMITED_FILENAMES 513 # define HEADNAME "%Y/tmpart.%$" 514 # else 515 # define HEADNAME "%./.rnhead.%$" 516 # endif 517 #endif 518 519 #ifndef MAKEDIR 520 /* shell script to make n-deep subdirectories */ 521 # ifndef DIRMAKER /* % and ~ */ 522 # define DIRMAKER "%X/makedir" 523 # endif 524 #endif 525 526 /* trn's default access list */ 527 #ifndef DEFACCESS 528 # define DEFACCESS "%X/access.def" 529 #endif 530 531 /* trn's access list */ 532 #ifndef TRNACCESS 533 # define TRNACCESS "%+/access" 534 #endif 535 536 /* location of newsrc file */ 537 #ifndef RCNAME /* % and ~ */ 538 # ifdef LIMITED_FILENAMES 539 # define RCNAME "%./newsrc" 540 # else 541 # define RCNAME "%./.newsrc" 542 # endif 543 #endif 544 545 /* temporary newsrc file in case we crash while writing out */ 546 #ifndef RCNAME_NEW 547 # define RCNAME_NEW "%s.new" 548 #endif 549 550 /* newsrc file at the beginning of this session */ 551 #ifndef RCNAME_OLD 552 # define RCNAME_OLD "%s.old" 553 #endif 554 555 /* lockfile for each newsrc that is not ~/.newsrc (which uses .rnlock) */ 556 #ifndef RCNAME_LOCK 557 # define RCNAME_LOCK "%s.LOCK" 558 #endif 559 560 /* news source info for each newsrc that is not ~/.newsrc (.rnlast) */ 561 #ifndef RCNAME_INFO 562 # define RCNAME_INFO "%s.info" 563 #endif 564 565 /* if existent, contains process number of current or crashed trn */ 566 #ifndef LOCKNAME /* % and ~ */ 567 # ifdef LIMITED_FILENAMES 568 # define LOCKNAME "%+/lock" 569 # else 570 # define LOCKNAME "%./.rnlock" 571 # endif 572 #endif 573 574 /* information from last invocation of trn */ 575 #ifndef LASTNAME /* % and ~ */ 576 # ifdef LIMITED_FILENAMES 577 # define LASTNAME "%+/rnlast" 578 # else 579 # define LASTNAME "%./.rnlast" 580 # endif 581 #endif 582 583 #ifndef SIGNATURE_FILE 584 # ifdef LIMITED_FILENAMES 585 # define SIGNATURE_FILE "%./signatur" 586 # else 587 # define SIGNATURE_FILE "%./.signature" 588 # endif 589 #endif 590 591 #ifndef NNTP_AUTH_FILE 592 # define NNTP_AUTH_FILE "%./.nntpauth" 593 #endif 594 595 /* a motd-like file for trn */ 596 #ifndef NEWSNEWSNAME /* % and ~ */ 597 # define NEWSNEWSNAME "%X/newsnews" 598 #endif 599 600 /* command to send a reply */ 601 #ifndef MAILPOSTER /* % and ~ */ 602 # define MAILPOSTER "Rnmail -h %h" 603 #endif 604 605 #ifdef INTERNET 606 # ifndef MAILHEADER /* % */ 607 # define MAILHEADER "To: %t\nSubject: %(%i=^$?:Re: %S\nX-Newsgroups: %n\nIn-Reply-To: %i)\n%(%{FROM}=^$?:From: %{FROM}\n)%(%{REPLYTO}=^$?:Reply-To: %{REPLYTO}\n)%(%[references]=^$?:References: %[references]\n)Organization: %o\nCc: \nBcc: \n\n" 608 # endif 609 #else 610 # ifndef MAILHEADER /* % */ 611 # define MAILHEADER "To: %T\nSubject: %(%i=^$?:Re: %S\n%(%{FROM}=^$?:From: %{FROM}\n)%(%{REPLYTO}=^$?:Reply-To: %{REPLYTO}\n)X-Newsgroups: %n\nIn-Reply-To: %i)\n%(%[references]=^$?:References: %[references]\n)Organization: %o\nCc: \nBcc: \n\n" 612 # endif 613 #endif 614 615 #ifndef YOUSAID /* % */ 616 # define YOUSAID "In article %i you write:" 617 #endif 618 619 /* command to forward an article */ 620 #define FORWARDPOSTER MAILPOSTER 621 622 #ifdef INTERNET 623 # ifndef FORWARDHEADER /* % */ 624 # define FORWARDHEADER "To: %\"\n\nTo: \"\nSubject: %(%i=^$?:%[subject] (fwd\\)\n%(%{FROM}=^$?:From: %{FROM}\n)%(%{REPLYTO}=^$?:Reply-To: %{REPLYTO}\n)X-Newsgroups: %n\nIn-Reply-To: %i)\n%(%[references]=^$?:References: %[references]\n)Organization: %o\nMime-Version: 1.0\nContent-Type: multipart/mixed; boundary=\"=%$%^#=--\"\nCc: \nBcc: \n\n" 625 # endif 626 #else 627 # ifndef FORWARDHEADER /* % */ 628 # define FORWARDHEADER "To: %\"\n\nTo: \"\nSubject: %(%i=^$?:%[subject] (fwd\\)\n%(%{FROM}=^$?:From: %{FROM}\n)%(%{REPLYTO}=^$?:Reply-To: %{REPLYTO}\n)X-Newsgroups: %n\nIn-Reply-To: %i)\n%(%[references]=^$?:References: %[references]\n)Organization: %o\nMime-Version: 1.0\nContent-Type: multipart/mixed; boundary=\"=%$%^#=--\"\nCc: \nBcc: \n\n" 629 # endif 630 #endif 631 632 #ifndef FORWARDMSG /* % */ 633 # define FORWARDMSG "------- start of forwarded message -------" 634 #endif 635 636 #ifndef FORWARDMSGEND /* % */ 637 # define FORWARDMSGEND "------- end of forwarded message -------" 638 #endif 639 640 /* command to submit a followup article */ 641 #ifndef NEWSPOSTER /* % and ~ */ 642 # define NEWSPOSTER "Pnews -h %h" 643 #endif 644 645 #ifndef NEWSHEADER /* % */ 646 # 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%(%{FROM}=^$?:From: %{FROM}\n)%(%{REPLYTO}=^$?:Reply-To: %{REPLYTO}\n)Distribution: %(%i=^$?%\"Distribution: \":%D)\nOrganization: %o\nKeywords: %[keywords]\nCc: %(%F=poster?%t:%(%F!=@?:%F))\n\n" 647 #endif 648 649 #ifndef ATTRIBUTION /* % */ 650 # define ATTRIBUTION "In article %i,%?%)f <%>f> wrote:" 651 #endif 652 653 #ifndef PIPESAVER /* % */ 654 # define PIPESAVER "%(%B=^0$?<%A:tail +%Bc %A |) %b" 655 #endif 656 657 #ifndef SHARSAVER 658 # define SHARSAVER "tail +%Bc %A | /bin/sh" 659 #endif 660 661 #ifndef CUSTOMSAVER 662 # define CUSTOMSAVER "tail +%Bc %A | %e" 663 #endif 664 665 #ifndef VERIFY_RIPEM 666 # define VERIFY_RIPEM "ripem -d -Y fgs -i %A" 667 #endif 668 669 #ifndef VERIFY_PGP 670 # define VERIFY_PGP "pgp +batchmode -m %A" 671 #endif 672 673 #ifdef MKDIRS 674 675 # ifndef SAVEDIR /* % and ~ */ 676 # define SAVEDIR "%p/%c" 677 # endif 678 # ifndef SAVENAME /* % */ 679 # define SAVENAME "%a" 680 # endif 681 682 #else 683 684 # ifndef SAVEDIR /* % and ~ */ 685 # define SAVEDIR "%p" 686 # endif 687 # ifndef SAVENAME /* % */ 688 # define SAVENAME "%^C" 689 # endif 690 691 #endif 692 693 #ifndef KILLGLOBAL /* % and ~ */ 694 # define KILLGLOBAL "%p/KILL" 695 #endif 696 697 #ifndef KILLLOCAL /* % and ~ */ 698 # define KILLLOCAL "%p/%c/KILL" 699 #endif 700 701 #ifndef KILLTHREADS /* % and ~ */ 702 # define KILLTHREADS "%+/Kill/Threads" 703 #endif 704 705 #ifdef USE_FILTER 706 # ifndef FILTERPROG 707 # define FILTERPROG "%+/filter" 708 # endif 709 #endif /* USE_FILTER */ 710 711 /* how to cancel an article */ 712 #ifndef CALL_INEWS 713 # ifdef BNEWS 714 # define CALL_INEWS "%x/inews -h <%h" 715 # else 716 # define CALL_INEWS "inews -h <%h" 717 # endif 718 #endif 719 720 /* how to cancel an article, continued */ 721 #ifndef CANCELHEADER 722 # define CANCELHEADER "Newsgroups: %n\nSubject: cancel\n%(%{FROM}=^$?:From: %{FROM}\n)Control: cancel %i\nDistribution: %D\n\n%i was cancelled from within trn.\n" 723 #endif 724 725 /* how to supersede an article */ 726 #ifndef SUPERSEDEHEADER 727 # define SUPERSEDEHEADER "Newsgroups: %n\nSubject: %[subject]\n%(%{FROM}=^$?:From: %{FROM}\n)Summary: %[summary]\nExpires: %[expires]\nReferences: %[references]\nFrom: %[from]\nReply-To: %[reply-to]\nSupersedes: %i\nSender: %[sender]\nFollowup-To: %[followup-to]\nDistribution: %D\nOrganization: %o\nKeywords: %[keywords]\n\n" 728 #endif 729 730 #ifndef LOCALTIMEFMT 731 # define LOCALTIMEFMT "%a %b %d %X %Z %Y" 732 #endif 733 734 /* where to find the mail file */ 735 #ifndef MAILFILE 736 # define MAILFILE "/usr/spool/mail/%L" 737 #endif 738 739 /* dependencies of nice background scoring */ 740 #ifdef PENDING 741 # ifdef NICEBG 742 # ifndef I_TERMIO 743 # ifndef I_TERMIOS 744 # undef NBG_TERMIO 745 # endif 746 # endif 747 /* later insert defines to turn off NBG_SIGIO when needed */ 748 # endif 749 #else /* !PENDING */ 750 # undef NICEBG 751 #endif 752 753 #ifndef HAS_VFORK 754 # define vfork fork 755 #endif 756 757 /* Winsock is only initialized if NNTP_SUPPORT is defined */ 758 #ifdef WINSOCK 759 # ifndef NNTP_SUPPORT 760 # ifdef USEURL 761 # undef USEURL 762 # endif 763 # endif 764 #endif 765 766 /* TK requires TCL */ 767 #ifdef USE_TK 768 # ifndef USE_TCL 769 # define USE_TCL 770 # endif 771 #endif 772 773 /* *** end of the machine dependent stuff *** */ 774 775 /* GLOBAL THINGS */ 776 777 /* file statistics area */ 778 779 EXT struct stat filestat; 780 781 /* various things of type char */ 782 783 EXT char msg[CBUFLEN]; /* general purpose message buffer */ 784 EXT char buf[LBUFLEN+1]; /* general purpose line buffer */ 785 EXT char cmd_buf[CBUFLEN]; /* buffer for formatting system commands */ 786 EXT char* indstr INIT(">"); /* indent for old article embedded in followup */ 787 788 EXT char* cwd INIT(NULL); /* current working directory */ 789 EXT char* dfltcmd INIT(NULL); /* 1st char is default command */ 790 791 /* switches */ 792 793 #ifdef DEBUG 794 EXT int debug INIT(0); /* -D */ 795 # define DEB_COREDUMPSOK 2 796 # define DEB_HEADER 4 797 # define DEB_INTRP 8 798 # define DEB_NNTP 16 799 # define DEB_INNERSRCH 32 800 # define DEB_FILEXP 64 801 # define DEB_HASH 128 802 # define DEB_XREF_MARKER 256 803 # define DEB_CTLAREA_BITMAP 512 804 # define DEB_RCFILES 1024 805 # define DEB_NEWSRC_LINE 2048 806 # define DEB_SEARCH_AHEAD 4096 807 # define DEB_CHECKPOINTING 8192 808 # define DEB_FEED_XREF 16384 809 #endif 810 811 #ifdef ARTSEARCH 812 EXT int scanon INIT(0); /* -S */ 813 #endif 814 815 EXT bool use_threads INIT(THREAD_INIT); /* -x */ 816 EXT int max_tree_lines INIT(6); 817 818 EXT char UnivSelCmds[3] INIT("Z>"); 819 EXT char NewsrcSelCmds[3] INIT("Z>"); 820 EXT char AddSelCmds[3] INIT("Z>"); 821 EXT char NewsgroupSelCmds[3] INIT("Z>"); 822 EXT char NewsSelCmds[3] INIT("Z>"); 823 EXT char OptionSelCmds[3] INIT("Z>"); 824 825 EXT int UnivSelBtnCnt; 826 EXT int NewsrcSelBtnCnt; 827 EXT int AddSelBtnCnt; 828 EXT int NewsgroupSelBtnCnt; 829 EXT int NewsSelBtnCnt; 830 EXT int OptionSelBtnCnt; 831 EXT int ArtPagerBtnCnt; 832 833 EXT char* UnivSelBtns INIT(NULL); 834 EXT char* NewsrcSelBtns INIT(NULL); 835 EXT char* AddSelBtns INIT(NULL); 836 EXT char* NewsgroupSelBtns INIT(NULL); 837 EXT char* NewsSelBtns INIT(NULL); 838 EXT char* OptionSelBtns INIT(NULL); 839 EXT char* ArtPagerBtns INIT(NULL); 840 841 EXT bool dont_filter_control INIT(FALSE); /* -j */ 842 EXT int join_subject_len INIT(0); /* -J */ 843 EXT bool kill_thru_kludge INIT(TRUE); /* -k */ 844 EXT bool keep_the_group_static INIT(FALSE); /* -K */ 845 EXT bool mbox_always INIT(FALSE); /* -M */ 846 EXT bool norm_always INIT(FALSE); /* -N */ 847 EXT bool thread_always INIT(FALSE); /* -a */ 848 EXT int auto_arrow_macros INIT(2); /* -A */ 849 EXT bool breadth_first INIT(FALSE); /* -b */ 850 EXT bool bkgnd_spinner INIT(FALSE); /* -B */ 851 EXT bool novice_delays INIT(TRUE); /* +f */ 852 EXT int olden_days INIT(FALSE); /* -o */ 853 EXT char auto_select_postings INIT(0); /* -p */ 854 EXT bool checkflag INIT(FALSE); /* -c */ 855 EXT char* savedir INIT(NULL); /* -d */ 856 EXT bool suppress_cn INIT(FALSE); /* -s */ 857 EXT int countdown INIT(5); /* how many lines to list before invoking -s */ 858 EXT bool muck_up_clear INIT(FALSE); /* -loco */ 859 EXT bool erase_screen INIT(FALSE); /* -e */ 860 EXT bool can_home INIT(FALSE); 861 EXT bool erase_each_line INIT(FALSE); /* fancy -e */ 862 EXT int findlast INIT(0); /* -r */ 863 EXT bool allow_typeahead INIT(FALSE); /* -T */ 864 #ifdef EDIT_DISTANCE 865 EXT bool fuzzyGet INIT(FALSE); /* -G */ 866 #endif 867 #ifdef VERBOSE 868 # ifdef TERSE 869 EXT bool verbose INIT(TRUE); /* +t */ 870 # endif 871 #endif 872 EXT bool unbroken_subjects INIT(FALSE); /* -u */ 873 EXT bool unsafe_rc_saves INIT(FALSE); /* -U */ 874 #ifdef VERIFY 875 EXT bool verify INIT(FALSE); /* -v */ 876 #endif 877 EXT bool quickstart INIT(FALSE); /* -q */ 878 879 #define DEFAULT_REFETCH_SECS 4L*60*60 /* 4 hours */ 880 EXT time_t defRefetchSecs INIT(DEFAULT_REFETCH_SECS); /* -z */ 881 882 EXT int word_wrap_offset INIT(8); /* right-hand column size (0 is off) */ 883 884 #define NOMARKING 0 885 #define STANDOUT 1 886 #define UNDERLINE 2 887 #define LASTMARKING 3 888 EXT int marking INIT(NOMARKING); /* -m */ 889 #define HALFPAGE_MARKING 1 890 #define BACKPAGE_MARKING 2 891 EXT int marking_areas INIT(HALFPAGE_MARKING); 892 893 EXT ART_LINE initlines INIT(0); /* -i */ 894 EXT bool append_unsub /* -I */ 895 #ifdef APPEND_UNSUB 896 INIT(1); 897 #else 898 INIT(0); 899 #endif 900 901 EXT bool UseUnivSelector INIT(FALSE); 902 EXT bool UseNewsrcSelector INIT(FALSE); 903 EXT bool UseAddSelector INIT(TRUE); 904 EXT bool UseNewsgroupSelector INIT(TRUE); 905 EXT int UseNewsSelector INIT(SELECT_INIT-1); 906 EXT bool UseMouse INIT(FALSE); 907 EXT char MouseModes[32] INIT("acjlptwvK"); 908 EXT bool use_colors INIT(FALSE); 909 EXT bool UseTk INIT(FALSE); 910 EXT bool UseTcl INIT(FALSE); 911 EXT bool UseSelNum INIT(FALSE); 912 EXT bool SelNumGoto INIT(FALSE); 913 /* miscellania */ 914 915 EXT bool in_ng INIT(FALSE); /* TRUE if in a newsgroup */ 916 EXT char mode INIT('i'); /* current state of trn */ 917 EXT char gmode INIT('I'); /* general mode of trn */ 918 919 EXT FILE* tmpfp INIT(NULL); /* scratch fp used for .rnlock, .rnlast, etc. */ 920 921 #define PLURAL(num) ((num)==1? nullstr : ess) 922 #define ALLBITS(val,bits) (((val) & (bits)) == (bits)) 923 924 /* Factored strings */ 925 926 EXT char nullstr[1] INIT(""); 927 EXT char ess[2] INIT("s"); 928 EXT char sh[] INIT(SH); 929 EXT char defeditor[] INIT(DEFEDITOR); 930 EXT char hforhelp[] INIT("Type h for help.\n"); 931 #ifdef STRICTCR 932 EXT char badcr[] INIT("\nUnnecessary CR ignored.\n"); 933 #endif 934 EXT char readerr[] INIT("rn read error"); 935 EXT char unsubto[] INIT("Unsubscribed to newsgroup %s\n"); 936 EXT char cantopen[] INIT("Can't open %s\n"); 937 EXT char cantcreate[] INIT("Can't create %s\n"); 938 EXT char cantrecreate[] INIT("Can't recreate %s -- restoring older version.\n\ 939 Perhaps you are near or over quota?\n"); 940 941 #ifdef VERBOSE 942 EXT char nocd[] INIT("Can't chdir to directory %s\n"); 943 #else 944 EXT char nocd[] INIT("Can't find %s\n"); 945 #endif 946 947 #ifdef NOLINEBUF 948 #define FLUSH ,fflush(stdout) 949 #else 950 #define FLUSH 951 #endif 952 953 #ifdef lint 954 #undef FLUSH 955 #define FLUSH 956 #undef putchar 957 #define putchar(c) 958 #endif 959 960 #define nntp_advise(str) fputs(str,stdout) 961 #define nntp_init_error(str) fputs(str,stdout) 962 #define nntp_error(str) fputs(str,stderr) 963 #define NNTP_ERROR_IS_FATAL 964 #define NNTP_HANDLE_TIMEOUT 965 #define NNTP_HANDLE_AUTH_ERR 966