Mercurial > illumos > onarm
comparison usr/src/cmd/mailx/edit.c @ 0:c9caec207d52 b86
Initial porting based on b86
author | Koji Uno <koji.uno@sun.com> |
---|---|
date | Tue, 02 Jun 2009 18:56:50 +0900 |
parents | |
children | 1a15d5aaf794 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c9caec207d52 |
---|---|
1 /* | |
2 * CDDL HEADER START | |
3 * | |
4 * The contents of this file are subject to the terms of the | |
5 * Common Development and Distribution License, Version 1.0 only | |
6 * (the "License"). You may not use this file except in compliance | |
7 * with the License. | |
8 * | |
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | |
10 * or http://www.opensolaris.org/os/licensing. | |
11 * See the License for the specific language governing permissions | |
12 * and limitations under the License. | |
13 * | |
14 * When distributing Covered Code, include this CDDL HEADER in each | |
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. | |
16 * If applicable, add the following below this CDDL HEADER, with the | |
17 * fields enclosed by brackets "[]" replaced with your own identifying | |
18 * information: Portions Copyright [yyyy] [name of copyright owner] | |
19 * | |
20 * CDDL HEADER END | |
21 */ | |
22 /* | |
23 * Copyright 1996 Sun Microsystems, Inc. All rights reserved. | |
24 * Use is subject to license terms. | |
25 */ | |
26 | |
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ | |
28 /* All Rights Reserved */ | |
29 | |
30 | |
31 /* | |
32 * University Copyright- Copyright (c) 1982, 1986, 1988 | |
33 * The Regents of the University of California | |
34 * All Rights Reserved | |
35 * | |
36 * University Acknowledgment- Portions of this document are derived from | |
37 * software developed by the University of California, Berkeley, and its | |
38 * contributors. | |
39 */ | |
40 | |
41 #pragma ident "@(#)edit.c 1.25 05/06/08 SMI" | |
42 | |
43 #include "rcv.h" | |
44 #include <locale.h> | |
45 | |
46 | |
47 /* | |
48 * mailx -- a modified version of a University of California at Berkeley | |
49 * mail program | |
50 * | |
51 * Perform message editing functions. | |
52 */ | |
53 | |
54 static void edit1(int *msgvec, char *ed); | |
55 | |
56 /* | |
57 * Edit a message list. | |
58 */ | |
59 | |
60 int | |
61 editor(int *msgvec) | |
62 { | |
63 char *edname; | |
64 | |
65 if ((edname = value("EDITOR")) == NOSTR || *edname == '\0') | |
66 edname = EDITOR; | |
67 edit1(msgvec, edname); | |
68 return(0); | |
69 } | |
70 | |
71 /* | |
72 * Invoke the visual editor on a message list. | |
73 */ | |
74 | |
75 int | |
76 visual(int *msgvec) | |
77 { | |
78 char *edname; | |
79 | |
80 if ((edname = value("VISUAL")) == NOSTR || *edname == '\0') | |
81 edname = VISUAL; | |
82 edit1(msgvec, edname); | |
83 return(0); | |
84 } | |
85 | |
86 /* | |
87 * Edit a message by writing the message into a funnily-named file | |
88 * (which should not exist) and forking an editor on it. | |
89 * We get the editor from the stuff above. | |
90 */ | |
91 | |
92 static void | |
93 edit1(int *msgvec, char *ed) | |
94 { | |
95 register int c, lastc = '\n'; | |
96 pid_t pid; | |
97 int *ip, mesg, blank = 1; | |
98 long ms, lines; | |
99 void (*sigint)(int), (*sigquit)(int); | |
100 FILE *ibuf, *obuf; | |
101 struct message *mp; | |
102 off_t size; | |
103 struct stat statb; | |
104 long modtime; | |
105 int fd = -1; | |
106 | |
107 /* | |
108 * Set signals; locate editor. | |
109 */ | |
110 | |
111 sigint = sigset(SIGINT, SIG_IGN); | |
112 sigquit = sigset(SIGQUIT, SIG_IGN); | |
113 ed = safeexpand(ed); | |
114 | |
115 /* | |
116 * Deal with each message to be edited . . . | |
117 */ | |
118 | |
119 for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) { | |
120 mesg = *ip; | |
121 touch(mesg); | |
122 mp = &message[mesg-1]; | |
123 dot = mp; | |
124 if (mp->m_text) { | |
125 if (!access(tempZedit, 2)) { | |
126 printf(gettext("%s: file exists\n"), tempZedit); | |
127 goto out; | |
128 } | |
129 | |
130 /* | |
131 * Copy the message into the edit file. | |
132 */ | |
133 | |
134 if ((fd = open(tempZedit, O_RDWR|O_CREAT| | |
135 O_EXCL, 0600)) < 0 || | |
136 (obuf = fdopen(fd, "w")) == NULL) { | |
137 perror(tempZedit); | |
138 goto out; | |
139 } | |
140 if (msend(mp, obuf, 0, fputs) < 0) { | |
141 perror(tempZedit); | |
142 fclose(obuf); | |
143 removefile(tempZedit); | |
144 goto out; | |
145 } | |
146 fflush(obuf); | |
147 if (fferror(obuf)) { | |
148 perror(tempZedit); | |
149 fclose(obuf); | |
150 removefile(tempZedit); | |
151 goto out; | |
152 } | |
153 fclose(obuf); | |
154 | |
155 /* | |
156 * If we are in read only mode, make the | |
157 * temporary message file readonly as well. | |
158 */ | |
159 | |
160 if (readonly) | |
161 chmod(tempZedit, 0400); | |
162 | |
163 /* | |
164 * Fork/execl the editor on the edit file. | |
165 */ | |
166 | |
167 if (stat(tempZedit, &statb) < 0) | |
168 modtime = 0; | |
169 else | |
170 modtime = statb.st_mtime; | |
171 pid = vfork(); | |
172 if (pid == (pid_t)-1) { | |
173 perror("fork"); | |
174 removefile(tempZedit); | |
175 goto out; | |
176 } | |
177 if (pid == 0) { | |
178 sigchild(); | |
179 if (sigint != SIG_IGN) | |
180 sigset(SIGINT, SIG_DFL); | |
181 if (sigquit != SIG_IGN) | |
182 sigset(SIGQUIT, SIG_DFL); | |
183 execlp(ed, ed, tempZedit, (char *)0); | |
184 perror(ed); | |
185 _exit(1); | |
186 } | |
187 while (wait(&mesg) != pid) | |
188 ; | |
189 | |
190 /* | |
191 * If in read only mode, just remove the editor | |
192 * temporary and return. | |
193 */ | |
194 | |
195 if (readonly) { | |
196 removefile(tempZedit); | |
197 continue; | |
198 } | |
199 | |
200 /* | |
201 * Now copy the message to the end of the | |
202 * temp file. | |
203 */ | |
204 | |
205 if (stat(tempZedit, &statb) < 0) { | |
206 perror(tempZedit); | |
207 continue; | |
208 } | |
209 if (modtime == statb.st_mtime) { | |
210 removefile(tempZedit); | |
211 continue; | |
212 } | |
213 if ((ibuf = fopen(tempZedit, "r")) == NULL) { | |
214 perror(tempZedit); | |
215 removefile(tempZedit); | |
216 continue; | |
217 } | |
218 removefile(tempZedit); | |
219 fseek(otf, (long) 0, 2); | |
220 size = fsize(otf); | |
221 mp->m_flag |= MODIFY; | |
222 mp->m_offset = size; | |
223 ms = 0L; | |
224 lines = 0; | |
225 while ((c = getc(ibuf)) != EOF) { | |
226 if (c == '\n') { | |
227 lines++; | |
228 blank = lastc == '\n'; | |
229 } | |
230 lastc = c; | |
231 putc(c, otf); | |
232 if (ferror(otf)) | |
233 break; | |
234 ms++; | |
235 } | |
236 if (!blank) { | |
237 putc('\n', otf); | |
238 ms++; | |
239 lines++; | |
240 } | |
241 mp->m_size = ms; | |
242 mp->m_lines = lines; | |
243 fflush(otf); | |
244 if (fferror(otf)) | |
245 perror("/tmp"); | |
246 fclose(ibuf); | |
247 setclen(mp); | |
248 } else { | |
249 printf("\n%s\n", gettext( | |
250 "*** Message content is not printable: pipe to command or save to a file ***")); | |
251 } | |
252 } | |
253 | |
254 /* | |
255 * Restore signals and return. | |
256 */ | |
257 | |
258 out: | |
259 sigset(SIGINT, sigint); | |
260 sigset(SIGQUIT, sigquit); | |
261 } |