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