Home | History | Annotate | Line # | Download | only in global
      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