mail.c (814aaaa7da4dab462d90e12e7b48b75f2093ccfd) | mail.c (b4b4b5304bd22eab265c9c049cb7fc6b55c4ef3f) |
---|---|
1/* 2 * Copyright (c) 2008-2014, Simon Schubert <2@0x2c.org>. 3 * Copyright (c) 2008 The DragonFly Project. All rights reserved. 4 * 5 * This code is derived from software contributed to The DragonFly Project 6 * by Simon Schubert <2@0x2c.org>. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 24 unchanged lines hidden (view full) --- 33 * SUCH DAMAGE. 34 */ 35 36#include <errno.h> 37#include <inttypes.h> 38#include <signal.h> 39#include <syslog.h> 40#include <unistd.h> | 1/* 2 * Copyright (c) 2008-2014, Simon Schubert <2@0x2c.org>. 3 * Copyright (c) 2008 The DragonFly Project. All rights reserved. 4 * 5 * This code is derived from software contributed to The DragonFly Project 6 * by Simon Schubert <2@0x2c.org>. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 24 unchanged lines hidden (view full) --- 33 * SUCH DAMAGE. 34 */ 35 36#include <errno.h> 37#include <inttypes.h> 38#include <signal.h> 39#include <syslog.h> 40#include <unistd.h> |
41#include <ctype.h> | |
42 43#include "dma.h" 44 45void 46bounce(struct qitem *it, const char *reason) 47{ 48 struct queue bounceq; 49 char line[1000]; --- 287 unchanged lines hidden (view full) --- 337 errlog(EX_SOFTWARE, "strdup"); 338 339 if (add_recp(queue, addr, EXPAND_WILDCARD) != 0) 340 errlogx(EX_DATAERR, "invalid recipient `%s'", addr); 341 342 goto again; 343} 344 | 41 42#include "dma.h" 43 44void 45bounce(struct qitem *it, const char *reason) 46{ 47 struct queue bounceq; 48 char line[1000]; --- 287 unchanged lines hidden (view full) --- 336 errlog(EX_SOFTWARE, "strdup"); 337 338 if (add_recp(queue, addr, EXPAND_WILDCARD) != 0) 339 errlogx(EX_DATAERR, "invalid recipient `%s'", addr); 340 341 goto again; 342} 343 |
345static int 346writeline(struct queue *queue, const char *line, ssize_t linelen) 347{ 348 ssize_t len; 349 350 while (linelen > 0) { 351 len = linelen; 352 if (linelen > 1000) { 353 len = 990; 354 } 355 if (fwrite(line, len, 1, queue->mailf) != 1) 356 return (-1); 357 if (linelen <= 1000) 358 break; 359 if (fwrite("\n", 1, 1, queue->mailf) != 1) 360 return (-1); 361 line += 990; 362 linelen = strlen(line); 363 } 364 return (0); 365} 366 | |
367int 368readmail(struct queue *queue, int nodot, int recp_from_header) 369{ 370 struct parse_state parse_state; | 344int 345readmail(struct queue *queue, int nodot, int recp_from_header) 346{ 347 struct parse_state parse_state; |
371 char *line = NULL; 372 ssize_t linelen; 373 size_t linecap = 0; 374 char newline[1000]; | 348 char line[1000]; /* by RFC2822 */ 349 size_t linelen; |
375 size_t error; 376 int had_headers = 0; 377 int had_from = 0; 378 int had_messagid = 0; 379 int had_date = 0; | 350 size_t error; 351 int had_headers = 0; 352 int had_from = 0; 353 int had_messagid = 0; 354 int had_date = 0; |
355 int had_last_line = 0; |
|
380 int nocopy = 0; 381 382 parse_state.state = NONE; 383 384 error = fprintf(queue->mailf, 385 "Received: from %s (uid %d)\n" 386 "\t(envelope-from %s)\n" 387 "\tid %s\n" 388 "\tby %s (%s);\n" 389 "\t%s\n", 390 username, useruid, 391 queue->sender, 392 queue->id, 393 hostname(), VERSION, 394 rfc822date()); 395 if ((ssize_t)error < 0) 396 return (-1); 397 398 while (!feof(stdin)) { | 356 int nocopy = 0; 357 358 parse_state.state = NONE; 359 360 error = fprintf(queue->mailf, 361 "Received: from %s (uid %d)\n" 362 "\t(envelope-from %s)\n" 363 "\tid %s\n" 364 "\tby %s (%s);\n" 365 "\t%s\n", 366 username, useruid, 367 queue->sender, 368 queue->id, 369 hostname(), VERSION, 370 rfc822date()); 371 if ((ssize_t)error < 0) 372 return (-1); 373 374 while (!feof(stdin)) { |
399 newline[0] = '\0'; 400 if ((linelen = getline(&line, &linecap, stdin)) <= 0) | 375 if (fgets(line, sizeof(line) - 1, stdin) == NULL) |
401 break; | 376 break; |
377 if (had_last_line) 378 errlogx(EX_DATAERR, "bad mail input format:" 379 " from %s (uid %d) (envelope-from %s)", 380 username, useruid, queue->sender); 381 linelen = strlen(line); 382 if (linelen == 0 || line[linelen - 1] != '\n') { 383 /* 384 * This line did not end with a newline character. 385 * If we fix it, it better be the last line of 386 * the file. 387 */ 388 line[linelen] = '\n'; 389 line[linelen + 1] = 0; 390 had_last_line = 1; 391 } |
|
402 if (!had_headers) { | 392 if (!had_headers) { |
403 if (linelen > 1000) 404 errlogx(EX_DATAERR, "bad mail input format:" 405 " from %s (uid %d) (envelope-from %s)", 406 username, useruid, queue->sender); 407 | |
408 /* 409 * Unless this is a continuation, switch of 410 * the Bcc: nocopy flag. 411 */ 412 if (!(line[0] == ' ' || line[0] == '\t')) 413 nocopy = 0; 414 415 if (strprefixcmp(line, "Date:") == 0) --- 19 unchanged lines hidden (view full) --- 435 parse_state.state = START; 436 if (parse_addrs(&parse_state, line, queue) < 0) { 437 errlogx(EX_DATAERR, "invalid address in header\n"); 438 /* NOTREACHED */ 439 } 440 } 441 } 442 | 393 /* 394 * Unless this is a continuation, switch of 395 * the Bcc: nocopy flag. 396 */ 397 if (!(line[0] == ' ' || line[0] == '\t')) 398 nocopy = 0; 399 400 if (strprefixcmp(line, "Date:") == 0) --- 19 unchanged lines hidden (view full) --- 420 parse_state.state = START; 421 if (parse_addrs(&parse_state, line, queue) < 0) { 422 errlogx(EX_DATAERR, "invalid address in header\n"); 423 /* NOTREACHED */ 424 } 425 } 426 } 427 |
443 if (line[0] == '\n' && !had_headers) { | 428 if (strcmp(line, "\n") == 0 && !had_headers) { |
444 had_headers = 1; 445 while (!had_date || !had_messagid || !had_from) { 446 if (!had_date) { 447 had_date = 1; | 429 had_headers = 1; 430 while (!had_date || !had_messagid || !had_from) { 431 if (!had_date) { 432 had_date = 1; |
448 snprintf(newline, sizeof(newline), "Date: %s\n", rfc822date()); | 433 snprintf(line, sizeof(line), "Date: %s\n", rfc822date()); |
449 } else if (!had_messagid) { 450 /* XXX msgid, assign earlier and log? */ 451 had_messagid = 1; | 434 } else if (!had_messagid) { 435 /* XXX msgid, assign earlier and log? */ 436 had_messagid = 1; |
452 snprintf(newline, sizeof(newline), "Message-Id: <%"PRIxMAX".%s.%"PRIxMAX"@%s>\n", | 437 snprintf(line, sizeof(line), "Message-Id: <%"PRIxMAX".%s.%"PRIxMAX"@%s>\n", |
453 (uintmax_t)time(NULL), 454 queue->id, 455 (uintmax_t)random(), 456 hostname()); 457 } else if (!had_from) { 458 had_from = 1; | 438 (uintmax_t)time(NULL), 439 queue->id, 440 (uintmax_t)random(), 441 hostname()); 442 } else if (!had_from) { 443 had_from = 1; |
459 snprintf(newline, sizeof(newline), "From: <%s>\n", queue->sender); | 444 snprintf(line, sizeof(line), "From: <%s>\n", queue->sender); |
460 } | 445 } |
461 if (fwrite(newline, strlen(newline), 1, queue->mailf) != 1) 462 goto fail; | 446 if (fwrite(line, strlen(line), 1, queue->mailf) != 1) 447 return (-1); |
463 } | 448 } |
464 strlcpy(newline, "\n", sizeof(newline)); | 449 strcpy(line, "\n"); |
465 } 466 if (!nodot && linelen == 2 && line[0] == '.') 467 break; 468 if (!nocopy) { | 450 } 451 if (!nodot && linelen == 2 && line[0] == '.') 452 break; 453 if (!nocopy) { |
469 if (newline[0] != '\0') { 470 if (fwrite(newline, strlen(newline), 1, queue->mailf) != 1) 471 goto fail; 472 } else { 473 if (writeline(queue, line, linelen) != 0) 474 goto fail; 475 } | 454 if (fwrite(line, strlen(line), 1, queue->mailf) != 1) 455 return (-1); |
476 } 477 } 478 479 return (0); | 456 } 457 } 458 459 return (0); |
480fail: 481 free(line); 482 return (-1); | |
483} | 460} |