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:
@@ -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);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user