*** empty log message ***
This commit is contained in:
@ -3,7 +3,7 @@
|
||||
#
|
||||
# Markus Zolliker, March 2000
|
||||
#--------------------------------------------------------------------------
|
||||
OBJ= tecc.o client.o coc.o buf.o errhdl.o util.o \
|
||||
OBJ= tecc.o client.o coc.o errhdl.o str_util.o str_buf.o \
|
||||
server.o lsc.o serutil.o logfile.o dlog.o \
|
||||
asynsrv_utility.o strjoin.o geterrno.o
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
#endif
|
||||
#ifdef __DECC
|
||||
#pragma module AsynSrv_Utility ident
|
||||
#pragma nostandard
|
||||
#endif
|
||||
/*
|
||||
** +--------------------------------------------------------------+
|
||||
@ -419,7 +418,9 @@
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __VMS
|
||||
#pragma nostandard
|
||||
#include <ucx$inetdef.h>
|
||||
#pragma standard
|
||||
#include <unixio.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
|
@ -1,6 +1,10 @@
|
||||
#include <sys/socket.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include "errhdl.h"
|
||||
#include "client.h"
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
@ -35,7 +39,7 @@ int CocOpen(CocConn *conn)
|
||||
tmo=100; /* wait total ca. 10 sec. for 15 tries */
|
||||
while (try>0) {
|
||||
try--;
|
||||
util_delay(tmo); tmo=tmo*5/4;
|
||||
CocDelay(tmo); tmo=tmo*5/4;
|
||||
ERR_I(i=CocConnect(conn, try>0));
|
||||
if (i==0) return(0);
|
||||
}
|
||||
@ -48,12 +52,12 @@ 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;
|
||||
conn->cmdbuf=buf_create(bufsize);
|
||||
conn->resbuf=buf_create(bufsize);
|
||||
ERR_P(conn->cmdbuf=str_create_buf(bufsize, '\0'));
|
||||
ERR_P(conn->resbuf=str_create_buf(bufsize, '\0'));
|
||||
conn->port=port;
|
||||
str_copy(conn->host, host);
|
||||
str_copy(conn->magic, magic);
|
||||
str_copy(conn->startcmd, startcmd);
|
||||
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);
|
||||
@ -69,15 +73,13 @@ int CocSendMagic(CocConn *conn, char *magic) {
|
||||
char *err;
|
||||
|
||||
if (magic[0]!='#') ERR_MSG("magic must start with '#'");
|
||||
buf_put_start(conn->resbuf); /* use return buffer for command in order to preserve command buffer */
|
||||
buf_put_str(conn->resbuf, magic);
|
||||
buf_put_end(conn->resbuf);
|
||||
if (conn->resbuf->buf==NULL) ERR_MSG("buffer full");
|
||||
ERR_SI(send(conn->fd, conn->resbuf->buf, conn->resbuf->size, 0));
|
||||
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=buf_get_str(conn->resbuf);
|
||||
ERR_P(err=str_get_str(conn->resbuf, NULL));
|
||||
if (*err!='\0') { ErrMsg(err); ErrTxt(": (response from server)",0); goto OnError; }
|
||||
if (buf_size(conn->resbuf)!=0) ERR_MSG("syntax error");
|
||||
ERR_I(str_get_end(conn->resbuf));
|
||||
return(0);
|
||||
OnError: return(-1);
|
||||
}
|
||||
@ -89,7 +91,7 @@ int CocTryCmd(CocConn *conn)
|
||||
ERR_I(CocOpen(conn));
|
||||
ERR_I(CocSendMagic(conn, conn->magic));
|
||||
}
|
||||
ERR_SI(send(conn->fd, conn->cmdbuf->buf, conn->cmdbuf->size, 0));
|
||||
ERR_SI(send(conn->fd, conn->cmdbuf->buf, conn->cmdbuf->wrpos, 0));
|
||||
ERR_I(CocRecv(conn->fd, conn->resbuf));
|
||||
return(0);
|
||||
OnError: return(-1);
|
||||
@ -103,16 +105,17 @@ int CocCmd(CocConn *conn, const char *rwList)
|
||||
const char *t, *s;
|
||||
char nam[32];
|
||||
CocVar *var;
|
||||
void *adr;
|
||||
|
||||
assert(conn!=NULL);
|
||||
buf_put_start(conn->cmdbuf);
|
||||
str_put_start(conn->cmdbuf);
|
||||
s=rwList;
|
||||
setmode=0;
|
||||
do {
|
||||
t=strchr(s, ',');
|
||||
if (t==NULL) t=s+strlen(s);
|
||||
if (*s=='[') {
|
||||
if (!setmode) buf_put_str(conn->cmdbuf, "[");
|
||||
if (!setmode) ERR_I(str_put_str(conn->cmdbuf, "["));
|
||||
s++;
|
||||
setmode=1;
|
||||
}
|
||||
@ -121,19 +124,17 @@ int CocCmd(CocConn *conn, const char *rwList)
|
||||
str_ncpy(nam, s, i+1);
|
||||
if (setmode) {
|
||||
if (nam[i-1]==']') { i--; nam[i]='\0'; setmode=0; }
|
||||
buf_put_str(conn->cmdbuf, nam);
|
||||
ERR_I(CocPutVar(conn->varList, conn->cmdbuf, nam));
|
||||
if (!setmode) buf_put_str(conn->cmdbuf, "]");
|
||||
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);
|
||||
var=CocFindVar(conn->varList, nam, NULL);
|
||||
if (var==NULL) ERR_MSG("variable not found");
|
||||
buf_put_str(conn->cmdbuf, nam);
|
||||
ERR_I(str_put_str(conn->cmdbuf, nam));
|
||||
}
|
||||
s=t+1;
|
||||
} while (*t!='\0');
|
||||
|
||||
buf_put_end(conn->cmdbuf);
|
||||
if (conn->cmdbuf->buf==NULL) ERR_MSG("out buffer full");
|
||||
cnt=3;
|
||||
while (1) {
|
||||
cnt--;
|
||||
@ -148,7 +149,7 @@ int CocCmd(CocConn *conn, const char *rwList)
|
||||
if (ErrCode!=ECONNRESET && ErrCode!=EPIPE) goto OnError;
|
||||
ErrShow("try again, error was");
|
||||
}
|
||||
err=buf_get_str(conn->resbuf);
|
||||
ERR_P(err=str_get_str(conn->resbuf, NULL));
|
||||
if (*err!='\0') { ErrMsg(err); ErrTxt(": (response from server)",0 ); goto OnError; }
|
||||
|
||||
/* read values */
|
||||
@ -166,11 +167,11 @@ int CocCmd(CocConn *conn, const char *rwList)
|
||||
if (*(t-1)==']') setmode=0;
|
||||
} else {
|
||||
str_ncpy(nam, s, i+1);
|
||||
ERR_I(CocGetVar(conn->varList, conn->resbuf, nam));
|
||||
ERR_I(CocGetVar(conn->varList, conn->resbuf, nam, 0));
|
||||
}
|
||||
s=t+1;
|
||||
} while (*t!='\0');
|
||||
if (buf_size(conn->resbuf)!=0) ERR_MSG("syntax error");
|
||||
ERR_I(str_get_end(conn->resbuf));
|
||||
return(0);
|
||||
|
||||
OnError: return(-1);
|
||||
@ -179,7 +180,7 @@ int CocCmd(CocConn *conn, const char *rwList)
|
||||
void CocCloseClient(CocConn *conn) {
|
||||
assert(conn!=NULL);
|
||||
close(conn->fd);
|
||||
buf_free(conn->cmdbuf);
|
||||
buf_free(conn->resbuf);
|
||||
str_free_buf(conn->cmdbuf);
|
||||
str_free_buf(conn->resbuf);
|
||||
CocFreeVarList(&conn->varList);
|
||||
}
|
||||
|
@ -1,10 +1,13 @@
|
||||
#ifndef _CLIENT_H_
|
||||
#define _CLIENT_H_
|
||||
|
||||
#include "coc.h"
|
||||
|
||||
typedef struct {
|
||||
int fd, port;
|
||||
CocVar *varList;
|
||||
buf_type *cmdbuf; /* for sending command */
|
||||
buf_type *resbuf; /* for response */
|
||||
Str_Buf *cmdbuf; /* for sending command */
|
||||
Str_Buf *resbuf; /* for response */
|
||||
char host[64];
|
||||
char magic[32];
|
||||
char startcmd[512];
|
||||
@ -14,3 +17,5 @@ int CocInitClient(CocConn *conn, char *host, int port, char *magic, int bufsize,
|
||||
int CocSendMagic(CocConn *conn, char *magic);
|
||||
int CocCmd(CocConn *conn, const char *rwList);
|
||||
void CocCloseClient(CocConn *conn);
|
||||
|
||||
#endif /* _CLIENT_H_ */
|
||||
|
140
tecs/coc.c
140
tecs/coc.c
@ -1,4 +1,12 @@
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <strings.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "errhdl.h"
|
||||
#include "util.h"
|
||||
#include "coc.h"
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/* CreateSocketAddress stolen from Tcl. Thanks to John Ousterhout */
|
||||
@ -44,7 +52,7 @@ int CocCreateSockAdr(
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
int CocRecv(int fd, buf_type *buf)
|
||||
int CocRecv(int fd, Str_Buf *buf)
|
||||
{
|
||||
struct timeval tmo={0,1};
|
||||
fd_set mask;
|
||||
@ -57,11 +65,9 @@ int CocRecv(int fd, buf_type *buf)
|
||||
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);
|
||||
ERR_SI(buf->wrpos=recv(fd, buf->buf, buf->dsize, 0));
|
||||
if (buf->wrpos==0) { ERR_COD(ECONNRESET); }
|
||||
str_get_start(buf);
|
||||
return(ret);
|
||||
OnError: return(-1);
|
||||
}
|
||||
@ -71,7 +77,17 @@ void CocVarList(CocVar **varList) {
|
||||
varListHdl=varList;
|
||||
}
|
||||
|
||||
CocVar *CocFindVar(CocVar *varList, const char *name) {
|
||||
void CocList() {
|
||||
CocVar *p;
|
||||
|
||||
p=*varListHdl;
|
||||
while (p!=NULL) {
|
||||
printf("%s %d\n", p->name, p->type);
|
||||
p=p->next;
|
||||
}
|
||||
}
|
||||
|
||||
CocVar *CocFindVar1(CocVar *varList, const char *name) {
|
||||
CocVar *p;
|
||||
|
||||
p=varList;
|
||||
@ -79,67 +95,129 @@ CocVar *CocFindVar(CocVar *varList, const char *name) {
|
||||
return(p);
|
||||
}
|
||||
|
||||
void CocDefVar(const char *name, void *var, int type, int *flag) {
|
||||
CocVar *CocFindVar(CocVar *varList, 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(varList, 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(varList, nam);
|
||||
if (p!=NULL && p->type==COC_ALIAS) { /* recursive call for alias */
|
||||
p=CocFindVar(varList, p->var, adr);
|
||||
}
|
||||
return(p);
|
||||
}
|
||||
|
||||
CocVar *CocDefVar(const char *name, void *var, int type, int *flag) {
|
||||
CocVar *p;
|
||||
const char *f;
|
||||
void *adr;
|
||||
|
||||
assert(varListHdl!=NULL);
|
||||
p=CocFindVar(*varListHdl, name);
|
||||
p=CocFindVar1(*varListHdl, name);
|
||||
if (p==NULL) {
|
||||
p=malloc(sizeof(*p));
|
||||
p->next=*varListHdl;
|
||||
*varListHdl=p;
|
||||
str_copy(p->name, name);
|
||||
}
|
||||
str_copy(p->name, name);
|
||||
p->var=var;
|
||||
p->type=type;
|
||||
p->flag=flag;
|
||||
return(p);
|
||||
}
|
||||
|
||||
int CocGetVar(CocVar *varList, buf_type *buf, const char *name) {
|
||||
CocVar *var;
|
||||
void CocDefVarS(const char *name, const char *tname, void *var, int type) {
|
||||
CocVar *p, *t;
|
||||
|
||||
var=CocFindVar(varList, name);
|
||||
assert(type==COC_PTR || type==COC_STRUCT);
|
||||
p=CocDefVar(name, var, type, &CocRD);
|
||||
p->strucType=CocDefVar(tname, NULL, COC_TYPE, &CocRD);
|
||||
}
|
||||
|
||||
int CocGetVar(CocVar *varList, Str_Buf *buf, const char *name, int secure) {
|
||||
CocVar *var;
|
||||
void *adr;
|
||||
|
||||
var=CocFindVar(varList, name, &adr);
|
||||
if (var==NULL) ERR_MSG("undefined variable");
|
||||
if (varList==serverVarList) { /* we are the server */
|
||||
if (adr==NULL) {
|
||||
adr=var->var;
|
||||
} else {
|
||||
adr=(char *)adr + (int)var->var;
|
||||
}
|
||||
if (secure) { /* 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);
|
||||
ERR_I(str_get_int(buf, (int *)adr));
|
||||
} else if (var->type==-2) {
|
||||
*(float *)var->var=buf_get_float(buf);
|
||||
ERR_I(str_get_float(buf, (float *)adr));
|
||||
} else if (var->type>1) {
|
||||
str_ncpy((char *)var->var, buf_get_str(buf), var->type);
|
||||
ERR_P(str_nget_str(buf, (char *)adr, var->type));
|
||||
} else {
|
||||
ERR_MSG("unknown type");
|
||||
}
|
||||
if (varList==serverVarList) { /* we are the server */
|
||||
if (secure) { /* we are the server */
|
||||
(*var->flag)++;
|
||||
}
|
||||
return(0);
|
||||
OnError: return(-1);
|
||||
}
|
||||
|
||||
int CocPutVar(CocVar *varList, buf_type *buf, const char *name) {
|
||||
int CocPutVar(CocVar *varList, Str_Buf *buf, const char *name, int secure) {
|
||||
CocVar *var;
|
||||
void *adr;
|
||||
char *c;
|
||||
|
||||
var=CocFindVar(varList, name);
|
||||
var=CocFindVar(varList, name, &adr);
|
||||
if (var==NULL) ERR_MSG("undefined variable");
|
||||
if (varList!=serverVarList) { /* we are the client */
|
||||
if (adr==NULL) {
|
||||
adr=var->var;
|
||||
} else {
|
||||
adr=(char *)adr + (int)var->var;
|
||||
}
|
||||
if (secure) { /* 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);
|
||||
ERR_I(str_put_int(buf, *(int *)adr));
|
||||
} else if (var->type==-2) {
|
||||
buf_put_float(buf, *(float *)var->var);
|
||||
ERR_I(str_put_float(buf, *(float *)adr));
|
||||
} else if (var->type>1) {
|
||||
c=var->var;
|
||||
if (c[0]<=2 && c[0]!=0) { ERR_MSG("illegal string"); }
|
||||
buf_put_str(buf, c);
|
||||
ERR_I(str_put_str(buf, adr));
|
||||
} else {
|
||||
ERR_MSG("unknown type");
|
||||
}
|
||||
if (varList!=serverVarList) { /* we are a client */
|
||||
if (secure) { /* we are a client */
|
||||
if (var->flag!=NULL) (*var->flag)++;
|
||||
}
|
||||
return(0);
|
||||
@ -159,3 +237,11 @@ void CocFreeVarList(CocVar **varList) {
|
||||
}
|
||||
*varList=NULL;
|
||||
}
|
||||
|
||||
void CocDelay(int msec) {
|
||||
struct timeval tmo;
|
||||
|
||||
tmo.tv_sec=msec / 1000;
|
||||
tmo.tv_usec=(msec % 1000)*1000+1;
|
||||
select(1,NULL,NULL,NULL,&tmo);
|
||||
}
|
||||
|
51
tecs/coc.h
51
tecs/coc.h
@ -1,40 +1,47 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#ifndef _COC_H_
|
||||
#define _COC_H_
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include "errhdl.h"
|
||||
#include "buf.h"
|
||||
#include "util.h"
|
||||
#include "str_buf.h"
|
||||
|
||||
int CocCreateSockAdr(
|
||||
struct sockaddr_in *sockaddrPtr, /* Socket address */
|
||||
const char *host, /* Host. NULL implies INADDR_ANY */
|
||||
int port); /* Port number */
|
||||
int CocRecv(int fd, buf_type *buf);
|
||||
int CocRecv(int fd, Str_Buf *buf);
|
||||
|
||||
typedef struct { void *next; char name[32]; void *var; int *flag; int type; } CocVar;
|
||||
typedef struct { void *next; char name[32]; void *var; int *flag; int type; void *strucType; } CocVar;
|
||||
|
||||
extern int CocRD;
|
||||
extern int CocWR;
|
||||
CocVar *serverVarList;
|
||||
|
||||
void CocDefVar(const char *name, void *var, int type, int *flag);
|
||||
CocVar *CocDefVar(const char *name, void *var, int type, int *flag);
|
||||
void CocDefVarS(const char *name, const char *tname, void *var, int type);
|
||||
void CocVarList(CocVar **varlist);
|
||||
void CocFreeVarList(CocVar **varList);
|
||||
CocVar *CocFindVar(CocVar *varList, const char *name);
|
||||
int CocPutVar(CocVar *varList, buf_type *buf, const char *name);
|
||||
int CocGetVar(CocVar *varList, buf_type *buf, const char *name);
|
||||
CocVar *CocFindVar(CocVar *varList, const char *name, void **adr);
|
||||
int CocPutVar(CocVar *varList, Str_Buf *buf, const char *name, int secure);
|
||||
int CocGetVar(CocVar *varList, Str_Buf *buf, const char *name, int secure);
|
||||
|
||||
#define CocDefInt(V,F) CocDefVar(#V,&V,-1,&F)
|
||||
#define CocDefFlt(V,F) CocDefVar(#V,&V,-2,&F)
|
||||
#define COC_INT -1
|
||||
#define COC_FLT -2
|
||||
#define COC_PTR -3
|
||||
#define COC_STRUCT -4
|
||||
#define COC_TYPE -5
|
||||
#define COC_ALIAS -6
|
||||
#define CocDefInt(V,F) CocDefVar(#V,&V,COC_INT,&F)
|
||||
#define CocDefFlt(V,F) CocDefVar(#V,&V,COC_FLT,&F)
|
||||
#define CocDefStr(V,F) CocDefVar(#V,V,sizeof(V),&F)
|
||||
#define CocDefPtr(V,S) CocDefVarS(#V,#S,&V,COC_PTR*(V!=(S *)NULL));
|
||||
#define CocDefStruct(V,S) CocDefVarS(#V,#S,&V,COC_STRUCT*(&V!=(S *)NULL));
|
||||
#define CocIntFld(S,V,F) CocDefVar(#S":"#V,&((S *)NULL)->V,COC_INT,&F);
|
||||
#define CocFltFld(S,V,F) CocDefVar(#S":"#V,&((S *)NULL)->V,COC_FLT,&F);
|
||||
#define CocStrFld(S,V,F) CocDefVar(#S":"#V,&((S *)NULL)->V,sizeof(((S *)NULL)->V),&F);
|
||||
#define CocDefCmd(V) CocDefVar("$",V,sizeof(V),&CocWR)
|
||||
#define CocDefStrPtr(V,S,F) CocDefVar(#V,V,S,&F)
|
||||
#define CocAlias(A,V) CocDefVar(#A, #V, COC_ALIAS, &CocRD);
|
||||
|
||||
void CocDelay(int msec);
|
||||
|
||||
#endif /* _COC_H_ */
|
||||
|
17
tecs/dlog.c
17
tecs/dlog.c
@ -1,3 +1,4 @@
|
||||
|
||||
/* switch off ANSI_C_SOURCE (allows compiling all sources with cc/stand=ansi) */
|
||||
#ifdef __VMS
|
||||
#ifdef __HIDE_FORBIDDEN_NAMES
|
||||
@ -147,19 +148,21 @@ int DlogPut(DlogSet *dset, time_t time, int nset, float val[]) {
|
||||
}
|
||||
|
||||
int DlogGet(DlogSet *dset, int iset, int nmax, double *starttime, float x[], float y[]) {
|
||||
int i0, i, n, undef;
|
||||
int i0, i1, i, n, undef;
|
||||
float f[DLOG_MAX_SET];
|
||||
|
||||
if (iset<0) ERR_MSG("illegal iset");
|
||||
if (iset>=dset->nset) return(0);
|
||||
|
||||
i = ( dset->last - dset->start ) / dset->period;
|
||||
i0=0;
|
||||
if (i0 <= i - dset->nlen) {
|
||||
i0 = i - dset->nlen + 1;
|
||||
if (i - dset->nlen > 0) {
|
||||
i1 = i - dset->nlen + 1;
|
||||
} else {
|
||||
i1 = 0;
|
||||
}
|
||||
i0=i1;
|
||||
|
||||
*starttime = dset->start + i0 * dset->period;
|
||||
*starttime = dset->start + i1 * dset->period;
|
||||
n=0;
|
||||
undef=2;
|
||||
while (i0<=i) {
|
||||
@ -167,7 +170,7 @@ int DlogGet(DlogSet *dset, int iset, int nmax, double *starttime, float x[], flo
|
||||
ERR_I(DlogRead(dset, i0, f));
|
||||
i0++;
|
||||
if (DEFINED(f[iset])) {
|
||||
x[n]=(float)i0*dset->period;
|
||||
x[n]=(float)(i0-i1)*dset->period;
|
||||
y[n]=f[iset];
|
||||
n++;
|
||||
undef=0;
|
||||
@ -205,7 +208,7 @@ int Dlog_Get_(char *name, int *nset, int *nmax, double *starttime, float x[], fl
|
||||
char buf[64];
|
||||
int ntot;
|
||||
/* for compaq unix */
|
||||
str_ntrim(buf, sizeof(buf), name, namlen);
|
||||
str_trim(buf, name, namlen);
|
||||
ERR_I(DlogOpen(&dset, buf, 0));
|
||||
ERR_I(ntot=DlogGetMany(&dset, *nset, *nmax, starttime, x, y, index));
|
||||
DlogClose(&dset);
|
||||
|
@ -1,3 +1,6 @@
|
||||
#ifndef _DLOG_H_
|
||||
#define _DLOG_H_
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#define DLOG_MAX_SET 32
|
||||
@ -47,3 +50,5 @@ int DlogUpd(DlogSet *dset);
|
||||
|
||||
int DlogClose(DlogSet *dset);
|
||||
/* close dlog set */
|
||||
|
||||
#endif /* _DLOG_H_ */
|
||||
|
@ -52,7 +52,7 @@ void ErrWriteGeneral(char *text, void (*outrtn)(), void *arg)
|
||||
}
|
||||
}
|
||||
outrtn(arg, buf);
|
||||
outrtn(arg, "---");
|
||||
outrtn(arg, "");
|
||||
}
|
||||
|
||||
void ErrOutFil(void *arg, char *text) {
|
||||
|
@ -1,3 +1,6 @@
|
||||
#ifndef _ERRHDL_H_
|
||||
#define _ERRHDL_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/errno.h>
|
||||
@ -79,3 +82,5 @@ void ErrLog(char *text);
|
||||
|
||||
extern int ErrCode;
|
||||
extern char *ErrMessage;
|
||||
|
||||
#endif /* _ERRHDL_H_ */
|
||||
|
143
tecs/logfile.c
143
tecs/logfile.c
@ -25,8 +25,8 @@ static int wrtMask=0;
|
||||
|
||||
int ftime (struct timeb *__timeptr); /* for some reason not defined in timeb.h with flag -std1 */
|
||||
|
||||
int logfileStd=0;
|
||||
int dirty=0;
|
||||
static int logfileStd;
|
||||
static int dirty, writeAll;
|
||||
|
||||
void logfileOpen(int first) {
|
||||
struct tm *tim;
|
||||
@ -50,6 +50,8 @@ void logfileOpen(int first) {
|
||||
} else {
|
||||
sprintf(filnam, "%s%04d-%02d-%02d.log", lnam, tim->tm_year+1900, tim->tm_mon+1, tim->tm_mday);
|
||||
}
|
||||
} else {
|
||||
assert(filnam[0]!='\0');
|
||||
}
|
||||
#ifdef __VMS
|
||||
if (first && notDated) {
|
||||
@ -66,9 +68,11 @@ void logfileOpen(int first) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void logfileInit(char *path, int nodate) {
|
||||
void logfileInit(char *path, int nodate, int use_stdout, int write_all) {
|
||||
str_copy(lnam, path);
|
||||
lastStamp=-1;
|
||||
logfileStd=use_stdout;
|
||||
writeAll=write_all;
|
||||
notDated=nodate;
|
||||
logfileOpen(1);
|
||||
}
|
||||
@ -78,22 +82,31 @@ void logfileOut(int mask, const char *fmt, ...)
|
||||
|
||||
assert(mask>0 && mask<32);
|
||||
va_start(ap, fmt);
|
||||
if (eptr!=NULL) {
|
||||
if (eptr-ebuf > sizeof(ebuf)-512) {
|
||||
sprintf(eptr, "... buffer full ... \1\1");
|
||||
eptr=NULL;
|
||||
} else {
|
||||
vsprintf(eptr, fmt, ap);
|
||||
assert(NULL==strchr(eptr, '\1'));
|
||||
eptr+=strlen(eptr);
|
||||
eptr[0]='\1'; /* put \1 as separator between blocks */
|
||||
eptr[1]=mask;
|
||||
eptr[2]='\0';
|
||||
eptr+=2;
|
||||
|
||||
if (writeAll) {
|
||||
#ifdef __VMS
|
||||
if (fil==NULL) logfileOpen(0);
|
||||
#endif
|
||||
vfprintf(fil, fmt, ap);
|
||||
wrtMask=LOG_ALL;
|
||||
} else {
|
||||
if (eptr!=NULL) {
|
||||
if (eptr-ebuf > sizeof(ebuf)-512) {
|
||||
sprintf(eptr, "... buffer full ... \1\1");
|
||||
eptr=NULL;
|
||||
} else {
|
||||
vsprintf(eptr, fmt, ap);
|
||||
assert(NULL==strchr(eptr, '\1'));
|
||||
eptr+=strlen(eptr);
|
||||
eptr[0]='\1'; /* put \1 as separator between blocks */
|
||||
eptr[1]=mask;
|
||||
eptr[2]='\0';
|
||||
eptr+=2;
|
||||
}
|
||||
}
|
||||
wrtMask=wrtMask | mask;
|
||||
}
|
||||
va_end(ap);
|
||||
wrtMask=wrtMask | mask;
|
||||
}
|
||||
|
||||
void logfileMask(int mask) {
|
||||
@ -111,34 +124,33 @@ void logfileStamp(void) {
|
||||
if (stamp!=lastStamp) {
|
||||
if (stamp<lastStamp) { /* time smaller than last time -> new day -> new logfile */
|
||||
if (fil!=NULL) { fclose(fil); fil=NULL; }
|
||||
logfileOpen(0);
|
||||
logfileOpen(1);
|
||||
}
|
||||
#ifdef __VMS
|
||||
else if (fil==NULL) logfileOpen(0);
|
||||
#endif
|
||||
lastStamp=stamp;
|
||||
logfileOut(LOG_MAIN, "--- %02d:%02d ---\n",tim->tm_hour,tim->tm_min);
|
||||
fprintf(fil, "--- %02d:%02d:%02d ---\n", tim->tm_hour, tim->tm_min, tim->tm_sec);
|
||||
dirty=0;
|
||||
}
|
||||
}
|
||||
|
||||
void logfileWrite(int mask) {
|
||||
void logfileWrite0(int mask) {
|
||||
char *s, *next;
|
||||
|
||||
logMask=logMask | mask;
|
||||
if (dirty) logfileStamp();
|
||||
if (dirty) logfileStamp(); /* there was something written since last time */
|
||||
|
||||
#ifdef __VMS
|
||||
if (fil==NULL) logfileOpen(0);
|
||||
#endif
|
||||
s=ebuf;
|
||||
if (*s!='\0' && wrtMask & logMask) {
|
||||
logfileStamp();
|
||||
dirty=1;
|
||||
|
||||
if (writeAll || *s!='\0' && wrtMask & logMask) {
|
||||
logfileStamp(); /* write stamp before write something */
|
||||
next=strchr(s, '\1');
|
||||
while (next!=NULL) {
|
||||
*next='\0';
|
||||
next++;
|
||||
if (*next & logMask) {
|
||||
fprintf(fil, "%s", s);
|
||||
dirty=1;
|
||||
}
|
||||
s=next+1;
|
||||
next=strchr(s, '\1');
|
||||
@ -148,6 +160,29 @@ void logfileWrite(int mask) {
|
||||
eptr=&ebuf[0];
|
||||
logMask=0;
|
||||
wrtMask=0;
|
||||
}
|
||||
|
||||
void logfileWrite(int mask) {
|
||||
|
||||
#ifdef __VMS
|
||||
if (fil==NULL) logfileOpen(0);
|
||||
#endif
|
||||
logfileWrite0(mask);
|
||||
#ifdef __VMS
|
||||
if (!logfileStd) { fclose(fil); fil=NULL; }
|
||||
#else
|
||||
fflush(fil);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void logfileShowErr(char *text)
|
||||
{
|
||||
#ifdef __VMS
|
||||
if (fil==NULL) logfileOpen(0);
|
||||
#endif
|
||||
logfileWrite0(LOG_ALL); /* write all */
|
||||
ErrWrite(fil, text);
|
||||
#ifdef __VMS
|
||||
if (!logfileStd) { fclose(fil); fil=NULL; }
|
||||
#else
|
||||
@ -155,39 +190,43 @@ void logfileWrite(int mask) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void logfileShowErr(char *text)
|
||||
{
|
||||
logfileWrite(LOG_ALL); /* write all */
|
||||
ErrWrite(fil, text);
|
||||
}
|
||||
|
||||
void logfileClose()
|
||||
{ logfileWrite(LOG_MAIN);
|
||||
{
|
||||
#ifdef __VMS
|
||||
if (fil==NULL) logfileOpen(0);
|
||||
#endif
|
||||
logfileWrite0(LOG_MAIN+LOG_WARN);
|
||||
lastStamp-=1;
|
||||
logfileStamp();
|
||||
if (fil!=NULL) { fclose(fil); fil=NULL; }
|
||||
filnam[0]='\0';
|
||||
}
|
||||
|
||||
void logfileOutBuf(int mask, buf_type *buf)
|
||||
{ char *obuf, *str;
|
||||
int osiz;
|
||||
void logfileOutBuf(int mask, Str_Buf *buf)
|
||||
{ char str[256];
|
||||
int rd0, sep;
|
||||
|
||||
obuf=buf->buf;
|
||||
osiz=buf->size;
|
||||
while (buf->size>0) {
|
||||
if (buf->buf==NULL) {
|
||||
logfileOut(mask, " ?"); break;
|
||||
} else if (buf->buf[0]==1) {
|
||||
logfileOut(mask, " %d", buf_get_int(buf));
|
||||
} else if (buf->buf[0]==2) {
|
||||
logfileOut(mask, " %f", buf_get_float(buf));
|
||||
} else {
|
||||
str=buf_get_str(buf);
|
||||
rd0=buf->rdpos;
|
||||
if (buf->rdpos < 0 || buf->rdpos >= buf->dsize
|
||||
|| buf->wrpos < 0 || buf->wrpos >= buf->dsize) {
|
||||
logfileOut(mask, "<buffer corrupt>"); return;
|
||||
}
|
||||
sep=0;
|
||||
while (buf->rdpos < buf->wrpos) {
|
||||
str_get_str(buf, str);
|
||||
if (buf->sep=='\0') {
|
||||
if (sep) logfileOut(mask, " ");
|
||||
if (*str=='\0') {
|
||||
logfileOut(mask, " .");
|
||||
logfileOut(mask, ".");
|
||||
} else {
|
||||
logfileOut(mask, " %s", str);
|
||||
logfileOut(mask, "%s", str);
|
||||
}
|
||||
sep=1;
|
||||
} else {
|
||||
if (sep) logfileOut(mask, "%c", buf->sep);
|
||||
logfileOut(mask, "%s", str);
|
||||
sep=1;
|
||||
}
|
||||
}
|
||||
buf->size=osiz;
|
||||
buf->buf=obuf;
|
||||
buf->rdpos=rd0;
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
#include "buf.h"
|
||||
#ifndef _LOGFILE_H_
|
||||
#define _LOGFILE_H_
|
||||
|
||||
#include "str_buf.h"
|
||||
|
||||
#define LOG_ALL 31
|
||||
#define LOG_SER 8
|
||||
@ -6,12 +9,12 @@
|
||||
#define LOG_WARN 2
|
||||
#define LOG_MAIN 1
|
||||
|
||||
void logfileInit(char *path, int nodate);
|
||||
void logfileInit(char *path, int nodate, int use_stdout, int write_all);
|
||||
void logfileOut(int mask, const char *fmt, ...);
|
||||
void logfileOutBuf(int mask, buf_type *buf);
|
||||
void logfileOutBuf(int mask, Str_Buf *buf);
|
||||
void logfileShowErr(char *text);
|
||||
void logfileMask(int mask);
|
||||
void logfileWrite(int mask);
|
||||
void logfileClose(void);
|
||||
|
||||
extern int logfileStd;
|
||||
#endif /* _LOGFILE_H_ */
|
||||
|
176
tecs/lsc.c
176
tecs/lsc.c
@ -1,37 +1,37 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <strings.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "errhdl.h"
|
||||
#include "logfile.h"
|
||||
#include "coc.h"
|
||||
#include "lsc.h"
|
||||
#include "util.h"
|
||||
|
||||
#define MC LSC_MAX_CMDS
|
||||
#define MAX_PAR 16
|
||||
#define MAX_ARG 9
|
||||
/* when changing FBUF_LEN, change also the constant in the fscanf call in subroutine LscExeCmd */
|
||||
#define FBUF_LEN 132
|
||||
|
||||
int LscEqPar(char *par, char *res) {
|
||||
char pbuf[SER_BUF_LEN], rbuf[SER_BUF_LEN];
|
||||
char *plist[MAX_PAR], *rlist[MAX_PAR];
|
||||
char *p, *r, pbuf[SER_BUF_LEN], rbuf[SER_BUF_LEN];
|
||||
int i,n,i1,i2;
|
||||
float f1, f2;
|
||||
char ch1, ch2;
|
||||
|
||||
strcpy(pbuf, par);
|
||||
strcpy(rbuf, res);
|
||||
n=MAX_PAR;
|
||||
str_split(pbuf, ',', plist, &n);
|
||||
str_split(rbuf, ',', rlist, &n);
|
||||
for (i=0; i<n; i++) {
|
||||
if (*plist[i]!='\0' && 0!=str_cmp(plist[i], rlist[i])) {
|
||||
i1=sscanf(plist[i], "%f%1s", &f1, &ch1);
|
||||
i2=sscanf(rlist[i], "%f%1s", &f2, &ch2);
|
||||
p=par;
|
||||
r=res;
|
||||
while (p!=NULL) {
|
||||
if (r==NULL) {
|
||||
return(0);
|
||||
}
|
||||
p=str_split(pbuf, p, ',');
|
||||
str_trim(pbuf, pbuf, sizeof(pbuf));
|
||||
r=str_split(rbuf, r, ',');
|
||||
str_trim(rbuf, rbuf, sizeof(rbuf));
|
||||
if (pbuf[0]!='\0' && 0!=strcasecmp(pbuf, rbuf)) {
|
||||
i1=sscanf(pbuf, "%f", &f1);
|
||||
i2=sscanf(rbuf, "%f", &f2);
|
||||
if (i1!=1 || i2!=1 || abs(f1-f2)>1e-4+abs(f1)*5e-6) {
|
||||
logfileOut(LOG_WARN, "%s#%s\n", plist[i], rlist[i]);
|
||||
logfileOut(LOG_WARN, "%s#%s\n", pbuf, rbuf);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
@ -39,11 +39,131 @@ int LscEqPar(char *par, char *res) {
|
||||
return(1);
|
||||
}
|
||||
|
||||
int LscCmdChkC(SerChannel *ser, const char *cmds) {
|
||||
char buf[128];
|
||||
assert(strlen(cmds)<128);
|
||||
strcpy(buf, cmds);
|
||||
return(LscCmdChk(ser, buf));
|
||||
char *LscCmd(SerChannel *ser, const char *cmds) {
|
||||
va_list ap;
|
||||
char *blank, *colon, *qu, *res;
|
||||
const char *p, *this, *next, *cmd_ptr, *retreq;
|
||||
const char *list[MC*3];
|
||||
char seg[SER_BUF_LEN], buf[SER_BUF_LEN], result[SER_BUF_LEN], par[SER_BUF_LEN];
|
||||
char cmd[SER_BUF_LEN];
|
||||
char varname[32];
|
||||
Str_Buf sbuf;
|
||||
int nres, i, j, response;
|
||||
|
||||
nres=0;
|
||||
response=0;
|
||||
str_link_buf(&sbuf, buf, sizeof(buf), STR_NOSEPARATOR);
|
||||
this=cmds;
|
||||
while (this!=NULL) {
|
||||
next=str_split(cmd, this, ';');
|
||||
retreq=strchr(cmd, '>');
|
||||
if (retreq!=NULL) { /* save pointer to return request */
|
||||
i=retreq-cmd;
|
||||
cmd[i]='\0'; /* cut return request */
|
||||
list[nres]=this+i;
|
||||
nres++;
|
||||
}
|
||||
cmd_ptr=sbuf.buf+sbuf.wrpos; /* pointer to command in buffer */
|
||||
p=str_split(seg, cmd, '[');
|
||||
ERR_I(str_put_str(&sbuf, seg));
|
||||
while (p!=NULL) { /* substitute variables */
|
||||
p=str_split(varname, p, ']');
|
||||
if (p==NULL) ERR_MSG("missing '\'");
|
||||
ERR_I(CocPutVar(serverVarList, &sbuf, varname, 0));
|
||||
p=str_split(seg, p, '[');
|
||||
ERR_I(str_put_str(&sbuf, seg));
|
||||
}
|
||||
ERR_I(str_copy(cmd, cmd_ptr));
|
||||
colon=strchr(cmd_ptr, ':');
|
||||
if (colon!=NULL) { /* command with query */
|
||||
blank=strchr(cmd_ptr, ' ');
|
||||
if (blank==NULL || blank>colon) {
|
||||
*colon=' '; blank=colon;
|
||||
} else {
|
||||
*colon=',';
|
||||
}
|
||||
list[nres]=colon+1; nres++; /* pointer to parameters */
|
||||
list[nres]=cmd_ptr; nres++; /* pointer to command */
|
||||
ERR_I(str_put_str(&sbuf, ";"));
|
||||
cmd[blank-cmd_ptr]='?'; /* build query */
|
||||
if (colon==blank) colon++;
|
||||
cmd[colon-cmd_ptr]='\0';
|
||||
ERR_I(str_put_str(&sbuf, cmd)); /* put query */
|
||||
ERR_I(str_put_str(&sbuf, ";"));
|
||||
response=1;
|
||||
} else {
|
||||
qu=strchr(cmd, '?');
|
||||
ERR_I(str_put_str(&sbuf, ";"));
|
||||
if (qu!=NULL) { /* command is a query */
|
||||
response=1;
|
||||
if (retreq==NULL) ERR_MSG("missing return format");
|
||||
list[nres]=NULL; nres++;
|
||||
} else {
|
||||
if (retreq!=NULL) ERR_MSG("no return request allowed after command without query ");
|
||||
}
|
||||
}
|
||||
this=next;
|
||||
}
|
||||
|
||||
if (!response) {
|
||||
ERR_I(str_put_str(&sbuf, "busy?"));
|
||||
} else {
|
||||
buf[sbuf.wrpos-1]='\0'; /* strip off trailing ";" */
|
||||
}
|
||||
ERR_P(res=SerCmd(ser, buf));
|
||||
if (0==strcmp("?TMO", res)) ERR_MSG("timeout");
|
||||
/*
|
||||
list[0..nres-1] contains a now:
|
||||
for a command with return request:
|
||||
- a pointer to a the request
|
||||
then, for a command with query:
|
||||
- a pointer to the parameters and
|
||||
- a pointer to the command
|
||||
this is repeated for every command
|
||||
*/
|
||||
|
||||
/* check results */
|
||||
this=res;
|
||||
for (i=0; i<nres; i++) {
|
||||
if (this==NULL) ERR_MSG("not all results received");
|
||||
this=str_split(result, this, ';');
|
||||
retreq=list[i];
|
||||
if (retreq!=NULL) {
|
||||
if (retreq[0]=='>') {
|
||||
i++;
|
||||
} else {
|
||||
retreq=NULL;
|
||||
}
|
||||
}
|
||||
if (list[i]!=NULL) {
|
||||
qu=str_split(par, list[i], ';'); /* get parameters */
|
||||
i++;
|
||||
if (!LscEqPar(par, result)) { /* try again with single command */
|
||||
qu=strchr(qu, ';');
|
||||
assert(list[i]!=NULL);
|
||||
str_copy(cmd, list[i]);
|
||||
if (qu!=NULL) cmd[qu-list[i]]='\0';
|
||||
ERR_P(qu=SerCmd(ser, cmd));
|
||||
if (!LscEqPar(par, qu)) ERR_MSG("result does not match");
|
||||
}
|
||||
}
|
||||
if (retreq!=NULL) { /* query */
|
||||
str_link_buf(&sbuf, result, 0, ',');
|
||||
str_split(par, retreq+1, ';');
|
||||
p=par;
|
||||
while (p!=NULL) {
|
||||
p=str_split(varname, p, ',');
|
||||
if (varname[0]!='\0') {
|
||||
ERR_I(CocGetVar(serverVarList, &sbuf, varname, 0));
|
||||
} else {
|
||||
ERR_P(str_get_str(&sbuf, NULL));
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return(res);
|
||||
OnError: return(NULL);
|
||||
}
|
||||
|
||||
int LscCmdChk(SerChannel *ser, char *cmds) {
|
||||
@ -58,7 +178,7 @@ int LscCmdChk(SerChannel *ser, char *cmds) {
|
||||
m=MC;
|
||||
do {
|
||||
n=m;
|
||||
cn=str_split(cn, ';', clist, &n);
|
||||
cn=str_splitx(cn, ';', clist, &n);
|
||||
for (i=0; i<n; i++) {
|
||||
c=clist[i];
|
||||
b=strchr(c, ' ');
|
||||
@ -91,7 +211,7 @@ int LscCmdChk(SerChannel *ser, char *cmds) {
|
||||
}
|
||||
strcpy(r1, res);
|
||||
j=n;
|
||||
r=str_split(res, ';', rlist, &n);
|
||||
r=str_splitx(res, ';', rlist, &n);
|
||||
if (r==NULL || n!=j) continue;
|
||||
for (i=0; i<n; i++) { /* compare parameters */
|
||||
if (! LscEqPar(plist[i], rlist[i])) {
|
||||
@ -104,3 +224,11 @@ int LscCmdChk(SerChannel *ser, char *cmds) {
|
||||
return(0);
|
||||
OnError: return(-1);
|
||||
}
|
||||
|
||||
int LscCmdChkC(SerChannel *ser, const char *cmds) {
|
||||
char buf[128];
|
||||
assert(strlen(cmds)<128);
|
||||
strcpy(buf, cmds);
|
||||
return(LscCmdChk(ser, buf));
|
||||
}
|
||||
|
||||
|
13
tecs/lsc.h
13
tecs/lsc.h
@ -1,14 +1,11 @@
|
||||
#ifndef _LSC_H_
|
||||
#define _LSC_H_
|
||||
|
||||
#include "serutil.h"
|
||||
#define LSC_MAX_CMDS 5
|
||||
|
||||
int LscCmdChk(SerChannel *ser, char *cmds);
|
||||
int LscCmdChkC(SerChannel *ser, const char *cmds);
|
||||
char *LscCmd(SerChannel *ser, const char *cmds);
|
||||
/*
|
||||
send one or several commands and check it's parameters
|
||||
a colon must separate the parameters
|
||||
attention:
|
||||
in LscCmdChk, *cmds will be modified (more efficient)
|
||||
in LscCmdChkC, *cmds must not be longer than 127 chars
|
||||
*/
|
||||
|
||||
int LscEqPar(char *par, char *res);
|
||||
@ -30,3 +27,5 @@ int LscNextCmd(SerChannel *ser, LscList clist);
|
||||
strip one line from LscList, and send it through LscCmdChk
|
||||
the list and the command buffers are freed when no longer used
|
||||
*/
|
||||
|
||||
#endif /* _LSC_H_ */
|
||||
|
@ -30,24 +30,24 @@ void SerA_error(void) {
|
||||
|
||||
SerChannel *SerOpen(const char *host, int msecTmo, void (*idleHdl)(int,int)) {
|
||||
struct SerChan *ser;
|
||||
char hbuf[64];
|
||||
char hbuf[64], cport[16];
|
||||
char *p, *c;
|
||||
int port, chan;
|
||||
|
||||
idleHandler=idleHdl;
|
||||
ser=calloc(1, sizeof(*ser));
|
||||
str_copy(hbuf, host);
|
||||
p=str_split1(hbuf, ':');
|
||||
str_copy(ser->asyn_info.host, hbuf);
|
||||
p=str_split(ser->asyn_info.host, hbuf, ':');
|
||||
port=4000;
|
||||
chan=0;
|
||||
if (p!=NULL) {
|
||||
c=str_split1(p, '/');
|
||||
c=str_split(cport, p, '/');
|
||||
if (c!=NULL) chan=atoi(c);
|
||||
port=atoi(p);
|
||||
port=atoi(cport);
|
||||
}
|
||||
ser->asyn_info.port=port;
|
||||
ser->asyn_info.chan=chan;
|
||||
logfileOut(LOG_MAIN, "open connection to %s:%d/%d\n", ser->asyn_info.host, ser->asyn_info.port, ser->asyn_info.chan);
|
||||
A_CHK(AsynSrv_Open(&ser->asyn_info));
|
||||
if (msecTmo==0) msecTmo=5000;
|
||||
A_CHK(AsynSrv_Config(&ser->asyn_info, "msecTmo", msecTmo, "idleHdl", idleHdl, NULL));
|
||||
|
@ -1,3 +1,6 @@
|
||||
#ifndef _SERUTIL_H_
|
||||
#define _SERUTIL_H_
|
||||
|
||||
#define SER_BUF_LEN 320
|
||||
|
||||
typedef struct { int private; } SerChannel;
|
||||
@ -6,3 +9,5 @@ SerChannel *SerOpen(const char *host, int msecTmo, void (*idleHdl)(int,int));
|
||||
char *SerCmdC(SerChannel *ser, const char *cmnd);
|
||||
char *SerCmd(SerChannel *ser, char *cmnd);
|
||||
int SerClose(SerChannel *ser);
|
||||
|
||||
#endif /* _SERUTIL_H_ */
|
||||
|
@ -5,17 +5,24 @@
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <sys/socket.h>
|
||||
#include <strings.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "errhdl.h"
|
||||
#include "logfile.h"
|
||||
#include "server.h"
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
|
||||
static buf_type *buf, *bufo;
|
||||
static Str_Buf *buf, *bufo;
|
||||
|
||||
static fd_set mask, rmask;
|
||||
static int maxfd;
|
||||
struct CocClient *cList, *cLastCmd=NULL;
|
||||
static int mainFd;
|
||||
static int modified;
|
||||
|
||||
int CocInitServer(int bufsize, int port) {
|
||||
int i;
|
||||
@ -23,8 +30,8 @@ int CocInitServer(int bufsize, int port) {
|
||||
char *err;
|
||||
|
||||
if (bufsize==0) bufsize=1024;
|
||||
buf=buf_create(bufsize);
|
||||
bufo=buf_create(bufsize);
|
||||
ERR_P(buf=str_create_buf(bufsize, '\0'));
|
||||
ERR_P(bufo=str_create_buf(bufsize,'\0'));
|
||||
cList=malloc(sizeof(*cList)); /* empty header */
|
||||
|
||||
/* first try to connect to an existing server */
|
||||
@ -48,18 +55,18 @@ int CocHandle1Request(int tmo_msec, int fd) {
|
||||
struct hostent *h;
|
||||
struct timeval tmo={0,1};
|
||||
struct CocClient *cl, *cl0;
|
||||
int i, newfd, setmode, status;
|
||||
int i, newfd, setmode;
|
||||
size_t cadrlen;
|
||||
char *err, *varname;
|
||||
|
||||
status=3;
|
||||
rmask=mask;
|
||||
if (fd>0) FD_SET(fd, &rmask);
|
||||
tmo.tv_sec=tmo_msec / 1000;
|
||||
tmo.tv_usec=(tmo_msec % 1000)*1000+1;
|
||||
if (fd>=maxfd) maxfd=fd+1;
|
||||
ERR_SI(i=select(maxfd,&rmask,NULL,NULL,&tmo));
|
||||
if (fd>0 && FD_ISSET(fd, &rmask)) return(1);
|
||||
if (fd>0 && FD_ISSET(fd, &rmask)) return(1); /* event on fd */
|
||||
if (i==0) return(0); /* timeout */
|
||||
|
||||
if (FD_ISSET(mainFd, &rmask)) {
|
||||
ERR_SI(newfd=accept(mainFd, (struct sockaddr *)&cadr, &cadrlen));
|
||||
@ -82,8 +89,8 @@ int CocHandle1Request(int tmo_msec, int fd) {
|
||||
cl0=cList; cl=cl0->next;
|
||||
while (cl!=NULL) {
|
||||
if (FD_ISSET(cl->fd, &rmask)) {
|
||||
buf->usize=recv(cl->fd, buf->start, buf->isize, 0);
|
||||
if (buf->usize<=0) {
|
||||
buf->wrpos=recv(cl->fd, buf->buf, buf->dsize, 0);
|
||||
if (buf->wrpos<=0) {
|
||||
logfileOut(LOG_MAIN, "(%d) disconnected\n",cl->fd);
|
||||
close(cl->fd);
|
||||
FD_CLR(cl->fd, &mask);
|
||||
@ -91,29 +98,26 @@ int CocHandle1Request(int tmo_msec, int fd) {
|
||||
free(cl);
|
||||
cl=cl0;
|
||||
} else {
|
||||
if (buf->usize<0) ERR_MSG("usize negative");
|
||||
|
||||
buf_put_start(bufo);
|
||||
buf_put_str(bufo, ""); /* empty error message */
|
||||
str_put_start(bufo);
|
||||
str_get_start(buf);
|
||||
ERR_I(str_put_str(bufo, "")); /* empty error message */
|
||||
setmode=0;
|
||||
buf_reset(buf);
|
||||
err=NULL;
|
||||
varname=buf_get_str(buf);
|
||||
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_MAIN, " set read mode\n");
|
||||
logfileOut(LOG_MAIN, "set read mode\n");
|
||||
cl->mode=1;
|
||||
} else if (0==strcmp(varname,"#rwacs")) {
|
||||
logfileOut(LOG_MAIN, " set write mode\n");
|
||||
logfileOut(LOG_MAIN, "set write mode\n");
|
||||
cl->mode=2;
|
||||
} else {
|
||||
err="bad access code";
|
||||
}
|
||||
buf_put_end(bufo);
|
||||
} else if (cl->mode==0) {
|
||||
err="no access";
|
||||
buf_put_end(bufo);
|
||||
} else {
|
||||
while (1) {
|
||||
if (varname[0]=='[') {
|
||||
@ -123,52 +127,50 @@ int CocHandle1Request(int tmo_msec, int fd) {
|
||||
setmode=0;
|
||||
} else if (setmode) {
|
||||
if (0==strcmp("$", varname)) { /* special case: command */
|
||||
str_copy(cl->cmd, buf_get_str(buf));
|
||||
ERR_P(str_get_str(buf, cl->cmd));
|
||||
cl->res[0]='\0';
|
||||
} else {
|
||||
i=CocGetVar(serverVarList, buf, varname);
|
||||
i=CocGetVar(serverVarList, buf, varname, 1);
|
||||
if (i<0) { err=ErrMessage; break; }
|
||||
}
|
||||
status=2;
|
||||
modified=1;
|
||||
} else {
|
||||
if (0==strcmp("$", varname)) { /* special case: response */
|
||||
buf_put_str(bufo, cl->res);
|
||||
ERR_I(str_put_str(bufo, cl->res));
|
||||
cl->res[0]='\0';
|
||||
} else {
|
||||
i=CocPutVar(serverVarList, bufo, varname);
|
||||
i=CocPutVar(serverVarList, bufo, varname, 0);
|
||||
if (i<0) { err=ErrMessage; break; }
|
||||
}
|
||||
}
|
||||
i=buf_size(buf);
|
||||
if (i<=0) {
|
||||
if (i<0) err="type mismatch";
|
||||
if (buf->rdpos>=buf->wrpos) {
|
||||
ERR_I(str_get_end(buf));
|
||||
break;
|
||||
}
|
||||
varname=buf_get_str(buf);
|
||||
if (buf_size(buf)<0) { err="syntax error"; break; }
|
||||
ERR_P(varname=str_get_str(buf, NULL));
|
||||
}
|
||||
buf_reset(buf);
|
||||
str_get_start(buf);
|
||||
logfileOutBuf(LOG_NET, buf);
|
||||
buf_put_end(bufo);
|
||||
str_get_start(bufo);
|
||||
logfileOut(LOG_NET, " |");
|
||||
logfileOutBuf(LOG_NET, bufo);
|
||||
}
|
||||
if (err==NULL) {
|
||||
logfileOut(LOG_NET, "\n");
|
||||
} else {
|
||||
buf_put_start(bufo); /* reset output */
|
||||
buf_put_str(bufo, err); /* put error message */
|
||||
buf_put_end(bufo);
|
||||
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->size, 0));
|
||||
ERR_SI(send(cl->fd, bufo->buf, bufo->wrpos, 0));
|
||||
}
|
||||
}
|
||||
cl0=cl; cl=cl->next;
|
||||
}
|
||||
}
|
||||
return(status);
|
||||
if (modified) return(2);
|
||||
return(3);
|
||||
OnError: return(-1);
|
||||
}
|
||||
|
||||
@ -176,12 +178,20 @@ int CocHandleRequests(int tmo_msec, int fd) {
|
||||
struct timeb tim1, tim0;
|
||||
int tdif, iret;
|
||||
|
||||
if (modified && fd==0) { /* earlier modification */
|
||||
modified=0;
|
||||
return(2);
|
||||
}
|
||||
ftime(&tim0);
|
||||
tdif=tmo_msec;
|
||||
while (tdif>=0) {
|
||||
ERR_I(iret=CocHandle1Request(tdif, fd));
|
||||
if (iret==2 && fd==0) return(iret); /* a variable was changed */
|
||||
if (iret!=3) return(iret); /* event on fd or timeout */
|
||||
if (fd==0) {
|
||||
if (iret==2) return(2); /* modification of a varaible */
|
||||
} 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);
|
||||
}
|
||||
@ -223,6 +233,6 @@ void CocCloseServer() {
|
||||
}
|
||||
free(cList);
|
||||
close(mainFd);
|
||||
buf_free(buf); buf_free(bufo);
|
||||
str_free_buf(buf); str_free_buf(bufo);
|
||||
logfileClose();
|
||||
}
|
||||
|
@ -1,3 +1,6 @@
|
||||
#ifndef _SERVER_H_
|
||||
#define _SERVER_H_
|
||||
|
||||
#include "coc.h"
|
||||
|
||||
struct CocClient { struct CocClient *next; int fd; int mode; char cmd[80]; char res[80]; };
|
||||
@ -10,7 +13,7 @@ int CocHandle1Request(int tmo_msec, int fd);
|
||||
handle hetwork requests.
|
||||
|
||||
return value: <0: error
|
||||
=0: error
|
||||
=0: timeout
|
||||
=1: event on fd
|
||||
=2: variable was changed
|
||||
=3: other network request treated
|
||||
@ -20,10 +23,10 @@ int CocHandle1Request(int tmo_msec, int fd);
|
||||
For CocHandleRequests:
|
||||
|
||||
if fd=0: returns when a network request has changed a variable,
|
||||
or when timeout has expired
|
||||
or when timeout has expired (result is 0 or 2)
|
||||
|
||||
if fd>0: returns when an read event is pending on fd
|
||||
or when timeout has expired
|
||||
or when timeout has expired (result is 0 or 1)
|
||||
|
||||
*/
|
||||
|
||||
@ -33,3 +36,5 @@ struct CocClient *CocGetNextCmd(void);
|
||||
*/
|
||||
|
||||
void CocCloseServer(void);
|
||||
|
||||
#endif /* _SERVER_H_ */
|
||||
|
27
tecs/str_buf.h
Normal file
27
tecs/str_buf.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef _STR_BUF_H_
|
||||
#define _STR_BUF_H_
|
||||
|
||||
typedef struct { char *buf; int dsize, rdpos, wrpos; char sep; } Str_Buf;
|
||||
|
||||
#define str_get_str(BUF,RES) str_nget_str(BUF,RES,sizeof(RES))
|
||||
|
||||
/* input */
|
||||
void str_get_start(Str_Buf *buf);
|
||||
char *str_nget_str(Str_Buf *buf, char *result, int reslen);
|
||||
int str_get_int(Str_Buf *buf, int *res);
|
||||
int str_get_float(Str_Buf *buf, float *res);
|
||||
int str_get_end(Str_Buf *buf);
|
||||
|
||||
/* output */
|
||||
void str_put_start(Str_Buf *buf);
|
||||
int str_put_str(Str_Buf *buf, const char *str);
|
||||
int str_put_int(Str_Buf *buf, int val);
|
||||
int str_put_float(Str_Buf *buf, float val);
|
||||
|
||||
/* common */
|
||||
#define STR_NOSEPARATOR ((char)1)
|
||||
Str_Buf *str_create_buf(size_t size, char separator);
|
||||
void str_link_buf(Str_Buf *buf, char *str, int size, char separator);
|
||||
void str_free_buf(Str_Buf *buf);
|
||||
|
||||
#endif /* _STR_BUF_H_ */
|
108
tecs/str_util.h
Normal file
108
tecs/str_util.h
Normal file
@ -0,0 +1,108 @@
|
||||
#ifndef _UTIL_H_
|
||||
#define _UTIL_H_
|
||||
|
||||
/*
|
||||
use these macros if DST is a fixed length character array
|
||||
*/
|
||||
|
||||
#define str_trim(DST,SRC,L) str_ntrim(DST,SRC,sizeof(DST),L)
|
||||
#define str_split(DST,SRC,SEP) str_nsplit(DST,SRC,SEP,sizeof(DST))
|
||||
#define str_substitute(DST,SRC,OLD,NEW) str_nsubstitute(DST,SRC,OLD,NEW,sizeof(DST))
|
||||
#define str_upcase(DST,SRC) str_nupcase(DST,SRC,sizeof(DST))
|
||||
#define str_copy(DST,SRC) str_ncpy(DST,SRC,sizeof(DST))
|
||||
#define str_append(DST,SRC) str_ncat(DST,SRC,sizeof(DST))
|
||||
|
||||
|
||||
char *str_split1(char *str, char separator);
|
||||
/*
|
||||
trims text before separator in *str and returns
|
||||
a pointer to the first character after separator
|
||||
*/
|
||||
|
||||
char *str_splitx(char *str, char sep, char *list[], int *n);
|
||||
/*
|
||||
split string into *n strings using separator sep.
|
||||
spaces at the end of the elements are trimmed
|
||||
attention: *str is modified ('\0' placed at the end of the elements)
|
||||
|
||||
if *n separators are found, result points to string after *n-th separator
|
||||
else result is NULL
|
||||
*n contains number of elements stored in list
|
||||
*/
|
||||
|
||||
int str_ntrim(char *dest, const char *src, int ldest, int lsrc);
|
||||
/*
|
||||
copy characters 0 to lsrc-1 from src to dest (max ldest chars).
|
||||
*/
|
||||
|
||||
char *str_nsplit(char *dst, const char *src, char sep, int dstlen);
|
||||
/*
|
||||
returns a pointer to the text after the separator sep in *src
|
||||
and copies the text before the separator to *dst
|
||||
when *src does not contain the separator sep
|
||||
NULL is returned, and *dst is a copy of *src
|
||||
*/
|
||||
|
||||
char *str_read_file(char *file);
|
||||
/*
|
||||
return one string containing the contents of file *file
|
||||
comments separated by '!' are omitted. The caller must
|
||||
free the result after use.
|
||||
*/
|
||||
|
||||
void str_replace_char(char *str, char ch, char rep);
|
||||
/*
|
||||
replace all occurences of character ch by character rep in string *str
|
||||
*/
|
||||
|
||||
int str_nsubstitute(char *result, char *str, char *old, char *new, int reslen);
|
||||
/*
|
||||
replace every instance of old in str by new.
|
||||
the result must not overlap
|
||||
if the result would be longer than reslen, the result is en empty string
|
||||
and the return value is -1;
|
||||
else the return value is the length of the result.
|
||||
return one string containing the contents of file *file
|
||||
the contents are treated in the following way:
|
||||
- #0,#1,...#n is replaced by the corresponding argument *args[n] (n=0..nargs-1, nargs<10)
|
||||
- at the end of each line spaces and comments separated by ! are trimmed
|
||||
*/
|
||||
|
||||
void str_nupcase(char *dst, const char *src, int dstlen);
|
||||
/*
|
||||
convert *str to uppercase
|
||||
*/
|
||||
|
||||
#ifdef __VMS_VER
|
||||
#if _VMS_VER<70000000
|
||||
|
||||
int strcasecmp(const char *str1, const char *str2);
|
||||
/*
|
||||
compare *str1 with *str2
|
||||
the comparison is not case sensitive
|
||||
if result=0: strings are equal
|
||||
else
|
||||
result>0 <==> *str1>*str2
|
||||
first different character is at position abs(result)-1
|
||||
*/
|
||||
|
||||
#else
|
||||
#include <strings.h>
|
||||
#endif /* __VMS_VER<70000000 */
|
||||
#else
|
||||
#include <strings.h>
|
||||
#endif /* __VMS_VER */
|
||||
|
||||
int str_ncpy(char *dst, const char *src, int maxdest);
|
||||
/*
|
||||
copy *src to *dest, maximal maxdest characters,
|
||||
it is guaranteed, that dst contains '\0'
|
||||
*/
|
||||
|
||||
int str_ncat(char *dst, const char *src, int maxdest);
|
||||
/*
|
||||
append *src to *dest, maximal maxdest characters,
|
||||
it is guaranteed, that dst contains '\0'
|
||||
*/
|
||||
|
||||
#endif /* _UTIL_H_ */
|
@ -13,7 +13,7 @@ main(int argc, char *argv[])
|
||||
char *res;
|
||||
|
||||
#ifdef __VMS
|
||||
ERR_P(conn=TeccInit("@start_tecs -p 9753 -l -d [.log]", 9753));
|
||||
ERR_P(conn=TeccInit("@start_tecs test -p 9753 -l -d ud0:[zolliker.lsc.log]", 9753));
|
||||
#else
|
||||
ERR_P(conn=TeccInit("TecsServer -p 9753 -l -d log/ &", 9753));
|
||||
#endif
|
||||
|
25
tecs/tecc.c
25
tecs/tecc.c
@ -1,4 +1,6 @@
|
||||
#include <string.h>
|
||||
#include "errhdl.h"
|
||||
#include "util.h"
|
||||
#include "tecc.h"
|
||||
|
||||
static char device[80], command[80];
|
||||
@ -10,9 +12,9 @@ pTecsClient TeccInit(char *startcmd, int port) {
|
||||
|
||||
ERR_SP(conn=(CocConn *)malloc(sizeof(*conn)));
|
||||
ERR_I(CocInitClient(conn, "", port, "#rwacs", 0, startcmd));
|
||||
CocDefFlt(tempX, CocRD);
|
||||
CocDefFlt(tempC, CocRD);
|
||||
CocDefFlt(tempP, CocRD);
|
||||
CocDefFlt(tempC, CocWR);
|
||||
CocDefFlt(tempX, CocRD);
|
||||
CocDefStr(device, CocWR);
|
||||
CocDefInt(quit, CocWR);
|
||||
CocDefCmd(command);
|
||||
@ -34,19 +36,18 @@ char *TeccGetDev(pTecsClient conn) {
|
||||
OnError: return(NULL);
|
||||
}
|
||||
|
||||
int TeccGet3(pTecsClient conn, float temp[3]) {
|
||||
int TeccGet3(pTecsClient conn, float *tC, float *tX, float *tP) {
|
||||
ERR_I(CocCmd(conn, "tempC,tempX,tempP"));
|
||||
temp[0]=tempC;
|
||||
temp[1]=tempX;
|
||||
temp[2]=tempP;
|
||||
*tC=tempC;
|
||||
*tX=tempX;
|
||||
*tP=tempP;
|
||||
return(0);
|
||||
OnError: return(-1);
|
||||
}
|
||||
|
||||
int TeccGet(pTecsClient conn, float *temp) {
|
||||
float t[3];
|
||||
ERR_I(TeccGet3(conn, t));
|
||||
*temp=t[2];
|
||||
ERR_I(CocCmd(conn, "tempP"));
|
||||
*temp=tempP;
|
||||
return(0);
|
||||
OnError: return(-1);
|
||||
}
|
||||
@ -65,14 +66,14 @@ int TeccSend(pTecsClient conn, char *cmd, char *reply, int replyLen) {
|
||||
str_copy(command, cmd);
|
||||
ERR_I(CocCmd(conn, "[$]"));
|
||||
cnt=40;
|
||||
util_delay(100);
|
||||
CocDelay(100);
|
||||
while (cnt>0) {
|
||||
ERR_I(CocCmd(conn, "$"));
|
||||
if (command[0]!='\0') {
|
||||
str_ncpy(reply, command, replyLen);
|
||||
return(0);
|
||||
}
|
||||
util_delay(250);
|
||||
CocDelay(250);
|
||||
cnt--;
|
||||
}
|
||||
str_ncpy(reply, "<no response>", replyLen);
|
||||
@ -82,7 +83,7 @@ int TeccSend(pTecsClient conn, char *cmd, char *reply, int replyLen) {
|
||||
|
||||
int TeccQuitServer(pTecsClient conn) {
|
||||
quit=1;
|
||||
ERR_I(CocCmd(conn, "quit"));
|
||||
ERR_I(CocCmd(conn, "[quit]"));
|
||||
return(0);
|
||||
OnError: return(-1);
|
||||
}
|
||||
|
@ -1,3 +1,6 @@
|
||||
#ifndef _TECC_H_
|
||||
#define _TECC_H_
|
||||
|
||||
#include "client.h"
|
||||
/*
|
||||
tecc.h: tecs client interface routines
|
||||
@ -41,3 +44,4 @@ int TeccKillServer(pTecsClient conn);
|
||||
/* kill the server process
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
#endif /* _TECC_H_ */
|
||||
|
940
tecs/tecs.c
940
tecs/tecs.c
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user