Deleted Added
full compact
fio.c (67496) fio.c (74769)
1/*
2 * Copyright (c) 1980, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 16 unchanged lines hidden (view full) ---

25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
1/*
2 * Copyright (c) 1980, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 16 unchanged lines hidden (view full) ---

25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * $FreeBSD: head/usr.bin/mail/fio.c 67496 2000-10-24 13:54:31Z phk $
33 * $FreeBSD: head/usr.bin/mail/fio.c 74769 2001-03-25 04:57:05Z mikeh $
34 */
35
36#ifndef lint
34 */
35
36#ifndef lint
37#if 0
37static char sccsid[] = "@(#)fio.c 8.1 (Berkeley) 6/6/93";
38static char sccsid[] = "@(#)fio.c 8.1 (Berkeley) 6/6/93";
39#endif
40static const char rcsid[] =
41 "$FreeBSD: head/usr.bin/mail/fio.c 74769 2001-03-25 04:57:05Z mikeh $";
38#endif /* not lint */
39
40#include "rcv.h"
41#include <sys/file.h>
42#include <sys/wait.h>
43
44#include <unistd.h>
45#include <paths.h>

--- 8 unchanged lines hidden (view full) ---

54
55/*
56 * Set up the input pointers while copying the mail file into /tmp.
57 */
58void
59setptr(ibuf)
60 register FILE *ibuf;
61{
42#endif /* not lint */
43
44#include "rcv.h"
45#include <sys/file.h>
46#include <sys/wait.h>
47
48#include <unistd.h>
49#include <paths.h>

--- 8 unchanged lines hidden (view full) ---

58
59/*
60 * Set up the input pointers while copying the mail file into /tmp.
61 */
62void
63setptr(ibuf)
64 register FILE *ibuf;
65{
62 extern char *tmpdir;
63 register int c, count;
64 register char *cp, *cp2;
65 struct message this;
66 FILE *mestmp;
67 off_t offset;
68 int maybe, inhead;
66 register int c, count;
67 register char *cp, *cp2;
68 struct message this;
69 FILE *mestmp;
70 off_t offset;
71 int maybe, inhead;
69 char linebuf[LINESIZE];
72 char linebuf[LINESIZE], pathbuf[PATHSIZE];
70
71 /* Get temporary file. */
73
74 /* Get temporary file. */
72 (void)sprintf(linebuf, "%s/mail.XXXXXX", tmpdir);
73 if ((c = mkstemp(linebuf)) == -1 ||
74 (mestmp = Fdopen(c, "r+")) == NULL) {
75 errx(1, "can't open %s", linebuf);
76 }
77 (void)unlink(linebuf);
75 (void)snprintf(pathbuf, sizeof(pathbuf), "%s/mail.XXXXXXXXXX", tmpdir);
76 if ((c = mkstemp(pathbuf)) == -1 || (mestmp = Fdopen(c, "r+")) == NULL)
77 err(1, "can't open %s", pathbuf);
78 (void) rm(pathbuf);
78
79 msgCount = 0;
80 maybe = 1;
81 inhead = 0;
82 offset = 0;
83 this.m_flag = MUSED|MNEW;
84 this.m_size = 0;
85 this.m_lines = 0;
86 this.m_block = 0;
87 this.m_offset = 0;
88 for (;;) {
79
80 msgCount = 0;
81 maybe = 1;
82 inhead = 0;
83 offset = 0;
84 this.m_flag = MUSED|MNEW;
85 this.m_size = 0;
86 this.m_lines = 0;
87 this.m_block = 0;
88 this.m_offset = 0;
89 for (;;) {
89 if (fgets(linebuf, LINESIZE, ibuf) == NULL) {
90 if (append(&this, mestmp)) {
91 perror("temporary file");
92 exit(1);
93 }
90 if (fgets(linebuf, sizeof(linebuf), ibuf) == NULL) {
91 if (append(&this, mestmp))
92 errx(1, "temporary file");
94 makemessage(mestmp);
95 return;
96 }
97 count = strlen(linebuf);
98 (void) fwrite(linebuf, sizeof *linebuf, count, otf);
93 makemessage(mestmp);
94 return;
95 }
96 count = strlen(linebuf);
97 (void) fwrite(linebuf, sizeof *linebuf, count, otf);
99 if (ferror(otf)) {
100 perror("/tmp");
101 exit(1);
102 }
103 linebuf[count - 1] = 0;
98 if (ferror(otf))
99 errx(1, "/tmp");
100 if (count)
101 linebuf[count - 1] = '\0';
104 if (maybe && linebuf[0] == 'F' && ishead(linebuf)) {
105 msgCount++;
102 if (maybe && linebuf[0] == 'F' && ishead(linebuf)) {
103 msgCount++;
106 if (append(&this, mestmp)) {
107 perror("temporary file");
108 exit(1);
109 }
104 if (append(&this, mestmp))
105 errx(1, "temporary file");
110 this.m_flag = MUSED|MNEW;
111 this.m_size = 0;
112 this.m_lines = 0;
113 this.m_block = blockof(offset);
114 this.m_offset = boffsetof(offset);
115 inhead = 1;
116 } else if (linebuf[0] == 0) {
117 inhead = 0;

--- 70 unchanged lines hidden (view full) ---

188 * passed message pointer.
189 */
190FILE *
191setinput(mp)
192 register struct message *mp;
193{
194
195 fflush(otf);
106 this.m_flag = MUSED|MNEW;
107 this.m_size = 0;
108 this.m_lines = 0;
109 this.m_block = blockof(offset);
110 this.m_offset = boffsetof(offset);
111 inhead = 1;
112 } else if (linebuf[0] == 0) {
113 inhead = 0;

--- 70 unchanged lines hidden (view full) ---

184 * passed message pointer.
185 */
186FILE *
187setinput(mp)
188 register struct message *mp;
189{
190
191 fflush(otf);
196 if (fseek(itf, (long)positionof(mp->m_block, mp->m_offset), 0) < 0) {
197 perror("fseek");
198 panic("Temporary file seek");
199 }
192 if (fseek(itf, (long)positionof(mp->m_block, mp->m_offset), 0) < 0)
193 err(1, "fseek");
200 return (itf);
201}
202
203/*
204 * Take the data out of the passed ghost file and toss it into
205 * a dynamically allocated message structure.
206 */
207void
208makemessage(f)
209 FILE *f;
210{
211 register size = (msgCount + 1) * sizeof (struct message);
212
213 if (message != 0)
214 free((char *) message);
215 if ((message = (struct message *) malloc((unsigned) size)) == 0)
194 return (itf);
195}
196
197/*
198 * Take the data out of the passed ghost file and toss it into
199 * a dynamically allocated message structure.
200 */
201void
202makemessage(f)
203 FILE *f;
204{
205 register size = (msgCount + 1) * sizeof (struct message);
206
207 if (message != 0)
208 free((char *) message);
209 if ((message = (struct message *) malloc((unsigned) size)) == 0)
216 panic("Insufficient memory for %d messages", msgCount);
210 err(1, "Out of memory");
217 dot = message;
218 size -= sizeof (struct message);
219 fflush(f);
220 (void) lseek(fileno(f), (off_t)sizeof *message, 0);
221 if (read(fileno(f), (char *) message, size) != size)
211 dot = message;
212 size -= sizeof (struct message);
213 fflush(f);
214 (void) lseek(fileno(f), (off_t)sizeof *message, 0);
215 if (read(fileno(f), (char *) message, size) != size)
222 panic("Message temporary file corrupted");
216 errx(1, "Message temporary file corrupted");
223 message[msgCount].m_size = 0;
224 message[msgCount].m_lines = 0;
225 Fclose(f);
226}
227
228/*
229 * Append the passed message descriptor onto the temp file.
230 * If the write fails, return 1, else 0

--- 79 unchanged lines hidden (view full) ---

310 register char *name;
311{
312 char xname[PATHSIZE];
313 char cmdbuf[PATHSIZE]; /* also used for file names */
314 register int pid, l;
315 register char *cp, *shell;
316 int pivec[2];
317 struct stat sbuf;
217 message[msgCount].m_size = 0;
218 message[msgCount].m_lines = 0;
219 Fclose(f);
220}
221
222/*
223 * Append the passed message descriptor onto the temp file.
224 * If the write fails, return 1, else 0

--- 79 unchanged lines hidden (view full) ---

304 register char *name;
305{
306 char xname[PATHSIZE];
307 char cmdbuf[PATHSIZE]; /* also used for file names */
308 register int pid, l;
309 register char *cp, *shell;
310 int pivec[2];
311 struct stat sbuf;
318 extern union wait wait_status;
312 extern int wait_status;
319
320 /*
321 * The order of evaluation is "%" and "#" expand into constants.
322 * "&" can expand into "+". "+" can expand into shell meta characters.
323 * Shell meta characters expand into constants.
324 * This way, we make no recursive expansion.
325 */
326 switch (*name) {
327 case '%':
313
314 /*
315 * The order of evaluation is "%" and "#" expand into constants.
316 * "&" can expand into "+". "+" can expand into shell meta characters.
317 * Shell meta characters expand into constants.
318 * This way, we make no recursive expansion.
319 */
320 switch (*name) {
321 case '%':
328 findmail(name[1] ? name + 1 : myname, xname);
322 findmail(name[1] ? name + 1 : myname, xname, sizeof(xname));
329 return savestr(xname);
330 case '#':
331 if (name[1] != 0)
332 break;
333 if (prevfile[0] == 0) {
334 printf("No previous file\n");
335 return NOSTR;
336 }
337 return savestr(prevfile);
338 case '&':
339 if (name[1] == 0 && (name = value("MBOX")) == NOSTR)
340 name = "~/mbox";
341 /* fall through */
342 }
323 return savestr(xname);
324 case '#':
325 if (name[1] != 0)
326 break;
327 if (prevfile[0] == 0) {
328 printf("No previous file\n");
329 return NOSTR;
330 }
331 return savestr(prevfile);
332 case '&':
333 if (name[1] == 0 && (name = value("MBOX")) == NOSTR)
334 name = "~/mbox";
335 /* fall through */
336 }
343 if (name[0] == '+' && getfold(cmdbuf) >= 0) {
344 sprintf(xname, "%s/%s", cmdbuf, name + 1);
337 if (name[0] == '+' && getfold(cmdbuf, sizeof(cmdbuf)) >= 0) {
338 snprintf(xname, sizeof(xname), "%s/%s", cmdbuf, name + 1);
345 name = savestr(xname);
346 }
347 /* catch the most common shell meta character */
339 name = savestr(xname);
340 }
341 /* catch the most common shell meta character */
348 if (name[0] == '~' && (name[1] == '/' || name[1] == '\0')) {
349 sprintf(xname, "%s%s", homedir, name + 1);
342 if (name[0] == '~' && homedir != NULL &&
343 (name[1] == '/' || name[1] == '\0')) {
344 snprintf(xname, sizeof(xname), "%s%s", homedir, name + 1);
350 name = savestr(xname);
351 }
345 name = savestr(xname);
346 }
352 if (!anyof(name, "~{[*?$`'\"\\"))
347 if (!strpbrk(name, "~{[*?$`'\"\\"))
353 return name;
354 if (pipe(pivec) < 0) {
348 return name;
349 if (pipe(pivec) < 0) {
355 perror("pipe");
350 warn("pipe");
356 return name;
357 }
351 return name;
352 }
358 sprintf(cmdbuf, "echo %s", name);
353 snprintf(cmdbuf, sizeof(cmdbuf), "echo %s", name);
359 if ((shell = value("SHELL")) == NOSTR)
360 shell = _PATH_CSHELL;
361 pid = start_command(shell, 0, -1, pivec[1], "-c", cmdbuf, NOSTR);
362 if (pid < 0) {
363 close(pivec[0]);
364 close(pivec[1]);
365 return NOSTR;
366 }
367 close(pivec[1]);
368 l = read(pivec[0], xname, BUFSIZ);
369 close(pivec[0]);
354 if ((shell = value("SHELL")) == NOSTR)
355 shell = _PATH_CSHELL;
356 pid = start_command(shell, 0, -1, pivec[1], "-c", cmdbuf, NOSTR);
357 if (pid < 0) {
358 close(pivec[0]);
359 close(pivec[1]);
360 return NOSTR;
361 }
362 close(pivec[1]);
363 l = read(pivec[0], xname, BUFSIZ);
364 close(pivec[0]);
370 if (wait_child(pid) < 0 && wait_status.w_termsig != SIGPIPE) {
365 if (wait_child(pid) < 0 && WIFSIGNALED(wait_status) && WTERMSIG(wait_status) != SIGPIPE) {
371 fprintf(stderr, "\"%s\": Expansion failed.\n", name);
372 return NOSTR;
373 }
374 if (l < 0) {
366 fprintf(stderr, "\"%s\": Expansion failed.\n", name);
367 return NOSTR;
368 }
369 if (l < 0) {
375 perror("read");
370 warn("read");
376 return NOSTR;
377 }
378 if (l == 0) {
379 fprintf(stderr, "\"%s\": No match.\n", name);
380 return NOSTR;
381 }
382 if (l == BUFSIZ) {
383 fprintf(stderr, "\"%s\": Expansion buffer overflow.\n", name);
384 return NOSTR;
385 }
371 return NOSTR;
372 }
373 if (l == 0) {
374 fprintf(stderr, "\"%s\": No match.\n", name);
375 return NOSTR;
376 }
377 if (l == BUFSIZ) {
378 fprintf(stderr, "\"%s\": Expansion buffer overflow.\n", name);
379 return NOSTR;
380 }
386 xname[l] = 0;
381 xname[l] = '\0';
387 for (cp = &xname[l-1]; *cp == '\n' && cp > xname; cp--)
388 ;
389 cp[1] = '\0';
382 for (cp = &xname[l-1]; *cp == '\n' && cp > xname; cp--)
383 ;
384 cp[1] = '\0';
390 if (index(xname, ' ') && stat(xname, &sbuf) < 0) {
385 if (strchr(xname, ' ') && stat(xname, &sbuf) < 0) {
391 fprintf(stderr, "\"%s\": Ambiguous.\n", name);
392 return NOSTR;
393 }
394 return savestr(xname);
395}
396
397/*
398 * Determine the current folder directory name.
399 */
400int
386 fprintf(stderr, "\"%s\": Ambiguous.\n", name);
387 return NOSTR;
388 }
389 return savestr(xname);
390}
391
392/*
393 * Determine the current folder directory name.
394 */
395int
401getfold(name)
396getfold(name, namelen)
402 char *name;
397 char *name;
398 int namelen;
403{
404 char *folder;
399{
400 char *folder;
401 int copylen;
405
406 if ((folder = value("folder")) == NOSTR)
407 return (-1);
408 if (*folder == '/')
402
403 if ((folder = value("folder")) == NOSTR)
404 return (-1);
405 if (*folder == '/')
409 strcpy(name, folder);
406 copylen = strlcpy(name, folder, namelen);
410 else
407 else
411 sprintf(name, "%s/%s", homedir, folder);
412 return (0);
408 copylen = snprintf(name, namelen, "%s/%s", homedir ? homedir : ".", folder);
409 return copylen >= namelen ? (-1) : (0);
413}
414
415/*
416 * Return the name of the dead.letter file.
417 */
418char *
419getdeadletter()
420{
421 register char *cp;
422
423 if ((cp = value("DEAD")) == NOSTR || (cp = expand(cp)) == NOSTR)
424 cp = expand("~/dead.letter");
425 else if (*cp != '/') {
426 char buf[PATHSIZE];
427
410}
411
412/*
413 * Return the name of the dead.letter file.
414 */
415char *
416getdeadletter()
417{
418 register char *cp;
419
420 if ((cp = value("DEAD")) == NOSTR || (cp = expand(cp)) == NOSTR)
421 cp = expand("~/dead.letter");
422 else if (*cp != '/') {
423 char buf[PATHSIZE];
424
428 (void) sprintf(buf, "~/%s", cp);
425 (void) snprintf(buf, sizeof(buf), "~/%s", cp);
429 cp = expand(buf);
430 }
431 return cp;
432}
426 cp = expand(buf);
427 }
428 return cp;
429}