From 1ccdcb1131e94a57845c62a4817f60f3a17a3a3c Mon Sep 17 00:00:00 2001 From: Stefan Luethje Date: Tue, 24 Jun 1997 23:35:40 +0000 Subject: [PATCH] isdnctrl can use a config file --- Makefile | 9 +- isdnctrl/Makefile.in | 17 +- isdnctrl/configure | 89 +++ isdnctrl/configure.in | 3 + isdnctrl/ctrlconf.c | 650 ++++++++++++++++ isdnctrl/ctrlconf.h | 60 ++ isdnctrl/isdnctrl.c | 1523 +++++++++++++++++++------------------- isdnctrl/isdnctrl.h | 151 ++++ isdnctrl/isdnctrl.man | 219 +++++- isdnlog/tools/isdnconf.c | 7 + scripts/config.in | 1 + scripts/defconfig | 1 + 12 files changed, 1961 insertions(+), 769 deletions(-) create mode 100644 isdnctrl/ctrlconf.c create mode 100644 isdnctrl/ctrlconf.h create mode 100644 isdnctrl/isdnctrl.h diff --git a/Makefile b/Makefile index a1a46fcc..222e9bff 100644 --- a/Makefile +++ b/Makefile @@ -23,6 +23,13 @@ do-it-all: config endif SUBDIRS := +ifeq ($(CONFIG_ISDNLOG),y) + SUBDIRS := $(SUBDIRS) lib +else + ifeq ($(CONFIG_CTRL_CONF),y) + SUBDIRS := $(SUBDIRS) lib + endif +endif ifeq ($(CONFIG_ISDNCTRL),y) SUBDIRS := $(SUBDIRS) isdnctrl endif @@ -55,7 +62,7 @@ ifeq ($(CONFIG_IMONTTY),y) SUBDIRS := $(SUBDIRS) imontty endif ifeq ($(CONFIG_ISDNLOG),y) - SUBDIRS := $(SUBDIRS) areacode lib isdnlog + SUBDIRS := $(SUBDIRS) areacode isdnlog else ifeq ($(CONFIG_LIB_AREACODE),y) SUBDIRS := $(SUBDIRS) areacode diff --git a/isdnctrl/Makefile.in b/isdnctrl/Makefile.in index 52d30c52..76e55c29 100644 --- a/isdnctrl/Makefile.in +++ b/isdnctrl/Makefile.in @@ -4,16 +4,19 @@ # (C) 1997 Fritz Elfert # # -SHELL = /bin/sh + + +SHELL = /bin/sh CFLAGS = -Wall -O2 -I. $(ISDN_INCLUDE) -LDFLAGS = -L../lib @LIBS@ +LDFLAGS = @LIBS@ +DBMLIB = @DBMLIB@ PROGRAM = isdnctrl MODULES = isdnctrl.o MANPAGE = isdnctrl.8 INSTALL = @INSTALL@ INSTALL_PROGRAM = $(INSTALL) -o 0 -g 0 -m 0750 INSTALL_MAN = $(INSTALL) -o 0 -g 0 -m 0644 -CC = @CC@ +CC = @CC@ -DVERSION=\"$(I4LVERSION)\" prefix = @prefix@ exec_prefix = @exec_prefix@ ifeq (../.config,$(wildcard ../.config)) @@ -26,6 +29,12 @@ else endif MAN8DIR = $(mandir)/man8 +ifdef CONFIG_CTRL_CONF +CC += -DI4L_CTRL_CONF +LDFLAGS += -L../lib -lisdn $(DBMLIB) +MODULES += ctrlconf.o +endif + .SUFFIXES: .SUFFIXES: .c .o @@ -35,7 +44,7 @@ config: @./configure $(PROGRAM): $(MODULES) - $(CC) $(CFLAGS) $? $(LDFLAGS) -o $@ + $(CC) $(CFLAGS) $(MODULES) $(LDFLAGS) -o $@ install-man: isdnctrl.man $(INSTALL) -d $(MAN8DIR) diff --git a/isdnctrl/configure b/isdnctrl/configure index 5d3f6e6f..c8728ebf 100755 --- a/isdnctrl/configure +++ b/isdnctrl/configure @@ -16,6 +16,11 @@ ac_default_prefix=/usr # Initialize some variables set by options. # The variables have the same names as the options, with # dashes changed to underlines. + +if test -r ../.config ; then + source ../.config +fi + build=NONE cache_file=./config.cache exec_prefix=NONE @@ -717,6 +722,88 @@ else fi +if test "$CONFIG_CTRL_CONF" = "y"; then +echo $ac_n "checking for -ldbm""... $ac_c" 1>&6 +ac_lib_var=`echo dbm'_'dbm_open | tr './+\055' '__p_'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldbm $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + DBMLIB=-ldbm; cat >> confdefs.h <<\EOF +#define HAVE_LIBDBM 1 +EOF + +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for -lgdbm""... $ac_c" 1>&6 +ac_lib_var=`echo gdbm'_'gdbm_open | tr './+\055' '__p_'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lgdbm $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + DBMLIB=-lgdbm; cat >> confdefs.h <<\EOF +#define HAVE_LIBGDBM 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + +fi +fi + echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 # On Suns, sometimes $CPP names a directory. @@ -1174,6 +1261,7 @@ s%@INSTALL_DATA@%$INSTALL_DATA%g s%@CC@%$CC%g s%@CPP@%$CPP%g s%@INSTALL@%$INSTALL%g +s%@DBMLIB@%$DBMLIB%g CEOF EOF @@ -1231,6 +1319,7 @@ s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g s%@INSTALL@%$INSTALL%g + " -f conftest.subs $ac_given_srcdir/$ac_file_in > $ac_file fi; done rm -f conftest.subs diff --git a/isdnctrl/configure.in b/isdnctrl/configure.in index 861dc070..f2ca4739 100644 --- a/isdnctrl/configure.in +++ b/isdnctrl/configure.in @@ -17,7 +17,10 @@ AC_CHECK_HEADER(linux/isdnif.h,,AC_MSG_ERROR("\nMissing linux/isdnif.h. Kernel s dnl Checks for typedefs, structures, and compiler characteristics. dnl Checks for library functions. +AC_CHECK_LIB(dbm, dbm_open, DBMLIB=-ldbm; AC_DEFINE(HAVE_LIBDBM), + AC_CHECK_LIB(gdbm, gdbm_open, DBMLIB=-lgdbm; AC_DEFINE(HAVE_LIBGDBM))) AC_TYPE_SIGNAL AC_SUBST(INSTALL) +AC_SUBST(DBMLIB) AC_OUTPUT(Makefile) diff --git a/isdnctrl/ctrlconf.c b/isdnctrl/ctrlconf.c new file mode 100644 index 00000000..438e61e6 --- /dev/null +++ b/isdnctrl/ctrlconf.c @@ -0,0 +1,650 @@ +/* $Id$ + * + * ISDN accounting for isdn4linux. (Utilities) + * + * Copyright 1995, 1997 by Stefan Luethje (luethje@sl-gw.lake.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Log$ + * + */ + +#include +#include +#include +#include +#include +#include + +#include "isdnctrl.h" +#include "ctrlconf.h" + +/*****************************************************************************/ + +#define PHONE(phone) ((isdn_net_ioctl_phone*) phone) + +/*****************************************************************************/ + +static int readinterfaces(int fd, section* CSec, section *PSec); +static char* readoptions(int fd, char *name, int is_master, section *CSec, section *PSec); +static int del_all_numbers(int fd, char *name, int direction); +static char* write_all_numbers(char *numbers); +static int set_all_numbers(int fd, char *name, int direction, char *numbers); +static int create_interface(int fd, char *name); +static int interface_exist(int fd, char *name); + +/*****************************************************************************/ + +int writeconfig(int fd, char *file) +{ + section *Section; + section *ConfigSection; + section *PhoneSection; + + ConfigSection = read_file(NULL,file,C_NOT_UNIQUE|C_NO_WARN_FILE); + read_conffiles(&PhoneSection,NULL); + + if ((Section = Set_Section(&ConfigSection,CONF_SEC_ISDNCTRL,C_OVERWRITE | C_WARN)) == NULL) + return -1; + + readinterfaces(fd,Section,PhoneSection); + + if (write_file(ConfigSection,file,cmd,VERSION) == NULL) + return -1; + + return 0; +} + +/*****************************************************************************/ + +static int readinterfaces(int fd, section* CSec, section *PSec) +{ + char name[10]; + FILE *iflst; + char s[BUFSIZ]; + char *p; + + if ((iflst = fopen("/proc/net/dev", "r")) == NULL) + { + perror("/proc/net/dev"); + return -1; + } + + while (!feof(iflst)) + { + fgets(s, sizeof(s), iflst); + + if ((p = strchr(s, ':'))) + { + *p = 0; + sscanf(s, "%s", name); + p = readoptions(fd, name, 1, CSec, PSec); + + while (p != NULL && *p != '\0') + { + strcpy(name, p); + p = readoptions(fd, name, 0, CSec, PSec); + } + } + } + + fclose(iflst); + + return 0; +} + +/*****************************************************************************/ + +static char* readoptions(int fd, char *name, int is_master, section *CSec, section *PSec) +{ + static isdn_net_ioctl_cfg cfg; + section *SubSec = NULL; + char inphone[BUFSIZ]; + char outphone[BUFSIZ]; + char string[256]; + char *interface = is_master?CONF_SEC_INTERFACE:CONF_SEC_SLAVE; + char *RetCode = NULL; + + + if (name == NULL && *name != '\0') + return NULL; + + strcpy(cfg.name, name); + + if (ioctl(fd, IIOCNETGCF, &cfg) < 0) + return NULL; + + strcpy(PHONE(inphone)->name, name); + PHONE(inphone)->outgoing = 0; + + if (ioctl(fd, IIOCNETGNM, PHONE(inphone)) < 0) + return NULL; + + strcpy(PHONE(outphone)->name, name); + PHONE(outphone)->outgoing = 1; + + if (ioctl(fd, IIOCNETGNM, PHONE(outphone)) < 0) + return NULL; + + if (Set_Section(&SubSec,interface,C_OVERWRITE | C_WARN) == NULL) + return NULL; + + if (Set_Entry(SubSec,interface,CONF_ENT_NAME,name, C_OVERWRITE | C_WARN) == NULL) + return NULL; + + if (*cfg.eaz != '\0') + if (Set_Entry(SubSec,interface,CONF_ENT_EAZ,cfg.eaz, C_OVERWRITE | C_WARN) == NULL) + return NULL; + + if (*inphone != '\0') + if (Set_Entry(SubSec,interface,CONF_ENT_PHONE_IN,write_all_numbers(inphone), C_OVERWRITE | C_WARN) == NULL) + return NULL; + + if (*outphone != '\0') + if (Set_Entry(SubSec,interface,CONF_ENT_PHONE_OUT,write_all_numbers(outphone), C_OVERWRITE | C_WARN) == NULL) + return NULL; + + if (Set_Entry(SubSec,interface,CONF_ENT_SECURE, cfg.secure?"on":"off", C_OVERWRITE | C_WARN) == NULL) + return NULL; + + if (cfg.callback) + { + if (Set_Entry(SubSec,interface,CONF_ENT_CALLBACK,num2callb[cfg.callback], C_OVERWRITE | C_WARN) == NULL) + return NULL; + + if (Set_Entry(SubSec,interface,CONF_ENT_CBHUP, cfg.cbhup?"on":"off", C_OVERWRITE | C_WARN) == NULL) + return NULL; + + sprintf(string,"%d",cfg.cbdelay / 5); + if (Set_Entry(SubSec,interface,CONF_ENT_CBDELAY, string, C_OVERWRITE | C_WARN) == NULL) + return NULL; + } + + if (cfg.dialmax) + { + sprintf(string,"%d",cfg.dialmax); + if (Set_Entry(SubSec,interface,CONF_ENT_DIALMAX, string, C_OVERWRITE | C_WARN) == NULL) + return NULL; + } + + if (cfg.onhtime) + { + sprintf(string,"%d",cfg.onhtime); + if (Set_Entry(SubSec,interface,CONF_ENT_HUPTIMEOUT, string, C_OVERWRITE | C_WARN) == NULL) + return NULL; + } + + if (Set_Entry(SubSec,interface,CONF_ENT_IHUP, cfg.ihup?"on":"off", C_OVERWRITE | C_WARN) == NULL) + return NULL; + + if (Set_Entry(SubSec,interface,CONF_ENT_CHARGEHUP, cfg.chargehup?"on":"off", C_OVERWRITE | C_WARN) == NULL) + return NULL; + + if (cfg.chargeint) + { + sprintf(string,"%d",cfg.chargeint); + if (Set_Entry(SubSec,interface,CONF_ENT_CHARGEINT, string, C_OVERWRITE | C_WARN) == NULL) + return NULL; + } + + if (Set_Entry(SubSec,interface,CONF_ENT_L2_PROT, num2key(cfg.l2_proto, l2protostr, l2protoval), C_OVERWRITE | C_WARN) == NULL) + return NULL; + + if (Set_Entry(SubSec,interface,CONF_ENT_L3_PROT, num2key(cfg.l3_proto, l3protostr, l3protoval), C_OVERWRITE | C_WARN) == NULL) + return NULL; + + if (Set_Entry(SubSec,interface,CONF_ENT_ENCAP, num2key(cfg.p_encap, pencapstr, pencapval), C_OVERWRITE | C_WARN) == NULL) + return NULL; + + if (*cfg.slave != '\0') + { + if (Set_Entry(SubSec,interface,CONF_ENT_ADDSLAVE, cfg.slave, C_OVERWRITE | C_WARN) == NULL) + return NULL; + + sprintf(string,"%d",cfg.slavedelay); + if (Set_Entry(SubSec,interface,CONF_ENT_SDELAY, string, C_OVERWRITE | C_WARN) == NULL) + return NULL; + + RetCode = cfg.slave; + } + + if (*cfg.drvid != '\0') + { + sprintf(string,"%s %s",cfg.drvid,cfg.exclusive>0?"exclusive":""); + if (Set_Entry(SubSec,interface,CONF_ENT_BIND, string, C_OVERWRITE | C_WARN) == NULL) + return NULL; + } + + if (cfg.pppbind >= 0) + { + sprintf(string,"%d",cfg.pppbind); + if (Set_Entry(SubSec,interface,CONF_ENT_PPPBIND, string, C_OVERWRITE | C_WARN) == NULL) + return NULL; + } + + if (Set_SubSection(CSec,CONF_ENT_INTERFACES,SubSec,C_APPEND | C_WARN) == NULL) + return NULL; + + return RetCode; +} + +/*****************************************************************************/ + +static char* write_all_numbers(char *numbers) +{ + return numbers; +} + +/*****************************************************************************/ + +int readconfig(int fd, char *file) +{ + section *Section; + section *ConfigSection; + section *PhoneSection; + entry *Entry; + char *argv[5]; + char *name; + int cnt = 1; + + if ((ConfigSection = read_file(NULL,file,C_NOT_UNIQUE|C_NO_WARN_FILE)) == NULL) + return -1; + + read_conffiles(&PhoneSection,NULL); + + if ((Section = Get_Section(ConfigSection,CONF_SEC_ISDNCTRL)) == NULL) + { + fprintf(stderr,"File `%s' has no section `%s'!\n",file,CONF_SEC_ISDNCTRL); + return -1; + } + if ((Entry = Get_Entry(Section->entries,CONF_ENT_INTERFACES)) == NULL) + { + fprintf(stderr,"Section `%s' has no entry `%s'!\n",CONF_SEC_ISDNCTRL,CONF_ENT_INTERFACES); + return -1; + } + + if ((Section = Entry->subsection) == NULL) + { + fprintf(stderr,"Entry `%s' has no subsections!\n",CONF_ENT_INTERFACES); + return -1; + } + + while (Section != NULL) + { + if ((Entry = Get_Entry(Section->entries,CONF_ENT_NAME)) == NULL) + { + fprintf(stderr,"Missing the interface name of the %d. interface sections!\n",cnt); + return -1; + } + else + name = Entry->value; + + if (!strcmp(Section->name, CONF_SEC_INTERFACE)) + create_interface(fd,name); + + Entry = Section->entries; + + while (Entry != NULL) + { + if (!strcmp(Entry->name,CONF_ENT_NAME)) + { + } + else + if (!strcmp(Entry->name,CONF_ENT_EAZ)) + { + argv[0] = cmds[EAZ].cmd; + argv[1] = name; + argv[2] = Entry->value; + argv[3] = NULL; + exec_args(fd,3,argv); + } + else + if (!strcmp(Entry->name,CONF_ENT_PHONE_IN)) + { + del_all_numbers(fd,name,0); + set_all_numbers(fd,name,0,Entry->value); + } + else + if (!strcmp(Entry->name,CONF_ENT_PHONE_OUT)) + { + del_all_numbers(fd,name,1); + set_all_numbers(fd,name,1,Entry->value); + } + else + if (!strcmp(Entry->name,CONF_ENT_SECURE)) + { + argv[0] = cmds[SECURE].cmd; + argv[1] = name; + argv[2] = Entry->value; + argv[3] = NULL; + exec_args(fd,3,argv); + } + else + if (!strcmp(Entry->name,CONF_ENT_CALLBACK)) + { + argv[0] = cmds[CALLBACK].cmd; + argv[1] = name; + argv[2] = Entry->value; + argv[3] = NULL; + exec_args(fd,3,argv); + } + else + if (!strcmp(Entry->name,CONF_ENT_CBDELAY)) + { + argv[0] = cmds[CBDELAY].cmd; + argv[1] = name; + argv[2] = Entry->value; + argv[3] = NULL; + exec_args(fd,3,argv); + } + else + if (!strcmp(Entry->name,CONF_ENT_CBHUP)) + { + argv[0] = cmds[CBHUP].cmd; + argv[1] = name; + argv[2] = Entry->value; + argv[3] = NULL; + exec_args(fd,3,argv); + } + else + if (!strcmp(Entry->name,CONF_ENT_DIALMAX)) + { + argv[0] = cmds[DIALMAX].cmd; + argv[1] = name; + argv[2] = Entry->value; + argv[3] = NULL; + exec_args(fd,3,argv); + } + else + if (!strcmp(Entry->name,CONF_ENT_HUPTIMEOUT)) + { + argv[0] = cmds[HUPTIMEOUT].cmd; + argv[1] = name; + argv[2] = Entry->value; + argv[3] = NULL; + exec_args(fd,3,argv); + } + else + if (!strcmp(Entry->name,CONF_ENT_IHUP)) + { + argv[0] = cmds[IHUP].cmd; + argv[1] = name; + argv[2] = Entry->value; + argv[3] = NULL; + exec_args(fd,3,argv); + } + else + if (!strcmp(Entry->name,CONF_ENT_CHARGEHUP)) + { + argv[0] = cmds[CHARGEHUP].cmd; + argv[1] = name; + argv[2] = Entry->value; + argv[3] = NULL; + exec_args(fd,3,argv); + } + else + if (!strcmp(Entry->name,CONF_ENT_CHARGEINT)) + { + argv[0] = cmds[CHARGEINT].cmd; + argv[1] = name; + argv[2] = Entry->value; + argv[3] = NULL; + exec_args(fd,3,argv); + } + else + if (!strcmp(Entry->name,CONF_ENT_L2_PROT)) + { + argv[0] = cmds[L2_PROT].cmd; + argv[1] = name; + argv[2] = Entry->value; + argv[3] = NULL; + exec_args(fd,3,argv); + } + else + if (!strcmp(Entry->name,CONF_ENT_L3_PROT)) + { + argv[0] = cmds[L3_PROT].cmd; + argv[1] = name; + argv[2] = Entry->value; + argv[3] = NULL; + exec_args(fd,3,argv); + } + else + if (!strcmp(Entry->name,CONF_ENT_ENCAP)) + { + argv[0] = cmds[ENCAP].cmd; + argv[1] = name; + argv[2] = Entry->value; + argv[3] = NULL; + exec_args(fd,3,argv); + } + else + if (!strcmp(Entry->name,CONF_ENT_BIND)) + { + char string[256]; + char *ptr; + + strcpy(string, Entry->value); + + if ((ptr = strchr(string,' ')) != NULL) + while (isspace(*ptr)) *ptr++ = '\0'; + + argv[0] = cmds[BIND].cmd; + argv[1] = name; + argv[2] = string; + argv[3] = ptr; + argv[4] = NULL; + exec_args(fd,ptr?4:3,argv); + } + else + if (!strcmp(Entry->name,CONF_ENT_PPPBIND)) + { + argv[0] = cmds[PPPBIND].cmd; + argv[1] = name; + argv[2] = Entry->value; + argv[3] = NULL; + exec_args(fd,3,argv); + } + else + if (!strcmp(Entry->name,CONF_ENT_ADDSLAVE)) + { + argv[0] = cmds[ADDSLAVE].cmd; + argv[1] = name; + argv[2] = Entry->value; + argv[3] = NULL; + exec_args(fd,3,argv); + } + else + if (!strcmp(Entry->name,CONF_ENT_SDELAY)) + { + argv[0] = cmds[SDELAY].cmd; + argv[1] = name; + argv[2] = Entry->value; + argv[3] = NULL; + exec_args(fd,3,argv); + } + else + { + fprintf(stderr,"Unknown entry `%s' in interface section `%s'!\n",Entry->name,name); + return -1; + } + + Entry = Entry->next; + } + + Section = Section->next; + cnt++; + } + + return 0; +} + +/*****************************************************************************/ + +static int interface_exist(int fd, char *name) +{ + char iname[10]; + FILE *iflst; + char s[BUFSIZ]; + char *p; + + + if ((iflst = fopen("/proc/net/dev", "r")) == NULL) + { + perror("/proc/net/dev"); + return -1; + } + + while (!feof(iflst)) + { + fgets(s, sizeof(s), iflst); + + if ((p = strchr(s, ':'))) + { + *p = 0; + sscanf(s, "%s", iname); + + if (!strcmp(name,iname)) + { + fclose(iflst); + return 1; + } + } + } + + fclose(iflst); + + return 0; +} + +/*****************************************************************************/ + +static int create_interface(int fd, char *name) +{ + char *argv[3]; + + + if (interface_exist(fd,name)) + return -1; + + argv[0] = cmds[ADDIF].cmd; + argv[1] = name; + argv[2] = NULL; + exec_args(fd,2,argv); + + return 0; +} + +/*****************************************************************************/ + +static int set_all_numbers(int fd, char *name, int direction, char *numbers) +{ + isdn_net_ioctl_phone phone; + char phonestr[BUFSIZ]; + char *ptr = phonestr; + char *ptr2; + + + strcpy(phonestr, numbers); + + if (*phonestr != '\0') + { + strcpy(phone.name, name); + phone.outgoing = direction; + + do + { + if ((ptr = strrchr(phonestr,' ')) == NULL) + ptr = phonestr; + else + { + ptr2 = ptr++; + while (isspace(*ptr2) && ptr2 != phonestr) *ptr2-- = '\0'; + } + + strcpy(phone.phone, ptr); + + if (*ptr != '\0') + { + if (ioctl(fd, IIOCNETANM, &phone) < 0) + { + perror(name); + return -1; + } + } + } + while (ptr != phonestr); + } + + return 0; +} + +/*****************************************************************************/ + +static int del_all_numbers(int fd, char *name, int direction) +{ + isdn_net_ioctl_phone phone; + char phonestr[BUFSIZ]; + char *ptr = phonestr; + char *ptr2; + + + if (name == NULL) + return -1; + + strcpy(PHONE(phonestr)->name, name); + PHONE(phonestr)->outgoing = direction; + + if (ioctl(fd, IIOCNETGNM, PHONE(phonestr)) < 0) + { + perror(name); + return -1; + } + + if (*phonestr != '\0') + { + strcpy(phone.name, name); + phone.outgoing = direction; + + do + { + if ((ptr = strrchr(phonestr,' ')) == NULL) + ptr = phonestr; + else + { + ptr2 = ptr++; + while (isspace(*ptr2) && ptr2 != phonestr) *ptr2-- = '\0'; + } + + if (*ptr != '\0') + { + strcpy(phone.phone, ptr); + + if (ioctl(fd, IIOCNETDNM, &phone) < 0) + { + perror(name); + return -1; + } + } + } + while (ptr != phonestr); + } + + return 0; +} + +/*****************************************************************************/ + diff --git a/isdnctrl/ctrlconf.h b/isdnctrl/ctrlconf.h new file mode 100644 index 00000000..dfe5f482 --- /dev/null +++ b/isdnctrl/ctrlconf.h @@ -0,0 +1,60 @@ +/* $Id$ + * + * ISDN accounting for isdn4linux. (Utilities) + * + * Copyright 1995, 1997 by Stefan Luethje (luethje@sl-gw.lake.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Log$ + * + */ + +#include "../lib/libisdn.h" + +/*****************************************************************************/ + +#define CONF_SEC_ISDNCTRL "ISDNCTRL" +#define CONF_ENT_INTERFACES "INTERFACES" +#define CONF_SEC_INTERFACE "INTERFACE" +#define CONF_SEC_SLAVE "SLAVE" +#define CONF_ENT_NAME "NAME" +#define CONF_ENT_EAZ "EAZ" +#define CONF_ENT_PHONE_IN "PHONE_IN" +#define CONF_ENT_PHONE_OUT "PHONE_OUT" +#define CONF_ENT_SECURE "SECURE" +#define CONF_ENT_CALLBACK "CALLBACK" +#define CONF_ENT_CBHUP "CBHUP" +#define CONF_ENT_CBDELAY "CBDELAY" +#define CONF_ENT_DIALMAX "DIALMAX" +#define CONF_ENT_HUPTIMEOUT "HUPTIMEOUT" +#define CONF_ENT_IHUP "IHUP" +#define CONF_ENT_CHARGEHUP "CHARGEHUP" +#define CONF_ENT_CHARGEINT "CHARGEINT" +#define CONF_ENT_L2_PROT "L2_PROT" +#define CONF_ENT_L3_PROT "L3_PROT" +#define CONF_ENT_ENCAP "ENCAP" +#define CONF_ENT_SDELAY "SDELAY" +#define CONF_ENT_ADDSLAVE "ADDSLAVE" +#define CONF_ENT_BIND "BIND" +#define CONF_ENT_PPPBIND "PPPBIND" + +/*****************************************************************************/ + +int writeconfig(int fd, char *file); +int readconfig(int fd, char *file); + +/*****************************************************************************/ + diff --git a/isdnctrl/isdnctrl.c b/isdnctrl/isdnctrl.c index 767fad79..d143c906 100644 --- a/isdnctrl/isdnctrl.c +++ b/isdnctrl/isdnctrl.c @@ -21,6 +21,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log$ + * Revision 1.3 1997/06/22 11:58:21 fritz + * Added ability to adjust slave triggerlevel. + * * Revision 1.2 1997/03/10 09:51:24 fritz * Bugfix: mapping was broken. * @@ -90,45 +93,20 @@ #include #include -char *l2protostr[] = { - "x75i", "x75ui", "x75bui", "hdlc", "\0" -}; +#define _ISDNCTRL_C_ +#include "isdnctrl.h" -int l2protoval[] = { - ISDN_PROTO_L2_X75I, ISDN_PROTO_L2_X75UI, - ISDN_PROTO_L2_X75BUI, ISDN_PROTO_L2_HDLC, -1 -}; +#ifdef I4L_CTRL_CONF +# include "../lib/libisdn.h" +# include "ctrlconf.h" +#endif /* I4L_CTRL_CONF */ -char *l3protostr[] = { - "trans", "\0" -}; - -int l3protoval[] = { - ISDN_PROTO_L3_TRANS, -1 -}; - -char *pencapstr[] = { - "ethernet", "rawip", "ip", "cisco-h", "syncppp", - "uihdlc", "\0" -}; - -int pencapval[] = { - ISDN_NET_ENCAP_ETHER, ISDN_NET_ENCAP_RAWIP, - ISDN_NET_ENCAP_IPTYP, ISDN_NET_ENCAP_CISCOHDLC, - ISDN_NET_ENCAP_SYNCPPP, ISDN_NET_ENCAP_UIHDLC, -1 -}; - -char *num2callb[] = { - "off", "in", "out" -}; - -char *cmd; char nextlistif[10]; void usage(void) { + fprintf(stderr, "%s version %s\n", cmd, VERSION); fprintf(stderr, "usage: %s \n", cmd); -#if 0 fprintf(stderr, "\n"); fprintf(stderr, "where is one of the following:\n"); fprintf(stderr, "\n"); @@ -167,11 +145,15 @@ void usage(void) fprintf(stderr, " removelink name MPPP, decrease number of links\n"); fprintf(stderr, " pppbind name [devicenum] PPP, bind interface to ippp-device (exclusive)\n"); fprintf(stderr, " pppunbind name PPP, remove ippp-device binding\n"); -#endif +#ifdef I4L_CTRL_CONF + fprintf(stderr, " writeconf [file] write the settings to file\n"); + fprintf(stderr, " readconf [file] read the settings from file\n"); +#endif /* I4L_CTRL_CONF */ + exit(-2); } -static int key2num(char *key, char **keytable, int *numtable) +int key2num(char *key, char **keytable, int *numtable) { int i = -1; while (strlen(keytable[++i])) @@ -180,8 +162,7 @@ static int key2num(char *key, char **keytable, int *numtable) return -1; } -static char * - num2key(int num, char **keytable, int *numtable) +char * num2key(int num, char **keytable, int *numtable) { int i = -1; while (numtable[++i] >= 0) @@ -265,6 +246,12 @@ static void listif(int isdnctrl, char *name, int errexit) printf("Master Interface: %s\n", strlen(cfg.master) ? cfg.master : "None"); printf("Pre-Bound to: "); listbind(cfg.drvid, cfg.exclusive); + printf("PPP-Bound to: "); + if (cfg.pppbind >= 0) + printf("%d\n", cfg.pppbind); + else + printf("Nothing\n"); + if (cfg.slave && strlen(cfg.slave)) strcpy(nextlistif, cfg.slave); else @@ -291,13 +278,13 @@ static void get_setup(int isdnctrl, char *name) exit(-1); } p = buffer; - fprintf(f,"[isdnctrl]\n"); + fprintf(f,"[isdnctrl]\n"); while (strlen(p)) { - if (strlen(cfg.master)) { - fprintf(f, " netslave=\"%s\"\n", p); - fprintf(f, " master=\"%s\"\n", p); + if (strlen(cfg.master)) { + fprintf(f, " netslave=\"%s\"\n", p); + fprintf(f, " master=\"%s\"\n", p); } else - fprintf(f, " netif=\"%s\"\n", p); + fprintf(f, " netif=\"%s\"\n", p); p += 10; memcpy((char *) &cfg, p, sizeof(cfg)); fprintf(f, " eazmsn=\"%s\"\n", cfg.eaz); @@ -324,737 +311,747 @@ static void get_setup(int isdnctrl, char *name) fclose(f); } -enum { - ADDIF, ADDSLAVE, DELIF, DIAL, - BIND, UNBIND, PPPBIND, PPPUNBIND, - BUSREJECT, MAPPING, SYSTEM, HANGUP, - ADDPHONE, DELPHONE, LIST, EAZ, - VERBOSE, GETCONF, HUPTIMEOUT, CBDELAY, - CHARGEINT, DIALMAX, SDELAY, CHARGEHUP, - CBHUP, IHUP, SECURE, CALLBACK, - L2_PROT, L3_PROT, ADDLINK, REMOVELINK, - ENCAP, TRIGGER -}; - -typedef struct { - char *cmd; - char *argno; -} cmd_struct; - -static cmd_struct cmds[] = -{ - {"addif", "0"}, - {"addslave", "1"}, - {"delif", "0"}, - {"dial", "0"}, - {"bind", "12"}, - {"unbind", "0"}, - {"pppbind", "1"}, - {"pppunbind", "0"}, - {"busreject", "1"}, - {"mapping", "01"}, - {"system", "0"}, - {"hangup", "0"}, - {"addphone", "2"}, - {"delphone", "2"}, - {"list", "0"}, - {"eaz", "01"}, - {"verbose", "0"}, - {"getconf", "0"}, - {"huptimeout", "01"}, - {"cbdelay", "01"}, - {"chargeint", "01"}, - {"dialmax", "01"}, - {"sdelay", "01"}, - {"chargehup", "01"}, - {"cbhup", "01"}, - {"ihup", "01"}, - {"secure", "01"}, - {"callback", "01"}, - {"l2_prot", "01"}, - {"l3_prot", "01"}, - {"addlink", "0"}, - {"removelink", "0"}, - {"encap", "01"}, - {"trigger", "01"}, - {NULL,} -}; - int findcmd(char *str) { - int i; + int i; - for (i = 0; cmds[i].cmd; i++) - if (!strcmp(cmds[i].cmd, str)) - return i; - return -1; + if (str != NULL) + for (i = 0; cmds[i].cmd; i++) + if (!strcmp(cmds[i].cmd, str)) + return i; + + return -1; +} + +int exec_args(int fd, int argc, char **argv) +{ + int i, + n, + args; + int result; + FILE *iflst; + char *p; + char s[255]; + isdn_net_ioctl_phone phone; + isdn_net_ioctl_cfg cfg; + isdn_ioctl_struct iocts; + unsigned long j; + char nstring[255]; +#ifdef I4L_CTRL_CONF + char conffile[PATH_MAX]; +#endif /* I4L_CTRL_CONF */ + char *id; + char *arg1; + char *arg2; + + + for (; *argv != NULL; argv++, argc--) { + if ((i = findcmd(argv[0])) < 0) { /* Unknown command */ + fprintf(stderr, "The given command \"%s\" is unknown.\n\n", argv[0]); + usage(); + return -1; + } + + args = cmds[i].argno[0] - '0'; + id = argv[1]; + + if (args > argc - 1) { + fprintf(stderr, "Too few arguments given for \"%s\".\n\n", argv[0]); + usage(); + return -1; + } + +#ifdef I4L_CTRL_CONF + if (id != NULL && i != GETCONF && i != WRITECONF && i != READCONF) { +#else + if (id != NULL && i != GETCONF) { +#endif /* I4L_CTRL_CONF */ + if (strlen(id) > 8) { + fprintf(stderr, "Interface name must not exceed 8 characters!\n"); + close(fd); + return -1; + } + } + + for (n = 1; cmds[i].argno[n]; n++) { + args = cmds[i].argno[n] - '0'; + if (((args > argc - 1) || findcmd(argv[args]) >= 0)) { + args = cmds[i].argno[n - 1] - '0'; + break; + } + } + + arg1 = (args > 1) ? argv[2] : ""; + arg2 = (args > 2) ? argv[3] : ""; + argc -= args; + argv += args; + + switch (i) { + case ADDIF: + strcpy(s, args?id:""); + if ((result = ioctl(fd, IIOCNETAIF, s)) < 0) { + perror("addif"); + return -1; + } + printf("%s added\n", s); + break; + + case ADDSLAVE: + if (strlen(arg1) > 8) { + fprintf(stderr, "slavename must not exceed 8 characters\n"); + return -1; + } + sprintf(s, "%s,%s", id, arg1); + if ((result = ioctl(fd, IIOCNETASL, s)) < 0) { + perror("addslave"); + return -1; + } + printf("%s added as slave to %s\n", s, id); + break; + + case DELIF: + if ((result = ioctl(fd, IIOCNETDIF, id)) < 0) { + perror(id); + return -1; + } + printf("%s deleted\n", id); + break; + + case DIAL: + if ((result = ioctl(fd, IIOCNETDIL, id)) < 0) { + perror(id); + return -1; + } + printf("Dialing of %s triggered\n", id); + break; + + case BIND: + if (args == 3) + if (strncmp(arg2, "excl", 4)) + usage(); + strcpy(cfg.name, id); + if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { + perror(id); + return -1; + } + if (args > 1) + { + sscanf(arg1, "%s", cfg.drvid); + cfg.exclusive = (args == 3); + if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { + sprintf(s, "%s or %s", id, arg2); + perror(s); + return -1; + } + } + printf("%s bound to ", id); + listbind(cfg.drvid, cfg.exclusive); + break; + + case UNBIND: + strcpy(cfg.name, id); + if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { + perror(id); + return -1; + } + if (!strlen(cfg.drvid)) { + printf("%s was not bound to anything\n", id); + return -1; + } + cfg.drvid[0] = '\0'; + cfg.exclusive = -1; + if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { + perror(id); + return -1; + } + printf("%s unbound successfully\n", id); + break; + + case PPPBIND: + strcpy(cfg.name, id); + if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { + perror(id); + return -1; + } + if (args > 1) { + sscanf(arg1, "%d", &cfg.pppbind); + if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { + sprintf(s, "%s or %s", id, arg1); + perror(s); + return -1; + } + } + printf("%s bound to ", id); + if (cfg.pppbind >= 0) + printf("%d\n", cfg.pppbind); + else + printf("nothing\n"); + break; + + case PPPUNBIND: + strcpy(cfg.name, id); + if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { + perror(id); + return -1; + } + if (cfg.pppbind < 0) { + printf("%s was not bound to anything\n", id); + return -1; + } + cfg.pppbind = -1; + if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { + perror(id); + return -1; + } + printf("%s unbound successfully\n", id); + break; + + case BUSREJECT: + strcpy(iocts.drvid, id); + if (strcmp(arg1, "on") && strcmp(arg1, "off")) { + fprintf(stderr, "Bus-Reject must be 'on' or 'off'\n"); + return -1; + } + iocts.arg = strcmp(arg1, "off"); + if ((result = ioctl(fd, IIOCSETBRJ, &iocts)) < 0) { + perror(id); + return -1; + } + break; + + case MAPPING: + strcpy(iocts.drvid, id); + if (args == 1) { + iocts.arg = (unsigned long) &nstring; + if ((result = ioctl(fd, IIOCGETMAP, &iocts)) < 0) { + perror(id); + return -1; + } + printf("MSN/EAZ-mapping for %s:\n%s\n", id, nstring); + } else { + char buf[400]; + strncpy(buf, arg1, sizeof(buf) - 1); + iocts.arg = (unsigned long) buf; + if ((result = ioctl(fd, IIOCSETMAP, &iocts)) < 0) { + perror(id); + return -1; + } + } + break; + + case SYSTEM: + if (strcmp(id, "on") && strcmp(id, "off")) { + fprintf(stderr, "System-Mode must be 'on' or 'off'\n"); + return -1; + } + j = strcmp(id, "on"); + if ((result = ioctl(fd, IIOCSETGST, j)) < 0) { + perror(id); + return -1; + } + break; + + case HANGUP: + if ((result = ioctl(fd, IIOCNETHUP, id)) < 0) { + perror(id); + return -1; + } + if (result) + printf("%s not connected\n", id); + else + printf("%s hung up\n", id); + break; + + case ADDPHONE: + if (strcmp(arg1, "in") && strcmp(arg1, "out")) { + fprintf(stderr, "Direction must be \"in\" or \"out\"\n"); + return -1; + } + phone.outgoing = strcmp(arg1, "out") ? 0 : 1; + if (strlen(arg2) > 20) { + fprintf(stderr, "phone-number must not exceed 20 characters\n"); + return -1; + } + strcpy(phone.name, id); + strcpy(phone.phone, arg2); + if ((result = ioctl(fd, IIOCNETANM, &phone)) < 0) { + perror(id); + return -1; + } + break; + + case DELPHONE: + if (strcmp(arg1, "in") && strcmp(arg1, "out")) { + fprintf(stderr, "Direction must be \"in\" or \"out\"\n"); + return -1; + } + phone.outgoing = strcmp(arg1, "out") ? 0 : 1; + if (strlen(arg2) > 20) { + fprintf(stderr, "phone-number must not exceed 20 characters\n"); + return -1; + } + strcpy(phone.name, id); + strcpy(phone.phone, arg2); + if ((result = ioctl(fd, IIOCNETDNM, &phone)) < 0) { + perror(id); + return -1; + } + break; + + case LIST: + if (!strcmp(id, "all")) { + char name[10]; + if ((iflst = fopen("/proc/net/dev", "r")) == NULL) { + perror("/proc/net/dev"); + return -1; + } + while (!feof(iflst)) { + fgets(s, sizeof(s), iflst); + if ((p = strchr(s, ':'))) { + *p = 0; + sscanf(s, "%s", name); + listif(fd, name, 0); + while (strlen(nextlistif)) + listif(fd, nextlistif, 0); + } + } + fclose(iflst); + } else + listif(fd, id, 1); + break; + + case EAZ: + strcpy(cfg.name, id); + if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { + perror(id); + return -1; + } + if (args == 2) { + i = -1; + strncpy(cfg.eaz, arg1, sizeof(cfg.eaz) - 1); + if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { + perror(id); + return -1; + } + } + printf("EAZ/MSN for %s is %s\n", cfg.name, cfg.eaz); + break; + + case VERBOSE: + i = -1; + sscanf(id, "%d", &i); + if (i < 0) { + fprintf(stderr, "Verbose-level must be >= 0\n"); + return -1; + } + if ((result = ioctl(fd, IIOCSETVER, i)) < 0) { + perror("IIOCSETVER"); + return -1; + } + printf("Verbose-level set to %d.\n", i); + break; + + case GETCONF: + if (args == 0) + id = "-"; + get_setup(fd, id); + printf("Configuration written to %s.\n", id); + break; + + case HUPTIMEOUT: + strcpy(cfg.name, id); + if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { + perror(id); + return -1; + } + if (args == 2) { + i = -1; + sscanf(arg1, "%d", &i); + if (i < 0) { + fprintf(stderr, "Hangup-Timeout must be >= 0\n"); + return -1; + } + cfg.onhtime = i; + if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { + perror(id); + return -1; + } + } + printf("Hangup-Timeout for %s is %d sec.\n", cfg.name, cfg.onhtime); + break; + + case CBDELAY: + strcpy(cfg.name, id); + if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { + perror(id); + return -1; + } + if (args == 2) { + i = -1; + sscanf(arg1, "%d", &i); + if (i < 0) { + fprintf(stderr, "Callback delay must be >= 0\n"); + return -1; + } + cfg.cbdelay = i * 5; + if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { + perror(id); + return -1; + } + } + printf("Callback delay for %s is %d sec.\n", cfg.name, cfg.cbdelay / 5); + break; + + case CHARGEINT: + strcpy(cfg.name, id); + if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { + perror(id); + return -1; + } + if (args == 2) { + i = -1; + sscanf(arg1, "%d", &i); + if (i < 0) { + fprintf(stderr, "Charge interval must be >= 0\n"); + return -1; + } + cfg.chargeint = i; + if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { + perror(id); + return -1; + } + } + printf("Charge Interval for %s is %d sec.\n", cfg.name, cfg.chargeint); + break; + + case DIALMAX: + strcpy(cfg.name, id); + if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { + perror(id); + return -1; + } + if (args == 2) { + i = -1; + sscanf(arg1, "%d", &i); + if (i < 1) { + fprintf(stderr, "Dialmax must be > 0\n"); + return -1; + } + cfg.dialmax = i; + if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { + perror(id); + return -1; + } + } + printf("Dialmax for %s is %d times.\n", cfg.name, cfg.dialmax); + break; + + case SDELAY: + strcpy(cfg.name, id); + if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { + perror(id); + return -1; + } + if (args == 2) { + i = -1; + sscanf(arg1, "%d", &i); + if (i < 1) { + fprintf(stderr, "Slave-activation delay must be >= 1\n"); + return -1; + } + cfg.slavedelay = i; + if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { + perror(id); + return -1; + } + } + printf("Slave-activation delay for %s is %d sec.\n", cfg.name, + cfg.slavedelay); + break; + + case TRIGGER: + strcpy(cfg.name, id); + if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { + perror(id); + exit(-1); + } + if (args) { + i = -1; + sscanf(arg1, "%d", &i); + if (i < 0) { + fprintf(stderr, "Slave triggerlevel must be >= 0\n"); + exit(-1); + } + cfg.triggercps = i; + if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { + perror(id); + exit(-1); + } + } + printf("Slave triggerlevel for %s is %d cps.\n", cfg.name, + cfg.triggercps); + break; + + case CHARGEHUP: + strcpy(cfg.name, id); + if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { + perror(id); + return -1; + } + if (args == 2) { + i = -1; + if (strcmp(arg1, "on") && strcmp(arg1, "off")) { + fprintf(stderr, "Charge-Hangup must be 'on' or 'off'\n"); + return -1; + } + cfg.chargehup = strcmp(arg1, "off"); + if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { + perror(id); + return -1; + } + } + printf("Charge-Hangup for %s is %s\n", cfg.name, cfg.chargehup ? "on" : "off"); + break; + + case CBHUP: + strcpy(cfg.name, id); + if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { + perror(id); + return -1; + } + if (args == 2) { + i = -1; + if (strcmp(arg1, "on") && strcmp(arg1, "off")) { + fprintf(stderr, "Callback-Hangup must be 'on' or 'off'\n"); + return -1; + } + cfg.cbhup = strcmp(arg1, "off"); + if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { + perror(id); + return -1; + } + } + printf("Reject before Callback for %s is %s\n", cfg.name, cfg.cbhup ? "on" : "off"); + break; + + case IHUP: + strcpy(cfg.name, id); + if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { + perror(id); + return -1; + } + if (args == 2) { + i = -1; + if (strcmp(arg1, "on") && strcmp(arg1, "off")) { + fprintf(stderr, "Incoming-Hangup must be 'on' or 'off'\n"); + return -1; + } + cfg.ihup = strcmp(arg1, "off"); + if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { + perror(id); + return -1; + } + } + printf("Incoming-Hangup for %s is %s\n", cfg.name, cfg.ihup ? "on" : "off"); + break; + + case SECURE: + strcpy(cfg.name, id); + if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { + perror(id); + return -1; + } + if (args == 2) { + i = -1; + if (strcmp(arg1, "on") && strcmp(arg1, "off")) { + fprintf(stderr, "Secure-parameter must be 'on' or 'off'\n"); + return -1; + } + cfg.secure = strcmp(arg1, "off"); + if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { + perror(id); + return -1; + } + } + printf("Security for %s is %s\n", cfg.name, cfg.secure ? "on" : "off"); + break; + + case CALLBACK: + strcpy(cfg.name, id); + if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { + perror(id); + return -1; + } + if (args == 2) { + i = -1; + if (strcmp(arg1, "on") && strcmp(arg1, "off") && + strcmp(arg1, "in") && strcmp(arg1, "out")) { + fprintf(stderr, "Callback-parameter must be 'on', 'in', 'out' or 'off'\n"); + return -1; + } + cfg.callback = strcmp(arg1, "off") ? 1 : 0; + if (!strcmp(arg1, "out")) + cfg.callback = 2; + if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { + perror(id); + return -1; + } + } + printf("Callback for %s is %s\n", cfg.name, num2callb[cfg.callback]); + break; + + case L2_PROT: + strcpy(cfg.name, id); + if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { + perror(id); + return -1; + } + if (args == 2) { + i = key2num(arg1, l2protostr, l2protoval); + if (i < 0) { + fprintf(stderr, "Layer-2-Protocol must be one of the following:\n"); + i = 0; + while (strlen(l2protostr[i])) + fprintf(stderr, "\t\"%s\"\n", l2protostr[i++]); + return -1; + } + cfg.l2_proto = i; + if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { + perror(id); + return -1; + } + } + printf("Layer-2-Protocol for %s is %s\n", cfg.name, + num2key(cfg.l2_proto, l2protostr, l2protoval)); + break; + + case L3_PROT: + strcpy(cfg.name, id); + if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { + perror(id); + return -1; + } + if (args == 2) { + i = key2num(arg1, l3protostr, l3protoval); + if (i < 0) { + fprintf(stderr, "Layer-3-Protocol must be one of the following:\n"); + i = 0; + while (strlen(l3protostr[i])) + fprintf(stderr, "\t\"%s\"\n", l3protostr[i++]); + return -1; + } + cfg.l3_proto = i; + if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { + perror(id); + return -1; + } + } + printf("Layer-3-Protocol for %s is %s\n", cfg.name, + num2key(cfg.l3_proto, l3protostr, l3protoval)); + break; + + case ADDLINK: + if ((result = ioctl(fd, IIOCNETALN, id)) < 0) { + perror(id); + return -1; + } + if (result) + printf("Can't increase number of links: %d\n", result); + else + printf("Ok, added a new link. (dialing)\n"); + break; + + case REMOVELINK: + if ((result = ioctl(fd, IIOCNETDLN, id)) < 0) { + perror(id); + return -1; + } + if (result) + printf("Can't decrease number of links: %d\n", result); + else + printf("Ok, removed a link. (hangup)\n"); + break; + + case ENCAP: + strcpy(cfg.name, id); + if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { + perror(id); + return -1; + } + if (args == 2) { + i = key2num(arg1, pencapstr, pencapval); + if (i < 0) { + fprintf(stderr, "Encapsulation must be one of the following:\n"); + i = 0; + while (strlen(pencapstr[i])) + fprintf(stderr, "\t\"%s\"\n", pencapstr[i++]); + return -1; + } + cfg.p_encap = i; + if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { + perror(id); + return -1; + } + } + printf("Encapsulation for %s is %s\n", cfg.name, + num2key(cfg.p_encap, pencapstr, pencapval)); + break; + +#ifdef I4L_CTRL_CONF + case WRITECONF: + if (args == 0) { + sprintf(conffile, "%s%c%s", confdir(), C_SLASH, CONFFILE); + id = conffile; + } + + if (writeconfig(fd, id)) + return -1; + + printf("ISDN Configuration written to %s.\n", id); + break; + + case READCONF: + if (args == 0) { + sprintf(conffile, "%s%c%s", confdir(), C_SLASH, CONFFILE); + id = conffile; + } + + if (readconfig(fd, id)) + return -1; + + printf("ISDN Configuration read from %s.\n", id); + break; +#endif /* I4L_CTRL_CONF */ + } + + if (argc > 1) { + printf("args=%d nextcmd %s\n",args, argv[1]); + } + } + + return 0; } void main(int argc, char **argv) { - int fd; - int i, - n, - args, - cmdptr; - int result; - FILE *iflst; - char *p; - char s[255]; - isdn_net_ioctl_phone phone; - isdn_net_ioctl_cfg cfg; - isdn_ioctl_struct iocts; - unsigned long j; - char nstring[255]; - char *id; - char *arg1; - char *arg2; + int fd; - cmd = argv[0]; - if (argc < 3) { - usage(); - return; - } - fd = open("/dev/isdnctrl", O_RDWR); - if (fd < 0) { - perror("/dev/isdnctrl"); - exit(-1); - } - id = argv[2]; - i = findcmd(argv[1]); - for (cmdptr = 2; cmdptr < argc;) { - if (i < 0) { /* Unknown command */ - fprintf(stderr, "The given command \"%s\" is unknown.\n\n", argv[cmdptr]); - usage(); - return; - } - if (i != GETCONF) { - if (strlen(id) > 8) { - fprintf(stderr, "Interface name must not exceed 8 characters!\n"); - close(fd); - return; - } - } - args = 0; - for (n = 0; cmds[i].argno[n]; n++) { - args = cmds[i].argno[n] - '0'; - if (!n && (args + cmdptr > argc - 1)) { - fprintf(stderr, "Too few arguments given for %s\n", cmds[i].cmd); - usage(); - return; - } - if (n && ((cmdptr + args > argc - 1) || findcmd(argv[cmdptr + args]) >= 0)) { - args = cmds[i].argno[n - 1] - '0'; - break; - } - } - arg1 = args ? argv[cmdptr + 1] : ""; - arg2 = (args > 1) ? argv[cmdptr + 2] : ""; - switch (i) { - case ADDIF: - strcpy(s, id); - if ((result = ioctl(fd, IIOCNETAIF, s)) < 0) { - perror("addif"); - exit(-1); - } - printf("%s added\n", s); - break; + if ((cmd = strrchr(argv[0], '/')) != NULL) + *cmd++ = '\0'; + else + cmd = argv[0]; - case ADDSLAVE: - if (strlen(arg1) > 8) { - fprintf(stderr, "slavename must not exceed 8 characters\n"); - exit(-1); - } - sprintf(s, "%s,%s", id, arg1); - if ((result = ioctl(fd, IIOCNETASL, s)) < 0) { - perror("addslave"); - exit(-1); - } - printf("%s added as slave to %s\n", s, id); - break; + fd = open("/dev/isdnctrl", O_RDWR); + if (fd < 0) { + perror("/dev/isdnctrl"); + exit(-1); + } - case DELIF: - if ((result = ioctl(fd, IIOCNETDIF, id)) < 0) { - perror(id); - exit(-1); - } - printf("%s deleted\n", id); - break; + if (argc == 1) { + usage(); + exit(-1); + } - case DIAL: - if ((result = ioctl(fd, IIOCNETDIL, id)) < 0) { - perror(id); - exit(-1); - } - printf("Dialing of %s triggered\n", id); - break; - - case BIND: - if (args == 2) - if (strncmp(arg2, "excl", 4)) - usage(); - strcpy(cfg.name, id); - if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - sscanf(argv[3], "%s", cfg.drvid); - cfg.exclusive = (args == 2); - if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { - sprintf(s, "%s or %s", id, arg2); - perror(s); - exit(-1); - } - printf("%s bound to ", id); - listbind(cfg.drvid, cfg.exclusive); - break; - - case UNBIND: - strcpy(cfg.name, id); - if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - if (!strlen(cfg.drvid)) { - printf("%s was not bound to anything\n", id); - exit(0); - } - cfg.drvid[0] = '\0'; - cfg.exclusive = -1; - if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - printf("%s unbound successfully\n", id); - break; - - case PPPBIND: - strcpy(cfg.name, id); - if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - sscanf(arg1, "%d", &cfg.pppbind); - if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { - sprintf(s, "%s or %s", id, arg1); - perror(s); - exit(-1); - } - printf("%s bound to %s", id, arg1); - break; - - case PPPUNBIND: - strcpy(cfg.name, id); - if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - if (cfg.pppbind < 0) { - printf("%s was not bound to anything\n", id); - exit(0); - } - cfg.pppbind = -1; - if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - printf("%s unbound successfully\n", id); - break; - - case BUSREJECT: - strcpy(iocts.drvid, id); - if (strcmp(arg1, "on") && strcmp(arg1, "off")) { - fprintf(stderr, "Bus-Reject must be 'on' or 'off'\n"); - exit(-1); - } - iocts.arg = strcmp(arg1, "off"); - if ((result = ioctl(fd, IIOCSETBRJ, &iocts)) < 0) { - perror(id); - exit(-1); - } - break; - - case MAPPING: - strcpy(iocts.drvid, id); - if (!args) { - iocts.arg = (unsigned long) &nstring; - if ((result = ioctl(fd, IIOCGETMAP, &iocts)) < 0) { - perror(id); - exit(-1); - } - printf("MSN/EAZ-mapping for %s:\n%s\n", id, nstring); - } else { - char buf[400]; - strncpy(buf, arg1, sizeof(buf) - 1); - iocts.arg = (unsigned long) buf; - if ((result = ioctl(fd, IIOCSETMAP, &iocts)) < 0) { - perror(id); - exit(-1); - } - } - break; - - case SYSTEM: - if (strcmp(id, "on") && strcmp(id, "off")) { - fprintf(stderr, "System-Mode must be 'on' or 'off'\n"); - exit(-1); - } - j = strcmp(id, "on"); - if ((result = ioctl(fd, IIOCSETGST, j)) < 0) { - perror(id); - exit(-1); - } - break; - - case HANGUP: - if ((result = ioctl(fd, IIOCNETHUP, id)) < 0) { - perror(id); - exit(-1); - } - if (result) - printf("%s not connected\n", id); - else - printf("%s hung up\n", id); - break; - - case ADDPHONE: - if (strcmp(arg1, "in") && strcmp(arg1, "out")) { - fprintf(stderr, "Direction must be \"in\" or \"out\"\n"); - exit(-1); - } - phone.outgoing = strcmp(arg1, "out") ? 0 : 1; - if (strlen(arg2) > 20) { - fprintf(stderr, "phone-number must not exceed 20 characters\n"); - exit(-1); - } - strcpy(phone.name, id); - strcpy(phone.phone, arg2); - if ((result = ioctl(fd, IIOCNETANM, &phone)) < 0) { - perror(id); - exit(-1); - } - break; - - case DELPHONE: - if (strcmp(arg1, "in") && strcmp(arg1, "out")) { - fprintf(stderr, "Direction must be \"in\" or \"out\"\n"); - exit(-1); - } - phone.outgoing = strcmp(arg1, "out") ? 0 : 1; - if (strlen(arg2) > 20) { - fprintf(stderr, "phone-number must not exceed 20 characters\n"); - exit(-1); - } - strcpy(phone.name, id); - strcpy(phone.phone, arg2); - if ((result = ioctl(fd, IIOCNETDNM, &phone)) < 0) { - perror(id); - exit(-1); - } - break; - - case LIST: - if (!strcmp(id, "all")) { - char name[10]; - if ((iflst = fopen("/proc/net/dev", "r")) == NULL) { - perror("/proc/net/dev"); - exit(-1); - } - while (!feof(iflst)) { - fgets(s, sizeof(s), iflst); - if ((p = strchr(s, ':'))) { - *p = 0; - sscanf(s, "%s", name); - listif(fd, name, 0); - while (strlen(nextlistif)) - listif(fd, nextlistif, 0); - } - } - fclose(iflst); - } else - listif(fd, id, 1); - break; - - case EAZ: - strcpy(cfg.name, id); - if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - if (args) { - i = -1; - strncpy(cfg.eaz, arg1, sizeof(cfg.eaz) - 1); - if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - } - printf("EAZ/MSN for %s is %s\n", cfg.name, cfg.eaz); - break; - - case VERBOSE: - i = -1; - sscanf(id, "%d", &i); - if (i < 0) { - fprintf(stderr, "Verbose-level must be >= 0\n"); - exit(-1); - } - if ((result = ioctl(fd, IIOCSETVER, i)) < 0) { - perror("IIOCSETVER"); - exit(-1); - } - printf("Verbose-level set to %d.\n", i); - break; - - case GETCONF: - get_setup(fd, id); - printf("Configuration written to %s.\n", id); - break; - - case HUPTIMEOUT: - strcpy(cfg.name, id); - if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - if (args) { - i = -1; - sscanf(arg1, "%d", &i); - if (i < 0) { - fprintf(stderr, "Hangup-Timeout must be >= 0\n"); - exit(-1); - } - cfg.onhtime = i; - if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - } - printf("Hangup-Timeout for %s is %d sec.\n", cfg.name, cfg.onhtime); - break; - - case CBDELAY: - strcpy(cfg.name, id); - if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - if (args) { - i = -1; - sscanf(arg1, "%d", &i); - if (i < 0) { - fprintf(stderr, "Callback delay must be >= 0\n"); - exit(-1); - } - cfg.cbdelay = i * 5; - if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - } - printf("Callback delay for %s is %d sec.\n", cfg.name, cfg.cbdelay / 5); - break; - - case CHARGEINT: - strcpy(cfg.name, id); - if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - if (args) { - i = -1; - sscanf(arg1, "%d", &i); - if (i < 0) { - fprintf(stderr, "Charge interval must be >= 0\n"); - exit(-1); - } - cfg.chargeint = i; - if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - } - printf("Charge Interval for %s is %d sec.\n", cfg.name, cfg.chargeint); - break; - - case DIALMAX: - strcpy(cfg.name, id); - if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - if (args) { - i = -1; - sscanf(arg1, "%d", &i); - if (i < 1) { - fprintf(stderr, "Dialmax must be > 0\n"); - exit(-1); - } - cfg.dialmax = i; - if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - } - printf("Dialmax for %s is %d times.\n", cfg.name, cfg.dialmax); - break; - - case SDELAY: - strcpy(cfg.name, id); - if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - if (args) { - i = -1; - sscanf(arg1, "%d", &i); - if (i < 1) { - fprintf(stderr, "Slave-activation delay must be >= 1\n"); - exit(-1); - } - cfg.slavedelay = i; - if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - } - printf("Slave-activation delay for %s is %d sec.\n", cfg.name, - cfg.slavedelay); - break; - - case TRIGGER: - strcpy(cfg.name, id); - if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - if (args) { - i = -1; - sscanf(arg1, "%d", &i); - if (i < 0) { - fprintf(stderr, "Slave triggerlevel must be >= 0\n"); - exit(-1); - } - cfg.triggercps = i; - if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - } - printf("Slave triggerlevel for %s is %d cps.\n", cfg.name, - cfg.triggercps); - break; - - case CHARGEHUP: - strcpy(cfg.name, id); - if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - if (args) { - i = -1; - if (strcmp(arg1, "on") && strcmp(arg1, "off")) { - fprintf(stderr, "Charge-Hangup must be 'on' or 'off'\n"); - exit(-1); - } - cfg.chargehup = strcmp(arg1, "off"); - if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - } - printf("Charge-Hangup for %s is %s\n", cfg.name, cfg.chargehup ? "on" : "off"); - break; - - case CBHUP: - strcpy(cfg.name, id); - if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - if (args) { - i = -1; - if (strcmp(arg1, "on") && strcmp(arg1, "off")) { - fprintf(stderr, "Callback-Hangup must be 'on' or 'off'\n"); - exit(-1); - } - cfg.cbhup = strcmp(arg1, "off"); - if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - } - printf("Reject before Callback for %s is %s\n", cfg.name, cfg.cbhup ? "on" : "off"); - break; - - case IHUP: - strcpy(cfg.name, id); - if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - if (args) { - i = -1; - if (strcmp(arg1, "on") && strcmp(arg1, "off")) { - fprintf(stderr, "Incoming-Hangup must be 'on' or 'off'\n"); - exit(-1); - } - cfg.ihup = strcmp(arg1, "off"); - if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - } - printf("Incoming-Hangup for %s is %s\n", cfg.name, cfg.ihup ? "on" : "off"); - break; - - case SECURE: - strcpy(cfg.name, id); - if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - if (args) { - i = -1; - if (strcmp(arg1, "on") && strcmp(arg1, "off")) { - fprintf(stderr, "Secure-parameter must be 'on' or 'off'\n"); - exit(-1); - } - cfg.secure = strcmp(arg1, "off"); - if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - } - printf("Security for %s is %s\n", cfg.name, cfg.secure ? "on" : "off"); - break; - - case CALLBACK: - strcpy(cfg.name, id); - if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - if (args) { - i = -1; - if (strcmp(arg1, "on") && strcmp(arg1, "off") && - strcmp(arg1, "in") && strcmp(arg1, "out")) { - fprintf(stderr, "Callback-parameter must be 'on', 'in', 'out' or 'off'\n"); - exit(-1); - } - cfg.callback = strcmp(arg1, "off") ? 1 : 0; - if (!strcmp(arg1, "out")) - cfg.callback = 2; - if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - } - printf("Callback for %s is %s\n", cfg.name, num2callb[cfg.callback]); - break; - - case L2_PROT: - strcpy(cfg.name, id); - if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - if (args) { - i = key2num(arg1, l2protostr, l2protoval); - if (i < 0) { - fprintf(stderr, "Layer-2-Protocol must be one of the following:\n"); - i = 0; - while (strlen(l2protostr[i])) - fprintf(stderr, "\t\"%s\"\n", l2protostr[i++]); - exit(-1); - } - cfg.l2_proto = i; - if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - } - printf("Layer-2-Protocol for %s is %s\n", cfg.name, - num2key(cfg.l2_proto, l2protostr, l2protoval)); - break; - - case L3_PROT: - strcpy(cfg.name, id); - if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - if (args) { - i = key2num(arg1, l3protostr, l3protoval); - if (i < 0) { - fprintf(stderr, "Layer-3-Protocol must be one of the following:\n"); - i = 0; - while (strlen(l3protostr[i])) - fprintf(stderr, "\t\"%s\"\n", l3protostr[i++]); - exit(-1); - } - cfg.l3_proto = i; - if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - } - printf("Layer-3-Protocol for %s is %s\n", cfg.name, - num2key(cfg.l3_proto, l3protostr, l3protoval)); - break; - - case ADDLINK: - if ((result = ioctl(fd, IIOCNETALN, id)) < 0) { - perror(id); - exit(-1); - } - if (result) - printf("Can't increase number of links: %d\n", result); - else - printf("Ok, added a new link. (dialing)\n"); - break; - - case REMOVELINK: - if ((result = ioctl(fd, IIOCNETDLN, id)) < 0) { - perror(id); - exit(-1); - } - if (result) - printf("Can't decrease number of links: %d\n", result); - else - printf("Ok, removed a link. (hangup)\n"); - break; - - case ENCAP: - strcpy(cfg.name, id); - if ((result = ioctl(fd, IIOCNETGCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - if (args) { - i = key2num(arg1, pencapstr, pencapval); - if (i < 0) { - fprintf(stderr, "Encapsulation must be one of the following:\n"); - i = 0; - while (strlen(pencapstr[i])) - fprintf(stderr, "\t\"%s\"\n", pencapstr[i++]); - exit(-1); - } - cfg.p_encap = i; - if ((result = ioctl(fd, IIOCNETSCF, &cfg)) < 0) { - perror(id); - exit(-1); - } - } - printf("Encapsulation for %s is %s\n", cfg.name, - num2key(cfg.p_encap, pencapstr, pencapval)); - break; - } - cmdptr += args + 1; - if (cmdptr < argc) { - printf("args=%d nextcmd %s\n",args, argv[cmdptr]); - i = findcmd(argv[cmdptr]); - } - } - close(fd); + exec_args(fd,argc-1,argv+1); + close(fd); } diff --git a/isdnctrl/isdnctrl.h b/isdnctrl/isdnctrl.h new file mode 100644 index 00000000..0905e62f --- /dev/null +++ b/isdnctrl/isdnctrl.h @@ -0,0 +1,151 @@ +/* $Id$ + * ISDN driver for Linux. (Control-Utility) + * + * Copyright 1994,95 by Fritz Elfert (fritz@wuemaus.franken.de) + * Copyright 1995 Thinking Objects Software GmbH Wuerzburg + * + * This file is part of Isdn4Linux. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Log$ + * + */ + +/*****************************************************************************/ + +enum { + ADDIF, ADDSLAVE, DELIF, DIAL, + BIND, UNBIND, PPPBIND, PPPUNBIND, + BUSREJECT, MAPPING, SYSTEM, HANGUP, + ADDPHONE, DELPHONE, LIST, EAZ, + VERBOSE, GETCONF, HUPTIMEOUT, CBDELAY, + CHARGEINT, DIALMAX, SDELAY, CHARGEHUP, + CBHUP, IHUP, SECURE, CALLBACK, + L2_PROT, L3_PROT, ADDLINK, REMOVELINK, + ENCAP, TRIGGER, +#ifdef I4L_CTRL_CONF + WRITECONF, READCONF +#endif /* I4L_CTRL_CONF */ +}; + +typedef struct { + char *cmd; + char *argno; +} cmd_struct; + +/*****************************************************************************/ + +#ifdef _ISDNCTRL_C_ +#define _EXTERN + +cmd_struct cmds[] = +{ + {"addif", "01"}, + {"addslave", "2"}, + {"delif", "1"}, + {"dial", "1"}, + {"bind", "123"}, + {"unbind", "1"}, + {"pppbind", "12"}, + {"pppunbind", "1"}, + {"busreject", "2"}, + {"mapping", "12"}, + {"system", "1"}, + {"hangup", "1"}, + {"addphone", "3"}, + {"delphone", "3"}, + {"list", "1"}, + {"eaz", "12"}, + {"verbose", "1"}, + {"getconf", "01"}, + {"huptimeout", "12"}, + {"cbdelay", "12"}, + {"chargeint", "12"}, + {"dialmax", "12"}, + {"sdelay", "12"}, + {"chargehup", "12"}, + {"cbhup", "12"}, + {"ihup", "12"}, + {"secure", "12"}, + {"callback", "12"}, + {"l2_prot", "12"}, + {"l3_prot", "12"}, + {"addlink", "1"}, + {"removelink", "1"}, + {"encap", "12"}, + {"trigger", "01"}, +#ifdef I4L_CTRL_CONF + {"writeconf", "01"}, + {"readconf", "01"}, +#endif /* I4L_CTRL_CONF */ + {NULL,} +}; + +char *l2protostr[] = { + "x75i", "x75ui", "x75bui", "hdlc", "\0" +}; + +int l2protoval[] = { + ISDN_PROTO_L2_X75I, ISDN_PROTO_L2_X75UI, + ISDN_PROTO_L2_X75BUI, ISDN_PROTO_L2_HDLC, -1 +}; + +char *l3protostr[] = { + "trans", "\0" +}; + +int l3protoval[] = { + ISDN_PROTO_L3_TRANS, -1 +}; + +char *pencapstr[] = { + "ethernet", "rawip", "ip", "cisco-h", "syncppp", + "uihdlc", "\0" +}; + +int pencapval[] = { + ISDN_NET_ENCAP_ETHER, ISDN_NET_ENCAP_RAWIP, + ISDN_NET_ENCAP_IPTYP, ISDN_NET_ENCAP_CISCOHDLC, + ISDN_NET_ENCAP_SYNCPPP, ISDN_NET_ENCAP_UIHDLC, -1 +}; + +char *num2callb[] = { + "off", "in", "out" +}; + +#else +#define _EXTERN extern + +_EXTERN cmd_struct cmds[]; +_EXTERN char *l2protostr[]; +_EXTERN int l2protoval[]; +_EXTERN char *l3protostr[]; +_EXTERN int l3protoval[]; +_EXTERN char *pencapstr[]; +_EXTERN int pencapval[]; +_EXTERN char *num2callb[]; + +#endif + +_EXTERN char *cmd; + +_EXTERN int key2num(char *key, char **keytable, int *numtable); +_EXTERN char * num2key(int num, char **keytable, int *numtable); +_EXTERN int exec_args(int fd, int argc, char **argv); + +#undef _EXTERN + +/*****************************************************************************/ diff --git a/isdnctrl/isdnctrl.man b/isdnctrl/isdnctrl.man index 8192a96f..2b96cff3 100644 --- a/isdnctrl/isdnctrl.man +++ b/isdnctrl/isdnctrl.man @@ -1,4 +1,4 @@ -.TH ISDNCTRL 8 "02. April 1996" +.TH ISDNCTRL 8 "25. June 1997" .UC 4 .SH NAME isdnctrl \- get/set ISDN device information @@ -196,6 +196,12 @@ interfaces cannot use that interface anymore. .B unbind name Unbinds a the previously bound interface "name". .TP 5 +.B pppbind name [num] +Binds the current interface to a ippp device (/dev/ipppX). +This works only for syncronous ppp. +The value must be a number. +If no number is omitted, it shows the the curring binding. +.TP 5 .B busreject driverId [on|off] If switched on, isdn4linux replies a REJECT to incoming calls, it cannot match to any configured interface. If switched off, nothing @@ -236,6 +242,217 @@ Force dialing of interface "name". .TP 5 .B mapping driverId MSN0[,MSN1[,MSN2]] ... [,MSN9] Installs a mapping-table for MSN<->EAZ-mapping. See README for details. +.TP 5 +.B writeconf [file] +Writes the configuration into a file. If "file" is omitted, the default file +/etc/isdn/isdn.conf will be used. +.TP 5 +.B readconf [file] +Reads the configuration from a file. If "file" is omitted, the default file +/etc/isdn/isdn.conf will be used. + +.SS Syntax of the configuration file +This syntax will be used for the options +.B readconf +and +.B writeconf. + +All entries are included in the section +.B [ISDNCTRL]. +This section contains an entry +.B INTERFACES, +which describes the interfaces. Each subsection +.B [INTERFACE] +or +.B [SLAVE] +describes one interface. There are the following entries possible: +.TP 5 +.B NAME +The name of the interface. +This entry is required. + +.B Example: +NAME = ippp0 +.TP 5 +.B EAZ +Set the EAZ or the MSN. +This entry is required. + +.B Example: +EAZ = 4711 +.TP 5 +.B PHONE_IN +Set the incoming phone number(s). +It requires at least one blank between the different numbers. + +.B Example: +PHONE_IN = 08151234 08151235 08151236 +.TP 5 +.B PHONE_OUT +Set the outgoing phone number(s). +It requires at least one blank between the different numbers. + +.B Example: +PHONE_OUT = 08151237 08151238 +.TP 5 +.B SECURE +Turn on or off the security feature. +Allowed values are "on" and "off". + +.B Example: +SECURE = on +.TP 5 +.B CALLBACK +Selects callback mode. +Allowed values are "off", "in" and "out". + +.B Example: +CALLBACK = in +.TP 5 +.B CBHUP +Turns on or off hangup before starting callback. +Allowed values are "on" and "off". + +.B Example: +CBHUP = on +.TP 5 +.B CBDELAY +Set the callback delay to "seconds". + +.B Example: +CBDELAY = 5 +.TP 5 +.B DIALMAX +Set the number of dial atempts to "num". + +.B Example: +DIALMAX = 1 +.TP 5 +.B HUPTIMEOUT +Set the hanguptime to "seconds". + +.B Example: +HUPTIMEOUT = 20 +.TP 5 +.B IHUP +Turns on or off the hangup timeout for incoming calls. +Allowed values are "on" and "off". + +.B Example: +IHUP = on +.TP 5 +.B CHARGEHUP +Turns on or off hangup before next charge info. +Allowed values are "on" and "off". + +.B Example: +CHARGEHUP = on +.TP 5 +.B CHARGEINT +Sets the charge interval to "seconds". + +.B Example: +CHARGEINT = 1 +.TP 5 +.B L2_PROT +Set the layer-2 protocol. +Allowed values are "x75i", "x75ui", "x75bui" and "hdlc". + +.B Example: +L2_PROT = hdlc +.TP 5 +.B L3_PROT +Set the layer-3 protocol. +Allowed value is only "trans". + +.B Example: +L3_PROT = trans +.TP 5 +.B ENCAP +Sets the encapsulation mode. +Allowed values are "rawip", "ip", "cisco_h", "ethernet", "syncppp" and "uihdlc". + +.B Example: +ENCAP = rawip +.TP 5 +.B SDELAY +Set the delay in seconds for the slave-dialing. + +.B Example: +SDELAY = 0 +.TP 5 +.B ADDSLAVE +Adds a slave interface for channel-bundling. + +.B Example: +ADDSLAVE = s-ippp0 +.TP 5 +.B BIND +Binds the current interface to a specific physical channel. +Before and after the comma may not be a blank. + +.B Example: +BIND = teles1,0 +.TP 5 +.B PPPBIND +Binds the current interface to a ippp device (/dev/ipppX). +This works only for syncronous ppp. +The value must be a number. + +.B Example: +PPPBIND = 0 + + +.TP 5 +.B Example for a configuration file + +[ISDNCTRL] + INTERFACES = { + [INTERFACE] + NAME = isdn0 + EAZ = 4711 + PHONE_IN = 08151234 + PHONE_OUT = 08151234 + SECURE = on + DIALMAX = 1 + HUPTIMEOUT= 20 + IHUP = on + CHARGEHUP = on + L2_PROT = hdlc + L3_PROT = trans + ENCAP = rawip + ADDSLAVE = s-isdn0 + SDELAY = 10 + + [SLAVE] + NAME = s-isdn0 + EAZ = 4711 + PHONE_OUT = 08151234 + SECURE = on + DIALMAX = 1 + HUPTIMEOUT= 10 + IHUP = on + CHARGEHUP = on + L2_PROT = hdlc + L3_PROT = trans + ENCAP = rawip + + [INTERFACE] + NAME = ippp0 + EAZ = 4712 + PHONE_OUT = 08151235 08151236 + SECURE = on + DIALMAX = 5 + HUPTIMEOUT= 200 + IHUP = on + CHARGEHUP = on + L2_PROT = hdlc + L3_PROT = trans + ENCAP = syncppp + PPPBIND = 0 + } + + .SH WILDCARDS For matching incoming calls phone numbers can be be set by diff --git a/isdnlog/tools/isdnconf.c b/isdnlog/tools/isdnconf.c index 0d7a42bd..5661d95b 100644 --- a/isdnlog/tools/isdnconf.c +++ b/isdnlog/tools/isdnconf.c @@ -20,6 +20,11 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log$ + * Revision 1.12 1997/06/22 23:03:34 luethje + * In subsection FLAGS it will be checked if the section name FLAG is korrect + * isdnlog recognize calls abroad + * bugfix for program starts + * * Revision 1.11 1997/05/25 19:41:13 luethje * isdnlog: close all files and open again after kill -HUP * isdnrep: support vbox version 2.0 @@ -1226,8 +1231,10 @@ static info_args** Set_Flags(section *SPtr, int *Flags) { RetCode[NumArgs]->time = EPtr->value; } +/* else _print_msg("Error: Invalid variable `%s'!\n",EPtr->name); +*/ EPtr = EPtr->next; } diff --git a/scripts/config.in b/scripts/config.in index 8e690f94..9bfb5473 100644 --- a/scripts/config.in +++ b/scripts/config.in @@ -54,6 +54,7 @@ comment 'Runtime configuration tools' bool 'isdnctrl' CONFIG_ISDNCTRL if [ "$CONFIG_ISDNCTRL" = "y" ]; then bool 'Enable isdnctrl debug-option' CONFIG_ISDNCTRL_DEBUG + bool 'Enable configfile-option (uses dbm lib)' CONFIG_CTRL_CONF fi bool 'iprofd' CONFIG_IPROFD endmenu diff --git a/scripts/defconfig b/scripts/defconfig index 32deea91..65dadd51 100644 --- a/scripts/defconfig +++ b/scripts/defconfig @@ -34,6 +34,7 @@ CONFIG_AREACODE_DATA='/usr/lib/isdn' # CONFIG_ISDNCTRL=y # CONFIG_ISDNCTRL_DEBUG is not set +# CONFIG_CTRL_CONF is not set CONFIG_IPROFD=y #