#include #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 || host[0]=='\0') { 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 */ (*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 the 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; }