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} |