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