new tecs version M.Z.08.2001
This commit is contained in:
@@ -1,67 +1,449 @@
|
||||
/* needed to define accept() and gethostbyaddr() correctly when using flag -std1
|
||||
*/
|
||||
#ifdef __unix__
|
||||
#ifndef _XOPEN_SOURCE_EXTENDED
|
||||
#define _XOPEN_SOURCE_EXTENDED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "myc_mem.h"
|
||||
#include "sys_util.h"
|
||||
#include "err_handling.h"
|
||||
#include "myc_err.h"
|
||||
#include "coc_logfile.h"
|
||||
#include "coc_util.h"
|
||||
#include "coc_server.h"
|
||||
#include "str_util.h"
|
||||
#include "myc_str.h"
|
||||
#include "myc_time.h"
|
||||
|
||||
static Str_Buf *buf, *bufo;
|
||||
#define COC_NUL COC_SEP
|
||||
|
||||
typedef struct _CocVar {
|
||||
struct _CocVar *next;
|
||||
char name[32];
|
||||
void *var;
|
||||
int access;
|
||||
int type;
|
||||
void *strucType;
|
||||
int (*hdl)(int, void *);
|
||||
int pending;
|
||||
} CocVar;
|
||||
|
||||
CocVar *serverVarList=NULL;
|
||||
static CocVar **varListHandle=&serverVarList;
|
||||
static CocVar *lastDef=NULL;
|
||||
|
||||
typedef struct {
|
||||
CocVar *var;
|
||||
void *base;
|
||||
int mode;
|
||||
} Pend;
|
||||
|
||||
typedef struct _CocClient {
|
||||
struct _CocClient *next;
|
||||
int fd;
|
||||
int mode;
|
||||
Pend pend[16];
|
||||
int npend;
|
||||
int logmask;
|
||||
char synch;
|
||||
void *data;
|
||||
} CocClient;
|
||||
|
||||
void *(*setData)(void *);
|
||||
|
||||
/*
|
||||
static CocClientData **clData;
|
||||
static int clDataSize;
|
||||
*/
|
||||
|
||||
DeclStrBuf(buf, COC_CMD_LEN);
|
||||
DeclStrBuf(bufo, COC_RES_LEN);
|
||||
|
||||
static fd_set mask, rmask;
|
||||
static int maxfd;
|
||||
struct CocClient *cList, *cLastCmd=NULL;
|
||||
CocClient *cList;
|
||||
static int mainFd;
|
||||
static int modified;
|
||||
static char loglist[16];
|
||||
|
||||
int CocInitServer(int bufsize, int port) {
|
||||
void CocVarList(void **varList) {
|
||||
if (varList==NULL) {
|
||||
varListHandle=(CocVar **)varList;
|
||||
} else {
|
||||
varListHandle=&serverVarList;
|
||||
}
|
||||
}
|
||||
|
||||
void CocList() {
|
||||
CocVar *p;
|
||||
|
||||
p=*varListHandle;
|
||||
while (p!=NULL) {
|
||||
printf("%s %d ", p->name, p->type);
|
||||
p=p->next;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
CocVar *CocFindVar1(const char *name) {
|
||||
CocVar *p;
|
||||
|
||||
p=*varListHandle;
|
||||
while (p!=NULL && 0!=strcasecmp(p->name,name)) p=p->next;
|
||||
return(p);
|
||||
}
|
||||
|
||||
void *CocFindVar(const char *name, void **adr) {
|
||||
CocVar *p, *t;
|
||||
const char *f;
|
||||
void *base;
|
||||
char nam[32];
|
||||
|
||||
f=str_split(nam, name, '.');
|
||||
if (f==NULL) {
|
||||
f=str_split(nam, name, '-');
|
||||
if (f!=NULL) {
|
||||
if (f[0]!='>') {
|
||||
f=NULL;
|
||||
} else {
|
||||
f++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (f!=NULL) {
|
||||
if (adr!=NULL) *adr=NULL;
|
||||
p=CocFindVar1(nam);
|
||||
if (p==NULL) { return(NULL); }
|
||||
t=p->strucType;
|
||||
if (t==NULL) { return(NULL); }
|
||||
str_copy(nam, t->name);
|
||||
str_append(nam, ":");
|
||||
str_append(nam, f);
|
||||
if (adr!=NULL) {
|
||||
base=p->var;
|
||||
if (p->type==COC_PTR) base=*(void **)base;
|
||||
*adr=base;
|
||||
}
|
||||
} else if (adr!=NULL) {
|
||||
*adr=NULL;
|
||||
}
|
||||
p=CocFindVar1(nam);
|
||||
if (p!=NULL && p->type==COC_ALIAS) { /* recursive call for alias */
|
||||
p=CocFindVar(p->var, adr);
|
||||
}
|
||||
return(p);
|
||||
}
|
||||
|
||||
void *CocIntPtr(int *ptr) { return(ptr); }
|
||||
void *CocFltPtr(float *ptr) { return(ptr); }
|
||||
void *CocChrPtr(char *ptr) { return(ptr); }
|
||||
|
||||
void *CocDefVar(const char *name, void *var, int type, int access) {
|
||||
CocVar *p;
|
||||
const char *f;
|
||||
void *adr;
|
||||
|
||||
assert(varListHandle!=NULL);
|
||||
p=CocFindVar1(name);
|
||||
if (p==NULL) {
|
||||
NEW(p,CocVar);
|
||||
p->next=*varListHandle;
|
||||
*varListHandle=p;
|
||||
str_copy(p->name, name);
|
||||
p->type=type;
|
||||
} else {
|
||||
assert(p->type==type);
|
||||
}
|
||||
p->var=var;
|
||||
p->access=access;
|
||||
/* printf("define %s %d\n", name, (int)var); */
|
||||
lastDef=p;
|
||||
return(p);
|
||||
OnError:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void CocHdl(int (*handler)(int, void *)) {
|
||||
assert(lastDef!=NULL);
|
||||
lastDef->hdl=handler;
|
||||
}
|
||||
|
||||
void CocDefVarS(const char *name, const char *tname, void *var, int type) {
|
||||
CocVar *p, *t;
|
||||
|
||||
assert(type==COC_PTR || type==COC_STRUCT);
|
||||
p=CocDefVar(name, var, type, COC_RDONLY);
|
||||
p->strucType=CocDefVar(tname, NULL, COC_TYPE, COC_RDONLY);
|
||||
}
|
||||
|
||||
char err_name[64];
|
||||
|
||||
int CocGetThisVar(CocVar *var, void *base, StrBuf *buf, int separator) {
|
||||
void *adr;
|
||||
int iret;
|
||||
|
||||
if (base==NULL) {
|
||||
adr=var->var;
|
||||
if (adr==NULL)
|
||||
ERR_MSG("NULL pointer accessed");
|
||||
} else { /* dereference */
|
||||
adr=(char *)base + (int)var->var;
|
||||
}
|
||||
/* printf("get %s %d\n", name, (int)adr); */
|
||||
if (var->type==-1) {
|
||||
ERR_I(StrGetInt(buf, (int *)adr, separator));
|
||||
} else if (var->type==-2) {
|
||||
ERR_I(StrGetFloat(buf, (float *)adr, separator));
|
||||
} else if (var->type>1) {
|
||||
ERR_P(StrNGet(buf, (char *)adr, var->type, separator));
|
||||
} else {
|
||||
ERR_MSG("unknown type");
|
||||
}
|
||||
return(0);
|
||||
OnError: return(-1);
|
||||
}
|
||||
|
||||
int CocPutThisVar(CocVar *var, void *base, StrBuf *buf, int separator) {
|
||||
void *adr;
|
||||
int iret;
|
||||
|
||||
if (base==NULL) {
|
||||
adr=var->var;
|
||||
if (adr==NULL)
|
||||
ERR_MSG("NULL pointer accessed");
|
||||
} else { /* dereference */
|
||||
adr=(char *)base + (int)var->var;
|
||||
}
|
||||
/* printf("put %s %d\n", name, (int)adr); */
|
||||
if (var->type==-1) {
|
||||
ERR_I(StrPutInt(buf, *(int *)adr, separator));
|
||||
} else if (var->type==-2) {
|
||||
ERR_I(StrPutFloat(buf, *(float *)adr, separator));
|
||||
} else if (var->type>1) {
|
||||
ERR_I(StrPut(buf, adr, separator));
|
||||
} else {
|
||||
ERR_MSG("unknown type");
|
||||
}
|
||||
return(0);
|
||||
OnError: return(-1);
|
||||
}
|
||||
|
||||
int CocGetVar(const char *name, StrBuf *buf, int separator) {
|
||||
CocVar *var;
|
||||
void *base;
|
||||
|
||||
var=CocFindVar(name, &base);
|
||||
if (var==NULL) ERR_MSG("undefined variable");
|
||||
ERR_I(CocGetThisVar(var, base, buf, separator));
|
||||
return(0);
|
||||
OnError: str_copy(err_name, name); ErrTxt(err_name,0); return(-1);
|
||||
}
|
||||
|
||||
int CocPutVar(const char *name, StrBuf *buf, int separator) {
|
||||
CocVar *var;
|
||||
void *base;
|
||||
|
||||
var=CocFindVar(name, &base);
|
||||
if (var==NULL) ERR_MSG("undefined variable");
|
||||
ERR_I(CocPutThisVar(var, base, buf, separator));
|
||||
return(0);
|
||||
OnError: str_copy(err_name, name); ErrTxt(err_name,0); return(-1);
|
||||
}
|
||||
|
||||
void CocFreeVarList(void) {
|
||||
CocVar *p, *v;
|
||||
|
||||
v=*varListHandle;
|
||||
while (v!=NULL) {
|
||||
p=v;
|
||||
v=p->next;
|
||||
p->next=NULL;
|
||||
FREE(p);
|
||||
}
|
||||
*varListHandle=NULL;
|
||||
}
|
||||
|
||||
void CocToClients(int mask, char *str) {
|
||||
int iret;
|
||||
CocClient *cl;
|
||||
|
||||
cl=cList->next;
|
||||
while (cl!=NULL) {
|
||||
if (cl->logmask & mask) {
|
||||
iret=CocSend(cl->fd, str, strlen(str)+1);
|
||||
if (iret<0) {
|
||||
cl->logmask=0; /* disable logging for dead clients */
|
||||
logfileOut(LOG_MAIN, "(%d) disconnected while logging\n", cl->fd);
|
||||
}
|
||||
}
|
||||
cl=cl->next;
|
||||
}
|
||||
}
|
||||
|
||||
int CocInitServer(void *(*setDataRtn)(void *), int port) {
|
||||
int i;
|
||||
struct sockaddr_in sadr;
|
||||
char *err;
|
||||
|
||||
if (bufsize==0) bufsize=1024;
|
||||
ERR_P(buf=str_create_buf(bufsize, '\0'));
|
||||
ERR_P(bufo=str_create_buf(bufsize,'\0'));
|
||||
NEW(cList); /* empty header */
|
||||
|
||||
/* first try to connect to an existing server */
|
||||
setData=setDataRtn;
|
||||
/*
|
||||
clDataSize=clientDataSize;
|
||||
clData=clientData;
|
||||
*/
|
||||
NEW(cList,CocClient); /* empty header */
|
||||
|
||||
ERR_SI(mainFd=socket(AF_INET, SOCK_STREAM, 0));
|
||||
i = 1;
|
||||
ERR_SI(setsockopt(mainFd,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(int))); /* allow quick port reuse */
|
||||
ERR_I(CocCreateSockAdr(&sadr, NULL, port));
|
||||
ERR_SI(bind(mainFd, (struct sockaddr *)&sadr, sizeof(sadr)));
|
||||
logfileOutRtn=CocToClients;
|
||||
logfileOut(LOG_INFO, "created server on port %d\n", port);
|
||||
ERR_SI(listen(mainFd, 8));
|
||||
FD_ZERO(&mask);
|
||||
FD_SET(mainFd, &mask);
|
||||
maxfd=mainFd+1;
|
||||
CocDefStr(loglist, COC_RDWR);
|
||||
return(0);
|
||||
OnError: return(-1);
|
||||
}
|
||||
|
||||
int CocHandleThis(CocVar *var, void *base, StrBuf *outBuf, int mode) {
|
||||
int iret;
|
||||
|
||||
if (var->hdl!=NULL) {
|
||||
iret=var->hdl(mode, base);
|
||||
if (iret<0) { /* error */
|
||||
ErrShow(var->name);
|
||||
ERR_I(StrPut(outBuf, "", COC_ERR)); /* signal error message */
|
||||
ERR_I(StrPut(outBuf, ErrMessage, COC_SEP));
|
||||
return(0);
|
||||
}
|
||||
if (iret==COC_DRD) {
|
||||
ERR_I(StrPut(outBuf, "", COC_DELAYED)); /* delayed response message */
|
||||
ERR_I(StrPut(outBuf, "", COC_SEP)); /* empty message */
|
||||
return(COC_DRD);
|
||||
}
|
||||
if (iret!=0 && iret!=COC_DWR)
|
||||
ERR_MSG("illegal return value from handler");
|
||||
} else {
|
||||
iret=0;
|
||||
}
|
||||
ERR_I(CocPutThisVar(var, base, outBuf, COC_NUL));
|
||||
return(iret);
|
||||
OnError: return(-1);
|
||||
}
|
||||
|
||||
int CocPushThisHandler(CocVar *var, CocClient *cl, void *base, int mode) {
|
||||
int n;
|
||||
|
||||
if (mode==COC_DWR) {
|
||||
if (var->pending) return(0);
|
||||
var->pending=1;
|
||||
}
|
||||
n=cl->npend;
|
||||
if (n>=sizeof(cl->pend)) {
|
||||
ERR_MSG("too many commands")
|
||||
}
|
||||
cl->pend[n].var=var;
|
||||
cl->pend[n].base=base;
|
||||
cl->pend[n].mode=mode;
|
||||
cl->npend=n+1;
|
||||
return(0);
|
||||
OnError: return(-1);
|
||||
}
|
||||
|
||||
int CocCallHandlers(void) {
|
||||
CocClient *cl;
|
||||
CocVar *var;
|
||||
Pend *p;
|
||||
int i, iret, mode, delayedRead;
|
||||
char synch;
|
||||
DeclStrBuf(bufr, COC_RES_LEN);
|
||||
|
||||
cl=cList->next;
|
||||
while (cl!=NULL) {
|
||||
|
||||
delayedRead=0;
|
||||
/* treat delayed write handlers first */
|
||||
for (i=0; i<cl->npend; i++) {
|
||||
p=&cl->pend[i];
|
||||
mode=p->mode;
|
||||
var=p->var;
|
||||
assert(var!=NULL && var->hdl!=NULL);
|
||||
if (mode==COC_DWR) {
|
||||
var->pending=0;
|
||||
ERR_I(var->hdl(mode, p->base));
|
||||
p->mode=0;
|
||||
} else {
|
||||
delayedRead=1;
|
||||
}
|
||||
}
|
||||
if (delayedRead) {
|
||||
StrClear(&bufr);
|
||||
synch=cl->synch;
|
||||
ERR_I(StrPut(&bufr, "", cl->synch));
|
||||
for (i=0; i<cl->npend; i++) {
|
||||
p=&cl->pend[i];
|
||||
mode=p->mode;
|
||||
var=p->var;
|
||||
assert(var!=NULL && var->hdl!=NULL);
|
||||
if (mode==COC_DRD) {
|
||||
iret=var->hdl(mode, p->base);
|
||||
if (iret<0) { /* error */
|
||||
ERR_I(StrPut(&bufr, "", COC_ERR)); /* signal error message */
|
||||
ERR_I(StrPut(&bufr, ErrMessage, COC_SEP));
|
||||
}
|
||||
ERR_I(CocPutThisVar(var, p->base, &bufr, COC_NUL));
|
||||
}
|
||||
}
|
||||
if (cl->synch==synch) { /* send only if no new request from client received */
|
||||
assert(cl->fd!=0);
|
||||
ERR_I(CocSend(cl->fd, bufr.buf, bufr.wrpos));
|
||||
}
|
||||
}
|
||||
cl->npend=0;
|
||||
cl=cl->next;
|
||||
}
|
||||
return(0);
|
||||
OnError:
|
||||
cl->npend=0;
|
||||
return(-1);
|
||||
}
|
||||
|
||||
void CocShowHandlers(char *buf, int buf_len) {
|
||||
CocClient *cl;
|
||||
Pend *p;
|
||||
int i;
|
||||
|
||||
buf[0]='\0';
|
||||
cl=cList->next;
|
||||
while (cl!=NULL) {
|
||||
for (i=0; i<cl->npend; i++) {
|
||||
p=&cl->pend[i];
|
||||
if (p->mode==COC_DWR) {
|
||||
assert(p->var!=NULL);
|
||||
if (buf[0]!='\0') str_ncat(buf, ", ", buf_len);
|
||||
str_ncat(buf, p->var->name, buf_len);
|
||||
}
|
||||
}
|
||||
cl=cl->next;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int CocHandle1Request(int tmo_msec, int fd) {
|
||||
struct sockaddr_in cadr;
|
||||
struct hostent *h;
|
||||
struct timeval tmo={0,1};
|
||||
struct CocClient *cl, *cl0;
|
||||
int i, newfd, setmode;
|
||||
size_t cadrlen;
|
||||
char *err, *varname;
|
||||
CocClient *cl, *cl0;
|
||||
CocVar *var;
|
||||
int i, lmask, newfd, n, iret;
|
||||
sys_adr_len cadrlen; /* see sys_util.h */
|
||||
char *err, *cmd, *arg, *varname;
|
||||
void *base;
|
||||
|
||||
rmask=mask;
|
||||
if (fd>0) FD_SET(fd, &rmask);
|
||||
@@ -76,14 +458,18 @@ int CocHandle1Request(int tmo_msec, int fd) {
|
||||
ERR_SI(newfd=accept(mainFd, (struct sockaddr *)&cadr, &cadrlen));
|
||||
FD_SET(newfd, &mask);
|
||||
if (newfd>=maxfd) maxfd=newfd+1;
|
||||
cl=cList;
|
||||
NEW(cl, CocClient);
|
||||
cl->fd=newfd;
|
||||
cl->mode=0;
|
||||
cl->cmd[0]='\0';
|
||||
cl->res[0]='\0';
|
||||
NEW(cList);
|
||||
if (setData!=NULL) {
|
||||
ERR_P(cl->data = setData(NULL)); /* create new client data object */
|
||||
}
|
||||
/*
|
||||
ERR_SP(cList=calloc(1,sizeof(CocClient)+clDataSize));
|
||||
*/
|
||||
cl->next=cList->next;
|
||||
cList->next=cl;
|
||||
h=gethostbyaddr(&cadr.sin_addr, 4, AF_INET);
|
||||
h=gethostbyaddr((void *)&cadr.sin_addr, 4, AF_INET);
|
||||
if (h==NULL) {
|
||||
logfileOut(LOG_INFO, "(%d) open from %s\n", newfd, "local");
|
||||
} else {
|
||||
@@ -93,8 +479,8 @@ int CocHandle1Request(int tmo_msec, int fd) {
|
||||
cl0=cList; cl=cl0->next;
|
||||
while (cl!=NULL) {
|
||||
if (FD_ISSET(cl->fd, &rmask)) {
|
||||
buf->wrpos=recv(cl->fd, buf->buf, buf->dsize, 0);
|
||||
if (buf->wrpos<=0) {
|
||||
iret=CocRecv(cl->fd, &buf, -1, NULL);
|
||||
if (iret<=0) {
|
||||
logfileOut(LOG_INFO, "(%d) disconnected\n",cl->fd);
|
||||
close(cl->fd);
|
||||
FD_CLR(cl->fd, &mask);
|
||||
@@ -102,76 +488,81 @@ int CocHandle1Request(int tmo_msec, int fd) {
|
||||
FREE(cl);
|
||||
cl=cl0;
|
||||
} else {
|
||||
|
||||
str_put_start(bufo);
|
||||
str_get_start(buf);
|
||||
ERR_I(str_put_str(bufo, "")); /* empty error message */
|
||||
setmode=0;
|
||||
cl->logmask=0; /* stop output to log client */
|
||||
lmask=0;
|
||||
StrReset(&buf);
|
||||
StrClear(&bufo);
|
||||
err=NULL;
|
||||
ERR_P(varname=str_get_str(buf, NULL));
|
||||
logfileOut(LOG_NET, "(%d) ", cl->fd);
|
||||
if (varname[0]=='#') { /* access code */
|
||||
if (0==strcmp(varname,"#rdacc")) {
|
||||
logfileOut(LOG_INFO, "set read mode\n");
|
||||
cl->mode=1;
|
||||
} else if (0==strcmp(varname,"#rwacs")) {
|
||||
logfileOut(LOG_INFO, "set write mode\n");
|
||||
cl->mode=2;
|
||||
} else {
|
||||
err="bad access code";
|
||||
}
|
||||
} else if (cl->mode==0) {
|
||||
err="no access";
|
||||
} else {
|
||||
while (1) {
|
||||
if (varname[0]=='[') {
|
||||
if (cl->mode<2) { err="no write access"; break; }
|
||||
setmode=1; /* switch to set mode */
|
||||
} else if (varname[0]==']') { /* switch to read mode */
|
||||
setmode=0;
|
||||
} else if (setmode) {
|
||||
if (0==strcmp("$", varname)) { /* special case: command */
|
||||
ERR_P(str_get_str(buf, cl->cmd));
|
||||
cl->res[0]='\0';
|
||||
} else {
|
||||
i=CocGetVar(serverVarList, buf, varname, 1);
|
||||
if (i<0) {
|
||||
err=ErrMessage; break;
|
||||
}
|
||||
}
|
||||
modified=1;
|
||||
logfileOutBuf(LOG_NET, &buf);
|
||||
/* cl->npend=0; why that ? */
|
||||
logfileOut(LOG_NET, "\n");
|
||||
cl->synch=buf.buf[0];
|
||||
ERR_P(StrGet(&buf, NULL, cl->synch));
|
||||
ERR_I(StrPut(&bufo, "", cl->synch));
|
||||
while (!StrEnd(&buf)) {
|
||||
ERR_P(varname=StrGet(&buf, NULL, ' '));
|
||||
if (cl->synch==COC_MAGIC) { /* access code */
|
||||
if (0==strcmp(varname,"rdacs")) {
|
||||
logfileOut(LOG_INFO, "set read mode\n");
|
||||
cl->mode=1;
|
||||
ERR_I(StrPut(&bufo, "", COC_SEP)); /* empty message */
|
||||
} else if (0==strcmp(varname,"rwacs")) {
|
||||
logfileOut(LOG_INFO, "set write mode\n");
|
||||
cl->mode=2;
|
||||
ERR_I(StrPut(&bufo, "", COC_SEP)); /* empty message */
|
||||
} else {
|
||||
if (0==strcmp("$", varname)) { /* special case: response */
|
||||
ERR_I(str_put_str(bufo, cl->res));
|
||||
cl->res[0]='\0';
|
||||
ERR_I(StrPut(&bufo, "", COC_ERR)); /* signal error message */
|
||||
ERR_I(StrPut(&bufo, "bad access code", COC_SEP));
|
||||
}
|
||||
ERR_P(StrGet(&buf, NULL, COC_NUL)); /* skip separator */
|
||||
} else if (cl->mode==0) {
|
||||
ERR_I(StrPut(&bufo, "", COC_ERR)); /* signal terminal error message */
|
||||
ERR_I(StrPut(&bufo, "no access", COC_SEP));
|
||||
ERR_P(StrGet(&buf, NULL, COC_NUL)); /* skip separator */
|
||||
} else {
|
||||
if (cl->data!=NULL) {
|
||||
setData(cl->data);
|
||||
}
|
||||
var=CocFindVar(varname, &base);
|
||||
if (var==NULL) {
|
||||
ERR_I(StrPut(&bufo, "", COC_ERR)); /* signal error message */
|
||||
ERR_I(StrPut(&bufo, "undefined variable", COC_SEP));
|
||||
ERR_P(StrGet(&buf, NULL, COC_NUL)); /* skip separator */
|
||||
} else if (buf.seen) { /* separator was there: set mode */
|
||||
if (var->access > cl->mode) {
|
||||
ERR_I(StrPut(&bufo, "", COC_ERR)); /* signal error message */
|
||||
ERR_I(StrPut(&bufo, "no access", COC_SEP));
|
||||
ERR_P(StrGet(&buf, NULL, COC_NUL)); /* skip separator */
|
||||
} else {
|
||||
i=CocPutVar(serverVarList, bufo, varname, 0);
|
||||
if (i<0) {
|
||||
err=ErrMessage; break;
|
||||
ERR_I(CocGetThisVar(var, base, &buf, COC_SEP));
|
||||
if (0==strcmp(var->name,"loglist")) {
|
||||
str_upcase(loglist, loglist);
|
||||
if (NULL!=strchr(loglist,'A')) lmask = lmask | LOG_ALL;
|
||||
if (NULL!=strchr(loglist,'S')) lmask = lmask | LOG_SER;
|
||||
if (NULL!=strchr(loglist,'N')) lmask = lmask | LOG_NET;
|
||||
if (NULL!=strchr(loglist,'I')) lmask = lmask | LOG_INFO;
|
||||
if (NULL!=strchr(loglist,'M')) lmask = lmask | LOG_MAIN;
|
||||
ERR_I(StrPut(&bufo, "", COC_NUL)); /* o.k. */
|
||||
} else {
|
||||
ERR_I(iret=CocHandleThis(var, base, &bufo, COC_WR));
|
||||
if (iret) ERR_I(CocPushThisHandler(var, cl, base, iret));
|
||||
}
|
||||
modified=1;
|
||||
}
|
||||
} else {
|
||||
ERR_P(StrGet(&buf, NULL, COC_NUL)); /* skip separator */
|
||||
ERR_I(iret=CocHandleThis(var, base, &bufo, COC_RD));
|
||||
if (iret) ERR_I(CocPushThisHandler(var, cl, base, iret));
|
||||
}
|
||||
if (buf->rdpos>=buf->wrpos) {
|
||||
ERR_I(str_get_end(buf));
|
||||
break;
|
||||
}
|
||||
ERR_P(varname=str_get_str(buf, NULL));
|
||||
}
|
||||
str_get_start(buf);
|
||||
logfileOutBuf(LOG_NET, buf);
|
||||
str_get_start(bufo);
|
||||
logfileOut(LOG_NET, " |");
|
||||
logfileOutBuf(LOG_NET, bufo);
|
||||
}
|
||||
if (err==NULL) {
|
||||
logfileOut(LOG_NET, "\n");
|
||||
} else {
|
||||
str_put_start(bufo); /* reset output */
|
||||
str_put_str(bufo, err); /* put error message */
|
||||
logfileOut(LOG_NET, " (%s)\n", err);
|
||||
/* logfileMask(LOG_NET); */
|
||||
}
|
||||
ERR_SI(send(cl->fd, bufo->buf, bufo->wrpos, 0));
|
||||
ERR_I(StrGetEnd(&buf));
|
||||
logfileOut(LOG_NET, " ");
|
||||
logfileOutBuf(LOG_NET, &bufo);
|
||||
logfileOut(LOG_NET, "\n");
|
||||
ERR_I(CocSend(cl->fd, bufo.buf, bufo.wrpos));
|
||||
cl->logmask=lmask;
|
||||
}
|
||||
}
|
||||
cl0=cl; cl=cl->next;
|
||||
@@ -183,54 +574,30 @@ int CocHandle1Request(int tmo_msec, int fd) {
|
||||
}
|
||||
|
||||
int CocHandleRequests(int tmo_msec, int fd) {
|
||||
struct timeb tim1, tim0;
|
||||
int tdif, iret;
|
||||
int tdif, iret, tim0;
|
||||
|
||||
if (modified && fd==0) { /* earlier modification */
|
||||
modified=0;
|
||||
return(2);
|
||||
}
|
||||
ftime(&tim0);
|
||||
tim0=mycMsecSince(0);
|
||||
tdif=tmo_msec;
|
||||
while (tdif>=0) {
|
||||
ERR_I(iret=CocHandle1Request(tdif, fd));
|
||||
if (fd==0) {
|
||||
if (iret==2) return(2); /* modification of a varaible */
|
||||
if (iret==2) return(2); /* modification of a variable */
|
||||
} else {
|
||||
if (iret==1) return(1); /* event on fd */
|
||||
}
|
||||
if (iret==0) return(0); /* timeout */
|
||||
ftime(&tim1);
|
||||
tdif=tmo_msec-((tim1.time-tim0.time)*1000+tim1.millitm-tim0.millitm);
|
||||
tdif = tmo_msec - mycMsecSince(tim0);
|
||||
}
|
||||
return(0); /* timeout */
|
||||
OnError: return(-1);
|
||||
}
|
||||
|
||||
struct CocClient *CocGetNextCmd() {
|
||||
struct CocClient *cl;
|
||||
|
||||
cl=cLastCmd;
|
||||
while (cl!=NULL) {
|
||||
if (cl->cmd[0]!='\0') {
|
||||
cLastCmd=cl->next;
|
||||
return(cl);
|
||||
}
|
||||
cl=cl->next;
|
||||
}
|
||||
cl=cList->next;
|
||||
while (cl!=NULL && cl!=cLastCmd) {
|
||||
if (cl->cmd[0]!='\0') {
|
||||
cLastCmd=cl->next;
|
||||
return(cl);
|
||||
}
|
||||
cl=cl->next;
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
void CocCloseServer() {
|
||||
struct CocClient *cl, *cl0;
|
||||
CocClient *cl, *cl0;
|
||||
|
||||
cl=cList->next;
|
||||
while (cl!=NULL) {
|
||||
@@ -241,6 +608,4 @@ void CocCloseServer() {
|
||||
}
|
||||
FREE(cList);
|
||||
close(mainFd);
|
||||
str_free_buf(buf); str_free_buf(bufo);
|
||||
logfileClose();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user