]> diplodocus.org Git - nmh/blob - sbr/ext_hook.c
106114f829b02ada5e341fb5a13aee91d2ea2a4b
[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 "context_find.h"
11 #include "pidstatus.h"
12 #include "arglist.h"
13 #include "error.h"
14
15 int
16 ext_hook(char *hook_name, char *message_file_name_1, char *message_file_name_2)
17 {
18 char *hook; /* hook program from context */
19 pid_t pid; /* ID of child process */
20 int status; /* exit or other child process status */
21 char **vec; /* argument vector for child process */
22 int vecp; /* Vector index */
23 char *program; /* Name of program to execute */
24
25 static bool did_message; /* set if we've already output a message */
26
27 if ((hook = context_find(hook_name)) == NULL)
28 return OK;
29
30 switch (pid = fork()) {
31 case -1:
32 status = NOTOK;
33 inform("external database may be out-of-date.");
34 break;
35
36 case 0:
37 vec = argsplit(hook, &program, &vecp);
38 vec[vecp++] = message_file_name_1;
39 vec[vecp++] = message_file_name_2;
40 vec[vecp++] = NULL;
41 execvp(program, vec);
42 advise(program, "Unable to execute");
43 _exit(1);
44 /* NOTREACHED */
45
46 default:
47 status = pidwait(pid, -1);
48 break;
49 }
50
51 if (status == OK)
52 return OK;
53
54 if (!did_message) {
55 char *msghook;
56 if ((msghook = context_find("msg-hook")) != NULL)
57 inform("%s", msghook);
58 else {
59 char errbuf[BUFSIZ];
60 snprintf(errbuf, sizeof(errbuf), "external hook \"%s\"", hook);
61 pidstatus(status, stderr, errbuf);
62 }
63 did_message = true;
64 }
65
66 return NOTOK;
67 }