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