new tecs version M.Z.08.2001
This commit is contained in:
@@ -1,19 +1,24 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include "err_handling.h"
|
||||
#include <signal.h>
|
||||
#include "myc_err.h"
|
||||
#include "coc_util.h"
|
||||
#include "coc_client.h"
|
||||
#include "str_util.h"
|
||||
#include "sys_util.h"
|
||||
#include "myc_str.h"
|
||||
|
||||
/* --- non ANSI signal --- */
|
||||
#ifndef SIGPIPE
|
||||
#define SIGPIPE 13
|
||||
#endif
|
||||
|
||||
#define COC_NETTMO 5
|
||||
#define COC_RESTMO 60
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
int CocConnect(CocConn *conn) {
|
||||
@@ -67,15 +72,13 @@ int CocOpen(CocConn *conn)
|
||||
int CocInitClient(CocConn *conn, char *host, int port, char *magic, int bufsize, char *startcmd) {
|
||||
assert(conn!=NULL);
|
||||
if (bufsize==0) bufsize=1024;
|
||||
ERR_P(conn->cmdbuf=str_create_buf(bufsize, '\0'));
|
||||
ERR_P(conn->resbuf=str_create_buf(bufsize, '\0'));
|
||||
StrLink(&conn->cmdbuf, conn->cmdbuf_);
|
||||
StrLink(&conn->resbuf, conn->resbuf_);
|
||||
conn->port=port;
|
||||
ERR_I(str_copy(conn->host, host));
|
||||
ERR_I(str_copy(conn->magic, magic));
|
||||
ERR_I(str_copy(conn->startcmd, startcmd));
|
||||
conn->fd=-1;
|
||||
conn->varList=NULL;
|
||||
CocVarList(&conn->varList);
|
||||
ERR_I(CocOpen(conn));
|
||||
ERR_I(CocSendMagic(conn, conn->magic));
|
||||
return(0);
|
||||
@@ -86,15 +89,17 @@ int CocInitClient(CocConn *conn, char *host, int port, char *magic, int bufsize,
|
||||
|
||||
int CocSendMagic(CocConn *conn, char *magic) {
|
||||
char *err;
|
||||
int siz, n;
|
||||
|
||||
if (magic[0]!='#') ERR_MSG("magic must start with '#'");
|
||||
str_put_start(conn->resbuf); /* use return buffer for command in order to preserve command buffer */
|
||||
ERR_I(str_put_str(conn->resbuf, magic));
|
||||
ERR_SI(send(conn->fd, conn->resbuf->buf, conn->resbuf->wrpos, 0));
|
||||
ERR_I(CocRecv(conn->fd, conn->resbuf));
|
||||
ERR_P(err=str_get_str(conn->resbuf, NULL));
|
||||
if (*err!='\0') { ErrMsg(err); ErrTxt(": (response from server)",0); goto OnError; }
|
||||
ERR_I(str_get_end(conn->resbuf));
|
||||
StrClear(&conn->resbuf); /* use return buffer for command in order to preserve command buffer */
|
||||
ERR_I(StrPut(&conn->resbuf, "", COC_MAGIC));
|
||||
ERR_I(StrPut(&conn->resbuf, magic, COC_SEP));
|
||||
ERR_I(CocSend(conn->fd, conn->resbuf.buf, conn->resbuf.wrpos));
|
||||
ERR_I(CocRecv(conn->fd, &conn->resbuf, COC_NETTMO, NULL));
|
||||
ERR_P(err=StrGet(&conn->resbuf, NULL, COC_SEP));
|
||||
if (err[0]!=COC_MAGIC) ERR_MSG("magic synch error");
|
||||
if (err[1]!='\0') { ErrMsg(err+1); ErrTxt(": (response from server)",0); goto OnError; }
|
||||
ERR_I(StrGetEnd(&conn->resbuf));
|
||||
return(0);
|
||||
OnError: return(-1);
|
||||
}
|
||||
@@ -102,9 +107,10 @@ int CocSendMagic(CocConn *conn, char *magic) {
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
int CocCheck(CocConn *conn) {
|
||||
|
||||
if (conn->fd<0) return(1);
|
||||
ERR_SI(send(conn->fd, "quit", 5, 0));
|
||||
ERR_I(CocRecv(conn->fd, conn->resbuf));
|
||||
ERR_I(CocSend(conn->fd, "_quit", 6));
|
||||
ERR_I(CocRecv(conn->fd, &conn->resbuf, COC_NETTMO, NULL));
|
||||
return(0);
|
||||
OnError:
|
||||
if (ErrCode==ECONNRESET || ErrCode==EPIPE) return(1);
|
||||
@@ -114,16 +120,24 @@ int CocCheck(CocConn *conn) {
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
int CocTryCmd(CocConn *conn) {
|
||||
int iret=-1;
|
||||
int iret=-1, siz;
|
||||
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
if (conn->fd<0) {
|
||||
/*
|
||||
ERR_I(iret=CocOpen(conn));
|
||||
*/
|
||||
ERR_I(iret=CocConnect(conn));
|
||||
if (iret == 1) {
|
||||
CocDelay(500);
|
||||
ErrTxt("connect",1); return (-1);
|
||||
}
|
||||
|
||||
iret=-1;
|
||||
ERR_I(CocSendMagic(conn, conn->magic));
|
||||
}
|
||||
ERR_SI(send(conn->fd, conn->cmdbuf->buf, conn->cmdbuf->wrpos, 0));
|
||||
ERR_I(CocRecv(conn->fd, conn->resbuf));
|
||||
ERR_I(CocSend(conn->fd, conn->cmdbuf.buf, conn->cmdbuf.wrpos));
|
||||
ERR_I(CocRecv(conn->fd, &conn->resbuf, COC_NETTMO, NULL));
|
||||
return(0);
|
||||
OnError:
|
||||
if (ErrCode==ECONNRESET || ErrCode==EPIPE) return(-2);
|
||||
@@ -134,7 +148,6 @@ int CocTryCmd(CocConn *conn) {
|
||||
|
||||
int CocCmdWithRetry(CocConn *conn) {
|
||||
int cnt, iret;
|
||||
char *err;
|
||||
|
||||
if (conn==NULL) ERR_MSG("not connected");
|
||||
cnt=3;
|
||||
@@ -152,118 +165,321 @@ int CocCmdWithRetry(CocConn *conn) {
|
||||
ErrShort(ErrMessage);
|
||||
ErrShort("try to reconnect");
|
||||
}
|
||||
ERR_P(err=str_get_str(conn->resbuf, NULL));
|
||||
if (*err!='\0') { ErrMsg(err); ErrTxt(": (response from server)",0 ); return(-2); }
|
||||
return(0);
|
||||
OnError: return(-1);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
int CocSet(CocConn *conn, const char *name, const char *value) {
|
||||
int iret=-1;
|
||||
|
||||
void CocReset(CocConn *conn) {
|
||||
assert(conn!=NULL);
|
||||
str_put_start(conn->cmdbuf);
|
||||
ERR_I(str_put_str(conn->cmdbuf, "["));
|
||||
ERR_I(str_put_str(conn->cmdbuf, name));
|
||||
ERR_I(str_put_str(conn->cmdbuf, value));
|
||||
ERR_I(str_put_str(conn->cmdbuf, "]"));
|
||||
|
||||
ERR_I(iret=CocCmdWithRetry(conn));
|
||||
|
||||
ERR_I(str_get_end(conn->resbuf));
|
||||
return(0);
|
||||
|
||||
OnError: return(iret);
|
||||
StrClear(&conn->cmdbuf);
|
||||
if (conn->synch!=COC_SYN0) {
|
||||
conn->synch=COC_SYN0;
|
||||
} else {
|
||||
conn->synch=COC_SYN1;
|
||||
}
|
||||
StrPut(&conn->cmdbuf, "", conn->synch);
|
||||
conn->nargs=0;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
int CocGetN(CocConn *conn, const char *name, char *value, int reslen) {
|
||||
int iret=-1;
|
||||
int CocPushArg(CocConn *conn, const char *name, void *value, int type) {
|
||||
StrBuf *buf;
|
||||
int n;
|
||||
|
||||
assert(conn!=NULL);
|
||||
str_put_start(conn->cmdbuf);
|
||||
ERR_I(str_put_str(conn->cmdbuf, name));
|
||||
|
||||
ERR_I(iret=CocCmdWithRetry(conn));
|
||||
|
||||
ERR_P(str_nget_str(conn->resbuf, value, reslen));
|
||||
ERR_I(str_get_end(conn->resbuf));
|
||||
assert(NULL==strchr(name, ' '));
|
||||
buf=&conn->cmdbuf;
|
||||
n=conn->nargs;
|
||||
if (n>=sizeof(conn->args)) ERR_MSG("too many return arguments");
|
||||
conn->args[n].adr=value;
|
||||
conn->args[n].type=type;
|
||||
conn->args[n].cmd=buf->buf + buf->wrpos;
|
||||
conn->nargs=n+1;
|
||||
if (value==NULL) {
|
||||
ERR_I(StrPut(buf, name, ' '));
|
||||
} else {
|
||||
ERR_I(StrPut(buf, name, COC_SEP));
|
||||
}
|
||||
return(0);
|
||||
|
||||
OnError: return(iret);
|
||||
OnError: return(-1);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
int CocCmd(CocConn *conn, const char *rwList)
|
||||
{ int setmode, i, iret=-1;
|
||||
const char *t, *s;
|
||||
char nam[32];
|
||||
CocVar *var;
|
||||
void *adr;
|
||||
int CocPutStr(CocConn *conn, const char *name, const char *value) {
|
||||
StrBuf *buf;
|
||||
|
||||
ERR_I(CocPushArg(conn, name, NULL, 4));
|
||||
ERR_I(StrPut(&conn->cmdbuf, value, COC_SEP));
|
||||
return(0);
|
||||
OnError: return(-1);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
int CocPutFloat(CocConn *conn, const char *name, float value) {
|
||||
|
||||
ERR_I(CocPushArg(conn, name, NULL, COC_FLT));
|
||||
ERR_I(StrPutFloat(&conn->cmdbuf, value, COC_SEP));
|
||||
return(0);
|
||||
OnError: return(-1);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
int CocPutInt(CocConn *conn, const char *name, int value) {
|
||||
|
||||
ERR_I(CocPushArg(conn, name, NULL, COC_INT));
|
||||
ERR_I(StrPutInt(&conn->cmdbuf, value, COC_SEP));
|
||||
return(0);
|
||||
OnError: return(-1);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
int CocGetStr(CocConn *conn, const char *name, char *value, int value_len) {
|
||||
|
||||
return(CocPushArg(conn, name, value, value_len));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
int CocGetFloat(CocConn *conn, const char *name, float *value) {
|
||||
|
||||
return(CocPushArg(conn, name, value, COC_FLT));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
int CocGetInt(CocConn *conn, const char *name, int *value) {
|
||||
|
||||
return(CocPushArg(conn, name, value, COC_INT));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
int CocDoIt(CocConn *conn, char *res, int res_len) {
|
||||
StrBuf *buf;
|
||||
int i, pending;
|
||||
CocArg *a;
|
||||
char *resp, *t, tag;
|
||||
int iret=0;
|
||||
|
||||
assert(conn!=NULL);
|
||||
str_put_start(conn->cmdbuf);
|
||||
s=rwList;
|
||||
setmode=0;
|
||||
do {
|
||||
t=strchr(s, ',');
|
||||
if (t==NULL) t=s+strlen(s);
|
||||
if (*s=='[') {
|
||||
if (!setmode) ERR_I(str_put_str(conn->cmdbuf, "["));
|
||||
s++;
|
||||
setmode=1;
|
||||
}
|
||||
i=t-s;
|
||||
assert(i<32);
|
||||
str_ncpy(nam, s, i+1);
|
||||
if (setmode) {
|
||||
if (nam[i-1]==']') { i--; nam[i]='\0'; setmode=0; }
|
||||
ERR_I(str_put_str(conn->cmdbuf, nam));
|
||||
ERR_I(CocPutVar(conn->varList, conn->cmdbuf, nam, 0));
|
||||
if (!setmode) ERR_I(str_put_str(conn->cmdbuf, "]"));
|
||||
} else {
|
||||
var=CocFindVar(conn->varList, nam, NULL);
|
||||
if (var==NULL) ERR_MSG("variable not found");
|
||||
ERR_I(str_put_str(conn->cmdbuf, nam));
|
||||
}
|
||||
s=t+1;
|
||||
} while (*t!='\0');
|
||||
ERR_I(CocCmdWithRetry(conn));
|
||||
buf=&conn->resbuf;
|
||||
while (buf->buf[0] != conn->synch) { /* throw away unsynchronized answers */
|
||||
ERR_I(CocRecv(conn->fd, buf, COC_NETTMO, NULL));
|
||||
}
|
||||
|
||||
ERR_I(iret=CocCmdWithRetry(conn));
|
||||
pending=conn->nargs;
|
||||
*res='\0';
|
||||
while (1) {
|
||||
if (buf->buf[0] != conn->synch) ERR_MSG("synch error");
|
||||
ERR_P(StrGet(buf, NULL, conn->synch));
|
||||
i=0;
|
||||
a=conn->args;
|
||||
while (pending>0 && i<conn->nargs) {
|
||||
if (a->type!=0) {
|
||||
resp=buf->buf + buf->rdpos;
|
||||
tag=*resp;
|
||||
if (tag==COC_DELAYED) { /* delayed response */
|
||||
resp++;
|
||||
ERR_P(StrGet(buf, NULL, COC_SEP));
|
||||
} else {
|
||||
pending--;
|
||||
if (tag==COC_ERR || tag==COC_TRM) { /* error response */
|
||||
str_ncat(res, a->cmd, res_len);
|
||||
resp++;
|
||||
ERR_P(StrGet(buf, NULL, COC_SEP));
|
||||
str_ncat(res, ": ", res_len);
|
||||
iret=1;
|
||||
if (tag==COC_TRM) return(1);
|
||||
} else {
|
||||
if (a->adr==NULL) {
|
||||
t=strchr(res, COC_SEP);
|
||||
str_ncat(res, a->cmd, res_len);
|
||||
t=strchr(t, ' ');
|
||||
assert(t!=NULL); /* truncate argument */
|
||||
*t=COC_SEP;
|
||||
str_ncat(res, "=", res_len);
|
||||
ERR_P(StrGet(buf, NULL, COC_SEP));
|
||||
} else {
|
||||
str_ncat(res, a->cmd, res_len);
|
||||
str_ncat(res, "=", res_len);
|
||||
if (a->type==COC_INT) {
|
||||
ERR_I(StrGetInt(buf, (int *)a->adr, COC_SEP));
|
||||
} else if (a->type==COC_FLT) {
|
||||
ERR_I(StrGetFloat(buf, (float *)a->adr, COC_SEP));
|
||||
} else if (a->type>1) {
|
||||
ERR_P(StrNGet(buf, (char *)a->adr, a->type, COC_SEP));
|
||||
} else {
|
||||
ERR_MSG("unknown type");
|
||||
}
|
||||
a->type=0;
|
||||
}
|
||||
}
|
||||
str_ncat(res, resp, res_len);
|
||||
str_ncat(res, "\n", res_len);
|
||||
}
|
||||
}
|
||||
i++; a++;
|
||||
}
|
||||
ERR_I(StrGetEnd(buf));
|
||||
if (pending==0) return(iret); /* no more delayed response awaiting */
|
||||
|
||||
/* read values */
|
||||
s=rwList;
|
||||
setmode=0;
|
||||
do {
|
||||
t=strchr(s, ',');
|
||||
if (t==NULL) t=s+strlen(s);
|
||||
if (*s=='[') {
|
||||
s++;
|
||||
setmode=1;
|
||||
ERR_I(CocRecv(conn->fd, buf, COC_RESTMO, NULL));
|
||||
}
|
||||
return(iret);
|
||||
OnError: return(-1);
|
||||
}
|
||||
|
||||
static int interrupt, logFd=0;
|
||||
|
||||
void CocIntSignal(int sig) {
|
||||
char buf[4];
|
||||
int siz;
|
||||
|
||||
if (logFd) {
|
||||
interrupt=2;
|
||||
buf[0]=COC_CLRLOG;
|
||||
buf[1]=COC_SEP; /* send "clear log" message */
|
||||
printf("\nCLRLOG\n");
|
||||
CocSend(logFd, buf, 2);
|
||||
} else {
|
||||
printf("\ninterrupt\n");
|
||||
interrupt=1;
|
||||
}
|
||||
}
|
||||
|
||||
int CocWatchLog(CocConn *conn, char *loglist) {
|
||||
char cbuf[1024];
|
||||
StrBuf *buf;
|
||||
int fd, iret;
|
||||
int i, siz, n;
|
||||
|
||||
sys_ctrl_init();
|
||||
fd=conn->fd;
|
||||
CocReset(conn);
|
||||
ERR_I(CocPutStr(conn, "loglist", loglist));
|
||||
ERR_I(CocDoIt(conn, cbuf, sizeof(cbuf)));
|
||||
buf=&conn->resbuf;
|
||||
interrupt=0;
|
||||
logFd=fd;
|
||||
signal(SIGINT, CocIntSignal);
|
||||
|
||||
while (!interrupt) {
|
||||
logFd=fd;
|
||||
ERR_I(iret=CocRecv(fd, buf, 60, &logFd));
|
||||
if (iret>0) {
|
||||
if (buf->buf[0]==COC_CLRLOG) { /* confirmed "clear log" message */
|
||||
interrupt=3;
|
||||
} else { /* it's a log message */
|
||||
StrReset(buf);
|
||||
while (!StrEnd(buf)) {
|
||||
ERR_P(StrGet(buf, cbuf, COC_SEP));
|
||||
printf("%s", cbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
i=t-s;
|
||||
if (setmode) {
|
||||
if (*(t-1)==']') setmode=0;
|
||||
} else {
|
||||
str_ncpy(nam, s, i+1);
|
||||
ERR_I(CocGetVar(conn->varList, conn->resbuf, nam, 0));
|
||||
}
|
||||
s=t+1;
|
||||
} while (*t!='\0');
|
||||
ERR_I(str_get_end(conn->resbuf));
|
||||
}
|
||||
signal(SIGINT, SIG_DFL);
|
||||
logFd=0;
|
||||
if (interrupt==1) { /* send "clear log" message */
|
||||
cbuf[0]=COC_CLRLOG;
|
||||
cbuf[1]=COC_SEP; /* send "clear log" message */
|
||||
printf("\nclrlog\n");
|
||||
CocSend(fd, cbuf, 2);
|
||||
do {
|
||||
ERR_I(CocRecv(fd, buf, 10, NULL));
|
||||
} while (buf->buf[0]!=COC_CLRLOG);
|
||||
}
|
||||
return(0);
|
||||
OnError:
|
||||
signal(SIGINT, SIG_DFL);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
OnError: return(iret);
|
||||
int CocShowLog(CocConn *conn, char *loglist, int start, int lines) {
|
||||
char cbuf[1024];
|
||||
StrBuf *buf;
|
||||
int fd, iret;
|
||||
int i, siz, n;
|
||||
|
||||
fd=conn->fd;
|
||||
CocReset(conn);
|
||||
if (start>0) {
|
||||
ERR_I(CocPutInt(conn, "logstart", start));
|
||||
}
|
||||
ERR_I(CocPutInt(conn, "loglines", lines));
|
||||
ERR_I(CocPutStr(conn, "logshow", loglist));
|
||||
ERR_I(CocDoIt(conn, cbuf, sizeof(cbuf)));
|
||||
buf=&conn->resbuf;
|
||||
|
||||
while (1) {
|
||||
ERR_I(iret=CocRecv(fd, buf, 10, NULL));
|
||||
if (iret<=0) break;
|
||||
if (buf->buf[0]==COC_CLRLOG) { /* end of log message */
|
||||
break;
|
||||
} else { /* it's a log message */
|
||||
StrReset(buf);
|
||||
while (!StrEnd(buf)) {
|
||||
ERR_P(StrGet(buf, cbuf, COC_SEP));
|
||||
printf("%s", cbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
OnError:
|
||||
signal(SIGINT, SIG_DFL);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
void CocCloseClient(CocConn *conn) {
|
||||
assert(conn!=NULL);
|
||||
close(conn->fd);
|
||||
str_free_buf(conn->cmdbuf);
|
||||
str_free_buf(conn->resbuf);
|
||||
CocFreeVarList(&conn->varList);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static char rbuf[256];
|
||||
|
||||
int CocSet(CocConn *conn, const char *name, const char *value) {
|
||||
int iret;
|
||||
|
||||
assert(conn!=NULL);
|
||||
CocReset(conn);
|
||||
ERR_I(CocPutStr(conn, name, value));
|
||||
ERR_I(iret=CocDoIt(conn, rbuf, sizeof(rbuf)));
|
||||
if (iret) ERR_MSG(rbuf);
|
||||
return(0);
|
||||
OnError: return(-1);
|
||||
}
|
||||
|
||||
int CocGetN(CocConn *conn, const char *name, char *value, int reslen) {
|
||||
int iret;
|
||||
|
||||
assert(conn!=NULL);
|
||||
CocReset(conn);
|
||||
ERR_I(CocGetStr(conn, name, value, reslen));
|
||||
ERR_I(iret=CocDoIt(conn, rbuf, sizeof(rbuf)));
|
||||
if (iret) ERR_MSG(rbuf);
|
||||
return(0);
|
||||
OnError: return(-1);
|
||||
}
|
||||
|
||||
int CocSetGetN(CocConn *conn, const char *name, const char *cmd, char *value, int reslen) {
|
||||
int iret;
|
||||
|
||||
assert(conn!=NULL);
|
||||
CocReset(conn);
|
||||
ERR_I(CocPutStr(conn, name, cmd));
|
||||
ERR_I(CocDoIt(conn, value, reslen));
|
||||
return(0);
|
||||
OnError: return(-1);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user