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, with or without
   6:  * modification, are permitted provided that the following conditions
   7:  * are met:
   8:  * 1. Redistributions of source code must retain the above copyright
   9:  *    notice, this list of conditions and the following disclaimer.
  10:  * 2. Redistributions in binary form must reproduce the above copyright
  11:  *    notice, this list of conditions and the following disclaimer in the
  12:  *    documentation and/or other materials provided with the distribution.
  13:  * 3. All advertising materials mentioning features or use of this software
  14:  *    must display the following acknowledgement:
  15:  *	This product includes software developed by the University of
  16:  *	California, Berkeley and its contributors.
  17:  * 4. Neither the name of the University nor the names of its contributors
  18:  *    may be used to endorse or promote products derived from this software
  19:  *    without specific prior written permission.
  20:  *
  21:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31:  * SUCH DAMAGE.
  32:  */
  33: 
  34: #if !defined(lint) && defined(DOSCCS)
  35: static char sccsid[] = "@(#)edit.c	5.15.1 (2.11BSD) 1996/1/27";
  36: #endif
  37: 
  38: #include "rcv.h"
  39: #include <sys/stat.h>
  40: 
  41: /*
  42:  * Mail -- a mail program
  43:  *
  44:  * Perform message editing functions.
  45:  */
  46: 
  47: /*
  48:  * Edit a message list.
  49:  */
  50: 
  51: editor(msgvec)
  52:     int *msgvec;
  53: {
  54: 
  55:     return edit1(msgvec, 'e');
  56: }
  57: 
  58: /*
  59:  * Invoke the visual editor on a message list.
  60:  */
  61: 
  62: visual(msgvec)
  63:     int *msgvec;
  64: {
  65: 
  66:     return edit1(msgvec, 'v');
  67: }
  68: 
  69: /*
  70:  * Edit a message by writing the message into a funnily-named file
  71:  * (which should not exist) and forking an editor on it.
  72:  * We get the editor from the stuff above.
  73:  */
  74: edit1(msgvec, type)
  75:     int *msgvec;
  76:     char type;
  77: {
  78:     register int c;
  79:     int i;
  80:     FILE *fp;
  81:     register struct message *mp;
  82:     off_t size;
  83: 
  84:     /*
  85: 	 * Deal with each message to be edited . . .
  86: 	 */
  87:     for (i = 0; msgvec[i] && i < msgCount; i++) {
  88:         sig_t sigint;
  89: 
  90:         if (i > 0) {
  91:             char buf[100];
  92:             char *p;
  93: 
  94:             printf("Edit message %d [ynq]? ", msgvec[i]);
  95:             if (fgets(buf, sizeof buf, stdin) == 0)
  96:                 break;
  97:             for (p = buf; *p == ' ' || *p == '\t'; p++)
  98:                 ;
  99:             if (*p == 'q')
 100:                 break;
 101:             if (*p == 'n')
 102:                 continue;
 103:         }
 104:         dot = mp = &message[msgvec[i] - 1];
 105:         touch(mp);
 106:         sigint = signal(SIGINT, SIG_IGN);
 107:         fp = run_editor(setinput(mp), mp->m_size, type, readonly);
 108:         if (fp != NULL) {
 109:             (void) fseek(otf, (long) 0, 2);
 110:             size = ftell(otf);
 111:             mp->m_block = blockof(size);
 112:             mp->m_offset = offstof(size);
 113:             mp->m_size = fsize(fp);
 114:             mp->m_lines = 0;
 115:             mp->m_flag |= MODIFY;
 116:             rewind(fp);
 117:             while ((c = getc(fp)) != EOF) {
 118:                 if (c == '\n')
 119:                     mp->m_lines++;
 120:                 if (putc(c, otf) == EOF)
 121:                     break;
 122:             }
 123:             if (ferror(otf))
 124:                 perror("/tmp");
 125:             (void) Fclose(fp);
 126:         }
 127:         (void) signal(SIGINT, sigint);
 128:     }
 129:     return 0;
 130: }
 131: 
 132: /*
 133:  * Run an editor on the file at "fpp" of "size" bytes,
 134:  * and return a new file pointer.
 135:  * Signals must be handled by the caller.
 136:  * "Type" is 'e' for _PATH_EX, 'v' for _PATH_VI.
 137:  */
 138: FILE *
 139: run_editor(fp, size, type, readonly)
 140:     register FILE *fp;
 141:     off_t size;
 142:     char type;
 143: {
 144:     register FILE *nf = NULL;
 145:     register int t;
 146:     time_t modtime;
 147:     char *edit;
 148:     struct stat statb;
 149:     extern char tempEdit[];
 150: 
 151:     if ((t = creat(tempEdit, readonly ? 0400 : 0600)) < 0) {
 152:         perror(tempEdit);
 153:         goto out;
 154:     }
 155:     if ((nf = Fdopen(t, "w")) == NULL) {
 156:         perror(tempEdit);
 157:         (void) unlink(tempEdit);
 158:         goto out;
 159:     }
 160:     if (size >= 0)
 161:         while (--size >= 0 && (t = getc(fp)) != EOF)
 162:             (void) putc(t, nf);
 163:     else
 164:         while ((t = getc(fp)) != EOF)
 165:             (void) putc(t, nf);
 166:     (void) fflush(nf);
 167:     if (fstat(fileno(nf), &statb) < 0)
 168:         modtime = 0;
 169:     else
 170:         modtime = statb.st_mtime;
 171:     if (ferror(nf)) {
 172:         (void) Fclose(nf);
 173:         perror(tempEdit);
 174:         (void) unlink(tempEdit);
 175:         nf = NULL;
 176:         goto out;
 177:     }
 178:     if (Fclose(nf) < 0) {
 179:         perror(tempEdit);
 180:         (void) unlink(tempEdit);
 181:         nf = NULL;
 182:         goto out;
 183:     }
 184:     nf = NULL;
 185:     if ((edit = value(type == 'e' ? "EDITOR" : "VISUAL")) == NOSTR)
 186:         edit = type == 'e' ? _PATH_EX : _PATH_VI;
 187:     if (run_command(edit, 0L, -1, -1, tempEdit, NOSTR) < 0) {
 188:         (void) unlink(tempEdit);
 189:         goto out;
 190:     }
 191:     /*
 192: 	 * If in read only mode or file unchanged, just remove the editor
 193: 	 * temporary and return.
 194: 	 */
 195:     if (readonly) {
 196:         (void) unlink(tempEdit);
 197:         goto out;
 198:     }
 199:     if (stat(tempEdit, &statb) < 0) {
 200:         perror(tempEdit);
 201:         goto out;
 202:     }
 203:     if (modtime == statb.st_mtime) {
 204:         (void) unlink(tempEdit);
 205:         goto out;
 206:     }
 207:     /*
 208: 	 * Now switch to new file.
 209: 	 */
 210:     if ((nf = Fopen(tempEdit, "a+")) == NULL) {
 211:         perror(tempEdit);
 212:         (void) unlink(tempEdit);
 213:         goto out;
 214:     }
 215:     (void) unlink(tempEdit);
 216: out:
 217:     return nf;
 218: }

Defined functions

edit1 defined in line 74; used 2 times
editor defined in line 51; used 2 times
run_editor defined in line 138; used 3 times
visual defined in line 62; used 2 times

Defined variables

sccsid defined in line 35; never used
Last modified: 1996-01-27
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 850
Valid CSS Valid XHTML 1.0 Strict