#ifndef LINT
static char *rcsid="$Id: clnt_unix.c,v 1.16 2001/07/20 07:35:54 crosser Exp $";
#endif
/*
$Log: clnt_unix.c,v $
Revision 1.16 2001/07/20 07:35:54 crosser
more tuning of AF_UNIX address size, now works on FreeBSD
Revision 1.15 2001/07/20 05:48:59 crosser
address bug with AF_UNIX address size
fix permissions of unix datagram socket (on Linux, honors umask)
Revision 1.14 1999/10/06 15:54:03 crosser
fix for kluge about initializing private fields
Initialization for global parameters
Revision 1.13 1999/10/03 21:18:03 crosser
First (probably) working version with new run time config parser.
Also added listenq parameter (backlog size for listen()) and
renamed wtest to whoson (and with man page). Release 2.00beta1.
Revision 1.12 1999/08/19 17:22:14 crosser
Move to new config scheme (does not work yet)
Revision 1.11 1999/07/27 17:30:05 crosser
fix names
Revision 1.10 1999/06/02 22:10:36 crosser
deal with UNIX_PATH_MAX in a better way
Revision 1.9 1999/01/30 14:41:05 crosser
fix use of saved errno
Revision 1.8 1998/07/26 14:06:40 crosser
fix for multiline responces
Revision 1.7 1998/07/12 16:43:57 crosser
Change protocol: responce now is terminated with empty line
Revision 1.6 1998/07/05 00:26:18 crosser
Change copyright
Revision 1.5 1998/07/03 11:10:39 crosser
setup for _REENTRANT mode
Revision 1.4 1998/07/03 09:32:48 crosser
make persistant connections work
Revision 1.3 1998/07/02 18:01:15 crosser
change error reporting to syslog
Revision 1.2 1998/07/02 15:37:07 crosser
make right return if req invalid or disallowed
Revision 1.1 1998/07/01 21:55:16 crosser
Initial revision
*/
/*
WHAT IS IT:
Implementation of experimental "whoson" protocol
AUTHOR:
Eugene G. Crosser <crosser@average.org>
COPYRIGHT:
Public domain
*/
#include "config.h"
#include <sys/types.h>
#include <time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/un.h>
#include <netdb.h>
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "whoson.h"
#include "rtconfig.h"
#include "clnt_common.h"
#include "report.h"
#include "rtc_begin.h"
#include "clnt_unix_cfg.h"
#include "rtc_middle.h"
#include "clnt_unix_cfg.h"
#include "rtc_end.h"
#define MAXTRIES 3
#define MAXREQL 1024
int wso_unix_clnt_connect(void *priv,char *buf)
{
wso_clnt_unix_cfg *rec=(wso_clnt_unix_cfg *)(priv);
struct sockaddr_un server;
int len,off,left,crcount,lfcount,saveerr;
char *p;
int tries=0;
RETSIGTYPE (*savepipe)(int);
#ifdef _REENTRANT
int fd=-1;
#define FD fd
#else
#define FD rec->fd
#endif
DPRINT(("unix_connect at entry fd=%d\n",FD))
if (FD >= 0) goto session;
reconnect:
memset((char *)&server,0,sizeof(server));
server.sun_family = AF_UNIX;
strncpy(server.sun_path,rec->port,sizeof(server.sun_path)-1);
server.sun_path[sizeof(server.sun_path)-1]='\0';
if ((FD=socket(AF_UNIX,SOCK_STREAM,0)) < 0) {
ERRLOG((LOG_ERR,"[WHOSON] server socket: %m"))
return -1;
}
if (connect(FD,(struct sockaddr *)&server,
sizeof(server)-sizeof(server.sun_path)+
strlen(server.sun_path)+1) < 0) {
ERRLOG((LOG_ERR,"[WHOSON] connect server: %m"))
close(FD);
FD=-1;
return -1;
}
session:
savepipe=signal(SIGPIPE,SIG_IGN);
len=write(FD,buf,strlen(buf));
saveerr=errno;
(void)signal(SIGPIPE,savepipe);
errno=saveerr;
if (len != strlen(buf)) {
if ((errno == EPIPE) && (++tries < MAXTRIES)) {
DPRINT(("server gone (write), reconnecting %d\n",tries))
close(FD);
goto reconnect;
}
ERRLOG((LOG_ERR,"[WHOSON] write to server: %m"))
close(FD);
FD=-1;
return -1;
}
off=0;
left=MAXREQL-1;
crcount=0;
lfcount=0;
while (left) {
if ((len=read(FD,buf+off,left)) < 0) {
if ((errno == EPIPE) && (++tries < MAXTRIES)) {
DPRINT(("server gone (read), reconnect %d\n",
tries))
close(FD);
goto reconnect;
}
ERRLOG((LOG_ERR,"[WHOSON] read from server: %m"))
close(FD);
FD=-1;
return -1;
}
if (len == 0) break;
for (p=buf+off;
(p<buf+MAXREQL) && (crcount<2) && (lfcount<2);
p++)
switch (*p) {
case '\r': crcount++;
break;
case '\n': lfcount++;
break;
default: crcount=0; lfcount=0;
break;
}
off+=len;
left-=len;
if ((crcount > 1) || (lfcount > 1)) break;
}
buf[off]='\0';
#ifdef _REENTRANT
close(FD);
FD=-1;
#endif
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1