1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
|
/* Run a program that hooks into some other system. The first argument is
* name of the hook to use, the second is the full path name of a mail message.
* The third argument is also the full path name of a mail message, or a NULL
* pointer if it isn't needed. Look in the context for an error message if
* something goes wrong; there is a built-in message in case one isn't specified.
* Only produce the error message once.
*/
#include "h/mh.h"
#include "pidwait.h"
#include "ext_hook.h"
#include "context_find.h"
#include "pidstatus.h"
#include "utils.h"
#include "arglist.h"
#include "error.h"
int
ext_hook(char *hook_name, char *message_file_name_1, char *message_file_name_2)
{
char *hook; /* hook program from context */
pid_t pid; /* ID of child process */
int status; /* exit or other child process status */
char **vec; /* argument vector for child process */
int vecp; /* Vector index */
char *program; /* Name of program to execute */
static bool did_message; /* set if we've already output a message */
if ((hook = context_find(hook_name)) == NULL)
return OK;
switch (pid = fork()) {
case -1:
status = NOTOK;
inform("external database may be out-of-date.");
break;
case 0:
vec = argsplit(hook, &program, &vecp);
vec[vecp++] = message_file_name_1;
vec[vecp++] = message_file_name_2;
vec[vecp++] = NULL;
execvp(program, vec);
advise(program, "Unable to execute");
_exit(1);
/* NOTREACHED */
default:
status = pidwait(pid, -1);
break;
}
if (status == OK)
return OK;
if (!did_message) {
char *msghook;
if ((msghook = context_find("msg-hook")) != NULL)
inform("%s", msghook);
else {
char errbuf[BUFSIZ];
snprintf(errbuf, sizeof(errbuf), "external hook \"%s\"", hook);
pidstatus(status, stderr, errbuf);
}
did_message = true;
}
return NOTOK;
}
|