home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mmdf / mmdf-IIb.43 / uip / ucbmail / edit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-06-03  |  4.3 KB  |  249 lines

  1. /*
  2.  *  E D I T . C 
  3.  *
  4.  *  EE/CIS Computer Lab
  5.  *  Department of Computer and Information Sciences
  6.  *  Department of Electrical Engineering
  7.  *  University of Delaware
  8.  *
  9.  *  REVISION HISTORY:
  10.  *
  11.  *  $Revision: 1.3 $
  12.  *
  13.  *  $Log:    edit.c,v $
  14.  * Revision 1.3  85/12/18  13:20:26  galvin
  15.  * Add another argument to send to indicate whether or not this
  16.  * message should be delimited by MMDF message delimiters.
  17.  * 
  18.  * Revision 1.2  85/12/18  03:17:35  galvin
  19.  * Added comment header for revision history.
  20.  * 
  21.  *
  22.  */
  23.  
  24. /*
  25.  * Copyright (c) 1980 Regents of the University of California.
  26.  * All rights reserved.  The Berkeley software License Agreement
  27.  * specifies the terms and conditions for redistribution.
  28.  */
  29.  
  30. #ifndef lint
  31. static char *sccsid = "@(#)edit.c    5.2 (Berkeley) 6/21/85";
  32. #endif not lint
  33.  
  34. #include "./rcv.h"
  35. #include <stdio.h>
  36. #include <sys/stat.h>
  37.  
  38. /*
  39.  * Mail -- a mail program
  40.  *
  41.  * Perform message editing functions.
  42.  */
  43.  
  44. /*
  45.  * Edit a message list.
  46.  */
  47.  
  48. editor(msgvec)
  49.     int *msgvec;
  50. {
  51.     char *edname;
  52.  
  53.     if ((edname = value("EDITOR")) == NOSTR)
  54.         edname = EDITOR;
  55.     return(edit1(msgvec, edname));
  56. }
  57.  
  58. /*
  59.  * Invoke the visual editor on a message list.
  60.  */
  61.  
  62. visual(msgvec)
  63.     int *msgvec;
  64. {
  65.     char *edname;
  66.  
  67.     if ((edname = value("VISUAL")) == NOSTR)
  68.         edname = VISUAL;
  69.     return(edit1(msgvec, edname));
  70. }
  71.  
  72. /*
  73.  * Edit a message by writing the message into a funnily-named file
  74.  * (which should not exist) and forking an editor on it.
  75.  * We get the editor from the stuff above.
  76.  */
  77.  
  78. edit1(msgvec, ed)
  79.     int *msgvec;
  80.     char *ed;
  81. {
  82.     register char *cp, *cp2;
  83.     register int c;
  84.     int *ip, pid, mesg, lines;
  85.     long ms;
  86.     int (*sigint)(), (*sigquit)();
  87.     FILE *ibuf, *obuf;
  88.     char edname[15], nbuf[10];
  89.     struct message *mp;
  90.     off_t fsize(), size;
  91.     struct stat statb;
  92.     long modtime;
  93.  
  94.     /*
  95.      * Set signals; locate editor.
  96.      */
  97.  
  98.     sigint = sigset(SIGINT, SIG_IGN);
  99.     sigquit = sigset(SIGQUIT, SIG_IGN);
  100.  
  101.     /*
  102.      * Deal with each message to be edited . . .
  103.      */
  104.  
  105.     for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
  106.         mesg = *ip;
  107.         mp = &message[mesg-1];
  108.         mp->m_flag |= MODIFY;
  109.  
  110.         /*
  111.          * Make up a name for the edit file of the
  112.          * form "Message%d" and make sure it doesn't
  113.          * already exist.
  114.          */
  115.  
  116.         cp = &nbuf[10];
  117.         *--cp = 0;
  118.         while (mesg) {
  119.             *--cp = mesg % 10 + '0';
  120.             mesg /= 10;
  121.         }
  122.         cp2 = copy("Message", edname);
  123.         while (*cp2++ = *cp++)
  124.             ;
  125.         if (!access(edname, 2)) {
  126.             printf("%s: file exists\n", edname);
  127.             goto out;
  128.         }
  129.  
  130.         /*
  131.          * Copy the message into the edit file.
  132.          */
  133.  
  134.         close(creat(edname, 0600));
  135.         if ((obuf = fopen(edname, "w")) == NULL) {
  136.             perror(edname);
  137.             goto out;
  138.         }
  139.         if (send(mp, obuf, 0, 0) < 0) {
  140.             perror(edname);
  141.             fclose(obuf);
  142.             remove(edname);
  143.             goto out;
  144.         }
  145.         fflush(obuf);
  146.         if (ferror(obuf)) {
  147.             remove(edname);
  148.             fclose(obuf);
  149.             goto out;
  150.         }
  151.         fclose(obuf);
  152.  
  153.         /*
  154.          * If we are in read only mode, make the
  155.          * temporary message file readonly as well.
  156.          */
  157.  
  158.         if (readonly)
  159.             chmod(edname, 0400);
  160.  
  161.         /*
  162.          * Fork/execl the editor on the edit file.
  163.          */
  164.  
  165.         if (stat(edname, &statb) < 0)
  166.             modtime = 0;
  167.         modtime = statb.st_mtime;
  168.         pid = vfork();
  169.         if (pid == -1) {
  170.             perror("fork");
  171.             remove(edname);
  172.             goto out;
  173.         }
  174.         if (pid == 0) {
  175.             sigchild();
  176.             if (sigint != SIG_IGN)
  177.                 sigsys(SIGINT, SIG_DFL);
  178.             if (sigquit != SIG_IGN)
  179.                 sigsys(SIGQUIT, SIG_DFL);
  180.             execl(ed, ed, edname, 0);
  181.             perror(ed);
  182.             _exit(1);
  183.         }
  184.         while (wait(&mesg) != pid)
  185.             ;
  186.  
  187.         /*
  188.          * If in read only mode, just remove the editor
  189.          * temporary and return.
  190.          */
  191.  
  192.         if (readonly) {
  193.             remove(edname);
  194.             continue;
  195.         }
  196.  
  197.         /*
  198.          * Now copy the message to the end of the
  199.          * temp file.
  200.          */
  201.  
  202.         if (stat(edname, &statb) < 0) {
  203.             perror(edname);
  204.             goto out;
  205.         }
  206.         if (modtime == statb.st_mtime) {
  207.             remove(edname);
  208.             goto out;
  209.         }
  210.         if ((ibuf = fopen(edname, "r")) == NULL) {
  211.             perror(edname);
  212.             remove(edname);
  213.             goto out;
  214.         }
  215.         remove(edname);
  216.         fseek(otf, (long) 0, 2);
  217.         size = fsize(otf);
  218.         mp->m_block = blockof(size);
  219.         mp->m_offset = offsetof(size);
  220.         ms = 0L;
  221.         lines = 0;
  222.         while ((c = getc(ibuf)) != EOF) {
  223.             if (c == '\n')
  224.                 lines++;
  225.             putc(c, otf);
  226.             if (ferror(otf))
  227.                 break;
  228.             ms++;
  229.         }
  230.         mp->m_size = ms;
  231.         mp->m_lines = lines;
  232.         if (ferror(otf))
  233.             perror("/tmp");
  234.         fclose(ibuf);
  235.     }
  236.  
  237.     /*
  238.      * Restore signals and return.
  239.      */
  240.     sigset(SIGINT, sigint);
  241.     sigset(SIGQUIT, sigquit);
  242.     return(0);
  243.  
  244. out:
  245.     sigset(SIGINT, sigint);
  246.     sigset(SIGQUIT, sigquit);
  247.     return(-1);
  248. }
  249.