#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
+#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "subrou.h"
+#include "unieml.h"
#include "uniprc.h"
#include "unissl.h"
#include "devsoc.h"
#define HINTFLG AI_CANONNAME
#endif
+#define MXCARIN 200 //maximun number of char within carpile
+
typedef struct {
PROTYP proto; //Connexion protocol type
+ int handle; //connexion handle
+ SSL_CTX *ctx; //encryption context
+ int maxcarin; //absolute number within carin
+ char *EOL; //End of line marker
+ int carin; //number of char within incpt;
+ char *carpile; //area to store incoming char
char *ip; //Binding IP //IPV4 or IPV6
char *port; //Binding Port
char *hostname; //binding hostname
time_t lasttry; //successful binding last time
int iteration; //number of soc slot used on the IP
- int handle; //connexion handle
}SOCTYP;
static _Bool modopen; //module open/close status
/* */
/* */
/********************************************************/
-static SOCPTR *freebinding(SOCPTR *socptr)
+static SOCPTR *freesocket(SOCPTR *socptr)
{
if (socptr!=(SOCPTR *)0) {
soc->hostname=rou_freestr(soc->hostname);
soc->ip=rou_freestr(soc->ip);
soc->port=rou_freestr(soc->port);
+ soc->carpile=rou_freestr(soc->carpile);
(void) free(soc);
socptr=(SOCPTR *)0;
}
*/
/********************************************************/
/* */
+/* Procedure to create a new socket */
+/* */
+/* */
+/********************************************************/
+static SOCTYP *newsocket()
+
+{
+SOCTYP *soc;
+
+soc=(SOCTYP *)calloc(1,sizeof(SOCTYP));
+soc->maxcarin=MXCARIN;
+soc->carin=0;
+soc->EOL=strdup(CRLF);
+soc->carpile=(char *)calloc(soc->maxcarin,sizeof(char));
+return soc;
+}
+/*
+\f
+*/
+/********************************************************/
+/* */
+/* Procedure to duplicate a socket */
+/* */
+/********************************************************/
+static SOCTYP *dupsocket(SOCTYP *soc)
+
+{
+SOCTYP *newsoc;
+
+newsoc=(SOCTYP *)newsocket();
+newsoc->proto=soc->proto;
+newsoc->hostname=strdup(soc->hostname);
+newsoc->ip=strdup(soc->ip);
+newsoc->port=strdup(soc->port);
+newsoc->iteration=soc->iteration;
+newsoc->handle=-1;
+return newsoc;
+}
+/*
+\f
+*/
+/********************************************************/
+/* */
+/* Procedure to wait and get a new handle */
+/* */
+/********************************************************/
+static int getnewhandle(SOCTYP *soc)
+
+{
+#define OPEP "devsoc.c:getnewhandle"
+
+int newhandle;
+
+if ((newhandle=accept(soc->handle,(SOCKADDR *)0,(socklen_t *)0))<0) {
+ if (errno==EAGAIN)
+ errno=EWOULDBLOCK;
+ switch (errno) {
+ case EWOULDBLOCK :
+ (void) rou_alert(0,"%s Socket on IP/PORT <%s/%s> is in no_block mode "
+ "(Bug?!, errno=<%s>)",
+ OPEP,soc->ip,soc->port,strerror(errno));
+ break;
+ case EINVAL :
+ (void) rou_alert(0,"%s Socket on IP/PORT <%s/%s> not available "
+ "(Bug?!, errno=<%s>)",
+ OPEP,soc->ip,soc->port,strerror(errno));
+ break;
+ case EINTR :
+ (void) rou_alert(3,"%s Socket on IP/PORT <%s/%s> got a signal "
+ "(errno=<%s>)",
+ OPEP,soc->ip,soc->port,strerror(errno));
+ break;
+ default :
+ (void) rou_alert(0,"%s Unexpected error on IP/PORT <%s/%s> (errno=<%s>)",
+ OPEP,soc->ip,soc->port,strerror(errno));
+ break;
+ }
+ }
+return newhandle;
+#undef OPEP
+}
+/*
+\f
+*/
+/********************************************************/
+/* */
/* Procedure to bind a socket to a specific */
/* address and return the linked handle */
/* */
static int bindhandle(struct addrinfo *ai,SOCTYP *soc)
{
-#define OPEP "unisoc.c:bindhandle,"
+#define OPEP "devsoc.c:bindhandle,"
#define BFSZ 30 //working buffer size
int handle;
socs=(SOCTYP **)socptr;
for (i=0;socs[i]!=(SOCTYP *)0;i++) {
- socs[i]=freebinding(socs[i]);
+ socs[i]=freesocket(socs[i]);
}
(void) free(socs);
socptr=(SOCPTR **)0;
{
SOCTYP *soc;
-soc=(SOCTYP *)calloc(1,sizeof(SOCTYP));
+soc=newsocket();
soc->proto=proto;
soc->ip=strdup(ip);
soc->port=strdup(port);
PUBLIC _Bool soc_openbinding(SOCPTR *socptr)
{
-#define OPEP "unisoc.c:soc_openbinding"
+#define OPEP "devsoc.c:soc_openbinding"
_Bool done;
SOCTYP *soc;
PUBLIC void soc_closebinding(SOCPTR *socptr)
{
-#define OPEP "unisoc.c:soc_closebinding"
+#define OPEP "devsoc.c:soc_closebinding"
SOCTYP *soc;
int phase;
*/
/********************************************************/
/* */
+/* Procedure to wait for incoming character on */
+/* socket, waiting up to attend second. */
+/* */
+/********************************************************/
+PUBLIC int soc_waitforchar(SOCPTR *socptr,TIMESPEC *attend)
+
+{
+register int status;
+
+status=-1;
+if (socptr!=(SOCTYP *)0) {
+ struct pollfd polling[1];
+
+ polling[0].events=POLLIN|POLLPRI;
+ polling[0].revents=(short)0;
+ polling[0].fd=((SOCTYP *)socptr)->handle;
+ status=ppoll(polling,1,attend,(sigset_t *)0);
+ }
+return status;
+}
+/*
+^L
+*/
+/********************************************************/
+/* */
+/* Procedure to return the next available line */
+/* within the socket carpile. */
+/* */
+/********************************************************/
+PUBLIC int soc_getnextline(SOCPTR *socptr,char **lineptr)
+
+{
+#define OPEP "devsoc.c:soc_getnextline"
+
+int got;
+register SOCTYP *soc;
+char *eol;
+int phase;
+_Bool proceed;
+
+*lineptr=(char *)0;
+got=0;
+eol=(char *)0;
+soc=(SOCTYP *)socptr;
+phase=0;
+proceed=true;
+while (proceed==true) {
+ switch (phase) {
+ case 0 : //Do we have dat in carpile
+ if (soc==(SOCTYP *)0) {
+ (void) rou_alert(0,"%s, socket binding reference is NULL (Bug!?)",OPEP);
+ phase=999; //no need to go further
+ }
+ case 1 : //Do we have char available in carpile
+ if (soc->carin==0)
+ phase=999; //No char,no need to check for line
+ break;
+ case 2 : //Do we have a CRLF
+ eol=strstr(soc->carpile,soc->EOL);
+ if (eol==(char *)0)
+ phase=999; //No End Of Line yet
+ break;
+ case 3 : //duplicating carpile
+ *lineptr=calloc(soc->carin+1,sizeof(char));
+ *eol='\000';
+ (void) strcpy(*lineptr,soc->carpile);
+ (void) strcat(*lineptr,soc->EOL);
+ got=strlen(*lineptr);
+ break;
+ case 4 : //managing carpile
+ soc->carin-=strlen(*lineptr);
+ if (soc->carin>0)
+ (void) memmove(soc->carpile,soc->carpile+strlen(*lineptr),soc->carin);
+ soc->carpile[soc->carin]='\000';
+ break;
+ default : //SAFE guard
+ proceed=false;
+ break;
+ }
+ phase++;
+ }
+return got;
+#undef OPEP
+}
+/*
+^L
+*/
+/********************************************************/
+/* */
+/* Procedure to send data to a tcp socket. */
+/* return the number of character transmitted, is */
+/* unable to send char return -1; */
+/* */
+/********************************************************/
+PUBLIC int soc_writebuffer(SOCPTR *socptr,char *buffer,int tosend)
+
+{
+#define OPEP "devsoc.c:soc_writebuffer"
+
+int sent;
+SOCTYP *soc;
+
+sent=-1;
+soc=(SOCTYP *)socptr;
+if (soc!=(SOCTYP *)0) {
+ int got;
+
+ got=recv(soc->handle,(char *)0,0,MSG_PEEK);
+ switch (got) {
+ case -1 :
+ if (errno==EWOULDBLOCK)
+ errno=EAGAIN;
+ switch (errno) {
+ case EAGAIN :
+ sent=send(soc->handle,buffer,tosend,0);
+ break;
+ default :
+ (void) rou_alert(9,"%s, Unexpected status '%02d' error=<%s> (errno='%d')\n",
+ OPEP,got,strerror(errno),errno);
+ break;
+ }
+ default :
+ (void) fprintf(stderr,"Got JMPDBG'%02d'\n",got);
+ break;
+ }
+ }
+return sent;
+#undef OPEP
+}
+/*
+^L
+*/
+/********************************************************/
+/* */
+/* Procedure to read incoming character from the */
+/* socket. */
+/* */
+/********************************************************/
+PUBLIC void soc_receive(SOCPTR *socptr)
+
+{
+SOCTYP *soc;
+
+soc=(SOCTYP *)socptr;
+if (soc!=(SOCTYP *)0) {
+ int got;
+ int limit;
+
+ limit=(soc->maxcarin-soc->carin)-1;
+ got=recv(soc->handle,soc->carpile+soc->carin,limit,MSG_DONTWAIT);
+ switch (got) {
+ case -1 : //do not block
+ if (errno==EWOULDBLOCK)
+ errno=EAGAIN;
+ switch (errno) {
+ case EAGAIN : //no char available
+ break;
+ default :
+ (void) fprintf(stderr,"JMPDBG soc_receive error=<%s>\n",strerror(errno));
+ break;
+ }
+ break;
+ case 0 : //EOL?
+ break;
+ default : //we got som char from remote
+ soc->carin+=got; //managing carpile
+ soc->carpile[soc->carin]='\000';
+ break;
+ }
+ }
+}
+/*
+^L
+*/
+/********************************************************/
+/* */
/* Procedure to wait an accept a connexion comming */
/* from a remote client. */
/* return the handle */
/* */
/********************************************************/
-PUBLIC int soc_accept(SOCPTR *socptr,int pos)
+PUBLIC SOCPTR *soc_accept(SOCPTR *socptr,int pos)
{
-#define OPEP "unisoc.c:soc_accept"
+#define OPEP "devsoc.c:soc_accept"
+SOCTYP *newsoc;
int newhandle;
-register SOCTYP *soc;
+SOCTYP *soc;
+int flags;
+int phase;
+_Bool proceed;
+newsoc=(SOCTYP *)0;
newhandle=-1;
soc=(SOCTYP *)socptr;
+flags=0;
+phase=0;
+proceed=true;
+while (proceed==true) {
+ switch (phase) {
+ case 0 : //checking if soc is available
+ if (soc==(SOCTYP *)0) {
+ (void) rou_core_dump("%s, socket descripteur missing (Bug?)",OPEP);
+ phase=999; //never reached
+ }
+ break;
+ case 1 : //display ready on process status;
+ (void) prc_settitle("%s waiting on [%s:%s] (%02d/%02d)",
+ appname,soc->ip,soc->port,pos,soc->iteration);
+ break;
+ case 2 : //getting the new handle
+ if ((newhandle=getnewhandle(soc))<0) {
+ newhandle=-1;
+ phase=999; //no need to go further
+ }
+ break;
+ case 3 : //getting newhandle flag
+ if ((flags=fcntl(newhandle,F_GETFL,0))<0) {
+ (void) rou_core_dump("%s, Unable to get socket descripteur on "
+ "IP/PORT <%s/%s> (Bug? error=<%s>)",
+ OPEP,soc->ip,soc->port,strerror(errno));
+ phase=999; //never reached
+ }
+ break;
+ case 4 : //setting newhandle working mode
+ if ((flags=fcntl(newhandle,F_SETFL,flags|O_NONBLOCK|O_ASYNC))<0) {
+ (void) rou_core_dump("%s, Unable to set socket descripteur on "
+ "IP/PORT <%s/%s> (Bug? error=<%s>)",
+ OPEP,soc->ip,soc->port,strerror(errno));
+ phase=999; //never reached
+ }
+ break;
+ case 5 : //preparing a new socket
+ newsoc=dupsocket(soc);
+ newsoc->handle=newhandle;
+ break;
+ case 6 : //configuring extra socket features
+ switch (newsoc->proto) {
+ case pro_smtp : //plain socket
+ case pro_starttls : //plain socket + STARTTLS
+ phase=999;
+ break;
+ case pro_smtps : //set secure socket
+ newsoc->ctx=ssl_getctx(true); //ssl in server mode
+ break;
+ default : //undefined socket type???
+ (void) rou_alert(0,"%s, Undefined socket protocol='%d' (Bug?)",
+ OPEP,soc->proto);
+ break;
+ }
+ break;
+ default : //SAFE guard
+ proceed=false;
+ break;
+ }
+ phase++;
+ }
+return (SOCPTR *)newsoc;
+#undef OPEP
+}
+/*
+^L
+*/
+/********************************************************/
+/* */
+/* Procedure to return the addrename or port */
+/* for local or remote socket. */
+/* */
+/********************************************************/
+PUBLIC char *soc_getaddrinfo(SOCPTR *socptr,_Bool local,_Bool ip)
+
+{
+#define OPEP "devsoc.c:soc_getaddrinfo"
+
+char *data;
+SOCTYP *soc;
+int mode;
+
+data=(char *)0;
+soc=(SOCTYP *)socptr;
+mode=NI_NAMEREQD;
+if (local==false)
+ mode=NI_NUMERICHOST;
+mode|=NI_NUMERICSERV;
if (soc!=(SOCTYP *)0) {
- (void) prc_settitle("Waiting contact (%02d/%02d) on %s:%s",
- pos,soc->iteration,soc->ip,soc->port);
- if ((newhandle=accept(soc->handle,(SOCKADDR *)0,(socklen_t *)0))<0) {
- if (errno==EAGAIN)
- errno=EWOULDBLOCK;
- switch (errno) {
- case EWOULDBLOCK :
- (void) rou_alert(0,"%s Socket on IP/PORT <%s/%s> is in no_block mode "
- "(Bug?!, errno=<%s>)",
- OPEP,soc->ip,soc->port,strerror(errno));
- break;
- case EINVAL :
- (void) rou_alert(0,"%s Socket on IP/PORT <%s/%s> not available "
- "(Bug?!, errno=<%s>)",
- OPEP,soc->ip,soc->port,strerror(errno));
- break;
- case EINTR :
- (void) rou_alert(0,"%s Socket on IP/PORT <%s/%s> got a signal "
- "(errno=<%s>)",
- OPEP,soc->ip,soc->port,strerror(errno));
- break;
- default :
- (void) rou_alert(0,"%s Unexpected error on IP/PORT <%s/%s> (errno=<%s>)",
- OPEP,soc->ip,soc->port,strerror(errno));
- break;
- }
+ int status;
+ struct sockaddr connip;
+ socklen_t taille;
+ char host[NI_MAXHOST];
+ char serv[NI_MAXSERV];
+
+ taille=(socklen_t)(sizeof(connip));
+ if (local==true)
+ status=getsockname(soc->handle,&connip,&taille);
+ else
+ status=getpeername(soc->handle,&connip,&taille);
+ switch (status) {
+ case -1 : //trouble to read socket data
+ switch(errno) {
+ case ENOTCONN : //other side just vanished
+ break;
+ default :
+ (void) rou_alert(0,"%s, Unable to socket data (local=%d, error=<%s>)",
+ OPEP,local,strerror(errno));
+ break;
+ }
+ break;
+ default :
+ if (getnameinfo(&connip,taille,host,sizeof(host),serv,sizeof(serv),mode)==0) {
+ if (ip==true)
+ data=strdup(host);
+ else
+ data=strdup(serv);
+ }
+ break;
}
- else {
- int flags;
+ }
+return data;
+#undef OPEP
+}
+/*
+^L
+*/
+/********************************************************/
+/* */
+/* Procedure to close and release exchange socket */
+/* */
+/********************************************************/
+SOCPTR *soc_release(SOCPTR *socptr)
- if ((flags=fcntl(newhandle,F_GETFL,0))<0)
- (void) rou_core_dump("%s, Unable to get socket descripteur on "
- "IP/PORT <%s/%s> (Bug? error=<%s>)",
- OPEP,soc->ip,soc->port,strerror(errno));
- if ((flags=fcntl(newhandle,F_SETFL,flags|O_NONBLOCK|O_ASYNC))<0)
- (void) rou_core_dump("%s, Unable to set socket descripteur on "
- "IP/PORT <%s/%s> (Bug? error=<%s>)",
+{
+#define OPEP "devsoc.c:soc_release"
+
+SOCTYP *soc;
+int phase;
+_Bool proceed;
+
+soc=(SOCTYP *)socptr;
+phase=0;
+proceed=true;
+while (proceed==true) {
+ switch (phase) {
+ case 0 : //checking if soc is available
+ if (soc==(SOCTYP *)0) {
+ (void) rou_core_dump("%s, socket descripteur missing (Bug?)",OPEP);
+ phase=999; //never reached
+ }
+ break;
+ case 1 : //shuting dow the TCP link
+ if (shutdown(soc->handle,SHUT_RDWR)<0) {
+ switch (errno) {
+ case ENOTCONN : //already disconnect by other side!
+ (void) rou_alert(0,"%s [%s:%s] Already disconnected (errno=<%s>)",
+ OPEP,soc->ip,soc->port,strerror(errno));
+ break;
+ default :
+ (void) rou_alert(0,"%s unable to shutdown [%s:%s] (errno=<%s>)",
+ OPEP,soc->ip,soc->port,strerror(errno));
+ break;
+ }
+ }
+ break;
+ case 2 : //closing connexion
+ if (close(soc->handle)<0) {
+ (void) rou_alert(0,"%s unable to close channel [%s:%s] properly "
+ "(errno=<%s>)",
OPEP,soc->ip,soc->port,strerror(errno));
+ }
+ break;
+ case 3 : //freeing the SSL contaxt
+ soc->ctx=ssl_releasectx(soc->ctx);
+ break;
+ case 4 : //fee memory used by socket
+ soc=freesocket(soc);
+ socptr=(SOCPTR *)soc;
+ break;
+ default : //SAFE guard
+ proceed=false;
+ break;
}
+ phase++;
}
-return newhandle;
+return socptr;
#undef OPEP
}
/*
switch ((int)mode) {
case true :
(void) rou_modesubrou(mode);
+ (void) eml_modeunieml(mode);
(void) prc_modeuniprc(mode);
(void) ssl_modeunissl(mode);
break;
case false :
(void) ssl_modeunissl(mode);
(void) prc_modeuniprc(mode);
+ (void) eml_modeunieml(mode);
(void) rou_modesubrou(mode);
break;
default :
static _Bool modopen; //boolean module open/close
/*
-\f
-*/
-/********************************************************/
-/* */
-/* Procedure to find the hostname related to an */
-/* socket, if local is true return the local */
-/* hostname else return the remote PID. */
-/* if trouble, return a NULL pointer. */
-/* */
-/********************************************************/
-static char *getaddrname(int handle,_Bool local)
-
-{
-#define OPEP "gestcp.c:soc_getaddrname"
-
-char *name;
-
-struct sockaddr connip;
-socklen_t taille;
-int status;
-char host[NI_MAXHOST];
-
-name=(char *)0;
-taille=sizeof(connip);
-status=-1;
-if (local==true) {
- if ((status=getsockname(handle,&connip,&taille))==0) {
- if (getnameinfo(&connip,taille,host,sizeof(host),(char *)0,0,NI_NAMEREQD)==0)
- name=strdup(host);
- }
- }
-else {
- if ((status=getpeername(handle,&connip,&taille))==0) {
- if (getnameinfo(&connip,taille,host,sizeof(host),(char *)0,0,NI_NUMERICHOST)==0)
- name=strdup(host);
- }
- }
-if (status<0) {
- switch (errno) {
- case ENOTCONN : //other side just vanished
- break;
- default :
- (void) rou_alert(0,"%s, Unable to find reverse (local=%d, error=<%s>)",
- OPEP,local,strerror(errno));
- break;
- }
- }
-return name;
-#undef OPEP
-}
-/*
^L
*/
/********************************************************/
#define OPEP "gesttcp.c:freecontact"
if (contact!=(CONTYP *)0) {
- if (contact->channel>=0) {
- if (close(contact->channel)<0) {
- (void) rou_alert(0,"%s unable to close channel properly (errno=<%s>)",
- OPEP,strerror(errno));
- }
- }
- contact->carpile=rou_freestr(contact->carpile);
- contact->EOL=rou_freestr(contact->EOL);
contact->peerip=rou_freestr(contact->peerip);
contact->locname=rou_freestr(contact->locname);
(void) free(contact);
*/
/********************************************************/
/* */
-/* Procedure to check if char are available on */
-/* soc interface. */
-/* comming from the remote end. */
-/* */
-/********************************************************/
-static int waitforchar(CONTYP *tact,TIMESPEC *attend)
-
-{
-struct pollfd polling[1];
-
-polling[0].events=POLLIN|POLLPRI;
-polling[0].revents=(short)0;
-polling[0].fd=tact->channel;
-return ppoll(polling,1,attend,(sigset_t *)0);
-}
-/*
-^L
-*/
-/********************************************************/
-/* */
-/* Procedure to read the maximun of characters */
-/* comming from the remote end. */
-/* */
-/********************************************************/
-static void readmaxchar(CONTYP *tact)
-
-{
-int limit;
-
-limit=(tact->maxcarin-tact->carin)-1;
-if (limit>0) {
- int got;
-
- got=recv(tact->channel,tact->carpile+tact->carin,limit,MSG_DONTWAIT);
- (void) printf("readmax got '%d' char\n",got);
- switch (got) {
- case -1 : //do not block
- if (errno==EWOULDBLOCK)
- errno=EAGAIN;
- switch (errno) {
- case EAGAIN : //no char available
- break;
- default :
- (void) fprintf(stderr,"JMPDBG readmax error=<%s>\n",strerror(errno));
- break;
- }
- break;
- case 0 : //EOL?
- break;
- default : //we got som char from remote
- tact->carin+=got; //managing carpile
- tact->carpile[tact->carin]='\000';
- break;
- }
- }
-}
-/*
-^L
-*/
-/********************************************************/
-/* */
-/* Procedure to locate CRLF within the current line*/
-/* assigne memory and store carpile contents */
-/* */
-/********************************************************/
-static int getnextline(CONTYP *tact,char **lineptr)
-
-{
-int got;
-char *eol;
-int phase;
-_Bool proceed;
-
-*lineptr=(char *)0;
-got=0;
-eol=(char *)0;
-phase=0;
-proceed=true;
-while (proceed==true) {
- switch (phase) {
- case 0 : //Do we have dat in carpile
- if (tact->carin==0)
- phase=999; //No char,no need to check for line
- break;
- case 1 : //Do we have a CRLF
- eol=strstr(tact->carpile,tact->EOL);
- if (eol==(char *)0)
- phase=999; //No End Of Line yet
- break;
- case 2 : //duplicating carpile
- *lineptr=calloc(tact->carin+1,sizeof(char));
- *eol='\000';
- (void) strcpy(*lineptr,tact->carpile);
- (void) strcat(*lineptr,tact->EOL);
- got=strlen(*lineptr);
- break;
- case 3 : //managing carpile
- tact->carin-=strlen(*lineptr);
- if (tact->carin>0)
- (void) memmove(tact->carpile,tact->carpile+strlen(*lineptr),tact->carin);
- tact->carpile[tact->carin]='\000';
- break;
- default : //SAFE guard
- proceed=false;
- break;
- }
- phase++;
- }
-return got;
-}
-/*
-^L
-*/
-/********************************************************/
-/* */
/* Procedure to read char from remote peer, wait */
/* for a CRLF AS EOL. */
/* */
}
break;
case 1 : //get nextline
- if ((got=getnextline(contact,lineptr))>0)
+ if ((got=soc_getnextline(contact->socptr,lineptr))>0)
phase=999; //we got a line.
break;
case 2 : //waiting for new character presence
- switch (waitforchar(contact,attend)) {
+ switch (soc_waitforchar(contact->socptr,attend)) {
case -1 : //trouble? signal?
case 0 : //normal time out
break; //no need to read line
default : //char available
- (void) readmaxchar(contact);
+ (void) soc_receive(contact->socptr);
phase=0; //check for new line
break;
}
*/
/********************************************************/
/* */
-/* Procedure to send data to a tcp socket. */
-/* return the number of character transmitted, is */
-/* unable to send char return -1; */
+/* Procedure to write buffer on the socket output */
+/* return the number of char sent on channel. */
/* */
/********************************************************/
-PUBLIC int tcp_write(CONTYP *contact,char *buffer,int parnum)
+PUBLIC int tcp_write(CONTYP *contact,char *buffer,int tosend)
{
int sent;
-int got;
sent=-1;
-got=recv(contact->channel,(char *)0,0,MSG_PEEK);
-switch (got) {
- case -1 :
- if (errno==EWOULDBLOCK)
- errno=EAGAIN;
- switch (errno) {
- case EAGAIN :
- sent=send(contact->channel,buffer,parnum,0);
- break;
- default :
- (void) fprintf(stderr,"Got '%02d' error=<%s> (errno='%d')\n",
- got,strerror(errno),errno);
- break;
- }
- break;
- default :
- (void) fprintf(stderr,"Got '%02d'\n",got);
- break;
- }
+if (contact!=(CONTYP *)0)
+ sent=soc_writebuffer(contact->socptr,buffer,tosend);
return sent;
}
/*
break;
case 1 : //waiting from contact
contact=calloc(1,sizeof(CONTYP));
- contact->socptr=socptr;
- contact->maxcarin=MXCARIN;
- contact->carin=0;
- contact->EOL=strdup(CRLF);
- contact->carpile=(char *)calloc(contact->maxcarin,sizeof(char));
- if ((contact->channel=soc_accept(socptr,pos))<0) {
+ if ((contact->socptr=soc_accept(socptr,pos))==(SOCPTR *)0) {
(void) rou_alert(0,"%s Unable to open contact",OPEP);
contact=freecontact(contact);
phase=999; //no contact
}
break;
case 2 : //check socket components
- contact->locname=getaddrname(contact->channel,true);
- contact->peerip=getaddrname(contact->channel,false);
+ contact->locname=soc_getaddrinfo(contact->socptr,true,false);
+ contact->peerip=soc_getaddrinfo(contact->socptr,false,false);
if ((contact->locname==(char *)0)||(contact->peerip==(char *)0)) {
(void) rou_alert(0,"%s Unable to establish contact entities",OPEP);
contact=freecontact(contact);
break;
case 1 : //properly closing remote contact
(void) rou_alert(0,"Contact with IP=<%s> Exiting",contact->peerip);
- if (shutdown(contact->channel,SHUT_RDWR)<0) {
- switch (errno) {
- case ENOTCONN : //already disconnect by other side!
- (void) rou_alert(0,"%s Already disconnected (errno=<%s>)",
- OPEP,strerror(errno));
- break;
- default :
- (void) rou_alert(0,"%s unable to shutdown (errno=<%s>)",
- OPEP,strerror(errno));
- break;
- }
- }
+ contact->socptr=soc_release(contact->socptr);
break;
case 2 : //freeing contact memory
contact=freecontact(contact);