BSD 4_1c_2 release
[unix-history] / usr / src / ucb / Mail / edit.c
CommitLineData
de0c3def
KS
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
e804469b 13static char *SccsId = "@(#)edit.c 2.4 10/21/82";
de0c3def
KS
14
15/*
16 * Edit a message list.
17 */
18
19editor(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
33visual(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
49edit1(msgvec, ed)
50 int *msgvec;
51 char *ed;
52{
53 register char *cp, *cp2;
54 register int c;
55 int *ip, pid, mesg, lines;
0154300b 56 long ms;
de0c3def
KS
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
75a98b9b
KS
70 sigint = sigset(SIGINT, SIG_IGN);
71 sigquit = sigset(SIGQUIT, SIG_IGN);
de0c3def
KS
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 }
184ac060 111 if (send(mp, obuf, 0) < 0) {
de0c3def
KS
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
19f7cf64
KS
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
de0c3def
KS
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) {
34e92c90 147 sigchild();
de0c3def 148 if (sigint != SIG_IGN)
75a98b9b 149 sigsys(SIGINT, SIG_DFL);
de0c3def 150 if (sigquit != SIG_IGN)
75a98b9b 151 sigsys(SIGQUIT, SIG_DFL);
de0c3def
KS
152 execl(ed, ed, edname, 0);
153 perror(ed);
154 _exit(1);
155 }
156 while (wait(&mesg) != pid)
157 ;
158
19f7cf64
KS
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
de0c3def
KS
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);
0154300b 192 ms = 0L;
de0c3def
KS
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
213out:
75a98b9b
KS
214 sigset(SIGINT, sigint);
215 sigset(SIGQUIT, sigquit);
de0c3def 216}