date and time created 80/10/08 09:52:12 by kas
[unix-history] / usr / src / usr.bin / 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
13static char *SccsId = "@(#)edit.c 1.1 %G%";
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;
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
194out:
195 signal(SIGINT, sigint);
196 signal(SIGQUIT, sigquit);
197}