home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / elm / elm2.4 / lib / mk_aliases.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-08  |  20.0 KB  |  789 lines

  1.  
  2. static char rcsid[] = "@(#)$Id: mk_aliases.c,v 5.12 1993/05/08 20:25:33 syd Exp $";
  3.  
  4. /*******************************************************************************
  5.  *  The Elm Mail System  -  $Revision: 5.12 $   $State: Exp $
  6.  *
  7.  *            Copyright (c) 1988-1992 USENET Community Trust
  8.  *            Copyright (c) 1986,1987 Dave Taylor
  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: mk_aliases.c,v $
  17.  * Revision 5.12  1993/05/08  20:25:33  syd
  18.  * Add sleepmsg to control transient message delays
  19.  * From: Syd
  20.  *
  21.  * Revision 5.11  1993/04/12  01:06:42  syd
  22.  * If I have two aliases of the same name the duplicate is caught *but
  23.  * still written to the data file*!!!
  24.  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
  25.  *
  26.  * Revision 5.10  1993/02/08  01:11:49  syd
  27.  * Make alias names consistently handled as lower case.
  28.  * From: chip@chinacat.unicom.com (Chip Rosenthal)
  29.  *
  30.  * Revision 5.9  1993/01/20  03:37:16  syd
  31.  * Nits and typos in the NLS messages and corresponding default messages.
  32.  * From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
  33.  *
  34.  * Revision 5.8  1993/01/19  04:52:19  syd
  35.  *     add c)hange alias command to alias helpfile
  36.  *     if a deleted alias is changed, undelete it.  Also added the 'N'
  37.  * flag to changed aliases to help remind the user.  Documented it.
  38.  * Note:  if they mark the alias for deletion AFTER making the change it
  39.  * WILL be deleted. (and marked accordingly)
  40.  *     modified alias mode title string to indicate when a resync was
  41.  * needed.
  42.  *     allow editing alias file when none exist.
  43.  *     Now aliases are check for illegal characters (and WS) and
  44.  * addresses are check for illegal WS when they are being entered.  If
  45.  * anything illegal is found and message is printed and they keep entering
  46.  * the item until they get it right.
  47.  *     I fixed a couple of places where int should be long to match
  48.  * the declared type of alias_rec.length
  49.  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
  50.  *
  51.  * Revision 5.7  1993/01/05  17:52:14  syd
  52.  * Add missing quote check to whitespace error check loop
  53.  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
  54.  *
  55.  * Revision 5.6  1992/12/11  02:10:24  syd
  56.  * Make Elm complain about spaces that are not after commas in
  57.  * alias and address lists
  58.  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
  59.  *
  60.  * Revision 5.5  1992/12/11  02:09:06  syd
  61.  * Fix where the user creates a first new alias, then deletes it, the
  62.  * alias stays on screen, but the file really will be empty if it was the
  63.  * last alias, so the retry to delete gives 'cannot open ...file' messages
  64.  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
  65.  *
  66.  * Revision 5.4  1992/11/15  01:15:28  syd
  67.  * The alias message_count isn't set to zero if the last alias has
  68.  * been deleted from the alias table. As no aliases are reread from
  69.  * the aliases database the message_count is left as it was before.
  70.  *
  71.  * Fixed that the function do_newalias() sometimes returns without freeing
  72.  * the buffer allocated before. The patch adds these free calls.
  73.  *
  74.  * When you erroneously type a number in your folder elm asks you for
  75.  * a new current message number. But now if you erase this one number
  76.  * and leave the string empty elm will set the new current message to
  77.  * the second message on our sun4! The patch adds a check for an empty
  78.  * string and returns the current number if no number was entered.
  79.  * From: vogt@isa.de (Gerald Vogt)
  80.  *
  81.  * Revision 5.3  1992/11/07  16:32:14  syd
  82.  * comments should be allowed anywhere in the alias file.
  83.  * From: "Robert L. Howard" <robert.howard@matd.gatech.edu>
  84.  *
  85.  * Revision 5.2  1992/10/11  01:46:35  syd
  86.  * change dbm name to dbz to avoid conflicts with partial call
  87.  * ins from shared librarys, and from mixing code with yp code.
  88.  * From: Syd via prompt from Jess Anderson
  89.  *
  90.  * Revision 5.1  1992/10/03  22:41:36  syd
  91.  * Initial checkin as of 2.4 Release at PL0
  92.  *
  93.  *
  94.  ******************************************************************************/
  95.  
  96. /** Install a new set of aliases for the 'Elm' mailer. 
  97.  
  98.     This code is shared with newalias and elm so that
  99.   it is easier to do updates while in elm.  The main routine
  100.   here is do_newalias().  If the third argument is TRUE then
  101.   we were called from elm.  That means that we will need to 
  102.   sleep() between error messages....  The fourth arguement
  103.   controls whether or not we should warn about missing aliases.text
  104.   files.  For the newalias program that's an error, for elm it's
  105.   ok.  Warning -- this last is a *hack* to get elm2.4b out the
  106.   door -- do_newalias should really return an error value and
  107.   the caller should generate the message.
  108.  
  109. **/
  110.  
  111. #include "headers.h"
  112. #include "s_newalias.h"
  113. #include <ctype.h>
  114. #include "ndbz.h"
  115.  
  116. #ifdef BSD
  117. #  include <sys/file.h>
  118. #  undef tolower
  119. #  undef toupper
  120. #endif
  121.  
  122. #define group(string)        (index(string,',') != NULL)
  123.  
  124. int  buff_loaded;        /* for file input overlap... */
  125. int  err_flag;            /* if errors, don't save!    */
  126. int  al_count;            /* how many aliases so far?  */
  127. char msg_buff[SLEN];        /* buffer for error messages */
  128. DBZ  *aliases_hash;             /* current alias file        */
  129. char *buffer;            /* alias line buffer         */
  130. long buffer_size;        /* size of alias buffer      */
  131. long file_offset = 0;        /* offset into file so far   */
  132.  
  133. extern int  is_system;        /* system file updating?     */
  134.  
  135. #ifdef DEBUG
  136. extern FILE *debugfile;
  137. extern int  debug;
  138. #endif
  139.  
  140. int
  141. get_alias(file, fromelm)
  142. FILE *file;
  143. int fromelm;
  144. {
  145.     /* load buffer with the next complete alias from the file.
  146.        (this can include reading in multiple lines and appending
  147.        them all together!)  Returns EOF after last entry in file.
  148.     
  149.     Lines that start with '#' are assumed to be comments and are
  150.      ignored.  White space as the first field of a line is taken
  151.     to indicate that this line is a continuation of the previous. */
  152.  
  153.     static char mybuffer[LONG_STRING];
  154.     int    done = 0, len;
  155.     char   *s;
  156.  
  157.     /** get the first line of the entry... **/
  158.  
  159.     buffer[0] = '\0';            /* zero out line */
  160.     len = 0;
  161.  
  162.     if (get_line(file, mybuffer, TRUE, fromelm) == -1) 
  163.         return(-1);
  164.     strcpy(buffer, mybuffer);
  165.     len = strlen(buffer);
  166.  
  167.     /** now read in the rest (if there is any!) **/
  168.  
  169.     do {
  170.       if (get_line(file, mybuffer, FALSE, fromelm) == -1) {
  171.           if (err_flag)
  172.               return(-1);
  173.           buff_loaded = 0;    /* force a read next pass! */
  174.           return(0);    /* okay. let's just hand 'buffer' back! */
  175.       }
  176.       done = (! whitespace(mybuffer[0]));
  177.       if (! done) {
  178.           for (s = mybuffer; *s && whitespace(*s); s++) ;
  179.           *--s = ' ';
  180.           len += strlen(s);
  181.           if (len >= buffer_size) {
  182.               sprintf(msg_buff, catgets(elm_msg_cat,
  183.                       NewaliasSet, NewaliasLineToLong,
  184.                   "Line + continuations exceeds maximum length of %ld:"),
  185.                   buffer_size);
  186.               error(msg_buff);
  187.               if (fromelm && sleepmsg > 0)
  188.                   sleep(sleepmsg);
  189.               sprintf(msg_buff, "%.40s", buffer);
  190.               error(msg_buff);
  191.           err_flag++;
  192.           } else
  193.           strcat(buffer, s);
  194.       }
  195.     } while (! done);
  196.     
  197.     return(0);    /* no sweat! */
  198. }
  199.  
  200. int
  201. get_line(file, buffer, first_line, fromelm)
  202. FILE *file;
  203. char *buffer;
  204. int  first_line, fromelm;
  205. {
  206. /*
  207.  *    Read line from file.
  208.  *    If first_line and buff_loaded, then just return!
  209.  *    All comment and blank lines are just ignored (never passed back).
  210.  */
  211.     int len;
  212.  
  213.     if (first_line && buff_loaded) {
  214.       buff_loaded = 1;
  215.       return(0);
  216.     }
  217.  
  218.     buff_loaded = 1;    /* we're going to get SOMETHING in the buffer */
  219.  
  220.     do {
  221.        /*
  222.     * We will just ignore any line that begins with comment (no
  223.     * matter how long).
  224.     */
  225.       do {
  226.         len = mail_gets(buffer, LONG_STRING, file);
  227.       } while (buffer[0] == '#');
  228.  
  229.       if (len > 0) {
  230.         if (buffer[len - 1] != '\n') {
  231.           if (fromelm) {
  232.           error(catgets(elm_msg_cat, NewaliasSet, NewaliasSplitShort,
  233.           "Line too long, split using continuation line format:"));
  234.           if (sleepmsg > 0)
  235.               sleep(sleepmsg);
  236.           sprintf(msg_buff, "%.40s", buffer);
  237.           }
  238.           else {
  239.           sprintf(msg_buff, catgets(elm_msg_cat,
  240.               NewaliasSet, NewaliasSplit,
  241.           "Line too long, split using continuation line format (starting line\nwith whitespace):\n%.40s\n"), buffer);
  242.           }
  243.           error(msg_buff);
  244.           err_flag++;
  245.           return(-1);
  246.         }
  247.       }
  248.       else {
  249.         return(-1);
  250.       }
  251.       no_ret(buffer);
  252. /*
  253.  *    If the buffer is zero length after returns are stripped (and
  254.  *    len was > 0) we need to go ahead and get another line.
  255.  */
  256.     } while (strlen(buffer) == 0);
  257.  
  258.     return(0);
  259. }
  260.  
  261. void
  262. de_escape(the_string)
  263. char *the_string;
  264. {
  265.     register char *s, *out;
  266.  
  267.     for (s = the_string, out = the_string; *s; s++) {
  268.         if (*s != '\\')
  269.         *out++ = *s;
  270.         else
  271.         *out++ = *++s;
  272.     }
  273.     *out = '\0';
  274.  
  275.     return;
  276. }
  277.  
  278. int
  279. add_to_hash_table(word, offset)
  280. char *word;
  281. long  offset;
  282. {
  283.     datum    key, value, ovalue;
  284.     long    off;
  285.     
  286.     key.dptr = word;
  287.     key.dsize = strlen(word);
  288.     off = offset;
  289.     value.dptr = (char *) &off;
  290.     value.dsize = sizeof(off);
  291.  
  292.     ovalue = dbz_fetch(aliases_hash, key);
  293.     if (ovalue.dptr != NULL) {
  294.         sprintf(msg_buff, catgets(elm_msg_cat,
  295.                 NewaliasSet, NewaliasDupAlias,
  296.             "** Duplicate alias '%s' in file.  Multiples ignored."),
  297.         word);
  298.         error(msg_buff);
  299.         return(-1);
  300.     }
  301.  
  302.     if (dbz_store(aliases_hash, key, value) < 0) {
  303.         sprintf(msg_buff, catgets(elm_msg_cat,
  304.                 NewaliasSet, NewaliasErrWrite,
  305.             "** Error writing alias '%s'."), word);
  306.         error(msg_buff);
  307.         err_flag++;
  308.         return(-1);
  309.     }
  310. /*
  311.  *    No probs.  Increment the number of aliases done.
  312.  */
  313.     al_count++;
  314.     return(0);
  315.  
  316. }
  317.  
  318. void
  319. add_to_table(data, aliases, lastn, firstn, comment, addresses)
  320. FILE *data;
  321. register char *aliases, *lastn, *firstn, *comment, *addresses;
  322. {
  323.     struct alias_rec    alias;
  324.     register char    *s;
  325. /*
  326.  *    crack the information into an alias_rec structure, then add the entry
  327.  *    each alias at a time to the dbz file.
  328.  */
  329.     alias.status = 0;
  330.     alias.alias = 0;
  331. /*
  332.  *    loop over each alias in aliases (split at the ,)
  333.  */
  334.     while (aliases != NULL) {
  335.         if ((s = index(aliases, ',')) != NULL)
  336.         *s++ = '\0';
  337.  
  338.         alias.last_name = alias.alias + strlen(aliases) + 1;
  339.         alias.name = alias.last_name + strlen(lastn) + 1;
  340.         alias.comment = alias.name + strlen(lastn) + 1;
  341.         if (firstn)
  342.         alias.comment += strlen(firstn) + 1;
  343.         if (comment)
  344.             alias.address = alias.comment + strlen(comment) + 1;
  345.         else
  346.             alias.address = alias.comment + 1;
  347.         alias.type = is_system ? SYSTEM : USER;
  348.         alias.type |= group(addresses) ? GROUP : PERSON;
  349.         alias.length = ((int) alias.address) + strlen(addresses) + 1;
  350.  
  351.     /*
  352.      *  Convert alias name to lower case for writing to file
  353.      */
  354.         aliases = shift_lower(aliases);
  355.  
  356.     /*
  357.      *  Only add an entry if we could add it to the hash table.
  358.      *  (no errors or duplicates)
  359.      */
  360.         if (add_to_hash_table(aliases, file_offset+sizeof(alias)) == 0) {
  361.             file_offset += alias.length + sizeof(alias);
  362.         /*
  363.          *  Write the entry to the data file, followed by its data
  364.          */
  365.             fwrite((char *)&alias, sizeof(alias), 1, data);
  366.             fwrite(aliases, strlen(aliases) + 1, 1, data);
  367.             fwrite(lastn, strlen(lastn) + 1, 1, data);
  368.             if (firstn) {
  369.             fwrite(firstn, strlen(firstn), 1, data);
  370.             fwrite(" ", 1, 1, data);
  371.             }
  372.             fwrite(lastn, strlen(lastn) + 1, 1, data);
  373.             if (comment)
  374.                 fwrite(comment, strlen(comment) + 1, 1, data);
  375.             else
  376.                 fwrite("\0", 1, 1, data);
  377.             fwrite(addresses, strlen(addresses) + 1, 1, data);
  378.  
  379.             fflush(data);
  380.         }
  381.         aliases = s;
  382.     }
  383.  
  384. }    
  385.  
  386. int
  387. check_alias(aliases)
  388. char *aliases;
  389. {
  390. /*
  391.  *    Check and make sure this is a legal alias.
  392.  */
  393.     register char *s, *out;
  394.     int badws_flg = 0;
  395. /*
  396.  *    First, strip out any whitespace (and make sure it was
  397.  *    legal whitespace).  Legal whitespace follows ','.
  398.  */
  399.     for (s = aliases, out = aliases; *s; s++) {
  400.         if (whitespace(*s)) {
  401.             if (*(out-1) != ',') {
  402.                 badws_flg++;        /* Keep going for now */
  403.             *out++ = *s;
  404.             }
  405.         }
  406.         else {
  407.         *out++ = *s;
  408.         }
  409.     }
  410.     *out = '\0';
  411.  
  412. /*
  413.  *    We have to delay reporting the error until the (legal)
  414.  *    spaces are striped, otherwise aliases is all screwed
  415.  *    up and doesn't display well at all.
  416.  */
  417.     if (badws_flg) {
  418.         sprintf(msg_buff, catgets(elm_msg_cat,
  419.             NewaliasSet, NewaliasAliasWSNotAllowed,
  420.             "Error - whitespace in alias '%.30s' is not allowed."),
  421.             aliases);
  422.         error(msg_buff);
  423.         return(-1);
  424.     }
  425.  
  426. /*
  427.  *    Verify the alias name is valid
  428.  */
  429.     for (s = aliases; *s != '\0' && (ok_alias_char(*s)||*s==','); ++s ) ;
  430.     if ( *s != '\0' ) {
  431.         MCsprintf(msg_buff, catgets(elm_msg_cat,
  432.                 NewaliasSet, NewaliasCharNotSupported,
  433.             "Error - character '%c' in alias '%s' is not supported."),
  434.             *s, aliases);
  435.         error(msg_buff);
  436.         return(-1);
  437.     }
  438.     return(0);
  439. }
  440.  
  441. int
  442. check_address(addresses)
  443. char *addresses;
  444. {
  445.  
  446.     register char *s, *out;
  447.     int in_quote = FALSE;
  448.     int badws_flg = 0;
  449. /*
  450.  *    Now strip out any whitespace (and make sure it was
  451.  *    legal whitespace).  Legal whitespace follows ','.
  452.  *    Don't mess with white space in quotes.
  453.  */
  454.     for (s = addresses, out = addresses; *s; s++) {
  455.         if (*s == '"')
  456.         in_quote = !in_quote;
  457.  
  458.         if (!in_quote && whitespace(*s)) {
  459.             if (*(out-1) == ',') {
  460.                 continue;
  461.             }
  462.             else {
  463.                 badws_flg++;        /* Keep going for now */
  464.             }
  465.         }
  466.         *out++ = *s;
  467.     }
  468.     *out = '\0';
  469.  
  470. /*
  471.  *    We have to delay reporting the error until the (legal)
  472.  *    spaces are striped, otherwise addresses is all screwed
  473.  *    up and doesn't display well at all.
  474.  */
  475.     if (badws_flg) {
  476.         sprintf(msg_buff, catgets(elm_msg_cat,
  477.             NewaliasSet, NewaliasAddressWSNotAllowed,
  478.             "Error - whitespace in address '%.30s' is not allowed."),
  479.             addresses);
  480.         error(msg_buff);
  481.         return(-1);
  482.     }
  483.     return(0);
  484. }
  485.  
  486. void
  487. put_alias(data)
  488. FILE *data;
  489. {
  490. /*
  491.  *    parse the buffer into aliases, names, comments and addresses
  492.  *    and then add the alias
  493.  */
  494.     register char *s, *aliases, *lastn, *firstn, *comment, *addresses;
  495.     int    in_quote = FALSE;
  496.  
  497. /*
  498.  *    extract the alias name, its the part up to the first =, less the
  499.  *    white space on the end.
  500.  */
  501.     aliases = buffer;
  502.     if ((s = index(buffer, '=')) == NULL) {
  503.         sprintf(msg_buff, catgets(elm_msg_cat,
  504.                 NewaliasSet, NewaliasNoFieldSep,
  505.                 "Error - alias \"%.40s\" missing '=' field separator."),
  506.             aliases);
  507.         error(msg_buff);
  508.         err_flag++;
  509.         return;
  510.     }
  511.  
  512.     lastn = s + 1;
  513.     while (--s >= aliases && whitespace(*s) ) ;
  514.     *++s = '\0';
  515.  
  516.     if (check_alias(aliases) == -1) {
  517.         err_flag++;
  518.         return;
  519.     }
  520.     
  521. /*
  522.  *    get the second field into "lastn" - putting stuff after ','
  523.  *    into "comment".  skip over white space after = and before last =
  524.  */
  525.     while (*lastn != '\0' && whitespace(*lastn) )
  526.         lastn++;
  527.  
  528.     for (s = lastn; *s; s++) {
  529.         if (*s == '\\') {
  530.         s++;
  531.         continue;
  532.         }
  533.  
  534.         if (*s == '"')
  535.         in_quote = !in_quote;
  536.  
  537.         if (in_quote)
  538.         continue;
  539.  
  540.         if (*s == '=') {
  541.         addresses = s + 1;
  542.         break;
  543.         }
  544.     }
  545.  
  546.     if (*s != '=') {
  547.         sprintf(msg_buff, catgets(elm_msg_cat,
  548.                 NewaliasSet, NewaliasNoFieldSep,
  549.             "Error - alias \"%.40s\" missing '=' field separator."),
  550.         aliases);
  551.         error(msg_buff);
  552.         err_flag++;
  553.         return;
  554.     }
  555.  
  556. /*
  557.  *    Remove trailing whitespace from second field
  558.  */
  559.     while (--s >= lastn && whitespace(*s) ) ;
  560.     *++s = '\0';
  561. /*
  562.  *    now get anything after a comma (marks comment within name field)
  563.  */
  564.     for (s = lastn, comment = NULL; *s; s++) {
  565.         if (*s == '\\') {
  566.         s++;
  567.         continue;
  568.         }
  569.  
  570.         if (*s == '"')
  571.         in_quote = !in_quote;
  572.  
  573.         if (in_quote)
  574.         continue;
  575.  
  576.         if (*s == ',') {
  577.         comment = s + 1;
  578.         while (--s >= lastn && whitespace(*s) ) ;
  579.             *++s = '\0';        /* Trailing whitespace... */
  580.         break;
  581.         }
  582.     }
  583.  
  584. /*
  585.  *    strip leading whitespace from comment
  586.  */
  587.     if (comment) {
  588.       while (*comment != '\0' && whitespace(*comment) )
  589.         comment++;
  590.     }
  591.  
  592. /*
  593.  *    remainder of line is the addresses, remove leading and
  594.  *    trailing whitespace
  595.  */
  596.     while (*addresses != '\0' && whitespace(*addresses) )
  597.         addresses++;
  598.  
  599.     s = addresses + strlen(addresses);
  600.     while (--s >= addresses && whitespace(*s) ) ;
  601.     *++s = '\0';
  602.  
  603.     if (check_address(addresses) == -1) {
  604.         err_flag++;
  605.         return;
  606.     }
  607.  
  608. /*
  609.  *    split the lastn field into firstn and lastn
  610.  */
  611.     for (s = lastn, firstn = NULL; *s; s++) {
  612.         if (*s == '\\') {
  613.         s++;
  614.         continue;
  615.         }
  616.  
  617.         if (*s == '"')
  618.         in_quote = !in_quote;
  619.  
  620.         if (in_quote)
  621.         continue;
  622.  
  623.         if (*s == ';') {
  624.         firstn = s + 1;
  625.         while (--s >= lastn && whitespace(*s) ) ;
  626.         *++s = '\0';        /* Trailing whitespace... */
  627.         break;
  628.         }
  629.     }
  630.  
  631. /*
  632.  *    strip leading whitespace from firstn
  633.  */
  634.     if (firstn) {
  635.         while (*firstn && whitespace(*firstn))
  636.         firstn++;
  637.     }
  638.  
  639. /*
  640.  *    now remove 'escapes' from name/comment and aliases fields, in place
  641.  */
  642.     de_escape(lastn);
  643.     if (firstn) {
  644.         de_escape(firstn);
  645.     }
  646.     if (comment) {
  647.         de_escape(comment);
  648.     }
  649.     de_escape(addresses);
  650.  
  651.     add_to_table(data, aliases, lastn, firstn, comment, addresses);
  652. }
  653.  
  654. int
  655. do_newalias(inputname, dataname, fromelm, textwarn)
  656. char *inputname, *dataname;
  657. int fromelm, textwarn;
  658. {
  659.     FILE *in, *data;
  660.  
  661. /*
  662.  *    try and allocate a big buffer (larger than a 64k segment...
  663.  *        if it succeeds, mark dbz to run in-core
  664.  *        if not, allocate a smaller buffer
  665.  */
  666.     if ((buffer = malloc(20 * VERY_LONG_STRING)) == NULL) {
  667.         if ((buffer = malloc(2 * VERY_LONG_STRING)) == NULL) {
  668.             error(catgets(elm_msg_cat, NewaliasSet, NewaliasNoAlloc,
  669.                     "Unable to allocate space for alias buffer!"));
  670.             return(-1);
  671.         }
  672.         buffer_size = 2 * VERY_LONG_STRING;
  673.         dbz_incore(FALSE);
  674.     }
  675.     else {
  676.         buffer_size = 20 * VERY_LONG_STRING;
  677.         dbz_incore(TRUE);
  678.     }
  679.  
  680.     if ((in = fopen(inputname,"r")) == NULL) {
  681.         if ( textwarn )
  682.         {
  683.             sprintf(msg_buff, catgets(elm_msg_cat,
  684.                 NewaliasSet, NewaliasNoOpenIn,
  685.                 "Couldn't open %s for input!"), inputname);
  686.         }
  687.         else {
  688.             *msg_buff = '\0';
  689.         }
  690.         error(msg_buff);
  691.         free(buffer);
  692.         return(-1);
  693.     }
  694.  
  695.     if ((aliases_hash = dbz_fresh(dataname, 4999, 0, 0)) == NULL) {
  696.         MCsprintf(msg_buff, catgets(elm_msg_cat,
  697.                 NewaliasSet, NewaliasNoOpendbz,
  698.             "Couldn't open %s.pag or %s.dir for output!"),
  699.             dataname, dataname);
  700.         error(msg_buff);
  701.         free(buffer);
  702.         return(-1);
  703.     }
  704.  
  705.     if ((data = fopen(dataname, "w")) == NULL) {
  706.         sprintf(msg_buff, catgets(elm_msg_cat,
  707.                 NewaliasSet, NewaliasNoOpenOut,
  708.                 "Couldn't open %s for output!"), dataname);
  709.         error(msg_buff);
  710.         free(buffer);
  711.         return(-1);
  712.     }
  713.  
  714.     buff_loaded = 0;     /* file buffer empty right now! */
  715.     al_count = 0;
  716.     err_flag = 0;
  717.  
  718.     while (get_alias(in, fromelm) != -1) {
  719.         put_alias(data);
  720.         if (err_flag) break;
  721.     }
  722.  
  723.     if (err_flag) {
  724.         if (fromelm && sleepmsg > 0)
  725.         sleep(sleepmsg);
  726.         error(catgets(elm_msg_cat, NewaliasSet, NewaliasNoSave,
  727.                 "** Not saving tables!  Please fix and re-run!"));
  728.         free(buffer);
  729.         return(-1);
  730.     }
  731.     else {
  732.         dbz_close(aliases_hash);
  733.         fclose(data);
  734.         fclose(in);
  735.         free(buffer);
  736.     
  737.         if (al_count == 0) {
  738.             delete_alias_files(dataname, fromelm);
  739.         }
  740.  
  741.         return(al_count);
  742.     }
  743.     /*NOTREACHED*/
  744. }
  745.  
  746. delete_alias_files(dataname, fromelm)
  747. char *dataname;
  748. int fromelm;
  749. {
  750. /*
  751.  *    This routine remove all the alias hash and data files.
  752.  *    This is called from do_newalias() when there are no user
  753.  *    aliases to be kept.
  754.  */
  755.  
  756.     char fname[SLEN];
  757.  
  758.     if (unlink(dataname)) {
  759.       sprintf(msg_buff,
  760.         catgets(elm_msg_cat, NewaliasSet, NewaliasCouldntDeleteData,
  761.         "Could not delete alias data file %s!"), fname);
  762.       error(msg_buff);
  763.       if (fromelm && sleepmsg > 0)
  764.         sleep(sleepmsg);
  765.     }
  766.  
  767.     sprintf(fname,"%s.dir", dataname);
  768.     if (unlink(fname)) {
  769.       sprintf(msg_buff,
  770.         catgets(elm_msg_cat, NewaliasSet, NewaliasCouldntDeleteHash,
  771.         "Could not delete alias hash file %s!"), fname);
  772.       error(msg_buff);
  773.       if (fromelm && sleepmsg > 0)
  774.         sleep(sleepmsg);
  775.     }
  776.  
  777.     sprintf(fname,"%s.pag", dataname);
  778.     if (unlink(fname)) {
  779.       sprintf(msg_buff,
  780.         catgets(elm_msg_cat, NewaliasSet, NewaliasCouldntDeleteHash,
  781.         "Could not delete alias hash file %s!"), fname);
  782.       error(msg_buff);
  783.       if (fromelm && sleepmsg > 0)
  784.         sleep(sleepmsg);
  785.     }
  786.  
  787. }
  788.  
  789.