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: }
Defined functions
edit1
defined in line
49; used 2 times
Defined variables