home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / metamail / tahoe / edit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-02-18  |  4.1 KB  |  218 lines

  1. /*
  2.  * Copyright (c) 1980 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that this notice is preserved and that due credit is given
  7.  * to the University of California at Berkeley. The name of the University
  8.  * may not be used to endorse or promote products derived from this
  9.  * software without specific prior written permission. This software
  10.  * is provided ``as is'' without express or implied warranty.
  11.  */
  12.  
  13. #ifdef notdef
  14. static char sccsid[] = "@(#)edit.c    5.5 (Berkeley) 2/18/88";
  15. #endif /* notdef */
  16.  
  17. #include "rcv.h"
  18. #include <stdio.h>
  19. #include <sys/stat.h>
  20. #include <sys/wait.h>
  21.  
  22. /*
  23.  * Mail -- a mail program
  24.  *
  25.  * Perform message editing functions.
  26.  */
  27.  
  28. /*
  29.  * Edit a message list.
  30.  */
  31.  
  32. editor(msgvec)
  33.     int *msgvec;
  34. {
  35.     char *edname;
  36.  
  37.     if ((edname = value("EDITOR")) == NOSTR)
  38.         edname = EDITOR;
  39.     return(edit1(msgvec, edname));
  40. }
  41.  
  42. /*
  43.  * Invoke the visual editor on a message list.
  44.  */
  45.  
  46. visual(msgvec)
  47.     int *msgvec;
  48. {
  49.     char *edname;
  50.  
  51.     if ((edname = value("VISUAL")) == NOSTR)
  52.         edname = VISUAL;
  53.     return(edit1(msgvec, edname));
  54. }
  55.  
  56. /*
  57.  * Edit a message by writing the message into a funnily-named file
  58.  * (which should not exist) and forking an editor on it.
  59.  * We get the editor from the stuff above.
  60.  */
  61.  
  62. edit1(msgvec, ed)
  63.     int *msgvec;
  64.     char *ed;
  65. {
  66.     register int c;
  67.     int *ip, pid, mesg;
  68.     int (*sigint)(), (*sigquit)();
  69.     FILE *ibuf, *obuf;
  70.     char edname[15];
  71.     register struct message *mp;
  72.     extern char tempEdit[];
  73.     off_t fsize(), size;
  74.     struct stat statb;
  75.     long modtime;
  76.     union wait status;
  77.  
  78.     /*
  79.      * Set signals; locate editor.
  80.      */
  81.  
  82.     sigint = signal(SIGINT, SIG_IGN);
  83.     sigquit = signal(SIGQUIT, SIG_IGN);
  84.  
  85.     /*
  86.      * Deal with each message to be edited . . .
  87.      */
  88.  
  89.     for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
  90.         mesg = *ip;
  91.         mp = &message[mesg-1];
  92.         mp->m_flag |= MODIFY;
  93.         touch(mesg);
  94.         dot = mp;
  95.  
  96.         /*
  97.          * Make up a name for the edit file of the
  98.          * form "Message%d" and make sure it doesn't
  99.          * already exist.
  100.          */
  101.         (void) sprintf(edname, "Message%d", mesg);
  102.         if (!access(edname, 2)) {
  103.             printf("%s: file exists\n", edname);
  104.             goto out;
  105.         }
  106.  
  107.         /*
  108.          * Copy the message into the edit file.
  109.          */
  110.         (void) close(creat(edname, 0600));
  111.         if ((obuf = fopen(edname, "w")) == NULL) {
  112.             perror(edname);
  113.             goto out;
  114.         }
  115.         if (send(mp, obuf, 0) < 0) {
  116.             perror(edname);
  117.             (void) fclose(obuf);
  118.             (void) remove(edname);
  119.             goto out;
  120.         }
  121.         (void) fflush(obuf);
  122.         if (ferror(obuf)) {
  123.             (void) remove(edname);
  124.             (void) fclose(obuf);
  125.             goto out;
  126.         }
  127.         (void) fclose(obuf);
  128.  
  129.         /*
  130.          * If we are in read only mode, make the
  131.          * temporary message file readonly as well.
  132.          */
  133.  
  134.         if (readonly)
  135.             (void) chmod(edname, 0400);
  136.  
  137.         /*
  138.          * Fork/execl the editor on the edit file.
  139.          */
  140.  
  141.         if (stat(edname, &statb) < 0)
  142.             modtime = 0;
  143.         modtime = statb.st_mtime;
  144.         pid = vfork();
  145.         if (pid == -1) {
  146.             perror("fork");
  147.             (void) remove(edname);
  148.             goto out;
  149.         }
  150.         if (pid == 0) {
  151.             if (sigint != SIG_IGN)
  152.                 (void) signal(SIGINT, SIG_DFL);
  153.             if (sigquit != SIG_IGN)
  154.                 (void) signal(SIGQUIT, SIG_DFL);
  155.             execl(ed, ed, edname, 0);
  156.             perror(ed);
  157.             _exit(1);
  158.         }
  159.         while (wait(&status) != pid)
  160.             ;
  161.  
  162.         /*
  163.          * If in read only mode, just remove the editor
  164.          * temporary and return.
  165.          */
  166.  
  167.         if (readonly) {
  168.             (void) remove(edname);
  169.             continue;
  170.         }
  171.  
  172.         /*
  173.          * Now copy the message to the end of the
  174.          * temp file.
  175.          */
  176.  
  177.         if (stat(edname, &statb) < 0) {
  178.             perror(edname);
  179.             goto out;
  180.         }
  181.         if (modtime == statb.st_mtime) {
  182.             (void) remove(edname);
  183.             goto out;
  184.         }
  185.         if ((ibuf = fopen(edname, "r")) == NULL) {
  186.             perror(edname);
  187.             (void) remove(edname);
  188.             goto out;
  189.         }
  190.         (void) remove(edname);
  191.         (void) fseek(otf, (long) 0, 2);
  192.         size = ftell(otf);
  193.         mp->m_block = blockof(size);
  194.         mp->m_offset = offsetof(size);
  195.         mp->m_size = fsize(ibuf);
  196.         mp->m_lines = 0;
  197.         while ((c = getc(ibuf)) != EOF) {
  198.             if (c == '\n')
  199.                 mp->m_lines++;
  200.             (void) putc(c, otf);
  201.             if (ferror(otf))
  202.                 break;
  203.         }
  204.         if (ferror(otf))
  205.             perror("/tmp");
  206.         (void) fclose(ibuf);
  207.     }
  208.  
  209.     /*
  210.      * Restore signals and return.
  211.      */
  212.  
  213. out:
  214.     (void) signal(SIGINT, sigint);
  215.     (void) signal(SIGQUIT, sigquit);
  216.     return 0;
  217. }
  218.