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
mail_run_foreground(const char * dir,char ** argv)77 int 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
mail_run_background(const char * dir,char ** argv)113 int 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
mail_run_replace(const char * dir,char ** argv)143 NORETURN 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