/* ** ** Copyright (C) 1993 Swedish University Network (SUNET) ** ** ** This program is developed by UDAC, Uppsala University by commission ** of the Swedish University Network (SUNET). ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITTNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ** ** ** Martin.Wendel@its.uu.se ** Torbjorn.Wictorin@its.uu.se ** ** ITS ** P.O. Box 887 ** S-751 08 Uppsala ** Sweden ** */ #include "emil.h" #include extern int pseudo_route; static int fd[2]; void do_fork() { /* int pgrp; */ char *precipient; if (pipe(fd) != 0) { logger(LOG_ERR, "Unable to create pipe\n"); closelog(); fprintf(stderr, "Emil: Unable to create pipe\n"); exit(EX_OSERR); } if (fork() == 0) { /* Child */ int dev; { /* setpgrp(0, pgrp); */ if (close(0) == -1) { logger(LOG_ERR, "close child failed \n"); fprintf(stderr, "Emil: Close child failed\n"); exit(EX_IOERR); } if (dup(fd[0]) == -1) { logger(LOG_ERR, "dup 1 failed\n"); fprintf(stderr, "Emil: dup 1 failed\n"); exit(EX_OSERR); } if (close(fd[0]) == -1 || close(fd[1]) == -1) { logger(LOG_ERR, "close 1 failed\n"); fprintf(stderr, "Emil: Close 1 failed\n"); exit(EX_IOERR); } if (close(1) == -1) { logger(LOG_ERR, "close 2 failed\n"); fprintf(stderr, "Emil: Close 2 failed\n"); exit(EX_IOERR); } if ((dev = open("/dev/null", O_WRONLY)) == -1) { logger(LOG_ERR, "open /dev/null failed\n"); fprintf(stderr, "Emil: Open /dev/null failed\n"); exit(EX_NOPERM); } if (dup(dev) == -1) { logger(LOG_ERR, "dup 2 failed\n"); fprintf(stderr, "Emil: Dup 2 failed\n"); exit(EX_OSERR); } if (close(2) == -1) { logger(LOG_ERR, "close 3 failed\n"); fprintf(stderr, "Emil: Close 3 failed\n"); exit(EX_IOERR); } if (dup(dev) == -1) { logger(LOG_ERR, "dup 3 failed\n"); fprintf(stderr, "Emil: Dup 3 failed\n"); exit(EX_OSERR); } if (close(dev) == -1) { logger(LOG_ERR, "close 3 failed\n"); fprintf(stderr, "Emil: Close 3 failed\n"); exit(EX_IOERR); } precipient = (char *)Yalloc(strlen(recipient) + 8); if (pseudo_route == 1) sprintf(precipient, "@EMIL:%s", recipient); else sprintf(precipient, "%s", recipient); execv(mailer[0], &mailer[1]); closelog(); fprintf(stderr, "Emil: Reached unreachable in forks.c\n"); exit(EX_UNAVAILABLE); } } else /* Parent */ { if (close(fd[0]) == -1) { logger(LOG_ERR, "close 4 failed\n"); closelog(); fprintf(stderr, "Emil: Close 4 failed\n"); exit(EX_IOERR); } if (close(1) == -1) { logger(LOG_ERR, "close 5 failed\n"); closelog(); fprintf(stderr, "Emil: Close 5 failed\n"); exit(EX_IOERR); } if (dup(fd[1]) == -1) { logger(LOG_ERR, "dup 4 failed"); closelog(); fprintf(stderr, "Emil: Dup 4 failed\n"); exit(EX_OSERR); } } } int end_fork() { /* Cleanup after fork */ int status; if (close(1) == -1) { logger(LOG_ERR, "close 6 failed\n"); closelog(); fprintf(stderr, "Emil: Close 6 failed\n"); exit(EX_IOERR); } if (close(fd[1]) == -1) { logger(LOG_ERR, "close 7 failed\n"); closelog(); fprintf(stderr, "Emil: Close 7 failed\n"); exit(EX_IOERR); } closelog(); wait(&status); if (status == -1) exit(EX_SOFTWARE); if ((status & 0377) != 0) exit(EX_TEMPFAIL); /* normal death -- return status */ status = (status >> 8) & 0377; exit(status); }