diff --git a/vbox3/INSTALL-CVS b/vbox3/INSTALL-CVS index ed93bc58..b2737c1d 100644 --- a/vbox3/INSTALL-CVS +++ b/vbox3/INSTALL-CVS @@ -5,10 +5,13 @@ complete the package. Before you compile do the following steps from the main directory: -% autoheader % aclocal +% autoheader % autoconf % automake This will create all needed files not included with the copy of the CVS tree. + +Note: aclocal must be call before autoheader or some define's will not be + created! \ No newline at end of file diff --git a/vbox3/vboxgetty/AUTHORS b/vbox3/vboxgetty/AUTHORS index d72fe3c7..0560596a 100644 --- a/vbox3/vboxgetty/AUTHORS +++ b/vbox3/vboxgetty/AUTHORS @@ -1 +1 @@ -Michael Herold +Michael 'Ghandi' Herold diff --git a/vbox3/vboxgetty/Makefile.am b/vbox3/vboxgetty/Makefile.am index 4767b317..64f41e44 100644 --- a/vbox3/vboxgetty/Makefile.am +++ b/vbox3/vboxgetty/Makefile.am @@ -1,5 +1,5 @@ ## -## vboxgetty/Makefile.am - (C) 1997-1998 Michael Herold +## $Id: Makefile.am,v 1.3 1998/07/06 09:05:17 michael Exp $ ## ## system admin executables to install #################################### @@ -15,7 +15,7 @@ packagepiddir = @packagepiddir@ tclpackagelibs = @LINK_TCL_LIBS@ tclpackageinclude = @LINK_TCL_INCL@ -DEFS += -DSYSCONFDIR='"$(sysconfdir)"' -DDATADIR='"$(datadir)"' -DLOGDIR='"$(packagelogdir)"' -DLOCKDIR='"$(packagelockdir)"' -DPIDDIR='"$(packagepiddir)"' +DEFS += -DSYSCONFDIR='"$(sysconfdir)"' -DPKGDATADIR='"$(pkgdatadir)"' -DLOGDIR='"$(packagelogdir)"' -DLOCKDIR='"$(packagelockdir)"' -DPIDDIR='"$(packagepiddir)"' INCLUDES = $(all_includes) $(tclpackageinclude) ## vbox low level modem library ########################################### @@ -31,10 +31,14 @@ vboxgetty_LDADD = $(tclpackagelibs) -L. -lvboxmodem vboxgetty_SOURCES = log.c log.h \ modem.c modem.h \ rc.c rc.h \ + vboxrc.c vboxrc.h \ + userrc.c userrc.h \ stringutils.c stringutils.h \ tclscript.c tclscript.h \ vboxgetty.c vboxgetty.h \ - voice.c voice.h + voice.c voice.h \ + control.c control.h \ + lock.c lock.h ## other directories to process ########################################### diff --git a/vbox3/vboxgetty/control.c b/vbox3/vboxgetty/control.c new file mode 100644 index 00000000..d1a3c2e7 --- /dev/null +++ b/vbox3/vboxgetty/control.c @@ -0,0 +1,143 @@ +/* +** $Id: control.c,v 1.1 1998/07/06 09:05:18 michael Exp $ +** +** Copyright 1996-1998 Michael 'Ghandi' Herold +** +** $Log: control.c,v $ +** Revision 1.1 1998/07/06 09:05:18 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. +** +*/ + +#include "../config.h" + +#include +#include +#include +#include +#include + +#include "control.h" +#include "stringutils.h" +#include "log.h" + +/** Variablen ************************************************************/ + +static char ctrlpathname[PATH_MAX + 1]; +static char ctrllastline[VBOX_CTRL_MAX_RCLINE + 1]; + +/*************************************************************************/ +/** ctrl_exists(): Untersucht ob eine Kontrolldatei existiert und **/ +/** gibt deren Inhalt zurück. **/ +/*************************************************************************/ +/** => home Homeverzeichnis des Benutzers. **/ +/** => name Name der Kontrolldatei (ohne vboxctrl-). **/ +/** **/ +/** <= NULL wenn die Datei nicht gelesen werden konnte **/ +/** oder ein Zeiger auf deren Initstring. **/ +/*************************************************************************/ + +char *ctrl_exists(char *home, char *name) +{ + FILE *cptr; + char *stop; + + printstring(ctrlpathname, "%s/vboxctrl-%s", home, name); + + if ((cptr = fopen(ctrlpathname, "r"))) + { + if (fgets(ctrllastline, VBOX_CTRL_MAX_RCLINE, cptr)) + { + ctrllastline[strlen(ctrllastline) - 1] = '\0'; + + if ((stop = index(ctrllastline, '\r'))) *stop = '\0'; + + fclose(cptr); + return(ctrllastline); + } + + fclose(cptr); + } + + return(NULL); +} + +/*************************************************************************/ +/** ctrl_create(): Erzeugt eine Kontrolldatei und schreibt den Init- **/ +/** string. **/ +/*************************************************************************/ +/** => home Homeverzeichnis des Benutzers. **/ +/** => name Name der Kontrolldatei (ohne vboxctrl-). **/ +/** => init Initstring. **/ +/** **/ +/** <= 0 wenn die Datei erzeugt werden konnte oder -1 bei **/ +/** einem Fehler. **/ +/*************************************************************************/ + +int ctrl_create(char *home, char *name, char *init) +{ + FILE *cptr = NULL; + int loop = 5; + + printstring(ctrlpathname, "%s/vboxctrl-%s", home, name); + + while (loop > 0) + { + log_line(LOG_D, "Creating control \"vboxctrl-%s:%s\"...\n", name, init); + + if ((cptr = fopen(ctrlpathname, "w"))) + { + fprintf(cptr, "%s\n", init); + fclose(cptr); + return(0); + } + + usleep(500); + + loop--; + } + + log_line(LOG_E, "Can't create \"%s\".\n", ctrlpathname); + + return(-1); +} + +/*************************************************************************/ +/** ctrl_remove(): Löscht eine Kontrolldatei. **/ +/*************************************************************************/ +/** => home Homeverzeichnis des Benutzers. **/ +/** => name Name der Kontrolldatei (ohne vboxctrl-). **/ +/** **/ +/** <= 0 wenn die Datei gelöscht werden konnte oder -1 **/ +/** bei einem Fehler. **/ +/*************************************************************************/ + +int ctrl_remove(char *home, char *name) +{ + int loop = 5; + + printstring(ctrlpathname, "%s/vboxctrl-%s", home, name); + + while (loop > 0) + { + log_line(LOG_D, "Removing control \"vboxctrl-%s\"...\n", name); + + if (remove(ctrlpathname) == 0) return(0); + + if (errno == ENOENT) return(0); + + usleep(500); + + loop--; + } + + log_line(LOG_E, "Can't remove \"%s\".\n", ctrlpathname); + + return(-1); +} diff --git a/vbox3/vboxgetty/control.h b/vbox3/vboxgetty/control.h new file mode 100644 index 00000000..d6cb3ddc --- /dev/null +++ b/vbox3/vboxgetty/control.h @@ -0,0 +1,20 @@ +/* +** $Id: control.h,v 1.1 1998/07/06 09:05:20 michael Exp $ +** +** Copyright 1996-1998 Michael 'Ghandi' Herold +*/ + +#ifndef _VBOX_CONTROL_H +#define _VBOX_CONTROL_H 1 + +/** Defines **************************************************************/ + +#define VBOX_CTRL_MAX_RCLINE 64 + +/** Prototypes ***********************************************************/ + +extern char *ctrl_exists(char *, char *); +extern int ctrl_create(char *, char *, char *); +extern int ctrl_remove(char *, char *); + +#endif /* _VBOX_CONTROL_H */ diff --git a/vbox3/vboxgetty/examples/Makefile.am b/vbox3/vboxgetty/examples/Makefile.am index 4f69f2d5..21ed3099 100644 --- a/vbox3/vboxgetty/examples/Makefile.am +++ b/vbox3/vboxgetty/examples/Makefile.am @@ -1,5 +1,5 @@ ## -## vboxgetty/examples/Makefile.am - (C) 1997-1998 Michael Herold +## $Id: Makefile.am,v 1.4 1998/07/06 09:05:49 michael Exp $ ## ## Other directories ##################################################### diff --git a/vbox3/vboxgetty/examples/scripts/Makefile.am b/vbox3/vboxgetty/examples/scripts/Makefile.am index e36ebd62..211cbf77 100644 --- a/vbox3/vboxgetty/examples/scripts/Makefile.am +++ b/vbox3/vboxgetty/examples/scripts/Makefile.am @@ -1,5 +1,5 @@ ## -## vboxgetty/examples/scripts/Makefile.am - (C) 1997-1998 Michael Herold +## $Id: Makefile.am,v 1.4 1998/07/06 09:05:55 michael Exp $ ## ## The tcl scripts to install ############################################ diff --git a/vbox3/vboxgetty/examples/scripts/initmodem.tcl b/vbox3/vboxgetty/examples/scripts/initmodem.tcl index 80076122..88bdd0c2 100644 --- a/vbox3/vboxgetty/examples/scripts/initmodem.tcl +++ b/vbox3/vboxgetty/examples/scripts/initmodem.tcl @@ -1,4 +1,4 @@ -# $Id: initmodem.tcl,v 1.1 1998/06/17 16:47:34 michael Exp $ +# $Id: initmodem.tcl,v 1.2 1998/07/06 09:05:56 michael Exp $ #----------------------------------------------------------------------# # This script is called every time the modem should be initialized. If # # the script produce errors (syntax error or the command "error"), the # @@ -15,7 +15,7 @@ if { [vbox_modem_command "$vbxv_init" "OK"] > 0 } { if { [vbox_modem_command "$vbxv_initnumber" "OK"] > 0 } { if { [vbox_modem_command "AT+FCLASS=8" "OK"] > 0 } { - if { [vbox_modem_command "ATS13.2=1S13.4=1" "OK"] > 0 } { + if { [vbox_modem_command "ATS13.2=1S13.4=1S13.6=0S13.7=1" "OK"] > 0 } { return } } diff --git a/vbox3/vboxgetty/examples/vboxgetty.user b/vbox3/vboxgetty/examples/vboxgetty.user index 963ba009..84810017 100644 --- a/vbox3/vboxgetty/examples/vboxgetty.user +++ b/vbox3/vboxgetty/examples/vboxgetty.user @@ -1,4 +1,4 @@ -# $Id: vboxgetty.user,v 1.1 1998/06/17 16:47:31 michael Exp $ +# $Id: vboxgetty.user,v 1.2 1998/07/06 09:05:50 michael Exp $ # # Number to user mapping. Please read the documentation to learn how this # configuration file work! @@ -7,4 +7,5 @@ # # Format: number:user:group:umask:freespace -784051[34]:michael:users:0077:2000000 +7840513:michael:users:0077:2000000 +7840514:nicole:users:0077:2000000 diff --git a/vbox3/vboxgetty/libvboxmodem.c b/vbox3/vboxgetty/libvboxmodem.c index b9055bb0..37cfc202 100644 --- a/vbox3/vboxgetty/libvboxmodem.c +++ b/vbox3/vboxgetty/libvboxmodem.c @@ -1,15 +1,26 @@ /* -** $Id: libvboxmodem.c,v 1.2 1998/06/17 17:01:19 michael Exp $ +** $Id: libvboxmodem.c,v 1.3 1998/07/06 09:05:21 michael Exp $ ** -** Copyright 1997-1998 by Michael Herold +** Copyright 1996-1998 Michael 'Ghandi' Herold ** ** $Log: libvboxmodem.c,v $ +** Revision 1.3 1998/07/06 09:05:21 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. +** ** Revision 1.2 1998/06/17 17:01:19 michael ** - First part of the automake/autoconf implementation. Currently vbox will ** *not* compile! ** */ +#include "../config.h" + #include #include #include @@ -105,18 +116,28 @@ int vboxmodem_open(struct vboxmodem *vbm, unsigned char *devicename) /** => vbm Pointer to the initialized modem structure **/ /*************************************************************************/ -void vboxmodem_close(struct vboxmodem *vbm) +int vboxmodem_close(struct vboxmodem *vbm) { - if (vbm->fd != -1) close(vbm->fd); - if (vbm->devicename ) free(vbm->devicename); if (vbm->input ) free(vbm->input); if (vbm->nocarriertxt) free(vbm->nocarriertxt); - vbm->fd = -1; vbm->devicename = NULL; vbm->input = NULL; vbm->nocarriertxt = NULL; + + if (vbm->fd != -1) + { + if (close(vbm->fd) == -1) + { + set_modem_error("Can't close modem device!"); + + return(-1); + } + else vbm->fd = -1; + } + + return(0); } /*************************************************************************/ @@ -262,15 +283,15 @@ static void vboxmodem_raw_mode(TIO *modemtio) } /*************************************************************************/ -/** vboxmodem_speed(): Sets speed to 57600. **/ +/** vboxmodem_speed(): Sets speed to 38400. **/ /*************************************************************************/ /** => modemtio Pointer to a terminal io structure **/ /*************************************************************************/ static void vboxmodem_speed(TIO *modemtio) { - cfsetospeed(modemtio, B57600); - cfsetispeed(modemtio, B57600); + cfsetospeed(modemtio, B38400); + cfsetispeed(modemtio, B38400); } /*************************************************************************/ @@ -286,7 +307,6 @@ static void vboxmodem_flowcontrol(TIO *modemtio) modemtio->c_cflag |= (CRTSCTS); } - /*************************************************************************/ /** vboxmodem_check_nocarrier(): Checks for carrier lost. **/ /*************************************************************************/ diff --git a/vbox3/vboxgetty/libvboxmodem.h b/vbox3/vboxgetty/libvboxmodem.h index 46fc4e16..eda8398f 100644 --- a/vbox3/vboxgetty/libvboxmodem.h +++ b/vbox3/vboxgetty/libvboxmodem.h @@ -1,13 +1,14 @@ /* -** $Id: libvboxmodem.h,v 1.1 1998/06/17 16:38:46 michael Exp $ +** $Id: libvboxmodem.h,v 1.2 1998/07/06 09:05:22 michael Exp $ ** -** Copyright 1997-1998 by Michael 'Ghandi' Herold +** Copyright 1996-1998 Michael 'Ghandi' Herold */ #ifndef _VBOX_LIBMODEM_H #define _VBOX_LIBMODEM_H 1 #include +#include /** Defines **************************************************************/ @@ -36,7 +37,7 @@ struct vboxmodem /** Prototypes ***********************************************************/ extern int vboxmodem_open(struct vboxmodem *, unsigned char *); -extern void vboxmodem_close(struct vboxmodem *); +extern int vboxmodem_close(struct vboxmodem *); extern unsigned char *vboxmodem_error(void); extern int vboxmodem_raw_read(struct vboxmodem *, unsigned char *, int); extern size_t vboxmodem_raw_write(struct vboxmodem *, unsigned char *, int); diff --git a/vbox3/vboxgetty/lock.c b/vbox3/vboxgetty/lock.c new file mode 100644 index 00000000..e1bdc4aa --- /dev/null +++ b/vbox3/vboxgetty/lock.c @@ -0,0 +1,140 @@ +/* +** $Id: lock.c,v 1.1 1998/07/06 09:05:23 michael Exp $ +** +** Copyright 1996-1998 Michael 'Ghandi' Herold +** +** $Log: lock.c,v $ +** Revision 1.1 1998/07/06 09:05:23 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. +** +*/ + +#include "../config.h" + +#include +#include +#include +#include +#include + +#include "lock.h" +#include "log.h" + +/*************************************************************************/ +/** lock_create(): Erzeugt einen Lock. **/ +/*************************************************************************/ +/** => name Name der Lockdatei. **/ +/** **/ +/** <= 0 wenn der Lock erzeugt werden konnte oder -1 wenn **/ +/** nicht. **/ +/*************************************************************************/ + +int lock_create(char *name) +{ + char line[32]; + FILE *lptr; + long lock; + int loop; + + log_line(LOG_D, "Creating lock \"%s\"...\n", name); + + lock = -1; + loop = 5; + + /* Prüfen ob der Lock bereits existiert. Wenn ja wird die */ + /* PID eingelesen. */ + + if (access(name, F_OK) == 0) + { + if ((lptr = fopen(name, "r"))) + { + if (fgets(line, 32, lptr)) + { + line[strlen(line) - 1] = '\0'; + + lock = xstrtol(line, -1); + } + + fclose(lptr); + } + else + { + log_line(LOG_E, "Lock exists but can not be opened.\n"); + + return(-1); + } + } + + /* Wenn der Lock existiert, wird ein Signal 0 an den ent- */ + /* sprechenden Prozeß geschickt um herauszufinden ob dieser */ + /* noch existiert. */ + + if (lock > 1) + { + if (kill(lock, 0) == 0) + { + log_line(LOG_E, "Lock exists - pid %ld is running.\n", lock); + + return(-1); + } + else log_line(LOG_D, "Lock exists - pid %ld not running.\n", lock); + } + + /* Der Lock existierte nicht, die Datei wird neu ange- */ + /* legt. */ + + while (loop > 0) + { + if ((lptr = fopen(name, "w"))) + { + fprintf(lptr, "%010ld\n", getpid()); + fclose(lptr); + return(0); + } + + usleep(500); + + loop--; + } + + log_line(LOG_E, "Can't create lock \"%s\".\n", name); + + return(-1); +} + +/*************************************************************************/ +/** lock_remove(): Entfernt einen Lock. **/ +/*************************************************************************/ +/** => name Name der Lockdatei. **/ +/** **/ +/** <= 0 wenn der Lock entfernt werden konnte oder -1 **/ +/** wenn nicht. **/ +/*************************************************************************/ + +int lock_remove(char *name) +{ + int loop = 5; + + log_line(LOG_D, "Removing lock \"%s\"...\n", name); + + while (loop > 0) + { + if (remove(name) == 0) return(0); + + if (errno == ENOENT) return(0); + + usleep(500); + + loop--; + } + + log_line(LOG_E, "Can't remove lock \"%s\".\n", name); + + return(-1); +} diff --git a/vbox3/vboxgetty/lock.h b/vbox3/vboxgetty/lock.h new file mode 100644 index 00000000..38d59e31 --- /dev/null +++ b/vbox3/vboxgetty/lock.h @@ -0,0 +1,15 @@ +/* +** $Id: lock.h,v 1.1 1998/07/06 09:05:24 michael Exp $ +** +** Copyright 1996-1998 Michael 'Ghandi' Herold +*/ + +#ifndef _VBOX_LOCK_H +#define _VBOX_LOCK_H 1 + +/** Prototypes ***********************************************************/ + +extern int lock_create(char *); +extern int lock_remove(char *); + +#endif /* _VBOX_LOCK_H */ diff --git a/vbox3/vboxgetty/log.c b/vbox3/vboxgetty/log.c index ced2bcc7..8bcdcb2a 100644 --- a/vbox3/vboxgetty/log.c +++ b/vbox3/vboxgetty/log.c @@ -1,21 +1,42 @@ /* -** $Id: log.c,v 1.2 1998/06/17 17:01:20 michael Exp $ +** $Id: log.c,v 1.3 1998/07/06 09:05:25 michael Exp $ ** -** Copyright 1997-1998 by Michael Herold +** Copyright 1996-1998 Michael 'Ghandi' Herold ** ** $Log: log.c,v $ +** Revision 1.3 1998/07/06 09:05:25 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. +** ** Revision 1.2 1998/06/17 17:01:20 michael ** - First part of the automake/autoconf implementation. Currently vbox will ** *not* compile! ** */ +#include "../config.h" + +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + #include #include #include #include #include -#include #include "voice.h" #include "log.h" @@ -35,10 +56,12 @@ static struct logsequence logsequence[] = }; /*************************************************************************/ -/** log_open(): Opens the log. **/ +/** log_open(): Öffnet die Logdatei im append mode. **/ /*************************************************************************/ -/** => name Name of the ttyI (appended to real logname) **/ -/** <= 0 on success or -1 on error **/ +/** => name Name der Logdatei. **/ +/** **/ +/** <= 0 wenn die Datei geöffnet werden konnte oder -1 bei **/ +/** einem Fehler. **/ /*************************************************************************/ int log_open(char *name) @@ -49,7 +72,7 @@ int log_open(char *name) } /*************************************************************************/ -/** log_close(): Close the log. **/ +/** log_close(): Schließt eine mit log_open() geöffnete Logdatei. **/ /*************************************************************************/ void log_close(void) @@ -60,7 +83,9 @@ void log_close(void) } /*************************************************************************/ -/** **/ +/** log_set_debuglevel(): Setzt den Logdebuglevel. **/ +/*************************************************************************/ +/** => level Debuglevel der gesetzt werden soll. **/ /*************************************************************************/ void log_set_debuglevel(int level) @@ -69,12 +94,11 @@ void log_set_debuglevel(int level) } /*************************************************************************/ -/** log_line(): Writes a line to the log including the current date & **/ -/** time and the log level. **/ +/** log_line(): Schreibt Text mit vorangestelltem Datum in den Log. **/ /*************************************************************************/ -/** => level Debuglevel **/ -/** => fmt Formatstring **/ -/** => ... Args **/ +/** => level Debuglevel unter dem der Text ausgegeben werden soll. **/ +/** => fmt Formatstring. **/ +/** => ... Argumente für den Formatstring. **/ /*************************************************************************/ void log_line(int level, char *fmt, ...) @@ -138,10 +162,12 @@ void log_line(int level, char *fmt, ...) } /*************************************************************************/ -/** log_char(): Writes a char to the log. **/ +/** log_char(): Schreibt ein einzelnes Zeichen in den Log. Einige **/ +/** nicht darstellbare Zeichen werden dabei ersetzt. **/ /*************************************************************************/ -/** => level Debuglevel **/ -/** => c Char to log **/ +/** => level Debuglevel unter dem das Zeichen ausgegeben werden **/ +/** soll. **/ +/** => c Zeichen das ausgegeben werden soll. **/ /*************************************************************************/ void log_char(int level, char c) @@ -173,11 +199,12 @@ void log_char(int level, char c) } /*************************************************************************/ -/** log_text(): Writes a line to the log. **/ +/** log_text(): Schreibt Text in den Log. Die Funktion verhält sich **/ +/** wie log_line(); es wird kein Datum vorangestellt. **/ /*************************************************************************/ -/** => level Debuglevel **/ -/** => fmt Formatstring **/ -/** => ... Args **/ +/** => level Debuglevel unter dem der Text ausgegeben werden soll. **/ +/** => fmt Formatstring. **/ +/** => ... Argumente für den Formatstring. **/ /*************************************************************************/ void log_text(int level, char *fmt, ...) @@ -198,10 +225,11 @@ void log_text(int level, char *fmt, ...) } /*************************************************************************/ -/** log_code(): Writes a line with log_char() to the log. **/ +/** log_code(): Schreibt einen String mittels log_char() in den Log. **/ /*************************************************************************/ -/** => level Debuglevel **/ -/** => sequence Sequence of chars to log **/ +/** => level Debuglevel unter dem der String ausgegeben werden **/ +/** soll. **/ +/** => sequence String der ausgegeben werden soll. **/ /*************************************************************************/ void log_code(int level, char *sequence) diff --git a/vbox3/vboxgetty/log.h b/vbox3/vboxgetty/log.h index 948f9dca..8424fa6b 100644 --- a/vbox3/vboxgetty/log.h +++ b/vbox3/vboxgetty/log.h @@ -1,7 +1,7 @@ /* -** $Id: log.h,v 1.1 1998/06/17 16:38:47 michael Exp $ +** $Id: log.h,v 1.2 1998/07/06 09:05:26 michael Exp $ ** -** Copyright 1997-1998 by Michael 'Ghandi' Herold +** Copyright 1996-1998 Michael 'Ghandi' Herold */ #ifndef _VBOX_LOG_H diff --git a/vbox3/vboxgetty/modem.c b/vbox3/vboxgetty/modem.c index 74d8e0c5..de85d3ef 100644 --- a/vbox3/vboxgetty/modem.c +++ b/vbox3/vboxgetty/modem.c @@ -1,15 +1,26 @@ /* -** $Id: modem.c,v 1.2 1998/06/17 17:01:21 michael Exp $ +** $Id: modem.c,v 1.3 1998/07/06 09:05:26 michael Exp $ ** -** Copyright 1997-1998 by Michael Herold +** Copyright 1996-1998 Michael 'Ghandi' Herold ** ** $Log: modem.c,v $ +** Revision 1.3 1998/07/06 09:05:26 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. +** ** Revision 1.2 1998/06/17 17:01:21 michael ** - First part of the automake/autoconf implementation. Currently vbox will ** *not* compile! ** */ +#include "../config.h" + #if TIME_WITH_SYS_TIME # include # include @@ -34,30 +45,38 @@ #include "log.h" #include "modem.h" #include "libvboxmodem.h" +#include "stringutils.h" -static struct modemsetup modemsetup = -{ - 4, /* Echo timeout (sec) */ - 4, /* Command timeout (sec) */ - 6, /* Ring timeout (sec) */ - 1800, /* Alive timeout (sec) */ - 400 /* Toggle DTR (ms) */ -}; +/** Variables ************************************************************/ static unsigned char lastmodemresult[VBOXMODEM_BUFFER_SIZE + 1]; static int timeoutstatus = 0; -static void modem_timeout_function(int); -static int modem_write(struct vboxmodem *, char *); -static int modem_get_echo(struct vboxmodem *, char *); -static int modem_get_rawsequence(struct vboxmodem *, char *, int); -static int modem_check_result(char *, char *); +/** Structures ***********************************************************/ + +struct modemsetup modemsetup = +{ + 4, /* Echo timeout (sec) */ + 4, /* Command timeout (sec) */ + 6, /* Ring timeout (sec) */ + 1800, /* Alive timeout (sec) */ + 400 /* Toggle DTR (ms) */ +}; + +/** Prototypes ***********************************************************/ + +static void modem_timeout_function(int); +static int modem_write(struct vboxmodem *, char *); +static int modem_get_echo(struct vboxmodem *, char *); +static int modem_get_rawsequence(struct vboxmodem *, char *, int); +static int modem_check_result(char *, char *); /*************************************************************************/ -/** modem_set_timeout(): Sets modem function timeout. **/ +/** modem_set_timeout(): Setzt den Timeout für die Modemfunctionen. **/ /*************************************************************************/ -/** => timeout Timeout in seconds **/ +/** => timeout Timeout in Sekunden. Bei Angabe von 0 wird **/ +/** ein bestehender Timeout gelöscht. **/ /*************************************************************************/ void modem_set_timeout(int timeout) @@ -78,9 +97,10 @@ void modem_set_timeout(int timeout) } /*************************************************************************/ -/** modem_get_timeout(): Returns the timeout status. **/ +/** modem_get_timeout(): Gibt zurück ob ein Timeout aufgetreten ist. **/ /*************************************************************************/ -/** <= 1 if timeout or 0 if not **/ +/** <= 1 wenn ein Timeout aufgetreten ist oder 0 **/ +/** wenn nicht. **/ /*************************************************************************/ int modem_get_timeout(void) @@ -89,10 +109,12 @@ int modem_get_timeout(void) } /*************************************************************************/ -/** modem_get_sequence(): Reads a specified sequence from the modem. **/ +/** modem_get_sequence(): Liest einen Text vom Modem. **/ /*************************************************************************/ -/** => seq Sequence to read **/ -/** <= 0 sequence read or -1 not read **/ +/** => seq Text der gelesen werden soll. **/ +/** **/ +/** <= 0 wenn der Text gelesen werden konnte oder **/ +/** -1 wenn nicht. **/ /*************************************************************************/ int modem_get_sequence(struct vboxmodem *vbm, char *seq) @@ -101,10 +123,10 @@ int modem_get_sequence(struct vboxmodem *vbm, char *seq) } /*************************************************************************/ -/** modem_flush(): Flushs modem input/output. **/ +/** modem_flush(): Leert die Modem-Eingabe/Ausgabe. **/ /*************************************************************************/ -/** => Pointer to modem structure **/ -/** => Flush timeout in seconds **/ +/** => vbm Zeiger auf die Modem-Struktur. **/ +/** => timeout Timeout in Sekunden. **/ /*************************************************************************/ void modem_flush(struct vboxmodem *vbm, int timeout) @@ -150,11 +172,12 @@ void modem_flush(struct vboxmodem *vbm, int timeout) } /*************************************************************************/ -/** modem_hangup(): Toggles the data terminal ready line to hangup the **/ -/** modem. **/ +/** modem_hangup(): Wechselt die DTR Leitung um das Modem aufzulegen. **/ /*************************************************************************/ -/** => vbm Pointer to modem structure **/ -/** <= 0 on success or -1 on error **/ +/** => vbm Zeiger auf die Modem-Struktur. **/ +/** **/ +/** <= 0 wenn das Modem aufgelegt werden konnte oder -1 **/ +/** wenn nicht. **/ /*************************************************************************/ int modem_hangup(struct vboxmodem *vbm) @@ -181,14 +204,17 @@ int modem_hangup(struct vboxmodem *vbm) } /*************************************************************************/ -/** modem_command(): Sends a command to the modem and waits for one or **/ -/** more results. **/ +/** modem_command(): Sendet ein Kommando zum Modem und wartet auf eine **/ +/** Rückantwort. **/ /*************************************************************************/ -/** => vbm Pointer to modem structure **/ -/** => command Command to send **/ -/** => result Needed answer(s) (seperater with '|') **/ -/** <= Number of the found answer, 0 nothing found, -1 on **/ -/** error **/ +/** => vbm Zeiger auf die Modem-Struktur. **/ +/** => command Kommando das gesendet werden soll. **/ +/** => result Rückantwort auf die gewartet werden soll. Mehrere **/ +/** Rückantworten können mit '|' getrennt angegeben **/ +/** werden. **/ +/** **/ +/** <= -1 bei einem Fehler, 0 wenn keine der Rückantwort- **/ +/** en gefunden wurde oder die Nummer der Rückantwort. **/ /*************************************************************************/ int modem_command(struct vboxmodem *vbm, char *command, char *result) @@ -272,11 +298,15 @@ int modem_command(struct vboxmodem *vbm, char *command, char *result) } /*************************************************************************/ -/** modem_read(): Reads a terminated string from the modem. **/ +/** modem_read(): Liest einen terminierten String vom Modem. **/ /*************************************************************************/ -/** => vbm Pointer to modem structure **/ -/** => line Pointer to write buffer **/ -/** => readtimeout Timeout in seconds **/ +/** => vbm Zeiger auf die Modem-Struktur. **/ +/** => line Speicherbereich in den der String gelesen werden **/ +/** soll. **/ +/** => readtimeout Timeout in Sekunden. **/ +/** **/ +/** <= 0 wenn der String gelesen werden konnte oder -1 **/ +/** wenn nicht. **/ /*************************************************************************/ int modem_read(struct vboxmodem *vbm, char *line, int readtimeout) @@ -326,9 +356,13 @@ int modem_read(struct vboxmodem *vbm, char *line, int readtimeout) return(0); } - /*************************************************************************/ -/** **/ +/** modem_wait(): Wartet auf einen eingehenden Anruf. **/ +/*************************************************************************/ +/** => vbm Zeiger auf die Modem-Struktur. **/ +/** **/ +/** <= 0 wenn ein eingehender Anruf anliegt oder -1 bei **/ +/** Timeout/Fehler. **/ /*************************************************************************/ int modem_wait(struct vboxmodem *vbm) @@ -339,7 +373,7 @@ int modem_wait(struct vboxmodem *vbm) fd_set fd; int back; - log_line(LOG_D, "Waiting...\n"); + log_line(LOG_A, "Waiting...\n"); FD_ZERO(&fd); FD_SET(vbm->fd, &fd); @@ -369,34 +403,34 @@ int modem_wait(struct vboxmodem *vbm) return(0); } +/*************************************************************************/ +/** modem_set_nocarrier(): Setzt den NO CARRIER Status. **/ +/*************************************************************************/ +/** => vbm Zeiger auf die Modem-Struktur. **/ +/** => carrier 1 wenn ein Carrier anliegt oder 0. **/ +/*************************************************************************/ + void modem_set_nocarrier(struct vboxmodem *vbm, int carrier) { vbm->nocarrier = carrier; } +/*************************************************************************/ +/** modem_get_nocarrier(): Gibt den NO CARRIER Status zurück. **/ +/*************************************************************************/ +/** <= 1 wenn ein Carrier anliegt oder 0. **/ +/*************************************************************************/ + int modem_get_nocarrier(struct vboxmodem *vbm) { return(vbm->nocarrier); } - - - - - - - - - - - - - /*************************************************************************/ -/** modem_timeout_function(): Function called from timeout signal hand- **/ -/** ler. **/ +/** modem_timeout_function(): Funktion die bei einem Modem-Timeout ge- **/ +/** startet wird. **/ /*************************************************************************/ -/** => s Signal number **/ +/** => s Signalnummer. **/ /*************************************************************************/ static void modem_timeout_function(int s) @@ -410,10 +444,13 @@ static void modem_timeout_function(int s) } /*************************************************************************/ -/** modem_write(): Sends a null terminated string to the modem. **/ +/** modem_write(): Sendet einen 0-terminierten String zum Modem. **/ /*************************************************************************/ -/** => vbm Pointer to modem structure **/ -/** => s Terminated string to write **/ +/** => vbm Zeiger auf die Modem-Struktur. **/ +/** => s String der gesendet werden soll. **/ +/** **/ +/** <= 0 wenn der String gesendet werden konnte oder -1 **/ +/** bei einem Fehler. **/ /*************************************************************************/ static int modem_write(struct vboxmodem *vbm, char *s) @@ -423,12 +460,14 @@ static int modem_write(struct vboxmodem *vbm, char *s) return(-1); } - /*************************************************************************/ -/** modem_get_echo(): Reads modem echo. **/ +/** modem_get_echo(): Liest das Echo eines Modem-Kommandos. **/ /*************************************************************************/ -/** => vbm Pointer to modem structure **/ -/** => echo Command to get echo from **/ +/** => vbm Zeiger auf die Modem-Struktur. **/ +/** => echo Modem-Echo das erwartet wird. **/ +/** **/ +/** <= 0 wenn das Modem-Echo gelesen werden konnte **/ +/** oder -1 bei einem Fehler. **/ /*************************************************************************/ static int modem_get_echo(struct vboxmodem *vbm, char *echo) @@ -437,9 +476,7 @@ static int modem_get_echo(struct vboxmodem *vbm, char *echo) } /*************************************************************************/ -/** modem_get_rawsequence(): Reads a raw sequence from modem. This is **/ -/** a subroutine for modem_get_sequence() & **/ -/** modem_get_echo(). **/ +/** modem_get_rawsequence(): **/ /*************************************************************************/ static int modem_get_rawsequence(struct vboxmodem *vbm, char *line, int echo) @@ -492,7 +529,7 @@ static int modem_get_rawsequence(struct vboxmodem *vbm, char *line, int echo) } /*************************************************************************/ -/** modem_check_result(): Checks for a string in the modem result. **/ +/** modem_check_result(): **/ /*************************************************************************/ static int modem_check_result(char *have, char *need) @@ -506,8 +543,7 @@ static int modem_check_result(char *have, char *need) log_code(LOG_D, need); log_text(LOG_D, "\"... "); - strncpy(line, need, VBOXMODEM_BUFFER_SIZE); - line[VBOXMODEM_BUFFER_SIZE] = '\0'; + xstrncpy(line, need, VBOXMODEM_BUFFER_SIZE); more = strchr(line, '|'); word = strtok(line, "|"); @@ -537,12 +573,3 @@ static int modem_check_result(char *have, char *need) return(0); } - - - - - - - - - diff --git a/vbox3/vboxgetty/modem.h b/vbox3/vboxgetty/modem.h index 82d316f5..af2c0e80 100644 --- a/vbox3/vboxgetty/modem.h +++ b/vbox3/vboxgetty/modem.h @@ -1,7 +1,7 @@ /* -** $Id: modem.h,v 1.1 1998/06/17 16:38:49 michael Exp $ +** $Id: modem.h,v 1.2 1998/07/06 09:05:27 michael Exp $ ** -** Copyright 1997-1998 by Michael 'Ghandi' Herold +** Copyright 1996-1998 Michael 'Ghandi' Herold */ #ifndef _VBOX_MODEM_H @@ -9,15 +9,15 @@ #include "libvboxmodem.h" +/** Defines **************************************************************/ + #define VBOXMODEM_STAT_INIT 0 #define VBOXMODEM_STAT_WAIT 1 #define VBOXMODEM_STAT_RING 2 #define VBOXMODEM_STAT_TEST 3 #define VBOXMODEM_STAT_EXIT 255 - - - +/** Structures ***********************************************************/ struct modemsetup { @@ -26,15 +26,11 @@ struct modemsetup int ringtimeout; int alivetimeout; int toggle_dtr_time; - - - - }; +extern struct modemsetup modemsetup; - - +/** Prototypes ***********************************************************/ extern void modem_set_timeout(int); extern int modem_get_timeout(void); diff --git a/vbox3/vboxgetty/rc.c b/vbox3/vboxgetty/rc.c index e059d148..1fe41272 100644 --- a/vbox3/vboxgetty/rc.c +++ b/vbox3/vboxgetty/rc.c @@ -1,15 +1,26 @@ /* -** $Id: rc.c,v 1.2 1998/06/17 17:01:22 michael Exp $ +** $Id: rc.c,v 1.3 1998/07/06 09:05:28 michael Exp $ ** -** Copyright 1997-1998 by Michael Herold +** Copyright 1996-1998 Michael 'Ghandi' Herold ** ** $Log: rc.c,v $ +** Revision 1.3 1998/07/06 09:05:28 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. +** ** Revision 1.2 1998/06/17 17:01:22 michael ** - First part of the automake/autoconf implementation. Currently vbox will ** *not* compile! ** */ +#include "../config.h" + #include #include #include @@ -19,14 +30,16 @@ #include "rc.h" /*************************************************************************/ -/** rc_read(): Reads a configuration into the structure. **/ +/** rc_read(): Liest eine Konfiguration vom Typ = ein. **/ /*************************************************************************/ -/** => rc Configuration structure **/ -/** => rcname Name of the configuration to read **/ -/** => section Name of the section to jump to **/ -/** <= 0 success **/ -/** <= -1 unable to open **/ -/** <= -2 section not found **/ +/** => rc Zeiger auf die Konfigurations-Struktur. **/ +/** => rcname Name der Konfiguration die eingelesen werden soll. **/ +/** => section Sektion zu der gesprungen werden soll (im Moment **/ +/** nicht unterstützt). **/ +/** **/ +/** <= 0 wenn die Konfiguration eingelesen wurde, -1 bei **/ +/** einem Fehler und -2 wenn die Sektion nicht gefunden **/ +/** wurde. **/ /*************************************************************************/ int rc_read(struct vboxrc *rc, char *rcname, char *section) @@ -56,7 +69,6 @@ int rc_read(struct vboxrc *rc, char *rcname, char *section) if ((section) && (rcsjump == 0)) { - continue; } @@ -81,7 +93,9 @@ int rc_read(struct vboxrc *rc, char *rcname, char *section) } /*************************************************************************/ -/** **/ +/** rc_free(): Gibt den Speicher einer Konfigurations-Struktur frei. **/ +/*************************************************************************/ +/** => rc Zeiger auf die Konfigurations-Struktur. **/ /*************************************************************************/ void rc_free(struct vboxrc *rc) @@ -98,6 +112,16 @@ void rc_free(struct vboxrc *rc) } } +/*************************************************************************/ +/** rc_get_entry(): Gibt den Wert eines Konfigurations-Eintrags zu- **/ +/** rück. **/ +/*************************************************************************/ +/** => rc Zeiger auf die Konfigurations-Struktur. **/ +/** => name Name des Eintrags dessen Wert man haben möchte. **/ +/** **/ +/** <= Wert des Eintrages oder NULL. **/ +/*************************************************************************/ + unsigned char *rc_get_entry(struct vboxrc *rc, char *name) { int i = 0; @@ -113,7 +137,13 @@ unsigned char *rc_get_entry(struct vboxrc *rc, char *name) } /*************************************************************************/ -/** **/ +/** rc_set_entry(): Setzt den Wert eines Konfigurations-Eintrags. **/ +/*************************************************************************/ +/** => rc Zeiger auf die Konfigurations-Struktur. **/ +/** => name Name des Eintrags dessen Wert gesetzt werden soll. **/ +/** => value Wert der gesetzt werden soll. **/ +/** **/ +/** <= Wert des Eintrags oder NULL. **/ /*************************************************************************/ unsigned char *rc_set_entry(struct vboxrc *rc, char *name, char *value) @@ -156,6 +186,13 @@ unsigned char *rc_set_entry(struct vboxrc *rc, char *name, char *value) return(NULL); } +/*************************************************************************/ +/** rc_set_empty(): Setzt den Wert eines Konfigurations-Eintrags wenn **/ +/** dieser noch keinen Wert enthält. **/ +/*************************************************************************/ +/** Siehe rc_set_entry(). **/ +/*************************************************************************/ + unsigned char *rc_set_empty(struct vboxrc *rc, char *name, char *value) { int i = 0; @@ -174,4 +211,3 @@ unsigned char *rc_set_empty(struct vboxrc *rc, char *name, char *value) return(NULL); } - diff --git a/vbox3/vboxgetty/rc.h b/vbox3/vboxgetty/rc.h index 3d369dac..b310ed12 100644 --- a/vbox3/vboxgetty/rc.h +++ b/vbox3/vboxgetty/rc.h @@ -1,25 +1,30 @@ /* -** $Id: rc.h,v 1.1 1998/06/17 16:38:50 michael Exp $ +** $Id: rc.h,v 1.2 1998/07/06 09:05:29 michael Exp $ ** -** Copyright 1997-1998 by Michael 'Ghandi' Herold +** Copyright 1996-1998 Michael 'Ghandi' Herold */ #ifndef _VBOX_RC_H #define _VBOX_RC_H 1 +/** Defines **************************************************************/ + #define VBOX_MAX_RCLINE_SIZE 255 +/** Structures ***********************************************************/ + struct vboxrc { unsigned char *name; unsigned char *value; }; +/** Prototypes ***********************************************************/ + extern int rc_read(struct vboxrc *, char *, char *); extern void rc_free(struct vboxrc *); extern unsigned char *rc_get_entry(struct vboxrc *, char *); extern unsigned char *rc_set_entry(struct vboxrc *, char *, char *); extern unsigned char *rc_set_empty(struct vboxrc *, char *, char *); - #endif /* _VBOX_RC_H */ diff --git a/vbox3/vboxgetty/stringutils.c b/vbox3/vboxgetty/stringutils.c index b74c4fbd..30ed03cd 100644 --- a/vbox3/vboxgetty/stringutils.c +++ b/vbox3/vboxgetty/stringutils.c @@ -1,25 +1,32 @@ /* -** $Id: stringutils.c,v 1.2 1998/06/17 17:01:23 michael Exp $ +** $Id: stringutils.c,v 1.3 1998/07/06 09:05:30 michael Exp $ ** -** Copyright 1997-1998 by Michael Herold +** Copyright 1996-1998 Michael 'Ghandi' Herold ** ** $Log: stringutils.c,v $ +** Revision 1.3 1998/07/06 09:05:30 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. +** ** Revision 1.2 1998/06/17 17:01:23 michael ** - First part of the automake/autoconf implementation. Currently vbox will ** *not* compile! ** */ +#include "../config.h" + #include #include "stringutils.h" /*************************************************************************/ -/** xstrncpy(): Copy one string to another (length limited). **/ -/*************************************************************************/ -/** => dest Destination **/ -/** => source Source **/ -/** => max Destination buffer length **/ +/** xstrncpy(): **/ /*************************************************************************/ void xstrncpy(char *dest, char *source, int max) @@ -30,11 +37,7 @@ void xstrncpy(char *dest, char *source, int max) } /*************************************************************************/ -/** xstrtol(): Converts a string to a number. **/ -/*************************************************************************/ -/** => string String to convert **/ -/** => number Default number if string can not converted **/ -/** <= Number **/ +/** xstrtol(): **/ /*************************************************************************/ long xstrtol(char *string, long number) @@ -51,3 +54,22 @@ long xstrtol(char *string, long number) return(number); } + +/*************************************************************************/ +/** xstrtoo(): **/ +/*************************************************************************/ + +long xstrtoo(char *string, long number) +{ + long back; + char *stop; + + if (string) + { + back = strtol(string, &stop, 8); + + if (*stop == '\0') return(back); + } + + return(number); +} diff --git a/vbox3/vboxgetty/stringutils.h b/vbox3/vboxgetty/stringutils.h index c543c985..02b48393 100644 --- a/vbox3/vboxgetty/stringutils.h +++ b/vbox3/vboxgetty/stringutils.h @@ -1,15 +1,20 @@ /* -** $Id: stringutils.h,v 1.1 1998/06/17 16:38:51 michael Exp $ +** $Id: stringutils.h,v 1.2 1998/07/06 09:05:30 michael Exp $ ** -** Copyright 1997-1998 by Michael 'Ghandi' Herold +** Copyright 1996-1998 Michael 'Ghandi' Herold */ #ifndef _VBOX_STRINGUTILS_H #define _VBOX_STRINGUTILS_H 1 +/** Defines **************************************************************/ + +#define printstring sprintf + /** Prototypes ***********************************************************/ extern void xstrncpy(char *, char *, int); extern long xstrtol(char *, long); +extern long xstrtoo(char *, long); #endif /* _VBOX_STRINGUTILS_H */ diff --git a/vbox3/vboxgetty/tclscript.c b/vbox3/vboxgetty/tclscript.c index f3e73d24..8086810a 100644 --- a/vbox3/vboxgetty/tclscript.c +++ b/vbox3/vboxgetty/tclscript.c @@ -1,9 +1,18 @@ /* -** $Id: tclscript.c,v 1.3 1998/06/18 12:38:17 michael Exp $ +** $Id: tclscript.c,v 1.4 1998/07/06 09:05:31 michael Exp $ ** -** Copyright 1997-1998 by Michael Herold +** Copyright 1996-1998 Michael 'Ghandi' Herold ** ** $Log: tclscript.c,v $ +** Revision 1.4 1998/07/06 09:05:31 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. +** ** Revision 1.3 1998/06/18 12:38:17 michael ** - 2nd part of the automake/autoconf implementation (now compiles again). ** @@ -13,15 +22,17 @@ ** */ +#include "../config.h" + #include #include #include -#include "config.h" #include "vboxgetty.h" #include "log.h" #include "modem.h" #include "tclscript.h" +#include "stringutils.h" static Tcl_Interp *interpreter = NULL; @@ -32,6 +43,7 @@ static Tcl_Interp *interpreter = NULL; int vbox_block(VBOX_TCLFUNC_PROTO); int vbox_log(VBOX_TCLFUNC_PROTO); int vbox_modem_command(VBOX_TCLFUNC_PROTO); +int vbox_voice(VBOX_TCLFUNC_PROTO); static struct vbox_tcl_function vbox_tcl_functions[] = @@ -39,6 +51,7 @@ static struct vbox_tcl_function vbox_tcl_functions[] = { "exit", vbox_block }, { "vbox_log", vbox_log }, { "vbox_modem_command", vbox_modem_command }, + { "vbox_voice" , vbox_voice }, { NULL, NULL } }; @@ -92,26 +105,27 @@ void scr_remove_interpreter(void) /** <= 0 on success or -1 on error **/ /*************************************************************************/ -int scr_execute(char *name, char *user) +int scr_execute(char *name, struct vboxuser *user) { int canrun = 0; if (user) { + printstring(temppathname, "%s/%s/scripts/%s", user->home, user->name, name); - canrun = 0; + if (access(temppathname, F_OK|R_OK) == 0) canrun = 1; } if (!canrun) { - printstring(temppathname, "%s/%s/%s", DATADIR, PACKAGE, name); + printstring(temppathname, "%s/%s", PKGDATADIR, name); if (access(temppathname, F_OK|R_OK) == 0) canrun = 1; } if (canrun) { - log_line(LOG_A, "Running \"%s\"...\n", temppathname); + log_line(LOG_D, "Running \"%s\"...\n", temppathname); if (Tcl_EvalFile(interpreter, temppathname) == TCL_OK) { @@ -272,12 +286,120 @@ int vbox_modem_command(VBOX_TCLFUNC) return(TCL_OK); } - - - - - - +/*************************************************************************/ +/** vbox_voice(): Tcl Kommando "vbox_voice". Die Funktion gibt immer **/ +/** TCL_OK zurück. Das Ergebnis der jeweiligen Funktion **/ +/** wird als Rückgabe des Tcl Kommandos geliefert. **/ +/*************************************************************************/ + +int vbox_voice(VBOX_TCLFUNC) +{ + char *cmd; + char *arg; + int rc; + int i; + + if (objc == 3) + { + cmd = Tcl_GetStringFromObj(objv[1], NULL); + arg = Tcl_GetStringFromObj(objv[2], NULL); + + if ((cmd) && (arg)) + { + switch (*cmd) + { + case 'W': + case 'w': + { + /* Zeitspanne warten und dabei auch eingehende */ + /* Daten vom Modem bearbeiten. */ + + switch (voice_wait(xstrtol(arg, 60))) + { + case 0: + Tcl_SetResult(intp, "OK", NULL); + break; + + case 1: + Tcl_SetResult(intp, "TOUCHTONE", NULL); + break; + + case 2: + Tcl_SetResult(intp, "SUSPEND", NULL); + break; + + default: + Tcl_SetResult(intp, "HANGUP", NULL); + break; + } + } + break; + + case 'P': + case 'p': + { + /* Nachricht(en) abspielen und dabei auch eingeh- */ + /* ende Daten vom Modem bearbeiten. */ + + } + break; + + case 'R': + case 'r': + { + /* Speicherung der Audiodaten starten/stoppen */ + /* (record). In diesem Fall wird ERROR bei ei- */ + /* nem Fehler oder OK zurückgegeben. */ + + if (strcasecmp(arg, "stop") == 0) rc = voice_save(0); + if (strcasecmp(arg, "start") == 0) rc = voice_save(1); + + switch (rc) + { + case 0: + Tcl_SetResult(intp, "OK", NULL); + break; + + default: + Tcl_SetResult(intp, "ERROR", NULL); + break; + } + } + break; + + case 'H': + case 'h': + { + /* Eingehende Audiodaten zum mithören an ein */ + /* anderes Device schicken. */ + + if (strcasecmp(arg, "stop") == 0) rc = voice_hear(0); + if (strcasecmp(arg, "local") == 0) rc = voice_hear(1); + + switch (rc) + { + case 0: + Tcl_SetResult(intp, "OK", NULL); + break; + + default: + Tcl_SetResult(intp, "ERROR", NULL); + break; + } + } + break; + + default: + { + Tcl_SetResult(intp, "ERROR", NULL); + } + break; + } + } + } + + return(TCL_OK); +} diff --git a/vbox3/vboxgetty/tclscript.h b/vbox3/vboxgetty/tclscript.h index 1d3c5a4a..2ae0fd00 100644 --- a/vbox3/vboxgetty/tclscript.h +++ b/vbox3/vboxgetty/tclscript.h @@ -1,13 +1,16 @@ /* -** $Id: tclscript.h,v 1.1 1998/06/17 16:38:53 michael Exp $ +** $Id: tclscript.h,v 1.2 1998/07/06 09:05:32 michael Exp $ ** -** Copyright 1997-1998 by Michael 'Ghandi' Herold +** Copyright 1996-1998 Michael 'Ghandi' Herold */ #ifndef _VBOX_TCLSCRIPT_H #define _VBOX_TCLSCRIPT_H 1 #include +#include "userrc.h" + +/** Structures ***********************************************************/ struct vbox_tcl_function { @@ -21,19 +24,17 @@ struct vbox_tcl_variable char *args; }; +/** Defines **************************************************************/ #define VBOX_TCLFUNC_PROTO ClientData, Tcl_Interp *, int, Tcl_Obj *CONST [] #define VBOX_TCLFUNC ClientData data, Tcl_Interp *intp, int objc, Tcl_Obj *CONST objv[] - /** Prototypes ***********************************************************/ extern int scr_create_interpreter(void); extern void scr_remove_interpreter(void); -extern int scr_execute(char *, char *); +extern int scr_execute(char *, struct vboxuser *); extern int scr_init_variables(struct vbox_tcl_variable *); - - extern char *scr_tcl_version(void); #endif /* _VBOX_TCLSCRIPT_H */ diff --git a/vbox3/vboxgetty/userrc.c b/vbox3/vboxgetty/userrc.c new file mode 100644 index 00000000..6c3de0f1 --- /dev/null +++ b/vbox3/vboxgetty/userrc.c @@ -0,0 +1,192 @@ +/* +** $Id: userrc.c,v 1.1 1998/07/06 09:05:33 michael Exp $ +** +** Copyright 1996-1998 Michael 'Ghandi' Herold +** +** $Log: userrc.c,v $ +** Revision 1.1 1998/07/06 09:05:33 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. +** +*/ + +#include "../config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "userrc.h" +#include "rc.h" +#include "stringutils.h" +#include "vboxgetty.h" +#include "log.h" + +/*************************************************************************/ +/** userrc_parse(): Liest die Datei "vboxgetty.user" ein. **/ +/*************************************************************************/ +/** => vboxuser Zeiger auf die User-Struktur. **/ +/** => home Spoolverzeichnis des Benutzers. **/ +/** => phone Lokale Telefonnummer die einem Benutzer zugewiesen **/ +/** werden soll. **/ +/** **/ +/** <= 0 wenn die Nummer einem Benutzer zugeordnet werden **/ +/** konnte oder -1 bei einem Fehler. **/ +/*************************************************************************/ + +int userrc_parse(struct vboxuser *vboxuser, char *home, char *phone) +{ + struct passwd *pwdent; + struct group *grpent; + char line[USERRC_MAX_RCLINE + 1]; + FILE *rc; + char *stop; + char *pattern; + char *group; + char *name; + char *space; + char *mask; + int linenr; + int havegroup; + + log_line(LOG_D, "Searching local user for number %s...\n", phone); + + printstring(temppathname, "%s/vboxgetty.user", SYSCONFDIR); + + if ((rc = fopen(temppathname, "r"))) + { + linenr = 0; + + while (fgets(line, USERRC_MAX_RCLINE, rc)) + { + linenr++; + + line[strlen(line) - 1] = '\0'; + + if ((*line == '\0') || (*line == '#')) continue; + + pattern = strtok(line, ":"); + name = strtok(NULL, ":"); + group = strtok(NULL, ":"); + mask = strtok(NULL, ":"); + space = strtok(NULL, ":"); + + if ((!pattern) || (!name) || (!group) || (!mask) || (!space)) + { + log_line(LOG_E, "Error in \"%s\" line %d.\n", temppathname, linenr); + + break; + } + + if (fnmatch(pattern, vboxuser->localphone, 0) == 0) + { + log_line(LOG_D, "Found - number matchs pattern \"%s\".\n", pattern); + + if (!*name) + { + log_line(LOG_E, "You *must* specify a user name or a user id!\n"); + + break; + } + + if (*name == '#') + pwdent = getpwuid((uid_t)xstrtol(&name[1], 0)); + else + pwdent = getpwnam(name); + + if (!pwdent) + { + log_line(LOG_E, "Unable to locate \"%s\" in systems passwd list.\n", name); + + break; + } + + vboxuser->uid = pwdent->pw_uid; + vboxuser->gid = pwdent->pw_gid; + + if ((strlen(home) + strlen(pwdent->pw_name) + 2) < (PATH_MAX - 100)) + { + xstrncpy(vboxuser->name, pwdent->pw_name, VBOXUSER_USERNAME); + + printstring(vboxuser->home, "%s/%s", home, pwdent->pw_name); + } + else + { + log_line(LOG_E, "Oops! Spool directory name and user name too long!\n"); + + break; + } + + if (*group) + { + havegroup = 0; + + setgrent(); + + while ((grpent = getgrent())) + { + if (*group == '#') + { + if (grpent->gr_gid == (gid_t)xstrtol(&group[1], 0)) + { + vboxuser->gid = grpent->gr_gid; + havegroup = 1; + + break; + } + } + else + { + if (strcmp(grpent->gr_name, group) == 0) + { + vboxuser->gid = grpent->gr_gid; + havegroup = 1; + + break; + } + } + } + + endgrent(); + + if (!havegroup) + { + log_line(LOG_E, "Unable to locate \"%s\" in systems group list.\n", group); + + break; + } + } + + vboxuser->space = xstrtol(space, 0); + vboxuser->umask = (mode_t)strtol(mask, &stop, 8); + + if (*stop != '\0') + { + log_line(LOG_E, "Illegal umask \"%s\" in line %d.\n", mask, linenr); + + break; + } + + fclose(rc); + + log_line(LOG_D, "User \"%s\" (%d.%d) will be used...\n", vboxuser->name, vboxuser->uid, vboxuser->gid); + + return(0); + } + } + + fclose(rc); + } + else log_line(LOG_W, "Can't open \"%s\".\n", temppathname); + + return(-1); +} diff --git a/vbox3/vboxgetty/userrc.h b/vbox3/vboxgetty/userrc.h new file mode 100644 index 00000000..0999b9a2 --- /dev/null +++ b/vbox3/vboxgetty/userrc.h @@ -0,0 +1,38 @@ +/* +** $Id: userrc.h,v 1.1 1998/07/06 09:05:34 michael Exp $ +** +** Copyright 1996-1998 Michael 'Ghandi' Herold +*/ + +#ifndef _USERRC_H +#define _USERRC_H 1 + +#include + +/** Defines **************************************************************/ + +#define USERRC_MAX_RCLINE 255 + +#define VBOXUSER_CALLID 64 +#define VBOXUSER_NUMBER 64 +#define VBOXUSER_USERNAME 64 + +/** Structures ***********************************************************/ + +struct vboxuser +{ + uid_t uid; + gid_t gid; + int umask; + long space; + char incomingid[VBOXUSER_CALLID + 1]; + char localphone[VBOXUSER_NUMBER + 1]; + char name[VBOXUSER_USERNAME + 1]; + char home[PATH_MAX + 1]; +}; + +/** Prototypes ***********************************************************/ + +extern int userrc_parse(struct vboxuser *, char *, char *); + +#endif /* _USERRC_H */ diff --git a/vbox3/vboxgetty/vboxgetty.c b/vbox3/vboxgetty/vboxgetty.c index 8fccde86..4b73557d 100644 --- a/vbox3/vboxgetty/vboxgetty.c +++ b/vbox3/vboxgetty/vboxgetty.c @@ -1,9 +1,18 @@ /* -** $Id: vboxgetty.c,v 1.3 1998/06/18 12:38:18 michael Exp $ +** $Id: vboxgetty.c,v 1.4 1998/07/06 09:05:35 michael Exp $ ** -** Copyright 1997-1998 by Michael Herold +** Copyright 1996-1998 Michael 'Ghandi' Herold ** ** $Log: vboxgetty.c,v $ +** 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. +** ** Revision 1.3 1998/06/18 12:38:18 michael ** - 2nd part of the automake/autoconf implementation (now compiles again). ** @@ -13,6 +22,8 @@ ** */ +#include "../config.h" + #include #include #include @@ -20,21 +31,26 @@ #include #include #include - -#include "../config.h" +#include +#include #include "log.h" #include "tcl.h" #include "modem.h" #include "rc.h" +#include "vboxrc.h" +#include "userrc.h" #include "voice.h" #include "stringutils.h" #include "tclscript.h" #include "vboxgetty.h" +#include "control.h" +#include "lock.h" /** Variables ************************************************************/ static char *progbasename; +static char *isdnttyname; char temppathname[PATH_MAX + 1]; @@ -50,6 +66,8 @@ static struct vboxrc rc_getty_c[] = { "echotimeout" , NULL }, { "ringtimeout" , NULL }, { "alivetimeout" , NULL }, + { "spooldir" , NULL }, + { "toggledtrtime" , NULL }, { NULL , NULL } }; @@ -66,12 +84,12 @@ struct vboxmodem vboxmodem; /** Prototypes ***********************************************************/ -static int parse_getty_rc(unsigned char *); -static void show_usage(int, int); -static int process_incoming_call(void); -static int run_modem_init(void); -static int parse_user_rc(struct vboxuser *); - +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); /*************************************************************************/ /** The magic main... **/ @@ -79,7 +97,6 @@ static int parse_user_rc(struct vboxuser *); void main(int argc, char **argv) { - char *isdnttyname; char *stop; int opts; char *debugstr; @@ -92,8 +109,8 @@ void main(int argc, char **argv) if ((stop = rindex(argv[0], '/'))) progbasename = ++stop; - /* Parse command line arguments and set the selected (or default) */ - /* debuglevel. */ + /* Die Argumente des Programms einlesen und den Debuglevel */ + /* setzen. */ debugstr = NULL; isdnttyname = NULL; @@ -155,9 +172,12 @@ void main(int argc, char **argv) log_set_debuglevel(debuglvl); } - /* Remove all before the last '/' from the tty name. And check if */ - /* the device is accessable (not really needed since we need root */ - /* privilegs to start). */ + umask(xstrtoo(VBOX_ROOT_UMASK, 0)); + + /* Pfadangaben vom Devicenamen abschneiden und überprüfen ob */ + /* das Device vom Benutzer gelesen und beschrieben werden */ + /* kann (eigentlich nicht nötig, da nur unter Rootrechten ge- */ + /* startet werden kann. */ if (isdnttyname) { @@ -179,9 +199,9 @@ void main(int argc, char **argv) show_usage(100, 1); } - /* Check if we start with root privilegs. The permissions will be */ - /* dropped later, but we need root privilegs to open tty's, logs */ - /* etc. */ + /* Prüfen ob das Programm unter Rootrechten gestartet wurde. Die */ + /* Rechte werden später auf die des jeweiligen Benutzers geän- */ + /* dert, zum Start sind aber Rootrechte nötig. */ if (getuid() != 0) { @@ -190,15 +210,15 @@ void main(int argc, char **argv) quit_program(100); } - /* Now its time to open the log. The name of the current tty will */ - /* be appended to the name. */ + /* Jetzt wird der Log geöffnet. Der Name des aktuellen Devices */ + /* wird an das Ende angehängt. */ printstring(temppathname, "%s/vboxgetty-%s.log", LOGDIR, isdnttyname); log_open(temppathname); - /* Start and initialize the tcl-interpreter (version 8.0 or */ - /* higher is required). */ + /* Tcl-Interpreter starten. Für die momentanen Funktionen wird */ + /* Version 8 oder höher benötigt. */ if (scr_create_interpreter() == -1) { @@ -209,22 +229,22 @@ void main(int argc, char **argv) log_line(LOG_I, "Running vbox version %s (with tcl version %s).\n", VERSION, scr_tcl_version()); - /* Read the vboxgetty runtime configuration. 1st the global */ - /* and 2nd the tty. */ + /* Konfiguration des getty's abarbeiten. Zuerst wird die globale, */ + /* dann die des jeweiligen tty's eingelesen. */ - if (parse_getty_rc(isdnttyname) == -1) + if (vboxgettyrc_parse(isdnttyname) == -1) { log_line(LOG_E, "Unable to read/parse configuration!\n"); quit_program(100); } - /* Open modem device and do the main loop (initialize, wait, */ - /* answer and alive check). */ + /* Modem Device öffnen und die interne Initialisierung */ + /* ausführen (nicht der normale Modeminit). */ printstring(temppathname, "/dev/%s", isdnttyname); - log_line(LOG_D, "Opening modem device \"%s\" (57600, CTS/RTS)...\n", temppathname); + log_line(LOG_D, "Opening modem device \"%s\" (38400, CTS/RTS)...\n", temppathname); if (vboxmodem_open(&vboxmodem, temppathname) == -1) { @@ -233,8 +253,26 @@ void main(int argc, char **argv) quit_program(100); } -signal(SIGINT , quit_program); -signal(SIGTERM, quit_program); + /* 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ä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! */ modemstate = VBOXMODEM_STAT_INIT; modeminits = 0; @@ -299,8 +337,11 @@ signal(SIGTERM, quit_program); modem_set_nocarrier(&vboxmodem, 0); process_incoming_call(); modem_hangup(&vboxmodem); - - modemstate = VBOXMODEM_STAT_INIT; + + if (set_process_permissions(0, 0, xstrtoo(VBOX_ROOT_UMASK, 0)) != 0) + modemstate = VBOXMODEM_STAT_EXIT; + else + modemstate = VBOXMODEM_STAT_INIT; break; @@ -318,15 +359,33 @@ signal(SIGTERM, quit_program); } /*************************************************************************/ -/** quit_program(): Frees all used resources and exist. **/ +/** quit_program(): Gibt alle belegten Resourcen frei und beendet das **/ +/** Programm. **/ /*************************************************************************/ -/** => rc Exit return code (1-99 reserved for signals) **/ +/** => rc Rückgabewert des Programms (1-99 ist reserviert). **/ /*************************************************************************/ void quit_program(int rc) { modem_hangup(&vboxmodem); - vboxmodem_close(&vboxmodem); + + 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); + } scr_remove_interpreter(); @@ -338,10 +397,12 @@ void quit_program(int rc) } /*************************************************************************/ -/** show_usage(): Shows usage/version message. **/ +/** show_usage(): Zeigt Benutzermeldung/Version an und beendet dann das **/ +/** Programm. **/ /*************************************************************************/ -/** => rc Exit return level (1-99 reserved for signals) **/ -/** => help 1 shows help message, 0 version string **/ +/** => rc Rückgabewert des Programms (1-99 ist reserviert). **/ +/** => help 1 wenn die Benutzermeldung oder 0 wenn die Version **/ +/** angezeigt werden soll. **/ /*************************************************************************/ static void show_usage(int rc, int help) @@ -366,9 +427,11 @@ static void show_usage(int rc, int help) } /*************************************************************************/ -/** run_modem_init(): Starts the tcl script to initialize the modem. **/ +/** run_modem_init(): Startet das Tcl-Skript zum initislisieren des **/ +/** Modems. **/ /*************************************************************************/ -/** <= 0 on success or -1 on error **/ +/** <= 0 wenn die Initialisierung geklappt hat, -1 bei **/ +/** einem Fehler. **/ /*************************************************************************/ static int run_modem_init(void) @@ -380,53 +443,50 @@ static int run_modem_init(void) { NULL , NULL } }; - log_line(LOG_A, "Initializing modem...\n"); + log_line(LOG_D, "Initializing modem...\n"); if (scr_init_variables(vars) == 0) { if (scr_execute("initmodem.tcl", NULL) == 0) return(0); } - log_line(LOG_E, "Can't initialize modem!\n"); + log_line(LOG_E, "Can't initialize modem device!\n"); return(-1); } +/*************************************************************************/ +/** 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. **/ +/*************************************************************************/ - - - - - - - - - -static int parse_getty_rc(unsigned char *tty) +static int vboxgettyrc_parse(unsigned char *tty) { - char *name; + printstring(temppathname, "%s/vboxgetty.conf", SYSCONFDIR); - log_line(LOG_A, "Reading configuration...\n"); - - name = "/usr/local/etc/vboxgetty.conf"; - - if (rc_read(rc_getty_c, name, NULL) < 0) + if (rc_read(rc_getty_c, temppathname, NULL) < 0) { if (errno != ENOENT) { - log_line(LOG_E, "Can't open \"%s\" (%s)!\n", name, strerror(errno)); + log_line(LOG_E, "Can't open \"%s\" (%s)!\n", temppathname, strerror(errno)); return(-1); } } - name = "/usr/local/etc/vboxgetty.conf.ttyI0"; + printstring(temppathname, "%s/vboxgetty.conf.%s", SYSCONFDIR, tty); - if (rc_read(rc_getty_c, name, NULL) < 0) + if (rc_read(rc_getty_c, temppathname, NULL) < 0) { if (errno != ENOENT) { - log_line(LOG_E, "Can't open \"%s\" (%s)!\n", name, strerror(errno)); + log_line(LOG_E, "Can't open \"%s\" (%s)!\n", temppathname, strerror(errno)); return(-1); } @@ -434,13 +494,21 @@ static int parse_getty_rc(unsigned char *tty) log_line(LOG_D, "Filling unset configuration variables with defaults...\n"); - 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, "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 ); if (!rc_get_entry(rc_getty_c, "initnumber")) { @@ -452,164 +520,215 @@ static int parse_getty_rc(unsigned char *tty) return(0); } - /*************************************************************************/ -/** **/ +/** process_incoming_call(): Bearbeitet einen eingehenden Anruf. **/ /*************************************************************************/ static int process_incoming_call(void) { - struct vboxuser vboxuser; + struct vboxuser vboxuser; + struct vboxcall vboxcall; + char line[VBOXMODEM_BUFFER_SIZE + 1]; + int haverings; + int waitrings; + int usersetup; + int ringsetup; + int inputisok; + char *stop; - char line[VBOXMODEM_BUFFER_SIZE + 1]; - int haverings; - int waitrings; - int havesetup; + memset(&vboxuser, 0, sizeof(vboxuser)); + memset(&vboxcall, 0, sizeof(vboxcall)); - haverings = 0; - waitrings = 0; - havesetup = 0; + haverings = 0; + waitrings = -1; + usersetup = 0; + ringsetup = 0; - while (modem_read(&vboxmodem, line, (int)xstrtol(rc_get_entry(rc_getty_c, "ringtimeout"), 6)) == 0) + while (modem_read(&vboxmodem, line, modemsetup.ringtimeout) == 0) { - if ((strncmp(line, "CALLER NUMBER: ", 15) == 0) && (!havesetup)) + inputisok = 0; + + /* Wenn der Benutzer der angerufenen Nummer ermittelt ist und */ + /* dessen Konfigurations abgearbeitet wurde, wird überprüft ob */ + /* der Anruf angenommen werden soll. */ + + if ((usersetup) && (ringsetup)) { - xstrncpy(vboxuser.incomingid, &line[15] , VBOXUSER_CALLID); - xstrncpy(vboxuser.localphone, "9317840513", VBOXUSER_NUMBER); - - if (parse_user_rc(&vboxuser) == 0) + if (waitrings >= 0) { - if ((vboxuser.uid == 0) || (vboxuser.gid == 0)) + if ((stop = ctrl_exists(vboxuser.home, "answer"))) { - log_line(LOG_W, "No user for ID %s found - call will be ignored!\n", vboxuser.incomingid); - - - - - + 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; + } + log_line(LOG_D, "Call will be answered after %d ring(s).\n", waitrings); } - - havesetup = 1; } - continue; + if (waitrings > 0) + { + if (haverings >= waitrings) + { + return(voice_init(&vboxuser, &vboxcall)); + } + } } - if (strcmp(line, "RING") == 0) + /* Ring abarbeiten: Beim ersten Ring wird die angerufene */ + /* Nummer gesichert, die durch ATS13.7=1 mit einem Slash */ + /* an den Ringstring angehängt ist. */ + + if (strncmp(line, "RING/", 5) == 0) { + inputisok++; haverings++; - if (havesetup) - log_line(LOG_A, "RING #%03d (%s)...\n", haverings, vboxuser.incomingid); - else - log_line(LOG_A, "RING #%03d...\n", haverings); + if (!ringsetup) + { + xstrncpy(vboxuser.localphone, &line[5], VBOXUSER_NUMBER); + + ringsetup = 1; + } + + log_line(LOG_A, "%s #%03d (%s)...\n", line, haverings, (usersetup ? vboxcall.name : "not known")); } - else + + /* CallerID aus dem Modeminput kopieren. Wenn bereits die */ + /* angerufene Nummer ermittelt wurde, wird einmalig die */ + /* Konfigurationsdatei des Benutzers abgearbeitet. */ + + if (strncmp(line, "CALLER NUMBER: ", 15) == 0) + { + inputisok++; + + if ((ringsetup) && (!usersetup)) + { + xstrncpy(vboxuser.incomingid, &line[15], VBOXUSER_CALLID); + + 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öscht. */ + + ctrl_remove(vboxuser.home, "suspend"); + + 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"); + } + } + + /* 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); + } + } + + if (!inputisok) { log_line(LOG_D, "Got junk line \""); log_code(LOG_D, line); log_text(LOG_D, "\"...\n"); + + continue; } } return(-1); } - /*************************************************************************/ -/** **/ +/** set_process_permissions(): Setzt die effektive uid/gid des Pro- **/ +/** zesses und die umask. **/ /*************************************************************************/ -static int parse_user_rc(struct vboxuser *vboxuser) +int set_process_permissions(uid_t uid, gid_t gid, int mask) { - char line[VBOX_RCLINE_SIZE + 1]; - FILE *rc; - char *stop; - char *pattern; - char *group; - char *name; - char *space; - char *mask; - int linenr; + log_line(LOG_D, "Setting effective permissions to %d.%d [%04o]...\n", uid, gid, mask); - log_line(LOG_D, "Searching local user for ID %s...\n", vboxuser->incomingid); - - vboxuser->uid = 0; - vboxuser->gid = 0; - vboxuser->home[0] = 0; - vboxuser->umask = -1; - vboxuser->space = -1; - - printstring(temppathname, "%s/vboxgetty.user", SYSCONFDIR); - - if ((rc = fopen(temppathname, "r"))) + if (setegid(gid) == 0) { - linenr = 0; - - while (fgets(line, VBOX_RCLINE_SIZE, rc)) + if (seteuid(uid) == 0) { - linenr++; - - line[strlen(line) - 1] = '\0'; + if (mask != 0) umask(mask); - if ((stop = rindex(line, '#'))) *stop = '\0'; - - while (strlen(line) > 0) - { - if ((line[strlen(line) - 1] != ' ') && (line[strlen(line) - 1] != '\t')) break; - - line[strlen(line) - 1] = '\0'; - } - - if (*line == '\0') continue; - - pattern = strtok(line, ":"); - name = strtok(NULL, ":"); - group = strtok(NULL, ":"); - mask = strtok(NULL, ":"); - space = strtok(NULL, ":"); - - if ((!pattern) || (!name) || (!group) || (!mask) || (!space)) - { - log_line(LOG_E, "Error in \"%s\" line %d.\n", temppathname, linenr); - - fclose(rc); - return(-1); - } - - - - - - - - + return(0); } - - fclose(rc); - } - else - { - log_line(LOG_W, "Can't open \"%s\".\n", temppathname); - - return(-1); + else log_line(LOG_E, "Can't set effective uid to %d!\n", uid); } + else log_line(LOG_E, "Can't set effective gid to %d!\n", gid); - return(0); + return(-1); } +/*************************************************************************/ +/** pid_create(): Erzeugt die PID Datei für den getty. **/ +/*************************************************************************/ +/** => name Name der Datei. **/ +/*************************************************************************/ +static void pid_create(char *name) +{ + FILE *pptr; + log_line(LOG_D, "Creating \"%s\"...\n", name); + + if ((pptr = fopen(name, "w"))) + { + fprintf(pptr, "%ld\n", getpid()); + fclose(pptr); + } +} +/*************************************************************************/ +/** pid_remove(): Löscht die PID Datei des getty. **/ +/*************************************************************************/ +/** => name Name der Datei. **/ +/*************************************************************************/ +static void pid_remove(char *name) +{ + log_line(LOG_D, "Removing \"%s\"...\n", name); - - - - - - - - + remove(name); +} diff --git a/vbox3/vboxgetty/vboxgetty.h b/vbox3/vboxgetty/vboxgetty.h index acb3fb41..e6b35772 100644 --- a/vbox3/vboxgetty/vboxgetty.h +++ b/vbox3/vboxgetty/vboxgetty.h @@ -1,7 +1,7 @@ /* -** $Id: vboxgetty.h,v 1.1 1998/06/17 16:38:54 michael Exp $ +** $Id: vboxgetty.h,v 1.2 1998/07/06 09:05:36 michael Exp $ ** -** Copyright 1997-1998 by Michael 'Ghandi' Herold +** Copyright 1996-1998 Michael 'Ghandi' Herold */ #ifndef _VBOXGETTY_H @@ -12,40 +12,21 @@ #include #include -#define VBOX_DEFAULT_SPOOLDIR "/var/spool/vbox" +/** Defines **************************************************************/ -#define VBOX_RCLINE_SIZE 255 +#define VBOX_ROOT_UMASK "0022" -#define VBOXUSER_CALLID 64 -#define VBOXUSER_NUMBER 64 +/** Variables ************************************************************/ extern char temppathname[PATH_MAX + 1]; +/** Structures ***********************************************************/ + extern struct vboxmodem vboxmodem; -struct vboxuser -{ - uid_t uid; - gid_t gid; - int umask; - long space; - char incomingid[VBOXUSER_CALLID + 1]; - char localphone[VBOXUSER_NUMBER + 1]; - char home[PATH_MAX + 1]; -}; - - - - - - - - - - -extern void quit_program(int); - -#define printstring sprintf +/** Prototypes ***********************************************************/ +extern void quit_program(int); +extern int set_process_permissions(uid_t, gid_t, int); #endif /* _VBOXGETTY_H */ diff --git a/vbox3/vboxgetty/vboxrc.c b/vbox3/vboxgetty/vboxrc.c new file mode 100644 index 00000000..01c2c150 --- /dev/null +++ b/vbox3/vboxgetty/vboxrc.c @@ -0,0 +1,499 @@ +/* +** $Id: vboxrc.c,v 1.1 1998/07/06 09:05:37 michael Exp $ +** +** Copyright 1996-1998 Michael 'Ghandi' Herold +** +** $Log: vboxrc.c,v $ +** Revision 1.1 1998/07/06 09:05:37 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. +** +*/ + +#include "../config.h" + +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + +#include +#include +#include +#include + +#include "vboxrc.h" +#include "log.h" +#include "stringutils.h" + +/** Variables ************************************************************/ + +static char *weekdaynames[] = +{ + "SO" , "MO" , "DI" , "MI" , "DO" , "FR" , "SA" , + "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT", + + NULL +}; + +/** Prototypes ***********************************************************/ + +static int vboxrc_check_user_section(FILE *, struct vboxcall *, char *); +static int vboxrc_goto_section(FILE *, char *); +static int vboxrc_parse_time(char *); +static int vboxrc_parse_days(char *); +static time_t vboxrc_return_time(time_t, char *, int); +static void vboxrc_return_timestr(time_t, char *); + +/*************************************************************************/ +/** vboxrc_parse(): Liest die "vboxrc" eines Benutzers ein und gibt **/ +/** die Anzahl der Klingelzeichen zurück nach denen **/ +/** der Anruf beantwortet werden soll. **/ +/*************************************************************************/ +/** => call Zeiger auf die Call-Struktur. **/ +/** => home Spoolverzeichnis des Benutzers. **/ +/** => id Eingegangene CallerID. **/ +/*************************************************************************/ + +int vboxrc_parse(struct vboxcall *call, char *home, char *id) +{ + char line[VBOXRC_MAX_RCLINE + 1]; + char name[PATH_MAX + 1]; + FILE *rc; + int nr; + char *dummy; + char *owner; + char *phone; + char *table; + int i; + + printstring(name, "%s/vboxrc", home); + + log_line(LOG_D, "Parsing \"%s\"...\n", name); + + xstrncpy(call->name , "*** Unknown ***", VBOXRC_MAX_RCLINE); + xstrncpy(call->section, "*** Unknown ***", VBOXRC_MAX_RCLINE); + xstrncpy(call->script , "answercall.tcl" , VBOXRC_MAX_RCLINE); + + call->ringring = 0; + call->tollring = 0; + call->savetime = 90; + + if ((rc = fopen(name, "r"))) + { + if (vboxrc_goto_section(rc, "[CALLERID]") == 0) + { + log_line(LOG_D, "Searching callerid \"%s\"...\n", id); + + while (fgets(line, (VBOXRC_MAX_RCLINE - 3), rc)) + { + line[strlen(line) - 1] = '\0'; + + if ((*line == '\0') || (*line == '#')) continue; + if ((*line == '[' ) || (*line == ']')) break; + + dummy = line; + owner = NULL; + table = NULL; + phone = NULL; + + while (isspace(*dummy)) dummy++; + + if ((*dummy) && (dummy)) phone = strsep(&dummy, "\t "); + + while (isspace(*dummy)) dummy++; + + if ((*dummy) && (phone)) table = strsep(&dummy, "\t "); + + while (isspace(*dummy)) dummy++; + + if ((*dummy) && (table)) owner = dummy; + + if ((owner) && (phone) && (table)) + { + if (fnmatch(phone, id, 0) == 0) + { + xstrncpy(call->name, owner, VBOXRC_MAX_RCLINE); + + switch (*table) + { + case '*': + printstring(call->section, "[%s]", "default"); + break; + + case '-': + printstring(call->section, "[%s]", owner); + break; + + default: + printstring(call->section, "[%s]", table); + break; + } + + log_line(LOG_D, "Found - name is \"%s\".\n", call->name); + + for (i = 0; i < strlen(call->section); i++) + { + call->section[i] = toupper(call->section[i]); + } + + nr = vboxrc_check_user_section(rc, call, call->section); + + fclose(rc); + return(nr); + } + } + } + + log_line(LOG_W, "Unable to locate \"%s\" settings.\n", id); + } + else log_line(LOG_W, "Can't seek to section \"[CALLERID]\".\n"); + + fclose(rc); + } + else log_line(LOG_W, "Can't open \"%s\".\n", name); + + return(0); +} + +/*************************************************************************/ +/** vboxrc_check_user_section(): **/ +/*************************************************************************/ + +static int vboxrc_check_user_section(FILE *rc, struct vboxcall *call, char *section) +{ + char line[VBOXRC_MAX_RCLINE + 1]; + char *time; + char *days; + char *name; + char *save; + char *ring; + char *toll; + char *stop; + + if (vboxrc_goto_section(rc, section) == 0) + { + while (fgets(line, (VBOXRC_MAX_RCLINE - 3), rc)) + { + line[strlen(line) - 1] = '\0'; + + if ((*line == '\0') || (*line == '#')) continue; + if ((*line == '[' ) || (*line == ']')) break; + + time = strtok(line, "\t "); + days = strtok(NULL, "\t "); + name = strtok(NULL, "\t "); + save = strtok(NULL, "\t "); + ring = strtok(NULL, "\t "); + toll = strtok(NULL, "\t "); + + if ((time) && (days) && (name) && (save) && (ring) && (toll)) + { + if (vboxrc_parse_time(time) == 0) + { + if (vboxrc_parse_days(days) == 0) + { + call->ringring = xstrtol(ring, 0); + call->tollring = xstrtol(toll, 0); + call->savetime = xstrtol(save, 0); + + if ((stop = rindex(name, '/'))) + { + stop++; + + xstrncpy(call->script, stop, VBOXRC_MAX_RCLINE); + } + else xstrncpy(call->script, name, VBOXRC_MAX_RCLINE); + + if (call->tollring > 0) + { + } + + return(call->ringring); + } + } + } + } + } + else log_line(LOG_W, "Can't seek to section \"%s\".\n", section); + + return(0); +} + +/*************************************************************************/ +/** vboxrc_goto_section(): **/ +/*************************************************************************/ + +static int vboxrc_goto_section(FILE *rc, char *section) +{ + char line[VBOXRC_MAX_RCLINE + 1]; + + log_line(LOG_D, "Seeking to section \"%s\"...\n", section); + + rewind(rc); + + while (fgets(line, (VBOXRC_MAX_RCLINE - 3), rc)) + { + line[strlen(line) - 1] = '\0'; + + if ((*line == '\0') || (*line == '#')) continue; + + if (strcasecmp(line, section) == 0) return(0); + } + + return(-1); +} + +/*************************************************************************/ +/** vboxrc_parse_time(): Checks if one or more timestring match the **/ +/** current time. **/ +/*************************************************************************/ + +static int vboxrc_parse_time(char *timestr) +{ + char timestring[VBOXRC_MAX_RCLINE + 1]; + char timevaluebeg[8 + 1]; + char timevalueend[8 + 1]; + char timevaluenow[8 + 1]; + char *timeptr; + char *timenxt; + char *timebeg; + char *timeend; + time_t timenow; + time_t timesecsbeg; + time_t timesecsend; + + log_line(LOG_D, "Parsing time(s) \"%s\"...\n", timestr); + + xstrncpy(timestring, timestr, VBOXRC_MAX_RCLINE); + + timeptr = timestring; + timenow = time(NULL); + + vboxrc_return_timestr(timenow, timevaluenow); + + if (strcmp(timestring, "*") == 0) + { + log_line(LOG_D, "Range **:**:** - **:**:** (%s): match.\n", timevaluenow); + + return(0); + } + + if ((strcmp(timestring, "!") == 0) || (strcmp(timestring, "-") == 0)) + { + log_line(LOG_D, "Range --:--:-- - --:--:-- (%s): don't match.\n", timevaluenow); + + return(-1); + } + + while (timeptr) + { + if ((timenxt = index(timeptr, ','))) *timenxt++ = '\0'; + + timebeg = timeptr; + timeend = index(timebeg, '-'); + + if (timeend) + *timeend++ = '\0'; + else + timeend = timebeg; + + if (!timeend) timeend = timebeg; + + timesecsbeg = vboxrc_return_time(timenow, timebeg, 0); + timesecsend = vboxrc_return_time(timenow, timeend, 1); + + if ((timesecsbeg > 0) && (timesecsend > 0)) + { + if ((timesecsend >= timesecsbeg)) + { + vboxrc_return_timestr(timesecsbeg, timevaluebeg); + vboxrc_return_timestr(timesecsend, timevalueend); + vboxrc_return_timestr(timenow , timevaluenow); + + log_line(LOG_D, "Range %s - %s (%s): ", timevaluebeg, timevalueend, timevaluenow); + + if ((timenow >= timesecsbeg) && (timenow <= timesecsend)) + { + log_text(LOG_D, "match.\n"); + + return(0); + } + else log_text(LOG_D, "don't match.\n"); + } + else log_line(LOG_W, "Bad time; start greater than end (%s-%s) - ignored...\n", timebeg, timeend); + } + else log_line(LOG_W, "Bad time; can't convert timestring (%s-%s) - ignored...\n", timebeg, timeend); + + timeptr = timenxt; + } + + log_line(LOG_D, "String contains no matching time!\n"); + + return(-1); +} + +/*************************************************************************/ +/** vboxrc_parse_days(): Checks if one or more daystrings match the **/ +/** current day. **/ +/*************************************************************************/ + +static int vboxrc_parse_days(char *strdays) +{ + struct tm *timelocal; + char *beg; + char *nxt; + char days[VBOXRC_MAX_RCLINE + 1]; + int i; + int d; + time_t currenttime; + + xstrncpy(days, strdays, VBOXRC_MAX_RCLINE); + + log_line(LOG_D, "Parsing day(s) \"%s\"...\n", days); + + if (strcmp(days, "*") == 0) + { + log_line(LOG_D, "Range *: match.\n"); + + return(0); + } + + if ((strcmp(days, "-") == 0) || (strcmp(days, "!") == 0)) + { + log_line(LOG_D, "Range -: don't match.\n"); + + return(-1); + } + + currenttime = time(NULL); + + if (!(timelocal = localtime(¤ttime))) + { + log_line(LOG_E, "Can't get local time (don't match)...\n"); + + return(-1); + } + + for (i = 0; i < strlen(days); i++) + { + if ((!isalpha(days[i])) && (days[i] != ',')) + { + log_line(LOG_E, "Error in day string \"%s\" (don't match).\n", days); + + return(-1); + } + } + + beg = days; + + while (beg) + { + if ((nxt = index(beg, ','))) *nxt++ = 0; + + d = 0; + i = 0; + + while (weekdaynames[i]) + { + if (strcasecmp(weekdaynames[i], beg) == 0) + { + if (d == timelocal->tm_wday) + { + log_line(LOG_D, "Range %s: match.\n", beg); + + return(0); + } + else log_line(LOG_D, "Range %s: don't match.\n", beg); + } + + d++; + i++; + + if (d >= 7) d = 0; + } + + beg = nxt; + } + + log_line(LOG_D, "String contains no matching day!\n"); + + return(-1); +} + +/*************************************************************************/ +/** vboxrc_return_time(): Converts a time string to seconds since the **/ +/** 1st januar 1970. **/ +/*************************************************************************/ + +static time_t vboxrc_return_time(time_t timenow, char *timestr, int mode) +{ + struct tm *locala; + struct tm localb; + + char timestring[5 + 1]; + char *hourstr; + char *minsstr; + int hourint; + int minsint; + int secsint; + + xstrncpy(timestring, timestr, 5); + + hourstr = timestring; + minsstr = index(hourstr, ':'); + + if (!minsstr) + { + if (mode == 0) minsstr = "00"; + if (mode != 0) minsstr = "59"; + } + else *minsstr++ = '\0'; + + if (mode == 0) secsint = 0; + else secsint = 59; + + hourint = atoi(hourstr); + minsint = atoi(minsstr); + + if ((hourint < 0) || (hourint > 23)) return(0); + if ((minsint < 0) || (minsint > 59)) return(0); + + if (!(locala = localtime(&timenow))) return(0); + + memcpy(&localb, locala, sizeof(struct tm)); + + localb.tm_sec = secsint; + localb.tm_min = minsint; + localb.tm_hour = hourint; + + return(mktime(&localb)); +} + +/*************************************************************************/ +/** vboxrc_return_timestr(): Converts a unix time into a string like **/ +/** HH:MM:SS. **/ +/*************************************************************************/ + +static void vboxrc_return_timestr(time_t timeint, char *timestr) +{ + struct tm *tm; + + if ((tm = localtime(&timeint))) + { + if (strftime(timestr, 20, "%H:%M:%S", tm) == 8) return; + } + + xstrncpy(timestr, "??:??:??", 8); +} diff --git a/vbox3/vboxgetty/vboxrc.h b/vbox3/vboxgetty/vboxrc.h new file mode 100644 index 00000000..f4fc58f6 --- /dev/null +++ b/vbox3/vboxgetty/vboxrc.h @@ -0,0 +1,29 @@ +/* +** $Id: vboxrc.h,v 1.1 1998/07/06 09:05:38 michael Exp $ +** +** Copyright 1996-1998 Michael 'Ghandi' Herold +*/ + +#ifndef _VBOXRC_H +#define _VBOXRC_H 1 + +/** Defines **************************************************************/ + +#define VBOXRC_MAX_RCLINE 255 + +/** Structures ***********************************************************/ + +struct vboxcall +{ + char section[VBOXRC_MAX_RCLINE + 1]; + char name[VBOXRC_MAX_RCLINE + 1]; + char script[VBOXRC_MAX_RCLINE + 1]; + int ringring; + int tollring; + int savetime; +}; + +/** Prototypes ***********************************************************/ + +#endif /* _VBOXRC_H */ + \ No newline at end of file diff --git a/vbox3/vboxgetty/voice.c b/vbox3/vboxgetty/voice.c index f73d5949..36a7d33b 100644 --- a/vbox3/vboxgetty/voice.c +++ b/vbox3/vboxgetty/voice.c @@ -1,55 +1,158 @@ /* -** $Id: voice.c,v 1.2 1998/06/17 17:01:26 michael Exp $ +** $Id: voice.c,v 1.3 1998/07/06 09:05:38 michael Exp $ ** -** Copyright 1997-1998 by Michael Herold +** Copyright 1996-1998 Michael 'Ghandi' Herold ** ** $Log: voice.c,v $ +** Revision 1.3 1998/07/06 09:05:38 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. +** ** Revision 1.2 1998/06/17 17:01:26 michael ** - First part of the automake/autoconf implementation. Currently vbox will ** *not* compile! ** */ +#ifdef HAVE_CONFIG_H +# include "../config.h" +#endif + +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + #include #include #include #include #include -#include "log.h" -#include "vboxgetty.h" -#include "modem.h" #include "voice.h" +#include "log.h" +#include "modem.h" +#include "stringutils.h" +#include "userrc.h" +#include "vboxrc.h" +#include "vboxgetty.h" +#include "tclscript.h" +#include "control.h" + +/** Variables ************************************************************/ + +static struct vboxuser *voicevboxuser; +static struct vboxcall *voicevboxcall; static int voicesave = -1; +static int voicevbox = 0; static int voicehear = -1; static int voicestat = VBOXVOICE_STAT_OK; -static char voicename[1000]; +static char voicename_ulaw[PATH_MAX + 1]; +static char voicename_vbox[PATH_MAX + 1]; -int voice_init(void) +/*************************************************************************/ +/** **/ +/*************************************************************************/ + +int voice_init(struct vboxuser *vboxuser, struct vboxcall *vboxcall) { - log_line(LOG_D, "Setting voice compression to \"ulaw\"...\n"); + char msgsavetime[32]; + char voicestoppl[2]; + char voicestoprc[2]; + time_t currenttime; + char *stop; + int rc; - if (modem_command(&vboxmodem, "AT+VSM=6+VLS=2", "OK") > 0) + struct vbox_tcl_variable vars[] = { - log_line(LOG_D, "Starting full duplex audio mode...\n"); + { "vbxv_savetime" , msgsavetime }, + { "vbxv_callerid" , vboxuser->incomingid }, + { "vbxv_callername" , vboxcall->name }, + { "vbxv_localphone" , vboxuser->localphone }, + { "vbxv_username" , vboxuser->name }, + { "vbxv_userhome" , vboxuser->home }, + { "vbxv_usedscript" , vboxcall->script }, + { "vbxv_saveulaw" , voicename_ulaw }, + { "vbxv_savevbox" , voicename_vbox }, + { NULL , NULL } + }; - if (modem_command(&vboxmodem, "AT+VTX+VRX", "CONNECT") > 0) + printstring(msgsavetime, "%d", vboxcall->savetime); + + /* Die beiden übergebenen Strukturen global machen, damit alle */ + /* Voice Funktionen sie benutzen können. */ + + voicevboxuser = vboxuser; + voicevboxcall = vboxcall; + + /* Die Namen der beiden Dateien (*.ulaw und *.vbox) erzeugen. */ + /* Eine Datei enthält die Audiodaten, die andere die Inform- */ + /* ationen über den Benutzer. */ + + currenttime = time(NULL); + + printstring(voicename_ulaw, "%s/incoming/%11.11lu-%8.8lu.ulaw", vboxuser->home, (unsigned long)currenttime, (unsigned long)getpid()); + printstring(voicename_vbox, "%s/incoming/%11.11lu-%8.8lu.vbox", vboxuser->home, (unsigned long)currenttime, (unsigned long)getpid()); + + /* Variablen für Tcl erzeugen, Kompression setzen, Full Duplex */ + /* Audio Modus starten und das Skript aufrufen. */ + + if (scr_init_variables(vars) == 0) + { + log_line(LOG_D, "Setting voice compression to \"ulaw\"...\n"); + + if (modem_command(&vboxmodem, "AT+VSM=6+VLS=2", "OK") > 0) { - /* start answer.tcl */ + log_line(LOG_D, "Starting full duplex audio mode...\n"); - printstring(voicename, "/tmp/vbox-1.ulaw"); + if (modem_command(&vboxmodem, "AT+VTX+VRX", "CONNECT") > 0) + { + rc = scr_execute(vboxcall->script, vboxuser); - voice_hear(1); - voice_save(1); + voice_hear(0); + voice_save(0); - voice_wait(30); - - voice_save(0); - voice_hear(0); + printstring(voicestoppl, "%c%c", DLE, ETX); + printstring(voicestoprc, "%c%c", DLE, DC4); - return(0); + log_line(LOG_D, "Sending \"\" to stop playback mode...\n"); + + vboxmodem_raw_write(&vboxmodem, voicestoppl, 2); + + log_line(LOG_D, "Sending \"\" to stop record mode...\n"); + + vboxmodem_raw_write(&vboxmodem, voicestoprc, 2); + + modem_flush(&vboxmodem, 0); + + if ((stop = ctrl_exists(vboxuser->home, "suspend"))) + { + ctrl_remove(vboxuser->home, "suspend"); + + log_line(LOG_A, "Suspending call to number %s...\n", stop); + + if (modem_command(&vboxmodem, "AT+S1", "OK") > 0) { + log_line(LOG_D, "Call suspended to number %s.\n", stop); + } else { + log_line(LOG_E, "Can't suspend call to number %s.\n", stop); + } + } + + return(rc); + } } } @@ -57,10 +160,16 @@ int voice_init(void) } /*************************************************************************/ -/** voice_wait(): Reads audio datas. **/ +/** voice_wait(): Liest eine angegebene Zeit lang Audiodaten vom Modem. **/ /*************************************************************************/ -/** => timeout Timeout in seconds **/ +/** => timeout Timeout in Sekunden **/ /*************************************************************************/ +/** <= 0 wenn der Timeout eingetreten ist. **/ +/** 1 wenn eine gültige Touchtonesequenz gefunden wurde. **/ +/** 2 wenn der Anruf suspended werden soll. **/ +/** -1 bei einem Fehler. **/ +/*************************************************************************/ + int voice_wait(int timeout) { @@ -77,7 +186,7 @@ int voice_wait(int timeout) if (voicesave == -1) log_line(LOG_D, "Reading audio datas (%ds timeout)...\n", timeout); else - log_line(LOG_D, "Recording \"%s\" (%ds timeout)...\n", voicename, timeout); + log_line(LOG_D, "Recording \"%s\" (%ds timeout)...\n", voicename_ulaw, timeout); modem_set_timeout(timeout); @@ -126,6 +235,8 @@ int voice_wait(int timeout) if (voicehear != -1) write(voicehear, line_o, byte_o); } + if (ctrl_exists(voicevboxuser->home, "suspend")) voicestat |= VBOXVOICE_STAT_SUSPEND; + if ((result != 1) || (modem_get_timeout())) { if (!modem_get_timeout()) @@ -138,11 +249,19 @@ int voice_wait(int timeout) } } + modem_set_timeout(0); + + result = 0; + if (voicestat & VBOXVOICE_STAT_TOUCHTONE) { log_line(LOG_D, "Full touchtone sequence found!\n"); + + result = 1; } + if (voicestat & VBOXVOICE_STAT_SUSPEND) result = 2; + if ((voicestat & VBOXVOICE_STAT_HANGUP) || (vboxmodem.nocarrier)) { log_line(LOG_D, "Remote hangup - audio output & saving stopped.\n"); @@ -151,42 +270,79 @@ int voice_wait(int timeout) voice_hear(0); modem_command(&vboxmodem, "", "NO CARRIER"); + + result = -1; } - - - - - - - - - - modem_set_timeout(0); - - return(0); + return(result); } - - /*************************************************************************/ -/** **/ +/** voice_save(): Schaltet das mitspeichern der eingehenden Audiodaten **/ +/** ein oder aus. **/ +/*************************************************************************/ +/** => save 1 wenn die Daten gespeichert werden sollen oder 0 **/ +/** wenn nicht. **/ +/** **/ +/** <= 0 wenn die Aktion ausgeführt werden konnte oder -1 **/ +/** einem Fehler. **/ /*************************************************************************/ int voice_save(int save) { + struct vboxsave vboxsave; + int desc; + if (save) { + log_line(LOG_D, "Starting audio recording...\n"); + + if (!voicevbox) + { + /* Wenn die *.vbox Datei noch nicht existiert wird sie */ + /* jetzt erzeugt. Die Datei enthält die Informationen */ + /* wer wann wie die Nachricht gesprochen hat. */ + + log_line(LOG_D, "Opening \"%s\"...\n", voicename_vbox); + + if ((desc = open(voicename_vbox, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) != -1) + { + vboxsave.time = time(NULL); + + xstrncpy(vboxsave.name , voicevboxcall->name , VBOXSAVE_NAME); + xstrncpy(vboxsave.id , voicevboxuser->incomingid, VBOXSAVE_ID ); + + if (write(desc, &vboxsave, sizeof(vboxsave)) == sizeof(vboxsave)) + { + voicevbox = 1; + } + + close(desc); + } + else log_line(LOG_E, "Can't create \"%s\".\n", voicename_vbox); + } + if (voicesave == -1) { - voicesave = open(voicename, O_WRONLY|O_CREAT|O_APPEND); + log_line(LOG_D, "Opening \"%s\"...\n", voicename_ulaw); + + voicesave = open(voicename_ulaw, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); } if (voicesave != -1) return(0); + + log_line(LOG_E, "Can't open/append \"%s\".\n", voicename_ulaw); } else { - if (voicesave != -1) close(voicesave); + log_line(LOG_D, "Stopping audio recording...\n"); + + if (voicesave != -1) + { + log_line(LOG_D, "Closing \"%s\"...\n", voicename_ulaw); + + close(voicesave); + } voicesave = -1; diff --git a/vbox3/vboxgetty/voice.h b/vbox3/vboxgetty/voice.h index ee925f2d..5e3652a0 100644 --- a/vbox3/vboxgetty/voice.h +++ b/vbox3/vboxgetty/voice.h @@ -1,18 +1,39 @@ /* -** $Id: voice.h,v 1.1 1998/06/17 16:38:56 michael Exp $ +** $Id: voice.h,v 1.2 1998/07/06 09:05:40 michael Exp $ ** -** Copyright 1997-1998 by Michael 'Ghandi' Herold +** Copyright 1996-1998 Michael 'Ghandi' Herold */ #ifndef _VBOX_VOICE_H #define _VBOX_VOICE_H 1 -#define VBOXVOICE_BUFFER_SIZE 32 +#ifdef HAVE_CONFIG_H +# include "../config.h" +#endif + +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + +#include "userrc.h" +#include "vboxrc.h" + +/** Defines **************************************************************/ + +#define VBOXVOICE_BUFFER_SIZE 32 #define VBOXVOICE_STAT_OK 0 #define VBOXVOICE_STAT_TIMEOUT 1 #define VBOXVOICE_STAT_HANGUP 2 #define VBOXVOICE_STAT_TOUCHTONE 4 +#define VBOXVOICE_STAT_SUSPEND 8 #define ETX (0x03) #define NL (0x0A) @@ -23,8 +44,21 @@ #define DC4 (0x14) #define CAN (0x18) +#define VBOXSAVE_NAME 64 +#define VBOXSAVE_ID 64 -extern int voice_init(void); +/** Structures ***********************************************************/ + +struct vboxsave +{ + time_t time; + char name[VBOXSAVE_NAME + 1]; + char id[VBOXSAVE_ID + 1]; +}; + +/** Prototypes ***********************************************************/ + +extern int voice_init(struct vboxuser *, struct vboxcall *); extern int voice_save(int); extern int voice_hear(int); extern int voice_wait(int);