renamed sources
This commit is contained in:
@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
** TAS_SRC:[LIB]ASYNSRV_ERRCODES.H
|
|
||||||
**
|
|
||||||
** Include file generated from ASYNSRV_ERRCODES.OBJ
|
|
||||||
**
|
|
||||||
** 25-NOV-1999 14:40:45.57
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define ASYNSRV__NO_ROOM 0x86480CC
|
|
||||||
#define ASYNSRV__FORCED_CLOSED 0x86480C4
|
|
||||||
#define ASYNSRV__BAD_SOCKET 0x86480BC
|
|
||||||
#define ASYNSRV__BAD_SEND_UNKN 0x86480B4
|
|
||||||
#define ASYNSRV__BAD_SEND_PIPE 0x86480AC
|
|
||||||
#define ASYNSRV__BAD_SEND_NET 0x86480A4
|
|
||||||
#define ASYNSRV__BAD_SEND_LEN 0x864809C
|
|
||||||
#define ASYNSRV__BAD_SEND 0x8648094
|
|
||||||
#define ASYNSRV__BAD_REPLY 0x864808C
|
|
||||||
#define ASYNSRV__BAD_RECV1_PIPE 0x8648084
|
|
||||||
#define ASYNSRV__BAD_RECV1_NET 0x864807C
|
|
||||||
#define ASYNSRV__BAD_RECV1 0x8648074
|
|
||||||
#define ASYNSRV__BAD_RECV_UNKN 0x864806C
|
|
||||||
#define ASYNSRV__BAD_RECV_PIPE 0x8648064
|
|
||||||
#define ASYNSRV__BAD_RECV_NET 0x864805C
|
|
||||||
#define ASYNSRV__BAD_RECV_LEN 0x8648054
|
|
||||||
#define ASYNSRV__BAD_RECV 0x864804C
|
|
||||||
#define ASYNSRV__BAD_PROT_LVL 0x8648044
|
|
||||||
#define ASYNSRV__BAD_PAR 0x864803C
|
|
||||||
#define ASYNSRV__BAD_NOT_BCD 0x8648034
|
|
||||||
#define ASYNSRV__BAD_HOST 0x864802C
|
|
||||||
#define ASYNSRV__BAD_FLUSH 0x8648024
|
|
||||||
#define ASYNSRV__BAD_CONNECT 0x864801C
|
|
||||||
#define ASYNSRV__BAD_CMND_LEN 0x8648014
|
|
||||||
#define ASYNSRV__BAD_BIND 0x864800C
|
|
||||||
#define ASYNSRV__FACILITY 0x864
|
|
186
tecs/client.c
186
tecs/client.c
@ -1,186 +0,0 @@
|
|||||||
#include <sys/socket.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include "errhdl.h"
|
|
||||||
#include "client.h"
|
|
||||||
#include "str_util.h"
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
int CocConnect(CocConn *conn, int allowConnRefused) {
|
|
||||||
int i;
|
|
||||||
struct sockaddr_in sadr;
|
|
||||||
|
|
||||||
ERR_I(CocCreateSockAdr(&sadr, conn->host, conn->port));
|
|
||||||
ERR_SI(conn->fd=socket(AF_INET, SOCK_STREAM, 0));
|
|
||||||
i = 1;
|
|
||||||
ERR_SI(setsockopt(conn->fd,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(int))); /* allow quick port reuse */
|
|
||||||
i=connect(conn->fd, (struct sockaddr *)&sadr, sizeof(sadr));
|
|
||||||
if (i<0) {
|
|
||||||
if (allowConnRefused && errno==ECONNREFUSED) return(1);
|
|
||||||
ERR_COD(errno);
|
|
||||||
}
|
|
||||||
return(0);
|
|
||||||
OnError: return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int CocOpen(CocConn *conn)
|
|
||||||
{
|
|
||||||
int i, try, tmo;
|
|
||||||
|
|
||||||
ERR_I(i=CocConnect(conn, conn->startcmd[0]!='\0'));
|
|
||||||
if (i==0) return(0);
|
|
||||||
|
|
||||||
printf("%s\n", conn->startcmd);
|
|
||||||
ERR_I(system(conn->startcmd));
|
|
||||||
|
|
||||||
try=15;
|
|
||||||
tmo=100; /* wait total ca. 10 sec. for 15 tries */
|
|
||||||
while (try>0) {
|
|
||||||
try--;
|
|
||||||
CocDelay(tmo); tmo=tmo*5/4;
|
|
||||||
ERR_I(i=CocConnect(conn, try>0));
|
|
||||||
if (i==0) return(0);
|
|
||||||
}
|
|
||||||
ERR_MSG("error in CocConnect");
|
|
||||||
OnError: return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
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'));
|
|
||||||
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);
|
|
||||||
OnError: return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
int CocSendMagic(CocConn *conn, char *magic) {
|
|
||||||
char *err;
|
|
||||||
|
|
||||||
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));
|
|
||||||
return(0);
|
|
||||||
OnError: return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
int CocTryCmd(CocConn *conn)
|
|
||||||
{ if (conn->fd<0) {
|
|
||||||
ERR_I(CocOpen(conn));
|
|
||||||
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));
|
|
||||||
return(0);
|
|
||||||
OnError: return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
int CocCmd(CocConn *conn, const char *rwList)
|
|
||||||
{ int iret, cnt, setmode, i;
|
|
||||||
char *err;
|
|
||||||
const char *t, *s;
|
|
||||||
char nam[32];
|
|
||||||
CocVar *var;
|
|
||||||
void *adr;
|
|
||||||
|
|
||||||
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');
|
|
||||||
|
|
||||||
cnt=3;
|
|
||||||
while (1) {
|
|
||||||
cnt--;
|
|
||||||
if (cnt<=0) {
|
|
||||||
ERR_I(CocTryCmd(conn));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
iret=CocTryCmd(conn);
|
|
||||||
if (iret>=0) break;
|
|
||||||
close(conn->fd);
|
|
||||||
conn->fd=-1;
|
|
||||||
if (ErrCode!=ECONNRESET && ErrCode!=EPIPE) goto OnError;
|
|
||||||
ErrShow("try again, error was");
|
|
||||||
}
|
|
||||||
ERR_P(err=str_get_str(conn->resbuf, NULL));
|
|
||||||
if (*err!='\0') { ErrMsg(err); ErrTxt(": (response from server)",0 ); goto OnError; }
|
|
||||||
|
|
||||||
/* read values */
|
|
||||||
s=rwList;
|
|
||||||
setmode=0;
|
|
||||||
do {
|
|
||||||
t=strchr(s, ',');
|
|
||||||
if (t==NULL) t=s+strlen(s);
|
|
||||||
if (*s=='[') {
|
|
||||||
s++;
|
|
||||||
setmode=1;
|
|
||||||
}
|
|
||||||
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));
|
|
||||||
return(0);
|
|
||||||
|
|
||||||
OnError: 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);
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
#ifndef _CLIENT_H_
|
|
||||||
#define _CLIENT_H_
|
|
||||||
|
|
||||||
#include "coc.h"
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int fd, port;
|
|
||||||
CocVar *varList;
|
|
||||||
Str_Buf *cmdbuf; /* for sending command */
|
|
||||||
Str_Buf *resbuf; /* for response */
|
|
||||||
char host[64];
|
|
||||||
char magic[32];
|
|
||||||
char startcmd[512];
|
|
||||||
} CocConn;
|
|
||||||
|
|
||||||
int CocInitClient(CocConn *conn, char *host, int port, char *magic, int bufsize, char *startcmd);
|
|
||||||
int CocSendMagic(CocConn *conn, char *magic);
|
|
||||||
int CocCmd(CocConn *conn, const char *rwList);
|
|
||||||
void CocCloseClient(CocConn *conn);
|
|
||||||
|
|
||||||
#endif /* _CLIENT_H_ */
|
|
247
tecs/coc.c
247
tecs/coc.c
@ -1,247 +0,0 @@
|
|||||||
#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 "str_util.h"
|
|
||||||
#include "coc.h"
|
|
||||||
/*-------------------------------------------------------------------------*/
|
|
||||||
/* CreateSocketAddress stolen from Tcl. Thanks to John Ousterhout */
|
|
||||||
|
|
||||||
CocVar *serverVarList=NULL;
|
|
||||||
static CocVar **varListHdl=&serverVarList;
|
|
||||||
int CocRD=0;
|
|
||||||
int CocWR=0;
|
|
||||||
|
|
||||||
int CocCreateSockAdr(
|
|
||||||
struct sockaddr_in *sockaddrPtr, /* Socket address */
|
|
||||||
const char *host, /* Host. NULL implies INADDR_ANY */
|
|
||||||
int port) /* Port number */
|
|
||||||
{
|
|
||||||
struct hostent *hostent; /* Host database entry */
|
|
||||||
struct in_addr addr; /* For 64/32 bit madness */
|
|
||||||
|
|
||||||
(void) memset((char *) sockaddrPtr, '\0', sizeof(struct sockaddr_in));
|
|
||||||
sockaddrPtr->sin_family = AF_INET;
|
|
||||||
sockaddrPtr->sin_port = htons((unsigned short) (port & 0xFFFF));
|
|
||||||
if (host == NULL || 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, Str_Buf *buf)
|
|
||||||
{
|
|
||||||
struct timeval tmo={0,1};
|
|
||||||
fd_set mask;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
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");
|
|
||||||
|
|
||||||
ERR_SI(buf->wrpos=recv(fd, buf->buf, buf->dsize, 0));
|
|
||||||
if (buf->wrpos==0) { ERR_COD(ECONNRESET); }
|
|
||||||
str_get_start(buf);
|
|
||||||
return(buf->wrpos);
|
|
||||||
OnError: return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CocVarList(CocVar **varList) {
|
|
||||||
assert(varList!=NULL);
|
|
||||||
varListHdl=varList;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
while (p!=NULL && 0!=strcmp(p->name,name)) p=p->next;
|
|
||||||
return(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
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=CocFindVar1(*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;
|
|
||||||
return(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
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, &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 (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) {
|
|
||||||
ERR_I(str_get_int(buf, (int *)adr));
|
|
||||||
} else if (var->type==-2) {
|
|
||||||
ERR_I(str_get_float(buf, (float *)adr));
|
|
||||||
} else if (var->type>1) {
|
|
||||||
ERR_P(str_nget_str(buf, (char *)adr, var->type));
|
|
||||||
} else {
|
|
||||||
ERR_MSG("unknown type");
|
|
||||||
}
|
|
||||||
if (secure) { /* we are the server */
|
|
||||||
(*var->flag)++;
|
|
||||||
}
|
|
||||||
return(0);
|
|
||||||
OnError: return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int CocPutVar(CocVar *varList, Str_Buf *buf, const char *name, int secure) {
|
|
||||||
CocVar *var;
|
|
||||||
void *adr;
|
|
||||||
char *c;
|
|
||||||
|
|
||||||
var=CocFindVar(varList, name, &adr);
|
|
||||||
if (var==NULL) ERR_MSG("undefined variable");
|
|
||||||
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) {
|
|
||||||
ERR_I(str_put_int(buf, *(int *)adr));
|
|
||||||
} else if (var->type==-2) {
|
|
||||||
ERR_I(str_put_float(buf, *(float *)adr));
|
|
||||||
} else if (var->type>1) {
|
|
||||||
ERR_I(str_put_str(buf, adr));
|
|
||||||
} else {
|
|
||||||
ERR_MSG("unknown type");
|
|
||||||
}
|
|
||||||
if (secure) { /* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
47
tecs/coc.h
47
tecs/coc.h
@ -1,47 +0,0 @@
|
|||||||
#ifndef _COC_H_
|
|
||||||
#define _COC_H_
|
|
||||||
|
|
||||||
#include <netinet/in.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, Str_Buf *buf);
|
|
||||||
|
|
||||||
typedef struct { void *next; char name[32]; void *var; int *flag; int type; void *strucType; } CocVar;
|
|
||||||
|
|
||||||
extern int CocRD;
|
|
||||||
extern int CocWR;
|
|
||||||
CocVar *serverVarList;
|
|
||||||
|
|
||||||
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, 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 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_ */
|
|
251
tecs/dlog.c
251
tecs/dlog.c
@ -1,251 +0,0 @@
|
|||||||
|
|
||||||
/* switch off ANSI_C_SOURCE (allows compiling all sources with cc/stand=ansi) */
|
|
||||||
#ifdef __VMS
|
|
||||||
#ifdef __HIDE_FORBIDDEN_NAMES
|
|
||||||
#undef __HIDE_FORBIDDEN_NAMES
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include "errhdl.h"
|
|
||||||
#include "str_util.h"
|
|
||||||
#include "dlog.h"
|
|
||||||
|
|
||||||
#define VERSION 1.1
|
|
||||||
|
|
||||||
#define DEFINED(F) (abs((F)-dset->undef)>1.0e-5*(F))
|
|
||||||
|
|
||||||
static time_t gmtoff;
|
|
||||||
|
|
||||||
int DlogWrite(DlogSet *dset, int idx, void *data) {
|
|
||||||
int p;
|
|
||||||
|
|
||||||
p = dset->headsize + (idx % dset->nlen) * dset->fsize;
|
|
||||||
if (p!=dset->pos) {
|
|
||||||
ERR_SI(lseek(dset->fd, p, SEEK_SET));
|
|
||||||
}
|
|
||||||
ERR_SI(write(dset->fd, data, dset->fsize));
|
|
||||||
dset->pos = p + dset->fsize;
|
|
||||||
return(0);
|
|
||||||
OnError:
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int DlogRead(DlogSet *dset, int idx, void *data) {
|
|
||||||
int p;
|
|
||||||
|
|
||||||
p = dset->headsize + (idx % dset->nlen) * dset->fsize;
|
|
||||||
if (p!=dset->pos) {
|
|
||||||
ERR_SI(lseek(dset->fd, p, SEEK_SET));
|
|
||||||
}
|
|
||||||
ERR_SI(read(dset->fd, data, dset->fsize));
|
|
||||||
dset->pos = p + dset->fsize;
|
|
||||||
return(0);
|
|
||||||
OnError:
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int DlogOpen(DlogSet *dset, char *name, int write) {
|
|
||||||
int i, p, np, fd, flags;
|
|
||||||
time_t tim;
|
|
||||||
struct tm *timp;
|
|
||||||
|
|
||||||
fd=0;
|
|
||||||
str_copy(dset->name, name);
|
|
||||||
if (write) {
|
|
||||||
flags=O_RDWR | O_SYNC;
|
|
||||||
} else {
|
|
||||||
flags=O_RDONLY | O_SYNC;
|
|
||||||
}
|
|
||||||
#ifdef __VMS
|
|
||||||
ERR_SI(fd=open(name, flags, 0, "SHR=UPD"));
|
|
||||||
gmtoff=0;
|
|
||||||
#else
|
|
||||||
ERR_SI(fd=open(name, flags, 0));
|
|
||||||
time(&tim);
|
|
||||||
timp=localtime(&tim);
|
|
||||||
gmtoff=timp->tm_gmtoff;
|
|
||||||
#endif
|
|
||||||
dset->fd=fd;
|
|
||||||
|
|
||||||
p=(char *)&dset->fd - (char *)dset;
|
|
||||||
ERR_SI(read(dset->fd, dset, p));
|
|
||||||
dset->pos=p;
|
|
||||||
if ((int)(dset->version*1000+0.5) != (int)(VERSION*1000+0.5)) ERR_MSG("version mismatch");
|
|
||||||
if (dset->headsize != p) ERR_MSG("illegal dlog file");
|
|
||||||
return(0);
|
|
||||||
OnError:
|
|
||||||
if (fd!=0) close(fd);
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int DlogCreate(DlogSet *dset, char *name, time_t start, int nset, int nlen, int period, float undef) {
|
|
||||||
int fd, i, j, p;
|
|
||||||
va_list ap;
|
|
||||||
float f[DLOG_MAX_SET];
|
|
||||||
|
|
||||||
fd=0;
|
|
||||||
if (nset>DLOG_MAX_SET) ERR_MSG("nset too large");
|
|
||||||
dset->nset=nset;
|
|
||||||
dset->nlen=nlen;
|
|
||||||
dset->start=start;
|
|
||||||
dset->last=start-period;
|
|
||||||
dset->period=period;
|
|
||||||
dset->undef=undef;
|
|
||||||
dset->version=VERSION;
|
|
||||||
str_copy(dset->name, name);
|
|
||||||
|
|
||||||
for (i=0; i<nset; i++) {
|
|
||||||
f[i]=dset->undef;
|
|
||||||
}
|
|
||||||
ERR_SI(fd=open(name, O_RDWR | O_CREAT | O_SYNC | O_TRUNC, 0666));
|
|
||||||
dset->fd=fd;
|
|
||||||
p=(char *)&dset->fd - (char *)dset;
|
|
||||||
dset->headsize = p;
|
|
||||||
dset->fsize = nset * sizeof(float);
|
|
||||||
ERR_SI(write(dset->fd, dset, p));
|
|
||||||
dset->pos=p;
|
|
||||||
return(0);
|
|
||||||
OnError:
|
|
||||||
if (fd!=0) close(fd);
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int DlogPut(DlogSet *dset, time_t time, int nset, float val[]) {
|
|
||||||
int i, i0, j;
|
|
||||||
float f[DLOG_MAX_SET], f0[DLOG_MAX_SET];
|
|
||||||
|
|
||||||
if (nset > dset->nset) nset = dset->nset;
|
|
||||||
|
|
||||||
for (j=0; j < nset; j++) { f[j]=val[j]; }
|
|
||||||
for (j=nset; j < dset->nset; j++) { f[j]=dset->undef; }
|
|
||||||
|
|
||||||
i = ( time - dset->start ) / dset->period;
|
|
||||||
i0 = ( dset->last - dset->start ) / dset->period;
|
|
||||||
|
|
||||||
if (i0==i) {
|
|
||||||
ERR_I(DlogRead(dset, i, f0));
|
|
||||||
for (j=0; j<nset; j++) {
|
|
||||||
if (DEFINED(f0[j]) && /* when last point defined */
|
|
||||||
(i%2 && f0[j]>f[j] || /* take maximum (for odd i) */
|
|
||||||
!i%2 && f0[j]<f[j] ) /* or minimum (for even i) */
|
|
||||||
) f[j]=f0[j]; /* of f0 and f0 */
|
|
||||||
}
|
|
||||||
} else if (i0<i-1) {
|
|
||||||
for (j=0; j < dset->nset; j++) { f0[j]=dset->undef; }
|
|
||||||
i0++;
|
|
||||||
while (i0<i) {
|
|
||||||
ERR_I(DlogWrite(dset, i0, f0));
|
|
||||||
i0++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ERR_I(DlogWrite(dset, i, f));
|
|
||||||
dset->last=time;
|
|
||||||
return(0);
|
|
||||||
OnError:
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int DlogGet(DlogSet *dset, int iset, int nmax, double *starttime, float x[], float y[]) {
|
|
||||||
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;
|
|
||||||
if (i - dset->nlen > 0) {
|
|
||||||
i1 = i - dset->nlen + 1;
|
|
||||||
} else {
|
|
||||||
i1 = 0;
|
|
||||||
}
|
|
||||||
i0=i1;
|
|
||||||
|
|
||||||
*starttime = dset->start + i1 * dset->period + gmtoff;
|
|
||||||
n=0;
|
|
||||||
undef=2;
|
|
||||||
while (i0<=i) {
|
|
||||||
if (n>=nmax) return(n);
|
|
||||||
ERR_I(DlogRead(dset, i0, f));
|
|
||||||
i0++;
|
|
||||||
if (DEFINED(f[iset])) {
|
|
||||||
x[n]=(float)(i0-i1)*dset->period;
|
|
||||||
y[n]=f[iset];
|
|
||||||
n++;
|
|
||||||
undef=0;
|
|
||||||
} else if (undef==0) {
|
|
||||||
undef=1;
|
|
||||||
} else if (undef==1) {
|
|
||||||
undef=2;
|
|
||||||
x[n]=0;
|
|
||||||
y[n]=0;
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return(n);
|
|
||||||
OnError:
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int DlogGetMany(DlogSet *dset, int nset, int nmax, double *starttime, float x[], float y[], int index[]) {
|
|
||||||
int n, k, nmx, ntot;
|
|
||||||
|
|
||||||
ntot=0;
|
|
||||||
for (k=0; k<nset; k++) {
|
|
||||||
index[k]=ntot;
|
|
||||||
nmx=(nmax-ntot)/(nset-k);
|
|
||||||
ERR_I(n=DlogGet(dset, k, nmx, starttime, &x[ntot], &y[ntot]));
|
|
||||||
ntot+=n;
|
|
||||||
}
|
|
||||||
return(ntot);
|
|
||||||
OnError:
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int dlog_get_(char *name, int *nset, int *nmax, double *starttime, float x[], float y[], int index[], int namlen) {
|
|
||||||
DlogSet dset;
|
|
||||||
char buf[64];
|
|
||||||
int ntot;
|
|
||||||
/* for compaq unix */
|
|
||||||
str_trim(buf, name, namlen);
|
|
||||||
ERR_I(DlogOpen(&dset, buf, 0));
|
|
||||||
ERR_I(ntot=DlogGetMany(&dset, *nset, *nmax, starttime, x, y, index));
|
|
||||||
DlogClose(&dset);
|
|
||||||
return(ntot);
|
|
||||||
OnError:
|
|
||||||
ErrShow("error in dlog_get_");
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Dlog_Get(char **name, int *nset, int *nmax, double *starttime, float x[], float y[], int index[]) {
|
|
||||||
/* for VMS */
|
|
||||||
return(dlog_get_(name[1], nset, nmax, starttime, x, y, index, *(short *)name));
|
|
||||||
}
|
|
||||||
|
|
||||||
int DlogUpd(DlogSet *dset) {
|
|
||||||
ERR_SI(lseek(dset->fd, 0, SEEK_SET));
|
|
||||||
ERR_SI(write(dset->fd, &dset->last, sizeof(int)));
|
|
||||||
dset->pos=sizeof(int);
|
|
||||||
#ifdef __VMS
|
|
||||||
close(dset->fd);
|
|
||||||
DlogOpen(dset, dset->name, 1);
|
|
||||||
#endif
|
|
||||||
return(0);
|
|
||||||
OnError:
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int DlogClose(DlogSet *dset) {
|
|
||||||
ERR_I(DlogUpd(dset));
|
|
||||||
close(dset->fd);
|
|
||||||
return(0);
|
|
||||||
OnError:
|
|
||||||
return(-1);
|
|
||||||
}
|
|
54
tecs/dlog.h
54
tecs/dlog.h
@ -1,54 +0,0 @@
|
|||||||
#ifndef _DLOG_H_
|
|
||||||
#define _DLOG_H_
|
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#define DLOG_MAX_SET 32
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
time_t last, start;
|
|
||||||
float version, undef;
|
|
||||||
int period, headsize, fsize, nset, nlen;
|
|
||||||
int fd, pos;
|
|
||||||
char name[128];
|
|
||||||
} DlogSet;
|
|
||||||
|
|
||||||
|
|
||||||
int DlogOpen(DlogSet *dset, char *name, int write);
|
|
||||||
/* open existing dlog set */
|
|
||||||
|
|
||||||
int DlogCreate(DlogSet *dset, char *name, time_t start, int nset, int nlen, int period, float undef);
|
|
||||||
/* create new dlog file */
|
|
||||||
|
|
||||||
int DlogPut(DlogSet *dset, time_t time, int nset, float val[]);
|
|
||||||
/* put values to dlog set */
|
|
||||||
|
|
||||||
int DlogGet(DlogSet *dset, int iset, int nmax, double *starttime, float *x, float *y);
|
|
||||||
/* get one dataset from dlog set
|
|
||||||
|
|
||||||
iset is the dataset to be returned
|
|
||||||
nmax is the maximal number of points to be returned
|
|
||||||
x, y: the data (arrays declared with at least nmax elements)
|
|
||||||
|
|
||||||
on success, the return value is the effective length of returned data
|
|
||||||
*/
|
|
||||||
|
|
||||||
int DlogGetMany(DlogSet *dset, int nset, int nmax, double *starttime, float x[], float y[], int index[]);
|
|
||||||
/* get many datasets from dlog set
|
|
||||||
|
|
||||||
nset is the nember of datasets to be returned
|
|
||||||
nmax is the maximal number of points to be returned
|
|
||||||
x, y: the data, one dataset after an other (arrays declared with at least nmax elements)
|
|
||||||
index must be an array of at least nset elements.
|
|
||||||
it returns the start indices in x[] and y[] of the data sets.
|
|
||||||
|
|
||||||
on success, the return value is the effective length of returned data
|
|
||||||
*/
|
|
||||||
|
|
||||||
int DlogUpd(DlogSet *dset);
|
|
||||||
/* update pointer */
|
|
||||||
|
|
||||||
int DlogClose(DlogSet *dset);
|
|
||||||
/* close dlog set */
|
|
||||||
|
|
||||||
#endif /* _DLOG_H_ */
|
|
@ -1,86 +0,0 @@
|
|||||||
#include <assert.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "errhdl.h"
|
|
||||||
|
|
||||||
#define SLEN 64
|
|
||||||
#define MLEN 64
|
|
||||||
|
|
||||||
static char *txt[SLEN];
|
|
||||||
static int sp=0;
|
|
||||||
|
|
||||||
int ErrCode;
|
|
||||||
char *ErrMessage=NULL;
|
|
||||||
|
|
||||||
void ErrTxt(char *text, int systemError)
|
|
||||||
{
|
|
||||||
if (systemError) { sp=0; ErrCode=errno; ErrMessage=strerror(errno); }
|
|
||||||
if (sp<SLEN) {
|
|
||||||
txt[sp++]=text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ErrMsg(char *msg)
|
|
||||||
{
|
|
||||||
ErrCode=-1;
|
|
||||||
ErrMessage=msg; sp=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ErrCod(int code)
|
|
||||||
{
|
|
||||||
ErrCode=code;
|
|
||||||
ErrMessage=strerror(code); sp=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ErrWriteGeneral(char *text, void (*outrtn)(), void *arg)
|
|
||||||
{
|
|
||||||
int i, l;
|
|
||||||
char buf[256];
|
|
||||||
|
|
||||||
l=strlen(text)+strlen(ErrMessage)+6;
|
|
||||||
assert(l<256);
|
|
||||||
sprintf(buf, "--- %s: %s", text, ErrMessage);
|
|
||||||
for (i=0;i<sp;i++) {
|
|
||||||
if (txt[i][0]==':') {
|
|
||||||
l+=strlen(txt[i]);
|
|
||||||
assert(l<256);
|
|
||||||
strcat(buf, &(txt[i][1]));
|
|
||||||
} else {
|
|
||||||
outrtn(arg, buf);
|
|
||||||
l=strlen(txt[i]);
|
|
||||||
assert(l<256);
|
|
||||||
strcpy(buf, txt[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
outrtn(arg, buf);
|
|
||||||
outrtn(arg, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
void ErrOutFil(void *arg, char *text) {
|
|
||||||
fprintf((FILE *)arg, "%s\n", text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ErrWrite(FILE *fil, char *text)
|
|
||||||
{
|
|
||||||
ErrWriteGeneral(text, ErrOutFil, fil);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ErrShow(char *text) {
|
|
||||||
ErrWriteGeneral(text, ErrOutFil, stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __VMS
|
|
||||||
void ErrShowVms(char **text, void (*outrtn)(), void *arg) {
|
|
||||||
char buf[256];
|
|
||||||
int l;
|
|
||||||
|
|
||||||
l=*(short *)text;
|
|
||||||
if (l>=256) l=255;
|
|
||||||
strncpy(buf, text[1], l);
|
|
||||||
buf[l]='\0';
|
|
||||||
ErrWriteGeneral(buf, outrtn, arg);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void ERR_EXIT(char *text) {
|
|
||||||
ErrShow(text); exit(1);
|
|
||||||
}
|
|
@ -1,86 +0,0 @@
|
|||||||
#ifndef _ERRHDL_H_
|
|
||||||
#define _ERRHDL_H_
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <sys/errno.h>
|
|
||||||
|
|
||||||
/* ErrHDL Error handling utilities
|
|
||||||
-------------------------------
|
|
||||||
Makes code more readable by hiding annoying error condition checks.
|
|
||||||
|
|
||||||
Macros and routines:
|
|
||||||
|
|
||||||
Spelling in uppercase indicates, that it the program flow
|
|
||||||
may be modified (jump to OnError label or program exit).
|
|
||||||
|
|
||||||
|
|
||||||
ERR_x
|
|
||||||
|
|
||||||
Usage Error condition Error message taken from
|
|
||||||
-----------------------------------------------------------------------------------------
|
|
||||||
ERR_SI(res=routine1(...)) res<0 errno
|
|
||||||
ERR_SP(ptr=routine2(...)) ptr==NULL errno
|
|
||||||
ERR_I(res=routine3(...)) res<0 stored by routine3 using errhdl mechanism
|
|
||||||
ERR_P(ptr=routine4(...)) ptr==NULL stored by routine4 using errhdl mechanism
|
|
||||||
|
|
||||||
The result assignment "res=" or "ptr=" is optional.
|
|
||||||
|
|
||||||
Description:
|
|
||||||
The routine routineX is called.
|
|
||||||
If the result indicates an error, the source text is saved and the
|
|
||||||
program continues at the OnError label.
|
|
||||||
The error message and the source code of the calling instructions is
|
|
||||||
saved for a later call to ErrShow or ErrExit.
|
|
||||||
|
|
||||||
ERR_EXIT("program_name")
|
|
||||||
|
|
||||||
Show error and exit program.
|
|
||||||
|
|
||||||
ERR_MSG("message")
|
|
||||||
|
|
||||||
Signals an error condition. If "message" is replaced by a variable,
|
|
||||||
take care that it is not modified until ErrShow is called.
|
|
||||||
|
|
||||||
ERR_COD(cod)
|
|
||||||
|
|
||||||
Signals an error condition as code from errno.h
|
|
||||||
|
|
||||||
ErrShow("program_name")
|
|
||||||
ErrWrite(fil, "program_name")
|
|
||||||
|
|
||||||
Show actual error message with traceback information to stdout
|
|
||||||
or a file fil
|
|
||||||
|
|
||||||
Global Variables (read only)
|
|
||||||
|
|
||||||
int ErrCode
|
|
||||||
|
|
||||||
actual error message code
|
|
||||||
= errno for system errors or
|
|
||||||
= -1 for custom errors signaled by ERRMSG
|
|
||||||
|
|
||||||
char *ErrMessage
|
|
||||||
|
|
||||||
actual error message
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define ERR_SI(R) { if(0>(R)) { ErrTxt(#R,1); goto OnError; }; }
|
|
||||||
#define ERR_SP(R) { if(NULL==(R)) { ErrTxt(#R,1); goto OnError; }; }
|
|
||||||
#define ERR_I(R) { if(0>(R)) { ErrTxt(#R,0); goto OnError; }; }
|
|
||||||
#define ERR_P(R) { if(NULL==(R)) { ErrTxt(#R,0); goto OnError; }; }
|
|
||||||
#define ERR_MSG(R) { ErrMsg(R); goto OnError; }
|
|
||||||
#define ERR_COD(R) { ErrCod(R); goto OnError; }
|
|
||||||
|
|
||||||
void ErrTxt(char *text, int systemError);
|
|
||||||
void ErrMsg(char *msg);
|
|
||||||
void ErrCod(int code);
|
|
||||||
void ErrShow(char *text);
|
|
||||||
void ErrWrite(FILE *fil, char *text);
|
|
||||||
void ERR_EXIT(char *text);
|
|
||||||
void ErrLog(char *text);
|
|
||||||
|
|
||||||
extern int ErrCode;
|
|
||||||
extern char *ErrMessage;
|
|
||||||
|
|
||||||
#endif /* _ERRHDL_H_ */
|
|
232
tecs/logfile.c
232
tecs/logfile.c
@ -1,232 +0,0 @@
|
|||||||
/* switch off ANSI_C_SOURCE (allows compiling all sources with cc/stand=ansi) */
|
|
||||||
#ifdef __VMS
|
|
||||||
#ifdef __HIDE_FORBIDDEN_NAMES
|
|
||||||
#undef __HIDE_FORBIDDEN_NAMES
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/timeb.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include "logfile.h"
|
|
||||||
#include "errhdl.h"
|
|
||||||
#include "str_util.h"
|
|
||||||
|
|
||||||
static FILE *fil=NULL;
|
|
||||||
static char lnam[256]="", filnam[256]="";
|
|
||||||
static char ebuf[20000]="";
|
|
||||||
static char *eptr=&ebuf[0];
|
|
||||||
static int lastStamp=0;
|
|
||||||
static int notDated=0;
|
|
||||||
static int logMask=0;
|
|
||||||
static int wrtMask=0;
|
|
||||||
|
|
||||||
int ftime (struct timeb *__timeptr); /* for some reason not defined in timeb.h with flag -std1 */
|
|
||||||
|
|
||||||
static int logfileStd;
|
|
||||||
static int dirty, writeAll;
|
|
||||||
|
|
||||||
void logfileOpen(int first) {
|
|
||||||
struct tm *tim;
|
|
||||||
struct timeb btim;
|
|
||||||
|
|
||||||
if (logfileStd) {
|
|
||||||
fil=stdout;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
assert(fil==NULL);
|
|
||||||
if (first) {
|
|
||||||
ftime(&btim);
|
|
||||||
tim=localtime(&btim.time);
|
|
||||||
if (notDated) {
|
|
||||||
if (lnam[0]=='\0') {
|
|
||||||
str_copy(filnam, "test.log");
|
|
||||||
} else {
|
|
||||||
str_copy(filnam, lnam);
|
|
||||||
str_append(filnam, ".log");
|
|
||||||
}
|
|
||||||
} 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) {
|
|
||||||
fil=fopen(filnam, "w", "SHR=UPD"); /* new version at restart */
|
|
||||||
} else {
|
|
||||||
fil=fopen(filnam, "a", "SHR=UPD");
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (first && notDated) {
|
|
||||||
fil=fopen(filnam, "w"); /* overwrite at restart */
|
|
||||||
} else {
|
|
||||||
fil=fopen(filnam, "a");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void logfileOut(int mask, const char *fmt, ...)
|
|
||||||
{ va_list ap;
|
|
||||||
|
|
||||||
assert(mask>0 && mask<32);
|
|
||||||
va_start(ap, fmt);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void logfileMask(int mask) {
|
|
||||||
logMask=logMask | mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
void logfileStamp(void) {
|
|
||||||
struct tm *tim;
|
|
||||||
struct timeb btim;
|
|
||||||
int stamp;
|
|
||||||
|
|
||||||
ftime(&btim);
|
|
||||||
tim=localtime(&btim.time);
|
|
||||||
stamp=tim->tm_hour*60+tim->tm_min;
|
|
||||||
if (stamp!=lastStamp) {
|
|
||||||
if (stamp<lastStamp) { /* time smaller than last time -> new day -> new logfile */
|
|
||||||
if (fil!=NULL) { fclose(fil); fil=NULL; }
|
|
||||||
logfileOpen(1);
|
|
||||||
}
|
|
||||||
#ifdef __VMS
|
|
||||||
else if (fil==NULL) logfileOpen(0);
|
|
||||||
#endif
|
|
||||||
lastStamp=stamp;
|
|
||||||
fprintf(fil, "--- %02d:%02d:%02d ---\n", tim->tm_hour, tim->tm_min, tim->tm_sec);
|
|
||||||
dirty=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void logfileWrite0(int mask) {
|
|
||||||
char *s, *next;
|
|
||||||
|
|
||||||
logMask=logMask | mask;
|
|
||||||
if (dirty) logfileStamp(); /* there was something written since last time */
|
|
||||||
|
|
||||||
s=ebuf;
|
|
||||||
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');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ebuf[0]='\0';
|
|
||||||
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
|
|
||||||
fflush(fil);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void logfileClose()
|
|
||||||
{
|
|
||||||
#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, Str_Buf *buf)
|
|
||||||
{ char str[256];
|
|
||||||
int rd0, sep;
|
|
||||||
|
|
||||||
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, ".");
|
|
||||||
} else {
|
|
||||||
logfileOut(mask, "%s", str);
|
|
||||||
}
|
|
||||||
sep=1;
|
|
||||||
} else {
|
|
||||||
if (sep) logfileOut(mask, "%c", buf->sep);
|
|
||||||
logfileOut(mask, "%s", str);
|
|
||||||
sep=1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buf->rdpos=rd0;
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
#ifndef _LOGFILE_H_
|
|
||||||
#define _LOGFILE_H_
|
|
||||||
|
|
||||||
#include "str_buf.h"
|
|
||||||
|
|
||||||
#define LOG_ALL 31
|
|
||||||
#define LOG_SER 8
|
|
||||||
#define LOG_NET 4
|
|
||||||
#define LOG_WARN 2
|
|
||||||
#define LOG_MAIN 1
|
|
||||||
|
|
||||||
void logfileInit(char *path, int nodate, int use_stdout, int write_all);
|
|
||||||
void logfileOut(int mask, const char *fmt, ...);
|
|
||||||
void logfileOutBuf(int mask, Str_Buf *buf);
|
|
||||||
void logfileShowErr(char *text);
|
|
||||||
void logfileMask(int mask);
|
|
||||||
void logfileWrite(int mask);
|
|
||||||
void logfileClose(void);
|
|
||||||
|
|
||||||
#endif /* _LOGFILE_H_ */
|
|
171
tecs/lsc.c
171
tecs/lsc.c
@ -1,171 +0,0 @@
|
|||||||
#include <stdlib.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include "errhdl.h"
|
|
||||||
#include "logfile.h"
|
|
||||||
#include "coc.h"
|
|
||||||
#include "lsc.h"
|
|
||||||
#include "str_util.h"
|
|
||||||
|
|
||||||
#define MC LSC_MAX_CMDS
|
|
||||||
#define MAX_PAR 16
|
|
||||||
#define MAX_ARG 9
|
|
||||||
|
|
||||||
int LscEqPar(char *par, char *res) {
|
|
||||||
char *p, *r, pbuf[SER_BUF_LEN], rbuf[SER_BUF_LEN];
|
|
||||||
int i,n,i1,i2;
|
|
||||||
float f1, f2;
|
|
||||||
|
|
||||||
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", pbuf, rbuf);
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
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') {
|
|
||||||
if (p==NULL) { /* last element: get rest of line */
|
|
||||||
sbuf.sep='\0';
|
|
||||||
}
|
|
||||||
ERR_I(CocGetVar(serverVarList, &sbuf, varname, 0));
|
|
||||||
} else {
|
|
||||||
ERR_P(str_get_str(&sbuf, NULL));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return(res);
|
|
||||||
OnError: return(NULL);
|
|
||||||
}
|
|
31
tecs/lsc.h
31
tecs/lsc.h
@ -1,31 +0,0 @@
|
|||||||
#ifndef _LSC_H_
|
|
||||||
#define _LSC_H_
|
|
||||||
|
|
||||||
#include "serutil.h"
|
|
||||||
#define LSC_MAX_CMDS 5
|
|
||||||
|
|
||||||
char *LscCmd(SerChannel *ser, const char *cmds);
|
|
||||||
/*
|
|
||||||
*/
|
|
||||||
|
|
||||||
int LscEqPar(char *par, char *res);
|
|
||||||
/*
|
|
||||||
compare if parameters are equal (numbers as numbers, spaces ignored)
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct { struct LscElem *next; char *cmnd; } LscElem;
|
|
||||||
typedef struct { struct LscElem *head, *tail; } LscList;
|
|
||||||
|
|
||||||
int LscPushCmd(LscList clist, char *cmnd);
|
|
||||||
/*
|
|
||||||
push a command on th command list. If cmnd points to a temporary buffer,
|
|
||||||
strdup() must be used.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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_ */
|
|
@ -1,176 +0,0 @@
|
|||||||
#ifndef _rs232c_def_
|
|
||||||
#define _rs232c_def_
|
|
||||||
/*------------------------------------------------ RS232C_DEF.H Ident V02F
|
|
||||||
** Definitions for the RS-232-C Server Protocol
|
|
||||||
**
|
|
||||||
** On UNIX systems, this file is located in /public/lib/include
|
|
||||||
** On VMS systems, this file is a module in mad_lib:sinq_c.tlb
|
|
||||||
*/
|
|
||||||
#define RS__PROTOCOL_ID "V01A"
|
|
||||||
#define RS__PROTOCOL_ID_V01B "V01B"
|
|
||||||
|
|
||||||
#define RS__PROTOCOL_CODE 1 /* Code corresponding to RS__PROTOCOL_ID */
|
|
||||||
#define RS__PROTOCOL_CODE_V01B 2 /* Code corresponding to RS__PROTOCOL_ID_0 */
|
|
||||||
|
|
||||||
#ifndef OffsetOf
|
|
||||||
#define OffsetOf(type, identifier) ((size_t)(&((type*) NULL)->identifier))
|
|
||||||
#endif
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
** Structure of Message from Client to Server - everything is sent in ASCII
|
|
||||||
** for LabView's benefit.
|
|
||||||
** Name #bytes Description
|
|
||||||
** ==== ====== ===========
|
|
||||||
** msg_size 4 Number of bytes following (rounded up to multiple
|
|
||||||
** of 4).
|
|
||||||
** msg_id 4 Message ident (an incrementing counter for debugging).
|
|
||||||
** c_pcol_lvl 4 Client-Protocol-Level (should be "V01A").
|
|
||||||
** serial_port 4 Serial port to which commands should be sent. This
|
|
||||||
** is a small integer).
|
|
||||||
** tmo 4 Time-out in units of 0.1 secs (<0 = "wait for ever").
|
|
||||||
** terms 1 + 3 Terminators. The first char gives the number of
|
|
||||||
** terminators (up to 3) and the following 3 chars
|
|
||||||
** are valid response terminators, e.g. "1\r\0\0".
|
|
||||||
** n_cmnds 4 Number of commands following.
|
|
||||||
** cmnds 356 The command buffer. This is a concatenated list of
|
|
||||||
** commands with the structure described below.
|
|
||||||
**
|
|
||||||
** Structure of a command item in the cmnds buffer.
|
|
||||||
**
|
|
||||||
** a) RS__PROTOCOL_ID = "V01A"
|
|
||||||
**
|
|
||||||
** Name #bytes Description
|
|
||||||
** ==== ====== ===========
|
|
||||||
** cmnd_len 2 The number of bytes following encoded as 2 ASCII
|
|
||||||
** decimal chars.
|
|
||||||
** cmnd <cmnd_len> The command to be sent on Serial Port <serial_port>.
|
|
||||||
** The string should contain any required terminator
|
|
||||||
** bytes but should not be zero-terminated (unless
|
|
||||||
** the zero-byte should be transmitted at the end
|
|
||||||
** of the command). cmnd_len should count the
|
|
||||||
** terminator byte.
|
|
||||||
**
|
|
||||||
** An example of a command item might be: "06RMT 1\r"
|
|
||||||
**
|
|
||||||
** b) RS__PROTOCOL_ID = "V01B"
|
|
||||||
**
|
|
||||||
** Name #bytes Description
|
|
||||||
** ==== ====== ===========
|
|
||||||
** cmnd_len 4 The number of bytes following encoded as 4 ASCII
|
|
||||||
** decimal chars.
|
|
||||||
** cmnd <cmnd_len> The command to be sent on Serial Port <serial_port>.
|
|
||||||
** The string should contain any required terminator
|
|
||||||
** bytes but should not be zero-terminated (unless
|
|
||||||
** the zero-byte should be transmitted at the end
|
|
||||||
** of the command). <cmnd_len> should count the
|
|
||||||
** terminator byte.
|
|
||||||
**
|
|
||||||
** An example of a command item might be: "0006RMT 1\r"
|
|
||||||
**--------------------------------------------------------------------------*/
|
|
||||||
struct RS__MsgStruct {
|
|
||||||
char msg_size[4]; /* 4 ASCII decimal chars!! */
|
|
||||||
char msg_id[4];
|
|
||||||
char c_pcol_lvl[4]; /* Client protocol level */
|
|
||||||
char serial_port[4];
|
|
||||||
char tmo[4]; /* Units are 0.1 secs */
|
|
||||||
char terms[4];
|
|
||||||
char n_cmnds[4];
|
|
||||||
char cmnds[356];
|
|
||||||
};
|
|
||||||
/*
|
|
||||||
** The "cmnds" buffer in RS__MsgStruct is a concatenated
|
|
||||||
** list of the following structures.
|
|
||||||
*/
|
|
||||||
struct RS__CmndStruct {
|
|
||||||
char cmnd_len[2];
|
|
||||||
char cmnd[1];
|
|
||||||
};
|
|
||||||
struct RS__CmndStruct_V01B {
|
|
||||||
char cmnd_len[4];
|
|
||||||
char cmnd[1];
|
|
||||||
};
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
** Structure of Reply from Server to Client - everything is sent in ASCII
|
|
||||||
** for LabView's benefit.
|
|
||||||
**
|
|
||||||
** Name #bytes Description
|
|
||||||
** ==== ====== ===========
|
|
||||||
** msg_size 4 Number of bytes following (rounded up to multiple
|
|
||||||
** of 4).
|
|
||||||
** msg_id 4 Message ident (this is a copy of the msg_id field
|
|
||||||
** in the message from Client to Server).
|
|
||||||
** s_pcol_lvl 4 Server-Protocol-Level (should be "V01A" or "V01B").
|
|
||||||
** n_rply 4 Number of replies following. If < 0, an error has
|
|
||||||
** been detected and sub_status may give additional
|
|
||||||
** information.
|
|
||||||
** rplys 496 The reply buffer. This is a concatenated list of
|
|
||||||
** replies with the structure described below.
|
|
||||||
** sub_status 12 A sub-status code. This field overlays the first 12
|
|
||||||
** bytes of rplys and may provide additional
|
|
||||||
** information in the case that n_rply < 0.
|
|
||||||
**
|
|
||||||
** Structure of a reply item in the rplys buffer.
|
|
||||||
**
|
|
||||||
** a) RS__PROTOCOL_ID = "V01A"
|
|
||||||
**
|
|
||||||
** Name #bytes Description
|
|
||||||
** ==== ====== ===========
|
|
||||||
** rply_len 2 The number of bytes following encoded as 2 ASCII
|
|
||||||
** decimal chars.
|
|
||||||
** term 1 The terminating character which was detected at the
|
|
||||||
** end of the reply. This will be one of the
|
|
||||||
** characters specified in <terms>.
|
|
||||||
** rply <rply_len-1> The zero-terminated reply. This is effectively the
|
|
||||||
** reply as received with the terminating character
|
|
||||||
** replaced by '\0'.
|
|
||||||
**
|
|
||||||
** An example of a reply item might be: "08\r12.345\0"
|
|
||||||
**
|
|
||||||
** b) RS__PROTOCOL_ID = "V01B"
|
|
||||||
**
|
|
||||||
** Name #bytes Description
|
|
||||||
** ==== ====== ===========
|
|
||||||
** rply_len 4 The number of bytes following encoded as 4 ASCII
|
|
||||||
** decimal chars.
|
|
||||||
** term 1 The terminating character which was detected at the
|
|
||||||
** end of the reply. This will be one of the
|
|
||||||
** characters specified in <terms>.
|
|
||||||
** rply <rply_len-1> The zero-terminated reply. This is effectively the
|
|
||||||
** reply as received with the terminating character
|
|
||||||
** replaced by '\0'.
|
|
||||||
**
|
|
||||||
** An example of a reply item might be: "0009\r12.3456\0"
|
|
||||||
**--------------------------------------------------------------------------*/
|
|
||||||
struct RS__RespStruct {
|
|
||||||
char msg_size[4];
|
|
||||||
char msg_id[4];
|
|
||||||
char s_pcol_lvl[4]; /* Server protocol level */
|
|
||||||
char n_rply[4]; /* Error if < 0 */
|
|
||||||
union {
|
|
||||||
char rplys[496];
|
|
||||||
char sub_status[12];
|
|
||||||
} u;
|
|
||||||
};
|
|
||||||
/*
|
|
||||||
** The "rplys" buffer in RS__RespStruct is a
|
|
||||||
** concatenated list of the following structures.
|
|
||||||
*/
|
|
||||||
struct RS__RplyStruct {
|
|
||||||
char rply_len[2]; /* 2 ASCII decimal chars!!
|
|
||||||
** The length includes the
|
|
||||||
** terminator, term, and the
|
|
||||||
** zero terminator of rply.
|
|
||||||
*/
|
|
||||||
char term; /* The terminating character */
|
|
||||||
char rply[1]; /* Zero terminated string */
|
|
||||||
};
|
|
||||||
struct RS__RplyStruct_V01B {
|
|
||||||
char rply_len[4]; /* 4 ASCII decimal chars!!
|
|
||||||
** The length includes the
|
|
||||||
** terminator, term, and the
|
|
||||||
** zero terminator of rply.
|
|
||||||
*/
|
|
||||||
char term; /* The terminating character */
|
|
||||||
char rply[1]; /* Zero terminated string */
|
|
||||||
};
|
|
||||||
/*------------------------------------------------ End of RS232C_DEF.H --*/
|
|
||||||
#endif /* _rs232c_def_ */
|
|
@ -1,97 +0,0 @@
|
|||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include "rs232c_def.h"
|
|
||||||
#include "asynsrv_def.h"
|
|
||||||
#include "sinq_prototypes.h"
|
|
||||||
#include "errhdl.h"
|
|
||||||
#include "serutil.h"
|
|
||||||
#include "logfile.h"
|
|
||||||
#include "str_util.h"
|
|
||||||
|
|
||||||
#define A_CHK(R) if (1!=(R)) { SerA_error(); ErrTxt(#R,0); goto OnError; }
|
|
||||||
|
|
||||||
void (*idleHandler)(int,int);
|
|
||||||
|
|
||||||
struct SerChan {
|
|
||||||
struct AsynSrv__info asyn_info; /* Contains skt, host, port & chan */
|
|
||||||
struct RS__MsgStruct to_host;
|
|
||||||
struct RS__RespStruct from_host;
|
|
||||||
char cmd[SER_BUF_LEN];
|
|
||||||
};
|
|
||||||
|
|
||||||
void SerA_error(void) {
|
|
||||||
char *a_txt;
|
|
||||||
int a_cod, a_my, a_vms;
|
|
||||||
|
|
||||||
AsynSrv_ErrInfo(&a_txt, &a_cod, &a_my, &a_vms);
|
|
||||||
ErrMsg("asynsrv error"); ErrTxt(a_txt,0);
|
|
||||||
}
|
|
||||||
|
|
||||||
SerChannel *SerOpen(const char *host, int msecTmo, void (*idleHdl)(int,int)) {
|
|
||||||
struct SerChan *ser;
|
|
||||||
char hbuf[64], cport[16];
|
|
||||||
char *p, *c;
|
|
||||||
int port, chan;
|
|
||||||
|
|
||||||
idleHandler=idleHdl;
|
|
||||||
ser=calloc(1, sizeof(*ser));
|
|
||||||
str_copy(hbuf, host);
|
|
||||||
p=str_split(ser->asyn_info.host, hbuf, ':');
|
|
||||||
port=4000;
|
|
||||||
chan=0;
|
|
||||||
if (p!=NULL) {
|
|
||||||
c=str_split(cport, p, '/');
|
|
||||||
if (c!=NULL) chan=atoi(c);
|
|
||||||
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));
|
|
||||||
return((SerChannel *)ser);
|
|
||||||
OnError: return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
int SerClose(SerChannel *serch) {
|
|
||||||
struct SerChan *ser;
|
|
||||||
|
|
||||||
ser=(struct SerChan *)serch;
|
|
||||||
A_CHK(AsynSrv_Close(&ser->asyn_info, 0));
|
|
||||||
return(0);
|
|
||||||
OnError: return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *SerCmdC(SerChannel *serch, const char *cmnd) {
|
|
||||||
char cmd[SER_BUF_LEN];
|
|
||||||
int l;
|
|
||||||
|
|
||||||
l=strlen(cmnd);
|
|
||||||
if (l>=SER_BUF_LEN-1) ERR_COD(ENOBUFS);
|
|
||||||
strcpy(cmd, cmnd);
|
|
||||||
return(SerCmd(serch, cmd));
|
|
||||||
OnError: return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *SerCmd(SerChannel *serch, char *cmnd) {
|
|
||||||
int l;
|
|
||||||
struct SerChan *ser;
|
|
||||||
char *result;
|
|
||||||
|
|
||||||
l=strlen(cmnd);
|
|
||||||
if (l>=SER_BUF_LEN-1) ERR_COD(ENOBUFS);
|
|
||||||
|
|
||||||
ser=(struct SerChan *)serch;
|
|
||||||
logfileOut(LOG_SER, ">%s\n", cmnd);
|
|
||||||
cmnd[l]=ser->asyn_info.eot[1];
|
|
||||||
cmnd[l+1]='\0';
|
|
||||||
A_CHK(AsynSrv_SendCmnds(&ser->asyn_info, &ser->to_host, &ser->from_host, cmnd, NULL));
|
|
||||||
result=AsynSrv_GetReply(&ser->asyn_info, &ser->from_host, NULL);
|
|
||||||
if (result==NULL) ERR_MSG("empty result");
|
|
||||||
/* if (idleHandler!=NULL) idleHandler(50,0); */
|
|
||||||
logfileOut(LOG_SER, "<%s\n", result);
|
|
||||||
return(result);
|
|
||||||
OnError: return(NULL);
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
#ifndef _SERUTIL_H_
|
|
||||||
#define _SERUTIL_H_
|
|
||||||
|
|
||||||
#define SER_BUF_LEN 320
|
|
||||||
|
|
||||||
typedef struct { int private; } SerChannel;
|
|
||||||
|
|
||||||
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_ */
|
|
238
tecs/server.c
238
tecs/server.c
@ -1,238 +0,0 @@
|
|||||||
/* needed to define ftime(), accept() and gethostbyaddr() correctly when using flag -std1 */
|
|
||||||
#ifndef _XOPEN_SOURCE_EXTENDED
|
|
||||||
#define _XOPEN_SOURCE_EXTENDED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#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 "str_util.h"
|
|
||||||
|
|
||||||
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;
|
|
||||||
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'));
|
|
||||||
cList=malloc(sizeof(*cList)); /* empty header */
|
|
||||||
|
|
||||||
/* first try to connect to an existing server */
|
|
||||||
|
|
||||||
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)));
|
|
||||||
logfileOut(LOG_MAIN, "created server on port %d\n", port);
|
|
||||||
ERR_SI(listen(mainFd, 8));
|
|
||||||
FD_ZERO(&mask);
|
|
||||||
FD_SET(mainFd, &mask);
|
|
||||||
maxfd=mainFd+1;
|
|
||||||
return(0);
|
|
||||||
OnError: return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
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); /* event on fd */
|
|
||||||
if (i==0) return(0); /* timeout */
|
|
||||||
|
|
||||||
if (FD_ISSET(mainFd, &rmask)) {
|
|
||||||
ERR_SI(newfd=accept(mainFd, (struct sockaddr *)&cadr, &cadrlen));
|
|
||||||
FD_SET(newfd, &mask);
|
|
||||||
if (newfd>=maxfd) maxfd=newfd+1;
|
|
||||||
cl=cList;
|
|
||||||
cl->fd=newfd;
|
|
||||||
cl->mode=0;
|
|
||||||
cl->cmd[0]='\0';
|
|
||||||
cl->res[0]='\0';
|
|
||||||
cList=malloc(sizeof(*cList));
|
|
||||||
cList->next=cl;
|
|
||||||
h=gethostbyaddr(&cadr.sin_addr, 4, AF_INET);
|
|
||||||
if (h==NULL) {
|
|
||||||
logfileOut(LOG_MAIN, "(%d) open from %s\n", newfd, "local");
|
|
||||||
} else {
|
|
||||||
logfileOut(LOG_MAIN, "(%d) open from %s\n", newfd, h->h_name);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
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) {
|
|
||||||
logfileOut(LOG_MAIN, "(%d) disconnected\n",cl->fd);
|
|
||||||
close(cl->fd);
|
|
||||||
FD_CLR(cl->fd, &mask);
|
|
||||||
cl0->next=cl->next;
|
|
||||||
free(cl);
|
|
||||||
cl=cl0;
|
|
||||||
} else {
|
|
||||||
|
|
||||||
str_put_start(bufo);
|
|
||||||
str_get_start(buf);
|
|
||||||
ERR_I(str_put_str(bufo, "")); /* empty error message */
|
|
||||||
setmode=0;
|
|
||||||
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_MAIN, "set read mode\n");
|
|
||||||
cl->mode=1;
|
|
||||||
} else if (0==strcmp(varname,"#rwacs")) {
|
|
||||||
logfileOut(LOG_MAIN, "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;
|
|
||||||
} else {
|
|
||||||
if (0==strcmp("$", varname)) { /* special case: response */
|
|
||||||
ERR_I(str_put_str(bufo, cl->res));
|
|
||||||
cl->res[0]='\0';
|
|
||||||
} else {
|
|
||||||
i=CocPutVar(serverVarList, bufo, varname, 0);
|
|
||||||
if (i<0) { err=ErrMessage; break; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cl0=cl; cl=cl->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (modified) return(2);
|
|
||||||
return(3);
|
|
||||||
OnError: return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
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 (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);
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
|
|
||||||
cl=cList->next;
|
|
||||||
while (cl!=NULL) {
|
|
||||||
close(cl->fd);
|
|
||||||
cl0=cl;
|
|
||||||
cl=cl->next;
|
|
||||||
free(cl0);
|
|
||||||
}
|
|
||||||
free(cList);
|
|
||||||
close(mainFd);
|
|
||||||
str_free_buf(buf); str_free_buf(bufo);
|
|
||||||
logfileClose();
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
#ifndef _SERVER_H_
|
|
||||||
#define _SERVER_H_
|
|
||||||
|
|
||||||
#include "coc.h"
|
|
||||||
|
|
||||||
struct CocClient { struct CocClient *next; int fd; int mode; char cmd[80]; char res[80]; };
|
|
||||||
|
|
||||||
int CocInitServer(int bufsize, int port);
|
|
||||||
|
|
||||||
int CocHandleRequests(int tmo_msec, int fd);
|
|
||||||
int CocHandle1Request(int tmo_msec, int fd);
|
|
||||||
/*
|
|
||||||
handle hetwork requests.
|
|
||||||
|
|
||||||
return value: <0: error
|
|
||||||
=0: timeout
|
|
||||||
=1: event on fd
|
|
||||||
=2: variable was changed
|
|
||||||
=3: other network request treated
|
|
||||||
|
|
||||||
CocHandle1Request handles only one network request
|
|
||||||
|
|
||||||
For CocHandleRequests:
|
|
||||||
|
|
||||||
if fd=0: returns when a network request has changed a variable,
|
|
||||||
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 (result is 0 or 1)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct CocClient *CocGetNextCmd(void);
|
|
||||||
/*
|
|
||||||
get next client with a pending command
|
|
||||||
*/
|
|
||||||
|
|
||||||
void CocCloseServer(void);
|
|
||||||
|
|
||||||
#endif /* _SERVER_H_ */
|
|
142
tecs/tecc.c
142
tecs/tecc.c
@ -1,142 +0,0 @@
|
|||||||
#include <string.h>
|
|
||||||
#include "errhdl.h"
|
|
||||||
#include "str_util.h"
|
|
||||||
#include "tecc.h"
|
|
||||||
|
|
||||||
static char device[80], command[80];
|
|
||||||
static int quit;
|
|
||||||
static float tempX, tempP, tempC;
|
|
||||||
|
|
||||||
pTecsClient TeccInit(char *startcmd, int port) {
|
|
||||||
CocConn *conn;
|
|
||||||
|
|
||||||
ERR_SP(conn=(CocConn *)malloc(sizeof(*conn)));
|
|
||||||
ERR_I(CocInitClient(conn, "", port, "#rwacs", 0, startcmd));
|
|
||||||
CocDefFlt(tempC, CocRD);
|
|
||||||
CocDefFlt(tempP, CocRD);
|
|
||||||
CocDefFlt(tempX, CocRD);
|
|
||||||
CocDefStr(device, CocWR);
|
|
||||||
CocDefInt(quit, CocWR);
|
|
||||||
CocDefCmd(command);
|
|
||||||
|
|
||||||
return((pTecsClient)conn);
|
|
||||||
OnError: return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
int TeccSetDev(pTecsClient conn, char *dev) {
|
|
||||||
str_copy(device, dev);
|
|
||||||
ERR_I(CocCmd(conn, "[device]"));
|
|
||||||
return(0);
|
|
||||||
OnError: return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *TeccGetDev(pTecsClient conn) {
|
|
||||||
ERR_I(CocCmd(conn, "device"));
|
|
||||||
return(device);
|
|
||||||
OnError: return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
int TeccGet3(pTecsClient conn, float *tC, float *tX, float *tP) {
|
|
||||||
ERR_I(CocCmd(conn, "tempC,tempX,tempP"));
|
|
||||||
*tC=tempC;
|
|
||||||
*tX=tempX;
|
|
||||||
*tP=tempP;
|
|
||||||
return(0);
|
|
||||||
OnError: return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int TeccGet(pTecsClient conn, float *temp) {
|
|
||||||
ERR_I(CocCmd(conn, "tempP"));
|
|
||||||
*temp=tempP;
|
|
||||||
return(0);
|
|
||||||
OnError: return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int TeccSet(pTecsClient conn, float temp) {
|
|
||||||
tempC=temp;
|
|
||||||
ERR_I(CocCmd(conn, "[tempC]"));
|
|
||||||
return(0);
|
|
||||||
OnError: return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int TeccSend(pTecsClient conn, char *cmd, char *reply, int replyLen) {
|
|
||||||
char *res;
|
|
||||||
int cnt;
|
|
||||||
|
|
||||||
str_copy(command, cmd);
|
|
||||||
ERR_I(CocCmd(conn, "[$]"));
|
|
||||||
cnt=40;
|
|
||||||
CocDelay(100);
|
|
||||||
while (cnt>0) {
|
|
||||||
ERR_I(CocCmd(conn, "$"));
|
|
||||||
if (command[0]!='\0') {
|
|
||||||
str_ncpy(reply, command, replyLen);
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
CocDelay(250);
|
|
||||||
cnt--;
|
|
||||||
}
|
|
||||||
str_ncpy(reply, "<no response>", replyLen);
|
|
||||||
return(0);
|
|
||||||
OnError: return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int TeccQuitServer(pTecsClient conn) {
|
|
||||||
quit=1;
|
|
||||||
ERR_I(CocCmd(conn, "[quit]"));
|
|
||||||
return(0);
|
|
||||||
OnError: return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TeccClose(pTecsClient conn) {
|
|
||||||
if (conn!=NULL) {
|
|
||||||
CocCloseClient(conn);
|
|
||||||
free(conn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __VMS
|
|
||||||
|
|
||||||
int TeccSetDevVms(pTecsClient conn, char **dev) {
|
|
||||||
int l;
|
|
||||||
|
|
||||||
l=*(short *)dev;
|
|
||||||
if (l>=sizeof(device)) l=sizeof(device)-1;
|
|
||||||
strncpy(device, dev[1], l);
|
|
||||||
while (l>0 && device[l-1]==' ') l--; /* trim */
|
|
||||||
device[l]='\0';
|
|
||||||
ERR_I(CocCmd(conn, "[device]"));
|
|
||||||
return(0);
|
|
||||||
OnError: return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int TeccGetDevVms(pTecsClient conn, char **dev) {
|
|
||||||
int l, ld;
|
|
||||||
|
|
||||||
ERR_I(CocCmd(conn, "device"));
|
|
||||||
ld=strlen(device);
|
|
||||||
l=*(short *)dev;
|
|
||||||
if (ld>=l) ld=l;
|
|
||||||
strncpy(dev[1], device, ld);
|
|
||||||
return(ld);
|
|
||||||
OnError: return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int TeccSendVms(pTecsClient conn, char **cmd, char **reply) {
|
|
||||||
int l, lr;
|
|
||||||
char cbuf[80], rbuf[80];
|
|
||||||
|
|
||||||
l=*(short *)cmd;
|
|
||||||
if (l>=sizeof(cbuf)) l=sizeof(cbuf)-1;
|
|
||||||
strncpy(cbuf, cmd[1], l);
|
|
||||||
while (l>0 && cbuf[l-1]==' ') l--; /* trim */
|
|
||||||
cbuf[l]='\0';
|
|
||||||
ERR_I(TeccSend(conn, cbuf, rbuf, sizeof(rbuf)));
|
|
||||||
lr=strlen(rbuf);
|
|
||||||
l=*(short *)reply;
|
|
||||||
if (lr>=l) lr=l;
|
|
||||||
strncpy(reply[1], rbuf, lr);
|
|
||||||
return(lr);
|
|
||||||
OnError: return(-1);
|
|
||||||
}
|
|
||||||
#endif
|
|
47
tecs/tecc.h
47
tecs/tecc.h
@ -1,47 +0,0 @@
|
|||||||
#ifndef _TECC_H_
|
|
||||||
#define _TECC_H_
|
|
||||||
|
|
||||||
#include "client.h"
|
|
||||||
/*
|
|
||||||
tecc.h: tecs client interface routines
|
|
||||||
|
|
||||||
M. Zolliker March 2000
|
|
||||||
------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
typedef CocConn *pTecsClient;
|
|
||||||
|
|
||||||
|
|
||||||
pTecsClient TeccInit(char *server, int port);
|
|
||||||
/* init tecs client (connect to server)
|
|
||||||
------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
int TeccSetDev(pTecsClient conn, char *dev);
|
|
||||||
/* set device type
|
|
||||||
------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
char *TeccGetDev(pTecsClient conn);
|
|
||||||
/* get device type
|
|
||||||
------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
int TeccGet(pTecsClient conn, float *temp);
|
|
||||||
/* set temperature
|
|
||||||
------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
int TeccSet(pTecsClient conn, float temp);
|
|
||||||
/* get temperature
|
|
||||||
------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
int TeccSend(pTecsClient conn, char *cmd, char *reply, int replyLen);
|
|
||||||
/* send a command transparently to the controller
|
|
||||||
replyLen is the maximal length of reply
|
|
||||||
------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
void TeccClose(pTecsClient conn);
|
|
||||||
/* close connection and free ressources
|
|
||||||
------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
int TeccKillServer(pTecsClient conn);
|
|
||||||
/* kill the server process
|
|
||||||
------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#endif /* _TECC_H_ */
|
|
Reference in New Issue
Block a user