162 lines
4.1 KiB
C
162 lines
4.1 KiB
C
#include <assert.h>
|
|
#include "coc.h"
|
|
/*-------------------------------------------------------------------------*/
|
|
/* CreateSocketAddress stolen from Tcl. Thanks to John Ousterhout */
|
|
|
|
CocVar *serverVarList=NULL;
|
|
static CocVar **varListHdl=&serverVarList;
|
|
int CocRD=0;
|
|
int CocWR=0;
|
|
|
|
int CocCreateSockAdr(
|
|
struct sockaddr_in *sockaddrPtr, /* Socket address */
|
|
const char *host, /* Host. NULL implies INADDR_ANY */
|
|
int port) /* Port number */
|
|
{
|
|
struct hostent *hostent; /* Host database entry */
|
|
struct in_addr addr; /* For 64/32 bit madness */
|
|
|
|
(void) memset((char *) sockaddrPtr, '\0', sizeof(struct sockaddr_in));
|
|
sockaddrPtr->sin_family = AF_INET;
|
|
sockaddrPtr->sin_port = htons((unsigned short) (port & 0xFFFF));
|
|
if (host == NULL) {
|
|
addr.s_addr = INADDR_ANY;
|
|
} else {
|
|
hostent = gethostbyname(host);
|
|
if (hostent != NULL) {
|
|
memcpy((char *) &addr,
|
|
(char *) hostent->h_addr_list[0], (size_t) hostent->h_length);
|
|
} else {
|
|
addr.s_addr = inet_addr(host);
|
|
if (addr.s_addr == (unsigned long)-1) {
|
|
return -1; /* error */
|
|
}
|
|
}
|
|
}
|
|
/*
|
|
* There is a rumor that this assignment may require care on
|
|
* some 64 bit machines.
|
|
*/
|
|
|
|
sockaddrPtr->sin_addr.s_addr = addr.s_addr;
|
|
return 0;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
int CocRecv(int fd, buf_type *buf)
|
|
{
|
|
struct timeval tmo={0,1};
|
|
fd_set mask;
|
|
int i, ret;
|
|
|
|
tmo.tv_sec=5; /* timeout 5 sec. */
|
|
|
|
FD_ZERO(&mask);
|
|
FD_SET(fd, &mask);
|
|
ERR_SI(i=select(fd+1,&mask,NULL,NULL,&tmo));
|
|
if (i==0) ERR_MSG("time out");
|
|
|
|
buf_put_start(buf);
|
|
ERR_SI(ret=recv(fd, buf->buf, buf->isize, 0));
|
|
if (ret==0) { ERR_COD(ECONNRESET); }
|
|
buf->usize=ret;
|
|
buf_reset(buf);
|
|
return(ret);
|
|
OnError: return(-1);
|
|
}
|
|
|
|
void CocVarList(CocVar **varList) {
|
|
assert(varList!=NULL);
|
|
varListHdl=varList;
|
|
}
|
|
|
|
CocVar *CocFindVar(CocVar *varList, const char *name) {
|
|
CocVar *p;
|
|
|
|
p=varList;
|
|
while (p!=NULL && 0!=strcmp(p->name,name)) p=p->next;
|
|
return(p);
|
|
}
|
|
|
|
void CocDefVar(const char *name, void *var, int type, int *flag) {
|
|
CocVar *p;
|
|
|
|
assert(varListHdl!=NULL);
|
|
p=CocFindVar(*varListHdl, name);
|
|
if (p==NULL) {
|
|
p=malloc(sizeof(*p));
|
|
p->next=*varListHdl;
|
|
*varListHdl=p;
|
|
}
|
|
str_copy(p->name, name);
|
|
p->var=var;
|
|
p->type=type;
|
|
p->flag=flag;
|
|
}
|
|
|
|
int CocGetVar(CocVar *varList, buf_type *buf, const char *name) {
|
|
CocVar *var;
|
|
|
|
var=CocFindVar(varList, name);
|
|
if (var==NULL) ERR_MSG("undefined variable");
|
|
if (varList==serverVarList) { /* we are the server */
|
|
if (var->flag==&CocRD) ERR_MSG("variable is read only");
|
|
}
|
|
if (var->type==-1) {
|
|
*(int *)var->var=buf_get_int(buf);
|
|
} else if (var->type==-2) {
|
|
*(float *)var->var=buf_get_float(buf);
|
|
} else if (var->type>1) {
|
|
str_ncpy((char *)var->var, buf_get_str(buf), var->type);
|
|
} else {
|
|
ERR_MSG("unknown type");
|
|
}
|
|
if (varList==serverVarList) { /* we are the server */
|
|
if (var->flag!=NULL) (*var->flag)++;
|
|
}
|
|
return(0);
|
|
OnError: return(-1);
|
|
}
|
|
|
|
int CocPutVar(CocVar *varList, buf_type *buf, const char *name) {
|
|
CocVar *var;
|
|
char *c;
|
|
|
|
var=CocFindVar(varList, name);
|
|
if (var==NULL) ERR_MSG("undefined variable");
|
|
if (varList!=serverVarList) { /* we are a client */
|
|
if (var->flag==&CocRD) ERR_MSG("variable is read only");
|
|
}
|
|
if (var->type==-1) {
|
|
buf_put_int(buf, *(int *)var->var);
|
|
} else if (var->type==-2) {
|
|
buf_put_float(buf, *(float *)var->var);
|
|
} else if (var->type>1) {
|
|
c=var->var;
|
|
if (c[0]<=2 && c[0]!=0) { ERR_MSG("illegal string"); }
|
|
buf_put_str(buf, c);
|
|
} else {
|
|
ERR_MSG("unknown type");
|
|
}
|
|
if (varList!=serverVarList) { /* we are a client */
|
|
if (var->flag!=NULL) (*var->flag)++;
|
|
}
|
|
return(0);
|
|
OnError: return(-1);
|
|
}
|
|
|
|
void CocFreeVarList(CocVar **varList) {
|
|
CocVar *p, *v;
|
|
|
|
if (varList==NULL) varList=&serverVarList;
|
|
v=*varList;
|
|
while (v!=NULL) {
|
|
p=v;
|
|
v=p->next;
|
|
p->next=NULL;
|
|
free(p);
|
|
}
|
|
*varList=NULL;
|
|
}
|