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