#ifndef LINT
static char *rcsid="$Id: clnt_common.c,v 1.11 2003/08/14 12:50:33 crosser Exp $";
#endif
/*
$Log: clnt_common.c,v $
Revision 1.11 2003/08/14 12:50:33 crosser
Memory leak in the client code (ilya@glas.net)
Changes to recent autoconf/automake (woods@weird.com)
use pidfile() if it exists (woods@weird.com)
Revision 1.10 1999/07/27 17:17:18 crosser
remove include version.h
Revision 1.9 1998/07/26 14:06:40 crosser
fix ret code if no servers
Revision 1.8 1998/07/12 16:43:57 crosser
Change protocol: responce now is terminated with empty line
Revision 1.7 1998/07/05 00:26:18 crosser
Change copyright
Revision 1.6 1998/07/04 23:39:35 crosser
wso_version
Revision 1.4 1998/07/02 18:01:15 crosser
change API
Revision 1.3 1998/07/02 15:37:07 crosser
persistent config
Revision 1.2 1998/07/01 05:01:22 crosser
Big reorganization
Revision 1.1 1998/05/05 19:08: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 <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#ifdef _REENTRANT
#include <pthread.h>
#endif
#include "whoson.h"
#include "rtconfig.h"
#include "report.h"
#define MAXREQL 1024
int wso_verbose=0;
static struct _servdesc *servdesc=NULL;
static int wso_request(char *verb,char *addr,char *name,
char *cbuf,int buflen) {
char buf[MAXREQL],*p;
int len=0;
int rc=-1;
char *configfile=DEFAULT_CONFIG;
struct _servdesc *next_server;
#ifdef _REENTRANT
static pthread_mutex_t mutex;
#endif
len=strlen(verb);
if (addr) len+=strlen(addr);
if (name) len+=strlen(name);
len+=7;
if (len > sizeof(buf)) {
ERRLOG((LOG_ERR,"[WHOSON] Request does not fit in %d bytes\n",
sizeof(buf)))
return -1;
}
sprintf(buf,"%s %s %s\r\n\r\n",
verb,
addr?addr:"",
name?name:"");
/* Note that in MT-safe version, we first check if config is filled
outside of the mutex, to avoid fiddling with the locks if we are
not going to change anything anyway. As a result, we need to check
the same thing *again* within the mutex-locked portion. Hope this
is still cheaper than locking again each time... */
if (!servdesc) {
#ifdef _REENTRANT
pthread_mutex_init(&mutex,(pthread_mutexattr_t*)0);
pthread_mutex_lock(&mutex);
if (!servdesc)
#endif
{
if (getenv("WHOSON_VERBOSE")) wso_verbose=1;
if ((configfile=getenv("WHOSON_CONFIG")) == NULL)
configfile=DEFAULT_CONFIG;
servdesc=wso_read_config(configfile,0);
}
if (!servdesc) {
ERRLOG((LOG_ERR,"[WHOSON] No configured servers\n"))
return -1;
}
#ifdef _REENTRANT
pthread_mutex_unlock(&mutex);
pthread_mutex_destroy(&mutex);
#endif
}
for (next_server = servdesc;next_server;next_server=servdesc->next) {
DPRINT(("trying next connector\n"))
if ((rc=(next_server->root.connector)(next_server->priv,buf))
>= 0)
break;
}
if (rc >= 0) switch (buf[0]) {
case '+': rc=0; break;
case '-': rc=+1; break;
default: rc=-1; break;
}
if (cbuf && buflen) {
strncpy(cbuf,buf+1,buflen-1);
cbuf[buflen-1]='\0';
if ((p=strchr(cbuf,'\n'))) *p='\0';
if ((p=strchr(cbuf,'\r'))) *p='\0';
DPRINT(("returning: \"%s\"\n",cbuf))
}
return rc;
}
char *wso_version(void)
{
return "Version " VERSION " Build " __DATE__;
}
int wso_login(char *addr,char *name,char *buf,int buflen) {
return wso_request("LOGIN",addr,name,buf,buflen);
}
int wso_logout(char *addr,char *buf,int buflen) {
return wso_request("LOGOUT",addr,NULL,buf,buflen);
}
int wso_query(char *addr,char *buf,int buflen) {
return wso_request("QUERY",addr,NULL,buf,buflen);
}
syntax highlighted by Code2HTML, v. 0.9.1