s/vfork/fork/
[mmh] / sbr / ext_hook.c
1 /*
2 ** Run a program that hooks into some other system.  The first argument is
3 ** name of the hook to use, the second is the full path name of a mail message.
4 ** The third argument is also the full path name of a mail message, or a NULL
5 ** pointer if it isn't needed.  Look in the context for an error message if
6 ** something goes wrong; there is a built-in message in case one isn't
7 ** specified.  Only produce the error message once.
8 */
9
10 #include <h/mh.h>
11
12 int
13 ext_hook(char *hook_name, char *message_file_name_1, char *message_file_name_2)
14 {
15         char *hook;     /* hook program from context          */
16         pid_t pid;      /* ID of child process                */
17         int  status;    /* exit or other child process status */
18         char *vec[4];   /* argument vector for child process  */
19
20         static int did_message = 0; /* set if we've already output a message */
21
22         if ((hook = context_find(hook_name)) == NULL)
23                 return (OK);
24
25         switch (pid = fork()) {
26         case -1:
27                 status = NOTOK;
28                 advise(NULL, "external database may be out-of-date.");
29                 break;
30
31         case 0:
32                 vec[0] = mhbasename(hook);
33                 vec[1] = message_file_name_1;
34                 vec[2] = message_file_name_2;
35                 vec[3] = NULL;
36                 execvp(hook, vec);
37                 _exit(-1);
38                 /* NOTREACHED */
39
40         default:
41                 status = pidwait(pid, -1);
42                 break;
43         }
44
45         if (status != OK) {
46                 if (did_message == 0) {
47                         if ((hook = context_find("msg-hook")) != NULL)
48                                 advise(NULL, hook);
49                         else
50                                 advise(NULL, "external hook (%s) did not work properly.", hook);
51
52                         did_message = 1;
53                 }
54
55                 return (NOTOK);
56         } else
57                 return (OK);
58 }