renamed most source files
This commit is contained in:
@ -3,8 +3,9 @@
|
||||
#
|
||||
# Markus Zolliker, March 2000
|
||||
#--------------------------------------------------------------------------
|
||||
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
|
||||
OBJ= tecs_cli.o coc_client.o coc_util.o err_handling.o \
|
||||
str_util.o str_buf.o coc_server.o tecs_lsc.o tecs_serial.o \
|
||||
coc_logfile.o tecs_dlog.o
|
||||
|
||||
#------------ for DigitalUnix
|
||||
CC=cc
|
||||
@ -19,8 +20,6 @@ tecs: $(OBJ)
|
||||
ranlib libtecsl.a
|
||||
- rm TecsServer
|
||||
cc -o TecsServer -g tecs.c -lm -L. -ltecsl -L../hardsup -lhlib
|
||||
- rm tcli
|
||||
cc -o tcli -g tcli.c -lm -L. -ltecsl
|
||||
|
||||
clean:
|
||||
rm *.o
|
||||
|
@ -56,7 +56,7 @@ int CocRecv(int fd, Str_Buf *buf)
|
||||
{
|
||||
struct timeval tmo={0,1};
|
||||
fd_set mask;
|
||||
int i, ret;
|
||||
int i;
|
||||
|
||||
tmo.tv_sec=5; /* timeout 5 sec. */
|
||||
|
||||
@ -68,7 +68,7 @@ int CocRecv(int fd, Str_Buf *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);
|
||||
return(buf->wrpos);
|
||||
OnError: return(-1);
|
||||
}
|
||||
|
||||
|
188
tecs/coc_client.c
Normal file
188
tecs/coc_client.c
Normal file
@ -0,0 +1,188 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include "err_handling.h"
|
||||
#include "coc_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;
|
||||
ErrWrite("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);
|
||||
}
|
21
tecs/coc_client.h
Normal file
21
tecs/coc_client.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef _COC_CLIENT_H_
|
||||
#define _COC_CLIENT_H_
|
||||
|
||||
#include "coc_util.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 /* _COC_CLIENT_H_ */
|
239
tecs/coc_logfile.c
Normal file
239
tecs/coc_logfile.c
Normal file
@ -0,0 +1,239 @@
|
||||
/* switch off ANSI_C_SOURCE for VMS-extended fopen, even when compiling with /ANSI */
|
||||
#ifdef __VMS
|
||||
#ifdef __HIDE_FORBIDDEN_NAMES
|
||||
#undef __HIDE_FORBIDDEN_NAMES
|
||||
#include <stdio.h>
|
||||
#define __HIDE_FORBIDDEN_NAMES
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
#include "coc_logfile.h"
|
||||
#include "err_handling.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(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;
|
||||
}
|
20
tecs/coc_logfile.h
Normal file
20
tecs/coc_logfile.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef _COC_LOGFILE_H_
|
||||
#define _COC_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 /* _COC_LOGFILE_H_ */
|
242
tecs/coc_server.c
Normal file
242
tecs/coc_server.c
Normal file
@ -0,0 +1,242 @@
|
||||
/* needed to define accept() and gethostbyaddr() correctly when using flag -std1
|
||||
*/
|
||||
#ifdef __unix__
|
||||
#ifndef _XOPEN_SOURCE_EXTENDED
|
||||
#define _XOPEN_SOURCE_EXTENDED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "err_handling.h"
|
||||
#include "coc_logfile.h"
|
||||
#include "coc_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();
|
||||
}
|
40
tecs/coc_server.h
Normal file
40
tecs/coc_server.h
Normal file
@ -0,0 +1,40 @@
|
||||
#ifndef _SERVER_H_
|
||||
#define _SERVER_H_
|
||||
|
||||
#include "coc_util.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_ */
|
249
tecs/coc_util.c
Normal file
249
tecs/coc_util.c
Normal file
@ -0,0 +1,249 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#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 "err_handling.h"
|
||||
#include "str_util.h"
|
||||
#include "coc_util.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_util.h
Normal file
47
tecs/coc_util.h
Normal file
@ -0,0 +1,47 @@
|
||||
#ifndef _COC_UTIL_H_
|
||||
#define _COC_UTIL_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_UTIL_H_ */
|
36
tecs/dlog.c
36
tecs/dlog.c
@ -9,6 +9,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
@ -21,6 +22,8 @@
|
||||
|
||||
#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;
|
||||
|
||||
@ -50,23 +53,26 @@ int DlogRead(DlogSet *dset, int idx, void *data) {
|
||||
}
|
||||
|
||||
int DlogOpen(DlogSet *dset, char *name, int write) {
|
||||
int i, p, np, fd;
|
||||
int i, p, np, fd, flags;
|
||||
time_t tim;
|
||||
struct tm *timp;
|
||||
|
||||
fd=0;
|
||||
str_copy(dset->name, name);
|
||||
if (write) {
|
||||
#ifdef __VMS
|
||||
ERR_SI(fd=open(name, O_RDWR | O_SYNC, 0, "SHR=UPD"));
|
||||
#else
|
||||
ERR_SI(fd=open(name, O_RDWR | O_SYNC, 0));
|
||||
#endif
|
||||
flags=O_RDWR | O_SYNC;
|
||||
} else {
|
||||
#ifdef __VMS
|
||||
ERR_SI(fd=open(name, O_RDONLY | O_SYNC, 0, "SHR=UPD"));
|
||||
#else
|
||||
ERR_SI(fd=open(name, O_RDONLY | O_SYNC, 0));
|
||||
#endif
|
||||
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;
|
||||
@ -162,7 +168,7 @@ int DlogGet(DlogSet *dset, int iset, int nmax, double *starttime, float x[], flo
|
||||
}
|
||||
i0=i1;
|
||||
|
||||
*starttime = dset->start + i1 * dset->period;
|
||||
*starttime = dset->start + i1 * dset->period + gmtoff;
|
||||
n=0;
|
||||
undef=2;
|
||||
while (i0<=i) {
|
||||
@ -203,7 +209,7 @@ int DlogGetMany(DlogSet *dset, int nset, int nmax, double *starttime, float x[],
|
||||
return(-1);
|
||||
}
|
||||
|
||||
int Dlog_Get_(char *name, int *nset, int *nmax, double *starttime, float x[], float y[], int index[], int namlen) {
|
||||
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;
|
||||
@ -214,13 +220,13 @@ int Dlog_Get_(char *name, int *nset, int *nmax, double *starttime, float x[], fl
|
||||
DlogClose(&dset);
|
||||
return(ntot);
|
||||
OnError:
|
||||
ErrShow("error in Dlog_Get");
|
||||
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));
|
||||
return(dlog_get_(name[1], nset, nmax, starttime, x, y, index, *(short *)name));
|
||||
}
|
||||
|
||||
int DlogUpd(DlogSet *dset) {
|
||||
|
95
tecs/err_handling.c
Normal file
95
tecs/err_handling.c
Normal file
@ -0,0 +1,95 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "err_handling.h"
|
||||
|
||||
#define SLEN 64
|
||||
#define MLEN 64
|
||||
|
||||
static char *txt[SLEN];
|
||||
static int sp=0;
|
||||
|
||||
int ErrCode;
|
||||
char *ErrMessage=NULL;
|
||||
void (*outrtn)()=NULL;
|
||||
void *outarg;
|
||||
|
||||
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 ErrOutFil(void *arg, char *text) {
|
||||
fprintf((FILE *)arg, "%s\n", text);
|
||||
}
|
||||
|
||||
void ErrWrite(char *text)
|
||||
{
|
||||
int i, l;
|
||||
char buf[256];
|
||||
|
||||
if (outrtn==NULL) {
|
||||
outrtn=ErrOutFil;
|
||||
outarg=stdout;
|
||||
}
|
||||
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(outarg, buf);
|
||||
l=strlen(txt[i]);
|
||||
assert(l<256);
|
||||
strcpy(buf, txt[i]);
|
||||
}
|
||||
}
|
||||
outrtn(outarg, buf);
|
||||
outrtn(outarg, "");
|
||||
}
|
||||
|
||||
void ErrSetOutRtn(void (*rtn)(), void *arg) {
|
||||
outrtn=rtn;
|
||||
outarg=arg;
|
||||
}
|
||||
|
||||
#ifdef __VMS
|
||||
|
||||
typedef struct { short size, dummy; char *text; } Desc;
|
||||
|
||||
void ErrShowVms(Desc *desc, void (*outrtn)(), void *arg) {
|
||||
char buf[256];
|
||||
int l;
|
||||
|
||||
l=desc->size;
|
||||
if (l>=256) l=255;
|
||||
strncpy(buf, desc->text, l);
|
||||
buf[l]='\0';
|
||||
ErrWrite(buf);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void ERR_EXIT(char *text) {
|
||||
ErrWrite(text); exit(1);
|
||||
}
|
83
tecs/err_handling.h
Normal file
83
tecs/err_handling.h
Normal file
@ -0,0 +1,83 @@
|
||||
#ifndef _ERR_HANDLING_H_
|
||||
#define _ERR_HANDLING_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 ErrWrite(char *text);
|
||||
void ERR_EXIT(char *text);
|
||||
void ErrLog(char *text);
|
||||
|
||||
extern int ErrCode;
|
||||
extern char *ErrMessage;
|
||||
|
||||
#endif /* _ERR_HANDLING_H_ */
|
92
tecs/lsc.c
92
tecs/lsc.c
@ -150,21 +150,18 @@ char *LscCmd(SerChannel *ser, const char *cmds) {
|
||||
}
|
||||
}
|
||||
if (retreq!=NULL) { /* query */
|
||||
if (retreq[1]=='>') { /* >> get whole response */
|
||||
str_link_buf(&sbuf, result, 0, ';');
|
||||
str_split(varname, retreq+2, ';');
|
||||
ERR_I(CocGetVar(serverVarList, &sbuf, varname, 0));
|
||||
} else {
|
||||
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));
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -172,70 +169,3 @@ char *LscCmd(SerChannel *ser, const char *cmds) {
|
||||
return(res);
|
||||
OnError: return(NULL);
|
||||
}
|
||||
|
||||
int LscCmdChk(SerChannel *ser, char *cmds) {
|
||||
char *b, *o, *cn, *c, *d, *r, *res;
|
||||
char *clist[MC], *plist[MC], *rlist[MC], *olist[MC];
|
||||
char obuf[SER_BUF_LEN], r1[SER_BUF_LEN];
|
||||
int i,n,m,j,cnt,l;
|
||||
|
||||
if (NULL!=strchr(cmds, '?')) ERR_COD(EINVAL);
|
||||
cn=cmds;
|
||||
o=&obuf[0];
|
||||
m=MC;
|
||||
do {
|
||||
n=m;
|
||||
cn=str_splitx(cn, ';', clist, &n);
|
||||
for (i=0; i<n; i++) {
|
||||
c=clist[i];
|
||||
b=strchr(c, ' ');
|
||||
d=strchr(c, ':');
|
||||
if (d==NULL) ERR_COD(EINVAL);
|
||||
if (b==NULL || b>d) {
|
||||
*d=' '; b=d;
|
||||
} else {
|
||||
*d=',';
|
||||
}
|
||||
plist[i]=d+1;
|
||||
l=strlen(c);
|
||||
if ((o-&obuf[0])+l+(d-c)+2>SER_BUF_LEN) ERR_COD(ENOBUFS);
|
||||
olist[i]=o;
|
||||
strcpy(o, c); o+=l;
|
||||
*o=';'; o++;
|
||||
strncpy(o, c, d-c);
|
||||
o[b-c]='?'; o+=d-c;
|
||||
if (b==d) o++;
|
||||
*o=';'; o++;
|
||||
};
|
||||
o--; *o='\0';
|
||||
cnt=0;
|
||||
do {
|
||||
cnt++;
|
||||
if (cnt>3) ERR_MSG("can not set parameter");
|
||||
ERR_P(res=SerCmd(ser, obuf));
|
||||
if (cnt>0) {
|
||||
if (0==strcmp(r1, res)) break; /* got two times the same result */
|
||||
}
|
||||
strcpy(r1, res);
|
||||
j=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])) {
|
||||
j=0; break;
|
||||
logfileMask(LOG_SER);
|
||||
}
|
||||
}
|
||||
} while (j==0);
|
||||
} while (cn!=NULL);
|
||||
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));
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <stdlib.h>
|
||||
#include "errhdl.h"
|
||||
#include "err_handling.h"
|
||||
#include "str_util.h"
|
||||
#include "str_buf.h"
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
@ -5,7 +7,7 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "errhdl.h"
|
||||
#include "err_handling.h"
|
||||
#include "str_util.h"
|
||||
|
||||
char *str_splitx(char *str, char sep, char *list[], int *n) {
|
||||
|
@ -74,7 +74,7 @@ void str_nupcase(char *dst, const char *src, int dstlen);
|
||||
*/
|
||||
|
||||
#ifdef __VMS_VER
|
||||
#if _VMS_VER<70000000
|
||||
#if __VMS_VER<70000000
|
||||
|
||||
int strcasecmp(const char *str1, const char *str2);
|
||||
/*
|
||||
|
30
tecs/tecs.c
30
tecs/tecs.c
@ -1,14 +1,16 @@
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "errhdl.h"
|
||||
#include "server.h"
|
||||
#include "logfile.h"
|
||||
#include "err_handling.h"
|
||||
#include "coc_server.h"
|
||||
#include "coc_logfile.h"
|
||||
#include "str_util.h"
|
||||
#include "lsc.h"
|
||||
#include "dlog.h"
|
||||
#include "tecs_lsc.h"
|
||||
#include "tecs_dlog.h"
|
||||
|
||||
#define TABLE_FILE "lsc.tab"
|
||||
#define NO_CODE 999
|
||||
@ -146,7 +148,7 @@ int instCurve(char *nam, char *channel) {
|
||||
if (num>20) ERR_MSG("illegal standard curve number");
|
||||
|
||||
retstat=-1; /* an error could be fixed */
|
||||
ERR_P(LscCmd(ser, "CRVHDR?[num]>>head"));
|
||||
ERR_P(LscCmd(ser, "CRVHDR?[num]>head"));
|
||||
|
||||
} else {
|
||||
|
||||
@ -189,7 +191,7 @@ int instCurve(char *nam, char *channel) {
|
||||
if (num<21 || num>60) ERR_MSG("illegal curve number");
|
||||
|
||||
retstat=-1; /* an error could be fixed */
|
||||
ERR_P(LscCmd(ser, "CRVHDR?[num]>>head"));
|
||||
ERR_P(LscCmd(ser, "CRVHDR?[num]>head"));
|
||||
|
||||
e=strchr(entry, '\n');
|
||||
if (e!=NULL) { *e='\0'; e++; }
|
||||
@ -216,7 +218,7 @@ int instCurve(char *nam, char *channel) {
|
||||
|
||||
n=3;
|
||||
do {
|
||||
ERR_P(LscCmd(ser, "CRVDEL [num];CRVHDR?[num]>buf1"));
|
||||
ERR_P(LscCmd(ser, "CRVDEL [num];CRVHDR?[num]>buf1,"));
|
||||
buf1[4]='\0';
|
||||
i=strcmp(buf1, "User");
|
||||
n--;
|
||||
@ -359,7 +361,7 @@ int loadCache() {
|
||||
bufi[2]=buf3;
|
||||
bufi[3]=buf4;
|
||||
for (i=60; i>21; i-=4) {
|
||||
sprintf(buf, "CRVHDR?%d>>buf1;CRVHDR?%d>>buf2;CRVHDR?%d>>buf3;CRVHDR?%d>>buf4", i, i-1, i-2, i-3);
|
||||
sprintf(buf, "CRVHDR?%d>buf1;CRVHDR?%d>buf2;CRVHDR?%d>buf3;CRVHDR?%d>buf4", i, i-1, i-2, i-3);
|
||||
ERR_P(LscCmd(ser, buf));
|
||||
k=0;
|
||||
for (j=i; j>i-4; j--) {
|
||||
@ -422,7 +424,7 @@ int SetTemp(int switchOn) {
|
||||
str_copy(chan, ch);
|
||||
tempH=tempC+tShift;
|
||||
if (switchOn) {
|
||||
ERR_P(LscCmd(ser, "CSET 1:[chan],1;RANGE:5;SETP 1:[tempH]"));
|
||||
ERR_P(LscCmd(ser, "CSET 1:[chan],1,1,0;RANGE:[iRange];SETP 1:[tempH]"));
|
||||
} else {
|
||||
ERR_P(LscCmd(ser, "CSET 1:[chan],1;SETP 1:[tempH]"));
|
||||
}
|
||||
@ -445,7 +447,7 @@ int ReadTemp() {
|
||||
|
||||
if (noResp) { /* check serial number */
|
||||
k=serialNo;
|
||||
ERR_P(LscCmd(ser, "*IDN?>buf1,buf2,serialNo"));
|
||||
ERR_P(LscCmd(ser, "*IDN?>buf1,buf2,serialNo,"));
|
||||
if (0!=strcmp(buf1, "LSCI") || 0!=strcmp(buf2, "MODEL340") || serialNo==0) return(0);
|
||||
if (k!=serialNo) {
|
||||
if (cryo.manual || cryo.code!=0) cryo.dirty=1;
|
||||
@ -615,7 +617,11 @@ int Settings() {
|
||||
}
|
||||
}
|
||||
power=pw;
|
||||
ERR_P(LscCmd(ser, "CLIMIT 1:[tLimit],0,0,[iAmp],[iRange];CSET 1:[cryo.ch1],1,1,0")); /* some times .ch2? */
|
||||
logfileOut(LOG_MAIN, "power %f\n", power, iAmp, iRange);
|
||||
ERR_P(LscCmd(ser, "CLIMIT 1:[tLimit],0,0,[iAmp],[iRange]"));
|
||||
tempC=0.001; tShift=0;
|
||||
ERR_I(SetTemp(1));
|
||||
tempC=0;
|
||||
}
|
||||
if (samp.nSens>=cryo.nSens) {
|
||||
maxfld=2*samp.nSens;
|
||||
|
143
tecs/tecs_cli.c
Normal file
143
tecs/tecs_cli.c
Normal file
@ -0,0 +1,143 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "err_handling.h"
|
||||
#include "str_util.h"
|
||||
#include "tecs_cli.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/tecs_cli.h
Normal file
47
tecs/tecs_cli.h
Normal file
@ -0,0 +1,47 @@
|
||||
#ifndef _TECS_CLI_H_
|
||||
#define _TECS_CLI_H_
|
||||
|
||||
#include "coc_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 /* _TECS_CLI_H_ */
|
244
tecs/tecs_dlog.c
Normal file
244
tecs/tecs_dlog.c
Normal file
@ -0,0 +1,244 @@
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include "err_handling.h"
|
||||
#include "str_util.h"
|
||||
#include "tecs_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:
|
||||
ErrWrite("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/tecs_dlog.h
Normal file
54
tecs/tecs_dlog.h
Normal file
@ -0,0 +1,54 @@
|
||||
#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_ */
|
179
tecs/tecs_lsc.c
Normal file
179
tecs/tecs_lsc.c
Normal file
@ -0,0 +1,179 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "err_handling.h"
|
||||
#include "coc_logfile.h"
|
||||
#include "coc_util.h"
|
||||
#include "tecs_lsc.h"
|
||||
#include "str_util.h"
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
#define nLIST 30
|
||||
|
||||
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[nLIST];
|
||||
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++; assert(nres<=nLIST);
|
||||
}
|
||||
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++; assert(nres<=nLIST); /* pointer to parameters */
|
||||
list[nres]=cmd_ptr; nres++; assert(nres<=nLIST); /* 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++; assert(nres<=nLIST);
|
||||
} 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)) {
|
||||
if (0!=strcmp(result, qu)) {
|
||||
ERR_MSG("result does not match");
|
||||
} else {
|
||||
ERR_MSG("result does not match command");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
52
tecs/tecs_lsc.h
Normal file
52
tecs/tecs_lsc.h
Normal file
@ -0,0 +1,52 @@
|
||||
#ifndef _TECS_LSC_H_
|
||||
#define _TECS_LSC_H_
|
||||
|
||||
#include "tecs_serial.h"
|
||||
|
||||
char *LscCmd(SerChannel *ser, const char *cmds);
|
||||
/*
|
||||
Send commands to LSC-340.
|
||||
There may be several commands separated by semicolon.
|
||||
A special syntax is used:
|
||||
- Commands containing a colon are commands with query,
|
||||
i.e. the sent parameters are checked. The sent parameters
|
||||
are those after the query, the command before the colon
|
||||
is used as query, after inserting a question mark.
|
||||
- Variable names in square brackets are substitute by their value
|
||||
- Return values may be assigned to variables, separated by
|
||||
a right angle bracket. There may be several variables
|
||||
separated by comma, corresponding to the returned parameters,
|
||||
beeing separated by commas also. If the variable is not terminated
|
||||
by a comma, the whole remaining result is assigned, even if it
|
||||
contains commas. Return values may only be used when a command
|
||||
with wuery was sent, or when the command was a query (containing
|
||||
a question mark).
|
||||
|
||||
Example:
|
||||
|
||||
LscCmd(ser, "RANGE:5>range;SETP 1:[tempH];CRVHDR?[num]>name,head;MODE 2");
|
||||
|
||||
assume that tempH=295 and num=25 the command sent to LSC is:
|
||||
|
||||
RANGE 5;RANGE?;SETP 1,295;SETP?1;CRVHDR?25;MODE 2
|
||||
|
||||
and assume LSC sens back:
|
||||
|
||||
3;295.000E+00;CTI5 ,R10410 ,3,+330.000E+0,2
|
||||
|
||||
then the following variables will be assigned:
|
||||
|
||||
range=3
|
||||
name="CTI5"
|
||||
head="R10410 ,3,+330.000E+0,2"
|
||||
|
||||
All used variables have to be declared with CocDef... (see coc_util.h)
|
||||
*/
|
||||
|
||||
int LscEqPar(char *par, char *res);
|
||||
/*
|
||||
compare if parameters are equal (numbers as numbers, spaces ignored)
|
||||
if any parameter in par is omitted, it is not compared
|
||||
*/
|
||||
|
||||
#endif /* _TECS_LSC_H_ */
|
97
tecs/tecs_serial.c
Normal file
97
tecs/tecs_serial.c
Normal file
@ -0,0 +1,97 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include "rs232c_def.h"
|
||||
#include "asynsrv_def.h"
|
||||
#include "sinq_prototypes.h"
|
||||
#include "err_handling.h"
|
||||
#include "tecs_serial.h"
|
||||
#include "coc_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);
|
||||
}
|
13
tecs/tecs_serial.h
Normal file
13
tecs/tecs_serial.h
Normal file
@ -0,0 +1,13 @@
|
||||
#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_ */
|
Reference in New Issue
Block a user