isdn4k-utils/isdnlog/connect/socket.c

496 lines
11 KiB
C

/*
* 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;
}
/****************************************************************************/