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