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