1998-06-17 16:38:44 +00:00
|
|
|
|
/*
|
1998-07-06 09:05:13 +00:00
|
|
|
|
** $Id: vboxgetty.c,v 1.4 1998/07/06 09:05:35 michael Exp $
|
1998-06-17 16:38:44 +00:00
|
|
|
|
**
|
1998-07-06 09:05:13 +00:00
|
|
|
|
** Copyright 1996-1998 Michael 'Ghandi' Herold <michael@abadonna.mayn.de>
|
1998-06-17 16:38:44 +00:00
|
|
|
|
**
|
|
|
|
|
** $Log: vboxgetty.c,v $
|
1998-07-06 09:05:13 +00:00
|
|
|
|
** Revision 1.4 1998/07/06 09:05:35 michael
|
|
|
|
|
** - New control file code added. The controls are not longer only empty
|
|
|
|
|
** files - they can contain additional informations.
|
|
|
|
|
** - Control "vboxctrl-answer" added.
|
|
|
|
|
** - Control "vboxctrl-suspend" added.
|
|
|
|
|
** - Locking mechanism added.
|
|
|
|
|
** - Configuration parsing added.
|
|
|
|
|
** - Some code cleanups.
|
|
|
|
|
**
|
1998-06-18 12:38:06 +00:00
|
|
|
|
** Revision 1.3 1998/06/18 12:38:18 michael
|
|
|
|
|
** - 2nd part of the automake/autoconf implementation (now compiles again).
|
|
|
|
|
**
|
1998-06-17 17:01:19 +00:00
|
|
|
|
** Revision 1.2 1998/06/17 17:01:24 michael
|
1998-06-17 16:38:44 +00:00
|
|
|
|
** - First part of the automake/autoconf implementation. Currently vbox will
|
|
|
|
|
** *not* compile!
|
|
|
|
|
**
|
|
|
|
|
*/
|
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
#include "../config.h"
|
|
|
|
|
|
1998-06-17 16:38:44 +00:00
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <getopt.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <signal.h>
|
|
|
|
|
#include <limits.h>
|
1998-07-06 09:05:13 +00:00
|
|
|
|
#include <errno.h>
|
|
|
|
|
#include <fnmatch.h>
|
1998-06-18 12:38:06 +00:00
|
|
|
|
|
1998-06-17 16:38:44 +00:00
|
|
|
|
#include "log.h"
|
|
|
|
|
#include "tcl.h"
|
|
|
|
|
#include "modem.h"
|
|
|
|
|
#include "rc.h"
|
1998-07-06 09:05:13 +00:00
|
|
|
|
#include "vboxrc.h"
|
|
|
|
|
#include "userrc.h"
|
1998-06-17 16:38:44 +00:00
|
|
|
|
#include "voice.h"
|
|
|
|
|
#include "stringutils.h"
|
|
|
|
|
#include "tclscript.h"
|
|
|
|
|
#include "vboxgetty.h"
|
1998-07-06 09:05:13 +00:00
|
|
|
|
#include "control.h"
|
|
|
|
|
#include "lock.h"
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
|
|
|
|
/** Variables ************************************************************/
|
|
|
|
|
|
|
|
|
|
static char *progbasename;
|
1998-07-06 09:05:13 +00:00
|
|
|
|
static char *isdnttyname;
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
|
|
|
|
char temppathname[PATH_MAX + 1];
|
|
|
|
|
|
|
|
|
|
/** Structures ***********************************************************/
|
|
|
|
|
|
|
|
|
|
static struct vboxrc rc_getty_c[] =
|
|
|
|
|
{
|
|
|
|
|
{ "init" , NULL },
|
|
|
|
|
{ "initnumber" , NULL },
|
|
|
|
|
{ "badinitsexit" , NULL },
|
|
|
|
|
{ "initpause" , NULL },
|
|
|
|
|
{ "commandtimeout", NULL },
|
|
|
|
|
{ "echotimeout" , NULL },
|
|
|
|
|
{ "ringtimeout" , NULL },
|
|
|
|
|
{ "alivetimeout" , NULL },
|
1998-07-06 09:05:13 +00:00
|
|
|
|
{ "spooldir" , NULL },
|
|
|
|
|
{ "toggledtrtime" , NULL },
|
1998-06-17 16:38:44 +00:00
|
|
|
|
{ NULL , NULL }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static struct option arguments[] =
|
|
|
|
|
{
|
|
|
|
|
{ "version" , no_argument , NULL, 'v' },
|
|
|
|
|
{ "help" , no_argument , NULL, 'h' },
|
|
|
|
|
{ "debug" , required_argument, NULL, 'x' },
|
|
|
|
|
{ "device" , required_argument, NULL, 'd' },
|
|
|
|
|
{ NULL , 0 , NULL, 0 }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct vboxmodem vboxmodem;
|
|
|
|
|
|
|
|
|
|
/** Prototypes ***********************************************************/
|
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
static int vboxgettyrc_parse(unsigned char *);
|
|
|
|
|
static int process_incoming_call(void);
|
|
|
|
|
static int run_modem_init(void);
|
|
|
|
|
static void pid_create(char *);
|
|
|
|
|
static void pid_remove(char *);
|
|
|
|
|
static void show_usage(int, int);
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
|
/** The magic main... **/
|
|
|
|
|
/*************************************************************************/
|
|
|
|
|
|
|
|
|
|
void main(int argc, char **argv)
|
|
|
|
|
{
|
|
|
|
|
char *stop;
|
|
|
|
|
int opts;
|
|
|
|
|
char *debugstr;
|
|
|
|
|
int debuglvl;
|
|
|
|
|
int i;
|
|
|
|
|
int modemstate;
|
|
|
|
|
int modeminits;
|
|
|
|
|
|
|
|
|
|
progbasename = argv[0];
|
|
|
|
|
|
|
|
|
|
if ((stop = rindex(argv[0], '/'))) progbasename = ++stop;
|
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
/* Die Argumente des Programms einlesen und den Debuglevel */
|
|
|
|
|
/* setzen. */
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
|
|
|
|
debugstr = NULL;
|
|
|
|
|
isdnttyname = NULL;
|
|
|
|
|
|
|
|
|
|
while ((opts = getopt_long(argc, argv, "vhx:d:", arguments, (int *)0)) != EOF)
|
|
|
|
|
{
|
|
|
|
|
switch (opts)
|
|
|
|
|
{
|
|
|
|
|
case 'x':
|
|
|
|
|
debugstr = optarg;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'd':
|
|
|
|
|
isdnttyname = optarg;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'v':
|
|
|
|
|
show_usage(200, 0);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'h':
|
|
|
|
|
default:
|
|
|
|
|
show_usage(200, 1);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (debugstr)
|
|
|
|
|
{
|
|
|
|
|
if (strcasecmp(debugstr, "FULL") != 0)
|
|
|
|
|
{
|
|
|
|
|
debuglvl = LOG_E;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < strlen(debugstr); i++)
|
|
|
|
|
{
|
|
|
|
|
switch (debugstr[i])
|
|
|
|
|
{
|
|
|
|
|
case 'W':
|
|
|
|
|
case 'w':
|
|
|
|
|
debuglvl |= LOG_W;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'I':
|
|
|
|
|
debuglvl |= LOG_I;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'A':
|
|
|
|
|
debuglvl |= LOG_A;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'D':
|
|
|
|
|
debuglvl |= LOG_D;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else debuglvl = LOG_X;
|
|
|
|
|
|
|
|
|
|
log_set_debuglevel(debuglvl);
|
|
|
|
|
}
|
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
umask(xstrtoo(VBOX_ROOT_UMASK, 0));
|
|
|
|
|
|
|
|
|
|
/* Pfadangaben vom Devicenamen abschneiden und <20>berpr<70>fen ob */
|
|
|
|
|
/* das Device vom Benutzer gelesen und beschrieben werden */
|
|
|
|
|
/* kann (eigentlich nicht n<>tig, da nur unter Rootrechten ge- */
|
|
|
|
|
/* startet werden kann. */
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
|
|
|
|
if (isdnttyname)
|
|
|
|
|
{
|
|
|
|
|
if ((stop = rindex(isdnttyname, '/'))) isdnttyname = ++stop;
|
|
|
|
|
|
|
|
|
|
printstring(temppathname, "/dev/%s", isdnttyname);
|
|
|
|
|
|
|
|
|
|
if (access(temppathname, F_OK|R_OK|W_OK) != 0)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "\n%s: error: \"%s\" doesn't exist or is not accessable!\n\n", progbasename, temppathname);
|
|
|
|
|
|
|
|
|
|
quit_program(100);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "\n%s: error: isdn tty name is required!\n", progbasename);
|
|
|
|
|
|
|
|
|
|
show_usage(100, 1);
|
|
|
|
|
}
|
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
/* Pr<50>fen ob das Programm unter Rootrechten gestartet wurde. Die */
|
|
|
|
|
/* Rechte werden sp<73>ter auf die des jeweiligen Benutzers ge<67>n- */
|
|
|
|
|
/* dert, zum Start sind aber Rootrechte n<>tig. */
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
|
|
|
|
if (getuid() != 0)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "\n%s: error: need root privilegs to start!\n\n", progbasename);
|
|
|
|
|
|
|
|
|
|
quit_program(100);
|
|
|
|
|
}
|
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
/* Jetzt wird der Log ge<67>ffnet. Der Name des aktuellen Devices */
|
|
|
|
|
/* wird an das Ende angeh<65>ngt. */
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
1998-06-18 12:38:06 +00:00
|
|
|
|
printstring(temppathname, "%s/vboxgetty-%s.log", LOGDIR, isdnttyname);
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
|
|
|
|
log_open(temppathname);
|
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
/* Tcl-Interpreter starten. F<>r die momentanen Funktionen wird */
|
|
|
|
|
/* Version 8 oder h<>her ben<65>tigt. */
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
|
|
|
|
if (scr_create_interpreter() == -1)
|
|
|
|
|
{
|
|
|
|
|
log_line(LOG_E, "Can't create/initialize the tcl interpreter!\n");
|
|
|
|
|
|
|
|
|
|
quit_program(100);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
log_line(LOG_I, "Running vbox version %s (with tcl version %s).\n", VERSION, scr_tcl_version());
|
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
/* Konfiguration des getty's abarbeiten. Zuerst wird die globale, */
|
|
|
|
|
/* dann die des jeweiligen tty's eingelesen. */
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
if (vboxgettyrc_parse(isdnttyname) == -1)
|
1998-06-17 16:38:44 +00:00
|
|
|
|
{
|
|
|
|
|
log_line(LOG_E, "Unable to read/parse configuration!\n");
|
|
|
|
|
|
|
|
|
|
quit_program(100);
|
|
|
|
|
}
|
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
/* Modem Device <20>ffnen und die interne Initialisierung */
|
|
|
|
|
/* ausf<73>hren (nicht der normale Modeminit). */
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
|
|
|
|
printstring(temppathname, "/dev/%s", isdnttyname);
|
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
log_line(LOG_D, "Opening modem device \"%s\" (38400, CTS/RTS)...\n", temppathname);
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
|
|
|
|
if (vboxmodem_open(&vboxmodem, temppathname) == -1)
|
|
|
|
|
{
|
|
|
|
|
log_line(LOG_E, "Can't open/setup modem device (%s).\n", vboxmodem_error());
|
|
|
|
|
|
|
|
|
|
quit_program(100);
|
|
|
|
|
}
|
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
/* Lock- und PID-Datei f<>r den getty und das entsprechende */
|
|
|
|
|
/* Device erzeugen. */
|
|
|
|
|
|
|
|
|
|
printstring(temppathname, "%s/LCK..%s", LOCKDIR, isdnttyname);
|
|
|
|
|
|
|
|
|
|
if (lock_create(temppathname) == -1) quit_program(100);
|
|
|
|
|
|
|
|
|
|
printstring(temppathname, "%s/vboxgetty-%s.pid", PIDDIR, isdnttyname);
|
|
|
|
|
|
|
|
|
|
pid_create(temppathname);
|
|
|
|
|
|
|
|
|
|
/* Signalh<6C>ndler installieren. Alle m<>glichen Signale werden */
|
|
|
|
|
/* auf quit_program() umgelenkt. */
|
|
|
|
|
|
|
|
|
|
signal(SIGINT , quit_program);
|
|
|
|
|
signal(SIGTERM, quit_program);
|
|
|
|
|
|
|
|
|
|
/* Hauptloop: Der Loop wird nur verlassen, wenn w<>hrend der */
|
|
|
|
|
/* Abarbeitung ein Fehler aufgetreten ist. Das Programm be- */
|
|
|
|
|
/* endet sich danach! */
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
|
|
|
|
modemstate = VBOXMODEM_STAT_INIT;
|
|
|
|
|
modeminits = 0;
|
|
|
|
|
|
|
|
|
|
while (modemstate != VBOXMODEM_STAT_EXIT)
|
|
|
|
|
{
|
|
|
|
|
switch (modemstate)
|
|
|
|
|
{
|
|
|
|
|
case VBOXMODEM_STAT_INIT:
|
|
|
|
|
|
|
|
|
|
if (run_modem_init() == -1)
|
|
|
|
|
{
|
|
|
|
|
if ((i = (int)xstrtol(rc_get_entry(rc_getty_c, "badinitsexit"), 10)) > 0)
|
|
|
|
|
{
|
|
|
|
|
modeminits++;
|
|
|
|
|
|
|
|
|
|
if (modeminits >= i)
|
|
|
|
|
{
|
|
|
|
|
modemstate = VBOXMODEM_STAT_EXIT;
|
|
|
|
|
modeminits = 0;
|
|
|
|
|
|
|
|
|
|
log_line(LOG_E, "Exit program while bad init limit are reached.\n");
|
|
|
|
|
}
|
|
|
|
|
else log_line(LOG_W, "Bad initialization - Program will exist on %d trys!\n", (i - modeminits));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
modemstate = VBOXMODEM_STAT_WAIT;
|
|
|
|
|
modeminits = 0;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case VBOXMODEM_STAT_WAIT:
|
|
|
|
|
|
|
|
|
|
modem_flush(&vboxmodem, 0);
|
|
|
|
|
|
|
|
|
|
if (modem_wait(&vboxmodem) == 0)
|
|
|
|
|
{
|
|
|
|
|
modemstate = VBOXMODEM_STAT_RING;
|
|
|
|
|
modeminits = 0;
|
|
|
|
|
}
|
|
|
|
|
else modemstate = VBOXMODEM_STAT_TEST;
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case VBOXMODEM_STAT_TEST:
|
|
|
|
|
|
|
|
|
|
log_line(LOG_D, "Checking if modem is still alive...\n");
|
|
|
|
|
|
|
|
|
|
if (modem_command(&vboxmodem, "AT", "OK") > 0)
|
|
|
|
|
{
|
|
|
|
|
modemstate = VBOXMODEM_STAT_WAIT;
|
|
|
|
|
modeminits = 0;
|
|
|
|
|
}
|
|
|
|
|
else modemstate = VBOXMODEM_STAT_INIT;
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case VBOXMODEM_STAT_RING:
|
|
|
|
|
|
|
|
|
|
modem_set_nocarrier(&vboxmodem, 0);
|
|
|
|
|
process_incoming_call();
|
|
|
|
|
modem_hangup(&vboxmodem);
|
1998-07-06 09:05:13 +00:00
|
|
|
|
|
|
|
|
|
if (set_process_permissions(0, 0, xstrtoo(VBOX_ROOT_UMASK, 0)) != 0)
|
|
|
|
|
modemstate = VBOXMODEM_STAT_EXIT;
|
|
|
|
|
else
|
|
|
|
|
modemstate = VBOXMODEM_STAT_INIT;
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
|
|
log_line(LOG_E, "Unknown modem status %d!\n", modemstate);
|
|
|
|
|
|
|
|
|
|
modemstate = VBOXMODEM_STAT_INIT;
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
quit_program(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
1998-07-06 09:05:13 +00:00
|
|
|
|
/** quit_program(): Gibt alle belegten Resourcen frei und beendet das **/
|
|
|
|
|
/** Programm. **/
|
1998-06-17 16:38:44 +00:00
|
|
|
|
/*************************************************************************/
|
1998-07-06 09:05:13 +00:00
|
|
|
|
/** => rc R<>ckgabewert des Programms (1-99 ist reserviert). **/
|
1998-06-17 16:38:44 +00:00
|
|
|
|
/*************************************************************************/
|
|
|
|
|
|
|
|
|
|
void quit_program(int rc)
|
|
|
|
|
{
|
|
|
|
|
modem_hangup(&vboxmodem);
|
1998-07-06 09:05:13 +00:00
|
|
|
|
|
|
|
|
|
log_line(LOG_D, "Closing modem device (%d)...\n", vboxmodem.fd);
|
|
|
|
|
|
|
|
|
|
if (vboxmodem_close(&vboxmodem) != 0)
|
|
|
|
|
{
|
|
|
|
|
log_line(LOG_E, "%s (%s)\n", vboxmodem_error(), strerror(errno));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isdnttyname)
|
|
|
|
|
{
|
|
|
|
|
printstring(temppathname, "%s/LCK..%s", LOCKDIR, isdnttyname);
|
|
|
|
|
|
|
|
|
|
lock_remove(temppathname);
|
|
|
|
|
|
|
|
|
|
printstring(temppathname, "%s/vboxgetty-%s.pid", PIDDIR, isdnttyname);
|
|
|
|
|
|
|
|
|
|
pid_remove(temppathname);
|
|
|
|
|
}
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
|
|
|
|
scr_remove_interpreter();
|
|
|
|
|
|
|
|
|
|
rc_free(rc_getty_c);
|
|
|
|
|
|
|
|
|
|
log_close();
|
|
|
|
|
|
|
|
|
|
exit(rc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
1998-07-06 09:05:13 +00:00
|
|
|
|
/** show_usage(): Zeigt Benutzermeldung/Version an und beendet dann das **/
|
|
|
|
|
/** Programm. **/
|
1998-06-17 16:38:44 +00:00
|
|
|
|
/*************************************************************************/
|
1998-07-06 09:05:13 +00:00
|
|
|
|
/** => rc R<>ckgabewert des Programms (1-99 ist reserviert). **/
|
|
|
|
|
/** => help 1 wenn die Benutzermeldung oder 0 wenn die Version **/
|
|
|
|
|
/** angezeigt werden soll. **/
|
1998-06-17 16:38:44 +00:00
|
|
|
|
/*************************************************************************/
|
|
|
|
|
|
|
|
|
|
static void show_usage(int rc, int help)
|
|
|
|
|
{
|
|
|
|
|
if (help)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stdout, "\n");
|
|
|
|
|
fprintf(stdout, "Usage: %s [OPTION] [OPTION] [...]\n", progbasename);
|
|
|
|
|
fprintf(stdout, "\n");
|
|
|
|
|
fprintf(stdout, "--device TTY Name of the isdn tty to use (required).\n");
|
|
|
|
|
fprintf(stdout, "--debug CODE Sets debug level (default \"EWI\").\n");
|
|
|
|
|
fprintf(stdout, "--version Display version and exit.\n");
|
|
|
|
|
fprintf(stdout, "--help Display this help and exit.\n");
|
|
|
|
|
fprintf(stdout, "\n");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
fprintf(stdout, "%s version %s\n", progbasename, VERSION);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
exit(rc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
1998-07-06 09:05:13 +00:00
|
|
|
|
/** run_modem_init(): Startet das Tcl-Skript zum initislisieren des **/
|
|
|
|
|
/** Modems. **/
|
1998-06-17 16:38:44 +00:00
|
|
|
|
/*************************************************************************/
|
1998-07-06 09:05:13 +00:00
|
|
|
|
/** <= 0 wenn die Initialisierung geklappt hat, -1 bei **/
|
|
|
|
|
/** einem Fehler. **/
|
1998-06-17 16:38:44 +00:00
|
|
|
|
/*************************************************************************/
|
|
|
|
|
|
|
|
|
|
static int run_modem_init(void)
|
|
|
|
|
{
|
|
|
|
|
struct vbox_tcl_variable vars[] =
|
|
|
|
|
{
|
|
|
|
|
{ "vbxv_init" , rc_get_entry(rc_getty_c, "init" ) },
|
|
|
|
|
{ "vbxv_initnumber" , rc_get_entry(rc_getty_c, "initnumber") },
|
|
|
|
|
{ NULL , NULL }
|
|
|
|
|
};
|
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
log_line(LOG_D, "Initializing modem...\n");
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
|
|
|
|
if (scr_init_variables(vars) == 0)
|
|
|
|
|
{
|
|
|
|
|
if (scr_execute("initmodem.tcl", NULL) == 0) return(0);
|
|
|
|
|
}
|
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
log_line(LOG_E, "Can't initialize modem device!\n");
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
|
|
|
|
return(-1);
|
|
|
|
|
}
|
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
/*************************************************************************/
|
|
|
|
|
/** vboxgettyrc_parse(): Liest die Konfiguration des gettys ein. Zu- **/
|
|
|
|
|
/** erst wird die globale und dann die des je- **/
|
|
|
|
|
/** weiligen tty's eingelesen. **/
|
|
|
|
|
/*************************************************************************/
|
|
|
|
|
/** => tty Name des benutzten tty's. **/
|
|
|
|
|
/** **/
|
|
|
|
|
/** <= 0 wenn alles eingelesen werden konnte oder **/
|
|
|
|
|
/** -1 bei einem Fehler. **/
|
|
|
|
|
/*************************************************************************/
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
static int vboxgettyrc_parse(unsigned char *tty)
|
1998-06-17 16:38:44 +00:00
|
|
|
|
{
|
1998-07-06 09:05:13 +00:00
|
|
|
|
printstring(temppathname, "%s/vboxgetty.conf", SYSCONFDIR);
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
if (rc_read(rc_getty_c, temppathname, NULL) < 0)
|
1998-06-17 16:38:44 +00:00
|
|
|
|
{
|
|
|
|
|
if (errno != ENOENT)
|
|
|
|
|
{
|
1998-07-06 09:05:13 +00:00
|
|
|
|
log_line(LOG_E, "Can't open \"%s\" (%s)!\n", temppathname, strerror(errno));
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
|
|
|
|
return(-1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
printstring(temppathname, "%s/vboxgetty.conf.%s", SYSCONFDIR, tty);
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
if (rc_read(rc_getty_c, temppathname, NULL) < 0)
|
1998-06-17 16:38:44 +00:00
|
|
|
|
{
|
|
|
|
|
if (errno != ENOENT)
|
|
|
|
|
{
|
1998-07-06 09:05:13 +00:00
|
|
|
|
log_line(LOG_E, "Can't open \"%s\" (%s)!\n", temppathname, strerror(errno));
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
|
|
|
|
return(-1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
log_line(LOG_D, "Filling unset configuration variables with defaults...\n");
|
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
if (!rc_set_empty(rc_getty_c, "init" , "ATZ&B512" )) return(-1);
|
|
|
|
|
if (!rc_set_empty(rc_getty_c, "badinitsexit" , "10" )) return(-1);
|
|
|
|
|
if (!rc_set_empty(rc_getty_c, "initpause" , "2500" )) return(-1);
|
|
|
|
|
if (!rc_set_empty(rc_getty_c, "commandtimeout" , "4" )) return(-1);
|
|
|
|
|
if (!rc_set_empty(rc_getty_c, "echotimeout" , "4" )) return(-1);
|
|
|
|
|
if (!rc_set_empty(rc_getty_c, "ringtimeout" , "6" )) return(-1);
|
|
|
|
|
if (!rc_set_empty(rc_getty_c, "alivetimeout" , "1800" )) return(-1);
|
|
|
|
|
if (!rc_set_empty(rc_getty_c, "toggledtrtime" , "400" )) return(-1);
|
|
|
|
|
if (!rc_set_empty(rc_getty_c, "spooldir" , "/var/spool/vbox")) return(-1);
|
|
|
|
|
|
|
|
|
|
modemsetup.echotimeout = xstrtol(rc_get_entry(rc_getty_c, "echotimeout" ), 4 );
|
|
|
|
|
modemsetup.commandtimeout = xstrtol(rc_get_entry(rc_getty_c, "commandtimeout"), 4 );
|
|
|
|
|
modemsetup.ringtimeout = xstrtol(rc_get_entry(rc_getty_c, "ringtimeout" ), 6 );
|
|
|
|
|
modemsetup.alivetimeout = xstrtol(rc_get_entry(rc_getty_c, "alivetimeout" ), 1800 );
|
|
|
|
|
modemsetup.toggle_dtr_time = xstrtol(rc_get_entry(rc_getty_c, "toggledtrtime" ), 400 );
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
|
|
|
|
if (!rc_get_entry(rc_getty_c, "initnumber"))
|
|
|
|
|
{
|
|
|
|
|
log_line(LOG_E, "Variable \"initnumber\" *must* be set!\n");
|
|
|
|
|
|
|
|
|
|
return(-1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
1998-07-06 09:05:13 +00:00
|
|
|
|
/** process_incoming_call(): Bearbeitet einen eingehenden Anruf. **/
|
1998-06-17 16:38:44 +00:00
|
|
|
|
/*************************************************************************/
|
|
|
|
|
|
|
|
|
|
static int process_incoming_call(void)
|
|
|
|
|
{
|
1998-07-06 09:05:13 +00:00
|
|
|
|
struct vboxuser vboxuser;
|
|
|
|
|
struct vboxcall vboxcall;
|
|
|
|
|
char line[VBOXMODEM_BUFFER_SIZE + 1];
|
|
|
|
|
int haverings;
|
|
|
|
|
int waitrings;
|
|
|
|
|
int usersetup;
|
|
|
|
|
int ringsetup;
|
|
|
|
|
int inputisok;
|
|
|
|
|
char *stop;
|
|
|
|
|
|
|
|
|
|
memset(&vboxuser, 0, sizeof(vboxuser));
|
|
|
|
|
memset(&vboxcall, 0, sizeof(vboxcall));
|
|
|
|
|
|
|
|
|
|
haverings = 0;
|
|
|
|
|
waitrings = -1;
|
|
|
|
|
usersetup = 0;
|
|
|
|
|
ringsetup = 0;
|
|
|
|
|
|
|
|
|
|
while (modem_read(&vboxmodem, line, modemsetup.ringtimeout) == 0)
|
|
|
|
|
{
|
|
|
|
|
inputisok = 0;
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
/* Wenn der Benutzer der angerufenen Nummer ermittelt ist und */
|
|
|
|
|
/* dessen Konfigurations abgearbeitet wurde, wird <20>berpr<70>ft ob */
|
|
|
|
|
/* der Anruf angenommen werden soll. */
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
if ((usersetup) && (ringsetup))
|
1998-06-17 16:38:44 +00:00
|
|
|
|
{
|
1998-07-06 09:05:13 +00:00
|
|
|
|
if (waitrings >= 0)
|
|
|
|
|
{
|
|
|
|
|
if ((stop = ctrl_exists(vboxuser.home, "answer")))
|
|
|
|
|
{
|
|
|
|
|
log_line(LOG_D, "Control \"vboxctrl-answer:%s\" found...\n", stop);
|
|
|
|
|
|
|
|
|
|
if ((strcasecmp(stop, "no") == 0) || (strcasecmp(stop, "hangup") == 0) || (strcasecmp(stop, "reject") == 0))
|
|
|
|
|
{
|
|
|
|
|
log_line(LOG_D, "Incoming call will be rejected...\n");
|
|
|
|
|
|
|
|
|
|
return(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (strcasecmp(stop, "now") != 0)
|
|
|
|
|
{
|
|
|
|
|
vboxuser.space = 0;
|
|
|
|
|
waitrings = xstrtol(stop, waitrings);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
vboxuser.space = 0;
|
|
|
|
|
waitrings = 1;
|
|
|
|
|
}
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
log_line(LOG_D, "Call will be answered after %d ring(s).\n", waitrings);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (waitrings > 0)
|
1998-06-17 16:38:44 +00:00
|
|
|
|
{
|
1998-07-06 09:05:13 +00:00
|
|
|
|
if (haverings >= waitrings)
|
1998-06-17 16:38:44 +00:00
|
|
|
|
{
|
1998-07-06 09:05:13 +00:00
|
|
|
|
return(voice_init(&vboxuser, &vboxcall));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
/* Ring abarbeiten: Beim ersten Ring wird die angerufene */
|
|
|
|
|
/* Nummer gesichert, die durch ATS13.7=1 mit einem Slash */
|
|
|
|
|
/* an den Ringstring angeh<65>ngt ist. */
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
if (strncmp(line, "RING/", 5) == 0)
|
|
|
|
|
{
|
|
|
|
|
inputisok++;
|
|
|
|
|
haverings++;
|
|
|
|
|
|
|
|
|
|
if (!ringsetup)
|
|
|
|
|
{
|
|
|
|
|
xstrncpy(vboxuser.localphone, &line[5], VBOXUSER_NUMBER);
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
ringsetup = 1;
|
|
|
|
|
}
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
log_line(LOG_A, "%s #%03d (%s)...\n", line, haverings, (usersetup ? vboxcall.name : "not known"));
|
|
|
|
|
}
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
/* CallerID aus dem Modeminput kopieren. Wenn bereits die */
|
|
|
|
|
/* angerufene Nummer ermittelt wurde, wird einmalig die */
|
|
|
|
|
/* Konfigurationsdatei des Benutzers abgearbeitet. */
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
if (strncmp(line, "CALLER NUMBER: ", 15) == 0)
|
|
|
|
|
{
|
|
|
|
|
inputisok++;
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
if ((ringsetup) && (!usersetup))
|
|
|
|
|
{
|
|
|
|
|
xstrncpy(vboxuser.incomingid, &line[15], VBOXUSER_CALLID);
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
if (userrc_parse(&vboxuser, rc_get_entry(rc_getty_c, "spooldir"), vboxuser.localphone) == 0)
|
|
|
|
|
{
|
|
|
|
|
if ((vboxuser.uid != 0) && (vboxuser.gid != 0))
|
|
|
|
|
{
|
|
|
|
|
/* Nachdem "vboxgetty.user" abgearbeitet ist und */
|
|
|
|
|
/* ein Benutzer gefunden wurde, werden einige der */
|
|
|
|
|
/* Kontrolldateien gel<65>scht. */
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
ctrl_remove(vboxuser.home, "suspend");
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
if ((stop = ctrl_exists(vboxuser.home, "answer")))
|
|
|
|
|
{
|
|
|
|
|
if ((strcasecmp(stop, "no") == 0) || (strcasecmp(stop, "hangup") == 0) || (strcasecmp(stop, "reject") == 0))
|
|
|
|
|
{
|
|
|
|
|
ctrl_remove(vboxuser.home, "answer");
|
|
|
|
|
}
|
|
|
|
|
}
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
/* Die "effective Permissions" des Prozesses auf */
|
|
|
|
|
/* die des Benutzers setzen und dessen Konfigurat- */
|
|
|
|
|
/* ionsdatei abarbeiten. */
|
|
|
|
|
|
|
|
|
|
if (set_process_permissions(vboxuser.uid, vboxuser.gid, vboxuser.umask) == 0)
|
|
|
|
|
{
|
|
|
|
|
usersetup = 1;
|
|
|
|
|
waitrings = vboxrc_parse(&vboxcall, vboxuser.home, vboxuser.incomingid);
|
|
|
|
|
|
|
|
|
|
if (waitrings <= 0)
|
|
|
|
|
{
|
|
|
|
|
if (waitrings < 0)
|
|
|
|
|
log_line(LOG_W, "Incoming call will be ignored!\n");
|
|
|
|
|
else
|
|
|
|
|
log_line(LOG_D, "Incoming call will be ignored (user setup)!\n");
|
|
|
|
|
}
|
|
|
|
|
else log_line(LOG_D, "Call will be answered after %d ring(s).\n", waitrings);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else log_line(LOG_W, "Useing uid/gid 0 is not allowed - call will be ignored!\n", vboxuser.incomingid);
|
|
|
|
|
}
|
|
|
|
|
else log_line(LOG_W, "Number \"%s\" not bound to a local user - call will be ignored!\n", vboxuser.localphone);
|
|
|
|
|
}
|
1998-06-17 16:38:44 +00:00
|
|
|
|
}
|
1998-07-06 09:05:13 +00:00
|
|
|
|
|
|
|
|
|
if (!inputisok)
|
1998-06-17 16:38:44 +00:00
|
|
|
|
{
|
|
|
|
|
log_line(LOG_D, "Got junk line \"");
|
|
|
|
|
log_code(LOG_D, line);
|
|
|
|
|
log_text(LOG_D, "\"...\n");
|
1998-07-06 09:05:13 +00:00
|
|
|
|
|
|
|
|
|
continue;
|
1998-06-17 16:38:44 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return(-1);
|
|
|
|
|
}
|
|
|
|
|
/*************************************************************************/
|
1998-07-06 09:05:13 +00:00
|
|
|
|
/** set_process_permissions(): Setzt die effektive uid/gid des Pro- **/
|
|
|
|
|
/** zesses und die umask. **/
|
1998-06-17 16:38:44 +00:00
|
|
|
|
/*************************************************************************/
|
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
int set_process_permissions(uid_t uid, gid_t gid, int mask)
|
1998-06-17 16:38:44 +00:00
|
|
|
|
{
|
1998-07-06 09:05:13 +00:00
|
|
|
|
log_line(LOG_D, "Setting effective permissions to %d.%d [%04o]...\n", uid, gid, mask);
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
if (setegid(gid) == 0)
|
1998-06-17 16:38:44 +00:00
|
|
|
|
{
|
1998-07-06 09:05:13 +00:00
|
|
|
|
if (seteuid(uid) == 0)
|
1998-06-17 16:38:44 +00:00
|
|
|
|
{
|
1998-07-06 09:05:13 +00:00
|
|
|
|
if (mask != 0) umask(mask);
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
return(0);
|
1998-06-17 16:38:44 +00:00
|
|
|
|
}
|
1998-07-06 09:05:13 +00:00
|
|
|
|
else log_line(LOG_E, "Can't set effective uid to %d!\n", uid);
|
1998-06-17 16:38:44 +00:00
|
|
|
|
}
|
1998-07-06 09:05:13 +00:00
|
|
|
|
else log_line(LOG_E, "Can't set effective gid to %d!\n", gid);
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
return(-1);
|
1998-06-17 16:38:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
/*************************************************************************/
|
|
|
|
|
/** pid_create(): Erzeugt die PID Datei f<>r den getty. **/
|
|
|
|
|
/*************************************************************************/
|
|
|
|
|
/** => name Name der Datei. **/
|
|
|
|
|
/*************************************************************************/
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
static void pid_create(char *name)
|
|
|
|
|
{
|
|
|
|
|
FILE *pptr;
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
log_line(LOG_D, "Creating \"%s\"...\n", name);
|
|
|
|
|
|
|
|
|
|
if ((pptr = fopen(name, "w")))
|
|
|
|
|
{
|
|
|
|
|
fprintf(pptr, "%ld\n", getpid());
|
|
|
|
|
fclose(pptr);
|
|
|
|
|
}
|
|
|
|
|
}
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
/*************************************************************************/
|
|
|
|
|
/** pid_remove(): L<>scht die PID Datei des getty. **/
|
|
|
|
|
/*************************************************************************/
|
|
|
|
|
/** => name Name der Datei. **/
|
|
|
|
|
/*************************************************************************/
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
static void pid_remove(char *name)
|
|
|
|
|
{
|
|
|
|
|
log_line(LOG_D, "Removing \"%s\"...\n", name);
|
1998-06-17 16:38:44 +00:00
|
|
|
|
|
1998-07-06 09:05:13 +00:00
|
|
|
|
remove(name);
|
|
|
|
|
}
|