File: ext_hook.c

package info (click to toggle)
nmh 1.8-4
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 7,860 kB
  • sloc: ansic: 50,445; sh: 22,697; makefile: 1,138; lex: 740; perl: 509; yacc: 265
file content (70 lines) | stat: -rw-r--r-- 1,969 bytes parent folder | download | duplicates (3)
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;
}