Add timeout, add password command, add diffrent verbosity levels.

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@23085 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Love Hörnquist Åstrand
2008-04-27 11:03:25 +00:00
parent 4495b636bb
commit d09435c527

View File

@@ -41,7 +41,8 @@
#include <getarg.h> #include <getarg.h>
struct command { struct command {
enum { CMD_EXPECT = 0, CMD_SEND } type; enum { CMD_EXPECT = 0, CMD_SEND, CMD_PASSWORD } type;
unsigned int lineno;
char *str; char *str;
struct command *next; struct command *next;
}; };
@@ -52,11 +53,21 @@ struct command {
static struct command *commands, **next = &commands; static struct command *commands, **next = &commands;
static sig_atomic_t alarmset = 0;
static int verbose; static int verbose;
static int timeout = 10;
static int master; static int master;
static int slave; static int slave;
static char line[256] = { 0 }; static char line[256] = { 0 };
static void
caught_signal(int signo)
{
alarmset = signo;
}
static void static void
open_pty(void) open_pty(void)
{ {
@@ -88,7 +99,7 @@ parse_configuration(const char *fn)
struct command *c; struct command *c;
char s[1024]; char s[1024];
char *str; char *str;
int lineno = 0; unsigned int lineno = 0;
FILE *cmd; FILE *cmd;
cmd = fopen(fn, "r"); cmd = fopen(fn, "r");
@@ -104,6 +115,7 @@ parse_configuration(const char *fn)
if (c == NULL) if (c == NULL)
errx(1, "malloc"); errx(1, "malloc");
c->lineno = lineno;
(*next) = c; (*next) = c;
next = &(c->next); next = &(c->next);
@@ -113,6 +125,9 @@ parse_configuration(const char *fn)
} else if ((str = iscmd(s, "send ")) != NULL) { } else if ((str = iscmd(s, "send ")) != NULL) {
c->type = CMD_SEND; c->type = CMD_SEND;
c->str = str; c->str = str;
} else if ((str = iscmd(s, "password ")) != NULL) {
c->type = CMD_PASSWORD;
c->str = str;
} else } else
errx(1, "Invalid command on line %d: %s", lineno, s); errx(1, "Invalid command on line %d: %s", lineno, s);
} }
@@ -136,9 +151,13 @@ eval_parent(pid_t pid)
for (c = commands; c != NULL; c = c->next) { for (c = commands; c != NULL; c = c->next) {
switch(c->type) { switch(c->type) {
case CMD_EXPECT: case CMD_EXPECT:
if (verbose)
printf("[expecting %s]", c->str);
len = 0; len = 0;
alarm(timeout);
while((sret = read(master, &in, sizeof(in))) > 0) { while((sret = read(master, &in, sizeof(in))) > 0) {
if (verbose) alarm(timeout);
if (verbose > 1)
printf("%c", in); printf("%c", in);
if (c->str[len] != in) { if (c->str[len] != in) {
len = 0; len = 0;
@@ -148,14 +167,24 @@ eval_parent(pid_t pid)
if (c->str[len] == '\0') if (c->str[len] == '\0')
break; break;
} }
alarm(0);
if (alarmset == SIGALRM)
errx(1, "timeout waiting for %s (line %u)",
c->str, c->lineno);
else if (alarmset)
errx(1, "got a signal %d waiting for %s (line %u)",
alarmset, c->str, c->lineno);
if (sret <= 0) if (sret <= 0)
errx(1, "end command while waiting for %s", c->str); errx(1, "end command while waiting for %s (line %u)",
c->str, c->lineno);
break; break;
case CMD_SEND: { case CMD_SEND:
case CMD_PASSWORD: {
size_t i = 0; size_t i = 0;
const char *msg = (c->type == CMD_PASSWORD) ? "****" : c->str;
if (verbose) if (verbose)
printf("[output]"); printf("[send %s]", msg);
len = strlen(c->str); len = strlen(c->str);
@@ -168,13 +197,14 @@ eval_parent(pid_t pid)
case 'r': ctrl = '\r'; break; case 'r': ctrl = '\r'; break;
case 't': ctrl = '\t'; break; case 't': ctrl = '\t'; break;
default: default:
errx(1, "unknown control char %c", c->str[i]); errx(1, "unknown control char %c (line %u)",
c->str[i], c->lineno);
} }
if (net_write(master, &ctrl, 1) != 1) if (net_write(master, &ctrl, 1) != 1)
errx(1, "command refused input"); errx(1, "command refused input (line %u)", c->lineno);
} else { } else {
if (net_write(master, &c->str[i], 1) != 1) if (net_write(master, &c->str[i], 1) != 1)
errx(1, "command refused input"); errx(1, "command refused input (line %u)", c->lineno);
} }
i++; i++;
} }
@@ -185,9 +215,12 @@ eval_parent(pid_t pid)
} }
} }
while(read(master, &in, sizeof(in)) > 0) while(read(master, &in, sizeof(in)) > 0)
if (verbose) if (verbose > 1)
printf("%c", in); printf("%c", in);
if (verbose)
printf("[end of program]\n");
/* /*
* Fetch status from child * Fetch status from child
*/ */
@@ -212,7 +245,8 @@ eval_parent(pid_t pid)
*/ */
static struct getargs args[] = { static struct getargs args[] = {
{ "verbose", 'v', arg_flag, &verbose, "verbose debugging" } { "timeout", 't', arg_integer, &timeout, "timout", "seconds" },
{ "verbose", 'v', arg_counter, &verbose, "verbose debugging" }
}; };
static void static void
@@ -237,14 +271,13 @@ main(int argc, char **argv)
argc -= optidx; argc -= optidx;
if (argc < 2) if (argc < 2)
errx(1, "to few arguments"); usage(1);
parse_configuration(argv[0]); parse_configuration(argv[0]);
argv += 1; argv += 1;
argc -= 1; argc -= 1;
open_pty(); open_pty();
pid = fork(); pid = fork();
@@ -265,6 +298,15 @@ main(int argc, char **argv)
err(1, "Failed to exec: %s", argv[0]); err(1, "Failed to exec: %s", argv[0]);
default: default:
close(slave); close(slave);
{
struct sigaction sa;
sa.sa_handler = caught_signal;
sa.sa_flags = 0;
sigemptyset (&sa.sa_mask);
sigaction(SIGALRM, &sa, NULL);
}
return eval_parent(pid); return eval_parent(pid);
} }