- 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.
This commit is contained in:
michael 1998-07-06 09:05:13 +00:00
parent abb82284a8
commit 65ba239115
31 changed files with 2080 additions and 443 deletions

View File

@ -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!

View File

@ -1 +1 @@
Michael Herold <michael@abadonna.mayn.de>
Michael 'Ghandi' Herold <michael@abadonna.mayn.de>

View File

@ -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 ###########################################

143
vbox3/vboxgetty/control.c Normal file
View File

@ -0,0 +1,143 @@
/*
** $Id: control.c,v 1.1 1998/07/06 09:05:18 michael Exp $
**
** Copyright 1996-1998 Michael 'Ghandi' Herold <michael@abadonna.mayn.de>
**
** $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 <stdio.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
#include <unistd.h>
#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);
}

20
vbox3/vboxgetty/control.h Normal file
View File

@ -0,0 +1,20 @@
/*
** $Id: control.h,v 1.1 1998/07/06 09:05:20 michael Exp $
**
** Copyright 1996-1998 Michael 'Ghandi' Herold <michael@abadonna.mayn.de>
*/
#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 */

View File

@ -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 #####################################################

View File

@ -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 ############################################

View File

@ -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
}
}

View File

@ -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

View File

@ -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 <michael@abadonna.mayn.de>
** Copyright 1996-1998 Michael 'Ghandi' Herold <michael@abadonna.mayn.de>
**
** $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 <stdlib.h>
#include <stdio.h>
#include <string.h>
@ -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. **/
/*************************************************************************/

View File

@ -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 <michael@abadonna.mayn.de>
*/
#ifndef _VBOX_LIBMODEM_H
#define _VBOX_LIBMODEM_H 1
#include <unistd.h>
#include <errno.h>
/** 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);

140
vbox3/vboxgetty/lock.c Normal file
View File

@ -0,0 +1,140 @@
/*
** $Id: lock.c,v 1.1 1998/07/06 09:05:23 michael Exp $
**
** Copyright 1996-1998 Michael 'Ghandi' Herold <michael@abadonna.mayn.de>
**
** $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 <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <errno.h>
#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);
}

15
vbox3/vboxgetty/lock.h Normal file
View File

@ -0,0 +1,15 @@
/*
** $Id: lock.h,v 1.1 1998/07/06 09:05:24 michael Exp $
**
** Copyright 1996-1998 Michael 'Ghandi' Herold <michael@abadonna.mayn.de>
*/
#ifndef _VBOX_LOCK_H
#define _VBOX_LOCK_H 1
/** Prototypes ***********************************************************/
extern int lock_create(char *);
extern int lock_remove(char *);
#endif /* _VBOX_LOCK_H */

View File

@ -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 <michael@abadonna.mayn.de>
** Copyright 1996-1998 Michael 'Ghandi' Herold <michael@abadonna.mayn.de>
**
** $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 <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#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)

View File

@ -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 <michael@abadonna.mayn.de>
*/
#ifndef _VBOX_LOG_H

View File

@ -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 <michael@abadonna.mayn.de>
** Copyright 1996-1998 Michael 'Ghandi' Herold <michael@abadonna.mayn.de>
**
** $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 <sys/time.h>
# include <time.h>
@ -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);
}

View File

@ -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 <michael@abadonna.mayn.de>
*/
#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);

View File

@ -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 <michael@abadonna.mayn.de>
** Copyright 1996-1998 Michael 'Ghandi' Herold <michael@abadonna.mayn.de>
**
** $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 <stdlib.h>
#include <stdio.h>
#include <string.h>
@ -19,14 +30,16 @@
#include "rc.h"
/*************************************************************************/
/** rc_read(): Reads a configuration into the structure. **/
/** rc_read(): Liest eine Konfiguration vom Typ <name>=<value> 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);
}

View File

@ -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 <michael@abadonna.mayn.de>
*/
#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 */

View File

@ -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 <michael@abadonna.mayn.de>
** Copyright 1996-1998 Michael 'Ghandi' Herold <michael@abadonna.mayn.de>
**
** $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 <string.h>
#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);
}

View File

@ -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 <michael@abadonna.mayn.de>
*/
#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 */

View File

@ -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 <michael@abadonna.mayn.de>
** Copyright 1996-1998 Michael 'Ghandi' Herold <michael@abadonna.mayn.de>
**
** $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 <tcl.h>
#include <string.h>
#include <unistd.h>
#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);
}

View File

@ -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 <michael@abadonna.mayn.de>
*/
#ifndef _VBOX_TCLSCRIPT_H
#define _VBOX_TCLSCRIPT_H 1
#include <tcl.h>
#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 */

192
vbox3/vboxgetty/userrc.c Normal file
View File

@ -0,0 +1,192 @@
/*
** $Id: userrc.c,v 1.1 1998/07/06 09:05:33 michael Exp $
**
** Copyright 1996-1998 Michael 'Ghandi' Herold <michael@abadonna.mayn.de>
**
** $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 <stdio.h>
#include <string.h>
#include <fnmatch.h>
#include <pwd.h>
#include <grp.h>
#include <sys/types.h>
#include <sys/stat.h>
#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);
}

38
vbox3/vboxgetty/userrc.h Normal file
View File

@ -0,0 +1,38 @@
/*
** $Id: userrc.h,v 1.1 1998/07/06 09:05:34 michael Exp $
**
** Copyright 1996-1998 Michael 'Ghandi' Herold <michael@abadonna.mayn.de>
*/
#ifndef _USERRC_H
#define _USERRC_H 1
#include <limits.h>
/** 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 */

View File

@ -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 <michael@abadonna.mayn.de>
** Copyright 1996-1998 Michael 'Ghandi' Herold <michael@abadonna.mayn.de>
**
** $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 <stdlib.h>
#include <stdio.h>
#include <getopt.h>
@ -20,21 +31,26 @@
#include <unistd.h>
#include <signal.h>
#include <limits.h>
#include "../config.h"
#include <errno.h>
#include <fnmatch.h>
#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);
}

View File

@ -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 <michael@abadonna.mayn.de>
*/
#ifndef _VBOXGETTY_H
@ -12,40 +12,21 @@
#include <limits.h>
#include <unistd.h>
#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 */

499
vbox3/vboxgetty/vboxrc.c Normal file
View File

@ -0,0 +1,499 @@
/*
** $Id: vboxrc.c,v 1.1 1998/07/06 09:05:37 michael Exp $
**
** Copyright 1996-1998 Michael 'Ghandi' Herold <michael@abadonna.mayn.de>
**
** $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 <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#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(&currenttime)))
{
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);
}

29
vbox3/vboxgetty/vboxrc.h Normal file
View File

@ -0,0 +1,29 @@
/*
** $Id: vboxrc.h,v 1.1 1998/07/06 09:05:38 michael Exp $
**
** Copyright 1996-1998 Michael 'Ghandi' Herold <michael@abadonna.mayn.de>
*/
#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 */

View File

@ -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 <michael@abadonna.mayn.de>
** Copyright 1996-1998 Michael 'Ghandi' Herold <michael@abadonna.mayn.de>
**
** $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 <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#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 \"<DLE><ETX>\" to stop playback mode...\n");
vboxmodem_raw_write(&vboxmodem, voicestoppl, 2);
log_line(LOG_D, "Sending \"<DLE><DC4>\" 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;

View File

@ -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 <michael@abadonna.mayn.de>
*/
#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 <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# 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);