1/*++ 2/* NAME 3/* mail_run 3 4/* SUMMARY 5/* run mail component program 6/* SYNOPSIS 7/* #include <mail_run.h> 8/* 9/* int mail_run_foreground(dir, argv) 10/* const char *dir; 11/* char **argv; 12/* 13/* int mail_run_background(dir, argv) 14/* const char *dir; 15/* char **argv; 16/* 17/* NORETURN mail_run_replace(dir, argv) 18/* const char *dir; 19/* char **argv; 20/* DESCRIPTION 21/* This module runs programs that live in the mail program directory. 22/* Each routine takes a directory and a command-line array. The program 23/* pathname is built by prepending the directory and a slash to the 24/* command name. 25/* 26/* mail_run_foreground() runs the named command in the foreground and 27/* waits until the command terminates. 28/* 29/* mail_run_background() runs the named command in the background. 30/* 31/* mail_run_replace() attempts to replace the current process by 32/* an instance of the named command. This function never returns. 33/* 34/* Arguments: 35/* .IP argv 36/* A null-terminated command-line vector. The first array element 37/* is the base name of the program to be executed. 38/* DIAGNOSTICS 39/* The result is (-1) if the command could not be run. Otherwise, 40/* mail_run_foreground() returns the termination status of the 41/* command. mail_run_background() returns the process id in case 42/* of success. 43/* CONFIGURATION PARAMETERS 44/* fork_attempts: number of attempts to fork() a process; 45/* fork_delay: delay in seconds between fork() attempts. 46/* LICENSE 47/* .ad 48/* .fi 49/* The Secure Mailer license must be distributed with this software. 50/* AUTHOR(S) 51/* Wietse Venema 52/* IBM T.J. Watson Research 53/* P.O. Box 704 54/* Yorktown Heights, NY 10598, USA 55/*--*/ 56 57/* System library. */ 58 59#include <sys_defs.h> 60#include <sys/wait.h> 61#include <unistd.h> 62#include <errno.h> 63 64/* Utility library. */ 65 66#include <msg.h> 67#include <stringops.h> 68#include <mymalloc.h> 69 70/* Global library. */ 71 72#include "mail_params.h" 73#include "mail_run.h" 74 75/* mail_run_foreground - run command in foreground */ 76 77int mail_run_foreground(const char *dir, char **argv) 78{ 79 int count; 80 char *path; 81 WAIT_STATUS_T status; 82 int pid; 83 int wpid; 84 85#define RETURN(x) { myfree(path); return(x); } 86 87 path = concatenate(dir, "/", argv[0], (char *) 0); 88 89 for (count = 0; count < var_fork_tries; count++) { 90 switch (pid = fork()) { 91 case -1: 92 msg_warn("fork %s: %m", path); 93 break; 94 case 0: 95 /* Reset the msg_cleanup() handlers in the child process. */ 96 (void) msg_cleanup((MSG_CLEANUP_FN) 0); 97 execv(path, argv); 98 msg_fatal("execv %s: %m", path); 99 default: 100 do { 101 wpid = waitpid(pid, &status, 0); 102 } while (wpid == -1 && errno == EINTR); 103 RETURN(wpid == -1 ? -1 : 104 WIFEXITED(status) ? WEXITSTATUS(status) : 1) 105 } 106 sleep(var_fork_delay); 107 } 108 RETURN(-1); 109} 110 111/* mail_run_background - run command in background */ 112 113int mail_run_background(const char *dir, char **argv) 114{ 115 int count; 116 char *path; 117 int pid; 118 119#define RETURN(x) { myfree(path); return(x); } 120 121 path = concatenate(dir, "/", argv[0], (char *) 0); 122 123 for (count = 0; count < var_fork_tries; count++) { 124 switch (pid = fork()) { 125 case -1: 126 msg_warn("fork %s: %m", path); 127 break; 128 case 0: 129 /* Reset the msg_cleanup() handlers in the child process. */ 130 (void) msg_cleanup((MSG_CLEANUP_FN) 0); 131 execv(path, argv); 132 msg_fatal("execv %s: %m", path); 133 default: 134 RETURN(pid); 135 } 136 sleep(var_fork_delay); 137 } 138 RETURN(-1); 139} 140 141/* mail_run_replace - run command, replacing current process */ 142 143NORETURN mail_run_replace(const char *dir, char **argv) 144{ 145 char *path; 146 147 path = concatenate(dir, "/", argv[0], (char *) 0); 148 execv(path, argv); 149 msg_fatal("execv %s: %m", path); 150} 151