home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Spezial / SPEZIAL2_97.zip / SPEZIAL2_97.iso / ANWEND / ONLINE / ELM23-2 / ELM23-2.ZIP / src / file.c < prev    next >
C/C++ Source or Header  |  1994-11-05  |  11KB  |  359 lines

  1.  
  2. static char rcsid[] = "@(#)$Id: file.c,v 4.1.1.1 90/10/07 19:48:05 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:    file.c,v $
  17.  * Revision 4.1.1.1  90/10/07  19:48:05  syd
  18.  * fix the bounce problem reported earlier when using MMDF submit as the MTA.
  19.  * From: Jim Clausing <jac%brahms.tinton.ccur.com@RELAY.CS.NET>
  20.  *
  21.  * Revision 4.1  90/04/28  22:43:02  syd
  22.  * checkin of Elm 2.3 as of Release PL0
  23.  *
  24.  *
  25.  ******************************************************************************/
  26.  
  27. /** File I/O routines, mostly the save to file command...
  28.  
  29. **/
  30.  
  31. #ifdef PWDINSYS
  32. #  include <sys/pwd.h>
  33. #else
  34. #  include <pwd.h>
  35. #endif
  36.  
  37. #include "headers.h"
  38. #include <ctype.h>
  39. #include <errno.h>
  40.  
  41. #ifdef BSD
  42. #undef tolower
  43. #endif
  44.  
  45. #ifndef OS2
  46. extern int errno;
  47. #endif
  48.  
  49. char *error_name(), *error_description(), *strcpy(), *getenv(), *nameof();
  50. unsigned long sleep();
  51.  
  52. int
  53. save(redraw, silently, type)
  54. int *redraw, silently, type;
  55. {
  56.     /** Save all tagged messages + current in a folder.  If no messages
  57.         are tagged, save the current message instead!  This routine
  58.         will return ZERO if the operation failed.
  59.         'redraw' is set to TRUE iff we use the '?' and mess up
  60.         the screen.  Pretty reasonable, eh?  If "silently" is set,
  61.         then don't output the "D" character upon marking for
  62.         deletion...
  63.         If delete is set, then delete the saved messages, else
  64.         we are just copying the messages without deletion.
  65.     **/
  66.  
  67.     register int tagged = 0, i, oldstat, appending = 0;
  68.     int mesgnum;    /* message whose address is used for save-by-name fn */
  69.     char filename[SLEN], address[LONG_STRING], buffer[LONG_STRING];
  70.     static char helpmsg[LONG_STRING];
  71.     FILE *save_file;
  72.     int delete = (type != 'C');
  73.     int reverse = (type == 'S');
  74.  
  75.     oldstat = headers[current-1]->status;    /* remember */
  76.     *redraw = FALSE;
  77.  
  78.     for (i=0; i < message_count; i++) {
  79.       if (ison(headers[i]->status, TAGGED)) {
  80.         if(!tagged)
  81.           mesgnum = i;    /* first tagged msg -  use this one for
  82.                  * save-by-name folder name */
  83.         tagged++;
  84.       }
  85.     }
  86.  
  87.     if (tagged == 0) {
  88.       mesgnum = current-1;    /* use this one for save-by-name folder name */
  89.       tagged = 1;
  90.       setit(headers[current-1]->status, TAGGED);
  91.     }
  92.  
  93.     dprint(4, (debugfile, "%d message%s tagged for saving (save)\n", tagged,
  94.         plural(tagged)));
  95.  
  96.     while (1) {
  97.  
  98.       PutLine2(LINES-2, 0, "%s message%s to: ",
  99.           (delete ? "Save" : "Copy"), plural(tagged));
  100.  
  101.       if (save_by_name) {
  102.         /** build default filename to save to **/
  103.         if (reverse) {
  104.           get_existing_address(buffer, mesgnum);
  105.           strcpy(address, strip_parens(buffer));
  106.         } 
  107.         else
  108.           get_return(address, mesgnum);
  109.         get_return_name(address, buffer, TRUE);
  110.         sprintf(filename, "=%s", buffer);
  111.       }
  112.       else
  113.         filename[0] = '\0';
  114.  
  115.       if (tagged > 1)
  116.         optionally_enter(filename, LINES-2, 19, FALSE, FALSE);
  117.       else
  118.         optionally_enter(filename, LINES-2, 18, FALSE, FALSE);
  119.  
  120.  
  121.       if (strlen(filename) == 0) {  /** <return> means 'cancel', right? **/
  122.         headers[current-1]->status = oldstat;    /* BACK! */
  123.         return(0);
  124.       }
  125.  
  126.       if (strcmp(filename,"?") == 0) {    /* user asked for listing */
  127.         *redraw = TRUE;    /* set the flag so we know what to do later */
  128.         if(!*helpmsg) {    /* format helpmsg if not yet done */
  129.  
  130.           strcpy(helpmsg, "\n\r\n\rEnter: <nothing> to not ");
  131.           strcat(helpmsg, (delete ? "save" : "copy"));
  132.           strcat(helpmsg, " your message");
  133.           strcat(helpmsg, (plural(tagged) ? "s" : ""));
  134.           strcat(helpmsg, "\n\r       '>' to ");
  135.           strcat(helpmsg, (delete ? "save" : "copy"));
  136.           strcat(helpmsg, " your message");
  137.           strcat(helpmsg, (plural(tagged) ? "s" : ""));
  138.           strcat(helpmsg, " to your \"received\" folder (");
  139.           strcat(helpmsg, nameof(recvd_mail));
  140.           strcat(helpmsg, ")\n\r       '<' to ");
  141.           strcat(helpmsg, (delete ? "save" : "copy"));
  142.           strcat(helpmsg, " your message");
  143.           strcat(helpmsg, (plural(tagged) ? "s" : ""));
  144.           strcat(helpmsg, " to your \"sent\" folder (");
  145.           strcat(helpmsg, nameof(sent_mail));
  146.           strcat(helpmsg, ") \n\r       a filename");
  147.           strcat(helpmsg, " (leading '=' denotes your folder directory ");
  148.           strcat(helpmsg, folders);
  149.           strcat(helpmsg, ").\n\r");
  150.         }
  151.  
  152.         list_folders(4, helpmsg);
  153.         continue;
  154.       }
  155.  
  156.       /* else - got a folder name - check it out */
  157.       if (! expand_filename(filename, TRUE)) {
  158.         dprint(2, (debugfile,
  159.           "Error: Failed on expansion of filename %s (save)\n",
  160.           filename));
  161.         continue;
  162.       }
  163.       if ((errno = can_open(filename, "a"))) {
  164.         error2("Cannot %s message to folder %s!",
  165.           delete ? "save":"copy", filename);
  166.         continue;
  167.       }
  168.       break;    /* got a valid filename */
  169.     }
  170.  
  171.     save_file_stats(filename);
  172.  
  173.     if (access(filename,ACCESS_EXISTS)== 0)     /* already there!! */
  174.       appending = 1;
  175.  
  176.     dprint(4,(debugfile, "Saving mail to folder '%s'...\n", filename));
  177.  
  178.     if ((save_file = fopen(filename,"a")) == NULL) {
  179.       dprint(2, (debugfile,
  180.         "Error: couldn't append to specified folder %s (save)\n",
  181.         filename));
  182.       error1("Couldn't append to folder %s!", filename);
  183.       headers[current-1]->status = oldstat;    /* BACK! */
  184.       return(0);
  185.     }
  186.  
  187.     /* if we need a redraw that means index screen no longer present
  188.      * so whatever silently was, now it's true - we can't show those
  189.      * delete markings.
  190.      */
  191.     if(*redraw) silently = TRUE;
  192.  
  193.     for (i=0; i < message_count; i++)     /* save each tagged msg */
  194.       if (headers[i]->status & TAGGED)
  195.         save_message(i, filename, save_file, (tagged > 1), appending++,
  196.              silently, delete);
  197.  
  198.     fclose(save_file);
  199.  
  200.     restore_file_stats(filename);
  201.  
  202.     if (tagged > 1)
  203.       error2("Message%s %s.", plural(tagged), delete ? "saved": "copied");
  204.     return(1);
  205. }
  206.  
  207. int
  208. save_message(number, filename, fd, pause, appending, silently, delete)
  209. int number, pause, appending, silently, delete;
  210. char *filename;
  211. FILE *fd;
  212. {
  213.     /** Save an actual message to a folder.  This is called by
  214.         "save()" only!  The parameters are the message number,
  215.         and the name and file descriptor of the folder to save to.
  216.         If 'pause' is true, a sleep(2) will be done after the
  217.         saved message appears on the screen...
  218.         'appending' is only true if the folder already exists
  219.         If 'delete' is true, mark the message for deletion.
  220.     **/
  221.  
  222.     register int save_current, is_new;
  223.  
  224.     dprint(4, (debugfile, "\tSaving message %d to folder...\n", number));
  225.  
  226.     save_current = current;
  227.     current = number+1;
  228.  
  229.     /* change status from NEW before copy and reset to what it was
  230.      * so that copy doesn't look new, but we can preserve new status
  231.      * of message in this mailfile. This is important because if
  232.      * user does a resync, we don't want NEW status to be lost.
  233.      * I.e. NEW becomes UNREAD when we "really" leave a mailfile.
  234.      */
  235.     if(is_new = ison(headers[number]->status, NEW))
  236.       clearit(headers[number]->status, NEW);
  237.       copy_message("", fd, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE);
  238.     if(is_new)
  239.       setit(headers[number]->status, NEW);
  240.     current = save_current;
  241.  
  242.     if (delete)
  243.       setit(headers[number]->status, DELETED); /* deleted, but ...   */
  244.     clearit(headers[number]->status, TAGGED);  /* not tagged anymore */
  245.  
  246.     if (appending)
  247.       error2("Message %d appended to folder %s.", number+1, filename);
  248.     else
  249.       error3("Message %d %s to folder %s.", number+1,
  250.          delete ? "saved" : "copied", filename);
  251.  
  252.     if (! silently)
  253.       show_new_status(number);    /* update screen, if needed */
  254.  
  255.     if (pause && (!silently) && (!appending))
  256.       sleep(2);
  257. }
  258.  
  259. int
  260. expand_filename(filename, use_cursor_control)
  261. char *filename;
  262. int use_cursor_control;
  263. {
  264.     /** Expands    ~/    to the current user's home directory
  265.             ~user/    to the home directory of "user"
  266.             =,+,%    to the user's folder's directory
  267.             !    to the user's incoming mailbox
  268.             >    to the user's received folder
  269.             <    to the user's sent folder
  270.             shell variables (begun with $)
  271.  
  272.         Returns     1    upon proper expansions
  273.             0    upon failed expansions
  274.      **/
  275.  
  276.     char temp_filename[SLEN], varname[SLEN],
  277.         env_value[SLEN], logname[SLEN], *ptr;
  278.     register int iindex;
  279.     struct passwd *pass, *getpwnam();
  280.     char *getenv();
  281.  
  282.     ptr = filename;
  283.     while (*ptr == ' ') ptr++;    /* leading spaces GONE! */
  284.     strcpy(temp_filename, ptr);
  285.  
  286.     /** New stuff - make sure no illegal char as last **/
  287.     if (lastch(temp_filename) == '\n' || lastch(temp_filename) == '\r')
  288.       lastch(temp_filename) = '\0';
  289.  
  290.     /** Strip off any trailing backslashes **/
  291.     while (lastch(temp_filename) == '\\')
  292.         lastch(temp_filename) = '\0';
  293.  
  294.     if (temp_filename[0] == '~') {
  295.       if(temp_filename[1] == '/')
  296.         sprintf(filename, "%s%s%s",
  297.           home, (lastch(home) != '/' ? "/" : ""), &temp_filename[2]);
  298.       else {
  299.         for(ptr = &temp_filename[1], iindex = 0; *ptr && *ptr != '/'; ptr++, iindex++)
  300.           logname[iindex] = *ptr;
  301.         logname[iindex] = '\0';
  302.         if((pass = getpwnam(logname)) == NULL) {
  303.           dprint(3,(debugfile,
  304.               "Error: Can't get home directory for %s (%s)\n",
  305.               logname, "expand_filename"));
  306.           if(use_cursor_control)
  307.         error1("Don't know what the home directory of \"%s\" is!",
  308.             logname);
  309.           else
  310.         printf(
  311.             "\n\rDon't know what the home directory of \"%s\" is!\n\r",
  312.             logname);
  313.           return(0);
  314.         }
  315.         sprintf(filename, "%s%s", pass->pw_dir, ptr);
  316.       }
  317.  
  318.     }
  319.     else if (temp_filename[0] == '=' || temp_filename[0] == '+' ||
  320.           temp_filename[0] == '%') {
  321.       sprintf(filename, "%s%s%s", folders,
  322.         (temp_filename[1] != '/' && lastch(folders) != '/')? "/" : "",
  323.           &temp_filename[1]);
  324.     }
  325.     else if (temp_filename[0] == '$') {    /* env variable! */
  326.       for(ptr = &temp_filename[1], iindex = 0; isalnum(*ptr); ptr++, iindex++)
  327.         varname[iindex] = *ptr;
  328.       varname[iindex] = '\0';
  329.  
  330.       env_value[0] = '\0';            /* null string for strlen! */
  331.       if (getenv(varname) != NULL)
  332.         strcpy(env_value, getenv(varname));
  333.  
  334.       if (strlen(env_value) == 0) {
  335.         dprint(3,(debugfile,
  336.             "Error: Can't expand environment variable $%s (%s)\n",
  337.             varname, "expand_filename"));
  338.         if(use_cursor_control)
  339.           error1("Don't know what the value of $%s is!", varname);
  340.         else
  341.           printf("\n\rDon't know what the value of $%s is!\n\r", varname);
  342.         return(0);
  343.       }
  344.  
  345.       sprintf(filename, "%s%s%s", env_value,
  346.         (*ptr != '/' && lastch(env_value) != '/')? "/" : "", ptr);
  347.  
  348.     } else if (strcmp(temp_filename, "!") == 0) {
  349.       strcpy(filename, defaultfile);
  350.     } else if (strcmp(temp_filename, ">") == 0) {
  351.       strcpy(filename, recvd_mail);
  352.     } else if (strcmp(temp_filename, "<") == 0) {
  353.       strcpy(filename, sent_mail);
  354.     } else
  355.       strcpy(filename, temp_filename);
  356.  
  357.     return(1);
  358. }
  359.