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
mail_run_foreground(const char * dir,char ** argv)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
mail_run_background(const char * dir,char ** argv)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
mail_run_replace(const char * dir,char ** argv)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