1 /* $NetBSD: edit.c,v 1.24 2007/10/29 23:20:38 christos Exp $ */
4 * Copyright (c) 1980, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
35 static char sccsid
[] = "@(#)edit.c 8.1 (Berkeley) 6/6/93";
37 __RCSID("$NetBSD: edit.c,v 1.24 2007/10/29 23:20:38 christos Exp $");
47 * Mail -- a mail program
49 * Perform message editing functions.
53 * Run an editor on the file at "fpp" of "size" bytes,
54 * and return a new file pointer.
55 * Signals must be handled by the caller.
56 * "Editortype" is 'e' for _PATH_EX, 'v' for _PATH_VI.
59 run_editor(FILE *fp
, off_t size
, int editortype
, int readonlyflag
)
65 char tempname
[PATHSIZE
];
68 (void)snprintf(tempname
, sizeof(tempname
),
69 "%s/mail.ReXXXXXXXXXX", tmpdir
);
70 if ((t
= mkstemp(tempname
)) == -1) {
74 if (readonlyflag
&& fchmod(t
, 0400) == -1) {
77 (void)unlink(tempname
);
80 if ((nf
= Fdopen(t
, "w")) == NULL
) {
83 (void)unlink(tempname
);
87 while (--size
>= 0 && (t
= getc(fp
)) != EOF
)
90 while ((t
= getc(fp
)) != EOF
)
96 (void)unlink(tempname
);
100 if (fstat(fileno(nf
), &statb
) < 0)
103 modtime
= statb
.st_mtime
;
104 if (Fclose(nf
) < 0) {
105 warn("%s", tempname
);
106 (void)unlink(tempname
);
111 editcmd
= value(editortype
== 'e' ? ENAME_EDITOR
: ENAME_VISUAL
);
113 editcmd
= editortype
== 'e' ? _PATH_EX
: _PATH_VI
;
114 if (run_command(editcmd
, NULL
, 0, -1, tempname
, NULL
) < 0) {
115 (void)unlink(tempname
);
119 * If in read only mode or file unchanged, just remove the editor
120 * temporary and return.
123 (void)unlink(tempname
);
126 if (stat(tempname
, &statb
) < 0) {
127 warn("%s", tempname
);
130 if (modtime
== statb
.st_mtime
) {
131 (void)unlink(tempname
);
135 * Now switch to new file.
137 if ((nf
= Fopen(tempname
, "a+")) == NULL
) {
138 warn("%s", tempname
);
139 (void)unlink(tempname
);
142 (void)unlink(tempname
);
148 * Edit a message by writing the message into a funnily-named file
149 * (which should not exist) and forking an editor on it.
150 * We get the editor from the stuff above.
153 edit1(int *msgvec
, int editortype
)
163 * Deal with each message to be edited . . .
165 msgCount
= get_msgCount();
166 for (i
= 0; msgvec
[i
] && i
< msgCount
; i
++) {
168 struct sigaction osa
;
174 (void)printf("Edit message %d [ynq]? ", msgvec
[i
]);
175 if (fgets(buf
, (int)sizeof(buf
), stdin
) == 0)
183 dot
= mp
= get_message(msgvec
[i
]);
186 (void)sig_ignore(SIGINT
, &osa
, &oset
);
187 fp
= run_editor(setinput(mp
), mp
->m_size
, editortype
,
190 (void)fseek(otf
, 0L, 2);
192 mp
->m_block
= blockof(size
);
193 mp
->m_offset
= blkoffsetof(size
);
194 mp
->m_size
= fsize(fp
);
197 mp
->m_flag
|= MMODIFY
;
199 while ((c
= getc(fp
)) != EOF
) {
201 * XXX. if you edit a message, we treat
202 * header lines as body lines in the recount.
203 * This is because the original message copy
204 * and the edit reread use different code to
205 * count the lines, and this one here is
212 if (putc(c
, otf
) == EOF
)
219 (void)sig_restore(SIGINT
, &osa
, &oset
);
226 * Edit a message list.
233 return edit1(msgvec
, 'e');
237 * Invoke the visual editor on a message list.
244 return edit1(msgvec
, 'v');