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