|
|
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 ! 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.