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