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