home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Spezial / SPEZIAL2_97.zip / SPEZIAL2_97.iso / ANWEND / ONLINE / ELM23-2 / ELM23-2.ZIP / src / read_rc.c < prev    next >
C/C++ Source or Header  |  1992-03-29  |  28KB  |  890 lines

  1.  
  2. static char rcsid[] = "@(#)$Id: read_rc.c,v 4.1.1.1 90/06/21 23:28:49 syd Exp $";
  3.  
  4. /*******************************************************************************
  5.  *  The Elm Mail System  -  $Revision: 4.1.1.1 $   $State: Exp $
  6.  *
  7.  *             Copyright (c) 1986, 1987 Dave Taylor
  8.  *             Copyright (c) 1988, 1989, 1990 USENET Community Trust
  9.  *******************************************************************************
  10.  * Bug reports, patches, comments, suggestions should be sent to:
  11.  *
  12.  *    Syd Weinstein, Elm Coordinator
  13.  *    elm@DSI.COM            dsinc!elm
  14.  *
  15.  *******************************************************************************
  16.  * $Log:    read_rc.c,v $
  17.  * Revision 4.1.1.1  90/06/21  23:28:49  syd
  18.  * Add apollo check for //node
  19.  * From: Russ Johnson
  20.  *
  21.  * Revision 4.1  90/04/28  22:43:46  syd
  22.  * checkin of Elm 2.3 as of Release PL0
  23.  *
  24.  *
  25.  ******************************************************************************/
  26.  
  27. /** This file contains programs to allow the user to have a .elm/elmrc file
  28.     in their home directory containing any of the following:
  29.  
  30.     fullname= <username string>
  31.     maildir = <directory>
  32.     tmpdir  = <directory>
  33.     sentmail = <file>
  34.     editor  = <editor>
  35.     receviedmail= <file>
  36.     calendar= <calendar file name>
  37.     shell   = <shell>
  38.     print   = <print command>
  39.     weedout = <list of headers to weed out>
  40.     prefix  = <copied message prefix string>
  41.     pager   = <command to use for displaying messages>
  42.  
  43.     escape  = <single character escape, default = '~' >
  44.  
  45. --
  46.     signature = <.signature file for all outbound mail>
  47. OR:
  48.     localsignature = <.signature file for local mail>
  49.     remotesignature = <.signature file for non-local mail>
  50. --
  51.  
  52.     bounceback= <hop count threshold, or zero to disable>
  53.     timeout = <seconds for main menu timeout or zero to disable>
  54.     userlevel = <0=amateur, 1=okay, 2 or greater = expert!>
  55.  
  56.     sortby  = <sent, received, from, size, subject, mailbox, status>
  57.  
  58.     alternatives = <list of addresses that forward to us>
  59.  
  60.     and/or the logical arguments:
  61.  
  62.     autocopy    [on|off]
  63.     askcc        [on|off]
  64.     copy        [on|off]
  65.     resolve     [on|off]
  66.     weed        [on|off]
  67.     noheader    [on|off]
  68.     titles      [on|off]
  69.     savebyname  [on|off]
  70.     forcename   [on|off]
  71.     movepage    [on|off]
  72.     pointnew    [on|off]
  73.     hpkeypad    [on|off]
  74.     hpsoftkeys  [on|off]
  75.     alwayskeep [on|off]
  76.     alwaysstore [on|off]
  77.     alwaysdel   [on|off]
  78.     arrow        [on|off]
  79.     menus        [on|off]
  80.     forms        [on|off]
  81.     warnings    [on|off]
  82.     names        [on|off]
  83.     ask        [on|off]
  84.     keepempty   [on|off]
  85.     promptafter[on|off]
  86.     sigdashes   [on|off]
  87.  
  88.  
  89.     Lines starting with '#' are considered comments and are not checked
  90.     any further!
  91.  
  92.     Modified 10/85 to know about "Environment" variables..
  93.     Modified 12/85 for the 'prefix' option
  94.     Modified  2/86 for the new 3.3 flags
  95.     Modified  8/86 (was I supposed to be keeping this up to date?)
  96. **/
  97.  
  98. #include <ctype.h>
  99. #include "headers.h"
  100.  
  101. #ifdef BSD
  102. #undef tolower
  103. #endif
  104.  
  105. extern char *pmalloc();
  106. extern int errno;
  107.  
  108. char  *error_name(), *error_description(), *shift_lower(),
  109.       *strtok(), *getenv(), *strcpy();
  110. void  exit();
  111.  
  112. #define  metachar(c)    (c == '+' || c == '%' || c == '=')
  113.  
  114. #define ASSIGNMENT      0
  115. #define WEEDOUT        1
  116. #define ALTERNATIVES    2
  117.  
  118. read_rc_file()
  119. {
  120.     /** this routine does all the actual work of reading in the
  121.         .rc file... **/
  122.  
  123.     FILE *file;
  124.     char buffer[SLEN], filename[SLEN], *cp, word1[SLEN], word2[SLEN];
  125.     int  i, ch, len,
  126.       rc_has_recvdmail = 0, rc_has_sentmail = 0, lineno = 0, errors = 0;
  127.  
  128.     /* Establish some defaults in case elmrc is incomplete or not there.
  129.      * Defaults for other elmrc options were established in their
  130.      * declaration - in elm.h.  And defaults for sent_mail and recvd_mail
  131.      * are established after the elmrc is read in since these default
  132.      * are based on the folders directory name, which may be given
  133.      * in the emrc.
  134.      * Also establish alternative_editor here since it is based on
  135.      * the default editor and not on the one that might be given in the
  136.      * elmrc.
  137.      */
  138.  
  139.     default_weedlist();
  140.  
  141.     alternative_addresses = NULL;     /* none yet! */
  142.  
  143.     raw_local_signature[0] = raw_remote_signature[0] =
  144.         local_signature[0] = remote_signature[0] = '\0';
  145.         /* no defaults for those */
  146.  
  147.     strcpy(raw_shell,((cp = getenv("SHELL")) == NULL)? default_shell : cp);
  148.     strcpy(shell, raw_shell);
  149.  
  150.     strcpy(raw_pager,((cp = getenv("PAGER")) == NULL)? default_pager : cp);
  151.     strcpy(pager, raw_pager);
  152.  
  153.     strcpy(raw_editor,((cp = getenv("EDITOR")) == NULL)? default_editor:cp);
  154.  
  155. #ifdef OS2
  156.         strcpy(temp_dir, tempdir);
  157. #else
  158.     strcpy(temp_dir,((cp = getenv("TMP")) == NULL)? default_temp:cp);
  159. #endif
  160.     if (temp_dir[strlen (temp_dir)-1] != '/')
  161.                 strcat(temp_dir, "/");
  162.  
  163.     strcpy(alternative_editor, raw_editor);
  164.     strcpy(editor, raw_editor);
  165.  
  166.     strcpy(raw_printout, default_printout);
  167.     strcpy(printout, raw_printout);
  168.  
  169.     sprintf(raw_folders, "%s/%s", home, default_folders);
  170.     strcpy(folders, raw_folders);
  171.  
  172.     sprintf(raw_calendar_file, "%s/%s", home, dflt_calendar_file);
  173.     strcpy(calendar_file, raw_calendar_file);
  174.  
  175.     /* see if the user has a $HOME/.elm directory */
  176.     sprintf(filename, "%s/%s", home, dotelm);
  177.  
  178.     if (access(filename, 00) == -1) {
  179.       if(batch_only)  {
  180.         printf("\n\rNotice:\
  181. \n\rThis version of ELM requires the use of a .elm directory to store your\
  182. \n\relmrc and alias files. I'd like to create the directory .elm for you\
  183. \n\rand set it up, but I can't in \"batch mode\".\
  184. \n\rPlease run ELM in \"normal mode\" first.\n\r");
  185.         exit(0);
  186.       }
  187.  
  188.       printf("\n\rNotice:\
  189. \n\rThis version of ELM requires the use of a .elm directory in your home\
  190. \n\rdirectory to store your elmrc and alias files. Shall I create the\
  191. \n\rdirectory .elm for you and set it up (y/n)? y%c",BACKSPACE);
  192.  
  193.       fflush(stdout);
  194.       ch=getchar();
  195.       if (ch == 'n' || ch == 'N') {
  196.         printf("No.\n\rVery well. I won't create it.\
  197.         \n\rBut, you may run into difficulties later.\n\r");
  198.         sleep(4);
  199.       }
  200.       else {
  201.         printf("Yes.\n\rGreat! I'll do it now.\n\r");
  202.         create_new_elmdir();
  203.       }
  204.     }
  205.  
  206.     /* Look for the elmrc file */
  207.     sprintf(filename,"%s/%s", home, elmrcfile);
  208.  
  209.     if ((file = fopen(filename, "r")) == NULL) {
  210.       dprint(2,(debugfile,"Warning:User has no \".elm/elmrc\" file\n\n"));
  211.  
  212.       /* look for old-style .elmrc file in $HOME */
  213.       sprintf(filename, "%s/%src", home, dotelm);
  214.       if (access(filename, 00) != -1) {
  215.         move_old_files_to_new();
  216.  
  217.         /* try to open elmrc file again */
  218.         sprintf(filename,"%s/%s", home, elmrcfile);
  219.         if((file = fopen(filename, "r")) == NULL) {
  220.           dprint(2, (debugfile,
  221.         "Warning: could not open new \".elm/elmrc\" file.\n"));
  222.           dprint(2, (debugfile, "** %s - %s **\n", error_name(errno),
  223.            error_description(errno)));
  224.           printf("Warning: could not open new \".elm/elmrc\" file!");
  225.           printf(" Using default parameters.\n\r");
  226.           sleep(4);
  227.         }
  228.       }
  229.     }
  230.  
  231.     if(file) {
  232.       int   last = ASSIGNMENT, this;
  233.  
  234.       while (fgets(buffer, SLEN, file) != NULL) {
  235.         lineno++;
  236.         no_ret(buffer);         /* remove return */
  237.         if (buffer[0] == '#'        /* comment       */
  238.          || strlen(buffer) < 2)     /* empty line    */
  239.           continue;
  240.  
  241.         this = ASSIGNMENT;
  242.  
  243.         if(breakup(buffer, word1, word2) == -1)
  244.           continue;        /* word2 is null - let default value stand */
  245.  
  246.         strcpy(word1, shift_lower(word1));    /* to lower case */
  247.  
  248.         if (equal(word1,"maildir") || equal(word1,"folders")) {
  249.           strcpy(raw_folders, word2);
  250.           expand_env(folders, word2);
  251.         }
  252.         else if (equal(word1,"tmpdir")) {
  253.           expand_env(temp_dir, word2);
  254.           if (temp_dir[strlen (temp_dir)-1] != '/')
  255.                 strcat(temp_dir, "/");
  256.         }
  257.         else if (equal(word1, "fullname") || equal(word1,"username") ||
  258.              equal(word1, "name")) {
  259.           strcpy(full_username, word2);
  260.         }
  261.         else if (equal(word1, "prefix")) {
  262.           for (i=0, len = strlen(word2); i < len; i++)
  263.         prefixchars[i] = (word2[i] == '_' ? ' ' : word2[i]);
  264.           prefixchars[i] = '\0';
  265.         }
  266.         else if (equal(word1, "shell")) {
  267.           strcpy(raw_shell, word2);
  268.           expand_env(shell, word2);
  269.         }
  270.         else if (equal(word1, "sort") || equal(word1, "sortby")) {
  271.           strcpy(word2, shift_lower(word2));
  272.           if (equal(word2, "sent"))
  273.          sortby = SENT_DATE;
  274.           else if (equal(word2, "received") || equal(word2,"recieved"))
  275.          sortby = RECEIVED_DATE;
  276.           else if (equal(word2, "from") || equal(word2, "sender"))
  277.          sortby = SENDER;
  278.           else if (equal(word2, "size") || equal(word2, "lines"))
  279.         sortby = SIZE;
  280.           else if (equal(word2, "subject"))
  281.         sortby = SUBJECT;
  282.           else if (equal(word2, "mailbox") || equal(word2, "folder"))
  283.         sortby = MAILBOX_ORDER;
  284.           else if (equal(word2, "status"))
  285.         sortby = STATUS;
  286.           else if (equal(word2, "reverse-sent") || equal(word2,"rev-sent"))
  287.          sortby = - SENT_DATE;
  288.           else if (strncmp(word2, "reverse-rec",11) == 0 ||
  289.                strncmp(word2,"rev-rec",7) == 0)
  290.          sortby = - RECEIVED_DATE;
  291.           else if (equal(word2, "reverse-from") || equal(word2, "rev-from")
  292.             || equal(word2,"reverse-sender")||equal(word2,"rev-sender"))
  293.          sortby = - SENDER;
  294.           else if (equal(word2, "reverse-size") || equal(word2, "rev-size")
  295.             || equal(word2, "reverse-lines")|| equal(word2,"rev-lines"))
  296.         sortby = - SIZE;
  297.           else if (equal(word2, "reverse-subject") ||
  298.                equal(word2, "rev-subject"))
  299.         sortby = - SUBJECT;
  300.           else if (equal(word2, "reverse-mailbox") ||
  301.                equal(word2, "rev-mailbox") ||
  302.                equal(word2, "reverse-folder") ||
  303.                equal(word2, "rev-folder"))
  304.         sortby = - MAILBOX_ORDER;
  305.           else if (equal(word2, "reverse-status") ||
  306.                equal(word2, "rev-status"))
  307.         sortby = - STATUS;
  308.           else {
  309.         errors++;
  310.         printf(
  311.       "I can't understand sort key %s in line %d in your \".elm/elmrc\" file\n",
  312.              word2, lineno);
  313.             continue;
  314.           }
  315.         }
  316.         else if (equal (word1, "receivedmail") || equal(word1, "mailbox")) {
  317.           /* the last is an old name of this option - here for
  318.            * compatibility in case the user has never written out
  319.            * a new elmrc while in elm since the name change.
  320.            */
  321.           rc_has_recvdmail = TRUE;
  322.           strcpy(raw_recvdmail, word2);
  323.           expand_env(recvd_mail, word2);
  324.         }
  325.         else if (equal(word1, "editor") || equal(word1,"mailedit")) {
  326.           strcpy(raw_editor, word2);
  327.           expand_env(editor, word2);
  328.         }
  329.         else if (equal(word1, "sentmail") ||
  330.         equal(word1, "savemail") || equal(word1, "saveto")) {
  331.           /* the last two were old names of this option - here for
  332.            * compatibility in case the user has never written out
  333.            * a new elmrc while in elm since the name change.
  334.            */
  335.           rc_has_sentmail = TRUE;
  336.           strcpy(raw_sentmail, word2);
  337.           expand_env(sent_mail, word2);
  338.         }
  339.         else if (equal(word1, "calendar")) {
  340.           strcpy(raw_calendar_file, word2);
  341.           expand_env(calendar_file, word2);
  342.         }
  343.         else if (equal(word1, "print") || equal(word1, "printmail")) {
  344.           strcpy(raw_printout, word2);
  345.           expand_env(printout, word2);
  346.         }
  347.         else if (equal(word1, "pager") || equal(word1, "page")) {
  348.           strcpy(raw_pager, word2);
  349.           expand_env(pager, word2);
  350.           if (equal(pager,"builtin+") || equal(pager,"internal+"))
  351.         clear_pages++;
  352.         }
  353.         else if (equal(word1, "signature")) {
  354.           if (equal(shift_lower(word2), "on") ||
  355.           equal(shift_lower(word2), "off")) {
  356.         errors++;
  357.         printf(
  358.     "\"signature\" used in obsolete way in .elm/elmrc file. Ignored!\n\r");
  359.         printf(
  360.  "\t(Signature should specify the filename to use rather than on/off.)\n\r\n");
  361.           }
  362.           else {
  363.         strcpy(raw_local_signature, word2);
  364.         strcpy(raw_remote_signature, raw_local_signature);
  365.         expand_env(local_signature, word2);
  366.         strcpy(remote_signature, local_signature);
  367.           }
  368.         }
  369.         else if (equal(word1, "localsignature")) {
  370.           strcpy(raw_local_signature, word2);
  371.           expand_env(local_signature, word2);
  372.         }
  373.         else if (equal(word1, "remotesignature")) {
  374.           strcpy(raw_remote_signature, word2);
  375.           expand_env(remote_signature, word2);
  376.         }
  377.         else if (equal(word1, "sigdashes")) {
  378.           sig_dashes = is_it_on(word2);
  379.         }
  380.         else if (equal(word1, "escape")) {
  381.           escape_char = word2[0];
  382.         }
  383.         else if (equal(word1, "attribution")) {
  384.           strcpy(attribution, word2);
  385.         }
  386.         else if (equal(word1, "autocopy")) {
  387.           auto_copy = is_it_on(word2);
  388.         }
  389.         else if (equal(word1, "copy") || equal(word1, "auto_cc")) {
  390.           auto_cc = is_it_on(word2);
  391.         }
  392.         else if (equal(word1, "names")) {
  393.           names_only = is_it_on(word2);
  394.         }
  395.         else if (equal(word1, "resolve")) {
  396.           resolve_mode = is_it_on(word2);
  397.         }
  398.         else if (equal(word1, "weed")) {
  399.           filter = is_it_on(word2);
  400.         }
  401.         else if (equal(word1, "noheader")) {
  402.           noheader = is_it_on(word2);
  403.         }
  404.         else if (equal(word1, "titles")) {
  405.           title_messages = is_it_on(word2);
  406.         }
  407.         else if (equal(word1, "savebyname") || equal(word1, "savename")) {
  408.           save_by_name = is_it_on(word2);
  409.         }
  410.         else if (equal(word1, "forcename")) {
  411.           force_name = is_it_on(word2);
  412.         }
  413.         else if (equal(word1, "movepage") || equal(word1, "page") ||
  414.              equal(word1, "movewhenpaged")) {
  415.           move_when_paged = is_it_on(word2);
  416.         }
  417.         else if (equal(word1, "pointnew") || equal(word1, "pointtonew")) {
  418.           point_to_new = is_it_on(word2);
  419.         }
  420.         else if (equal(word1, "keypad") || equal(word1, "hpkeypad")) {
  421.           hp_terminal = is_it_on(word2);
  422.         }
  423.         else if (equal(word1, "softkeys") || equal(word1, "hpsoftkeys")) {
  424.           if (hp_softkeys = is_it_on(word2))
  425.         hp_terminal = TRUE;    /* must be set also! */
  426.         }
  427.         else if (equal(word1, "arrow")) {
  428.           arrow_cursor += is_it_on(word2);    /* may have been set already */
  429.         }
  430.         else if (strncmp(word1, "form", 4) == 0) {
  431.           allow_forms = (is_it_on(word2)? MAYBE : NO);
  432.         }
  433.         else if (equal(word1, "promptafter")) {
  434.           prompt_after_pager = is_it_on(word2);
  435.         }
  436.         else if (strncmp(word1, "menu", 4) == 0) {
  437.           /* if not turned off by -m cmd line arg,
  438.            * obey elmrc file setting */
  439.           if(mini_menu)
  440.         mini_menu = is_it_on(word2);
  441.         }
  442.         else if (strncmp(word1, "warning", 7) == 0) {
  443.           warnings = is_it_on(word2);
  444.         }
  445.         else if (equal(word1, "alwaysleave")) {
  446.           /* this is an old option - here for
  447.            * compatibility in case the user has never written out
  448.            * a new elmrc while in elm since the split of
  449.            * alwaysleave into alwayskeep and alwaysstore
  450.            */
  451.           always_keep = is_it_on(word2);
  452.           always_store = !is_it_on(word2);
  453.         }
  454.         else if (equal(word1, "alwayskeep")) {
  455.           always_keep = is_it_on(word2);
  456.         }
  457.         else if (equal(word1, "alwaysstore") || equal(word1, "store")) {
  458.           always_store = is_it_on(word2);
  459.         }
  460.         else if (equal(word1, "alwaysdelete") || equal(word1, "delete")) {
  461.           always_del = is_it_on(word2);
  462.         }
  463.         else if (equal(word1, "askcc") || equal(word1, "cc")) {
  464.           prompt_for_cc = is_it_on(word2);
  465.         }
  466.         else if (equal(word1, "ask") || equal(word1, "question")) {
  467.           question_me = is_it_on(word2);
  468.         }
  469.         else if (equal(word1, "keep") || equal(word1, "keepempty")) {
  470.           keep_empty_files = is_it_on(word2);
  471.         }
  472.         else if (equal(word1, "bounce") || equal(word1, "bounceback")) {
  473.           bounceback = atoi(word2);
  474.           if (bounceback > MAX_HOPS) {
  475.         errors++;
  476.         printf(
  477.     "Warning: bounceback is set to greater than %d (max-hops). Ignored.\n",
  478.              MAX_HOPS);
  479.         bounceback = 0;
  480.           }
  481.         }
  482.         else if (equal(word1, "userlevel")) {
  483.           user_level = atoi(word2);
  484.         }
  485.         else if (equal(word1, "timeout")) {
  486.           timeout = atoi(word2);
  487.           if (timeout < 10) {
  488.         errors++;
  489.         printf(
  490.          "Warning: timeout is set to less than 10 seconds. Ignored.\n");
  491.         timeout = 0;
  492.           }
  493.         }
  494.         else if (equal(word1, "weedout")) {
  495.           weedout(word2);
  496.           this = WEEDOUT;
  497.         }
  498.         else if (equal(word1, "alternatives")) {
  499.           alternatives(word2);
  500.           this = ALTERNATIVES;
  501.         }
  502.         else if (last == WEEDOUT) {
  503.           weedout(buffer);
  504.           this = WEEDOUT;
  505.         }
  506.         else if (last == ALTERNATIVES) {
  507.           alternatives(buffer);
  508.           this = ALTERNATIVES;
  509.         }
  510.         else {
  511.           errors++;
  512.           printf(
  513.          "I can't understand line %d in your \".elm/elmrc\" file:\n> %s\n",
  514.              lineno, buffer);
  515.         }
  516.         last = this;
  517.       }
  518.       /* sleep two seconds for each error and then some so user
  519.        * can read them before screen is cleared */
  520.       if(errors)
  521.         sleep((errors * 2) + 2);
  522.  
  523.           fclose(file);
  524.     }
  525.  
  526.     /* see if the user has a folders directory */
  527.     if (access(folders, 00) == -1) {
  528.       if(batch_only)  {
  529.         printf("\n\rNotice:\
  530. \n\rELM requires the use of a folders directory to store your mail folders in.\
  531. \n\rI'd like to create the directory %s for you,\
  532. \n\rbut I can't in \"batch mode\". Please run ELM in \"normal mode\" first.\
  533. \n\r", folders);
  534.         exit(0);
  535.       }
  536.  
  537.       printf("\n\rNotice:\
  538. \n\rELM requires the use of a folders directory to store your mail folders in.\
  539. \n\rShall I create the directory %s for you (y/n)? y%c", folders, BACKSPACE);
  540.  
  541.       fflush(stdout);
  542.       ch=getchar();
  543.       if (ch == 'n' || ch == 'N') {
  544.         printf("No.\n\rVery well. I won't create it.\
  545.         \n\rBut, you may run into difficulties later.\n\r");
  546.         sleep(4);
  547.       }
  548.       else {
  549.         printf("Yes.\n\rGreat! I'll do it now.\n\r");
  550.         create_new_folders();
  551.       }
  552.     }
  553.  
  554.     /* If recvd_mail or sent_mail havent't yet been established in
  555.      * the elmrc, establish them from their defaults.
  556.      * Then if they begin with a metacharacter, replace it with the
  557.      * folders directory name.
  558.      */
  559.     if(!rc_has_recvdmail) {
  560.       strcpy(raw_recvdmail, default_recvdmail);
  561.       strcpy(recvd_mail, raw_recvdmail);
  562.     }
  563.     if(metachar(recvd_mail[0])) {
  564.       strcpy(buffer, &recvd_mail[1]);
  565.       sprintf(recvd_mail, "%s/%s", folders, buffer);
  566.     }
  567.  
  568.     if(!rc_has_sentmail) {
  569.       sprintf(raw_sentmail, default_sentmail);
  570.       sprintf(sent_mail, default_sentmail);
  571.     }
  572.     if(metachar(sent_mail[0])) {
  573.       strcpy(buffer, &sent_mail[1]);
  574.       sprintf(sent_mail, "%s/%s", folders, buffer);
  575.     }
  576.  
  577.     if (debug > 10)     /** only do this if we REALLY want debug! **/
  578.       dump_rc_results();
  579.  
  580. }
  581.  
  582. weedout(string)
  583. char *string;
  584. {
  585.     /** This routine is called with a list of headers to weed out.   **/
  586.  
  587.     char *strptr, *header;
  588.     register int i, len;
  589.  
  590.     strptr = string;
  591.  
  592.     while ((header = strtok(strptr, "\t ,\"'")) != NULL) {
  593.       if (strlen(header) > 0) {
  594.         if (! strcmp(header, "*end-of-user-headers*")) break;
  595.         if (weedcount > MAX_IN_WEEDLIST) {
  596.           printf("Too many weed headers!  Leaving...\n");
  597.           exit(1);
  598.         }
  599.         if ((weedlist[weedcount] = pmalloc(strlen(header) + 1))
  600.         == NULL) {
  601.           printf("Too many weed headers! Out of memory!  Leaving...\n");
  602.           exit(1);
  603.         }
  604.  
  605.         for (i=0, len = strlen(header); i< len; i++)
  606.           if (header[i] == '_') header[i] = ' ';
  607.  
  608.         strcpy(weedlist[weedcount], header);
  609.         weedcount++;
  610.       }
  611.       strptr = NULL;
  612.     }
  613. }
  614.  
  615. alternatives(string)
  616. char *string;
  617. {
  618.     /** This routine is called with a list of alternative addresses
  619.         that you may receive mail from (forwarded) **/
  620.  
  621.     char *strptr, *address;
  622.     struct addr_rec *current_record, *previous_record;
  623.  
  624.     previous_record = alternative_addresses;    /* start 'er up! */
  625.     /* move to the END of the alternative addresses list */
  626.  
  627.     if (previous_record != NULL)
  628.       while (previous_record->next != NULL)
  629.         previous_record = previous_record->next;
  630.  
  631.     strptr = (char *) string;
  632.  
  633.     while ((address = strtok(strptr, "\t ,\"'")) != NULL) {
  634.       if (previous_record == NULL) {
  635.         previous_record = (struct addr_rec *) pmalloc(sizeof
  636.         *alternative_addresses);
  637.  
  638.         strcpy(previous_record->address, address);
  639.         previous_record->next = NULL;
  640.         alternative_addresses = previous_record;
  641.       }
  642.       else {
  643.         current_record = (struct addr_rec *) pmalloc(sizeof
  644.         *alternative_addresses);
  645.  
  646.         strcpy(current_record->address, address);
  647.         current_record->next = NULL;
  648.         previous_record->next = current_record;
  649.         previous_record = current_record;
  650.       }
  651.       strptr = (char *) NULL;
  652.     }
  653. }
  654.  
  655. default_weedlist()
  656. {
  657.     /** Install the default headers to weed out!  Many gracious
  658.         thanks to John Lebovitz for this dynamic method of
  659.         allocation!
  660.     **/
  661.  
  662.     static char *default_list[] = { ">From", "In-Reply-To:",
  663.                "References:", "Newsgroups:", "Received:",
  664.                "Apparently-To:", "Message-Id:", "Content-Type:",
  665.                "From", "X-Mailer:", "Status:",
  666.                "*end-of-defaults*", NULL
  667.              };
  668.  
  669.     for (weedcount = 0; default_list[weedcount] != (char *) 0;weedcount++){
  670.       if ((weedlist[weedcount] =
  671.           pmalloc(strlen(default_list[weedcount]) + 1)) == NULL) {
  672.         printf("\n\rNot enough memory for default weedlist. Leaving.\n\r");
  673.         leave(1);
  674.       }
  675.       strcpy(weedlist[weedcount], default_list[weedcount]);
  676.     }
  677. }
  678.  
  679. int
  680. matches_weedlist(buffer)
  681. char *buffer;
  682. {
  683.     /** returns true iff the first 'n' characters of 'buffer'
  684.         match an entry of the weedlist **/
  685.  
  686.     register int i;
  687.  
  688.     for (i=0;i < weedcount; i++)
  689.       if (strncmp(buffer, weedlist[i], strlen(weedlist[i])) == 0)
  690.         return(1);
  691.  
  692.     return(0);
  693. }
  694.  
  695. int
  696. breakup(buffer, word1, word2)
  697. char *buffer, *word1, *word2;
  698. {
  699.     /** This routine breaks buffer down into word1, word2 where
  700.         word1 is alpha characters only, and there is an equal
  701.         sign delimiting the two...
  702.         alpha = beta
  703.         For lines with more than one 'rhs', word2 is set to the
  704.         entire string.
  705.         Return -1 if word 2 is of zero length, else 0.
  706.     **/
  707.  
  708.     register int i;
  709.  
  710.     for (i=0;buffer[i] != '\0' && ok_rc_char(buffer[i]); i++)
  711.       if (buffer[i] == '_')
  712.         word1[i] = '-';
  713.       else if (isupper(buffer[i]))
  714.         word1[i] = tolower(buffer[i]);
  715.       else
  716.         word1[i] = buffer[i];
  717.  
  718.     word1[i++] = '\0';    /* that's the first word! */
  719.  
  720.     /** spaces before equal sign? **/
  721.  
  722.     while (whitespace(buffer[i])) i++;
  723.     if (buffer[i] == '=') i++;
  724.  
  725.     /** spaces after equal sign? **/
  726.  
  727.     while (whitespace(buffer[i])) i++;
  728.  
  729.     if (buffer[i] != '\0')
  730.       strcpy(word2, (char *) (buffer + i));
  731.     else
  732.       word2[0] = '\0';
  733.  
  734.     /* remove trailing spaces from word2! */
  735.     i = strlen(word2) - 1;
  736.     while(i && (whitespace(word2[i]) || word2[i] == '\n'))
  737.       word2[i--] = '\0';
  738.  
  739.     return(*word2 == '\0' ? -1 : 0 );
  740.  
  741. }
  742.  
  743. expand_env(dest, buffer)
  744. char *dest, *buffer;
  745. {
  746.     /** expand possible metacharacters in buffer and then copy
  747.         to dest...
  748.  
  749.         BEWARE!! Because strtok() is used on buffer, buffer may be changed.
  750.  
  751.         This routine knows about "~" being the home directory,
  752.         and "$xxx" being an environment variable.
  753.     **/
  754.  
  755.     char  *word, *string, next_word[SLEN];
  756.  
  757.     if (buffer[0] == '/') {
  758.       dest[0] = '/';
  759.       dest[1] = '\0';
  760. /* Added for Apollos - handle //node */
  761.       if (buffer[1] == '/') {
  762.         dest[1] = '/';
  763.         dest[2] = '\0';
  764.       }
  765.     }
  766.     else
  767.       dest[0] = '\0';
  768.  
  769.     string = (char *) buffer;
  770.  
  771.     while ((word = strtok(string, "/")) != NULL) {
  772.       if (word[0] == '$') {
  773.         next_word[0] = '\0';
  774.         if (getenv((char *) (word + 1)) != NULL)
  775.         strcpy(next_word, getenv((char *) (word + 1)));
  776.         if (strlen(next_word) == 0)
  777.           leave(printf("\n\rCan't expand environment variable '%s'.\n\r",
  778.             word));
  779.       }
  780.       else if (word[0] == '~' && word[1] == '\0')
  781.         strcpy(next_word, home);
  782.       else
  783.         strcpy(next_word, word);
  784.  
  785.       sprintf(dest, "%s%s%s", dest,
  786.          (strlen(dest) > 0 && lastch(dest) != '/' ? "/":""),
  787.          next_word);
  788.  
  789.       string = (char *) NULL;
  790.     }
  791. }
  792.  
  793. #define on_off(s)    (s == 1? "ON " : "OFF")
  794. dump_rc_results()
  795. {
  796.  
  797.     register int i, len;
  798.  
  799.     fprintf(debugfile, "folders = %s ", folders);
  800.     fprintf(debugfile, "temp_dir = %s ", temp_dir);
  801.     fprintf(debugfile, "recvd_mail = %s ", recvd_mail);
  802.     fprintf(debugfile, "editor = %s\n", editor);
  803.     fprintf(debugfile, "printout = %s ", printout);
  804.     fprintf(debugfile, "sent_mail = %s ", sent_mail);
  805.     fprintf(debugfile, "calendar_file = %s\n", calendar_file);
  806.     fprintf(debugfile, "prefixchars = %s ", prefixchars);
  807.     fprintf(debugfile, "shell = %s ", shell);
  808.     fprintf(debugfile, "pager = %s\n", pager);
  809.     fprintf(debugfile, "\n");
  810.     fprintf(debugfile, "escape = %c\n", escape_char);
  811.     fprintf(debugfile, "\n");
  812.  
  813.     fprintf(debugfile, "mini_menu    = %s ", on_off(mini_menu));
  814.     fprintf(debugfile, "filter_hdrs  = %s ", on_off(filter));
  815.     fprintf(debugfile, "auto_copy      = %s\n", on_off(auto_copy));
  816.  
  817.     fprintf(debugfile, "resolve_mode   = %s ", on_off(resolve_mode));
  818.     fprintf(debugfile, "auto_save_copy = %s ", on_off(auto_cc));
  819.     fprintf(debugfile, "noheader     = %s\n", on_off(noheader));
  820.  
  821.     fprintf(debugfile, "title_msgs   = %s ", on_off(title_messages));
  822.     fprintf(debugfile, "hp_terminal    = %s ", on_off(hp_terminal));
  823.     fprintf(debugfile, "hp_softkeys    = %s\n", on_off(hp_softkeys));
  824.  
  825.     fprintf(debugfile, "save_by_name = %s ", on_off(save_by_name));
  826.     fprintf(debugfile, "force_name = %s\n", on_off(force_name));
  827.  
  828.     fprintf(debugfile, "move_paged   = %s ", on_off(move_when_paged));
  829.     fprintf(debugfile, "point_to_new   = %s ", on_off(point_to_new));
  830.     fprintf(debugfile, "prompt_after_pager   = %s ",
  831.         on_off(prompt_after_pager));
  832.     fprintf(debugfile, "bounceback     = %s\n", on_off(bounceback));
  833.  
  834.     fprintf(debugfile, "always_keep = %s ", on_off(always_keep));
  835.     fprintf(debugfile, "always_store = %s ", on_off(always_store));
  836.     fprintf(debugfile, "always_delete  = %s ", on_off(always_del));
  837.     fprintf(debugfile, "arrow_cursor   = %s ", on_off(arrow_cursor));
  838.     fprintf(debugfile, "names        = %s\n", on_off(names_only));
  839.  
  840.     fprintf(debugfile, "warnings     = %s ", on_off(warnings));
  841.     fprintf(debugfile, "question_me    = %s ", on_off(question_me));
  842.     fprintf(debugfile, "keep_nil_files = %s\n\n",
  843.                on_off(keep_empty_files));
  844.  
  845.     fprintf(debugfile, "local_signature  = %s\n", local_signature);
  846.     fprintf(debugfile, "remote_signature = %s\n", remote_signature);
  847.     fprintf(debugfile, "sig_dashes = %s\n", on_off(sig_dashes));
  848.  
  849.     fprintf(debugfile, "Userlevel is set to %s user: %d\n",
  850.         user_level == 0 ? "beginning" :
  851.          user_level > 1 ? "expert" : "intermediate", user_level);
  852.  
  853.     fprintf(debugfile, "\nAnd we're skipping the following headers:\n\t");
  854.  
  855.     for (len=8, i=0; i < weedcount; i++) {
  856.       if (weedlist[i][0] == '*') continue;    /* skip '*end-of-defaults*' */
  857.       if (len + strlen(weedlist[i]) > 80) {
  858.         fprintf(debugfile, " \n\t");
  859.         len = 8;
  860.       }
  861.       fprintf(debugfile, "%s  ", weedlist[i]);
  862.       len += strlen(weedlist[i]) + 3;
  863.     }
  864.  
  865.     fprintf(debugfile, "\n\n");
  866. }
  867.  
  868. is_it_on(word)
  869. char *word;
  870. {
  871.     /** Returns TRUE if the specified word is either 'ON', 'YES'
  872.         or 'TRUE', and FALSE otherwise.   We explicitly translate
  873.         to lowercase here to ensure that we have the fastest
  874.         routine possible - we really DON'T want to have this take
  875.         a long time or our startup will be major pain each time.
  876.     **/
  877.  
  878.     static char mybuffer[NLEN];
  879.     register int i, j;
  880.  
  881.     for (i=0, j=0; word[i] != '\0'; i++)
  882.       mybuffer[j++] = isupper(word[i]) ? tolower(word[i]) : word[i];
  883.     mybuffer[j] = '\0';
  884.  
  885.     return(  (strncmp(mybuffer, "on",   2) == 0) ||
  886.          (strncmp(mybuffer, "yes",  3) == 0) ||
  887.          (strncmp(mybuffer, "true", 4) == 0)
  888.           );
  889. }
  890.