#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 COPYRIGHT: Public domain */ #include "config.h" #include #include #include #include #include #include #include #ifdef HAVE_SYS_SELECT_H #include #endif #include #include #include #include #include #include #include #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 1) || (lfcount > 1)) break; } buf[off]='\0'; #ifdef _REENTRANT close(FD); FD=-1; #endif return 0; }