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