dma.c (6cec9cad762b6476313fb1f8e931a1647822db6b) | dma.c (e56bad4a94aff7e3e43200568b211de872a52aea) |
---|---|
1/* | 1/* |
2 * Copyright (c) 2008-2014, Simon Schubert <2@0x2c.org>. |
|
2 * Copyright (c) 2008 The DragonFly Project. All rights reserved. 3 * 4 * This code is derived from software contributed to The DragonFly Project | 3 * Copyright (c) 2008 The DragonFly Project. All rights reserved. 4 * 5 * This code is derived from software contributed to The DragonFly Project |
5 * by Simon 'corecode' Schubert <corecode@fs.ei.tum.de>. | 6 * by Simon Schubert <2@0x2c.org>. |
6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright --- 228 unchanged lines hidden (view full) --- 242go_background(struct queue *queue) 243{ 244 struct sigaction sa; 245 struct qitem *it; 246 pid_t pid; 247 248 if (daemonize && daemon(0, 0) != 0) { 249 syslog(LOG_ERR, "can not daemonize: %m"); | 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright --- 228 unchanged lines hidden (view full) --- 243go_background(struct queue *queue) 244{ 245 struct sigaction sa; 246 struct qitem *it; 247 pid_t pid; 248 249 if (daemonize && daemon(0, 0) != 0) { 250 syslog(LOG_ERR, "can not daemonize: %m"); |
250 exit(1); | 251 exit(EX_OSERR); |
251 } 252 daemonize = 0; 253 254 bzero(&sa, sizeof(sa)); 255 sa.sa_handler = SIG_IGN; 256 sigaction(SIGCHLD, &sa, NULL); 257 258 LIST_FOREACH(it, &queue->queue, next) { 259 /* No need to fork for the last dest */ 260 if (LIST_NEXT(it, next) == NULL) 261 goto retit; 262 263 pid = fork(); 264 switch (pid) { 265 case -1: 266 syslog(LOG_ERR, "can not fork: %m"); | 252 } 253 daemonize = 0; 254 255 bzero(&sa, sizeof(sa)); 256 sa.sa_handler = SIG_IGN; 257 sigaction(SIGCHLD, &sa, NULL); 258 259 LIST_FOREACH(it, &queue->queue, next) { 260 /* No need to fork for the last dest */ 261 if (LIST_NEXT(it, next) == NULL) 262 goto retit; 263 264 pid = fork(); 265 switch (pid) { 266 case -1: 267 syslog(LOG_ERR, "can not fork: %m"); |
267 exit(1); | 268 exit(EX_OSERR); |
268 break; 269 270 case 0: 271 /* 272 * Child: 273 * 274 * return and deliver mail 275 */ --- 5 unchanged lines hidden (view full) --- 281 * to flush the queue. 282 */ 283 setlogident("%s", it->queueid); 284 switch (acquirespool(it)) { 285 case 0: 286 break; 287 case 1: 288 if (doqueue) | 269 break; 270 271 case 0: 272 /* 273 * Child: 274 * 275 * return and deliver mail 276 */ --- 5 unchanged lines hidden (view full) --- 282 * to flush the queue. 283 */ 284 setlogident("%s", it->queueid); 285 switch (acquirespool(it)) { 286 case 0: 287 break; 288 case 1: 289 if (doqueue) |
289 exit(0); | 290 exit(EX_OK); |
290 syslog(LOG_WARNING, "could not lock queue file"); | 291 syslog(LOG_WARNING, "could not lock queue file"); |
291 exit(1); | 292 exit(EX_SOFTWARE); |
292 default: | 293 default: |
293 exit(1); | 294 exit(EX_SOFTWARE); |
294 } 295 dropspool(queue, it); 296 return (it); 297 298 default: 299 /* 300 * Parent: 301 * 302 * fork next child 303 */ 304 break; 305 } 306 } 307 308 syslog(LOG_CRIT, "reached dead code"); | 295 } 296 dropspool(queue, it); 297 return (it); 298 299 default: 300 /* 301 * Parent: 302 * 303 * fork next child 304 */ 305 break; 306 } 307 } 308 309 syslog(LOG_CRIT, "reached dead code"); |
309 exit(1); | 310 exit(EX_SOFTWARE); |
310} 311 312static void 313deliver(struct qitem *it) 314{ 315 int error; 316 unsigned int backoff = MIN_RETRY, slept; 317 struct timeval now; --- 8 unchanged lines hidden (view full) --- 326 error = deliver_remote(it); 327 else 328 error = deliver_local(it); 329 330 switch (error) { 331 case 0: 332 delqueue(it); 333 syslog(LOG_INFO, "delivery successful"); | 311} 312 313static void 314deliver(struct qitem *it) 315{ 316 int error; 317 unsigned int backoff = MIN_RETRY, slept; 318 struct timeval now; --- 8 unchanged lines hidden (view full) --- 327 error = deliver_remote(it); 328 else 329 error = deliver_local(it); 330 331 switch (error) { 332 case 0: 333 delqueue(it); 334 syslog(LOG_INFO, "delivery successful"); |
334 exit(0); | 335 exit(EX_OK); |
335 336 case 1: 337 if (stat(it->queuefn, &st) != 0) { 338 syslog(LOG_ERR, "lost queue file `%s'", it->queuefn); | 336 337 case 1: 338 if (stat(it->queuefn, &st) != 0) { 339 syslog(LOG_ERR, "lost queue file `%s'", it->queuefn); |
339 exit(1); | 340 exit(EX_SOFTWARE); |
340 } 341 if (gettimeofday(&now, NULL) == 0 && 342 (now.tv_sec - st.st_mtim.tv_sec > MAX_TIMEOUT)) { 343 snprintf(errmsg, sizeof(errmsg), 344 "Could not deliver for the last %d seconds. Giving up.", 345 MAX_TIMEOUT); 346 goto bounce; 347 } --- 85 unchanged lines hidden (view full) --- 433 */ 434 if (geteuid() == 0 || getuid() == 0) { 435 struct passwd *pw; 436 437 errno = 0; 438 pw = getpwnam(DMA_ROOT_USER); 439 if (pw == NULL) { 440 if (errno == 0) | 341 } 342 if (gettimeofday(&now, NULL) == 0 && 343 (now.tv_sec - st.st_mtim.tv_sec > MAX_TIMEOUT)) { 344 snprintf(errmsg, sizeof(errmsg), 345 "Could not deliver for the last %d seconds. Giving up.", 346 MAX_TIMEOUT); 347 goto bounce; 348 } --- 85 unchanged lines hidden (view full) --- 434 */ 435 if (geteuid() == 0 || getuid() == 0) { 436 struct passwd *pw; 437 438 errno = 0; 439 pw = getpwnam(DMA_ROOT_USER); 440 if (pw == NULL) { 441 if (errno == 0) |
441 errx(1, "user '%s' not found", DMA_ROOT_USER); | 442 errx(EX_CONFIG, "user '%s' not found", DMA_ROOT_USER); |
442 else | 443 else |
443 err(1, "cannot drop root privileges"); | 444 err(EX_OSERR, "cannot drop root privileges"); |
444 } 445 446 if (setuid(pw->pw_uid) != 0) | 445 } 446 447 if (setuid(pw->pw_uid) != 0) |
447 err(1, "cannot drop root privileges"); | 448 err(EX_OSERR, "cannot drop root privileges"); |
448 449 if (geteuid() == 0 || getuid() == 0) | 449 450 if (geteuid() == 0 || getuid() == 0) |
450 errx(1, "cannot drop root privileges"); | 451 errx(EX_OSERR, "cannot drop root privileges"); |
451 } 452 453 atexit(deltmp); 454 init_random(); 455 456 bzero(&queue, sizeof(queue)); 457 LIST_INIT(&queue.queue); 458 459 if (strcmp(argv[0], "mailq") == 0) { 460 argv++; argc--; 461 showq = 1; 462 if (argc != 0) | 452 } 453 454 atexit(deltmp); 455 init_random(); 456 457 bzero(&queue, sizeof(queue)); 458 LIST_INIT(&queue.queue); 459 460 if (strcmp(argv[0], "mailq") == 0) { 461 argv++; argc--; 462 showq = 1; 463 if (argc != 0) |
463 errx(1, "invalid arguments"); | 464 errx(EX_USAGE, "invalid arguments"); |
464 goto skipopts; 465 } else if (strcmp(argv[0], "newaliases") == 0) { 466 logident_base = "dma"; 467 setlogident("%s", logident_base); 468 469 if (read_aliases() != 0) | 465 goto skipopts; 466 } else if (strcmp(argv[0], "newaliases") == 0) { 467 logident_base = "dma"; 468 setlogident("%s", logident_base); 469 470 if (read_aliases() != 0) |
470 errx(1, "could not parse aliases file `%s'", config.aliases); 471 exit(0); | 471 errx(EX_SOFTWARE, "could not parse aliases file `%s'", config.aliases); 472 exit(EX_OK); |
472 } 473 474 opterr = 0; 475 while ((ch = getopt(argc, argv, ":A:b:B:C:d:Df:F:h:iL:N:no:O:q:r:R:tUV:vX:")) != -1) { 476 switch (ch) { 477 case 'A': 478 /* -AX is being ignored, except for -A{c,m} */ 479 if (optarg[0] == 'c' || optarg[0] == 'm') { --- 62 unchanged lines hidden (view full) --- 542 if (optopt == 'q') { 543 doqueue = 1; 544 break; 545 } 546 /* FALLTHROUGH */ 547 548 default: 549 fprintf(stderr, "invalid argument: `-%c'\n", optopt); | 473 } 474 475 opterr = 0; 476 while ((ch = getopt(argc, argv, ":A:b:B:C:d:Df:F:h:iL:N:no:O:q:r:R:tUV:vX:")) != -1) { 477 switch (ch) { 478 case 'A': 479 /* -AX is being ignored, except for -A{c,m} */ 480 if (optarg[0] == 'c' || optarg[0] == 'm') { --- 62 unchanged lines hidden (view full) --- 543 if (optopt == 'q') { 544 doqueue = 1; 545 break; 546 } 547 /* FALLTHROUGH */ 548 549 default: 550 fprintf(stderr, "invalid argument: `-%c'\n", optopt); |
550 exit(1); | 551 exit(EX_USAGE); |
551 } 552 } 553 argc -= optind; 554 argv += optind; 555 opterr = 1; 556 557 if (argc != 0 && (showq || doqueue)) | 552 } 553 } 554 argc -= optind; 555 argv += optind; 556 opterr = 1; 557 558 if (argc != 0 && (showq || doqueue)) |
558 errx(1, "sending mail and queue operations are mutually exclusive"); | 559 errx(EX_USAGE, "sending mail and queue operations are mutually exclusive"); |
559 560 if (showq + doqueue > 1) | 560 561 if (showq + doqueue > 1) |
561 errx(1, "conflicting queue operations"); | 562 errx(EX_USAGE, "conflicting queue operations"); |
562 563skipopts: 564 if (logident_base == NULL) 565 logident_base = "dma"; 566 setlogident("%s", logident_base); 567 568 act.sa_handler = sighup_handler; 569 act.sa_flags = 0; 570 sigemptyset(&act.sa_mask); 571 if (sigaction(SIGHUP, &act, NULL) != 0) 572 syslog(LOG_WARNING, "can not set signal handler: %m"); 573 574 parse_conf(CONF_PATH "/dma.conf"); 575 576 if (config.authpath != NULL) 577 parse_authfile(config.authpath); 578 579 if (showq) { 580 if (load_queue(&queue) < 0) | 563 564skipopts: 565 if (logident_base == NULL) 566 logident_base = "dma"; 567 setlogident("%s", logident_base); 568 569 act.sa_handler = sighup_handler; 570 act.sa_flags = 0; 571 sigemptyset(&act.sa_mask); 572 if (sigaction(SIGHUP, &act, NULL) != 0) 573 syslog(LOG_WARNING, "can not set signal handler: %m"); 574 575 parse_conf(CONF_PATH "/dma.conf"); 576 577 if (config.authpath != NULL) 578 parse_authfile(config.authpath); 579 580 if (showq) { 581 if (load_queue(&queue) < 0) |
581 errlog(1, "can not load queue"); | 582 errlog(EX_NOINPUT, "can not load queue"); |
582 show_queue(&queue); 583 return (0); 584 } 585 586 if (doqueue) { 587 flushqueue_signal(); 588 if (load_queue(&queue) < 0) | 583 show_queue(&queue); 584 return (0); 585 } 586 587 if (doqueue) { 588 flushqueue_signal(); 589 if (load_queue(&queue) < 0) |
589 errlog(1, "can not load queue"); | 590 errlog(EX_NOINPUT, "can not load queue"); |
590 run_queue(&queue); 591 return (0); 592 } 593 594 if (read_aliases() != 0) | 591 run_queue(&queue); 592 return (0); 593 } 594 595 if (read_aliases() != 0) |
595 errlog(1, "could not parse aliases file `%s'", config.aliases); | 596 errlog(EX_SOFTWARE, "could not parse aliases file `%s'", config.aliases); |
596 597 if ((sender = set_from(&queue, sender)) == NULL) | 597 598 if ((sender = set_from(&queue, sender)) == NULL) |
598 errlog(1, "set_from failed"); | 599 errlog(EX_SOFTWARE, NULL); |
599 600 if (newspoolf(&queue) != 0) | 600 601 if (newspoolf(&queue) != 0) |
601 errlog(1, "can not create temp file in `%s'", config.spooldir); | 602 errlog(EX_CANTCREAT, "can not create temp file in `%s'", config.spooldir); |
602 603 setlogident("%s", queue.id); 604 605 for (i = 0; i < argc; i++) { 606 if (add_recp(&queue, argv[i], EXPAND_WILDCARD) != 0) | 603 604 setlogident("%s", queue.id); 605 606 for (i = 0; i < argc; i++) { 607 if (add_recp(&queue, argv[i], EXPAND_WILDCARD) != 0) |
607 errlogx(1, "invalid recipient `%s'", argv[i]); | 608 errlogx(EX_DATAERR, "invalid recipient `%s'", argv[i]); |
608 } 609 610 if (LIST_EMPTY(&queue.queue) && !recp_from_header) | 609 } 610 611 if (LIST_EMPTY(&queue.queue) && !recp_from_header) |
611 errlogx(1, "no recipients"); | 612 errlogx(EX_NOINPUT, "no recipients"); |
612 613 if (readmail(&queue, nodot, recp_from_header) != 0) | 613 614 if (readmail(&queue, nodot, recp_from_header) != 0) |
614 errlog(1, "can not read mail"); | 615 errlog(EX_NOINPUT, "can not read mail"); |
615 616 if (LIST_EMPTY(&queue.queue)) | 616 617 if (LIST_EMPTY(&queue.queue)) |
617 errlogx(1, "no recipients"); | 618 errlogx(EX_NOINPUT, "no recipients"); |
618 619 if (linkspool(&queue) != 0) | 619 620 if (linkspool(&queue) != 0) |
620 errlog(1, "can not create spools"); | 621 errlog(EX_CANTCREAT, "can not create spools"); |
621 622 /* From here on the mail is safe. */ 623 624 if (config.features & DEFER || queue_only) 625 return (0); 626 627 run_queue(&queue); 628 629 /* NOTREACHED */ 630 return (0); 631} | 622 623 /* From here on the mail is safe. */ 624 625 if (config.features & DEFER || queue_only) 626 return (0); 627 628 run_queue(&queue); 629 630 /* NOTREACHED */ 631 return (0); 632} |