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