/*
**
** 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 <fcntl.h>
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);
}
syntax highlighted by Code2HTML, v. 0.9.1