Allow nghook to execute a program with the data socket connected to

stdin and stdout instead of relaying the data. Now it is possible
to say:

	nghook -e path: hook /usr/local/bin/foo arg1 arg2

and foo will have the hook to path: at file descriptors 0 and 1.

Add an option to specify control messages to be send to the node before
either executing the program or entering the data relay loop.
This commit is contained in:
Hartmut Brandt 2003-10-24 10:01:36 +00:00
parent ad5c39fe2a
commit d3a3b08778
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=121464
2 changed files with 109 additions and 13 deletions

View file

@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include <sysexits.h>
#include <errno.h>
#include <err.h>
#include <stringlist.h>
#include <sys/types.h>
#include <sys/socket.h>
@ -61,10 +62,13 @@ __FBSDID("$FreeBSD$");
static void WriteAscii(u_char * buf, int len);
static void Usage(void);
static void send_msgs(int, const char *);
static int outfd = STDOUT_FILENO;
static int infd = STDIN_FILENO;
static StringList *msgs;
/*
* main()
*/
@ -78,10 +82,14 @@ main(int ac, char *av[])
int asciiFlag = 0;
int loopFlag = 0;
int noInput = 0;
int execFlag = 0;
int ch;
if ((msgs = sl_init()) == NULL)
err(EX_OSERR, NULL);
/* Parse flags */
while ((ch = getopt(ac, av, "adlnsS")) != -1) {
while ((ch = getopt(ac, av, "aedlm:nsS")) != -1) {
switch (ch) {
case 'a':
asciiFlag = 1;
@ -89,12 +97,19 @@ main(int ac, char *av[])
case 'd':
NgSetDebug(NgSetDebug(-1) + 1);
break;
case 'e':
execFlag = 1;
break;
case 'l':
loopFlag = 1;
break;
case 'n':
noInput = 1;
break;
case 'm':
if (sl_add(msgs, optarg) == -1)
err(EX_OSERR, NULL);
break;
case 's':
outfd = STDIN_FILENO;
break;
@ -109,16 +124,29 @@ main(int ac, char *av[])
ac -= optind;
av += optind;
/* Get params */
switch (ac) {
case 2:
hook = av[1];
/* FALLTHROUGH */
case 1:
if (execFlag) {
if (asciiFlag || loopFlag) {
fprintf(stderr, "conflicting options\n");
Usage();
}
if (ac < 3)
Usage();
path = av[0];
break;
default:
Usage();
hook = av[1];
av += 2;
ac -= 2;
} else {
/* Get params */
switch (ac) {
case 2:
hook = av[1];
/* FALLTHROUGH */
case 1:
path = av[0];
break;
default:
Usage();
}
}
/* Get sockets */
@ -134,6 +162,23 @@ main(int ac, char *av[])
NGM_GENERIC_COOKIE, NGM_CONNECT, &ngc, sizeof(ngc)) < 0)
errx(EX_OSERR, "can't connect to node");
if (execFlag) {
/* move dsock to fd 0 and 1 */
(void)close(0);
(void)close(1);
if (!noInput)
(void)dup2(dsock, 0);
(void)dup2(dsock, 1);
send_msgs(csock, path);
/* try executing the program */
(void)execv(av[0], av);
err(EX_OSERR, "%s", av[0]);
} else
send_msgs(csock, path);
/* Close standard input if not reading from it */
if (noInput)
fclose(stdin);
@ -245,5 +290,20 @@ static void
Usage(void)
{
fprintf(stderr, "usage: nghook [-adlnsS] path [hookname]\n");
fprintf(stderr, " or: nghook -e [-n] [-m msg]* path hookname prog "
"[args...]\n");
exit(EX_USAGE);
}
/*
* Send the messages to the node
*/
static void
send_msgs(int cs, const char *path)
{
u_int i;
for (i = 0; i < msgs->sl_cur; i++)
if (NgSendAsciiMsg(cs, path, "%s", msgs->sl_str[i]) == -1)
err(EX_OSERR, "sending message '%s'", msgs->sl_str[i]);
}

View file

@ -44,8 +44,18 @@ node
.Sh SYNOPSIS
.Nm
.Op Fl Sadlns
.Op Fl m Ar msg
.Ar path
.Op Ar hookname
.Pp
.Nm
.Fl e
.Op Fl n
.Op Fl m Ar msg
.Ar path
.Ar hookname
.Ar program
.Op Ar args...
.Sh DESCRIPTION
The
.Nm
@ -61,14 +71,29 @@ is omitted,
.Dq debug
is assumed.
.Pp
At this point all data written to standard input is sent
If the
.Fl e
option is given the third argument is interpreted as the path to a program
and this program is executed with the remaining arguments as its arguments.
Before executing the program netgraph messages (specified by the
.Fl m
option) are sent to the node.
The program is executed with its standard input (unless closed by
.Fl n )
and output connected to the hook.
.Pp
If the
.Fl e
option is not given all data written to standard input is sent
to the node and all data received from the node is relayed
to standard output.
to standard output. Messages specified with
.Fl m
are send to the node before the loop is entered.
The
.Nm
utility exits when
.Dv EOF
is detected on standard input.
is detected on standard input in this case.
.Pp
The options are as follows:
.Pp
@ -81,9 +106,16 @@ Output each packet read in human-readable decoded
form instead of raw binary.
.It Fl d
Increase the debugging verbosity level.
.It Fl e
Execute the program specified by the third argument.
.It Fl l
Loops all received data back to the hook in addition to writing it
to standard output.
.It Fl m Ar msg
Before executing the program (in
.Fl e
mode) send the given ASCII control message to the node.
This option may be given more than once.
.It Fl n
Don't attempt to read any data from standard input.
The
@ -95,6 +127,10 @@ Use file descriptor 1 for input instead of the default 0.
.Sh BUGS
Although all input is read in unbuffered mode,
there's no way to control the packetization of the input.
.Pp
If the node sends a reponse to a message (specified by
.Fl m Ns No ),
this response is lost.
.Sh SEE ALSO
.Xr netgraph 3 ,
.Xr netgraph 4 ,