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 2.4 10/21/82"; 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 } 217