Added the source code isdnlog. isdnlog is not working yet.

A workaround for that problem:
copy lib/policy.h into the root directory of isdn4k-utils.
This commit is contained in:
luethje 1997-03-16 20:58:07 +00:00
parent cdfbd7902b
commit 186c856777
37 changed files with 16916 additions and 4 deletions

View File

@ -1,4 +1,4 @@
## $Id: Makefile,v 1.1 1997/03/03 04:37:33 fritz Exp $
## $Id: Makefile,v 1.2 1997/03/16 20:58:07 luethje Exp $
##
## ISDN accounting for isdn4linux.
##
@ -19,6 +19,11 @@
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
##
## $Log: Makefile,v $
## Revision 1.2 1997/03/16 20:58:07 luethje
## Added the source code isdnlog. isdnlog is not working yet.
## A workaround for that problem:
## copy lib/policy.h into the root directory of isdn4k-utils.
##
## Revision 1.1 1997/03/03 04:37:33 fritz
## Added files in isdnlog
##
@ -32,6 +37,9 @@ else
PREFIXDIR=$(ROOTDIR)
endif
PREFIXDIR=..
LIBAREA=1
LIBISDNDIR = $(PREFIXDIR)/lib
ifdef MAKELIB
SUBDIRS = $(LIBISDNDIR)
@ -83,7 +91,7 @@ SERVICEFILE = /etc/services
# DON'T EDIT BELOW THIS LINE
######################################################################
#I4LVERSION = 2.60
VERSION = 2.99.1
ifdef POSTGRES
CFLAGS += -DPOSTGRES
@ -109,7 +117,7 @@ CFLAGS += -DOLDCONFFILE=\"$(OLDCONFFILE)\" \
-DLOGFILE=\"$(LOGFILE)\" \
-DRELOADCMD=\"$(RELOADCMD)\" \
-DSTOPCMD=\"$(STOPCMD)\" \
-DI4LVERSION=\"$(I4LVERSION)\" \
-DVERSION=\"$(VERSION)\" \
-DCHARGEFILE=\"$(CHARGEFILE)\" \
-DSERV_PORT=$(SERV_PORT) \
-DREBOOTCMD=\"$(REBOOTCMD)\" \
@ -215,7 +223,7 @@ xinstall: xall install
# @echo ""
distrib: xdistclean
cd .. && tar cf /tmp/isdnlog-$(I4LVERSION).tar \
cd .. && tar cf /tmp/isdnlog-$(VERSION).tar \
isdnlog-$(I4LVERSION)/Makefile \
isdnlog-$(I4LVERSION)/Isdn \
isdnlog-$(I4LVERSION)/README \

View File

@ -2364,6 +2364,11 @@ Dies wird in 4 Stufen versucht:
4. Stufe: Der Rechner wird rebootet ("/sbin/reboot")
In der Parameterdatei wird dieses Feature mit
watchdog="value"
aufgerufen.
14.2 CHARGEMAX
--------------

92
isdnlog/connect/connect.c Normal file
View File

@ -0,0 +1,92 @@
/*
* ISDN accounting for isdn4linux.
*
* Copyright 1996 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.
*
*/
/****************************************************************************/
#define _CONNECT_C_
/****************************************************************************/
#include "socket.h"
/****************************************************************************/
int server_connect(struct servent **sp, int port)
{
int sock;
struct sockaddr_in server;
if (!port)
if ((*sp = getservbyname(SERV_ISDNLOG,"tcp")) != NULL)
port = (*sp)->s_port;
else
port = htons(SERV_PORT);
else
port = htons (port);
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = port;
if ((sock = socket(AF_INET,SOCK_STREAM,0)) < 0)
return NO_SOCKET;
if (bind(sock,(struct sockaddr*) &server,sizeof(server)) < 0)
return NO_BIND;
if (listen(sock,MAX_CLIENTS_LISTEN))
return NO_LISTEN;
return sock;
}
/****************************************************************************/
int client_connect(char *name, int port)
{
int sock;
struct sockaddr_in server;
struct servent *sp;
struct hostent *hp = gethostbyname (name);
if((sock = socket (AF_INET, SOCK_STREAM, 0)) < 0)
return NO_SOCKET;
if (!port)
if ((sp = getservbyname(SERV_ISDNLOG,"tcp")) != NULL)
port = sp->s_port;
else
port = htons(SERV_PORT);
else
port = htons (port);
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = port;
memcpy ((char *) &server.sin_addr, (char *) hp->h_addr, hp->h_length);
if (connect (sock, (struct sockaddr *) &server, sizeof (server)) < 0)
return NO_CONNECT;
return sock;
}

View File

@ -0,0 +1,526 @@
/*
* ISDN accounting for isdn4linux.
*
* Copyright 1996 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.
*
*/
/*****************************************************************************/
#define _CONV_ADDRESS_C_
/*****************************************************************************/
#include "socket.h"
/*****************************************************************************/
#define ADR_DELIMITER ':'
/*****************************************************************************/
int Set_String(char **Target, char*Source);
int Set_Address(Addresses **Adr, int Anz, char **Array, int *Cnt2);
int Set_String_Field(char ***String, int Anz,char **Array, int *Cnt2);
int Set_PhoneNumber(PhoneNumber **String, int Anz,char **Array, int *Cnt2);
int Set_Date(time_t *NewTime, char *Ptr1);
int Append_Date(char** String, time_t NewTime);
int Append_Integer(char** String, int Append);
int Append_String(char** String, char *Append);
/*****************************************************************************/
#ifdef STANDALONE
int main (int argc, char* argv[])
{
int len = 5000;
char buf[5000];
Address *Ptr;
while(!feof(stdin))
{
fgets(buf,len,stdin);
if ((Ptr = read_address(buf)) != NULL)
{
printf("%s\n",write_address(Ptr));
free_Address(Ptr);
}
}
return 0;
}
#endif
/*****************************************************************************/
Address* read_address(char* Ptr1)
{
Address *APtr;
char **Array;
int Cnt = 0;
Array = String_to_Array(Ptr1, ADR_DELIMITER);
if (Array == NULL)
{
del_Array(Array);
return NULL;
}
if ((APtr = (Address*) calloc(1,sizeof(Address))) == NULL)
{
free_Address(APtr);
del_Array(Array);
return NULL;
}
if (Set_String(&(APtr->NName),Array[Cnt++]))
{
free_Address(APtr);
del_Array(Array);
return NULL;
}
if (Set_String(&(APtr->FName),Array[Cnt++]))
{
free_Address(APtr);
del_Array(Array);
return NULL;
}
if (Array[Cnt])
APtr->NumAdr = atoi(Array[Cnt++]);
else
{
free_Address(APtr);
del_Array(Array);
return NULL;
}
if (Set_Address(&(APtr->Adr),APtr->NumAdr,Array,&Cnt))
{
free_Address(APtr);
del_Array(Array);
return NULL;
}
/*
if (Set_Date(&(APtr->Birthday),Ptr1))
*/
if (Set_String(&(APtr->Birthday),Array[Cnt++]))
{
free_Address(APtr);
del_Array(Array);
return NULL;
}
del_Array(Array);
return APtr;
}
/*****************************************************************************/
char* write_address(Address* Ptr)
{
int Cnt1, Cnt2;
int len;
char *RetCode = NULL;
if (Append_String(&RetCode,Ptr->NName))
return NULL;
if (Append_String(&RetCode,Ptr->FName))
return NULL;
if (Append_Integer(&RetCode,Ptr->NumAdr))
return NULL;
for (Cnt1 = 0; Cnt1 < Ptr->NumAdr; Cnt1++)
{
if (Append_String(&RetCode,Ptr->Adr[Cnt1].Company))
return NULL;
if (Append_String(&RetCode,Ptr->Adr[Cnt1].Street))
return NULL;
if (Append_String(&RetCode,Ptr->Adr[Cnt1].Country))
return NULL;
if (Append_String(&RetCode,Ptr->Adr[Cnt1].PLZ))
return NULL;
if (Append_String(&RetCode,Ptr->Adr[Cnt1].City))
return NULL;
if (Append_Integer(&RetCode,Ptr->Adr[Cnt1].NumTel))
return NULL;
for (Cnt2 = 0; Cnt2 < Ptr->Adr[Cnt1].NumTel; Cnt2++)
{
if (Append_String(&RetCode,Ptr->Adr[Cnt1].Tel[Cnt2].Number))
return NULL;
if (Append_String(&RetCode,Ptr->Adr[Cnt1].Tel[Cnt2].Alias))
return NULL;
}
if (Append_Integer(&RetCode,Ptr->Adr[Cnt1].NumFax))
return NULL;
for (Cnt2 = 0; Cnt2 < Ptr->Adr[Cnt1].NumFax; Cnt2++)
{
if (Append_String(&RetCode,Ptr->Adr[Cnt1].Fax[Cnt2].Number))
return NULL;
if (Append_String(&RetCode,Ptr->Adr[Cnt1].Fax[Cnt2].Alias))
return NULL;
}
if (Append_Integer(&RetCode,Ptr->Adr[Cnt1].NumEmail))
return NULL;
for (Cnt2 = 0; Cnt2 < Ptr->Adr[Cnt1].NumEmail; Cnt2++)
if (Append_String(&RetCode,Ptr->Adr[Cnt1].Email[Cnt2]))
return NULL;
}
/*
if (Append_Date(&RetCode,Ptr->Birthday))
*/
if (Append_String(&RetCode,Ptr->Birthday))
return NULL;
len = strlen(RetCode);
if (len > 0)
RetCode[len-1] = '\0';
return RetCode;
}
/*****************************************************************************/
int Append_Integer(char** String, int Append)
{
static char NewString[30];
sprintf(NewString,"%d",Append);
return Append_String(String,NewString);
}
/*****************************************************************************/
int Append_String(char** String, char *Append)
{
int len1 = 0;
int len2 = 0;
if (Append == NULL)
Append = "";
else
len2 = strlen(Append);
if (*String)
{
len1 = strlen(*String);
*String = (char*) realloc(*String,(len1+len2+2)*sizeof(char));
}
else
*String = (char*) calloc(len2+2,sizeof(char));
if (*String == NULL)
return -1;
/*
strcat(*String,Append);
*/
memcpy(*String+len1,Append,len2);
(*String)[len1+len2] = ADR_DELIMITER;
(*String)[len1+len2+1] = '\0';
return 0;
}
/*****************************************************************************/
int Append_Date(char** String, time_t NewTime)
{
static char RetString[20];
struct tm *Time;
Time = localtime(&NewTime);
sprintf(RetString,"%d.%d.%d",Time->tm_mday,Time->tm_mon+1,Time->tm_year+1900);
return Append_String(String,RetString);
}
/*****************************************************************************/
int Set_Date(time_t *NewTime, char *Ptr)
{
int Day, Month, Year;
time_t t_Time;
struct tm Time;
static struct tm *CurTime = NULL;
if (*Ptr == '\0')
return 0;
if (sscanf(Ptr,"%d.%d.%d",&Day,&Month,&Year) == 3);
else
if (sscanf(Ptr,"%d/%d/%d",&Month,&Day,&Year) == 3);
else
return -1;
Time.tm_sec = 0;
Time.tm_min = 0;
Time.tm_hour = 0;
Time.tm_wday = 0;
Time.tm_yday = 0;
Time.tm_isdst = 0;
Time.tm_mday = Day;
Time.tm_mon = Month - 1;
if (Year < 100)
{
if (CurTime == NULL)
{
time(&t_Time);
CurTime = localtime(&t_Time);
}
Time.tm_year = (CurTime->tm_year/100) * 100 + Year;
}
else
Time.tm_year = Year - 1900;
(*NewTime) = mktime(&Time);
return 0;
}
/*****************************************************************************/
int Set_PhoneNumber(PhoneNumber **String, int Anz,char **Array, int *Cnt2)
{
int Cnt = 0;
if (!Anz)
return 0;
if((*String = (PhoneNumber*) calloc(Anz,sizeof(PhoneNumber))) == NULL)
return -1;
while (Cnt < Anz)
{
if (Set_String(&((*String)[Cnt].Number),Array[(*Cnt2)++]))
return -1;
if (Set_String(&((*String)[Cnt].Alias),Array[(*Cnt2)++]))
return -1;
Cnt++;
}
return 0;
}
/*****************************************************************************/
int Set_String_Field(char ***String, int Anz,char **Array, int *Cnt2)
{
int Cnt = 0;
if (!Anz)
return 0;
if((*String = (char**) calloc(Anz,sizeof(char*))) == NULL)
return -1;
while (Cnt < Anz)
{
if (Set_String(&((*String)[Cnt]),Array[(*Cnt2)++]))
return -1;
Cnt++;
}
return 0;
}
/*****************************************************************************/
int Set_Address(Addresses **Adr, int Anz, char **Array, int *Cnt2)
{
int Cnt = 0;
if (!Anz)
return 0;
if((*Adr = (Addresses*) calloc(Anz,sizeof(Addresses))) == NULL)
return -1;
while (Cnt < Anz)
{
if (Set_String(&((*Adr)[Cnt].Company),Array[(*Cnt2)++]))
return -1;
if (Set_String(&((*Adr)[Cnt].Street),Array[(*Cnt2)++]))
return -1;
if (Set_String(&((*Adr)[Cnt].Country),Array[(*Cnt2)++]))
return -1;
if (Set_String(&((*Adr)[Cnt].PLZ),Array[(*Cnt2)++]))
return -1;
if (Set_String(&((*Adr)[Cnt].City),Array[(*Cnt2)++]))
return -1;
if (Array[*Cnt2])
(*Adr)[Cnt].NumTel = atoi(Array[(*Cnt2)++]);
else
return -1;
if (Set_PhoneNumber(&((*Adr)[Cnt].Tel),(*Adr)[Cnt].NumTel,Array,Cnt2))
return -1;
if (Array[*Cnt2])
(*Adr)[Cnt].NumFax = atoi(Array[(*Cnt2)++]);
else
return -1;
if (Set_PhoneNumber(&((*Adr)[Cnt].Fax),(*Adr)[Cnt].NumFax,Array,Cnt2))
return -1;
if (Array[*Cnt2])
(*Adr)[Cnt].NumEmail = atoi(Array[(*Cnt2)++]);
else
return -1;
if (Set_String_Field(&((*Adr)[Cnt].Email),(*Adr)[Cnt].NumEmail,Array,Cnt2))
return -1;
Cnt++;
}
return 0;
}
/*****************************************************************************/
int Set_String(char **Target, char*Source)
{
int len = strlen(Source);
if (len && Source)
{
if ((*Target = (char*) calloc(len+1,sizeof(char))) == NULL)
return -1;
strcpy(*Target,Source);
if ((*Target)[len-1] == '\n')
(*Target)[len-1] = '\0';
}
return 0;
}
/*****************************************************************************/
void free_Address(Address *APtr)
{
int Cnt1, Cnt2;
if (APtr->Adr)
{
for(Cnt1 = 0; Cnt1 < APtr->NumAdr; Cnt1++)
{
if (APtr->Adr[Cnt1].Tel)
{
for(Cnt2 = 0; Cnt2 < APtr->Adr[Cnt1].NumTel; Cnt2++)
{
if (APtr->Adr[Cnt1].Tel[Cnt2].Number)
free(APtr->Adr[Cnt1].Tel[Cnt2].Number);
if (APtr->Adr[Cnt1].Tel[Cnt2].Alias)
free(APtr->Adr[Cnt1].Tel[Cnt2].Alias);
}
free(APtr->Adr[Cnt1].Tel);
}
if (APtr->Adr[Cnt1].Fax)
{
for(Cnt2 = 0; Cnt2 < APtr->Adr[Cnt1].NumFax; Cnt2++)
{
if (APtr->Adr[Cnt1].Fax[Cnt2].Number)
free(APtr->Adr[Cnt1].Fax[Cnt2].Number);
if (APtr->Adr[Cnt1].Fax[Cnt2].Alias)
free(APtr->Adr[Cnt1].Fax[Cnt2].Alias);
}
free(APtr->Adr[Cnt1].Fax);
}
if (APtr->Adr[Cnt1].Email)
{
for(Cnt2 = 0; Cnt2 < APtr->Adr[Cnt1].NumEmail; Cnt2++)
if (APtr->Adr[Cnt1].Email[Cnt2])
free(APtr->Adr[Cnt1].Email[Cnt2]);
}
if (APtr->Adr[Cnt1].Company)
free(APtr->Adr[Cnt1].Company);
if (APtr->Adr[Cnt1].Street)
free(APtr->Adr[Cnt1].Street);
if (APtr->Adr[Cnt1].Country)
free(APtr->Adr[Cnt1].Country);
if (APtr->Adr[Cnt1].PLZ)
free(APtr->Adr[Cnt1].PLZ);
if (APtr->Adr[Cnt1].City)
free(APtr->Adr[Cnt1].City);
}
free(APtr->Adr);
}
if (APtr->FName)
free(APtr->FName);
if (APtr->NName)
free(APtr->NName);
if (APtr->Birthday)
free(APtr->Birthday);
}
/*****************************************************************************/

495
isdnlog/connect/socket.c Normal file
View File

@ -0,0 +1,495 @@
/*
* ISDN accounting for isdn4linux.
*
* Copyright 1996 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.
*
*/
/****************************************************************************/
#define _SOCKET_C_
/****************************************************************************/
#include "socket.h"
/****************************************************************************/
int get_msg(socket_queue *sock, buffer *buf);
int bufcat(buffer *s1,buffer *s2, int first, int len);
int initbuf(buffer *buf);
/****************************************************************************/
int Write(socket_queue* sock)
{
/* ACHTUNG IN DIESER FKT DARF KEIN print_msg() AUFGERUFEN WERDEN !!!!! */
int RetCode;
static buffer *buf = NULL;
char *Ptr;
if (sock->descriptor < 0)
{
#ifdef DEBUG
syslog(LOG_DEBUG,"Write: Invalid Descriptor %d",sock->descriptor);
#endif
return 1;
}
if (!buf)
{
buf = (buffer*) calloc(1,sizeof(buffer));
if (!buf)
return NO_MEMORY;
if ((RetCode = initbuf(buf)) != 0)
return RetCode;
}
if ((Ptr = itos(sock->msgbuf.used+_MSG_LEN+_MSG_MSG,_MSG_LEN)) == NULL)
return -1;
memcpy(buf->buf,Ptr,_MSG_LEN);
buf->used = _MSG_LEN;
if ((Ptr = itos(sock->msg,_MSG_MSG)) == NULL)
return -1;
#ifdef DEBUG
syslog(LOG_DEBUG,"Write: Message %d:*%s*",sock->msg,sock->msgbuf.buf);
#endif
sock->msg = NO_MSG;
memcpy(buf->buf+_MSG_LEN,Ptr,_MSG_MSG);
buf->used += _MSG_MSG;
if ((RetCode = bufcat(buf,&(sock->msgbuf),0,sock->msgbuf.used)) != 0)
return RetCode;
return write(sock->descriptor,buf->buf,buf->used);
}
/****************************************************************************/
int Read(socket_queue* sock)
{
int RetCode;
int SelRet;
fd_set readmask;
struct timeval timeout = {0,0};
static buffer *buf = NULL;
if (sock->descriptor < 0)
{
#ifdef DEBUG
syslog(LOG_DEBUG,"Write: Invalid Descriptor %d",sock->descriptor);
#endif
return 1;
}
if (sock->restbuf.len > BUF_SIZE && sock->restbuf.used == 0)
{
free(sock->restbuf.buf);
sock->restbuf.buf = NULL;
initbuf(&(sock->restbuf));
}
if (sock->msgbuf.len > BUF_SIZE && sock->msgbuf.used == 0)
{
free(sock->msgbuf.buf);
sock->msgbuf.buf = NULL;
initbuf(&(sock->msgbuf));
}
else
sock->msgbuf.used = 0;
if (!buf)
{
if ((buf = (buffer*) calloc(1,sizeof(buffer))) == NULL)
return NO_MEMORY;
if ((RetCode = initbuf(buf)) != 0)
return RetCode;
}
else
if (buf->len > BUF_SIZE)
{
free(buf->buf);
buf->buf = NULL;
initbuf(buf);
}
FD_ZERO(&readmask);
FD_SET(sock->descriptor,&readmask);
while ((SelRet = select(sock->descriptor+1,&readmask,NULL,NULL,&timeout)) > 0 &&
FD_ISSET(sock->descriptor,&readmask))
if ((RetCode = buf->used = read(sock->descriptor,buf->buf,buf->len)) > 0)
{
if ((RetCode = bufcat(&(sock->restbuf),buf,0,buf->used)) != 0)
return RetCode;
}
else
return -1;
if (SelRet < 0)
return -1;
if (sock->restbuf.used)
if ((RetCode = get_msg(sock,buf)) != 0)
return RetCode;
return -1; /* Sollte nur ein Wert > 0 zurueckliefern */
}
/****************************************************************************/
int init_socket(socket_queue *sock)
{
int RetCode;
if (!sock)
return -1;
if ((RetCode = initbuf(&(sock->msgbuf))) != 0)
return RetCode;
if ((RetCode = initbuf(&(sock->restbuf))) != 0)
return RetCode;
return 0;
}
/****************************************************************************/
int get_msg(socket_queue *sock, buffer *buf)
{
int len;
int RetCode;
buf->used = 0;
sock->msgbuf.used = 0;
if (sock->restbuf.used < _MSG_LEN + _MSG_MSG)
{
sock->status = NO_NEXT_MSG;
sock->msg = NO_MSG;
return 0;
}
len = (int) stoi(sock->restbuf.buf,_MSG_LEN);
/* printf("stoi %d,%d\n",len,sock->restbuf.used); */
if (len > sock->restbuf.used)
{
sock->status = NO_NEXT_MSG;
sock->msg = NO_MSG;
return 0;
}
sock->msg = (int) stoi(sock->restbuf.buf+_MSG_LEN,_MSG_MSG);
if ((RetCode = bufcat(buf,&(sock->restbuf),0,sock->restbuf.used)) != 0)
return RetCode;
if ((RetCode = bufcat(&(sock->msgbuf),buf,_MSG_LEN+_MSG_MSG,len - _MSG_LEN - _MSG_MSG)) != 0)
return RetCode;
sock->restbuf.used = 0;
if ((RetCode = bufcat(&(sock->restbuf),buf,len,buf->used - len)) != 0)
return RetCode;
if (sock->restbuf.used >= _MSG_LEN + _MSG_MSG &&
stoi(sock->restbuf.buf,_MSG_LEN) <= sock->restbuf.used)
sock->status = NEXT_MSG;
else
sock->status = NO_NEXT_MSG;
return buf->used;
}
/****************************************************************************/
int msgcpy(socket_queue *sock, char *String, int len)
{
if (sock->msgbuf.len < len)
{
sock->msgbuf.len = len;
if ((sock->msgbuf.buf = (char*) realloc(sock->msgbuf.buf, len * sizeof(char))) == NULL)
return NO_MEMORY;
}
memcpy(sock->msgbuf.buf,String,len);
sock->msgbuf.used = len;
return 0;
}
/****************************************************************************/
int bufcat(buffer *s1, buffer *s2, int first, int len)
{
if (s1->used + len - first > s1->len)
{
s1->len = s1->used + len - first;
s1->buf = (char*) realloc(s1->buf, (s1->used + len - first) * sizeof(char));
if (s1->buf == NULL)
return NO_MEMORY;
}
memcpy((void*) (s1->buf + s1->used),(void*) (s2->buf + first), len);
s1->used += len;
return 0;
}
/****************************************************************************/
int initbuf(buffer *buf)
{
if (buf && buf->buf == NULL)
{
buf->buf = (char*) calloc(BUF_SIZE,sizeof(char));
buf->len = BUF_SIZE;
buf->used = 0;
}
return buf->buf?0:NO_MEMORY;
}
/****************************************************************************/
unsigned long stoi (unsigned char* s, int len)
{
unsigned long val = 0;
unsigned long Cnt = 0;
if (len > 4)
return 0;
while (Cnt < len)
val = (val << 8) + s[Cnt++];
return val;
}
/****************************************************************************/
char *itos (unsigned long val, int len)
{
static char s[16];
if (len > 4)
return NULL;
while(len-- > 0)
{
s[len] = (char) val % 256;
val = val >> 8;
}
return s;
}
/****************************************************************************/
int add_socket(socket_queue **sock, int new_socket)
{
int Cnt = 0;
if ((*sock) == NULL)
{
if (!((*sock) = (socket_queue*) calloc(2,sizeof(socket_queue))))
return NO_MEMORY;
(*sock)[0].descriptor = new_socket;
(*sock)[1].descriptor = NO_SOCKET;
}
else
{
Cnt = socket_size((*sock));
(*sock) = (socket_queue*) realloc((*sock),sizeof(socket_queue)*(Cnt+2));
memset(&((*sock)[Cnt+1]),0,sizeof(socket_queue));
(*sock)[Cnt+1].descriptor = NO_SOCKET;
(*sock)[Cnt].descriptor = new_socket;
}
if (init_socket(&((*sock)[Cnt])))
return NO_MEMORY;
return 0;
}
/****************************************************************************/
int del_socket(socket_queue **sock, int position)
{
int Cnt;
if (*sock == NULL)
return -1;
Cnt = socket_size((*sock));
if (position < 0 || position >= Cnt)
return -1;
free((*sock)[position].msgbuf.buf);
free((*sock)[position].restbuf.buf);
free((*sock)[position].f_hostname);
free((*sock)[position].f_username);
if (position == 0 && Cnt == 1)
{
free(*sock);
*sock = NULL;
return 0;
}
close((*sock)[position].descriptor);
memcpy(&((*sock)[position]),
&((*sock)[Cnt-1]),
sizeof(socket_queue));
memset(&((*sock)[Cnt-1]),0,sizeof(socket_queue));
(*sock)[Cnt-1].descriptor = NO_SOCKET;
(*sock) = (socket_queue*) realloc((*sock),sizeof(socket_queue)*Cnt);
return (*sock)?0:NO_MEMORY;
}
/****************************************************************************/
int socket_size(socket_queue *sock)
{
int Cnt = 0;
if (sock != NULL)
while(sock[Cnt].descriptor != NO_SOCKET)
Cnt++;
return Cnt;
}
/****************************************************************************/
int Set_Info_Struct(CALL **Info, char *String)
{
int Cnt = 0;
int channel;
char** Array = String_to_Array(String,C_DELIMITER);
while(Array[Cnt++]);
if (Cnt != 21)
{
del_Array(Array);
fprintf(stderr,"Internal error: wrong structure (%d elements)\n",Cnt);
return -1;
}
if (*Info == NULL)
if (((*Info) = (CALL*) calloc(1,sizeof(CALL))) == NULL)
return NO_MEMORY;
Cnt = 0;
channel = atoi(Array[Cnt++]);
(*Info)->stat = atoi(Array[Cnt++]);
(*Info)->dialin = atoi(Array[Cnt++]);
strcpy((*Info)->num[_ME((*Info))],Array[Cnt++]); /* Meine MSN */
strcpy((*Info)->alias[_ME((*Info))],Array[Cnt++]);
strcpy((*Info)->num[_OTHER((*Info))],Array[Cnt++]);
strcpy((*Info)->vorwahl[_OTHER((*Info))],Array[Cnt++]);
strcpy((*Info)->rufnummer[_OTHER((*Info))],Array[Cnt++]);
strcpy((*Info)->alias[_OTHER((*Info))],Array[Cnt++]);
strcpy((*Info)->area[_OTHER((*Info))],Array[Cnt++]);
(*Info)->connect = atoi(Array[Cnt++]);
(*Info)->t_duration = atoi(Array[Cnt++]);
(*Info)->aoce = atoi(Array[Cnt++]);
strcpy((*Info)->money,Array[Cnt++]);
strcpy((*Info)->currency,Array[Cnt++]);
(*Info)->ibytes = atoi(Array[Cnt++]);
(*Info)->obytes = atoi(Array[Cnt++]);
(*Info)->ibps = atof(Array[Cnt++]);
(*Info)->obps = atof(Array[Cnt++]);
strcpy((*Info)->msg,Array[Cnt++]);
del_Array(Array);
return channel;
}
/****************************************************************************/
char *GetHostByAddr(struct sockaddr *Addr)
{
char *RetCode = NULL;
char *Ptr;
struct hostent *hp = NULL;
struct in_addr *In = &((struct sockaddr_in*) Addr)->sin_addr;
if ((hp = gethostbyaddr((char*) In,sizeof(long int),AF_INET)) != NULL)
{
if ((RetCode = (char*) calloc(strlen(hp->h_name)+1,sizeof(char))) ==NULL)
return NULL;
strcpy(RetCode,hp->h_name);
}
else
if ((Ptr = inet_ntoa(*In)) != NULL)
{
if ((RetCode = (char*) calloc(strlen(Ptr)+1,sizeof(char))) ==NULL)
return NULL;
strcpy(RetCode,Ptr);
}
return RetCode;
}
/****************************************************************************/
char *GetHostByName(char *Name)
{
char *RetCode = NULL;
struct hostent *hp = NULL;
if ((hp = gethostbyname(Name)) != NULL)
{
if ((RetCode = (char*) calloc(strlen(hp->h_name)+1,sizeof(char))) ==NULL)
return NULL;
strcpy(RetCode,hp->h_name);
}
return RetCode;
}
/****************************************************************************/

214
isdnlog/connect/socket.h Normal file
View File

@ -0,0 +1,214 @@
/*
* ISDN accounting for isdn4linux.
*
* Copyright 1996 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.
*
*/
/****************************************************************************/
#ifndef __MY_SOCKET_H_
#define __MY_SOCKET_H_
/****************************************************************************/
#define PUBLIC extern
/****************************************************************************/
#include <tools.h>
/****************************************************************************/
#define SERV_ISDNLOG "isdnlog"
#define MAX_CLIENTS_LISTEN 5
#define PROT_VERSION "V0.2"
#ifndef SERV_PORT
# define SERV_PORT 20011
#endif
/****************************************************************************/
#define NO_NEXT_MSG 0
#define NEXT_MSG 1
/****************************************************************************/
#define NO_MSG 0
#define MSG_WHO_IS 1 /* Vom Server: String mit Nummer */
#define MSG_CALL_INFO 2 /* Vom Server: String mit Gebuehren-Info */
#define MSG_ANNOUNCE 3 /* Vom Client: Anmeldung beim Server mit User als String */
#define MSG_ANN_ACC 4 /* Vom Server: Mit Server-Typ z.B. T_ISDN4LINUX */
#define MSG_ANN_REJ 5 /* Vom Server: Ablehnung ohne weitere Info */
#define MSG_NEW_CALLER 6 /* Vom Client: String mit neuen Anrufer-Daten */
#define MSG_CALLER 7 /* Vom Server: String mit Anrufer-Daten */
#define MSG_TOPICS 8 /* Vom Server: Topics vom aktuellen Gespraech */
#define MSG_NOTICE 9 /* Vom Server: Uebermitteln von einer Notiz */
#define MSG_THRUPUT_INFO 10 /* Vom Server: Datendurchsatz */
#define MSG_CLOCK_INFO 11 /* Vom Server: Uhrzeit vom Amt */
#define MSG_SERVER 12 /* Vom Server: print_msg Meldungen */
#define MSG_CHANGE_CHAN 13 /* Vom Server: Kanal wurde gewechselt */
#define MSG_VERSION 14 /* Vom Server: Version des Protokolls: "PROT_VERSION" */
#define MSG_CLOSE 15 /* Die Verbindung wird beendet ohne Parameter, Dummy-Message */
/****************************************************************************/
#define _MSG_LEN 4
#define _MSG_MSG 2
#define _MSG_2B 2
/****************************************************************************/
#define WF_NOTHING 0 /* WF : Wait for */
#define WF_ACC 1
#define WF_CLOSE 2
/****************************************************************************/
/* Die folgenden Flags stehen im direkten Bezug zu user_access.c:ValidFlags */
#define T_NOTHING 0 /* Unterbau nicht vorhanden */
#define T_I4LCONF 1 /* Unterbau ist isdn4liunx und darf configuriert werden */
#define T_PROTOCOL 2 /* Meldungen vom S0 */
#define T_ADDRESSBOOK 4 /* Es soll das Adressbuch erlaubt werden. */
/* ACHTUNG: Die folgende muss immer Upgedatet werden */
#define T_ALL 6 /* Dieses ist die Summe aller gueltigen Flags. */
/****************************************************************************/
#define NO_SOCKET -2
#define NO_BIND -3
#define NO_LISTEN -4
#define NO_CONNECT -5
#define NO_MEMORY -6
/****************************************************************************/
#define C_DELIMITER '|'
/****************************************************************************/
typedef struct {
int len;
int used;
char *buf;
} buffer;
typedef struct _socket_queue{
int descriptor;
FILE *fp;
pid_t pid;
int chan;
info_args *info_arg;
int call_event;
int msg;
int status;
int waitstatus;
int servtyp;
int input_id;
char *f_hostname;
char *f_username;
int (*eval)(struct _socket_queue*);
buffer restbuf;
buffer msgbuf;
} socket_queue;
typedef struct {
char* Number;
char* Alias;
} PhoneNumber;
typedef struct {
char *Company;
char *Street;
char *Country;
char *PLZ;
char *City;
int NumTel;
PhoneNumber *Tel;
int NumFax;
PhoneNumber *Fax;
int NumEmail;
char **Email;
} Addresses;
typedef struct {
char *NName;
char *FName;
int NumAdr;
Addresses *Adr;
char* Birthday;
/*
time_t Birthday;
*/
} Address;
/****************************************************************************/
#ifdef _SOCKET_C_
#define _EXTERN
#else
#define _EXTERN extern
#endif
_EXTERN int Write(socket_queue* sock);
_EXTERN int Read(socket_queue* sock);
_EXTERN unsigned long stoi (unsigned char* s, int len);
_EXTERN char *itos (unsigned long val, int len);
_EXTERN int add_socket(socket_queue **sock,int new_socket);
_EXTERN int del_socket(socket_queue **sock,int position);
_EXTERN int socket_size(socket_queue *sock);
_EXTERN int msgcpy(socket_queue *sock, char *String, int len);
_EXTERN int init_socket(socket_queue *sock);
_EXTERN int Set_Info_Struct(CALL **Info, char *String);
_EXTERN char *GetHostByAddr(struct sockaddr *Addr);
_EXTERN char *GetHostByName(char *Name);
#undef _EXTERN
/****************************************************************************/
#ifdef _CONNECT_C_
#define _EXTERN
#else
#define _EXTERN extern
#endif
_EXTERN int client_connect(char *name, int port);
_EXTERN int server_connect(struct servent **sp, int port);
#undef _EXTERN
/****************************************************************************/
#ifdef _CONV_ADDRESS_C_
#define _EXTERN
#else
#define _EXTERN extern
#endif
_EXTERN Address* read_address(char* Ptr1);
_EXTERN char* write_address(Address *Ptr);
_EXTERN void free_Address(Address *APtr);
#undef _EXTERN
/****************************************************************************/
#endif /* __MY_SOCKET_H_*/

View File

@ -0,0 +1,11 @@
Diese Verzeichnis enthaelt 3 Files:
- LIESMICH.isdnbill > dieses File
- README.isdnbill > englische Version dieses Files
- isdnbill.tar.gz > einige Tcl/Tk scripts, um Einheiten eines Users anzuzeigen,
sowie einige bunte Buttons, wenn man die -i oder -S-- Option von ISDNLOG ohne
Sound verwenden will...
Die Scripts wurden mit ISDNLOG 2.30 getestet, Hinweise zur neuen Version 2.40
in der DOKU !
Doku (bis jetzt nur auf deutsch) als PostScript im isdnbill.tar.gz !

View File

@ -0,0 +1,7 @@
This dir contains 3 files:
- README.isdnbill > this file
- LIESMICH.isdnbill > german version of this file
- isdnbill.tar.gz > some Tcl/Tk scripts to display user's units and colourful
buttons, if you want to use the -i or -S-- option of ISDNLOG without sound...
Sorry, but there is no english version of the DOCU yet !

Binary file not shown.

View File

@ -0,0 +1,101 @@
Da sind sie endlich, die Skripte fuer den Versand von WinPopUp-Meldungen.
In die isdnlog.conf wird als allgemeines Event das START_Ring-Skript
eingetragen, dass bei eingehenden Anrufen einmal aufgerufen wird und mit
Send_WinPopup eine Meldung verschickt.
Ausserdem habe ich sowohl bei Connect als auch bei Hangup bei meinem
Provider ein Skripte eingetragen: ZDV_Connect und ZDV_Hangup. Diese
beiden senden ebenfalls mit Send_WinPopup einen Hinweis, dass die
ISDN-Leitung gerade auf- bzw. abgebaut wird. (Allerdings nur, wenn eine
Datei /etc/isdnlog/isdn.debug existiert, so kann man dies relativ leicht
an und abschalten.)
Das Hauptskript Send_WinPopup versendet mit smbclient die eigentlichen
Messages, in diesem Fall an die Rechner "mizar" und "alcor" (Das sollte
der TCP/IP-Name (aus dem Nameserver) der jeweiligen Rechner sein, oder
falls mit WINS gearbeitet wird, kann es auch der im Windows-Netzwerk
eingetragene Name sein, am Besten nimmt man an beiden Stellen den
gleichen Namen.)
Die Meldung im ersten Parameter wird an das Programm gepiped, da
smbclient sie normalerweise von der Tastatur einlesen wuerde. Ausserdem
kann man mit -U noch einen Absender angeben, den WinPopup anzeigt.
Auf den jeweiligen Rechnern muss WinPopup (3.11/95) oder der
Nachrichtendienst (NT) gestartet sein.
Als kleine Ergaenzung: Auch auf Linux-Rechnern kann man die WinPopups
empfangen, dann muss man allerdings im smb.conf die entsprechende Zeile
eintragen und ein Skript anlegen, was die Meldung irgendwie anzeigt oder
loggt.
Falls noch weiteres Interesse an der Konfiguration von Samba besteht,
kann ich auch gerne mal meine Konfig-Dateien posten.
Ich hoffe Ihr koennt was damit anfangen, die Skripte sind nicht gerade
elegant, aber ich hab sowas noch nicht oft gemacht.
Viel Spass,
-Michael
---- isdnlog.conf ----
MYMSNS=4
MYPREFIX=07472
START=IR=/etc/isdnlog/START_Ring $1 $2 $3;
MSN1 Telefon 1 -
MSN2 Telefax 1 -
MSN3,1 Michael 1 -
MSN4,7 Teles 1 -
PROVIDER ZDV_Internet 1 ippp0 OC=/etc/isdnlog/ZDV_Connect; OH=/etc/isdnlog/ZDV_Hangup;
---- START_Ring ---
#!/bin/sh
# Michael Ruder
#
# Version: 08.10.96
#
# /etc/isdnlog/START_Ring
#
/etc/isdnlog/Send_WinPopup 'Eingehender Anruf von '$2' auf '$3'.' &
# if test $3="IRGENDEINE_NUMMER"; then
# isdnctrl dial ippp0
# fi
---- Send_WinPopup ----
#!/bin/sh
# Michael Ruder
#
# Version: 08.10.96
#
# /etc/isdnlog/Send_WinPopup
#
echo $1 | smbclient -M mizar -U ISDN-Administrator >/dev/null
echo $1 | smbclient -M alcor -U ISDN-Administrator >/dev/null
---- ZDV_Connect ----
#!/bin/sh
# Michael Ruder
#
# Version: 08.10.96
#
# /etc/isdnlog/ZDV_Connect
#
if test -e "/etc/isdnlog/isdn.debug"; then
/etc/isdnlog/Send_WinPopup 'Die ISDN-Leitung wird aufgebaut.' &
fi
---- Auschnitt aus smb.conf ----
[global]
message command = mv %s %s.working; echo WinPopup-Message from %f@%m for %t: > %s; cat %s.working >> %s; wall %s; rm %s %s.working &
-Michael
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
< Michael Ruder, Fax +49-7472-91382, email: Michael.Ruder@Uni-Tuebingen.DE >
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/

589
isdnlog/isdnconf/isdnconf.c Normal file
View File

@ -0,0 +1,589 @@
/*
Der SI muss auch als Eingabe (mit Hex) erlaubt sein
MSNxx -> MSN
*/
/* $Id: isdnconf.c,v 1.1 1997/03/16 20:58:33 luethje Exp $
*
* ISDN accounting for isdn4linux. (Report-module)
*
* Copyright 1996, 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.
*
*/
#include "isdnconf.h"
/*****************************************************************************/
int print_in_modules(const char *fmt, ...);
int print_msg(int Level, const char *fmt, ...);
int add_data(section **conf_dat);
int delete_data(char *, char *, section **conf_dat);
int look_data(section **conf_dat);
int find_data(char *_alias, char *_number, section *conf_dat);
const char* make_word(const char *in);
char* tmp_dup(const char *in);
int add_line(section **Ptr, const char *Name);
/*****************************************************************************/
static int and = 0;
static int add = 0;
static int del = 0;
static int msn = 0;
static int quiet = 0;
static int short_out= 0;
static int long_out= 0;
static int match_flags = F_NO_HOLE_WORD;
static char areacode[SHORT_STRING_SIZE] = "";
static char si[SHORT_STRING_SIZE];
static char number[BUFSIZ] = "";
static char alias[BUFSIZ] = "";
static char conffile[BUFSIZ];
/*****************************************************************************/
int add_line(section **Ptr, const char *Name)
{
char buf[BUFSIZ] = "";
if (fgets(buf,BUFSIZ,stdin) != NULL)
{
if (strlen(buf) > 1)
{
buf[strlen(buf)-1] = '\0';
if (Set_Entry(*Ptr,NULL,tmp_dup(Name),buf,C_WARN) == NULL)
{
print_msg(PRT_ERR,"%s\n","Can not allocate memory!");
return -1;
}
}
}
else
{
free_section(*Ptr);
*Ptr = NULL;
return -1;
}
return 0;
}
/*****************************************************************************/
int add_data(section **conf_dat)
{
int Cnt = 0;
section *NewPtr = NULL;
section *SubPtr = NULL;
while(1)
{
NewPtr = NULL;
if (Set_Section(&NewPtr,tmp_dup(msn?CONF_SEC_MSN:CONF_SEC_NUM),C_NOT_UNIQUE) == NULL)
{
print_msg(PRT_ERR,"%s\n","Can not allocate memory!");
return -1;
}
if (!quiet)
print_msg(PRT_NORMAL,"%s:\t\t",make_word(CONF_ENT_ALIAS));
if (add_line(&NewPtr,CONF_ENT_ALIAS))
break;
if (!quiet)
print_msg(PRT_NORMAL,"%s:\t\t",make_word(CONF_ENT_NUM));
if (add_line(&NewPtr,CONF_ENT_NUM))
break;
if (!quiet)
print_msg(PRT_NORMAL,"%s:\t\t",CONF_ENT_SI);
if (add_line(&NewPtr,CONF_ENT_SI))
break;
if (!quiet)
print_msg(PRT_NORMAL,"%s:\t\t",make_word(CONF_ENT_ZONE));
if (add_line(&NewPtr,CONF_ENT_ZONE))
break;
if (!quiet)
print_msg(PRT_NORMAL,"%s:\t",make_word(CONF_ENT_INTFAC));
if (add_line(&NewPtr,CONF_ENT_INTFAC))
break;
while(1)
{
SubPtr = NULL;
if (Set_Section(&SubPtr,tmp_dup(CONF_SEC_FLAG),C_NOT_UNIQUE) == NULL)
{
print_msg(PRT_ERR,"%s\n","Can not allocate memory!");
return -1;
}
if (!quiet)
print_msg(PRT_NORMAL,"%s:\t\t",make_word(CONF_ENT_FLAGS));
if (add_line(&SubPtr,CONF_ENT_FLAGS))
break;
if (!quiet)
print_msg(PRT_NORMAL,"%s:\t",make_word(CONF_ENT_PROG));
if (add_line(&SubPtr,CONF_ENT_PROG))
break;
if (!quiet)
print_msg(PRT_NORMAL,"%s:\t\t",make_word(CONF_ENT_USER));
if (add_line(&SubPtr,CONF_ENT_USER))
break;
if (!quiet)
print_msg(PRT_NORMAL,"%s:\t\t",make_word(CONF_ENT_GROUP));
if (add_line(&SubPtr,CONF_ENT_GROUP))
break;
if (!quiet)
print_msg(PRT_NORMAL,"%s:\t",make_word(CONF_ENT_INTVAL));
if (add_line(&SubPtr,CONF_ENT_INTVAL))
break;
if (!quiet)
print_msg(PRT_NORMAL,"%s:\t\t",make_word(CONF_ENT_TIME));
if (add_line(&SubPtr,CONF_ENT_TIME))
break;
Set_SubSection(NewPtr,tmp_dup(CONF_ENT_START),SubPtr,C_APPEND | C_WARN);
}
if (!quiet)
print_msg(PRT_NORMAL,"\n\n");
while(*conf_dat != NULL)
conf_dat = &((*conf_dat)->next);
*conf_dat = NewPtr;
Cnt++;
}
if (!quiet)
print_msg(PRT_NORMAL,"\n");
return Cnt;
}
/*****************************************************************************/
int delete_data(char * _alias , char * _number, section **conf_dat)
{
short_out = 1;
if (!quiet)
print_msg(PRT_NORMAL,"Following entry deleted!\n");
if (!quiet)
find_data(_alias,_number,*conf_dat);
Del_Section(conf_dat,NULL);
return 0;
}
/*****************************************************************************/
int find_data(char *_alias, char *_number, section *conf_dat)
{
auto char *ptr;
auto entry *CEPtr;
auto section *SPtr;
if (quiet)
{
print_msg(PRT_NORMAL,"%s",_alias?_alias:(number[0]?expand_number(number):alias));
}
else
{
print_msg(PRT_NORMAL,"%s:\t\t%s\n",make_word(CONF_ENT_ALIAS),_alias?_alias:S_UNKNOWN);
print_msg(PRT_NORMAL,"%s:\t\t%s\n",make_word(CONF_ENT_NUM),_number?_number:S_UNKNOWN);
if (_number != NULL && (ptr = get_areacode(_number,NULL,C_NO_ERROR)) != NULL)
print_msg(PRT_NORMAL,"Location:\t%s\n",ptr);
if (!short_out)
{
ptr = (CEPtr = Get_Entry(conf_dat->entries,CONF_ENT_SI))?(CEPtr->value?CEPtr->value:"0"):"0";
print_msg(PRT_NORMAL,"%s:\t\t%s\n",CONF_ENT_SI,ptr);
ptr = (CEPtr = Get_Entry(conf_dat->entries,CONF_ENT_ZONE))?(CEPtr->value?CEPtr->value:""):"";
print_msg(PRT_NORMAL,"%s:\t\t%s\n",make_word(CONF_ENT_ZONE),ptr);
ptr = (CEPtr = Get_Entry(conf_dat->entries,CONF_ENT_INTFAC))?(CEPtr->value?CEPtr->value:""):"";
print_msg(PRT_NORMAL,"%s:\t%s\n",make_word(CONF_ENT_INTFAC),ptr);
}
if (long_out)
{
SPtr = Get_SubSection(conf_dat,CONF_ENT_START);
while (SPtr != NULL)
{
ptr = (CEPtr = Get_Entry(SPtr->entries,CONF_ENT_FLAGS))?(CEPtr->value?CEPtr->value:""):"";
print_msg(PRT_NORMAL,"%s:\t\t%s\n",make_word(CONF_ENT_FLAGS),ptr);
ptr = (CEPtr = Get_Entry(SPtr->entries,CONF_ENT_PROG))?(CEPtr->value?CEPtr->value:""):"";
print_msg(PRT_NORMAL,"%s:\t%s\n",make_word(CONF_ENT_PROG),ptr);
ptr = (CEPtr = Get_Entry(SPtr->entries,CONF_ENT_USER))?(CEPtr->value?CEPtr->value:""):"";
print_msg(PRT_NORMAL,"%s:\t%s\n",make_word(CONF_ENT_USER),ptr);
ptr = (CEPtr = Get_Entry(SPtr->entries,CONF_ENT_GROUP))?(CEPtr->value?CEPtr->value:""):"";
print_msg(PRT_NORMAL,"%s:\t%s\n",make_word(CONF_ENT_GROUP),ptr);
ptr = (CEPtr = Get_Entry(SPtr->entries,CONF_ENT_INTVAL))?(CEPtr->value?CEPtr->value:""):"";
print_msg(PRT_NORMAL,"%s:\t%s\n",make_word(CONF_ENT_INTVAL),ptr);
ptr = (CEPtr = Get_Entry(SPtr->entries,CONF_ENT_TIME))?(CEPtr->value?CEPtr->value:""):"";
print_msg(PRT_NORMAL,"%s:\t\t%s\n",make_word(CONF_ENT_TIME),ptr);
SPtr = SPtr->next;
}
}
}
print_msg(PRT_NORMAL,"\n");
return 0;
}
/*****************************************************************************/
int look_data(section **conf_dat)
{
int Cnt = 0;
auto entry *CEPtr;
char *_number = NULL, *_alias;
char _si[SHORT_STRING_SIZE];
section *old_conf_dat = NULL;
while (*conf_dat != NULL)
{
old_conf_dat = *conf_dat;
if (!strcmp((*conf_dat)->name,CONF_SEC_NUM) || !strcmp((*conf_dat)->name,CONF_SEC_MSN))
{
int Ret = 0;
_number = _alias = NULL;
_si[0] = '\0';
if ((CEPtr = Get_Entry((*conf_dat)->entries,CONF_ENT_NUM)) != NULL)
_number = CEPtr->value;
if ((CEPtr = Get_Entry((*conf_dat)->entries,CONF_ENT_ALIAS)) != NULL)
_alias = CEPtr->value;
if ((CEPtr = Get_Entry((*conf_dat)->entries,CONF_ENT_SI)) != NULL &&
CEPtr->value != NULL)
sprintf(_si,"%ld",strtol(CEPtr->value, NIL, 0));
if (and)
Ret = 1;
else
Ret = 0;
if (number[0] && _number != NULL)
{
if (!num_match(_number,number))
Ret = 1;
else
Ret = 0;
}
if (alias[0] && _alias != NULL)
{
int Ret2 = 0;
if (!match(alias,_alias,match_flags))
Ret2 = 1;
if (and)
Ret &= Ret2;
else
Ret |= Ret2;
}
if (si[0])
{
int Ret2 = 0;
if (!strcmp(_si,si))
Ret2 = 1;
if (and)
Ret &= Ret2;
else
Ret |= Ret2;
}
if (Ret == 1)
{
if (del)
{
delete_data(_alias,_number,conf_dat);
Cnt++;
}
else
{
find_data(_alias,_number,*conf_dat);
Cnt++;
}
}
}
if (*conf_dat != NULL && old_conf_dat == *conf_dat)
conf_dat = &((*conf_dat)->next);
}
if (Cnt == 0 && quiet && !del)
find_data(NULL,_number,*conf_dat);
return Cnt;
}
/*****************************************************************************/
char* tmp_dup(const char *in)
{
static char out[SHORT_STRING_SIZE];
strcpy(out,in);
return out;
}
/*****************************************************************************/
const char* make_word(const char *in)
{
int i = 0;
static char out[SHORT_STRING_SIZE];
out[0] ='\0';
while(in[i] != '\0')
out[i] = tolower(in[i]),i++;
out[i] ='\0';
out[0] = toupper(out[0]);
return out;
}
/*****************************************************************************/
int print_msg(int Level, const char *fmt, ...)
{
auto va_list ap;
auto char String[LONG_STRING_SIZE];
va_start(ap, fmt);
vsnprintf(String, LONG_STRING_SIZE, fmt, ap);
va_end(ap);
if (Level & PRT_ERR)
fprintf(stderr, "%s", String);
else
fprintf(stdout, "%s", String);
return 0;
}
/*****************************************************************************/
int print_in_modules(const char *fmt, ...)
{
auto va_list ap;
auto char String[LONG_STRING_SIZE];
va_start(ap, fmt);
(void)vsnprintf(String, LONG_STRING_SIZE, fmt, ap);
va_end(ap);
return print_msg(PRT_ERR, "%s", String);
}
/*****************************************************************************/
int main(int argc, char *argv[], char *envp[])
{
int c;
int Cnt = 0;
section *conf_dat = NULL;
char *myname = basename(argv[0]);
static char usage[] = "%s: usage: %s [ -%s ]\n";
static char options[] = "ADdn:a:t:f:c:wslimqV";
set_print_fct_for_tools(print_in_modules);
alias[0] = '\0';
number[0] = '\0';
sprintf(conffile,"%s%c%s",confdir(),C_SLASH,CONFFILE);
while ((c = getopt(argc, argv, options)) != EOF)
switch (c) {
case 'A' : add++;
break;
case 'D' : del++;
break;
case 'V' : print_version(myname);
exit(0);
case 'd' : and++;
break;
case 'm' : msn++;
break;
case 'i' : match_flags |= F_IGNORE_CASE;
break;
case 'n' : strcpy(number, optarg);
break;
case 'a' : strcpy(alias, optarg);
break;
case 't' : sprintf(si,"%ld",strtol(optarg, NIL, 0));
break;
case 's' : short_out++;
break;
case 'l' : long_out++;
break;
case 'w' : match_flags &= ~F_NO_HOLE_WORD;
break;
case 'q' : quiet++;
break;
case 'f' : strcpy(conffile, optarg);
break;
case 'c' : strcpy(areacode, optarg);
break;
case '?' : print_msg(PRT_ERR, usage, myname, myname, options);
return(1);
}
if (add || del)
{
if ((conf_dat = read_file(NULL, conffile, C_NOT_UNIQUE)) == NULL)
exit(2);
if (Set_Codes(conf_dat) != 0)
{
print_msg(PRT_ERR,"Error: Variables `%s' and `%s' are not set!\n",CONF_ENT_AREA,CONF_ENT_COUNTRY);
exit(5);
}
}
else
{
if (read_isdnconf(&conf_dat) == NULL)
exit(2);
}
if (number[0] != '\0')
strcpy(number, expand_number(number));
if (areacode[0] != '\0')
{
char *ptr;
if ((ptr = get_areacode(areacode,NULL,0)) != NULL)
{
print_msg(PRT_NORMAL,"%s\n",ptr);
exit(0);
}
else
exit(3);
}
if (optind < argc && !add)
{
if (!alias[0] && optind + 1 == argc)
strcpy(alias, argv[optind]);
else
{
print_msg(PRT_ERR,"Can not set two strings for alias!\n");
exit(3);
}
}
if (!add)
{
if (!alias[0] && !number[0] && !si[0])
{
print_msg(PRT_ERR, usage, argv[0], argv[0], options);
exit(4);
}
}
else
{
if (alias[0] || number[0] || si[0])
{
print_msg(PRT_ERR, usage, argv[0], argv[0], options);
exit(5);
}
}
if (add && del)
{
print_msg(PRT_ERR,"Can not do add and delete together!\n");
exit(1);
}
if (short_out && long_out)
{
print_msg(PRT_ERR,"Can not do long and short output together!\n");
exit(1);
}
if (add)
Cnt = add_data(&conf_dat);
else
Cnt = look_data(&conf_dat);
if ((add || del) && Cnt > 0)
if (write_file(conf_dat,conffile,myname,VERSION) == NULL)
exit(5);
free_section(conf_dat);
return 0;
}

View File

@ -0,0 +1,40 @@
/* $Id: isdnconf.h,v 1.1 1997/03/16 20:58:34 luethje Exp $
*
* ISDN accounting for isdn4linux.
*
* Copyright 1995, 1996 by Andreas Kool (akool@Kool.f.EUnet.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.
*
*/
#ifndef _ISDN_CONF_H_
#define _ISDN_CONF_H_
#define PRT_ERR 1
#define PRT_NORMAL 4
#define PUBLIC extern
#include "tools.h"
#ifdef _ISDN_CONF_C_
#define _EXTERN
#else
#define _EXTERN extern
#endif
#undef _EXTERN
#endif /* _ISDN_CONF_H_ */

313
isdnlog/isdnlog/functions.c Normal file
View File

@ -0,0 +1,313 @@
/* $Id: functions.c,v 1.1 1997/03/16 20:58:39 luethje Exp $
*
* ISDN accounting for isdn4linux. (log-module)
*
* Copyright 1995, 1997 by Andreas Kool (akool@Kool.f.EUnet.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
*/
#define _FUNCTIONS_C_
#include "isdnlog.h"
#ifdef POSTGRES
#include "postgres.h"
#endif
/*****************************************************************************/
static void saveCharge()
{
register int i;
auto FILE *f;
auto char fn[BUFSIZ], fno[BUFSIZ];
sprintf(fn, "%s/%s", confdir(), CHARGEFILE);
sprintf(fno, "%s.old", fn);
(void)rename(fn, fno);
if ((f = fopen(fn, "w")) != (FILE *)NULL) {
for (i = 0; i < knowns; i++)
if (known[i]->day > -1)
fprintf(f, "%s %d %g %g %d %g %g %g %g\n", known[i]->who,
known[i]->day, known[i]->charge, known[i]->scharge,
known[i]->month, known[i]->online, known[i]->sonline,
known[i]->bytes, known[i]->sbytes);
fclose(f);
} /* if */
} /* saveCharge */
/*****************************************************************************/
void _Exit(char *File, int Line, int RetCode) /* WARNING: RetCode==-9 does _not_ call exit()! */
{
#ifdef Q931
if (!q931dmp)
#endif
#ifdef DEBUG
print_msg(PRT_NORMAL, "exit now %d in module `%s' at line %d!\n", RetCode, File, Line);
#else
print_msg(PRT_NORMAL, "exit now %d\n", RetCode);
#endif
if (socket_size(sockets) >= 2) {
close(sockets[ISDNCTRL].descriptor);
close(sockets[ISDNINFO].descriptor);
if (xinfo && sockets[IN_PORT].descriptor != -2)
close(sockets[IN_PORT].descriptor);
} /* if */
closelog();
#ifdef POSTGRES
dbClose();
#endif
if (!replay) {
saveCharge();
delete_runfile(pidfile);
} /* if */
if (RetCode != -9)
exit(RetCode);
} /* Exit */
/*****************************************************************************/
int Change_Channel(int old_channel, int new_channel)
{
change_channel(old_channel,new_channel);
Change_Channel_Ring(old_channel,new_channel);
return 0;
}
/*****************************************************************************/
void now(void)
{
auto struct tms tms;
time(&cur_time);
tto = tt;
tt = times(&tms);
set_time_str();
} /* now */
/*****************************************************************************/
void set_time_str(void)
{
auto struct tm *tm_time = localtime(&cur_time);
tm_time->tm_isdst = 0;
strftime(stl, 64, "%a %b %d %X %Y", tm_time);
strftime(st, 64, "%a %b %d %X", tm_time);
strftime(idate, 256, "%a%b%d%T", tm_time);
fullhour = (!tm_time->tm_min && (tm_time->tm_sec <= (wakeup + 2)));
day = tm_time->tm_mday;
month = tm_time->tm_mon + 1;
} /* set_time_str */
/*****************************************************************************/
void logger(int chan)
{
auto int tries, fd;
register char *p;
auto char s[BUFSIZ];
#ifdef POSTGRES
auto DbStrIn db_set;
#endif
strcpy(s, ctime(&call[chan].connect));
if ((p = strchr(s, '\n')))
*p = 0;
/*
.aoce :: -1 -> keine aOC Meldung von VSt, muss berechnet werden
0 -> free of Charge (0130/...)
>0 -> #of Units
*/
if (!call[chan].aoc) {
if (!call[chan].dialin)
call[chan].aoce = -1;
call[chan].pay = 0.0;
} /* if */
tries = 0;
while (((fd = open(logname, O_WRONLY | O_APPEND | O_EXCL)) == -1) && (tries < 1000))
tries++;
if ((tries < 1000) && ((flog = fdopen(fd, "a")) == (FILE *)NULL))
print_msg(PRT_ERR, "Can not open file `%s': %s!\n", logname, strerror(errno));
else {
fprintf(flog, "%s|%-16s|%-16s|%5d|%10d|%10d|%5d|%c|%3d|%10ld|%10ld|%d.%d|%d|%d|%g|%s|%8.2f|\n",
s + 4, call[chan].num[CALLING], call[chan].num[CALLED],
(int)(call[chan].disconnect - call[chan].connect),
(int)call[chan].duration, (int)call[chan].connect,
call[chan].aoce, call[chan].dialin ? 'I' : 'O',
call[chan].cause, call[chan].ibytes, call[chan].obytes,
LOG_MAJOR_VERSION, LOG_MINOR_VERSION, call[chan].si1, call[chan].si11,
currency_factor, currency, call[chan].pay);
fclose(flog);
} /* else */
#ifdef POSTGRES
db_set.connect = call[chan].connect;
strcpy(db_set.calling, call[chan].num[CALLING]);
strcpy(db_set.called, call[chan].num[CALLED]);
db_set.duration = (int)(call[chan].disconnect - call[chan].connect);
db_set.hduration = (int)call[chan].duration;
db_set.aoce = call[chan].aoce;
db_set.dialin = call[chan].dialin ? 'I' : 'O';
db_set.cause = call[chan].cause;
db_set.ibytes = call[chan].ibytes;
db_set.obytes = call[chan].obytes;
db_set.version = LOG_MAJOR_VERSION * 100 + LOG_MINOR_VERSION;
db_set.si1 = call[chan].si1;
db_set.si11 = call[chan].si11;
db_set.currency_factor = currency_factor;
strcpy(db_set.currency, currency);
dbAdd(&db_set);
#endif
} /* logger */
/*****************************************************************************/
int print_msg(int Level, const char *fmt, ...)
{
/* ACHTUNG IN DIESER FKT DARF KEIN print_msg() AUFGERUFEN WERDEN !!!!! */
auto int SLevel = PRT_NOTHING, l;
auto char String[LONG_STRING_SIZE], s[LONG_STRING_SIZE];
auto va_list ap;
va_start(ap, fmt);
l = vsnprintf(String, LONG_STRING_SIZE, fmt, ap);
va_end(ap);
if (width) {
memcpy(s, String, l + 1);
if (l > width) {
if (s[l - 1] < ' ') {
s[width] = s[l - 1];
s[width + 1] = 0;
}
else
s[width] = 0;
} /* if */
} /* if */
SLevel = IS_DEBUG(Level) ? LOG_DEBUG : LOG_INFO;
if (Level & syslogmessage)
syslog(SLevel, "%s", String);
if (Level & stdoutput) {
(void)fputs(width ? s : String, stdout);
fflush(stdout);
} /* if */
if (Level & message)
if (fcons == NULL) {
fputs(width ? s : String, stderr);
fflush(stderr);
}
else {
fputs(width ? s : String, fcons);
fflush(fcons);
} /* else */
if (Level & xinfo)
print_from_server(String);
if (Level & PRT_LOG) {
fprintf(fprot, "%s %s", stl, String);
if (synclog)
fflush(fprot);
} /* if */
return(0);
} /* print_msg */
/*****************************************************************************/
int ringer(int chan, int event)
{
register int i, j, c;
int ProcessStarted = 0;
int old_c = -1;
info_args *infoarg = NULL;
print_msg(PRT_DEBUG_EXEC, "Got ring event %d on channel %d, number of sockets: %d\n", event, chan, socket_size(sockets));
/* chan; Der jeweilige B-Kanal (0 oder 1)
event:
RING_RING = Nummern wurden uebertragen
RING_CONNECT = Hoerer abgenommen
RING_HANGUP = Hoerer aufgelegt
RING_AOCD = Gebuehrenimpuls (wird noch nicht verwendet)
*/
if (event != RING_HANGUP)
{
if (event == RING_RING || event == RING_CONNECT)
call[chan].cur_event = event;
}
else
call[chan].cur_event = 0;
for (i = CALLING; i <= CALLED; i++) { /* fuer beide beteilige Telefonnummern */
c = call[chan].confentry[i];
if (c != -1 && c != old_c) { /* wenn Eintrag in isdnlog.conf gefunden */
old_c = c;
for (j = 0;known[c]->infoargs != NULL && (infoarg = known[c]->infoargs[j]) != NULL;j++)
ProcessStarted += Start_Ring(chan,infoarg,event,0);
}
}
if (ProcessStarted == 0)
{
for (j = 0;start_procs.infoargs != NULL && (infoarg = start_procs.infoargs[j]) != NULL;j++)
ProcessStarted += Start_Ring(chan,infoarg,event,0);
}
return ProcessStarted;
} /* ringer */
/*****************************************************************************/

75
isdnlog/isdnlog/isdnlog.8 Normal file
View File

@ -0,0 +1,75 @@
.TH ISDNLOG 8 "ISDN Utilities" "AKsoftware" \" -*- nroff -*-
.SH NAME
isdnlog \- Auswertung des ISDN D-Kanal Protokolls
.SH SYNOPSIS
.B isdnlog
[\-asrSVTDPMnNbF2] [\-v verbose-level] [\-p Port] [\-x X-Meldungen]
[\-m stderr-Meldungen] [\-l syslog-Meldungen] [\-t Clock stellen]
[\-c X-Buffer-Size] [\-C Device] [\-w Poll-Rate] [\-h Chargeint-Offset]
[\-W Columns] [\-H Einheiten] [\-f Conffile] [\-L X-Buffer-Size]
[\-A Amtsholung]
/dev/isdnctrlX | -
.SH DESCRIPTION
.BR isdnlog
ermoeglicht in Zusammenhang mit isdn4linux eine vollstaendige
Dekodierung des D-Kanal-Protokolls eines ISDN-Anschlusses.
Neben einem Protokoll aller Verbindungen kann
.B isdnlog
bei beliebigen Events (Verbindung entstanden, Verbindung beendet usw.)
Aktionen starten.
Fuer weitere Informationen siehe README
.SS OPTIONS
.TP
.I "\-V"
.B isdnlog
Print version information on standard output then exit successfully.
.SS MELDUNGEN
Bei den Optionen
.I "\-m",
.I "\-l"
oder
.I "\-x"
kann jeweils eine beliebige Kombination aus folgenden Meldungstypen
angegeben werden:
.RE
.sp
.RS +.2i
.ta 1.0i
.nf
1 PRT_ERR
2 PRT_WARN
4 PRT_INFO
4 PRT_PROG_OUT
4 PRT_NORMAL
8 PRT_LOG
0x10 PRT_SHOWNUMBERS
0x20 PRT_SHOWAOCD
0x40 PRT_SHOWCONNECT
0x80 PRT_SHOWHANGUP
0x100 PRT_SHOWCAUSE
0x200 PRT_SHOWTIME
0x400 PRT_SHOWBYTE
0x800 PRT_SHOWIMON
0x1000 PRT_SHOWBEARER
0x2000 PRT_SHOWTICKS
0x4000 PRT_DEBUG_GENERAL
0x8000 PRT_DEBUG_DIAG
0x10000 PRT_DEBUG_INFO
0x20000 PRT_DEBUG_EXEC
0x40000 PRT_DEBUG_BUGS
0x80000 PRT_DEBUG_DECODE
0x100000 PRT_DEBUG_RING
0x200000 PRT_DEBUG_CS
0x400000 PRT_DEBUG_PROT
0x800000 PRT_NOTHING
.fi
.RE
.sp
.SH FILES
.BR isdnlog
benoetigt zwingend die Konfigurationsdatei
.BR /etc/isdnlog/isdn.conf
.SH BUGS
Z.Zt. keine bekannt ;-)

888
isdnlog/isdnlog/isdnlog.c Normal file
View File

@ -0,0 +1,888 @@
/* $Id: isdnlog.c,v 1.1 1997/03/16 20:58:41 luethje Exp $
*
* ISDN accounting for isdn4linux. (log-module)
*
* Copyright 1995, 1997 by Andreas Kool (akool@Kool.f.EUnet.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
*/
#define _ISDNLOG_C_
#include "isdnlog.h"
#ifdef POSTGRES
#include "postgres.h"
#endif
/*****************************************************************************/
/* Letzte Exit-Nummer: 42 */
/*****************************************************************************/
static void loop(void);
static void init_variables(int argc, char* argv[]);
static int set_options(int argc, char* argv[]);
static void hup_handler(int isig);
static void exit_on_signal(int Sign);
int print_in_modules(const char *fmt, ...);
static int read_param_file(char *FileName);
/*****************************************************************************/
static char usage[] = "%s: usage: %s [ -%s ] file\n";
#ifdef Q931
static char options[] = "av:sp:x:m:l:rt:c:C:w:SVTDPMh:nW:H:f:bL:NqFA:2:";
#else
static char options[] = "av:sp:x:m:l:rt:c:C:w:SVTDPMh:nW:H:f:bL:NFA:2:";
#endif
static char msg1[] = "%s: Can't open %s (%s)\n";
static char *ptty = NULL;
static section *opt_dat = NULL;
/*****************************************************************************/
static void exit_on_signal(int Sign)
{
print_msg(PRT_NORMAL, "Got signal %d\n", Sign);
Exit(7);
} /* exit_on_signal */
/*****************************************************************************/
static void hup_handler(int isig)
{
print_msg(PRT_INFO, "re-reading %s\n", CONFFILE);
discardconfig();
if (readconfig(myname) != 0)
Exit(41);
signal(SIGHUP, hup_handler);
} /* hup_handler */
/*****************************************************************************/
static void loop(void)
{
auto fd_set readmask;
auto fd_set exceptmask;
auto int Cnt;
auto int len;
auto int queuenumber;
auto int NewSocket;
auto int NewClient = 0;
auto struct sockaddr incoming;
auto int Interval;
if (xinfo) {
first_descr++;
if ((NewSocket = listening(port)) >= 0) {
if (add_socket(&sockets, NewSocket))
Exit(11);
}
else
Exit(17);
}
else
if (add_socket(&sockets, -1))
Exit(11);
while (1) {
if (replay) {
if (trace)
dotrace();
if (!morectrl(0))
break;
}
else {
FD_ZERO(&readmask);
FD_ZERO(&exceptmask);
queuenumber = socket_size(sockets);
if (NewClient) {
/* Damit sich der neue Client anmelden kann, ohne
das was anderes dazwischen funkt ... */
FD_SET(sockets[NewClient].descriptor, &readmask);
NewClient = 0;
}
else {
for (Cnt = 0; Cnt < queuenumber; Cnt++)
FD_SET(sockets[Cnt].descriptor, &readmask);
for (Cnt = first_descr; Cnt < queuenumber; Cnt++)
FD_SET(sockets[Cnt].descriptor, &exceptmask);
} /* else */
if (newcps && ((ifo[0].u & ISDN_USAGE_MASK) + (ifo[1].u & ISDN_USAGE_MASK)))
Interval = wakeup; /* AK:06-Jun-96 */
else
Interval = 0;
while ((Cnt = select(FD_SETSIZE, &readmask, NULL, &exceptmask, Get_Interval(Interval))) < 0 && (errno == EINTR));
if ((Cnt < 0) && (errno != EINTR)) { /* kill -HUP ausgeschlossen */
print_msg(PRT_DEBUG_CS, "Error select: %s\n", strerror(errno));
Exit(12);
} /* if */
processrate();
if (!Cnt) /* Abbruch durch Timeout -> Programm starten */
Start_Interval();
now();
for (Cnt = first_descr; Cnt < socket_size(sockets); Cnt++) {
if (FD_ISSET(sockets[Cnt].descriptor, &exceptmask)) {
if (sockets[Cnt].fp == NULL) {
disconnect_client(Cnt);
break;
}
else {
int event = sockets[Cnt].call_event;
int cur_call = sockets[Cnt].chan;
info_args *infoarg = sockets[Cnt].info_arg;
Ring(NULL, NULL, Cnt, 0);
if (infoarg->flag & RING_LOOP && call[cur_call].cur_event == event)
Start_Process(cur_call, infoarg, event);
break;
} /* else */
}
else if (FD_ISSET(sockets[Cnt].descriptor, &readmask))
if (sockets[Cnt].fp == NULL) {
eval_message(Cnt);
/* Arbeite immer nur ein Client ab, du weisst nicht, ob der
naechste noch lebt */
break;
}
else
Print_Cmd_Output(Cnt);
} /* for */
if (xinfo && FD_ISSET(sockets[IN_PORT].descriptor, &readmask)) {
len = sizeof(incoming);
if ((NewSocket = accept(sockets[IN_PORT].descriptor, &incoming, &len)) == -1)
print_msg(PRT_DEBUG_CS, "Error accept: %s\n", strerror(errno));
else {
if (add_socket(&sockets, NewSocket))
Exit(13);
queuenumber = socket_size(sockets);
sockets[queuenumber - 1].f_hostname = GetHostByAddr(&incoming);
sockets[queuenumber - 1].waitstatus = WF_ACC;
NewClient = queuenumber - 1;
} /* else */
}
else if (FD_ISSET(sockets[ISDNINFO].descriptor, &readmask))
moreinfo();
else if (FD_ISSET(sockets[ISDNCTRL].descriptor, &readmask))
(void)morectrl(0);
else if (FD_ISSET(sockets[ISDNCTRL2].descriptor, &readmask))
(void)morectrl(1);
} /* else */
} /* while */
} /* loop */
/*****************************************************************************/
int print_in_modules(const char *fmt, ...)
{
auto va_list ap;
auto char String[LONG_STRING_SIZE];
va_start(ap, fmt);
(void)vsnprintf(String, LONG_STRING_SIZE, fmt, ap);
va_end(ap);
return print_msg(PRT_ERR, "%s", String);
} /* print_in_modules */
/*****************************************************************************/
static void init_variables(int argc, char* argv[])
{
flog = NULL; /* /var/adm/isdn.log */
fcons = NULL; /* /dev/ttyX (or stderr) */
fprot = NULL; /* /tmp/isdnctrl0 */
isdnctrl = NULL;
first_descr = FIRST_DESCR;
message = PRT_NORMAL | PRT_WARN | PRT_ERR | PRT_INFO;
syslogmessage = PRT_NOTHING;
xinfo = 0;
sound = 0;
trace = 0;
isdaemon = 0;
imon = 0;
port = 0;
wakeup = 1;
fullhour = 0;
tty_dv = 0;
net_dv = 0;
inf_dv = 0;
settime = 0;
replay = 0;
replaydev = 0;
verbose = 0;
synclog = 0;
any = 1;
stdoutput = 0;
allflags = 0;
newcps = 0;
chans = 2;
hupctrl = 0;
hup1 = hup2 = 0;
bilingual = 0;
mcalls = MAX_CALLS_IN_QUEUE;
xlog = MAX_PRINTS_IN_QUEUE;
sockets = NULL;
allflags = 0;
known = NULL;
opt_dat = NULL;
newline = 1;
width = 0;
watchdog = 0;
use_new_config = 1;
#ifdef Q931
q931dmp = 0;
#endif
CityWeekend = 0;
sprintf(mlabel, "%%s%s %%s%%s", "%e.%b %T %I");
*amtsholung = 0;
dual = 0;
myname = argv[0];
myshortname = basename(myname);
} /* init_variables */
/*****************************************************************************/
#ifdef Q931
static void traceoptions()
{
q931dmp++;
use_new_config = 0;
replay++;
port = 20012;
} /* traceoptions */
#endif
int set_options(int argc, char* argv[])
{
register int c;
register char *p;
auto int defaultmsg = PRT_NORMAL | PRT_WARN | PRT_ERR | PRT_INFO;
auto int newmessage = 0;
if (!message)
message = defaultmsg;
#ifdef Q931
if (!strcmp(myshortname, "trace"))
traceoptions();
#endif
while ((c = getopt(argc, argv, options)) != EOF)
switch (c) {
case 'V' : print_version(myshortname);
exit(0);
break;
case 'v' : verbose = strtol(optarg, NIL, 0);
break;
case 's' : synclog++;
break;
case 'p' : port = strtol(optarg, NIL, 0);
break;
case 'm' : newmessage = strtol(optarg, NIL, 0);
if (!newmessage) {
newmessage = defaultmsg;
printf("%s: WARNING: \"-m\" Option now requires numeric Argument\n", myshortname);
} /* if */
break;
case 'l' : syslogmessage = strtol(optarg, NIL, 0);
if (!syslogmessage) {
syslogmessage = defaultmsg;
printf("%s: WARNING: \"-l\" Option requires numeric Argument\n", myshortname);
} /* if */
break;
case 'x' : xinfo = strtol(optarg, NIL, 0);
if (!xinfo)
xinfo = defaultmsg;
break;
case 'r' : replay++;
break;
case 't' : settime = strtol(optarg, NIL, 0); /* 1=once, 2=ever */
break;
case 'C' : ptty = strdup(optarg);
break;
case 'M' : imon++;
break;
case 'S' : sound++;
break;
case 'w' : wakeup = strtol(optarg, NIL, 0);
break;
case 'D' : isdaemon++;
break;
case 'T' : trace++;
break;
case 'a' : any = 0;
break;
case 'P' : stdoutput = PRT_LOG;
break;
case 'h' : hupctrl++;
if ((p = strchr(optarg, ':'))) {
*p = 0;
hup1 = atoi(optarg);
hup2 = atoi(p + 1);
}
else
printf("%s: WARNING: \"-h\" Option requires two Arguments\n", myshortname);
break;
case 'b' : bilingual++;
break;
case 'c' : mcalls = strtol(optarg, NIL, 0);
break;
case 'L' : xlog = strtol(optarg, NIL, 0);
break;
case 'f' : read_param_file(optarg);
break;
case 'n' : newline = 0;
break;
case 'W' : width = strtol(optarg, NIL, 0);
break;
case 'H' : watchdog = strtol(optarg, NIL, 0);
break;
case 'N' : use_new_config = 0;
break;
#ifdef Q931
case 'q' : traceoptions();
break;
#endif
case 'F' : CityWeekend++;
break;
case 'A' : strcpy(amtsholung, optarg);
break;
case '2' : dual = strtol(optarg, NIL, 0);
break;
case '?' : printf(usage, myshortname, myshortname, options);
exit(1);
} /* switch */
if (newmessage)
message = newmessage;
if (trace && isdaemon) {
printf("%s","Can not trace and daemon together!\n");
exit(20);
} /* if */
if (stdoutput && isdaemon) {
printf("%s","Can not write to stdout as daemon!\n");
exit(21);
} /* if */
if (isdaemon) {
if (syslogmessage == -1)
syslogmessage = defaultmsg;
switch (fork()) {
case -1 : print_msg(PRT_ERR,"%s","Can not start fork()!\n");
Exit(18);
break;
case 0 : break;
default : _exit(0);
}
/* Wenn message nicht explixit gesetzt wurde, dann gibt es beim daemon auch
kein Output auf der Console/ttyx */
if (!newmessage && ptty == NULL)
message = 0;
} /* if */
allflags = syslogmessage | message | xinfo | stdoutput;
return optind;
} /* set_options */
/*****************************************************************************/
static int read_param_file(char *FileName)
{
register char *p;
auto section *SPtr;
auto entry *Ptr;
if (opt_dat != NULL)
{
print_msg(PRT_ERR,"Can not more than one option file (file %s)!\n", FileName);
return -1;
}
if ((SPtr = opt_dat = read_file(NULL, FileName, 0)) == NULL)
return -1;
while (SPtr != NULL)
{
if (!strcmp(SPtr->name,CONF_SEC_OPT))
{
Ptr = SPtr->entries;
while (Ptr != NULL)
{
if (!strcmp(Ptr->name,CONF_ENT_DEV))
isdnctrl = Ptr->value;
else
if (!strcmp(Ptr->name,CONF_ENT_LOG))
verbose = (int)strtol(Ptr->value, NIL, 0);
else
if (!strcmp(Ptr->name,CONF_ENT_FLUSH))
synclog = toupper(*(Ptr->value)) == 'Y'?1:0;
else
if (!strcmp(Ptr->name,CONF_ENT_PORT))
port = strtol(Ptr->value, NIL, 0);
else
if (!strcmp(Ptr->name,CONF_ENT_STDOUT))
message = strtol(Ptr->value, NIL, 0);
else
if (!strcmp(Ptr->name,CONF_ENT_SYSLOG))
syslogmessage = strtol(Ptr->value, NIL, 0);
else
if (!strcmp(Ptr->name,CONF_ENT_XISDN))
{
xinfo = strtol(Ptr->value, NIL, 0);
}
else
if (!strcmp(Ptr->name,CONF_ENT_TIME))
settime = (int)strtol(Ptr->value, NIL, 0);
else
if (!strcmp(Ptr->name,CONF_ENT_CON))
ptty = Ptr->value;
else
if (!strcmp(Ptr->name,CONF_ENT_START))
sound = toupper(*(Ptr->value)) == 'Y'?1:0;
else
if (!strcmp(Ptr->name,CONF_ENT_THRU))
wakeup = strtol(Ptr->value, NIL, 0);
else
if (!strcmp(Ptr->name,CONF_ENT_DAEMON))
isdaemon = toupper(*(Ptr->value)) == 'Y'?1:0;
else
if (!strcmp(Ptr->name,CONF_ENT_MON))
imon = toupper(*(Ptr->value)) == 'Y'?1:0;
else
if (!strcmp(Ptr->name,CONF_ENT_PIPE))
stdoutput = toupper(*(Ptr->value)) == 'Y'?PRT_LOG:0;
else
if (!strcmp(Ptr->name,CONF_ENT_MON))
imon = toupper(*(Ptr->value)) == 'Y'?1:0;
else
if (!strcmp(Ptr->name,CONF_ENT_HANGUP)) {
hupctrl++;
if ((p = strchr(Ptr->value, ':'))) {
*p = 0;
hup1 = atoi(Ptr->value);
hup2 = atoi(p + 1);
} /* if */
}
else
if (!strcmp(Ptr->name,CONF_ENT_BI))
bilingual = toupper(*(Ptr->value)) == 'Y'?1:0;
else
if (!strcmp(Ptr->name,CONF_ENT_CALLS))
mcalls = strtol(Ptr->value, NIL, 0);
else
if (!strcmp(Ptr->name,CONF_ENT_XLOG))
xlog = strtol(Ptr->value, NIL, 0);
else
if (!strcmp(Ptr->name,CONF_ENT_NL))
newline = toupper(*(Ptr->value)) == 'Y'?1:0;
else
if (!strcmp(Ptr->name,CONF_ENT_WIDTH))
width = (int)strtol(Ptr->value, NIL, 0);
else
if (!strcmp(Ptr->name,CONF_ENT_CW))
CityWeekend = toupper(*(Ptr->value)) == 'Y'?1:0;
else
if (!strcmp(Ptr->name,CONF_ENT_DUAL))
dual = (int)strtol(Ptr->value, NIL, 0);
else
if (!strcmp(Ptr->name,CONF_ENT_AMT))
strcpy(amtsholung,Ptr->value);
else
#ifdef Q931
if (!strcmp(Ptr->name,CONF_ENT_Q931))
{
if(toupper(*(Ptr->value)) == 'Y')
traceoptions();
}
else
#endif
if (!strcmp(Ptr->name,CONF_ENT_WD))
watchdog = (int)strtol(Ptr->value, NIL, 0);
else
print_msg(PRT_ERR,"Error: Invalid entry `%s'!\n",Ptr->name);
Ptr = Ptr->next;
}
}
else
print_msg(PRT_ERR,"Error: Invalid section `%s'!\n",SPtr->name);
SPtr = SPtr->next;
}
return 0;
}
/*****************************************************************************/
static void restoreCharge()
{
register int i, j, n = 0, nx = max(knowns, 1);
auto FILE *f;
auto char fn[BUFSIZ];
typedef struct {
char who[16];
int day;
double charge;
double scharge;
int month;
double online;
double sonline;
double bytes;
double sbytes;
} CHARGE;
auto CHARGE *charge;
if ((charge = (CHARGE *)malloc(sizeof(CHARGE) * nx)) != (CHARGE *)NULL) {
sprintf(fn, "%s/%s", confdir(), CHARGEFILE);
if ((f = fopen(fn, "r")) != (FILE *)NULL) {
while (fscanf(f, "%s %d %lg %lg %d %lg %lg %lg %lg\n",
charge[n].who, &charge[n].day, &charge[n].charge, &charge[n].scharge,
&charge[n].month, &charge[n].online, &charge[n].sonline,
&charge[n].bytes, &charge[n].sbytes) == 9) {
n++;
if (n == nx) {
nx++;
if ((charge = (CHARGE *)realloc((void *)charge, sizeof(CHARGE) * nx)) == (CHARGE *)NULL) {
fclose(f);
return;
} /* if */
} /* if */
} /* while */
if (n) {
for (i = 0; i < knowns; i++)
for (j = 0; j < n; j++)
if (!strcmp(known[i]->who, charge[j].who)) {
known[i]->day = charge[j].day;
known[i]->charge = charge[j].charge;
known[i]->scharge = charge[j].scharge;
known[i]->month = charge[j].month;
known[i]->online = charge[j].online;
known[i]->sonline = charge[j].sonline;
known[i]->bytes = charge[j].bytes;
known[i]->sbytes = charge[j].sbytes;
break;
} /* if */
} /* if */
fclose(f);
} /* if */
free(charge);
} /* if */
} /* restoreCharge */
/*****************************************************************************/
int main(int argc, char *argv[], char *envp[])
{
register char *p;
register int i, res = 0;
auto int lastarg;
auto char fn[BUFSIZ];
#ifdef TESTCENTER
extern void test_center(void);
#endif
if (getuid() != 0) {
fprintf(stderr,"Can only run as root!\n");
exit(35);
} /* if */
set_print_fct_for_lib(print_in_modules);
init_variables(argc, argv);
lastarg = set_options(argc,argv);
if (lastarg < argc)
isdnctrl = argv[lastarg];
if (isdnctrl == NULL) {
print_msg(PRT_ERR,"There is no valid input device!\n");
Exit(31);
}
else {
p = strrchr(isdnctrl, C_SLASH);
sprintf(pidfile, "%s.%s", myshortname, p ? p + 1 : isdnctrl);
if (add_socket(&sockets, -1) || /* reserviert fuer isdnctrl */
add_socket(&sockets, -1) || /* reserviert fuer isdnctrl2 */
add_socket(&sockets, -1) ) /* reserviert fuer isdninfo */
Exit(19);
if (replay) {
verbose = 0;
synclog = 0;
settime = 0;
xinfo = 0;
*isdnctrl2 = 0;
}
else {
if (strcmp(isdnctrl, "-") && dual) {
strcpy(isdnctrl2, isdnctrl);
p = strrchr(isdnctrl2, 0) - 1;
if (!isdigit(*p)) /* "/dev/isdnctrl" */
strcat(++p, "0");
if (isdigit(*(p - 1)))
p--;
i = atoi(p);
sprintf(p, "%d", i + 2);
}
else
*isdnctrl2 = 0;
} /* else */
strcpy((char *)logname, LOGFILE);
if (replay)
strcat((char *)logname, ".rep");
openlog(myshortname, LOG_NDELAY, LOG_DAEMON);
#ifdef TESTCENTER
test_center();
#endif
if (xinfo && read_user_access())
Exit(22);
signal(SIGPIPE, SIG_IGN);
signal(SIGHUP, hup_handler);
signal(SIGINT, exit_on_signal);
signal(SIGTERM, exit_on_signal);
signal(SIGALRM, exit_on_signal);
signal(SIGQUIT, exit_on_signal);
signal(SIGILL, exit_on_signal);
if (!(allflags & PRT_DEBUG_GENERAL))
signal(SIGSEGV, exit_on_signal);
sockets[ISDNCTRL].descriptor = !strcmp(isdnctrl, "-") ? fileno(stdin) : open(isdnctrl, O_RDONLY | O_NONBLOCK);
if (*isdnctrl2)
sockets[ISDNCTRL2].descriptor = open(isdnctrl2, O_RDONLY | O_NONBLOCK);
if ((sockets[ISDNCTRL].descriptor >= 0) && (!*isdnctrl2 || (sockets[ISDNCTRL2].descriptor >= 0))) {
if (ptty != NULL)
fcons = fopen(ptty, "a");
if ((ptty == NULL) || (fcons != (FILE *)NULL)) {
if (verbose) {
if ((p = strrchr(isdnctrl, '/')))
p++;
else
p = argv[lastarg];
sprintf(fn, "%s/%s", TMPDIR, p);
} /* if */
if (!verbose || ((fprot = fopen(fn, "a")) != (FILE *)NULL)) {
for (i = 0; i < MAXCHAN; i++)
clearchan(i, 1);
#ifdef Q931
if (q931dmp) {
mymsns = 3;
mycountry = "+49";
myarea = "6408";
currency = NULL;
dual = 1;
chargemax = 0.0;
connectmax = 0.0;
bytemax = 0.0;
connectmaxmode = 0;
bytemaxmode = 0;
knowns = retnum = 0;
known = (KNOWN **)NULL;
start_procs.infoargs = NULL;
start_procs.flags = 0;
setDefaults();
}
else
#endif
{
if (readconfig(myshortname) < 0)
Exit(30);
restoreCharge();
} /* if */
if (!replay) {
switch (i = create_runfile(pidfile)) {
case 0 : break;
case -1 : print_msg(PRT_ERR,"Can not open pid file: %s!\n", strerror(errno));
Exit(36);
default : print_msg(PRT_ERR,"Another %s is running with pid %d!\n", myshortname, i);
Exit(37);
} /* switch */
} /* if */
if (replay || ((sockets[ISDNINFO].descriptor = open(INFO, O_RDONLY | O_NONBLOCK)) >= 0)) {
now();
#ifdef Q931
if (!q931dmp)
#endif
print_msg(PRT_NORMAL, "%s Version %s loaded\n", myshortname, VERSION);
#ifdef POSTGRES
dbOpen();
#endif
loop();
if (sockets[ISDNINFO].descriptor >= 0)
close(sockets[ISDNINFO].descriptor);
}
else {
print_msg(PRT_ERR, msg1, myshortname, INFO, strerror(errno));
res = 7;
} /* else */
if (verbose)
fclose(fprot);
}
else {
print_msg(PRT_ERR, msg1, myshortname, fn, strerror(errno));
res = 5;
} /* else */
if (ptty != NULL)
fclose(fcons);
}
else {
print_msg(PRT_ERR, msg1, myshortname, fn, strerror(errno));
res = 3;
} /* else */
if (strcmp(isdnctrl, "-"))
close(sockets[ISDNCTRL].descriptor);
if (*isdnctrl2)
close(sockets[ISDNCTRL2].descriptor);
}
else {
print_msg(PRT_ERR, msg1, myshortname, isdnctrl, strerror(errno));
res = 2;
} /* else */
#ifdef Q931
if (!q931dmp)
#endif
print_msg(PRT_NORMAL, "%s Version %s exiting\n", myshortname, VERSION);
} /* else */
Exit(res);
return(res);
} /* main */

334
isdnlog/isdnlog/isdnlog.h Normal file
View File

@ -0,0 +1,334 @@
/* $Id: isdnlog.h,v 1.1 1997/03/16 20:58:43 luethje Exp $
*
* ISDN accounting for isdn4linux.
*
* Copyright 1995, 1997 by Andreas Kool (akool@Kool.f.EUnet.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: isdnlog.h,v $
* Revision 1.1 1997/03/16 20:58:43 luethje
* Added the source code isdnlog. isdnlog is not working yet.
* A workaround for that problem:
* copy lib/policy.h into the root directory of isdn4k-utils.
*
* Revision 2.6.36 1997/02/11 18:21:43 akool
* isdnctrl2 implemented
*
* Revision 2.6.30 1997/01/28 16:49:43 akool
* LOG_MAJOR_VERSION auf 3 erhoeht
*
* Revision 2.6.26 1997/01/18 12:56:43 akool
* huptimeofs neu definiert
*
* Revision 2.3.4 1996/04/05 11:30:43 akool
* New ibytes/obytes ioctl() from Fritz implemented
* USERFILE
*
* Revision 2.23 1996/03/14 18:07:43 akool
*
* Revision 2.15 1996/02/21 20:14:43 akool
*
* Revision 2.12 1996/02/13 20:08:43 root
* Nu geht's (oder?)
*
* Revision 2.12 1996/02/13 20:08:43 root
* Nu geht's (oder?)
*
* Revision 1.2 1996/02/13 20:05:28 root
* so nun gehts
*
* Revision 1.1 1996/02/13 14:28:14 root
* Initial revision
*
* Revision 2.05 1995/02/11 17:10:16 akool
*
*/
/****************************************************************************/
#ifndef _ISDNLOG_H_
#define _ISDNLOG_H_
/****************************************************************************/
#define PUBLIC extern
/****************************************************************************/
#include <tools.h>
#include "socket.h"
/****************************************************************************/
#define LOG_MAJOR_VERSION 3
#define LOG_MINOR_VERSION 0
/****************************************************************************/
#define MAX_CALLS_IN_QUEUE 100
#define MAX_PRINTS_IN_QUEUE 500
/****************************************************************************/
#define BROADCAST 0x7f
/****************************************************************************/
#define ISDNCTRL 0
#define ISDNCTRL2 1
#define ISDNINFO 2
#define IN_PORT 3
#define FIRST_DESCR 3
/****************************************************************************/
#define PRT_ERR 1
#define PRT_WARN 2
#define PRT_INFO 4
#define PRT_PROG_OUT 4
#define PRT_NORMAL 4
#define PRT_LOG 8
#define PRT_SHOWNUMBERS 0x10
#define PRT_SHOWAOCD 0x20
#define PRT_SHOWCONNECT 0x40
#define PRT_SHOWHANGUP 0x80
#define PRT_SHOWCAUSE 0x100
#define PRT_SHOWTIME 0x200
#define PRT_SHOWBYTE 0x400
#define PRT_SHOWIMON 0x800
#define PRT_SHOWBEARER 0x1000
#define PRT_SHOWTICKS 0x2000
#define PRT_DEBUG_GENERAL 0x4000
#define PRT_DEBUG_DIAG 0x8000
#define PRT_DEBUG_INFO 0x10000
#define PRT_DEBUG_EXEC 0x20000
#define PRT_DEBUG_BUGS 0x40000
#define PRT_DEBUG_DECODE 0x80000
#define PRT_DEBUG_RING 0x100000
#define PRT_DEBUG_CS 0x200000
#define PRT_DEBUG_PROT 0x400000
#define PRT_NOTHING 0x800000
#define IS_DEBUG(VALUE) (VALUE >= PRT_DEBUG_GENERAL && VALUE < PRT_NOTHING)
/****************************************************************************/
#define AOC_INITIAL 0
#define AOCDCurrency 1
#define AOCDChargingUnit 2
#define AOCECurrency 3
#define AOCEChargingUnit 4
#define AOCDCurrencyInfo 5
#define AOCECurrencyInfo 6
#define AOCDChargingUnitInfo 7
#define AOCEChargingUnitInfo 8
#define RecordedCurrency 9
#define TypeOfChargingInfo 10
#define Currency 11
#define Amount 12
#define CurrencyAmount 13
#define Multiplier 14
#define RecordedUnitsList 15
#define RecordedUnits 16
#define NumberOfUnits 17
/****************************************************************************/
#define VERBOSE_HEX 1 /* only "HEX:" messages from /dev/isdnctrl */
#define VERBOSE_CTRL 2 /* any message from /dev/isdnctrl */
#define VERBOSE_INFO 4 /* any message from /dev/isdninfo */
#define VERBOSE_RATE 8 /* any message from ioctl(IIOCGETCPS) */
/****************************************************************************/
#ifndef USERFILE
#define USERFILE "isdnlog.users"
#endif
/****************************************************************************/
typedef struct _interval {
int event;
int chan;
info_args *infoarg;
time_t next_start;
struct _interval *next;
} interval;
/****************************************************************************/
#ifdef _ISDNLOG_C_
#define _EXTERN
socket_queue *sockets = NULL;
#else
#define _EXTERN extern
extern socket_queue *sockets;
#endif
_EXTERN FILE *flog; /* /var/adm/isdn.log */
_EXTERN FILE *fcons; /* /dev/ttyX (or stderr) */
_EXTERN FILE *fprot; /* /tmp/isdnctrl0 */
_EXTERN int first_descr;
_EXTERN int chan;
_EXTERN int message;
_EXTERN int syslogmessage;
_EXTERN int xinfo;
_EXTERN int sound;
_EXTERN int trace;
_EXTERN int isdaemon;
_EXTERN int imon;
_EXTERN int port;
_EXTERN int wakeup;
_EXTERN int fullhour;
_EXTERN int tty_dv;
_EXTERN int net_dv;
_EXTERN int inf_dv;
_EXTERN clock_t tt;
_EXTERN clock_t tto;
_EXTERN char st[FNSIZE];
_EXTERN char stl[FNSIZE];
_EXTERN int settime;
_EXTERN int replay;
_EXTERN int replaydev;
_EXTERN int verbose;
_EXTERN int synclog;
_EXTERN int any;
_EXTERN int stdoutput;
_EXTERN int allflags;
_EXTERN int newcps;
_EXTERN int chans;
_EXTERN int bilingual;
_EXTERN int hupctrl;
_EXTERN int hup1;
_EXTERN int hup2;
_EXTERN int mcalls;
_EXTERN int xlog;
_EXTERN char *myname, *myshortname;
_EXTERN int newline;
_EXTERN int width;
_EXTERN int watchdog;
_EXTERN char *isdnctrl;
_EXTERN char isdnctrl2[FNSIZE];
_EXTERN char logname[FNSIZE];
_EXTERN char pidfile[SHORT_STRING_SIZE];
_EXTERN IFO ifo[ISDN_MAX_CHANNELS];
_EXTERN IO io[ISDN_MAX_CHANNELS];
#undef _EXTERN
/****************************************************************************/
#ifdef _PROCESSOR_C_
#define _EXTERN
#else
#define _EXTERN extern
#endif
_EXTERN void dotrace(void);
_EXTERN int morectrl(int card);
_EXTERN void moreinfo(void);
_EXTERN void processrate(void);
_EXTERN void clearchan(int chan, int total);
#undef _EXTERN
/****************************************************************************/
#ifdef _FUNCTIONS_C_
#define _EXTERN
#else
#define _EXTERN extern
#endif
#define Exit(a) _Exit(__FILE__,__LINE__,a)
_EXTERN void _Exit(char *File, int Line, int RetCode);
_EXTERN int print_msg(int Level, const char *fmt, ...);
_EXTERN int Change_Channel(int old_channel, int new_channel);
_EXTERN void set_time_str(void);
_EXTERN void now(void);
_EXTERN void logger(int chan);
_EXTERN int ringer(int chan, int event);
#undef _EXTERN
/****************************************************************************/
#ifdef _SERVER_C_
#define _EXTERN
#else
#define _EXTERN extern
#endif
_EXTERN int message_from_server(CALL *call, int chan);
_EXTERN int eval_message(int sock);
_EXTERN int start_server(int port);
_EXTERN int listening(int port);
_EXTERN int print_from_server(char *String);
_EXTERN int change_channel(int old_chan, int new_chan);
_EXTERN int disconnect_client(int sock);
#undef _EXTERN
/****************************************************************************/
#ifdef _START_PROG_C_
#define _EXTERN
#else
#define _EXTERN extern
#endif
_EXTERN int Ring(info_args *, char *[], int, int);
_EXTERN void Alarm(void);
_EXTERN int CheckTime(char *);
_EXTERN int Print_Cmd_Output( int sock );
_EXTERN int Get_Sock_From_Call_And_Info_Args( int chan, info_args *Ptr, int Cnt );
_EXTERN int Get_Sock_From_Call( int chan, int Cnt );
_EXTERN int Get_Sock_From_Info_Args( info_args *Ptr, int Cnt );
_EXTERN int Condition_Changed( int condition, int flag );
_EXTERN const char *Set_Ringer_Flags( int condtion, int InOut );
_EXTERN int Start_Ring(int chan, info_args *infoarg, int event, int intervalflag);
_EXTERN int Start_Process(int chan, info_args *infoarg, int event);
_EXTERN int New_Interval(int chan, info_args *infoarg, int event);
_EXTERN int Del_Interval(int chan, info_args *infoarg);
_EXTERN struct timeval *Get_Interval(int Sec);
_EXTERN int Change_Channel_Ring( int old_channel, int new_channel);
_EXTERN int Start_Interval(void);
#undef _EXTERN
/****************************************************************************/
#ifdef _USER_ACCESS_C_
#define _EXTERN
#else
#define _EXTERN extern
#endif
_EXTERN int read_user_access( void );
_EXTERN int write_user_access( void );
_EXTERN int user_has_access(char *User, char *Host);
_EXTERN int User_Get_Message(char *User, char *Host, char* mymsn, int Flag);
_EXTERN const char *userfile(void);
#undef _EXTERN
/****************************************************************************/
#endif /* _ISDNLOG_H_ */

334
isdnlog/isdnlog/messages.c Normal file
View File

@ -0,0 +1,334 @@
/* $Id: messages.c,v 1.1 1997/03/16 20:58:44 luethje Exp $
*
* ISDN accounting for isdn4linux. (Q.931-Messages)
*
* Copyright 1995, 1997 by Andreas Kool (akool@Kool.f.EUnet.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
*/
#define _MESSAGES_C_
#include "isdnlog.h"
static char *MessageType[] = { /* According to Table 4-2/Q.931 */
"\x01 ALERTING",
"\x02 CALL PROCEEDING",
"\x03 PROGRESS",
"\x05 SETUP",
"\x07 CONNECT",
"\x0d SETUP ACKNOWLEDGE",
"\x0f CONNECT ACKNOWLEDGE",
"\x20 USER INFORMATION",
"\x21 SUSPEND REJECT",
"\x22 RESUME REJECT",
"\x24 HOLD",
"\x25 SUSPEND",
"\x26 RESUME",
"\x28 HOLD ACKNOWLEDGE", /* Makeln Acknowledge */
"\x2d SUSPEND ACKNOWLEDGE",
"\x2e RESUME ACKNOWLEDGE",
"\x30 HOLD REJECT",
"\x31 RETRIEVE",
"\x33 RETRIEVE ACKNOWLEDGE", /* Makeln Eesume Acknowledge */
"\x37 RETRIEVE REJECT",
"\x45 DISCONNECT",
"\x46 RESTART",
"\x4d RELEASE",
"\x4e RESTART ACKNOWLEDGE",
"\x5a RELEASE COMPLETE",
"\x60 SEGMENT",
"\x62 FACILITY",
"\x64 REGISTER",
"\x6e NOTIFY",
"\x75 STATUS ENQUIRY",
"\x79 CONGESTION CONTROL",
"\x7b INFORMATION",
"\x7d STATUS",
NULL };
static char *MessageType1TR6[] = {
"\x61 REGister INDication",
"\x62 CANCel INDication",
"\x63 FACility STAtus",
"\x64 STAtus ACKnowledge",
"\x65 STAtus REJect",
"\x66 FACility INFormation",
"\x67 INFormation ACKnowledge",
"\x68 INFormation REJect",
"\x75 CLOSE",
"\x77 CLOse ACKnowledge",
"\x00 ESCape",
"\x01 ALERT",
"\x02 CALL SENT",
"\x07 CONNect",
"\x0f CONNect ACKnowledge",
"\x05 SETUP",
"\x0d SETUP ACKnowledge",
"\x26 RESume",
"\x2e RESume ACKnowledge",
"\x22 RESume REJect",
"\x25 SUSPend",
"\x2d SUSPend ACKnowledge",
"\x21 SUSPend REJect",
"\x20 USER INFO",
"\x40 DETach",
"\x45 DISConnect",
"\x4d RELease",
"\x5a RELease ACKnowledge",
"\x6e CANCel ACKnowledge",
"\x67 CANCel REJect",
"\x69 CONgestion CONtrol",
"\x60 FACility",
"\x68 FACility ACKnowledge",
"\x66 FACility CANcel",
"\x64 FACility REGister",
"\x65 FACility REJect",
"\x6d INFOrmation",
"\x6c REGister ACKnowledge",
"\x6f REGister REJect",
"\x63 STATus",
NULL };
static char *InformationElement[] = {
"\x00 Segmented message",
"\x04 bearer service indication", /* Bearer capability */
"\x08 Cause",
"\x0c Connected address (obsolete)",
"\x0d Extended facility information element identifier",
"\x10 Call identity",
"\x14 Call state",
"\x18 Channel identification",
"\x19 Data link connection identifier",
"\x1c Facility information element identifier", /* Facility */
"\x1e Progress indicator",
"\x20 Network-specific facilities",
"\x24 Terminal capabilities (obsolete)",
"\x27 Notification indicator",
"\x28 Display",
"\x29 Date/Time",
"\x2c Keypad facility",
"\x34 Signal",
"\x40 Information rate",
"\x42 End-to-end transit delay",
"\x43 Transit delay selection and indication",
"\x44 Packet layer binary parameters",
"\x45 Packet layer window size",
"\x46 Packet size",
"\x47 Closed user group",
"\x4a Reverse charge indication",
"\x4c COLP",
"\x6c Calling party number",
"\x6d Calling party subaddress",
"\x70 Called party number",
"\x71 Called party subaddress",
"\x74 Redirecting number",
"\x78 Transit network selection",
"\x79 Restart indicator",
"\x7c Low layer compatibility",
"\x7d High layer compatibility",
"\x7e User-user",
"\x7f Escape for extension",
NULL };
static char *InformationElement1TR6[] = {
"\x08 Cause",
"\x0c Connecting Address",
"\x10 Call IDentity",
"\x18 Channel IDentity",
"\x20 Network Specific Facility",
"\x28 Display",
"\x2c Keypad",
"\x6c Origination Address",
"\x70 Destination Address",
"\x7e User Info",
"\x01 Service Indicator",
"\x02 Charging Information",
"\x03 Date",
"\x05 Facility Select",
"\x06 Facility Status",
"\x07 Status Called",
"\x08 Additional Transmission Attributes",
NULL };
static char *CauseValue[] = { /* According to Q.850 */
"\x01 Unallocated (unassigned) number",
"\x02 No route to specified transit network",
"\x03 No route to destination",
"\x04 Send special information tone",
"\x05 Misdialled trunk prefix",
"\x06 Channel unacceptable",
"\x07 Channel awarded and being delivered in an established channel",
"\x08 Preemption",
"\x09 Preemption - circuit reserved for reuse",
"\x10 Normal call clearing",
"\x11 User busy",
"\x12 No user responding",
"\x13 No answer from user (user alerted)",
"\x14 Subscriber absent",
"\x15 Call rejected",
"\x16 Number changed",
"\x1a non-selected user clearing",
"\x1b Destination out of order",
"\x1c Invalid number format (address incomplete)",
"\x1d Facility rejected",
"\x1e Response to Status enquiry",
"\x1f Normal, unspecified",
"\x22 No circuit/channel available",
"\x26 Network out of order",
"\x27 Permanent frame mode connection out-of-service",
"\x28 Permanent frame mode connection operational",
"\x29 Temporary failure",
"\x2a Switching equipment congestion",
"\x2b Access information discarded",
"\x2c Requested circuit/channel not available",
"\x2e Precedence call blocked",
"\x2f Resource unavailable, unspecified",
"\x31 Quality of service unavailable",
"\x32 Requested facility not subscribed",
"\x35 Outgoing calls barred within CUG",
"\x37 Incoming calls barred within CUG",
"\x39 Bearer capability not authorized",
"\x3a Bearer capability not presently available",
"\x3e Inconsistency in designated outgoing access information and subscriber class",
"\x3f Service or option not available, unspecified",
"\x41 Bearer capability not implemented",
"\x42 Channel type not implemented",
"\x43 Requested facility not implemented",
"\x44 Only restricted digital information bearer capability is available",
"\x45 angeforderte Eigenschaft nicht implementiert",
"\x46 Nur beschraenkte digitale Information ueber Uebermittlungsfunktion ist verfuegbar",
"\x4f Service or option not implemented",
"\x51 Invalid call reference value",
"\x52 Identified channel does not exist",
"\x53 A suspended call exists, but this call identity does not",
"\x54 Call identity in use",
"\x55 No call suspended",
"\x56 Call having the requested call identity has been cleared",
"\x57 User not member of CUG",
"\x58 Incompatible destination",
"\x5a Non-existent CUG",
"\x5b Invalid transit network selection",
"\x5f Invalid message, unspecified",
"\x60 Mandatory information element is missing",
"\x61 Message type non-existent or not implemented",
"\x62 Message not compatible with call state or message type non-existent or not implemented",
"\x63 Information element/parameter non-existent or not implemented",
"\x64 Invalid information element contents",
"\x65 Message not compatible with call state",
"\x66 Recovery on timer expiry",
"\x67 Parameter non-existent or not implemented - passed on",
"\x6e Message with unrecognized parameter discarded",
"\x6f Protocol error, unspecified",
"\x7f Interworking, unspecified",
NULL };
static char *CauseValue1TR6[] = {
"\x00 Normal Call Clearing",
"\x01 Invalid Call Reference",
"\x03 Bearer Service Not Implemented",
"\x07 Caller Identity unknown",
"\x08 Caller Identity in Use",
"\x09 No Channels available",
"\x0a No Channels available",
"\x10 Facility Not Implemented",
"\x11 Facility Not Subscribed",
"\x20 Outgoing calls barred",
"\x21 User Access Busy",
"\x22 Negative GBG",
"\x23 Unknown GBG",
"\x25 No SPV known",
"\x35 Destination not obtainable",
"\x38 Number changed",
"\x39 Out Of Order",
"\x3a No User Response",
"\x3b User Busy",
"\x3d Incoming Barred",
"\x3e Call Rejected",
"\x58 Invalid destination address",
"\x59 Network Congestion",
"\x5a Remote User initiated",
"\x70 Local Procedure Error",
"\x71 Remote Procedure Error",
"\x72 Remote User Suspend",
"\x73 Remote User Resumed",
"\x7f User Info Discarded",
NULL };
static char *Service1TR6[] = {
"\x01 Fernsprechen",
"\x02 Telefax Gruppe 2/3, Modem-DFUE",
"\x03 X.21-Terminaladapter",
"\x04 Telefax Gruppe 4 (digital)",
"\x05 Bildschirmtext (64 kBit/s)",
"\x07 Datenuebertragung (64 kBit/s oder V.110)",
"\x08 X.25-Terminaladapter",
"\x09 Teletex (64 kBit/s)",
"\x0a Text-Fax (ASCII-Text und Grafiken gemischt)",
"\x0d Fernwirken, Telemetrie, Alarmierung",
"\x0e Fernzeichnen",
"\x0f Bildschirmtext (zukuenftiger Standard)",
"\x10 Bildtelefon",
NULL };
char *qmsg(int type, int version, int val)
{
register char **p, *what;
static char *nix = "";
switch (type) {
case TYPE_MESSAGE : p = (version == VERSION_1TR6) ? MessageType1TR6 : MessageType;
what = "Message type";
break;
case TYPE_ELEMENT : p = (version == VERSION_1TR6) ? InformationElement1TR6 : InformationElement;
what = "Information Element";
break;
case TYPE_CAUSE : if (val == -1)
return(nix);
p = (version == VERSION_1TR6) ? CauseValue1TR6 : CauseValue;
what = "Cause";
break;
case TYPE_SERVICE : p = Service1TR6;
what = "Service";
break;
default : p = (char **)NULL;
what = "";
break;
} /* switch */
while (*p && **p != val)
p++;
if (*p && (**p == val))
return(*p + 2);
else {
if (++retnum == MAXRET)
retnum = 0;
sprintf(retstr[retnum], "UNKNOWN %s 0x%02x", what, val);
return(retstr[retnum]);
} /* else */
} /* qmsg */

220
isdnlog/isdnlog/postgres.c Normal file
View File

@ -0,0 +1,220 @@
/* $Id: postgres.c,v 1.1 1997/03/16 20:58:45 luethje Exp $
*
* Interface for Postgres95-Database for isdn4linux. (db-module)
*
* by Markus Leist (markus@hal.dirnet.com)
*
* 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: postgres.c,v $
* Revision 1.1 1997/03/16 20:58:45 luethje
* Added the source code isdnlog. isdnlog is not working yet.
* A workaround for that problem:
* copy lib/policy.h into the root directory of isdn4k-utils.
*
* Revision 1.2 1996/12/05 10:20:04 admin
* first version auf Postgres95-Interface seems to be ok
*
* Revision 1.1 1996/12/04 10:03:24 admin
* Initial revision
*
*
*/
#ifdef POSTGRES
#define _POSTGRES_C_
#include "postgres.h"
int dbOpen(void)
{
/* get strings from macros */
db_Host = NULL;
if ( DB_HOST )
{
db_Host = malloc( strlen( DB_HOST));
strcpy( db_Host, DB_HOST);
}
db_Name = NULL;
if ( DB_NAME )
{
db_Name = malloc( strlen( DB_NAME));
strcpy( db_Name, DB_NAME);
}
db_Table = NULL;
if ( DB_TABLE )
{
db_Table = malloc( strlen( DB_TABLE));
strcpy( db_Table, DB_TABLE);
}
db_Port = NULL;
if ( DB_PORT )
{
db_Port = malloc( strlen( DB_PORT));
strcpy( db_Port, DB_PORT);
}
db_Options = NULL;
if ( DB_OPTIONS )
{
db_Options = malloc( strlen( DB_OPTIONS));
strcpy( db_Options, DB_OPTIONS);
}
db_Tty = NULL;
if ( DB_TTY )
{
db_Tty = malloc( strlen( DB_TTY));
strcpy( db_Tty, DB_TTY);
}
/* make a connection to the database */
db_Conn = PQsetdb( db_Host, db_Port, db_Options, db_Tty, db_Name);
/* check to see that the backend connection was successfully made */
if ( PQstatus( db_Conn) == CONNECTION_BAD)
{
syslog( LOG_ERR, "%s", "Connection to ISDN-database failed.");
syslog( LOG_ERR, "%s", PQerrorMessage( db_Conn));
PQfinish( db_Conn);
return( -1);
}
return( 0);
}
int dbClose(void)
{
PQfinish( db_Conn);
if ( db_Host)
free( db_Host);
if ( db_Name)
free( db_Name);
if ( db_Table)
free( db_Table);
if ( db_Port)
free( db_Port);
if ( db_Options)
free( db_Options);
if ( db_Tty)
free( db_Tty);
return( 0);
}
int dbAdd( DbStrIn *in)
{
PGresult *res;
char out_txt[400];
struct tm *tm;
assert( (int)in);
if ( dbStatus() ) /* returns -1 when not open */
if ( dbOpen() ) /* returns -1 when error appears */
return( -1);
res = PQexec( db_Conn, "BEGIN");
if ( PQresultStatus( res) != PGRES_COMMAND_OK)
{
syslog( LOG_ERR, "%s", "Connection to ISDN-database failed.");
syslog( LOG_ERR, "%s", PQerrorMessage( db_Conn));
PQfinish( db_Conn);
return( -1);
}
/* should PQclear PGresult whenever it is no longer needed to avoid
memory leaks */
PQclear( res);
tm = localtime( (__const time_t *) &(in->connect));
sprintf( out_txt
, "INSERT INTO %s "
"( sdate, stime, calling, called, charge, dir, "
" in_bytes, out_bytes, msec, sec, status, service, "
" source, vrsion, factor, currency) values "
"( \'%02d.%02d.%d\', \'%02d:%02d:%02d\', "
"\'%s\', \'%s\', \'%d\', \'%c\', "
"\'%ld\', \'%ld\', \'%d\', \'%d\', \'%d\', \'%d\', "
"\'%d\', \'%d\', \'%5.2f\', \'%s\' );",
db_Table,
tm->tm_mday, tm->tm_mon+1, tm->tm_year+1900,
tm->tm_hour, tm->tm_min, tm->tm_sec,
in->calling, in->called,
in->aoce, in->dialin,
in->ibytes, in->obytes,
in->hduration, in->duration,
in->cause, in->si1, in->si11,
in->version, in->currency_factor,
in->currency);
/* fetch instances from the pg_database, the system catalog of databases*/
res = PQexec( db_Conn, out_txt);
if ( PQresultStatus( res) != PGRES_COMMAND_OK)
{
syslog( LOG_ERR, "%s", "Connection to ISDN-database failed.");
syslog( LOG_ERR, "%s", PQerrorMessage( db_Conn));
PQfinish( db_Conn);
return( -1);
}
PQclear( res);
/* end the transaction */
res = PQexec( db_Conn, "END");
if ( PQresultStatus( res) != PGRES_COMMAND_OK)
{
syslog( LOG_ERR, "%s", "Connection to ISDN-database failed.");
syslog( LOG_ERR, "%s", PQerrorMessage( db_Conn));
PQfinish( db_Conn);
return( -1);
}
PQclear(res);
return( 0);
}
int dbStatus( void)
{
if ( PQstatus( db_Conn) == CONNECTION_BAD)
return( -1);
else
return( 0);
}
#endif

120
isdnlog/isdnlog/postgres.h Normal file
View File

@ -0,0 +1,120 @@
/* $Id: postgres.h,v 1.1 1997/03/16 20:58:46 luethje Exp $
*
* Interface for Postgres95-Database for isdn4linux.
*
* by Markus Leist (markus@hal.dirnet.com)
*
* 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: postgres.h,v $
* Revision 1.1 1997/03/16 20:58:46 luethje
* Added the source code isdnlog. isdnlog is not working yet.
* A workaround for that problem:
* copy lib/policy.h into the root directory of isdn4k-utils.
*
* Revision 1.2 1996/12/05 10:18:17 admin
* first version auf Postgres95-Interface seems to be ok
*
* Revision 1.1 1996/12/04 09:57:44 admin
* Initial revision
*
*
*/
/****************************************************************************/
#ifndef _POSTGRES_H_
#define _POSTGRES_H_
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <malloc.h>
#include <time.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/times.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <limits.h>
#include <signal.h>
#include <math.h>
#include <syslog.h>
#include <assert.h>
#include <libpq-fe.h> /* functions for postgres95 */
/* if DB_*-Macro=NULL, Postgres will use following environment variables:
PGHOST, PGPORT, PGOPTIONS, PGTTY, PGDATABASE */
#define DB_HOST NULL /* host name of backend-server */
#define DB_PORT NULL /* port of backend-server */
#define DB_OPTIONS NULL /* special options to start up backend-server */
#define DB_TTY NULL /* debugging tty for backend-server */
#define DB_NAME "isdn" /* name of database */
#define DB_TABLE "isdn2" /* name of table in database */
#define NUMSIZE 20
struct _DbStrIn
{
time_t connect; /* Zeitpunkt des Verbindungsaufbaues */
char calling[NUMSIZE]; /* Telefonnummer des Anrufers */
char called[NUMSIZE]; /* Telefonnummer des Gegners */
int duration; /* Dauer der Verbindung in Sekunden */
int hduration; /* Dauer der Verbindung in 1/100 Sekunden */
int aoce; /* Anzahl zu zahlender Gebuehreneinheiten (AOC-D) */
int dialin; /* "I" fuer incoming call, "O" fuer outgoing call */
int cause; /* Kam eine Verbindung nicht zustande ist hier der Grund */
long ibytes; /* Summe der uebertragenen Byte _von_ draussen (incoming) */
long obytes; /* Summe der uebertragenen Byte _nach_ draussen (outgoing) */
int version; /* Versionsnummer (LOG_MAJOR_VERSION*100 + LOG_MINOR_VERSION) */
int si1; /* Dienstkennung fuer diese Verbindung (1=Speech, 7=Data usw.) */
int si11; /* Bei Dienstkennung 1=Speech -> analog oder digital ? */
double currency_factor; /* Der Currency Factor fuer diese Verbinung (hier z.Zt. 0,12) */
char currency[32]; /* (16) Die Waehrung fuer diese Verbindung (in Deutschland "DM") */
};
typedef struct _DbStrIn DbStrIn;
/****************************************************************************/
#ifdef _POSTGRES_C_
#define _EXTERN
#else
#define _EXTERN extern
#endif
_EXTERN int dbOpen( void);
_EXTERN int dbClose( void);
_EXTERN int dbAdd( DbStrIn *in);
_EXTERN int dbStatus( void);
#undef _EXTERN
#ifdef _POSTGRES_C_
#define _EXTERN static
#else
#define _EXTERN extern
#endif
_EXTERN char *db_Host, *db_Port, *db_Options, *db_Tty;
_EXTERN char *db_Name, *db_Table;
_EXTERN PGconn *db_Conn;
#undef _EXTERN
#endif /* _POSTGRES_H_ */

4049
isdnlog/isdnlog/processor.c Normal file

File diff suppressed because it is too large Load Diff

727
isdnlog/isdnlog/server.c Normal file
View File

@ -0,0 +1,727 @@
/*
* ISDN accounting for isdn4linux.
*
* Copyright 1996 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.
*
*/
/****************************************************************************/
#define _SERVER_C_
/****************************************************************************/
#include "isdnlog.h"
/****************************************************************************/
static char **Old_Prints = NULL;
static char **Old_Info = NULL;
static char **Cur_Info = NULL;
static int Cur_Info_Size = 0;
/****************************************************************************/
static int new_client(int sock);
static int del_Cur_Info(int channel);
static int add_Cur_Info(int channel, char *String);
static int append_Old_Info(char *String);
static char *Get_Address(char *Number);
static int Set_Address(char *String);
static int Write_Caller_Message(int sock, CALL *info);
static char *Build_Call_Info(CALL *call, int chan);
static int save_messages(char *String, int channel, int stat);
static int broadcast_from_server(char* Num, int Flag, int Message, char *String);
static int append_Old_Prints(char *String);
static int String_For_Output(char *String);
/****************************************************************************/
extern time_t cur_time;
/****************************************************************************/
int listening(int port)
{
int sock;
struct servent *sp = NULL;
if ((sock = server_connect(&sp,port)) < 0)
{
if (sock == NO_SOCKET)
{
print_msg(PRT_NORMAL,"Can not open socket %d: %s\n",sock,strerror(errno));
}
else
if (sock == NO_BIND)
{
print_msg(PRT_NORMAL,"Can not bind socket: %s\n",strerror(errno));
}
else
if (sock == NO_LISTEN)
{
print_msg(PRT_NORMAL,"Can not start listening: %s\n",strerror(errno));
}
return -1;
}
if (sp)
{
print_msg(PRT_DEBUG_CS,"Got service %s on port %d\n",
sp->s_name,ntohs(sp->s_port));
}
else
{
print_msg(PRT_DEBUG_CS,"Got port %d\n", port);
}
return sock;
}
/****************************************************************************/
int new_client(int sock)
{
int Accept;
int Cnt;
int RetCode;
char *Host = NULL;
static CALL *Info = NULL;
if ((RetCode = read_user_access()) != 0)
{
print_msg(PRT_ERR,"Error while reading file \"%s\"!\n",userfile());
Exit(24);
}
sockets[sock].f_username = (char*) calloc(strlen(sockets[sock].msgbuf.buf)+1,
sizeof(char));
strcpy(sockets[sock].f_username,sockets[sock].msgbuf.buf);
Accept = user_has_access(sockets[sock].f_username,sockets[sock].f_hostname);
sockets[sock].msg = MSG_VERSION;
msgcpy(&(sockets[sock]),PROT_VERSION,strlen(PROT_VERSION)+1);
if (Write(&(sockets[sock])) < 1)
{
disconnect_client(sock);
return 0;
}
Host = sockets[sock].f_hostname != NULL ? sockets[sock].f_hostname : "unknown";
print_msg(PRT_DEBUG_CS,"connection from client %s@%s %s\n",
sockets[sock].f_username,
Host,
Accept != -1?"accepted":"rejected");
if (Accept == -1)
{ /* Ablehnung der Verbindung */
sockets[sock].waitstatus = WF_CLOSE;
sockets[sock].msg = MSG_ANN_REJ;
sockets[sock].msgbuf.used = 0;
Write(&(sockets[sock]));
/* Die naechste Zeile wird nicht gebraucht
disconnect_client(sock);
*/
return 0;
}
else
{ /* Verbindung wird angenommen */
sockets[sock].msg = MSG_ANN_ACC;
msgcpy(&(sockets[sock]),itos(Accept,_MSG_2B),_MSG_2B+1);
if (Write(&(sockets[sock])) < 1)
{
disconnect_client(sock);
return 0;
}
}
sockets[sock].waitstatus = WF_NOTHING;
if (Old_Info != NULL)
for (Cnt = 0; Cnt < mcalls; Cnt++)
if (Old_Info[Cnt] != NULL &&
Set_Info_Struct(&Info,Old_Info[Cnt]) >= 0 &&
User_Get_Message(sockets[sock].f_username,sockets[sock].f_hostname,Info->num[_ME(Info)],0) == 0)
{
sockets[sock].msg = MSG_CALL_INFO;
msgcpy(&(sockets[sock]),Old_Info[Cnt],strlen(Old_Info[Cnt])+1);
if (Write(&(sockets[sock])) < 1)
{
disconnect_client(sock);
return 0;
}
}
if (Cur_Info != NULL)
for (Cnt = 0; Cnt < Cur_Info_Size; Cnt++)
if (Cur_Info[Cnt] != NULL &&
Set_Info_Struct(&Info,Cur_Info[Cnt]) >= 0 &&
User_Get_Message(sockets[sock].f_username,sockets[sock].f_hostname,Info->num[_ME(Info)],0) == 0)
{
sockets[sock].msg = MSG_CALL_INFO;
msgcpy(&(sockets[sock]),Cur_Info[Cnt],strlen(Cur_Info[Cnt])+1);
if (Write(&(sockets[sock])) < 1)
{
disconnect_client(sock);
return 0;
}
}
if (Old_Prints != NULL && User_Get_Message(sockets[sock].f_username,sockets[sock].f_hostname,NULL,T_PROTOCOL) == 0)
for (Cnt = 0; Cnt < xlog; Cnt++)
if (Old_Prints[Cnt] != NULL)
{
sockets[sock].msg = MSG_SERVER;
msgcpy(&(sockets[sock]),Old_Prints[Cnt],strlen(Old_Prints[Cnt])+1);
if (Write(&(sockets[sock])) < 1)
{
disconnect_client(sock);
return 0;
}
}
else
break;
return 0;
}
/****************************************************************************/
int disconnect_client(int sock)
{
char User[SHORT_STRING_SIZE];
char Host[SHORT_STRING_SIZE];
if (sockets[sock].f_username == NULL)
strcpy(User,"unknown");
else
strcpy(User,sockets[sock].f_username);
if (sockets[sock].f_hostname == NULL)
strcpy(Host,"unknown");
else
strcpy(Host,sockets[sock].f_hostname);
close(sockets[sock].descriptor);
if (del_socket(&sockets,sock))
Exit(16);
print_msg(PRT_DEBUG_CS,"disconnect from client %s@%s!\n",User,Host);
print_msg(PRT_DEBUG_CS,"I/O error: %s!\n",strerror(errno));
return 0;
}
/****************************************************************************/
int eval_message (int sock)
{
long int Value;
int Msg;
do
{
if ((Value = Read(&(sockets[sock]))) < 0)
{
disconnect_client(sock);
break;
}
else
{
Msg = sockets[sock].msg;
switch(sockets[sock].waitstatus)
{
case WF_ACC:
switch (Msg)
{
case MSG_ANNOUNCE:
new_client(sock);
break;
default:
/* Meldung: Unbekannter Message-Typ Msg */
print_msg(PRT_ERR,"Unknown Message %d: %s\n",Msg,sockets[sock].msgbuf.buf);
disconnect_client(sock);
break;
}
break;
case WF_CLOSE:
switch (Msg)
{
case MSG_CLOSE:
disconnect_client(sock);
break;
default:
/* Meldung: Unbekannter Message-Typ Msg */
print_msg(PRT_ERR,"Unknown Message %d: %s\n",Msg,sockets[sock].msgbuf.buf);
disconnect_client(sock);
break;
}
break;
default:
switch (Msg)
{
case MSG_NEW_CALLER:
Set_Address(sockets[sock].msgbuf.buf);
break;
default:
/* Meldung: Unbekannter Message-Typ Msg */
print_msg(PRT_ERR,"Unknown Message %d: %s\n",Msg,sockets[sock].msgbuf.buf);
disconnect_client(sock);
break;
}
break;
}
}
} while (sockets[sock].status == NEXT_MSG);
return 0;
}
/****************************************************************************/
int broadcast_from_server(char* Num, int Flag, int Message, char *String)
{
int Cnt;
for(Cnt = first_descr; Cnt < socket_size(sockets); Cnt++)
{
if (sockets[Cnt].fp == NULL &&
sockets[Cnt].waitstatus == WF_NOTHING &&
User_Get_Message(sockets[Cnt].f_username,sockets[Cnt].f_hostname,Num,Flag) == 0)
{
sockets[Cnt].msg = Message;
msgcpy(&(sockets[Cnt]),String,strlen(String)+1);
if (Write(&(sockets[Cnt])) < 1)
disconnect_client(Cnt);
}
}
return 0;
}
/****************************************************************************/
int print_from_server(char *String)
{
int RetCode;
char NewString[LONG_STRING_SIZE];
time_t t = time(NULL);
struct tm *tm_time = localtime(&t);
tm_time->tm_isdst = 0;
strftime(NewString,LONG_STRING_SIZE,"%b %d %X ",tm_time);
strcat(NewString,String);
if ((RetCode = String_For_Output(NewString)) < 0)
return RetCode;
if ((RetCode = append_Old_Prints(NewString)) < 0)
return RetCode;
return broadcast_from_server(NULL,T_PROTOCOL,MSG_SERVER,NewString);
}
/****************************************************************************/
int message_from_server(CALL *call, int chan)
{
int Cnt;
int RetCode;
char *String = Build_Call_Info(call,chan);
if ((RetCode = String_For_Output(String)) < 0)
return RetCode;
if ((RetCode = save_messages(String,chan,call->stat)) < 0)
return RetCode;
for(Cnt = first_descr; Cnt < socket_size(sockets); Cnt++)
{
if (sockets[Cnt].fp == NULL &&
sockets[Cnt].waitstatus == WF_NOTHING &&
User_Get_Message(sockets[Cnt].f_username,sockets[Cnt].f_hostname,call->num[_ME(call)],0) == 0)
{
sockets[Cnt].msg = MSG_CALL_INFO;
msgcpy(&(sockets[Cnt]),String,strlen(String)+1);
if (Write(&(sockets[Cnt])) < 1)
disconnect_client(Cnt);
else
if (Write_Caller_Message(Cnt,call) < 0)
disconnect_client(Cnt);
}
}
return 0;
}
/****************************************************************************/
char *Build_Call_Info(CALL *call, int chan)
{
static char RetCode[LONG_STRING_SIZE];
/* Anmerkungen dazu:
1. ``connect'' kann auch (time_t)0 sein!
Dann besteht noch gar keine Verbindung - z.b. weil es gerade
klingelt, man aber noch nicht abgenommen hat!
2. Die ``Dauer'' zu uebertragen halte ich fuer unwichtig - bitte
korrigiert mich, wenn ich da falsch liege!
Die Dauer ist doch ``(jetzt) - connect'' ?
3. Die Einheiten sind:
0 : kostet nix (0130 Gespraech, oder man wird angerufen)
-1 .. -x : Gebuehrenimpuls
1 .. x : AOCE (Gebuehreninfo am Ende)
*/
sprintf(RetCode, "%d|%d|%d|%s|%s|%s|%s|%s|%s|%s|%d|%d|%d|%s|%s|%ld|%ld|%g|%g|%s\n",
chan, /* Kennung: 0 = erste, 1 = zweite laufende Verbindung */
call->stat, /* Satzart fuer _diese_ Meldung */
call->dialin, /* 1 = ein Anruf, 0 = man waehlt raus */
call->num[_ME(call)], /* Eigene MSN */
call->alias[_ME(call)], /* Alias de eigenen MSN */
call->num[_OTHER(call)], /* Telefonnummer des Anrufers/Angerufenen (wie von der VSt uebermittelt) */
call->vorwahl[_OTHER(call)], /* Vorwahl des Anrufers/Angerufenen */
call->rufnummer[_OTHER(call)], /* Rufnummer des Anrufers/Angerufenen */
call->alias[_OTHER(call)], /* Alias des Anrufers/Angerufenen */
call->area[_OTHER(call)], /* Ortsnetz des Anrufers/Angerufenen */
(int)(call->connect?call->connect:cur_time), /* Beginn (als (time_t) ) */
(int)(call->connect?cur_time - call->connect:0), /* aktuelle Dauer - in Sekunden seit CONNECT */
call->aoce, /* Einheiten (negativ: laufende Impulse, positiv: AOCE) */
double2str(abs(call->aoce) * currency_factor, 6, 2, DEB), /* kostet gerade */
currency_factor ? currency : "DM", /* Waehrung */
call->ibytes, /* Frank's ibytes */
call->obytes, /* Frank's obytes */
call->ibps, /* Aktueller Durchsatz INPUT: Bytes/Sekunde */
call->obps, /* Aktueller Durchsatz OUTPUT: Bytes/Sekunde */
call->msg); /* Status */
return RetCode;
}
/****************************************************************************/
int Write_Caller_Message(int sock, CALL *Info)
{
char *Address = NULL;
if (Info->num[0][0] == '\0')
return 0;
if (User_Get_Message(sockets[sock].f_username,sockets[sock].f_hostname,NULL,T_ADDRESSBOOK) != 0)
return 0;
/* Dirty Hack fuer emulation von neuen Anrufern */
if (Info->stat == STATE_CONNECT)
{
if ((Address = Get_Address(Info->num[0])) == NULL)
{
sockets[sock].msg = MSG_WHO_IS;
msgcpy(&(sockets[sock]),Info->num[0],strlen(Info->num[0])+1);
if (Write(&(sockets[sock])) < 1)
{
disconnect_client(sock);
return -1;
}
}
else
{
sockets[sock].msg = MSG_CALLER;
msgcpy(&(sockets[sock]),Address,strlen(Address)+1);
if (Write(&(sockets[sock])) < 1)
{
disconnect_client(sock);
return -1;
}
}
}
return 0;
}
/****************************************************************************/
char *Get_Address(char *Number)
{
/* Hier sollte die Adresse zur uebergebenen Telefonummer geliefert werden */
return NULL;
return "Burmester:Fred:2::Lohe 4:D:23869:Fischbek:2:04532/123:04532/124:0:0::Elmenhorster Str. 16:D:20000:Hamburg:0:0:1:fred@wo.auch.immer:08.01.68";
}
/****************************************************************************/
int Set_Address(char *String)
{
/* Hier sollte die Adresse zur uebergebenen Telefonummer geliefert werden */
print_msg(PRT_DEBUG_CS,"New Address*%s*\n",String);
return 0;
}
/****************************************************************************/
int save_messages(char *String, int channel, int stat)
{
int RetCode;
if (stat == STATE_HANGUP)
{
if ((RetCode = del_Cur_Info(channel)) < 0)
{
print_msg(PRT_DEBUG_CS,"Invalid Channel No. %d\n",channel);
}
if ((RetCode = append_Old_Info(String)) < 0)
return RetCode;
}
else
{
if ((RetCode = add_Cur_Info(channel,String)) < 0)
return RetCode;
}
return 0;
}
/****************************************************************************/
int del_Cur_Info(int channel)
{
if (Cur_Info == NULL || Cur_Info[channel] == NULL ||
channel >= Cur_Info_Size || channel < 0 )
return -1;
free(Cur_Info[channel]);
Cur_Info[channel] = NULL;
return 0;
}
/****************************************************************************/
int append_Old_Prints(char *String)
{
int Cnt = 0;
if (Old_Prints == NULL)
if ((Old_Prints = (char**) calloc(xlog,sizeof(char*))) == NULL)
return NO_MEMORY;
while(Cnt < xlog && Old_Prints[Cnt] != NULL)
Cnt++;
if (Cnt == xlog)
{
Cnt = 1;
if (Old_Prints[0] != NULL)
free(Old_Prints[0]);
while(Cnt < xlog)
{
Old_Prints[Cnt-1] = Old_Prints[Cnt];
Cnt++;
}
Cnt = xlog - 1;
}
if ((Old_Prints[Cnt] = (char*) calloc(strlen(String)+1,sizeof(char))) == NULL)
return NO_MEMORY;
else
strcpy(Old_Prints[Cnt],String);
return 0;
}
/****************************************************************************/
int append_Old_Info(char *String)
{
int Cnt = 0;
if (Old_Info == NULL)
if ((Old_Info = (char**) calloc(mcalls,sizeof(char*))) == NULL)
return NO_MEMORY;
while(Cnt < mcalls && Old_Info[Cnt] != NULL)
Cnt++;
if (Cnt == mcalls)
{
Cnt = 1;
free(Old_Info[0]);
while(Cnt < mcalls)
{
Old_Info[Cnt-1] = Old_Info[Cnt];
Cnt++;
}
Cnt = mcalls - 1;
}
if ((Old_Info[Cnt] = (char*) calloc(strlen(String)+1,sizeof(char))) == NULL)
return NO_MEMORY;
else
strcpy(Old_Info[Cnt],String);
return 0;
}
/****************************************************************************/
int add_Cur_Info(int channel, char *String)
{
char **Ptr;
if (channel < 0)
return 0;
if (Cur_Info == NULL)
if ((Cur_Info = (char**) calloc(channel + 1,sizeof(char*))) == NULL)
return NO_MEMORY;
else
Cur_Info_Size = channel + 1;
else
if (channel >= Cur_Info_Size)
{
if ((Ptr = (char**) calloc(channel + 1,sizeof(char*))) == NULL)
return NO_MEMORY;
memcpy(Ptr,Cur_Info,Cur_Info_Size*sizeof(char*));
Cur_Info_Size = channel + 1;
free(Cur_Info);
Cur_Info = Ptr;
}
if (Cur_Info[channel] != NULL)
free(Cur_Info[channel]);
if ((Cur_Info[channel] = (char*) calloc(strlen(String)+1,sizeof(char))) == NULL)
return NO_MEMORY;
else
strcpy(Cur_Info[channel],String);
return 0;
}
/****************************************************************************/
int String_For_Output(char* String)
{
char *Ptr;
char *CurPtr;
char NewString[LONG_STRING_SIZE];
strcpy(NewString,String);
CurPtr = NewString;
String[0] = '\0';
while ((Ptr = strtok(CurPtr,"\n\r")) != NULL)
{
CurPtr = NULL;
strcat(String,Ptr);
}
return 0;
}
/****************************************************************************/
int change_channel(int old_chan, int new_chan)
{
int RetCode = 0;
int Cnt;
char tmp_string[SHORT_STRING_SIZE];
char *String = NULL;
static CALL *Info = NULL;
print_msg(PRT_DEBUG_CS,"Will change channel from %d to %d\n",old_chan,new_chan);
if (old_chan < 0 || old_chan >= Cur_Info_Size ||
new_chan < 0 || Cur_Info[old_chan] == NULL )
return -1;
if (old_chan == new_chan)
return 0;
if ((RetCode = Set_Info_Struct(&Info,Cur_Info[old_chan])) < 0)
return RetCode;
if ((String = Build_Call_Info(Info, new_chan)) == NULL)
return -1;
if ((RetCode = del_Cur_Info(old_chan)) != 0)
return RetCode;
if ((RetCode = add_Cur_Info(new_chan,String)) != 0)
return RetCode;
print_msg(PRT_DEBUG_CS,"Change channel from %d to %d\n",old_chan,new_chan);
for(Cnt = first_descr; Cnt < socket_size(sockets); Cnt++)
{
if (sockets[Cnt].waitstatus == WF_NOTHING &&
User_Get_Message(sockets[Cnt].f_username,sockets[Cnt].f_hostname,Info->num[_ME(Info)],0) == 0)
{
sockets[Cnt].msg = MSG_CHANGE_CHAN;
sprintf(tmp_string,"%d%c%d",old_chan,C_DELIMITER,new_chan);
msgcpy(&(sockets[Cnt]),tmp_string,strlen(tmp_string)+1);
if (Write(&(sockets[Cnt])) < 1)
disconnect_client(Cnt);
}
}
return 0;
}
/****************************************************************************/

View File

@ -0,0 +1,811 @@
/* $Id: start_prog.c,v 1.1 1997/03/16 20:58:55 luethje Exp $
*
* ISDN accounting for isdn4linux.
*
* Copyright 1996 by Michael 'Ghandi' Herold,
* 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: start_prog.c,v $
* Revision 1.1 1997/03/16 20:58:55 luethje
* Added the source code isdnlog. isdnlog is not working yet.
* A workaround for that problem:
* copy lib/policy.h into the root directory of isdn4k-utils.
*
* Revision 2.3.27 1996/05/05 20:35:46 akool
*
* Revision 2.21 1996/03/13 11:58:46 akool
*/
#define _START_PROG_C_
#include "isdnlog.h"
#include <pwd.h>
#include <grp.h>
#include <sys/types.h>
/*************************************************************************/
static interval *RootIntervall = NULL;
/** Prototypes ***********************************************************/
static void KillCommand(int);
static int GetArgs(char *, char *[], char *[], int);
static interval *Next_Interval(void);
static int set_user(char *User);
static int set_group(char *Group);
/****************************************************************************/
static int set_user(char *User)
{
struct passwd* Ptr = NULL;
if (User == NULL || User[0] == '\0')
return 0;
setpwent();
while ((Ptr = getpwent()) != NULL)
{
if (!strcmp(Ptr->pw_name,User))
{
endpwent();
return setuid(Ptr->pw_uid);
}
}
endpwent();
return 0;
}
/****************************************************************************/
static int set_group(char *Group)
{
struct group* Ptr = NULL;
if (Group == NULL || Group[0] == '\0')
return 0;
setgrent();
while ((Ptr = getgrent()) != NULL)
{
if (!strcmp(Ptr->gr_name,Group))
{
endgrent();
return setgid(Ptr->gr_gid);
}
}
endgrent();
return 0;
}
/*************************************************************************
** Ring(-) - Externes Kommando ausfuehren oder loeschen. Bei einem Fehl- **
** er wird -1 zurueckgegeben; ansonsten die PID des neuen **
** Prozesses. Wenn das Kommando mit system() aufgerufen wur- **
** de (Async), wird -1 zurueckgegeben, da die PID nicht ge- **
** sichert werden muss. **
*************************************************************************
** Die : <= 0 Kommando ausfuehren. **
** > 0 PID killen. **
** Async: == 1 Kommando mit system() starten. **
** == 0 Kommando mit eigenem Prozess starten. **
*************************************************************************/
int Ring(info_args *Cmd, char *Opts[], int Die, int Async)
{
char Command[SHORT_STRING_SIZE + 1];
char String[LONG_STRING_SIZE];
int filedes[2];
char *Args[64];
pid_t pid;
FILE *fp;
print_msg(PRT_DEBUG_EXEC, "Ring: Cmd: '%s' Die: %d Async: %d\n", (Cmd&&Cmd->infoarg)?Cmd->infoarg:"NO COMMAND", Die, Async);
if (Die <= 0)
{
sprintf(Command,"%.*s",SHORT_STRING_SIZE-6,Cmd->infoarg);
/* Kommando soll gestartet werden - 'Async' gibt an, ob dieses */
/* mit system() oder mit einem eigenen Prozeß aufgerufen wer- */
/* den soll. */
if (GetArgs(Command,Args,Opts,64) == -1)
{
print_msg(PRT_ERR, "Can't start \"%s\" with execvp().\n", Args[0]);
return -1;
}
pipe(filedes);
switch (pid = fork())
{
case -1: print_msg(PRT_ERR, "%s\n", "Can't start fork()!");
return 0;
break;
case 0: if (paranoia_check(Args[0]) < 0)
exit(-1);
if (set_group(Cmd->group) < 0)
{
print_msg(PRT_ERR, "Can not set group %s: %s\n",Cmd->group,strerror(errno));
exit(-1);
}
if (set_user(Cmd->user) < 0)
{
print_msg(PRT_ERR, "Can not set user %s: %s\n",Cmd->user,strerror(errno));
exit(-1);
}
dup2(filedes[1],STDOUT_FILENO);
dup2(filedes[1],STDERR_FILENO);
execvp(Args[0], Args);
print_msg(PRT_ERR, "Can't start \"%s\" with execvp().\n", Args[0]);
/* Alarm(); */
exit(-1);
break;
}
fp = fdopen(filedes[0],"r");
close(filedes[1]);
print_msg(PRT_DEBUG_INFO, "Program \"%s\" \"%s\" started %ssynchronous.\n", Args[0], Args[1], (Async?"a":""));
if (Async == 1)
{
while(fgets(String,LONG_STRING_SIZE,fp) != NULL)
print_msg(PRT_PROG_OUT,"%s\n",String);
waitpid(pid,NULL,0);
fclose(fp);
return(0);
}
else
{
int sock;
if (add_socket(&sockets,filedes[0]))
return NO_MEMORY;
sock = socket_size(sockets)-1;
sockets[sock].fp = fp;
sockets[sock].pid = pid;
return sock;
}
}
else
{
KillCommand(Die);
return 0;
}
return(-1);
}
/*************************************************************************
** GetArgs(-) - Zerlegt eine Kommandozeile in einzelne Argumente. **
*************************************************************************/
static int GetArgs(char *Line, char *Args[], char *Opts[], int MaxArgs)
{
char *Arg = NULL;
char *Use = Line;
char *Ptr = NULL;
char *Ptr2 = NULL;
char *Org_Arg;
int MaxOpts= 0;
int i = 0;
int j = 0;
int Num = 0;
char HelpString[SHORT_STRING_SIZE];
static char **MemPtr = NULL;
if (MemPtr != NULL)
{
while(MemPtr[j] != NULL)
free(MemPtr[j++]);
free(MemPtr);
MemPtr = NULL;
j = 0;
}
while (Opts[MaxOpts] != NULL)
MaxOpts++;
while ((Org_Arg = Arg = strtok(Use, " \t")))
{
Use = NULL;
if (*Arg == '@')
{
FILE *fp = fopen(Arg+1,"r");
if (fp != NULL)
{
fgets(HelpString,SHORT_STRING_SIZE,fp);
if (*HelpString != '\0')
HelpString[strlen(HelpString)-1] = '\0';
Arg = strdup(HelpString);
MemPtr = (char**) realloc(MemPtr,sizeof(char*)*(j+2));
MemPtr[j++] = Arg;
MemPtr[j] = NULL;
fclose(fp);
}
else
Arg = NULL;
}
else
if (*Arg == '$')
{
if (Opts != NULL && (Num = atoi(Arg+1)) > 0 && Num <= MaxOpts)
Arg = Opts[Num-1];
else
if (strlen(Arg) > 3 && Arg[1] == '{' && (Ptr = strrchr(Arg,'}')) != NULL)
{
*Ptr = '\0';
if ((Ptr2 = getenv(To_Upper(Arg+2))) != NULL)
{
strcpy(HelpString,Ptr2);
strcat(HelpString,Ptr+1);
Arg = strdup(HelpString);
MemPtr = (char**) realloc(MemPtr,sizeof(char*)*(j+2));
MemPtr[j++] = Arg;
MemPtr[j] = NULL;
}
else
Arg = NULL;
}
else
Arg = getenv(To_Upper(Arg+1));
}
if (Arg == NULL || *Arg == '\0')
{
if (Arg == NULL)
print_msg(PRT_WARN,"Invalid argument `%s' for program start!\n",Org_Arg);
Arg = "?";
}
Ptr = Arg;
while((Ptr = Check_Quote(Ptr, S_QUOTES, QUOTE_DELETE)) != NULL && Ptr[0] != '\0')
Ptr++;
if (i < MaxArgs) Args[i++] = Arg;
}
Args[i] = NULL;
return(i);
}
/*************************************************************************
** KillCommand(-) - Beendet ein Programm anhand seiner PID. **
*************************************************************************/
static void KillCommand(int sock)
{
char String[LONG_STRING_SIZE] = "";
/* Kein Erbarmen - Alles was uns zwischen die Finger kommt wird */
/* gelöscht :-) */
if (sock > 0)
{
while (fgets(String,LONG_STRING_SIZE,sockets[sock].fp))
print_msg(PRT_PROG_OUT,"%s\n",String);
kill(sockets[sock].pid, SIGTERM);
kill(sockets[sock].pid, SIGKILL);
/* ACHTUNG: Die naechste Zeile kann schwierigkeiten machen!!!
Der Prozess kann eventuell hier haengen bleiben. Dann Zeile
auskommentieren. Ich weiss nicht, ob kill den Prozess auch
sauber beendet. Damit keine Zombies rumfahren vorsichtshaber
der waitpid.
Alternativ: waitpid(sockets[sock].pid,NULL,WNOHANG) */
waitpid(sockets[sock].pid,NULL,0);
fclose(sockets[sock].fp);
del_socket(&sockets,sock);
}
}
/*************************************************************************
** Alarm(-) - Gibt ein Alarmsignal über den internen Lautsprecher aus. **
*************************************************************************/
void Alarm(void)
{
#ifdef ALARM
int FD;
int i;
if ((FD = open("/dev/console", O_WRONLY)) == -1) FD = 0;
for (i = 0; i < 30; i++)
{
ioctl(FD, KIOCSOUND, (3000 - (i * 10)));
usleep((1 * 1000));
}
ioctl(FD, KIOCSOUND, 0);
#endif
}
/*************************************************************************
** CheckTime(-) - Prüft ob die Zeitangabe in den lokalen Zeitrahmen **
** fällt. Rückgabe ist TRUE/FALSE. **
*************************************************************************/
int CheckTime(char *Line)
{
char Temp[SHORT_STRING_SIZE + 1];
char Time[24];
char *Use;
struct tm *tm_Time;
char *Arg;
char *Minus;
int i;
int r;
int Beg;
int End;
time_t Local;
if (Line == NULL || *Line == '\0')
return 1;
strncpy(Temp, Line, SHORT_STRING_SIZE);
for (i = 0; i < 24; i++) Time[i] = 0;
Use = Temp;
/* Zeile in die einzelnen Komponenten trennen, die durch ',', */
/* ' ' oder ';' voneinander getrennt sein können. */
while ((Arg = strtok(Use, ", ;")))
{
Use = NULL;
if (*Arg == '*')
return 1;
if (!isdigit(*Arg))
{
print_msg(PRT_WARN, " Wrong time in `%s`: \"%s\"\n", CONFFILE, Arg);
continue;
}
if ((Minus = strchr(Arg, '-')))
{
*Minus++ = 0;
Beg = atoi(Arg);
End = atoi(Minus);
}
else
{
Beg = atoi(Arg);
End = Beg+1;
}
if ((Beg < 0) || (End < 0) || (Beg > 24) || (End > 25))
{
print_msg(PRT_WARN, "Time range not correct in `%s`: (%d-%d)\n", CONFFILE, Beg, End);
}
else
{
if (End <= Beg)
End += 24;
for (r = Beg; r < End; r++) Time[r%24] = 1;
}
}
/* Lokale Zeit errechnen und mit den Stunden im Zeitarray ver- */
/* gleichen. */
Local = time(NULL);
if ((tm_Time = localtime(&Local)) != NULL)
{
if (Time[tm_Time->tm_hour] == 1)
return(1);
}
else print_msg(PRT_ERR, "Can't get local time.\n");
return(0);
}
/****************************************************************************/
int Print_Cmd_Output( int sock )
{
char String[LONG_STRING_SIZE] = "";
if (feof(sockets[sock].fp))
{
KillCommand(sock);
return -1;
}
fgets(String,LONG_STRING_SIZE,sockets[sock].fp);
print_msg(PRT_PROG_OUT,"%s\n",String);
return 0;
}
/****************************************************************************/
int Get_Sock_From_Info_Args( info_args *Ptr, int Cnt )
{
if (socket_size(sockets) > Cnt || Cnt < 0)
while (sockets[Cnt].descriptor != -2)
if (sockets[Cnt].info_arg == Ptr)
return Cnt;
else
Cnt++;
return -1;
}
/****************************************************************************/
int Get_Sock_From_Call( int chan, int Cnt )
{
if (socket_size(sockets) > Cnt || Cnt < 0)
while (sockets[Cnt].descriptor != -2)
if (sockets[Cnt].chan == chan)
return Cnt;
else
Cnt++;
return -1;
}
/****************************************************************************/
int Get_Sock_From_Call_And_Info_Args( int chan, info_args *Ptr, int Cnt )
{
if (socket_size(sockets) > Cnt || Cnt < 0)
while (sockets[Cnt].descriptor != -2)
if (sockets[Cnt].chan == chan && sockets[Cnt].info_arg == Ptr)
return Cnt;
else
Cnt++;
return -1;
}
/****************************************************************************/
int Condition_Changed( int condition, int flag )
{
if ((flag & RING_CONNECT) || (flag & RING_RING))
{
if ((flag & RING_CONNECT) && condition == RING_CONNECT)
return 0;
if ((flag & RING_CONNECT) && condition == RING_AOCD)
return 0;
if ((flag & RING_CONNECT) && condition == RING_ERROR)
return 0;
if ((flag & RING_RING) && condition == RING_RING)
return 0;
if ((flag & RING_RING) && condition == RING_ERROR)
return 0;
return 1;
}
return 0;
}
/****************************************************************************/
const char *Set_Ringer_Flags( int condtion, int InOut )
{
char Char = 0;
static char RetCode[10];
if (InOut & RING_INCOMING) Char = 'I';
else
if (InOut & RING_OUTGOING) Char = 'O';
else
{
print_msg(PRT_ERR, "Error: Expected flag `I' or `O'!\n");
return NULL;
}
RetCode[0] = Char;
if (condtion & RING_RING ) Char = 'R';
else
if (condtion & RING_CONNECT ) Char = 'C';
else
if (condtion & RING_BUSY ) Char = 'B';
else
if (condtion & RING_AOCD ) Char = 'A';
else
if (condtion & RING_ERROR ) Char = 'E';
else
if (condtion & RING_HANGUP ) Char = 'H';
else
if (condtion & RING_KILL ) Char = 'K';
else
if (condtion & RING_SPEAK ) Char = 'S';
else
if (condtion & RING_PROVIDER) Char = 'P';
else
{
print_msg(PRT_ERR, "Internal error: Unknown flag %d for flag -S!\n",condtion);
return NULL;
}
RetCode[1] = Char;
RetCode[2] = '\0';
return RetCode;
}
/****************************************************************************/
int Start_Interval(void)
{
interval *Ptr = RootIntervall;
time_t cur_time = time(NULL);
int RetCode = 0;
while (Ptr != NULL)
{
if (Ptr->next_start <= cur_time)
{
RetCode += Start_Ring(Ptr->chan, Ptr->infoarg, Ptr->event, RING_INTERVAL);
Ptr->next_start = cur_time + Ptr->infoarg->interval;
}
Ptr = Ptr->next;
}
return RetCode;
}
/****************************************************************************/
static interval *Next_Interval(void)
{
interval *Ptr = RootIntervall;
interval *RetCode = NULL;
time_t next_time = 0;
while (Ptr != NULL)
{
if (next_time == 0 || Ptr->next_start < next_time)
{
next_time = Ptr->next_start;
RetCode = Ptr;
}
Ptr = Ptr->next;
}
return RetCode;
}
/****************************************************************************/
struct timeval *Get_Interval(int Sec)
{
static struct timeval timeout;
interval *Ptr = NULL;
timeout.tv_usec = 0;
if (Sec < 0)
Sec = 0;
if ((Ptr = Next_Interval()) != NULL || Sec != 0)
{
if (Ptr != NULL && (timeout.tv_sec = (int) (Ptr->next_start - time(NULL))) < 0)
timeout.tv_sec = 0;
else if (Sec)
/* if (Sec != 0 && Sec < timeout.tv_sec) AK:06-Jun-96 */
timeout.tv_sec = Sec;
}
else
return NULL;
return &timeout;
}
/****************************************************************************/
int Del_Interval(int chan, info_args *infoarg)
{
interval **Ptr = &RootIntervall;
interval *Ptr2;
while (*Ptr != NULL)
{
if ((*Ptr)->infoarg == infoarg && (*Ptr)->chan == chan)
{
Ptr2 = (*Ptr)->next;
free(*Ptr);
*Ptr = Ptr2;
return 0;
}
Ptr = &((*Ptr)->next);
}
return -1;
}
/****************************************************************************/
int New_Interval(int chan, info_args *infoarg, int event)
{
interval **Ptr = &RootIntervall;
if (infoarg->interval == 0)
return -1;
while (*Ptr != NULL)
Ptr = &((*Ptr)->next);
if ((*Ptr = (interval*) calloc(1,sizeof(interval))) == NULL)
return -1;
(*Ptr)->event = event;
(*Ptr)->infoarg = infoarg;
(*Ptr)->chan = chan;
(*Ptr)->next_start = infoarg->interval + time(NULL);
return 0;
}
/****************************************************************************/
int Start_Process(int chan, info_args *infoarg, int event)
{
char *Opts[4];
int InOut = call[chan].dialin?RING_INCOMING:RING_OUTGOING;
int sock = -1;
Opts[0] = (char*) Set_Ringer_Flags(event,InOut);
Opts[1] = call[chan].num[CALLING];
Opts[2] = call[chan].num[CALLED];
Opts[3] = NULL;
if ((infoarg->flag & event) && (infoarg->flag & InOut) &&
CheckTime(infoarg->time) && /* wenn die angegebene Zeit passt */
(sock = Ring(infoarg, Opts, 0, 0)) != -1 )
{
sockets[sock].info_arg = infoarg;
sockets[sock].chan = chan;
sockets[sock].call_event = event;
}
return sock<0?-1:0;
}
/****************************************************************************/
int Start_Ring(int chan, info_args *infoarg, int event, int intervalflag)
{
int ProcessStarted = 0;
char *Opts[4];
int InOut = call[chan].dialin?RING_INCOMING:RING_OUTGOING;
int f = infoarg->flag; /* die Flags zu diesem Eintrag */
int sock = 0;
Opts[0] = (char*) Set_Ringer_Flags(event,InOut);
Opts[1] = call[chan].num[CALLING];
Opts[2] = call[chan].num[CALLED];
Opts[3] = NULL;
if (intervalflag & RING_INTERVAL)
{
if (f & RING_KILL)
while ((sock = Get_Sock_From_Call_And_Info_Args(chan,infoarg,sock)) != -1)
if (sockets[sock].call_event == event)
Ring(NULL, NULL, sock++, 0);
else
sock++;
}
else
{
if (infoarg->interval != 0 && (event == RING_RING || event == RING_CONNECT))
New_Interval(chan, infoarg, event);
}
if (Condition_Changed(event,f))
{
while ((sock = Get_Sock_From_Call_And_Info_Args(chan,infoarg,sock)) != -1)
Ring(NULL, NULL, sock++, 0);
Del_Interval(chan,infoarg);
}
/* Wenn Event (siehe oben) passt, und INCOMING/OUTGOING passen */
if (!((f & RING_UNIQUE) &&
((event == RING_RING) || (event == RING_CONNECT) )) ||
Get_Sock_From_Call_And_Info_Args(chan,infoarg,0) == -1 )
{
if ((f & event) && (f & InOut) &&
CheckTime(infoarg->time) && /* wenn die angegebene Zeit passt */
(sock = Ring(infoarg, Opts, 0, 0)) != -1 )
{
sockets[sock].info_arg = infoarg;
sockets[sock].chan = chan;
sockets[sock].call_event = event;
ProcessStarted++;
}
}
return ProcessStarted;
}
/****************************************************************************/
int Change_Channel_Ring( int old_channel, int new_channel)
{
interval *Ptr = RootIntervall;
int sock = 0;
while ((sock = Get_Sock_From_Call( old_channel, sock )) >= 0)
{
sockets[sock].chan = new_channel;
}
while (Ptr != NULL)
{
if (Ptr->chan == old_channel)
Ptr->chan = new_channel;
Ptr = Ptr->next;
}
return 0;
}
/****************************************************************************/

View File

@ -0,0 +1,96 @@
#include "isdnlog.h"
void test_center (void)
{
#if 0
char File[256];
int Cnt = 20000;
sprintf(File,"%s%c%s",confdir(),C_SLASH,USERFILE);
while(Cnt--)
{
utime(File,NULL);
/* sleep(1); */
if (read_user_access() != 0)
Exit(-1);
if (write_user_access() != 0)
Exit(-1);
}
#elif 0
int Cnt = 200000;
int Max = 0;
int add = 0, del = 0;
while (Cnt--)
{
if (socket_size(sockets) == 0 || rand() % 2)
{
add++;
add_socket(&sockets,open("/dev/null",O_WRONLY));
if (socket_size(sockets) > Max) Max = socket_size(sockets);
}
else
{
del++;
del_socket(&sockets,rand() % socket_size(sockets));
}
}
printf("Max: %d, del: %d, add: %d, RAND_MAX: %d\n",Max,del,add,RAND_MAX);
Exit(-2);
#elif 0
char User[256];
char Host[256];
if (read_user_access() != 0)
Exit(-1);
scanf("%s",User);
scanf("%s",Host);
printf("User:*%s*\n",User);
printf("Host:*%s*\n",Host);
if (user_has_access(User,Host) == -1)
printf("Rejected\n");
else
printf("Accepted\n");
Exit(-3);
/* Problem: Wenn Hosts vom Internet in der user-Datei sind, werden
diese beim Start von isdnlog auf Gueltigkeit geprueft
Loesung: Eintrag dieser Hosts in die /etc/hosts */
/* Problem: Wenn Jeder Erdenbuerger von seiner Maschine Zugriff
auf meine Maschine haben soll */
#elif 0
char User[256];
char Host[256];
char MSN[256];
int Flag;
if (read_user_access() != 0)
Exit(-1);
scanf("%s",User);
scanf("%s",Host);
scanf("%s",MSN);
scanf("%d",&Flag);
printf("User:*%s*\n",User);
printf("Host:*%s*\n",Host);
printf("MSN :*%s*\n",MSN);
printf("Flag:*%d*\n",Flag);
if (User_Get_Message(User,Host,MSN,Flag) == -1)
printf("Rejected\n");
else
printf("Accepted\n");
Exit(-3);
#elif 1
readconfig("isdnlog");
Exit(-4);
#endif
}

File diff suppressed because it is too large Load Diff

485
isdnlog/isdnrep/cheap.c Normal file
View File

@ -0,0 +1,485 @@
/* $Id: cheap.c,v 1.1 1997/03/16 20:59:02 luethje Exp $
*
* ISDN accounting for isdn4linux. (Feiertagsberechnung)
*
* Copyright 1995, 1997 by Andreas Kool (akool@Kool.f.EUnet.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: cheap.c,v $
* Revision 1.1 1997/03/16 20:59:02 luethje
* Added the source code isdnlog. isdnlog is not working yet.
* A workaround for that problem:
* copy lib/policy.h into the root directory of isdn4k-utils.
*
*
* Revision 2.6.24 1997/01/12 20:51:21 akool
* City Weekend Tarif implemented (Thanks to Oliver Schoett <schoett@muc.de>)
*
* Revision 2.6.11 1996/12/30 10:05:21 Ad Aerts <ad@aasup.nl>
* Dutch accounting
*
* Revision 2.50 1996/08/24 10:47:21 akool
* Korrektur bei Taktberechnung Wochenende/Feiertage (Jochen Heuer)
*
* Revision 2.43 1996/07/04 09:52:21 akool
* Korrektur bei Taktberechnung City (Jochen Heuer)
*
* Revision 2.40 1996/06/19 01:55:21 akool
* Neue Tarife ab 1.7.96 implementiert
*
* Revision 2.3.27 1996/05/06 17:51:21 akool
* Korrektur bei Taktberechnung Regio 200
*
* Revision 2.01 1996/01/19 19:12:21 akool
* Korrektur bei Taktberechnung (Citytarif, 5:00 .. 9:00 war 240s, muss
* aber 150s heissen!)
*
* Revision 2.00 1996/01/10 20:10:21 akool
*
* Revision 1.22 1995/10/21 17:23:21 akool
* Tarife 1996 entsprechend Telekom-Unterlagen korrigiert
*
* Revision 1.14 1995/10/05 19:02:21 akool
* Ueberschreitung verschiedener Zeittakte bei einer Verbindung implementiert.
*
* Revision 1.2 1995/09/30 16:39:21 akool
* Um neue Tarifstruktur der Telekom ab 1.1.96 erweitert
* First public release
*
* Revision 1.1 1990/11/10 23:15:11 akool
* Initial revision (Code-Teile aus irgend einer alten c't)
*
*/
#include "isdnrep.h"
#define MUTT 3
#define KARF 4
#define OST1 5
#define OST2 6
#define CHRI 7
#define PFI1 8
#define PFI2 9
#define FRON 10
#define EINH 11
#define MARI 12
#define ALLE 13
#define BUSS 14
#define A_FEI 17
struct w_ftag {
char tag;
char monat;
char telekom; /* TRUE, wenn auch fuer die Deutsche Telekom ein Feiertag (siehe Telefonbuch!) */
};
static struct {
int tag;
int monat;
int jahr;
int tgind;
} _datum;
static char tab_tage[2][12] = {{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }};
static struct w_ftag t_ftag[A_FEI] = {
#ifdef ISDN_NL
{ 1, 1, 1 }, /* Neujahr */
{ 6, 1, 0 }, /* Erscheinungsfest - nur Baden-Wuerttemberg und Bayern */
{ 1, 5, 0 }, /* Maifeiertag */
{ 0, 0, 0 }, /* Muttertag */
{ 0, 0, 0 }, /* Karfreitag */
{ 0, 0, 1 }, /* Ostersonntag */
{ 0, 0, 1 }, /* Ostermontag */
{ 0, 0, 0 }, /* Christi Himmelfahrt */
{ 0, 0, 1 }, /* Pfingstsonntag */
{ 0, 0, 1 }, /* Pfingstmontag */
{ 0, 0, 0 }, /* Fronleichnam - nur in Baden-Wuerttemberg, Bayern, Hessen, Nordrhein-Westfalen, Rheinland-Pfalz und im Saarland */
{ 3, 10, 0 }, /* Tag der deutschen Einheit - vor 1990 am 17.6. */
{ 15, 8, 0 }, /* Maria Himmelfahrt - nur Saarland und ueberwiegend katholischen Gemeinden Bayerns */
{ 1, 11, 0 }, /* Allerheiligen - nur Baden-Wuerttemberg, Bayern, Nordrhein-Westfalen, Rheinland-Pfalz und im Saarland */
{ 0, 0, 0 }, /* Buss- und Bettag - nur bis incl. 1994 (wg. Pflegeversicherung abgeschafft) */
{ 25, 12, 1 }, /* 1. Weihnachtsfeiertag */
{ 26, 12, 1 }}; /* 2. Weihnachtsfeiertag */
#else
{ 1, 1, 1 }, /* Neujahr */
{ 6, 1, 0 }, /* Erscheinungsfest - nur Baden-Wuerttemberg und Bayern */
{ 1, 5, 1 }, /* Maifeiertag */
{ 0, 0, 1 }, /* Muttertag */
{ 0, 0, 1 }, /* Karfreitag */
{ 0, 0, 1 }, /* Ostersonntag */
{ 0, 0, 1 }, /* Ostermontag */
{ 0, 0, 1 }, /* Christi Himmelfahrt */
{ 0, 0, 1 }, /* Pfingstsonntag */
{ 0, 0, 1 }, /* Pfingstmontag */
{ 0, 0, 0 }, /* Fronleichnam - nur in Baden-Wuerttemberg, Bayern, Hessen, Nordrhein-Westfalen, Rheinland-Pfalz und im Saarland */
{ 3, 10, 1 }, /* Tag der deutschen Einheit - vor 1990 am 17.6. */
{ 15, 8, 0 }, /* Maria Himmelfahrt - nur Saarland und ueberwiegend katholischen Gemeinden Bayerns */
{ 1, 11, 0 }, /* Allerheiligen - nur Baden-Wuerttemberg, Bayern, Nordrhein-Westfalen, Rheinland-Pfalz und im Saarland */
{ 0, 0, 0 }, /* Buss- und Bettag - nur bis incl. 1994 (wg. Pflegeversicherung abgeschafft) */
{ 25, 12, 1 }, /* 1. Weihnachtsfeiertag */
{ 26, 12, 1 }}; /* 2. Weihnachtsfeiertag */
#endif
static int schalt(register int j)
{
return(((j % 4 == 0) && (j % 100 != 0)) || (j % 400 == 0));
} /* schalt */
static int tag_num(register int t, register int m, register int j)
{
register char *tm = tab_tage[schalt(j)];
while (--m)
t += *tm++;
return(t);
} /* tag_num */
static void num_tag(int jahr, int lfd)
{
register int i;
register char *t;
while (lfd < 1)
lfd += tag_num(31, 12, --jahr);
t = tab_tage[schalt(jahr)];
for (i = 1; lfd > *t && i < 13; i++)
lfd -= *t++;
if (i > 12)
num_tag(++jahr, lfd);
else {
_datum.monat = i;
_datum.tag = lfd;
_datum.jahr = jahr;
} /* else */
} /* num_tag */
static void comp_feier_tage(int jj)
{
static struct w_ftag t_stag[A_FEI];
static int firsttime = 1;
static int l_jj = -1;
register int mm, tt, i, j, a, b;
if (jj == l_jj)
return;
l_jj = jj;
if (firsttime) {
for (i = 0; i < A_FEI; i++)
t_stag[i] = t_ftag[i];
firsttime = 0;
}
else
for (i = 0; i < A_FEI; i++)
t_ftag[i] = t_stag[i];
/* Berechnung von Ostern nach C.F.Gauss */
i = jj / 100 - jj / 400 + 4;
j = i - jj / 300 + 11;
a = (((jj % 19) * 19) + j) % 30;
b = (((jj % 4) * 2 + (4 * jj) + (6 * a) + i) % 7) + a - 9;
if (b < 1) {
tt = 31 + b;
mm = 3;
}
else {
if ((b == 26) || ((a == 28) && (b == 25) && ((11 * (j + 1) % 30) < 19)))
b -= 7;
tt = b;
mm = 4;
} /* else */
num_tag(jj, tag_num(tt, mm, jj));
t_ftag[OST1].monat = _datum.monat; t_ftag[OST1].tag = _datum.tag;
num_tag(jj, 1 + tag_num(_datum.tag, _datum.monat, jj));
t_ftag[OST2].monat = _datum.monat; t_ftag[OST2].tag = _datum.tag;
num_tag(jj, - 3 + tag_num(_datum.tag, _datum.monat, jj));
t_ftag[KARF].monat = _datum.monat; t_ftag[KARF].tag = _datum.tag;
/* Pfingsten */
num_tag(jj, 51 + tag_num(_datum.tag, _datum.monat, jj));
t_ftag[PFI1].monat = _datum.monat; t_ftag[PFI1].tag = _datum.tag;
num_tag(jj, 1 + tag_num(_datum.tag, _datum.monat, jj));
t_ftag[PFI2].monat = _datum.monat; t_ftag[PFI2].tag = _datum.tag;
/* Himmelfahrt */
num_tag(jj, -10 + tag_num(t_ftag[PFI1].tag, t_ftag[PFI1].monat, jj));
t_ftag[CHRI].monat = _datum.monat; t_ftag[CHRI].tag = _datum.tag;
/* Fronleichnam */
num_tag(jj, 11 + tag_num(t_ftag[PFI1].tag, t_ftag[PFI1].monat, jj));
t_ftag[FRON].monat = _datum.monat; t_ftag[FRON].tag = _datum.tag;
} /* comp_feier_tage */
static int billig(time_t when)
{
register int i;
auto struct tm *tm;
tm = localtime(&when);
if (tm->tm_wday == 6) /* Samstag immer */
return(1);
if (tm->tm_wday == 0) /* Sonntag immer */
return(1);
if ((tm->tm_hour > 17) || (tm->tm_hour < 8)) /* zwischen 18:00 .. 7:59 immer */
return(1);
#ifndef ISDN_NL
if ((tm->tm_mday == 24) && (tm->tm_mon == 11)) /* Heilig-Abend immer */
return(1);
if ((tm->tm_mday == 31) && (tm->tm_mon == 11)) /* Sylvester immer */
return(1);
comp_feier_tage(tm->tm_year + 1900);
for (i = 0; i < A_FEI; i++)
if ((t_ftag[i].monat == tm->tm_mon + 1) &&
(t_ftag[i].tag == tm->tm_mday) &&
t_ftag[i].telekom)
return(1);
#endif
return(0); /* Sorry, it's expensive! */
} /* billig */
double cheap(time_t when, int zone)
{
auto double takt = 0.0;
#ifdef ISDN_NL
switch (zone) {
case 1 : takt = 1.000; break; /* local tariff Dfl 0.066/min */
case 2 : takt = 0.316; break; /* long distance Dfl 0.2106/min */
case 3 : takt = 0.074; break; /* International Dfl 0.90/min */
case 4 : takt = 0.070; break; /* International Dfl 0.95/min */
case 5 : takt = 0.060; break; /* International Dfl 1.10/min */
} /* switch */
if (billig(when)) {
takt *= 2.0;
} /* if */
#else
switch (zone) {
case 1 : takt = 360.00; break;
case 2 : takt = 60.00; break;
case 3 : takt = 21.00; break;
case 4 : takt = 21.00; break;
case 5 : takt = 12.00; break;
} /* switch */
if (billig(when)) {
if (takt == 12.00)
takt = 16.00;
else
takt *= 2.0;
} /* if */
#endif
return(takt);
} /* cheap */
double cheap96(time_t when, int zone, int *zeit)
{
#ifdef ISDN_NL
*zeit = 0;
return(cheap(when, zone));
#else
register int i, takt = 0;
auto struct tm *tm;
/* neue Tarife aus: iX 10/95, Pg 32 */
static double gebuehr[3][5][5] =
{{{ 90.00, 90.00, 150.00, 240.00, 240.00 }, /* City */
{ 26.00, 30.00, 45.00, 60.00, 120.00 }, /* Region 50 */
{ 12.00, 13.50, 21.50, 30.00, 120.00 }, /* Region 200 */
{ 11.50, 12.50, 20.00, 25.00, 120.00 }, /* Fern */
{ 30.00, 30.00, 30.00, 30.00, 30.00 }}, /* Angrenzende Laender */
/* Tarife, Wochenendtarife ab 1.7.96 */
{{ 90.00, 90.00, 150.00, 240.00, 240.00 }, /* City */
{ 26.00, 30.00, 45.00, 60.00, 120.00 }, /* Region 50 */
{ 13.00, 14.00, 22.50, 36.00, 120.00 }, /* Region 200 */
{ 12.00, 13.50, 21.50, 30.00, 120.00 }, /* Fern */
{ 26.00, 30.00, 45.00, 60.00, 60.00 }}, /* Vis-'a-vis 1 */
/* Tarife vom 27.-30.12., Feiertagstarife ab 1.7.96 */
{{ 90.00, 90.00, 150.00, 240.00, 240.00 }, /* City */
{ 36.00, 36.00, 45.00, 60.00, 120.00 }, /* Region 50 */
{ 36.00, 36.00, 36.00, 36.00, 120.00 }, /* Region 200 */
{ 36.00, 36.00, 36.00, 36.00, 120.00 }, /* Fern */
{ 26.00, 30.00, 45.00, 60.00, 60.00 }}}; /* Vis-'a-vis 1 */
/* Takt: 1 2 3 4 5
Werktag :
1 = Vormittag 9:00 .. 12:00
2 = Nachmittag 12:00 .. 18:00
3 = Freizeit 18:00 .. 21:00, 5:00 .. 9:00
4 = Mondschein 21:00 .. 2:00
5 = Nacht 2:00 .. 5:00
Wochenende/Feiertag :
3 = Freizeit 5:00 .. 21:00
4 = Mondschein 21:00 .. 5:00
*/
tm = localtime(&when);
if ((tm->tm_wday == 6) || (tm->tm_wday == 0)) { /* Samstag/Sonntag */
if ((tm->tm_hour > 4) && (tm->tm_hour < 21)) {
if (CityWeekend && (zone == 1))
takt = 4;
else
takt = 3;
}
else
takt = 4;
} /* if */
if ((tm->tm_mday == 24) && (tm->tm_mon == 11)) /* Heilig-Abend */
takt = 6;
if ((tm->tm_mday == 31) && (tm->tm_mon == 11)) /* Sylvester */
takt = 6;
comp_feier_tage(tm->tm_year + 1900);
for (i = 0; i < A_FEI; i++)
if ((t_ftag[i].monat == tm->tm_mon + 1) &&
(t_ftag[i].tag == tm->tm_mday) &&
t_ftag[i].telekom)
takt = 6;
if ((!takt) || (zone == 5)) {
if ((tm->tm_hour > 8) && (tm->tm_hour < 12))
takt = 1;
else if ((tm->tm_hour > 11) && (tm->tm_hour < 18))
takt = 2;
else if ((tm->tm_hour > 20) || (tm->tm_hour < 2))
takt = 4;
else if ((tm->tm_hour > 1) && (tm->tm_hour < 5))
takt = 5;
else
takt = 3;
} /* if */
if (((tm->tm_year > 95) && (tm->tm_mon > 5)) ||
(tm->tm_year > 96)) { /* Neuer Tarif ab 1.7.96 */
if ((takt == 6) && (zone < 5)) { /* Feiertage */
if ((tm->tm_hour > 4) && (tm->tm_hour < 21)) {
if (CityWeekend && (zone == 1)) {
*zeit = 8;
return(gebuehr[2][zone - 1][3]);
}
else
return(gebuehr[2][zone - 1][*zeit = 2]);
}
else
return(gebuehr[2][zone - 1][*zeit = 3]);
}
else if ((tm->tm_mon == 11) && /* Werktage vom 27.12. .. 30.12. */
(tm->tm_mday > 26) && (zone < 5)) {
return(gebuehr[2][zone - 1][*zeit = --takt]);
}
else /* Werktage bzw. Wochenenden */
return(gebuehr[1][zone - 1][*zeit = --takt]);
}
else {
if (zone == 5) { /* Angrenzende Laender */
*zeit = 0;
return(30);
}
else {
if (takt == 6) { /* Feiertage */
if ((tm->tm_hour > 4) && (tm->tm_hour < 21)) {
*zeit = 10;
return(gebuehr[0][zone - 1][2]);
}
else
return(gebuehr[0][zone - 1][*zeit = 3]);
}
else
return(gebuehr[0][zone - 1][*zeit = --takt]);
} /* else */
} /* else */
#endif
} /* cheap96 */
#ifdef DEBUG_CHEAP
main()
{
auto time_t cur_time, ltime;
auto struct tm *tm;
auto double o = 0.0, n;
time(&cur_time);
tm = localtime(&cur_time);
tm->tm_sec = 0;
tm->tm_min = 0;
tm->tm_hour = 0;
cur_time = ltime = mktime(tm);
while (cur_time - (7L * 24L * 60L * 60L) < ltime) {
n = cheap96(cur_time, 3);
if (n != o) {
printf("%7.2f %s", n, ctime(&cur_time));
o = n;
} /* if */
cur_time += 1L; /* (60L * 60L); */
} /* while */
} /* main */
#endif

25
isdnlog/isdnrep/isdnrep.1 Normal file
View File

@ -0,0 +1,25 @@
.TH ISDNREP 1 "ISDN Utilities" "AKsoftware" \" -*- nroff -*-
.SH NAME
isdnrep \- Gebuehrenabrechnung
.SH SYNOPSIS
.B isdnrep
[\-anvioN] [\-c Zone] [\-t Zeitabschnitt] [\-f logfile] [\-d Zeit] [\-p MSN]
.SH DESCRIPTION
.BR isdnrep
wertet die von isdnlog(8) gesammelten Informationen aus, und erstellt
ueber einen frei waehlbaren Zeitraum eine Gebuehrenabrechnung.
Fuer weitere Informationen siehe README
.SS OPTIONS
.TP
.I "\-V"
.B isdnrep
Print version information on standard output then exit successfully.
.SH FILES
.BR isdnrep
wertet ohne die Option "-f" die Datei
.BR "/var/log/isdn.log"
aus.
.SH BUGS
Z.Zt. keine bekannt ;-)

1403
isdnlog/isdnrep/isdnrep.c Normal file

File diff suppressed because it is too large Load Diff

41
isdnlog/isdnrep/isdnrep.h Normal file
View File

@ -0,0 +1,41 @@
/* $Id: isdnrep.h,v 1.1 1997/03/16 20:59:08 luethje Exp $
*
* ISDN accounting for isdn4linux.
*
* Copyright 1995, 1997 by Andreas Kool (akool@Kool.f.EUnet.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.
*
*/
#ifndef _ISDNREP_H_
#define _ISDNREP_H_
#define PUBLIC extern
#include <tools.h>
#ifdef _ISDNREP_C_
#define _EXTERN
#else
#define _EXTERN extern
#endif
_EXTERN double cheap96(time_t when, int zone, int *zeit);
_EXTERN double cheap(time_t when, int zone);
#undef _EXTERN
#endif /* _ISDNREP_H_ */

View File

@ -0,0 +1,22 @@
# Konkretes Beispiel fuer eine "isdnlog.conf"
#
# Eine genaue Beschreibung dazu siehe "README", Kapitel 4.2.6
#
MYPREFIX = 0815
PLAYER = /usr/bin/auplay
SOUNDS = /usr/sounds
START = O R L = $PLAYER ${SOUNDS}/unknown_ring.au,,8-14,16-22;\
IOA = $PLAYER ${SOUNDS}/pay.au,,8-14,16-22;\
IOC U = /usr/bin/who_is_it $2 $3;\
IOH = $PLAYER ${SOUNDS}/hangup.au,,8-14,16-22;\
IORAH = $PLAYER ${SOUNDS}/silent.au,,14-16,22-8;
4711 MSN\#1 1 - I RK = $PLAYER ${SOUNDS}/msn1_ring.au,5,8-14,16-22;\
- IOA = $PLAYER ${SOUNDS}/msn1_pay.au,,8-14,16-22;
4712 MSN\#2 1 - I RK = $PLAYER ${SOUNDS}/msn2_ring.au,5,8-14,16-22;
4713 MSN\#3 1 - I RK = $PLAYER ${SOUNDS}/msn3_ring.au,5,8-14,16-22;
*40441777 My_Provider 4 isdn0 OIR = $PLAYER ${SOUNDS}/provider_ring.au;\
OICU = /usr/bin/get.mails.from.provider,300;\
OICU = /usr/bin/get.news.from.provider,1800;

View File

@ -0,0 +1,12 @@
###############################################################################
#
# Generated by isdnlog 2.3.1 on Tue Apr 02 01:02:38 1996
#
###############################################################################
# File: /etc/isdnlog/isdnlog.users
# The empty section "world" means, that everybody from everywhere can connect
# to your isdnlog. Everybody gets all rights. Be careful with this section!
[world]

View File

@ -0,0 +1,28 @@
###############################################################################
#
# Generated by isdnlog 2.3.1 on Tue Apr 02 01:02:38 1996
#
###############################################################################
# File: /etc/isdnlog/isdnlog.users
# The following two lines allow the user "hans" to connect only
# from "machine1.from.nowhere", and the user "lilo" only from
# "machine4.at.home"
hans@machine1.from.nowhere MSN=*; PROTOCOL
lilo@machine4.at.home MSN=4711
# The section below, allow the users "fred" and "root" to access to the isdnlog
# from both machines (machine1.at.home, machine2.at.home).
[ my_first_entry ]
root ALL
@machine2.at.home
fred MSN=8150?,4711; PROTOCOL
@machine3.at.home
[ my_second_entry ]
root MSN=*
peter ADDRESSBOOK
@linux1.from.nowhere

4
isdnlog/samples/reload Executable file
View File

@ -0,0 +1,4 @@
#!/bin/sh
/sbin/rmmod hisax
/sbin/modprobe hisax io=1,2,12,0xd0000,0xd80 HiSax_id=bri1
/sbin/telesctrl bri1 1 4

37
isdnlog/samples/stop Normal file
View File

@ -0,0 +1,37 @@
#!/bin/sh
# very simple reload-example for the new chargemax feature of isdnlog
# this is called by isdnlog every time we get a AOCD and chargesum of
# active device is greater then CHARGEMAX.
# there are three parameter available:
#
# first ($1) is chargesum-CHARGEMAX
# second ($2) is ALIAS as defined in ISDNLOG.CONF
# third ($3) is total chargesum for active device
case "$1" in
'0,00')
echo "WARNING, charge-limit set by CHARGEMAX is reached!" >> /dev/console
echo "$2 is talking to much!" >> /dev/console
/bin/aplay /usr/sounds/attention.au
;;
'0,12')
echo "WARNING, $2 got charge-overflow == $1, total chargesum == $3" >> /dev/console
echo "next chargeint will cause i4l to stop" >> /dev/console
/bin/aplay /usr/sounds/earthdestruction.au
;;
'0,24')
echo "reload got charge-overflow == $1, now i4l will be stopped!" >> /dev/console
/sbin/init.d/i4l stop
;;
'0,36')
echo "aeh, still alive?! so we'll do a reboot!!" >> /dev/console
/bin/aplay /usr/sounds/crash.au
/sbin/reboot
;;
esac
echo "got charge_ov=$1 dev=$2 scharge=$3 " >> /dev/console

692
isdnlog/tools/dbmalloc.h Normal file
View File

@ -0,0 +1,692 @@
/*
* (c) Copyright 1990, 1991, 1992 Conor P. Cahill (cpcahil@virtech.vti.com)
*
* This software may be distributed freely as long as the following conditions
* are met:
* * the distribution, or any derivative thereof, may not be
* included as part of a commercial product
* * full source code is provided including this copyright
* * there is no charge for the software itself (there may be
* a minimal charge for the copying or distribution effort)
* * this copyright notice is not modified or removed from any
* source file
*/
/*
* $Id: dbmalloc.h,v 1.1 1997/03/16 20:59:19 luethje Exp $
*/
#ifndef _DEBUG_MALLOC_INC
#define _DEBUG_MALLOC_INC 1
/*
* __need_size_t is checked by Gnu's stddef.h
*/
#define __need_size_t
#include <stddef.h>
#undef __need_size_t
#ifdef force_cproto_to_use_defines
/*
* these are just here because cproto used the c-preprocessor to generate
* the prototypes and if they were left as #defines the prototypes.h file
* would have the contents of the define, not the define itself
*/
typedef void DATATYPE;
typedef size_t SIZETYPE;
typedef void VOIDTYPE;
typedef void MEMDATA;
typedef size_t MEMSIZE;
typedef int BCOPYSIZE;
typedef size_t STRSIZE;
typedef void FREETYPE;
typedef void EXITTYPE;
#ifdef WRTSIZE
#undef WRTSIZE
#endif
typedef unsigned int WRTSIZE;
/*
* for now, define CONST as const. A sed script in the makefile will change
* this back to CONST in the prototypes.h file.
*/
#define CONST const
#else /* force_cproto_to_use_defines */
/*
* The following entries are automatically added by the Configure script.
* If they are not correct for your system, then Configure is not handling
* your system correctly. Please report this to the author along with
* a description of your system and the correct values
*/
#if (__GNUC__ == 2) && __STDC__
#define VOIDTYPE void
#define CONST const
#define EXITTYPE void
#define DATATYPE void
#define SIZETYPE size_t
#define FREETYPE void
#define MEMDATA void
#define MEMSIZE size_t
#define BCOPYSIZE int
#define MEMCMPTYPE unsigned char
#define STRSIZE size_t
#define STRCMPTYPE unsigned char
#else /* (__GNUC__ == 2) && __STDC__ */
#if (__GNUC__ == 2)
#define VOIDTYPE void
#define CONST
#define EXITTYPE void
#define DATATYPE void
#define SIZETYPE size_t
#define FREETYPE void
#define MEMDATA void
#define MEMSIZE size_t
#define BCOPYSIZE int
#define MEMCMPTYPE unsigned char
#define STRSIZE size_t
#define STRCMPTYPE unsigned char
#else /* (__GNUC__ == 2) */
#if (__GNUC__ == 2) && __STDC__ && __cplusplus
#define VOIDTYPE void
#define CONST const
#define EXITTYPE void
#define DATATYPE void
#define SIZETYPE size_t
#define FREETYPE void
#define MEMDATA void
#define MEMSIZE size_t
#define BCOPYSIZE int
#define MEMCMPTYPE unsigned char
#define STRSIZE size_t
#define STRCMPTYPE unsigned char
#else /* (__GNUC__ == 2) && __STDC__ && __cplusplus */
#if (__GNUC__ == 2) && __STDC__
#define VOIDTYPE void
#define CONST const
#define EXITTYPE void
#define DATATYPE void
#define SIZETYPE size_t
#define FREETYPE void
#define MEMDATA void
#define MEMSIZE size_t
#define BCOPYSIZE int
#define MEMCMPTYPE unsigned char
#define STRSIZE size_t
#define STRCMPTYPE unsigned char
#endif /* (__GNUC__ == 2) && __STDC__ */
#endif /* (__GNUC__ == 2) && __STDC__ && __cplusplus */
#endif /* (__GNUC__ == 2) */
#endif /* (__GNUC__ == 2) && __STDC__ */
/*
* END of automatic configuration stuff.
*/
/*
* if DATATYPE is not defined, then the configure script must have had a
* problem, or was used with a different compiler. So we have to stop
* here and get the user to fix the problem.
*/
#ifndef DATATYPE
/*
* the following string should cause a comilation error and get the
* user to look at this stuff to find out what is wrong.
*/
"This file is not configured correctly for this system. Run configure
and check its results"
char * malloc(); /* DON'T REMOVE THIS LINE if you get a compiler error
here it is because the malloc.h file is not
configured correctly See the readme/problems
files for more info */
#endif /* DATATYPE */
#endif /* force_cproto_to_use_defines */
#define VOIDCAST (VOIDTYPE)
/*
* since we redefine much of the stuff that is #defined in string.h and
* memory.h, we should do what we can to make sure that they don't get
* included after us. This is typically accomplished by a special symbol
* (similar to _DEBUG_MALLOC_INC defined above) that is #defined when the
* file is included. Since we don't want the file to be included we will
* #define the symbol ourselves. These will typically have to change from
* one system to another. I have put in several standard mechanisms used to
* support this mechanism, so hopefully you won't have to modify this file.
*/
#ifndef _H_STRING
#define _H_STRING 1
#endif
#ifndef __STRING_H
#define __STRING_H 1
#endif
#ifndef _STRING_H_
#define _STRING_H_ 1
#endif
#ifndef _STRING_H
#define _STRING_H 1
#endif
#ifndef _STRING_INCLUDED
#define _STRING_INCLUDED 1
#endif
#ifndef __string_h
#define __string_h 1
#endif
#ifndef _string_h
#define _string_h 1
#endif
#ifndef __string_h__
#define __string_h__ 1
#endif
#ifndef _strings_h
#define _strings_h 1
#endif
#ifndef __strings_h
#define __strings_h 1
#endif
#ifndef __strings_h__
#define __strings_h__ 1
#endif
#ifndef _H_MEMORY
#define _H_MEMORY 1
#endif
#ifndef __MEMORY_H
#define __MEMORY_H 1
#endif
#ifndef _MEMORY_H_
#define _MEMORY_H_ 1
#endif
#ifndef _MEMORY_H
#define _MEMORY_H 1
#endif
#ifndef _MEMORY_INCLUDED
#define _MEMORY_INCLUDED 1
#endif
#ifndef __memory_h
#define __memory_h 1
#endif
#ifndef _memory_h
#define _memory_h 1
#endif
#ifndef __memory_h__
#define __memory_h__ 1
#endif
#ifndef _STDLIB_H
#define _STDLIB_H 1
#endif
/*
* for NCR, we need to disable their in-line expansion of the str* routines
*/
#define ISTRING 1
/*
* Malloc warning/fatal error handler defines...
*/
#define M_HANDLE_DUMP 0x80 /* 128 */
#define M_HANDLE_IGNORE 0
#define M_HANDLE_ABORT 1
#define M_HANDLE_EXIT 2
#define M_HANDLE_CORE 3
/*
* Mallopt commands and defaults
*
* the first four settings are ignored by the debugging dbmallopt, but are
* here to maintain compatibility with the system malloc.h.
*/
#define M_MXFAST 1 /* ignored by mallopt */
#define M_NLBLKS 2 /* ignored by mallopt */
#define M_GRAIN 3 /* ignored by mallopt */
#define M_KEEP 4 /* ignored by mallopt */
#define MALLOC_WARN 100 /* set malloc warning handling */
#define MALLOC_FATAL 101 /* set malloc fatal handling */
#define MALLOC_ERRFILE 102 /* specify malloc error file */
#define MALLOC_CKCHAIN 103 /* turn on chain checking */
#define MALLOC_FILLAREA 104 /* turn off area filling */
#define MALLOC_LOWFRAG 105 /* use best fit allocation mech */
#define MALLOC_CKDATA 106 /* turn off/on data checking */
#define MALLOC_REUSE 107 /* turn off/on freed seg reuse */
#define MALLOC_SHOWLINKS 108 /* turn off/on adjacent link disp */
#define MALLOC_DETAIL 109 /* turn off/on detail output */
#define MALLOC_FREEMARK 110 /* warn about freeing marked segs*/
#define MALLOC_ZERO 111 /* warn about zero len allocs */
union dbmalloptarg
{
int i;
char * str;
};
/*
* disable the standard mallopt function
*/
#define mallopt(a,b) (0)
/*
* Malloc warning/fatal error codes
*/
#define M_CODE_CHAIN_BROKE 1 /* malloc chain is broken */
#define M_CODE_NO_END 2 /* chain end != endptr */
#define M_CODE_BAD_PTR 3 /* pointer not in malloc area */
#define M_CODE_BAD_MAGIC 4 /* bad magic number in header */
#define M_CODE_BAD_CONNECT 5 /* chain poingers corrupt */
#define M_CODE_OVERRUN 6 /* data overrun in malloc seg */
#define M_CODE_REUSE 7 /* reuse of freed area */
#define M_CODE_NOT_INUSE 8 /* pointer is not in use */
#define M_CODE_NOMORE_MEM 9 /* no more memory available */
#define M_CODE_OUTOF_BOUNDS 10 /* gone beyound bounds */
#define M_CODE_FREELIST_BAD 11 /* inuse segment on freelist */
#define M_CODE_NOBOUND 12 /* can't calculate boundry */
#define M_CODE_STK_NOCUR 13 /* no current element on stack */
#define M_CODE_STK_BADFUNC 14 /* current func doesn't match */
#define M_CODE_UNDERRUN 15 /* data underrun in malloc seg */
#define M_CODE_FREEMARK 16 /* free of marked segment */
#define M_CODE_ZERO_ALLOC 17 /* zero length allocation */
#ifndef __STDCARGS
#if __STDC__ || __cplusplus
#define __STDCARGS(a) a
#else
#define __STDCARGS(a) ()
#endif
#endif
#if __cplusplus
extern "C" {
#endif
VOIDTYPE malloc_dump __STDCARGS((int));
VOIDTYPE malloc_list __STDCARGS((int,unsigned long, unsigned long));
int dbmallopt __STDCARGS((int, union dbmalloptarg *));
DATATYPE * debug_calloc __STDCARGS((CONST char *,int,SIZETYPE,SIZETYPE));
FREETYPE debug_cfree __STDCARGS((CONST char *, int, DATATYPE *));
FREETYPE debug_free __STDCARGS((CONST char *, int, DATATYPE *));
DATATYPE * debug_malloc __STDCARGS((CONST char *,int, SIZETYPE));
DATATYPE * debug_realloc __STDCARGS((CONST char *,int,
DATATYPE *,SIZETYPE));
VOIDTYPE DBmalloc_mark __STDCARGS((CONST char *,int, DATATYPE *));
unsigned long DBmalloc_inuse __STDCARGS((CONST char *,int,
unsigned long *));
int DBmalloc_chain_check __STDCARGS((CONST char *,int,int));
SIZETYPE DBmalloc_size __STDCARGS((CONST char *,int,CONST DATATYPE *));
DATATYPE * DBmemalign __STDCARGS((CONST char *, int,SIZETYPE, SIZETYPE));
void StackEnter __STDCARGS((CONST char *, CONST char *, int));
void StackLeave __STDCARGS((CONST char *, CONST char *, int));
/*
* X allocation related prototypes
*/
char * debug_XtMalloc __STDCARGS((CONST char *, int, unsigned int));
char * debug_XtRealloc __STDCARGS((CONST char *, int,
char *, unsigned int));
char * debug_XtCalloc __STDCARGS((CONST char *, int,
unsigned int, unsigned int));
void debug_XtFree __STDCARGS((CONST char *, int, char *));
void * debug_XtBCopy __STDCARGS((CONST char *, int, char *,
char *, int));
extern void (*XtAllocErrorHandler) __STDCARGS((CONST char *));
/*
* memory(3) related prototypes
*/
MEMDATA * DBmemccpy __STDCARGS((CONST char *file, int line,
MEMDATA *ptr1, CONST MEMDATA *ptr2,
int ch, MEMSIZE len));
MEMDATA * DBmemchr __STDCARGS((CONST char *file, int line,
CONST MEMDATA *ptr1, int ch,
MEMSIZE len));
MEMDATA * DBmemmove __STDCARGS((CONST char *file, int line,
MEMDATA *ptr1, CONST MEMDATA *ptr2,
MEMSIZE len));
MEMDATA * DBmemcpy __STDCARGS((CONST char *file, int line,
MEMDATA *ptr1, CONST MEMDATA *ptr2,
MEMSIZE len));
int DBmemcmp __STDCARGS((CONST char *file, int line,
CONST MEMDATA *ptr1,
CONST MEMDATA *ptr2, MEMSIZE len));
MEMDATA * DBmemset __STDCARGS((CONST char *file, int line,
MEMDATA *ptr1, int ch, MEMSIZE len));
VOIDTYPE DBbcopy __STDCARGS((CONST char *file, int line,
CONST MEMDATA *ptr2, MEMDATA *ptr1,
BCOPYSIZE len));
VOIDTYPE DBbzero __STDCARGS((CONST char *file, int line,
MEMDATA *ptr1, BCOPYSIZE len));
int DBbcmp __STDCARGS((CONST char *file, int line,
CONST MEMDATA *ptr2,
CONST MEMDATA *ptr1, BCOPYSIZE len));
/*
* string(3) related prototypes
*/
char * DBstrcat __STDCARGS((CONST char *file,int line, char *str1,
CONST char *str2));
char * DBstrdup __STDCARGS((CONST char *file, int line,
CONST char *str1));
char * DBstrncat __STDCARGS((CONST char *file, int line, char *str1,
CONST char *str2, STRSIZE len));
int DBstrcmp __STDCARGS((CONST char *file, int line,
CONST char *str1, CONST char *str2));
int DBstrncmp __STDCARGS((CONST char *file, int line,
CONST char *str1, CONST char *str2,
STRSIZE len));
int DBstricmp __STDCARGS((CONST char *file, int line,
CONST char *str1, CONST char *str2));
int DBstrincmp __STDCARGS((CONST char *file, int line,
CONST char *str1, CONST char *str2,
STRSIZE len));
char * DBstrcpy __STDCARGS((CONST char *file, int line, char *str1,
CONST char *str2));
char * DBstrncpy __STDCARGS((CONST char *file, int line, char *str1,
CONST char *str2, STRSIZE len));
STRSIZE DBstrlen __STDCARGS((CONST char *file, int line,
CONST char *str1));
char * DBstrchr __STDCARGS((CONST char *file, int line,
CONST char *str1, int c));
char * DBstrrchr __STDCARGS((CONST char *file, int line,
CONST char *str1, int c));
char * DBindex __STDCARGS((CONST char *file, int line,
CONST char *str1, int c));
char * DBrindex __STDCARGS((CONST char *file, int line,
CONST char *str1, int c));
char * DBstrpbrk __STDCARGS((CONST char *file, int line,
CONST char *str1, CONST char *str2));
STRSIZE DBstrspn __STDCARGS((CONST char *file, int line,
CONST char *str1, CONST char *str2));
STRSIZE DBstrcspn __STDCARGS((CONST char *file, int line,
CONST char *str1, CONST char *str2));
char * DBstrstr __STDCARGS((CONST char *file, int line,
CONST char *str1, CONST char *str2));
char * DBstrtok __STDCARGS((CONST char *file, int line, char *str1,
CONST char *str2));
#if __cplusplus
};
#endif
/*
* Macro which enables logging of the file and line number for each allocation
* so that it is easier to determine where the offending malloc comes from.
*
* NOTE that only code re-compiled with this include file will have this
* additional info. Calls from libraries that have not been recompiled will
* just have a null string for this info.
*/
#ifndef IN_MALLOC_CODE
/*
* allocation functions
*/
#ifdef malloc
#undef malloc
#endif
#ifdef realloc
#undef realloc
#endif
#ifdef calloc
#undef calloc
#endif
#ifdef cfree
#undef cfree
#endif
#ifdef free
#undef free
#endif
#define malloc(len) debug_malloc( __FILE__,__LINE__, (len))
#define realloc(ptr,len) debug_realloc(__FILE__,__LINE__, (ptr), (len))
#define calloc(numelem,size) debug_calloc(__FILE__,__LINE__,(numelem),(size))
#define cfree(ptr) debug_cfree(__FILE__,__LINE__,(ptr))
#define free(ptr) debug_free(__FILE__,__LINE__,(ptr))
#define malloc_chain_check(do) DBmalloc_chain_check(__FILE__,__LINE__,(do))
#define malloc_mark(ptr) DBmalloc_mark(__FILE__,__LINE__,(ptr))
#define malloc_inuse(histptr) DBmalloc_inuse(__FILE__,__LINE__,(histptr))
#define malloc_size(ptr) DBmalloc_size(__FILE__,__LINE__,(ptr))
#define memalign(align,size) DBmemalign(__FILE__,__LINE__,(align),(size))
/*
* X allocation routines
*/
#define XtCalloc(_num,_size) debug_XtCalloc(__FILE__,__LINE__,_num,_size)
#define XtMalloc(_size) debug_XtMalloc(__FILE__,__LINE__,_size)
#define XtRealloc(_ptr,_size) debug_XtRealloc(__FILE__,__LINE__,_ptr,_size)
#define XtFree(_ptr) debug_XtFree(__FILE__,__LINE__,_ptr)
#define _XtBCopy(ptr1,ptr2,len) debug_XtBcopy(__FILE__,__LINE__,ptr1,ptr2,len)
/*
* Other allocation functions
*/
#define _malloc(_size) debug_malloc(__FILE__,__LINE__,_size)
#define _realloc(_ptr,_size) debug_realloc(__FILE__,__LINE__,_ptr,_size)
#define _calloc(_num,_size) debug_calloc(__FILE__,__LINE__,_num,_size)
#define _free(_ptr) debug_free(__FILE__,__LINE__,_ptr)
/*
* memory(3) related functions
*/
#ifdef bcopy
#undef bcopy
#endif
#ifdef bzero
#undef bzero
#endif
#ifdef bcmp
#undef bcmp
#endif
#define memccpy(ptr1,ptr2,ch,len) DBmemccpy(__FILE__,__LINE__,ptr1,ptr2,ch,len)
#define memchr(ptr1,ch,len) DBmemchr(__FILE__,__LINE__,ptr1,ch,len)
#define memmove(ptr1,ptr2,len) DBmemmove(__FILE__,__LINE__,ptr1, ptr2, len)
#define memcpy(ptr1,ptr2,len) DBmemcpy(__FILE__, __LINE__, ptr1, ptr2, len)
#define memcmp(ptr1,ptr2,len) DBmemcmp(__FILE__,__LINE__,ptr1, ptr2, len)
#define memset(ptr1,ch,len) DBmemset(__FILE__,__LINE__,ptr1, ch, len)
#define bcopy(ptr2,ptr1,len) DBbcopy(__FILE__,__LINE__,ptr2,ptr1,len)
#define bzero(ptr1,len) DBbzero(__FILE__,__LINE__,ptr1,len)
#define bcmp(ptr2,ptr1,len) DBbcmp(__FILE__, __LINE__, ptr2, ptr1, len)
#define _bcopy(ptr2,ptr1,len) DBbcopy(__FILE__,__LINE__,ptr2,ptr1,len)
#define _bzero(ptr1,len) DBbzero(__FILE__,__LINE__,ptr1,len)
#define _bcmp(ptr2,ptr1,len) DBbcmp(__FILE__,__LINE__,ptr2,ptr1,len)
#define __dg_bcopy(ptr2,ptr1,len) DBbcopy(__FILE__,__LINE__,ptr2,ptr1,len)
#define __dg_bzero(ptr1,len) DBbzero(__FILE__,__LINE__,ptr1,len)
#define __dg_bcmp(ptr2,ptr1,len) DBbcmp(__FILE__,__LINE__,ptr2,ptr1,len)
/*
* string(3) related functions
*/
#ifdef index
#undef index
#endif
#ifdef rindex
#undef rindex
#endif
#ifdef strchr
#undef strchr
#endif
#ifdef strcmp
#undef strcmp
#endif
#ifdef strcpy
#undef strcpy
#endif
#ifdef strrchr
#undef strrchr
#endif
#define index(str1,c) DBindex(__FILE__, __LINE__, str1, c)
#define rindex(str1,c) DBrindex(__FILE__, __LINE__, str1, c)
#define strcat(str1,str2) DBstrcat(__FILE__,__LINE__,str1,str2)
#define strchr(str1,c) DBstrchr(__FILE__, __LINE__, str1,c)
#define strcmp(str1,str2) DBstrcmp(__FILE__, __LINE__, str1, str2)
#define strcpy(str1,str2) DBstrcpy(__FILE__, __LINE__, str1, str2)
#define strcspn(str1,str2) DBstrcspn(__FILE__, __LINE__, str1,str2)
#define strdup(str1) DBstrdup(__FILE__, __LINE__, str1)
#define stricmp(str1,str2) DBstricmp(__FILE__, __LINE__, str1, str2)
#define strincmp(str1,str2,len) DBstrincmp(__FILE__, __LINE__, str1,str2,len)
#define strlen(str1) DBstrlen(__FILE__, __LINE__, str1)
#define strncat(str1,str2,len) DBstrncat(__FILE__, __LINE__, str1,str2,len)
#define strncpy(str1,str2,len) DBstrncpy(__FILE__,__LINE__,str1,str2,len)
#define strncmp(str1,str2,len) DBstrncmp(__FILE__, __LINE__, str1,str2,len)
#define strpbrk(str1,str2) DBstrpbrk(__FILE__, __LINE__, str1,str2)
#define strrchr(str1,c) DBstrrchr(__FILE__,__LINE__,str1,c)
#define strspn(str1,str2) DBstrspn(__FILE__, __LINE__, str1,str2)
#define strstr(str1,str2) DBstrstr(__FILE__, __LINE__, str1, str2)
#define strtok(str1,str2) DBstrtok(__FILE__, __LINE__, str1, str2)
/*
* malloc stack related functions
*/
#define malloc_enter(func) StackEnter(func,__FILE__,__LINE__)
#define malloc_leave(func) StackLeave(func,__FILE__,__LINE__)
#endif /* IN_MALLOC_CODE */
#endif /* _DEBUG_MALLOC_INC */
/*
* $Log: dbmalloc.h,v $
* Revision 1.1 1997/03/16 20:59:19 luethje
* Added the source code isdnlog. isdnlog is not working yet.
* A workaround for that problem:
* copy lib/policy.h into the root directory of isdn4k-utils.
*
* Revision 1.38 1992/08/22 16:27:13 cpcahil
* final changes for pl14
*
* Revision 1.37 1992/08/18 11:42:00 cpcahil
* added more #defs to preclude memory/string.h inclusion
*
* Revision 1.36 1992/07/12 15:30:58 cpcahil
* Merged in Jonathan I Kamens' changes
*
* Revision 1.35 1992/07/03 00:03:25 cpcahil
* more fixes for pl13, several suggestons from Rich Salz.
*
* Revision 1.34 1992/07/02 15:35:52 cpcahil
* misc cleanups for PL13
*
* Revision 1.33 1992/07/02 13:49:54 cpcahil
* added support for new malloc_size function and additional tests to testerr
*
* Revision 1.32 1992/06/30 13:06:39 cpcahil
* added support for aligned allocations
*
* Revision 1.31 1992/06/22 23:40:10 cpcahil
* many fixes for working on small int systems
*
* Revision 1.30 1992/05/06 04:53:29 cpcahil
* performance enhancments
*
* Revision 1.29 1992/04/22 18:17:32 cpcahil
* added support for Xt Alloc functions, linted code
*
* Revision 1.28 1992/04/13 19:08:18 cpcahil
* fixed case insensitive stuff
*
* Revision 1.27 1992/04/13 18:41:18 cpcahil
* added case insensitive string comparison routines
*
* Revision 1.26 1992/04/13 17:26:25 cpcahil
* minor portability changes
*
* Revision 1.25 1992/04/13 14:13:18 cpcahil
* cleanup of log message.
*
* Revision 1.24 1992/04/13 03:09:14 cpcahil
* lots of changes.
*
* Revision 1.23 1992/03/01 12:42:38 cpcahil
* added support for managing freed areas and fixed doublword bndr problems
*
* Revision 1.22 1992/02/07 15:51:07 cpcahil
* mods for sun4
*
* Revision 1.21 1992/01/29 01:35:32 cpcahil
* added sgi definition.
*
* Revision 1.20 1992/01/28 21:42:25 cpcahil
* changes for the ibmRS6000
*
* Revision 1.19 1992/01/28 18:05:37 cpcahil
* misc fixes for patch 7
*
* Revision 1.18 1992/01/22 16:21:35 cpcahil
* added code to prevent inclusions of string.h and memory.h after malloc.h
* was included.
*
* Revision 1.17 1992/01/10 17:26:46 cpcahil
* fixed prototypes use of void.
*
* Revision 1.16 1992/01/10 16:53:39 cpcahil
* added more info on sizetype and datatype. added support for overriding
* use of void type.
*
* Revision 1.15 1992/01/09 17:19:11 cpcahil
* put the close brace in the correct position.
*
* Revision 1.14 1992/01/09 17:12:36 cpcahil
* added code to support inclusion in C++ modules
*
* Revision 1.13 1991/12/31 21:31:26 cpcahil
* changes for patch 6. See CHANGES file for more info
*
* Revision 1.12 1991/12/26 22:31:29 cpcahil
* added check to make sure file is not included twice.
*
* Revision 1.11 1991/12/06 17:58:46 cpcahil
* added cfree() for compatibility with some wierd systems
*
* Revision 1.10 91/12/06 08:54:18 cpcahil
* cleanup of __STDC__ usage and addition of CHANGES file
*
* Revision 1.9 91/12/04 09:23:40 cpcahil
* several performance enhancements including addition of free list
*
* Revision 1.8 91/12/02 19:10:11 cpcahil
* changes for patch release 5
*
* Revision 1.7 91/11/25 14:42:00 cpcahil
* Final changes in preparation for patch 4 release
*
* Revision 1.6 91/11/24 00:49:28 cpcahil
* first cut at patch 4
*
* Revision 1.5 91/11/20 11:54:10 cpcahil
* interim checkin
*
* Revision 1.4 90/08/29 22:23:38 cpcahil
* fixed mallopt to use a union as an argument.
*
* Revision 1.3 90/05/11 11:04:10 cpcahil
* took out some extraneous lines
*
* Revision 1.2 90/05/11 00:13:09 cpcahil
* added copyright statment
*
* Revision 1.1 90/02/23 07:09:03 cpcahil
* Initial revision
*
*/

1631
isdnlog/tools/isdnconf.c Normal file

File diff suppressed because it is too large Load Diff

850
isdnlog/tools/tools.c Normal file
View File

@ -0,0 +1,850 @@
/* $Id: tools.c,v 1.1 1997/03/16 20:59:24 luethje Exp $
*
* ISDN accounting for isdn4linux. (Utilities)
*
* Copyright 1995, 1997 by Andreas Kool (akool@Kool.f.EUnet.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: tools.c,v $
* Revision 1.1 1997/03/16 20:59:24 luethje
* Added the source code isdnlog. isdnlog is not working yet.
* A workaround for that problem:
* copy lib/policy.h into the root directory of isdn4k-utils.
*
* Revision 2.6.26 1997/01/19 22:23:43 akool
* Weitere well-known number's hinzugefuegt
*
* Revision 2.6.24 1997/01/15 19:13:43 akool
* neue AreaCode Lib 0.99 integriert
*
* Revision 2.6.20 1997/01/05 20:06:43 akool
* atom() erkennt nun "non isdnlog" "/tmp/isdnctrl0" Output's
*
* Revision 2.6.19 1997/01/05 19:39:43 akool
* LIBAREA Support added
*
* Revision 2.40 1996/06/16 10:06:43 akool
* double2byte(), time2str() added
*
* Revision 2.3.26 1996/05/05 12:09:16 akool
* known.interface added
*
* Revision 2.3.15 1996/04/22 21:10:16 akool
*
* Revision 2.3.4 1996/04/05 11:12:16 sl
* confdir()
*
* Revision 2.2.5 1996/03/25 19:41:16 akool
* 1TR6 causes implemented
*
* Revision 2.23 1996/03/14 20:29:16 akool
* Neue Routine i2a()
*
* Revision 2.17 1996/02/25 19:14:16 akool
* Soft-Error in atom() abgefangen
*
* Revision 2.06 1996/02/07 18:49:16 akool
* AVON-Handling implementiert
*
* Revision 2.01 1996/01/20 12:11:16 akool
* Um Einlesen der neuen isdnlog.conf Felder erweitert
* discardconfig() implementiert
*
* Revision 2.00 1996/01/10 20:11:16 akool
*
*/
/****************************************************************************/
#define PUBLIC /**/
#define _TOOLS_C_
/****************************************************************************/
#include "tools.h"
/****************************************************************************/
/*static char *cclass(register char *p, register int sub);*/
/****************************************************************************/
char Months[][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
/****************************************************************************/
static char proto[] = " 0,000000000";
static int cnf;
/****************************************************************************/
void set_print_fct_for_tools(int (*new_print_msg)(const char *, ...))
{
_print_msg = new_print_msg;
set_print_fct_for_lib(_print_msg);
}
/****************************************************************************/
time_t atom(register char *p)
{
register char *p1 = p;
auto struct tm tm;
#ifdef DEBUG_1
if (strlen(p) < 20) {
_print_msg(PRT_DEBUG_GENERAL, " DEBUG> Huch? atom(``%s'')\n", p);
return((time_t)0);
} /* if */
#endif
tm.tm_mon = 0;
while ((tm.tm_mon < 12) && memcmp(p1, Months[tm.tm_mon], 3)) tm.tm_mon++;
if (tm.tm_mon == 12)
return((time_t)-1);
p1 += 4;
p = p1 + 2;
*p = 0;
day = tm.tm_mday = atoi(p1);
p1 += 3;
p = p1 + 2;
*p = 0;
tm.tm_hour = atoi(p1);
p1 = ++p;
p += 2;
*p = 0;
tm.tm_min = atoi(p1);
p1 = ++p;
p += 2;
*p = 0;
tm.tm_sec = atoi(p1);
p1 = ++p;
p += 4;
*p = 0;
tm.tm_year = atoi(p1 + 2);
#ifdef DEBUG_1
if (tm.tm_year < 1995) {
_print_msg(PRT_DEBUG_GENERAL, " DEBUG> Huch? atom(): year=%d\n", tm.tm_year);
return((time_t)0);
} /* if */
#endif
tm.tm_wday = tm.tm_yday;
tm.tm_isdst = -1;
return(mktime(&tm));
} /* atom */
/****************************************************************************/
char *num2nam(char *num, int si)
{
register int i, n;
if (*num) {
for (n = 0; n < 2; n++) {
for (i = 0; i < knowns; i++) {
if (((known[i]->si == si) || n) && (!num_match(known[i]->num, num))) {
if (++retnum == MAXRET)
retnum = 0;
cnf = i;
return(strcpy(retstr[retnum], known[i]->who));
} /* if */
} /* for */
} /* for */
} /* if */
cnf = -1;
return("");
} /* num2nam */
/****************************************************************************/
#ifdef _GNU_SOURCE
char *double2str(double n, int l, int d, int flags)
{
if (++retnum == MAXRET)
retnum = 0;
sprintf(retstr[retnum], "%*.*f", l, d, n);
return(retstr[retnum]);
} /* double2str */
#else
char *double2str(double n, int l, int d, int flags)
{
register char *p, *ps, *pd, *px;
auto int decpt, sign, dec, dp;
auto char buf[BUFSIZ];
if (++retnum == MAXRET)
retnum = 0;
p = retstr[retnum] + l + 1;
*p = 0;
dec = d ? d : -1;
dp = l - dec;
*buf = '0';
memcpy(buf + 1, ecvt(n, DIGITS, &decpt, &sign), DIGITS);
ps = buf;
px = ps + decpt + d;
if (px >= buf) {
int rfound = 0;
pd = px + 1;
if (*pd > '4') {
pd++;
rfound++;
} /* if */
if (rfound) {
while (pd > px)
if (*pd >= '5') {
pd--;
while (*pd == '9')
*pd-- = '0';
*pd += 1;
}
else
pd--;
} /* if */
if (*buf == '1')
decpt++;
else
ps++;
if ((dp < 2 + sign) || ((decpt ? decpt : 1) + sign) >= dp) {
memset(retstr[retnum] + 1, '*', *retstr[retnum] = l);
return(retstr[retnum] + 1);
} /* if */
} /* if */
memcpy(retstr[retnum] + 1, proto + 21 - l + dec, *retstr[retnum] = l);
if (!((decpt < 0) && ((dec + decpt) <= 0))) {
pd = retstr[retnum] + dp - decpt;
if (sign) {
if (decpt > 0)
*(pd - 1) = '-';
else
*(retstr[retnum] + dp - 2) = '-';
} /* if */
while (decpt-- > 0)
*pd++ = *ps++;
pd++; /* skip comma */
while (d-- > 0)
*pd++ = *ps++;
} /* if */
if (flags & DEB) {
p = retstr[retnum] + 1;
while (*p == ' ')
p++;
return(p);
} /* if */
return(retstr[retnum] + 1);
} /* double2str */
#endif
/****************************************************************************/
char *double2byte(double bytes)
{
static char mode[4] = " KMG";
register int m = 0;
if (++retnum == MAXRET)
retnum = 0;
while (bytes > 999.9) {
bytes /= 1024.0;
m++;
} /* while */
sprintf(retstr[retnum], "%s%cb", double2str(bytes, 5, 1, 0), mode[m]);
return(retstr[retnum]);
} /* double2byte */
/****************************************************************************/
char *time2str(time_t sec)
{
static char mode[3] = "smh";
register int m = 0;
auto double s = (double)sec;
if (++retnum == MAXRET)
retnum = 0;
while (s > 59.9) {
s /= 60.0;
m++;
} /* while */
sprintf(retstr[retnum], "%s%c", double2str(s, 4, 1, 0), mode[m]);
return(retstr[retnum]);
} /* time2str */
/****************************************************************************/
char *double2clock(double n)
{
auto int x, h, m, s;
if (++retnum == MAXRET)
retnum = 0;
if (n <= 0.0)
sprintf(retstr[retnum], " ");
else {
#if 0
x = floor(n);
#else
x = (int)n;
#endif
h = (int)(x / 60 / 60);
x %= 60 * 60;
m = (int)(x / 60);
s = (int)(x % 60);
#if 0
sprintf(retstr[retnum], "%2d:%02d:%02d.%02d", h, m, s,
(int)((n - x) * 100));
#else
sprintf(retstr[retnum], "%2d:%02d:%02d", h, m, s);
#endif
} /* else */
return(retstr[retnum]);
} /* double2clock */
/****************************************************************************/
char *vnum(int chan, int who)
{
register int l = strlen(call[chan].num[who]), got = 0;
register int flag = C_NO_WARN | C_NO_EXPAND;
auto char *ptr;
auto int ll;
auto int prefix = strlen(S_COUNTRY_PREFIX);
if (++retnum == MAXRET)
retnum = 0;
*call[chan].vorwahl[who] =
*call[chan].rufnummer[who] =
*call[chan].alias[who] =
*call[chan].area[who] = 0;
call[chan].confentry[who] = -1;
if (!l) { /* keine Meldung von der Vst (Calling party number fehlt) */
sprintf(retstr[retnum], "%c", C_UNKNOWN);
return(retstr[retnum]);
} /* if */
strcpy(call[chan].alias[who], num2nam(call[chan].num[who], call[chan].si1));
if (cnf > -1) { /* Alias gefunden! */
call[chan].confentry[who] = cnf;
strcpy(retstr[retnum], call[chan].alias[who]);
} /* if */
#ifdef Q931
if (q931dmp)
flag |= C_NO_ERROR;
#endif
if ((ptr = get_areacode(call[chan].num[who], &ll, flag)) != 0) {
strcpy(call[chan].area[who], ptr);
l = ll;
got++;
} /* if */
/* Die folgenden Zeilen basieren nur auf eine Annahme, das ein Laendercode
aus zwei Ziffern besteht!!!!!!! */
if (l > 1) {
strncpy(call[chan].areacode[who], call[chan].num[who], 2 + prefix);
strncpy(call[chan].vorwahl[who], call[chan].num[who] + 2 + prefix, l - 2 - prefix);
strcpy(call[chan].rufnummer[who], call[chan].num[who] + l);
} /* if */
if (cnf > -1)
strcpy(retstr[retnum], call[chan].alias[who]);
else if (l > 1)
sprintf(retstr[retnum], "%s %s/%s, %s",
call[chan].areacode[who],
call[chan].vorwahl[who],
call[chan].rufnummer[who],
call[chan].area[who]);
else
strcpy(retstr[retnum], call[chan].num[who]);
return(retstr[retnum]);
} /* vnum */
/****************************************************************************/
char *i2a(int n, int l, int base)
{
static char Digits[] = "0123456789abcdef";
register char *p;
register int dot = 0;
if (++retnum == MAXRET)
retnum = 0;
p = retstr[retnum] + RETSIZE - 1;
*p = 0;
while (n || (l > 0)) {
if (n) {
*--p = Digits[n % base];
n /= base;
}
else
*--p = '0';
l--;
dot++;
if (!(dot % 8))
*--p = ' ';
else if (!(dot % 4))
*--p = '.';
} /* while */
return(((*p == ' ') || (*p == '.')) ? p + 1 : p);
} /* i2a */
/****************************************************************************/
static char *itoa(register unsigned int num, register char *p, register int radix, int dots)
{
register int i, j = 0;
register char *q = p + MAXDIG;
do {
i = (int)(num % radix);
i += '0';
if (i > '9')
i += 'A' - '0' - 10;
*--q = i;
if (dots)
if (!(++j % 3))
*--q = '.';
} while ((num = num / radix));
if (*q == '.')
q++;
i = p + MAXDIG - q;
do
*p++ = *q++;
while (--i);
return(p);
} /* itoa */
/****************************************************************************/
static char *ltoa(register unsigned long num, register char *p, register int radix, int dots)
{
register int i, j = 0;
register char *q = p + MAXDIG;
do {
i = (int)(num % radix);
i += '0';
if (i > '9')
i += 'A' - '0' - 10;
*--q = i;
if (dots)
if (!(++j % 3))
*--q = '.';
} while ((num = num / radix));
if (*q == '.')
q++;
i = p + MAXDIG - q;
do
*p++ = *q++;
while (--i);
return(p);
} /* ltoa */
/****************************************************************************/
int iprintf(char *obuf, int chan, register char *fmt, ...)
{
register char *p, *s;
register int c, i, who;
register short int width, ndigit;
register int ndfnd, ljust, zfill, lflag;
register long l;
register char *op = obuf;
#if 0
auto int decpt, sign;
#endif
auto char buf[MAXDIG + 1]; /* +1 for sign */
static char nul[] = "(null)";
auto va_list ap;
va_start(ap, fmt);
for (;;) {
c = *fmt++;
if (!c) {
va_end(ap);
*op = 0;
return((int)(op - obuf));
} /* if */
if (c != '%') {
*op++ = c;
continue;
} /* if */
p = s = buf;
ljust = 0;
if (*fmt == '-') {
fmt++;
ljust++;
} /* if */
zfill = ' ';
if (*fmt == '0') {
fmt++;
zfill = '0';
} /* if */
for (width = 0;;) {
c = *fmt++;
if (isdigit(c))
c -= '0';
else if (c == '*')
c = GETARG(int);
else
break;
width *= 10;
width += c;
} /* for */
ndfnd = ndigit = 0;
if (c == '.') {
for (;;) {
c = *fmt++;
if (isdigit(c))
c -= '0';
else if (c == '*')
c = GETARG(int);
else
break;
ndigit *= 10;
ndigit += c;
ndfnd++;
} /* for */
} /* if */
lflag = 0;
if (tolower(c) == 'l') {
lflag++;
if (*fmt)
c = *fmt++;
} /* if */
who = OTHER;
switch (c) {
case 'X' : lflag++;
case 'x' : c = 16;
goto oxu;
case 'U' : lflag++;
case 'u' : c = 10;
goto oxu;
case 'O' : lflag++;
case 'o' : c = 8;
oxu:
if (lflag)
p = ltoa((unsigned long)GETARG(long), p, c, 0);
else
p = itoa((unsigned int)GETARG(int), p, c, 0);
break;
case 'D' : lflag++;
case 'd' : if (lflag) {
if ((l = GETARG(long)) < 0) {
*p++ = '-';
l = -l;
} /* if */
p = ltoa((unsigned long)l, p, 10, 0);
}
else {
if ((i = GETARG(int)) < 0) {
*p++ = '-';
i = -i;
} /* if */
p = itoa((unsigned int)i, p, 10, 0);
} /* else */
break;
#if 0
case 'e' : if (!ndfnd)
ndigit = 6;
ndigit++;
p = ecvt(GETARG(double), ndigit, &decpt, &sign) + ndigit;
break;
case 'f' : if (!ndfnd)
ndigit = 6;
p = fcvt(GETARG(double), ndigit, &decpt, &sign) + ndigit;
break;
case 'g' : if (!ndfnd)
ndigit = 6;
p = gcvt(GETARG(double), ndigit, p) + ndigit;
break;
#endif
case 'c' : zfill = ' ';
*p++ = GETARG(int);
break;
case 's' : zfill = ' ';
if ((s = GETARG(char *)) == NULL)
s = nul;
if (!ndigit)
ndigit = 32767;
for (p = s; *p && --ndigit >= 0; p++);
break;
case 'k' : p = itoa(call[chan].card, p, 10, 0);
break;
case 't' : p = itoa(call[chan].tei, p, 10, 0);
break;
case 'C' : p = itoa(call[chan].cref, p, 10, 0);
break;
case 'B' : p = itoa(chan, p, 10, 0);
break;
case 'n' : who = ME;
case 'N' : if (!ndigit)
ndigit = 32767;
if (*fmt) {
switch (*fmt++) {
case '0' : s = call[chan].onum[who]; break;
case '1' : s = call[chan].num[who]; break;
case '2' : s = call[chan].vnum[who]; break;
case '3' : s = call[chan].vorwahl[who]; break;
case '4' : s = call[chan].rufnummer[who]; break;
case '5' : s = call[chan].alias[who]; break;
case '6' : s = call[chan].area[who]; break;
default : s = nul; break;
} /* switch */
p = s + strlen(s);
} /* if */
break;
case 'I' : switch (chan) {
case 0 : s = ""; p = s; break;
case 1 : s = " "; p = s + 2; break;
default : s = "* "; p = s + 2; break;
} /* switch */
break;
case 'a' : s = idate; p = s + 3;
break;
case 'b' : s = idate + 3; p = s + 3;
break;
case 'e' : s = idate + 6; p = s + 2;
break;
case 'T' : s = idate + 8; p = s + 8;
break;
default : *p++ = c;
break;
} /* switch */
i = p - s;
if ((width -= i) < 0)
width = 0;
if (!ljust)
width = -width;
if (width < 0) {
if ((*s == '-') && (zfill == '0')) {
*op++ = *s++;
i--;
} /* if */
do
*op++ = zfill;
while (++width);
} /* if */
while (--i >= 0)
*op++ = *s++;
while (width) {
*op++ = zfill;
width--;
} /* while */
} /* for */
} /* iprintf */
/****************************************************************************/
int print_version(char *myname)
{
_print_msg("%s Version %s, Copyright (C) 1995, 1996, 1997 Andreas Kool\n",myname,VERSION);
_print_msg("%s comes with ABSOLUTELY NO WARRANTY; for details see COPYING.\n", myname);
_print_msg("This is free software, and you are welcome to redistribute it\n");
_print_msg("under certain conditions; see COPYING for details.\n");
return 0;
}
/****************************************************************************/
char *t2tz(int zeit)
{
switch (zeit) {
case 0 : return("Vormittag"); break;
case 1 : return("Nachmittag"); break;
case 2 : return("Freizeit"); break;
case 3 : return("Mondschein"); break;
case 4 : return("Nacht"); break;
case 5 : return("Standard"); break;
case 6 : return("Spartarif"); break;
case 7 : return("City Weekend"); break;
case 8 : return("City Plus"); break;
case 9 : return("Feiertag"); break;
default : return(""); break;
} /* switch */
} /* t2tz */
/****************************************************************************/
char *z2s(int zone)
{
switch (zone) {
case 1 : return("City"); break;
case 2 : return("R50"); break;
case 3 : return("R200"); break;
case 4 : return("Fern"); break;
case 5 : return("EuroC"); break;
case 6 : return("Vis1"); break;
case 7 : return("Vis2"); break;
case 8 : return("Vis3"); break;
case 9 : return("Welt1"); break;
case 10 : return("Welt2"); break;
case 11 : return("Welt3"); break;
case 12 : return("T-Online"); break;
case 13 : return("KONF"); break;
case 14 : return("Inmar"); break;
case 15 : return("C-Box"); break;
case 16 : return("T-Box"); break;
default : return(""); break;
} /* switch */
} /* z2s */
/****************************************************************************/

609
isdnlog/tools/tools.h Normal file
View File

@ -0,0 +1,609 @@
/* $Id: tools.h,v 1.1 1997/03/16 20:59:25 luethje Exp $
*
* ISDN accounting for isdn4linux.
*
* Copyright 1995, 1997 by Andreas Kool (akool@Kool.f.EUnet.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: tools.h,v $
* Revision 1.1 1997/03/16 20:59:25 luethje
* Added the source code isdnlog. isdnlog is not working yet.
* A workaround for that problem:
* copy lib/policy.h into the root directory of isdn4k-utils.
*
* Revision 2.6.36 1997/02/10 09:30:43 akool
* MAXCARDS implemented
*
* Revision 2.6.25 1997/01/17 23:30:43 akool
* City Weekend Tarif implemented (Thanks to Oliver Schoett <schoett@muc.de>)
*
* Revision 2.6.20 1997/01/05 20:05:43 akool
* neue "AreaCode" Release implemented
*
* Revision 2.6.15 1997/01/02 19:51:43 akool
* CHARGEMAX erweitert
* CONNECTMAX implementiert
*
* Revision 2.40 1996/06/19 17:45:43 akool
* double2byte(), time2str() added
*
* Revision 2.3.26 1996/05/05 12:07:43 akool
* known.interface added
*
* Revision 2.3.23 1996/04/28 12:16:43 akool
* confdir()
*
* Revision 2.2.5 1996/03/25 19:17:43 akool
* 1TR6 causes implemented
*
* Revision 2.23 1996/03/24 12:11:43 akool
* Explicit decl. of basename() - new "unistd.h" dont have one
*
* Revision 2.15 1996/02/21 20:14:43 akool
*
* Revision 2.12 1996/02/13 20:08:43 root
* Nu geht's (oder?)
*
* Revision 2.12 1996/02/13 20:08:43 root
* Nu geht's (oder?)
*
* Revision 1.2 1996/02/13 20:05:28 root
* so nun gehts
*
* Revision 1.1 1996/02/13 14:28:14 root
* Initial revision
*
* Revision 2.05 1995/02/11 17:10:16 akool
*
*/
/****************************************************************************/
#ifndef _TOOLS_H_
#define _TOOLS_H_
/****************************************************************************/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <malloc.h>
#include <time.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/times.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/un.h>
#include <fcntl.h>
#include <ctype.h>
#include <limits.h>
#include <signal.h>
#include <math.h>
#include <syslog.h>
#include <sys/ioctl.h>
#ifdef linux
#include <sys/kd.h>
#include <linux/isdn.h>
#else
#include <libgen.h>
#endif
#ifdef DBMALLOC
#include "dbmalloc.h"
#endif
/****************************************************************************/
#include "policy.h"
#include "libisdn.h"
/****************************************************************************/
#ifndef OLDCONFFILE
# define OLDCONFFILE "isdnlog.conf"
#endif
#ifndef RELOADCMD
# define RELOADCMD "reload"
#endif
#ifndef STOPCMD
# define STOPCMD "stop"
#endif
#ifndef REBOOTCMD
# define REBOOTCMD "/sbin/reboot"
#endif
/****************************************************************************/
#undef min
#undef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define abs(x) (((x) < 0) ? -(x) : (x))
/****************************************************************************/
#define MAXDIG 128
#define GETARG(typ) va_arg(ap, typ)
/****************************************************************************/
#define NIL (char **)NULL
/****************************************************************************/
#define NUMSIZE 20
#define FNSIZE 64
#define RETSIZE 128
#define MAXRET 5
#define MAXZONES 6
#define MAXCHAN 7
#define MAXCARDS 2
#define DIGITS 17
#define DEB 1
#define MAXUNKNOWN 50
#define MAXCONNECTS 50
/****************************************************************************/
#define CALLING 0
#define CALLED 1
#define DATETIME 2
/****************************************************************************/
#define DIALOUT 0
#define DIALIN 1
/****************************************************************************/
#define ALERTING 0x01
#define CALL_PROCEEDING 0x02
#define SETUP 0x05
#define SETUP_ACKNOWLEDGE 0x0d
#define SUSPEND 0x25
#define SUSPEND_ACKNOWLEDGE 0x2d
#define RESUME 0x26
#define RESUME_ACKNOWLEDGE 0x2e
#define CONNECT 0x07
#define CONNECT_ACKNOWLEDGE 0x0f
#define FACILITY 0x62
#define NOTIFY 0x6e
#define STATUS 0x7d
#define MAKEL_ACKNOWLEDGE 0x28
#define MAKEL_RESUME_ACK 0x33
#define DISCONNECT 0x45
#define RELEASE 0x4d
#define RELEASE_COMPLETE 0x5a
#define INFORMATION 0x7b
#define AOCD_1TR6 0x6d
/****************************************************************************/
#define AOC_UNITS 0
#define AOC_AMOUNT 1
/****************************************************************************/
#define RING_INCOMING 1
#define RING_OUTGOING 2
#define RING_RING 4
#define RING_CONNECT 8
#define RING_BUSY 16
#define RING_AOCD 32
#define RING_ERROR 64
#define RING_HANGUP 128
#define RING_KILL 256
#define RING_SPEAK 512
#define RING_PROVIDER 1024
#define RING_LOOP 2048
#define RING_UNIQUE 4096
#define RING_INTERVAL 8192
/****************************************************************************/
#define STATE_RING 1 /* "Telefonklingeln" ... jemand ruft an, oder man selbst ruft raus */
#define STATE_CONNECT 2 /* Verbindung */
#define STATE_HANGUP 3 /* Verbindung beendet */
#define STATE_AOCD 100 /* Gebuehrenimpuls _waehrend_ der Verbindung */
#define STATE_CAUSE 101 /* Aussergewoehnliche Cause-Meldungen von der VSt */
#define STATE_TIME 102 /* Uhrzeit-Meldung von der VSt */
#define STATE_BYTE 103 /* Durchsatz-Meldung von Frank (Byte/s/B-Kanal) */
#define STATE_HUPTIMEOUT 104 /* Wechsel des hangup-Timer's */
/****************************************************************************/
#define AOC_OTHER -999999L
/****************************************************************************/
#define QCMASK 0377
#define QUOTE 0200
#define QMASK (QCMASK &~QUOTE)
#define NOT '!'
#define AVON "avon"
#define INFO "/dev/isdninfo"
#define BIGBUFSIZ 2048
/****************************************************************************/
#define VAR_START "START"
#define VAR_MYMSNS "MYMSNS"
#define VAR_MYCOUNTRY "MYAREA"
#define VAR_MYAREA "MYPREFIX"
#define VAR_CURRENCY "CURRENCY"
#define VAR_ILABEL "ILABEL"
#define VAR_OLABEL "OLABEL"
#define VAR_CHARGEMAX "CHARGEMAX"
#define VAR_CONNECTMAX "CONNECTMAX"
#define VAR_BYTEMAX "BYTEMAX"
/****************************************************************************/
#define VERSION_UNKNOWN 0
#define VERSION_EDSS1 1
#define VERSION_1TR6 2
#define DEF_NUM_MSN 3
/****************************************************************************/
#define OTHER (call[chan].dialin ? CALLING : CALLED)
#define ME (call[chan].dialin ? CALLED : CALLING)
#define _OTHER(call) (call->dialin ? CALLING : CALLED)
#define _ME(call) (call->dialin ? CALLED : CALLING)
/****************************************************************************/
#define SHORT_STRING_SIZE 256
#define LONG_STRING_SIZE 1024
#define BUF_SIZE 4096
/****************************************************************************/
/* Keywords for parameter file */
#define CONF_SEC_OPT "OPTIONS"
#define CONF_ENT_DEV "DEVICE"
#define CONF_ENT_LOG "LOG"
#define CONF_ENT_FLUSH "FLUSH"
#define CONF_ENT_PORT "PORT"
#define CONF_ENT_STDOUT "STDOUT"
#define CONF_ENT_SYSLOG "SYSLOG"
#define CONF_ENT_XISDN "XISDN"
#define CONF_ENT_TIME "TIME"
#define CONF_ENT_CON "CONSOLE"
#define CONF_ENT_START "START"
#define CONF_ENT_THRU "THRUPUT"
#define CONF_ENT_DAEMON "DAEMON"
#define CONF_ENT_PIPE "PIPE"
#define CONF_ENT_BI "BILINGUAL"
#define CONF_ENT_MON "MONITOR"
#define CONF_ENT_HANGUP "HANGUP"
#define CONF_ENT_CALLS "CALLS"
#define CONF_ENT_XLOG "XLOG"
#define CONF_ENT_NL "NEWLINE"
#define CONF_ENT_WIDTH "WIDTH"
#define CONF_ENT_WD "WATCHDOG"
#define CONF_ENT_CW "CITYWEEKEND"
#define CONF_ENT_AMT "AMT"
#define CONF_ENT_DUAL "DUAL"
#define CONF_ENT_Q931 "Q931DUMP"
/****************************************************************************/
/* Keywords for isdn.conf */
#define CONF_SEC_ISDNLOG "ISDNLOG"
#define CONF_ENT_CHARGE "CHARGEMAX"
#define CONF_ENT_CONNECT "CONNECTMAX"
#define CONF_ENT_BYTE "BYTEMAX"
#define CONF_ENT_CURR "CURRENCY"
#define CONF_ENT_ILABEL "ILABEL"
#define CONF_ENT_OLABEL "OLABEL"
#define CONF_ENT_RELOAD "RELOADCMD"
#define CONF_ENT_STOP "STOPCMD"
#define CONF_ENT_REBOOT "REBOOTCMD"
#define CONF_SEC_START "START"
#define CONF_SEC_FLAG "FLAG"
#define CONF_ENT_FLAGS "FLAGS"
#define CONF_ENT_PROG "PROGRAM"
#define CONF_ENT_USER "USER"
#define CONF_ENT_GROUP "GROUP"
#define CONF_ENT_INTVAL "INTERVAL"
#define CONF_ENT_TIME "TIME"
/****************************************************************************/
#define NO_MSN -1
#define C_FLAG_DELIM '|'
/****************************************************************************/
#define C_UNKNOWN '?'
#define S_UNKNOWN "UNKNOWN"
/****************************************************************************/
#define S_QUOTES "\\$@;,#"
/****************************************************************************/
#define TYPE_STRING 0
#define TYPE_MESSAGE 1
#define TYPE_ELEMENT 2
#define TYPE_CAUSE 3
#define TYPE_SERVICE 4
/****************************************************************************/
typedef struct {
int state;
int cref;
int tei;
int dialin;
int cause;
int aoce;
int traffic;
int channel;
int dialog;
int bearer;
int si1; /* Service Indicator entsprechend i4l convention */
int si11; /* if (si1 == 1) :: 0 = Telefon analog / 1 = Telefon digital */
char onum[2][NUMSIZE];
int screening;
char num[2][NUMSIZE];
char vnum[2][256];
char id[32];
char usage[16];
int confentry[2];
time_t time;
time_t connect;
time_t t_duration;
time_t disconnect;
clock_t duration;
int cur_event;
long ibytes;
long obytes;
long libytes;
long lobytes;
double ibps;
double obps;
char areacode[2][NUMSIZE];
char vorwahl[2][NUMSIZE];
char rufnummer[2][NUMSIZE];
char alias[2][NUMSIZE];
char area[2][128];
char money[64];
char currency[32];
char msg[128];
int stat;
int version;
int bchan;
double tick;
int chargeint;
int huptimeout;
char service[32];
double pay;
char digits[NUMSIZE];
int oc3;
int takteChargeInt;
int aoc;
int card;
} CALL;
/****************************************************************************/
typedef struct {
int flag;
char *time;
char *infoarg;
int interval;
char *user;
char *group;
/* char *service; */
} info_args;
/****************************************************************************/
typedef struct {
char *num;
char *who;
int zone;
int flags;
int si;
char *interface;
info_args **infoargs;
/* above from "isdnlog.conf" */
int usage[2];
double dur[2];
int eh;
double dm;
double charge;
double rcharge;
double scharge;
int day;
int month;
double online;
double sonline;
double bytes;
double sbytes;
} KNOWN;
/****************************************************************************/
typedef struct {
int in;
int out;
int eh;
int err;
double din;
double dout;
double dm;
long ibytes;
long obytes;
} sum_calls;
/****************************************************************************/
typedef struct {
int eh;
int cause;
time_t t;
int dir;
double duration;
double dm;
char num[2][NUMSIZE];
long ibytes;
long obytes;
double version;
int si;
int si1;
double currency_factor;
char currency[32];
double pay;
} one_call;
/****************************************************************************/
typedef struct {
unsigned long i;
unsigned long o;
} IO;
/****************************************************************************/
typedef struct {
char id[20];
int ch;
int dr;
int u;
int f;
char n[20];
} IFO;
/****************************************************************************/
PUBLIC KNOWN start_procs;
PUBLIC KNOWN **known;
PUBLIC int mymsns;
PUBLIC int knowns;
PUBLIC int currency_mode;
PUBLIC double currency_factor;
PUBLIC double chargemax;
PUBLIC double connectmax;
PUBLIC double bytemax;
PUBLIC int connectmaxmode;
PUBLIC int bytemaxmode;
PUBLIC char *currency;
PUBLIC int day;
PUBLIC int month;
PUBLIC int retnum;
PUBLIC int ln;
PUBLIC char retstr[MAXRET + 1][RETSIZE];
PUBLIC char Months[][4];
PUBLIC time_t cur_time;
PUBLIC section *conf_dat;
PUBLIC char ilabel[256];
PUBLIC char olabel[256];
PUBLIC char idate[256];
PUBLIC CALL call[MAXCHAN];
PUBLIC int use_new_config;
#ifdef Q931
PUBLIC int q931dmp;
#endif
PUBLIC int CityWeekend;
PUBLIC int dual;
PUBLIC char mlabel[BUFSIZ];
PUBLIC char amtsholung[NUMSIZE];
/****************************************************************************/
extern int optind, errno;
extern char *optarg;
/****************************************************************************/
#ifdef _TOOLS_C_
#define _EXTERN
_EXTERN char* reloadcmd = RELOADCMD;
_EXTERN char* stopcmd = STOPCMD;
_EXTERN char* rebootcmd = REBOOTCMD;
_EXTERN int (*_print_msg)(const char *, ...) = printf;
#else
#define _EXTERN extern
_EXTERN char* reloadcmd;
_EXTERN char* stopcmd;
_EXTERN char* rebootcmd;
_EXTERN int (*_print_msg)(const char *, ...);
#endif
_EXTERN void set_print_fct_for_tools(int (*new_print_msg)(const char *, ...));
_EXTERN int print_version(char *myname);
_EXTERN time_t atom(register char *p);
_EXTERN char *num2nam(char *num, int si);
_EXTERN char *double2str(double n, int l, int d, int flags);
_EXTERN char *double2byte(double bytes);
_EXTERN char *time2str(time_t sec);
_EXTERN char *double2clock(double n);
_EXTERN char *vnum(int chan, int who);
_EXTERN char *i2a(int n, int l, int base);
_EXTERN int iprintf(char *obuf, int chan, register char *fmt, ...);
_EXTERN char *qmsg(int type, int version, int val);
_EXTERN char *Myname;
#undef _EXTERN
/****************************************************************************/
#ifdef _ISDNCONF_C_
#define _EXTERN
#else
#define _EXTERN extern
#endif
_EXTERN int readconfig(char *myname);
_EXTERN void setDefaults(void);
_EXTERN void discardconfig(void);
_EXTERN char *t2tz(int zeit);
_EXTERN char *z2s(int zone);
_EXTERN section *read_isdnconf(section **_conf_dat);
#undef _EXTERN
/****************************************************************************/
#endif /* _TOOLS_H_ */