1 # 2 3 #include "rcv.h" 4 #include <stdio.h> 5 #include <sys/stat.h> 6 7 /* 8 * Mail -- a mail program 9 * 10 * Perform message editing functions. 11 */ 12 13 static char *SccsId = "@(#)edit.c 1.1 10/08/80"; 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 unsigned int 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 = signal(SIGINT, SIG_IGN); 71 sigquit = signal(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) { 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 * Fork/execl the editor on the edit file. 127 */ 128 129 if (stat(edname, &statb) < 0) 130 modtime = 0; 131 modtime = statb.st_mtime; 132 pid = vfork(); 133 if (pid == -1) { 134 perror("fork"); 135 remove(edname); 136 goto out; 137 } 138 if (pid == 0) { 139 if (sigint != SIG_IGN) 140 signal(SIGINT, SIG_DFL); 141 if (sigquit != SIG_IGN) 142 signal(SIGQUIT, SIG_DFL); 143 execl(ed, ed, edname, 0); 144 perror(ed); 145 _exit(1); 146 } 147 while (wait(&mesg) != pid) 148 ; 149 150 /* 151 * Now copy the message to the end of the 152 * temp file. 153 */ 154 155 if (stat(edname, &statb) < 0) { 156 perror(edname); 157 goto out; 158 } 159 if (modtime == statb.st_mtime) { 160 remove(edname); 161 goto out; 162 } 163 if ((ibuf = fopen(edname, "r")) == NULL) { 164 perror(edname); 165 remove(edname); 166 goto out; 167 } 168 remove(edname); 169 fseek(otf, (long) 0, 2); 170 size = fsize(otf); 171 mp->m_block = blockof(size); 172 mp->m_offset = offsetof(size); 173 ms = 0; 174 lines = 0; 175 while ((c = getc(ibuf)) != EOF) { 176 if (c == '\n') 177 lines++; 178 putc(c, otf); 179 if (ferror(otf)) 180 break; 181 ms++; 182 } 183 mp->m_size = ms; 184 mp->m_lines = lines; 185 if (ferror(otf)) 186 perror("/tmp"); 187 fclose(ibuf); 188 } 189 190 /* 191 * Restore signals and return. 192 */ 193 194 out: 195 signal(SIGINT, sigint); 196 signal(SIGQUIT, sigquit); 197 } 198