Added vboxputty functionality, from Gerrit Pape <pape@innominate.de>

This commit is contained in:
Paul Slootman 2000-11-30 15:40:01 +00:00
parent e165ade0fa
commit 86d035a538
10 changed files with 313 additions and 5 deletions

View File

@ -172,6 +172,9 @@ programs-d: ignore
programs-i: ignore
@echo "Installing '$(DESTDIR)$(sbindir)/vboxgetty'..."
@$(INSTALL_SBIN) $(TOPDIR)/src/vboxgetty $(DESTDIR)$(sbindir)/vboxgetty
@echo "Installing '$(DESTDIR)$(sbindir)/vboxputty'..."
@cd $(DESTDIR)$(sbindir); \
$(LN) -f vboxgetty vboxputty
@echo "Installing '$(DESTDIR)$(sbindir)/vboxd'..."
@$(INSTALL_SBIN) $(TOPDIR)/src/vboxd $(DESTDIR)$(sbindir)/vboxd
@echo "Installing '$(DESTDIR)$(bindir)/vboxcnvt'..."

View File

@ -1,8 +1,8 @@
AUTOMAKE_OPTIONS=foreign no-dependencies
SUBDIRS=de
man_MANS=autovbox.1 rmdtovbox.1 vbox.5 vbox.conf.5 vboxbeep.1 vboxconvert.1 vboxd.8 vboxd.conf.5 vboxgetty.8 vboxgetty.conf.5 vboxmode.1 vboxrc.5 vboxtcl.5 vboxtoau.1 vboxctrl.1 vboxmail.8 vboxplay.1
man_MANS=autovbox.1 rmdtovbox.1 vbox.5 vbox.conf.5 vboxbeep.1 vboxconvert.1 vboxd.8 vboxd.conf.5 vboxgetty.8 vboxgetty.conf.5 vboxmode.1 vboxrc.5 vboxtcl.5 vboxtoau.1 vboxctrl.1 vboxmail.8 vboxplay.1 vboxputty.8
DISTCLEANFILES=${man_MANS}
EXTRA_DIST=autovbox.man rmdtovbox.man vbox.conf.man vbox.man vboxbeep.man vboxconvert.man vboxd.conf.man vboxd.man vboxgetty.conf.man vboxgetty.man vboxmode.man vboxrc.man vboxtcl.man vboxtoau.man vboxctrl.man vboxmail.man vboxplay.man
EXTRA_DIST=autovbox.man rmdtovbox.man vbox.conf.man vbox.man vboxbeep.man vboxconvert.man vboxd.conf.man vboxd.man vboxgetty.conf.man vboxgetty.man vboxmode.man vboxrc.man vboxtcl.man vboxtoau.man vboxctrl.man vboxmail.man vboxplay.man vboxputty.man
%.1 %.5 %.8: %.man
MANDATE=`grep CHECKIN $< | awk '{print $$4}'`; \

View File

@ -89,9 +89,9 @@ VERSION = @VERSION@
AUTOMAKE_OPTIONS=foreign no-dependencies
SUBDIRS=de
man_MANS=autovbox.1 rmdtovbox.1 vbox.5 vbox.conf.5 vboxbeep.1 vboxconvert.1 vboxd.8 vboxd.conf.5 vboxgetty.8 vboxgetty.conf.5 vboxmode.1 vboxrc.5 vboxtcl.5 vboxtoau.1 vboxctrl.1 vboxmail.8 vboxplay.1
man_MANS=autovbox.1 rmdtovbox.1 vbox.5 vbox.conf.5 vboxbeep.1 vboxconvert.1 vboxd.8 vboxd.conf.5 vboxgetty.8 vboxgetty.conf.5 vboxmode.1 vboxrc.5 vboxtcl.5 vboxtoau.1 vboxctrl.1 vboxmail.8 vboxplay.1 vboxputty.8
DISTCLEANFILES=${man_MANS}
EXTRA_DIST=autovbox.man rmdtovbox.man vbox.conf.man vbox.man vboxbeep.man vboxconvert.man vboxd.conf.man vboxd.man vboxgetty.conf.man vboxgetty.man vboxmode.man vboxrc.man vboxtcl.man vboxtoau.man vboxctrl.man vboxmail.man vboxplay.man
EXTRA_DIST=autovbox.man rmdtovbox.man vbox.conf.man vbox.man vboxbeep.man vboxconvert.man vboxd.conf.man vboxd.man vboxgetty.conf.man vboxgetty.man vboxmode.man vboxrc.man vboxtcl.man vboxtoau.man vboxctrl.man vboxmail.man vboxplay.man vboxputty.man
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../src/config.h
CONFIG_CLEAN_FILES =

76
vbox/doc/vboxputty.man Normal file
View File

@ -0,0 +1,76 @@
.\" Process this file with groff -man -Tascii vboxputty.8
.TH VBOXPUTTY 8 "13. January 2000"
.UC 4
.SH NAME
vboxputty \- a self-dialing/-calling vboxgetty
.SH SYNOPSIS
.B vboxputty
.B "\-d"
.IR device
.RB [ "\-f"
.IR config-file ]
.RB [ "\-c"
.IR phonenumber ]
.RB [ "\-s"
.IR ring-timeout ]
.RB [ "\-w"
.IR wait ]
.RB [ "\-t"
.IR redial ]
.RB [ "\-r"
.IR redial-pause ]
.LP
.B vboxputty
.RB [\- "hv" ]
.SH DESCRIPTION
.I vboxputty
is a vboxgetty, not waiting for, but triggering a call. After
connect, vboxputty is acting exactly like vboxgetty.
.I vboxputty
exits with 0 if a connection was established, 99 on BUSY.
.LP
.SH OPTIONS
.IP -h
display a short help
.IP -v
display the version information
.IP "-f config-file"
use
.I config-file
instead of the default vboxgetty.conf
.IP "-d device"
use
.I device
(/dev/ttyI*) for dialout
.IP "-c phonenumber"
the phonenumber to be called
.IP "-s ring-timeout"
vboxputty will dial the
.I phonenumber
and wait
.I ring-timeout
seconds for the called party to accept the call, if
.I ring-timeout
seconds are ellapsed before connect, vboxputty will hangup.
.IP "-w wait"
after the connection is established, vboxputty will wait
.I wait
seconds before starting the tcl-script
.IP "-t redial"
if the called party is BUSY, vboxputty will try
.I redial
times to get a connect
.IP "-r redial-pause"
vboxputty waits
.I redial-pause
seconds between BUSY-redials
.SH FILES
.I /usr/local/vbox/etc/vboxgetty.conf
.SH AUTHOR
Gerrit Pape <pape@innominate.de>
.LP
.SH "SEE ALSO"
.B
the vbox-documentation

View File

@ -235,3 +235,21 @@ void exit_program(int s)
exit(0);
}
void exit_program_code(int s)
{
block_all_signals();
log(L_INFO, "Exit program with value %d...\n", s);
modem_close_port();
streamio_close(setup.vboxrc);
lock_type_unlock(LCK_PID);
lock_type_unlock(LCK_MODEM);
log(L_INFO, "------------------------[End session]-----------------------\n");
log_exit();
exit(s);
}

View File

@ -58,5 +58,5 @@ extern setup_t setup; /* Global setup */
extern int init_program(char *, char *);
extern void exit_program(int);
extern void exit_program_code(int);
#endif /* _VBOX_INIT_H */

View File

@ -105,6 +105,7 @@ int breaklist_search(char *line)
if (breaklist[i])
{
if (strcasecmp(breaklist[i], line) == 0) returnok();
if ((strcmp(breaklist[i], "ALL") == 0) && (strlen(line) > 3)) returnok();
}
}
}

View File

@ -144,6 +144,68 @@ int script_run(char *script)
return(result);
}
int script_run_call(char *script, char *call, int wait) {
/* returns 99 on temporary failure. */
Tcl_Interp *interpreter;
int result;
int rcdelete;
log(L_DEBUG, "Initializing tcl script \"%s\"...\n", script);
breaklist_init();
result = 1;
if ((interpreter = Tcl_CreateInterp())) {
if (Tcl_Init(interpreter) == TCL_OK) {
if (init_tcl_functions(interpreter)) {
if (init_tcl_variables(interpreter)) {
char cmnd[PATH_MAX +1 ];
int mcrc;
xstrncpy(cmnd, "ATD", PATH_MAX);
xstrncat(cmnd, call, PATH_MAX);
log(L_DEBUG, "vboxputty: Triggering call...\n");
if ((mcrc =modem_command(cmnd, "VCON|CONNECT|BUSY")) > 0) {
if (mcrc == 3) {
return(99);
}
sleep(wait);
log(L_INFO, "vboxputty: Running tcl script \"%s\"...\n", script);
if (Tcl_EvalFile(interpreter, script) != TCL_OK) {
log(L_ERROR, "In \"%s\": %s (line %d).\n", script, interpreter->result, interpreter->errorLine);
}
else {
log(L_DEBUG, "vboxputty: Back from tcl script...\n");
result = 0;
}
}
else {
log(L_FATAL, "vboxputty: Can't trigger call: no VCON|CONNECT.\n");
result = 99;
}
}
else log(L_ERROR, "In \"%s\": %s (line %d).\n", script, interpreter->result, interpreter->errorLine);
}
else log(L_FATAL, "Can't create all new tcl commands.\n");
if ((rcdelete = Tcl_InterpDeleted(interpreter)) == 0) {
log(L_DEBUG, "Freeing tcl interpreter...\n");
Tcl_DeleteInterp(interpreter);
}
else {
log(L_ERROR, "Can't free tcl interpreter - Tcl_InterpDeleted() returns %d!\n", rcdelete);
result = 1;
}
}
else log(L_FATAL, "Can't initialize tcl interpreter.\n");
}
else log(L_FATAL, "Can't create tcl interpreter.\n");
breaklist_exit();
if (result != 0) {
log(L_ERROR, "General tcl problem - setting flag to quit program...\n");
}
return(result);
}
/**************************************************************************/
/** init_tcl_functions(): Inits all new tcl functions. **/

View File

@ -22,6 +22,7 @@ struct vbox_tcl_function
/** Prototypes ***********************************************************/
extern int script_run(char *);
extern int script_run_call(char *, char *, int);
extern int script_check_interpreter(void);
#endif /* _VBOX_SCRIPT_H */

View File

@ -26,9 +26,13 @@
/** Prototypes ***********************************************************/
static void version(void);
static void version_vboxputty(void);
static void usage(void);
static void usage_vboxputty(void);
static void main_program(void);
static int main_vboxputty(char*, int, int, int, int);
static int answer_call(void);
static int trigger_call(char *, int, int);
static int check_spool_space(unsigned long);
/** Variables ************************************************************/
@ -49,6 +53,20 @@ static struct option arguments[] =
{ NULL , 0 , NULL, 0 }
};
static struct option arguments_vboxputty[] =
{
{ "version" , no_argument , NULL, 'v' },
{ "help" , no_argument , NULL, 'h' },
{ "file" , required_argument, NULL, 'f' },
{ "device" , required_argument, NULL, 'd' },
{ "call" , required_argument, NULL, 'c' },
{ "ring" , required_argument, NULL, 's' },
{ "wait" , required_argument, NULL, 'w' },
{ "try" , required_argument, NULL, 't' },
{ "redial" , required_argument, NULL, 'r' },
{ NULL , 0 , NULL, 0 }
};
/*************************************************************************/
/** The magic main... **/
/*************************************************************************/
@ -58,6 +76,11 @@ int main(int argc, char **argv)
char *usevrc = NULL;
char *device = NULL;
char *language = NULL;
char *call = NULL;
int ring = 40;
int wait = 2;
int try = 3;
int redial = 30;
int opts;
if (!(vbasename = rindex(argv[0], '/')))
@ -69,6 +92,42 @@ int main(int argc, char **argv)
usevrc = GETTYRC;
device = "";
if (strcmp(vbasename, "vboxputty") == 0) {
while ((opts = getopt_long(argc, argv, "vhf:d:c:s:w:t:r:", arguments_vboxputty, (int *)0)) != EOF) {
switch (opts)
{
case 'f':
usevrc = optarg;
break;
case 'd':
device = optarg;
break;
case 'c':
call = optarg;
break;
case 's':
ring = atoi(optarg);
break;
case 'w':
wait = atoi(optarg);
break;
case 't':
try = atoi(optarg);
break;
case 'r':
redial = atoi(optarg);
break;
case 'v':
version_vboxputty();
break;
case 'h':
default:
usage_vboxputty();
break;
}
}
}
else {
while ((opts = getopt_long(argc, argv, "vhf:d:", arguments, (int *)0)) != EOF)
{
switch (opts)
@ -98,6 +157,8 @@ int main(int argc, char **argv)
if (language) setenv("LANG", language, 1);
}
if (getuid() != 0)
{
log(L_STDERR, "%s: must be run by root!\n", vbasename);
@ -125,6 +186,11 @@ int main(int argc, char **argv)
signal(SIGINT , exit_program);
signal(SIGTERM , exit_program);
if (strcmp(vbasename, "vboxputty") == 0) {
int rc;
rc =main_vboxputty(call, ring, wait, try, redial);
exit_program_code(rc);
}
main_program();
exit_program(SIGTERM);
return 0; /*NOTREACHED*/
@ -142,6 +208,15 @@ static void version(void)
exit(1);
}
static void version_vboxputty(void)
{
fprintf(stderr, "\n");
fprintf(stderr, "vboxgetty version %s (%s)\n", VERSION, VERDATE);
fprintf(stderr, "%s version 0.1.0 (13.1.2000) <pape@innominate.de>\n", vbasename);
fprintf(stderr, "\n");
exit(1);
}
/*************************************************************************/
/** usage(): Displays usage message. **/
@ -160,6 +235,24 @@ static void usage(void)
exit(1);
}
static void usage_vboxputty(void)
{
fprintf(stderr, "\n");
fprintf(stderr, "Usage: %s OPTION [ OPTION ] [ ... ]\n", vbasename);
fprintf(stderr, "\n");
fprintf(stderr, "-f, --file FILE Overwrites \"%s\".\n", GETTYRC);
fprintf(stderr, "-d, --device TTY Use device TTY for modem operations [required].\n");
fprintf(stderr, "-c, --call NUMBER Number to dial is NUMBER.\n");
fprintf(stderr, "-s, --ring SEC Ring SEC seconds, then hangup.\n");
fprintf(stderr, "-w, --wait SEC sleep SEC seconds after connect.\n");
fprintf(stderr, "-t, --try NUM try NUM times to reach NUMBER.\n");
fprintf(stderr, "-r, --redial SEC Wait SEC seconds after connection-failure.\n");
fprintf(stderr, "-h, --help Displays this short help.\n");
fprintf(stderr, "-v, --version Displays the package version.\n");
fprintf(stderr, "\n");
exit(1);
}
/*************************************************************************/
/** main_program(): Mainloop. **/
@ -261,6 +354,40 @@ static void main_program(void)
}
}
static int main_vboxputty (char *call, int ring, int wait, int try, int redial) {
int modeminits = 0;
int rc =FALSE;
int i;
if (!modem_initialize()) {
if (setup.modem.badinitsexit > 0) {
modeminits++;
if (modeminits >= setup.modem.badinitsexit) {
modeminits = 0;
log(L_FATAL, "vboxputty: Exit program while bad init limit are reached.\n");
exit_program_code(1);
}
else {
log(L_WARN, "vboxputty: Bad initialization - Program will exist on %d trys!\n", (setup.modem.badinitsexit - modeminits));
}
}
}
for (i =0; i < try; i++) {
modem_flush(0);
if ((rc =trigger_call(call, ring, wait)) != 0) {
log(L_ERROR, "vboxputty: Cannot trigger call (No %d/%d): %d\n",
i +1, try, rc);
sleep(redial);
}
else {
break;
}
}
return(rc);
}
/*************************************************************************/
/** answer_call(): Answers the call and starts the tcl script. **/
/*************************************************************************/
@ -279,6 +406,26 @@ static int answer_call(void)
return(script_run(run));
}
static int trigger_call(char *call, int timeout, int wait) {
char run[PATH_MAX + 1];
if (!index(setup.voice.tclscriptname, '/')) {
xstrncpy(run, setup.spool, PATH_MAX);
xstrncat(run, "/", PATH_MAX);
xstrncat(run, setup.voice.tclscriptname, PATH_MAX);
}
else {
xstrncpy(run, setup.voice.tclscriptname, PATH_MAX);
}
if (!modem_command("ATS18=1", "OK")) {
log(L_ERROR, "vboxputty: Setting of S18 failed.\n");
}
else {
setup.modem.timeout_cmd = timeout;
return(script_run_call(run, call, wait));
}
return(FALSE);
}
/*************************************************************************/
/** check_spool_space(): Checks space on spoolpartition. **/