*** empty log message ***

This commit is contained in:
cvs
2000-03-08 13:41:57 +00:00
parent d50d83f2e7
commit 749772c6ae
13 changed files with 1197 additions and 0 deletions

32
tecs/Makefile Normal file
View File

@ -0,0 +1,32 @@
#---------------------------------------------------------------------------
# Makefile for the TECS Client library
#
# Markus Zolliker, March 2000
#--------------------------------------------------------------------------
OBJ= tecc.o client.o coc.o buf.o errhdl.o util.o
#---------- for Redhat linux
#cc= GCC
#cflags= -i/USR/LOCAL/INCLUDE -i. -i../ -dlinux -G -C
#------------ for DigitalUnix
CC=cc
CFLAGS= -I/data/koenneck/include -I. -I../ -std1 -g -c
#------------ for DigitalUnix with Fortify
#CFLAGS= -I/data/koenneck/include -DFORTIFY -I. -I../ -std1 -g -c
#------------ for CYGNUS toolchain on Win32
#CC=gcc
#CFLAGS= -I. -I../ -DCYGNUS -g -c
.c.o:
$(CC) $(CFLAGS) $*.c
tecsl: $(OBJ)
- rm libtecsl.a
ar cr libtecsl.a $(OBJ)
ranlib libtecsl.a
clean:
rm *.o
rm *.a

162
tecs/buf.c Normal file
View File

@ -0,0 +1,162 @@
#include <math.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include "buf.h"
#define TWO28 268435456.0
#define MAXINT 2147483647
/* static char *null="\0"; */
int buf_get_int(buf_type *buf)
{ char *b;
int *res;
b=buf->buf;
if (b==NULL) return(0);
if (b[0]!=1 || buf->size<5) {buf->buf=NULL; return(0); }
b++;
res=(int *)b;
b+=4;
buf->size-=5;
buf->buf=b;
return(*res);
}
char *buf_get_str(buf_type *buf)
{ char *b;
int l;
b=buf->buf;
if (b==NULL) return("");
if (b[0]==1 || b[0]==2) return("");
l=strlen(b);
if (buf->size<=l) {buf->buf=NULL; return(""); }
buf->buf+=l+1;
buf->size-=l+1;
return(b);
}
float buf_get_float(buf_type *buf)
{ char *b;
float res;
int *mant, iexp;
b=buf->buf;
if (b==NULL) return(0.0);
if (b[0]!=2 || buf->size<6) { buf->buf=NULL; return(0.0); }
iexp=b[1];
b+=2;
mant=(int *)b;
b+=4;
buf->size-=6;
res=(float)ldexp(*mant/TWO28, iexp);
buf->buf=b;
return res;
}
int buf_size(buf_type *buf)
{
if (buf->buf==NULL) return(-1);
return (buf->size);
}
void buf_put_int(buf_type *buf, int val)
{ char *b;
b=buf->buf;
if (b==NULL) return;
b[0]=1;
b++;
if (buf->size<=4) {buf->buf=NULL; return; }
*(int *)b=val;
b+=4;
buf->size-=5;
buf->buf=b;
return;
}
void buf_put_str(buf_type *buf, char *str)
{ char *b;
int l;
if (str[0]<=2 && str[0]!='\0') { buf->buf=NULL; return; };
b=buf->buf;
if (b==NULL) return;
l=strlen(str);
if (buf->size<=l) { buf->buf=NULL; return; }
strcpy(b, str);
buf->buf+=l+1;
buf->size-=l+1;
}
int buf_nint(float val)
{ int res;
if (val<0) {
if (val<-MAXINT) {
return(-MAXINT);
} else {
return(val-0.5);
}
} else {
if (val>MAXINT) {
return(MAXINT);
} else {
return(val+0.5);
}
}
}
void buf_put_float(buf_type *buf, float val)
{ char *b;
double d;
int iexp;
int mant;
b=buf->buf;
if (b==NULL) return;
if (buf->size<=4) {buf->buf=NULL; return; }
d=frexp((double)val, &iexp);
mant=buf_nint(d*TWO28);
if (iexp>127) iexp=127;
if (iexp<-128) iexp=-128;
b[0]=2;
b[1]=iexp;
b+=2;
*(int *)b=mant;
b+=4;
buf->size-=6;
buf->buf=b;
}
void buf_put_end(buf_type *buf)
{ buf->buf=buf->start;
buf->usize=buf->isize-buf->size;
buf->size=buf->usize;
}
void buf_put_start(buf_type *buf)
{ buf->buf=buf->start;
buf->size=buf->isize;
}
void buf_reset(buf_type *buf)
{ buf->buf=buf->start;
buf->size=buf->usize;
}
buf_type *buf_create(size_t size)
{ buf_type *buf;
buf=malloc(sizeof(*buf));
buf->start=malloc(size);
buf->isize=size;
return(buf);
}
void buf_free(buf_type *buf)
{ free(buf->buf);
free(buf);
}

20
tecs/buf.h Normal file
View File

@ -0,0 +1,20 @@
typedef struct { char *buf; char *start; int size; int usize; int isize, dummy; } buf_type;
/* input */
void buf_reset(buf_type *buf);
int buf_get_int(buf_type *buf);
char *buf_get_str(buf_type *buf);
float buf_get_float(buf_type *buf);
int buf_size(buf_type *buf);
/* output */
void buf_put_start(buf_type *buf);
void buf_put_int(buf_type *buf, int val);
void buf_put_str(buf_type *buf, char *str);
void buf_put_float(buf_type *buf, float val);
void buf_put_end(buf_type *buf);
/* common */
buf_type *buf_create(size_t size);
void buf_free(buf_type *buf);
void buf_log(buf_type *buf);

180
tecs/client.c Normal file
View File

@ -0,0 +1,180 @@
#include <assert.h>
#include "client.h"
#include "util.h"
/*-------------------------------------------------------------------------*/
int CocOpen(CocConn *conn)
{
int i, cnt, try, port, tryConn, tmo;
struct sockaddr_in sadr;
char *p, *q;
try=2;
tryConn=1;
tmo=0;
while (try>0) {
try--;
while (tryConn>0) {
port=CocPORT;
cnt=CocPORTS;
tryConn--;
while (cnt>0) {
ERR_SI(conn->fd=socket(AF_INET, SOCK_STREAM, 0));
ERR_I(CocCreateSockAdr(&sadr, conn->host, port));
i=connect(conn->fd, (struct sockaddr *)&sadr, sizeof(sadr));
if (i>=0) return(0);
if (errno!=ECONNREFUSED) { ERR_COD(errno); }
port++; cnt--;
}
util_delay(tmo); tmo+=100;
}
if (conn->startcmd[0]=='\0' || try<=0) { ERR_COD(ECONNREFUSED); }
p=conn->startcmd;
q=strchr(p,' ');
while (q!=NULL) {
p=q+1;
q=strchr(p,' ');
};
printf("start server %s\n", p);
ERR_I(system(conn->startcmd));
util_delay(100); tmo=200;
tryConn=5;
}
ERR_COD(ECONNREFUSED);
OnError: return(-1);
}
/*-------------------------------------------------------------------------*/
void CocInitClient(CocConn *conn, char *host, char *magic, int bufsize, char *startcmd)
{ void *e;
if (bufsize==0) bufsize=1024;
conn->cmdbuf=buf_create(bufsize);
conn->resbuf=buf_create(bufsize);
str_copy(conn->host, host);
str_copy(conn->magic, magic);
str_copy(conn->startcmd, startcmd);
conn->fd=-1;
conn->varList=NULL;
CocVarList(&conn->varList);
}
/*-------------------------------------------------------------------------*/
int CocSendMagic(CocConn *conn, char *magic) {
char *err;
if (magic[0]!='#') ERR_MSG("magic must start with '#'");
buf_put_start(conn->resbuf); /* use return buffer for command in order to preserve command buffer */
buf_put_str(conn->resbuf, magic);
buf_put_end(conn->resbuf);
if (conn->resbuf->buf==NULL) ERR_MSG("buffer full");
ERR_SI(send(conn->fd, conn->resbuf->buf, conn->resbuf->size, 0));
ERR_I(CocRecv(conn->fd, conn->resbuf));
err=buf_get_str(conn->resbuf);
if (*err!='\0') { ErrMsg(err); ErrTxt(": (response from server)",0); goto OnError; }
if (buf_size(conn->resbuf)!=0) ERR_MSG("syntax error");
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->size, 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;
buf_put_start(conn->cmdbuf);
s=rwList;
setmode=0;
do {
t=strchr(s, ',');
if (t==NULL) t=s+strlen(s);
if (*s=='[') {
if (!setmode) buf_put_str(conn->cmdbuf, "[");
s++;
setmode=1;
}
i=t-s;
assert(i<32);
str_ncpy(nam, s, i+1);
if (setmode) {
if (nam[i-1]==']') { nam[i-1]='\0'; setmode=0; }
buf_put_str(conn->cmdbuf, nam);
ERR_I(CocPutVar(conn->varList, conn->cmdbuf, nam));
if (!setmode) buf_put_str(conn->cmdbuf, "]");
} else {
var=CocFindVar(conn->varList, nam);
if (var==NULL) ERR_MSG("variable not found");
buf_put_str(conn->cmdbuf, nam);
}
s=t+1;
} while (*t!='\0');
buf_put_end(conn->cmdbuf);
if (conn->cmdbuf->buf==NULL) ERR_MSG("out buffer full");
cnt=3;
while (1) {
cnt--;
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=buf_get_str(conn->resbuf);
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) {
str_ncpy(nam, s, i+1);
if (nam[i-1]==']') { nam[i-1]='\0'; setmode=0; }
ERR_I(CocGetVar(conn->varList, conn->resbuf, nam));
}
s=t+1;
} while (*t!='\0');
if (buf_size(conn->resbuf)!=0) ERR_MSG("syntax error");
return(0);
OnError: return(-1);
}
void CocCloseClient(CocConn *conn) {
close(conn->fd);
buf_free(conn->cmdbuf);
buf_free(conn->resbuf);
CocFreeVarList(&conn->varList);
}

16
tecs/client.h Normal file
View File

@ -0,0 +1,16 @@
#include "coc.h"
typedef struct {
int fd, dummy;
CocVar *varList;
buf_type *cmdbuf; /* for sending command */
buf_type *resbuf; /* for response */
char host[64];
char magic[32];
char startcmd[64];
} CocConn;
void CocInitClient(CocConn *conn, char *host, char *magic, int bufsize, char *startcmd);
int CocSendMagic(CocConn *conn, char *magic);
int CocCmd(CocConn *conn, const char *rwList);
void CocCloseClient(CocConn *conn);

161
tecs/coc.c Normal file
View File

@ -0,0 +1,161 @@
#include <assert.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) {
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, buf_type *buf)
{
struct timeval tmo={0,1};
fd_set mask;
int i, ret;
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");
buf_put_start(buf);
ERR_SI(ret=recv(fd, buf->buf, buf->isize, 0));
if (ret==0) { ERR_COD(ECONNRESET); }
buf->usize=ret;
buf_reset(buf);
return(ret);
OnError: return(-1);
}
void CocVarList(CocVar **varList) {
assert(varList!=NULL);
varListHdl=varList;
}
CocVar *CocFindVar(CocVar *varList, const char *name) {
CocVar *p;
p=varList;
while (p!=NULL && 0!=strcmp(p->name,name)) p=p->next;
return(p);
}
void CocDefVar(const char *name, void *var, int type, int *flag) {
CocVar *p;
assert(varListHdl!=NULL);
p=CocFindVar(*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;
}
int CocGetVar(CocVar *varList, buf_type *buf, const char *name) {
CocVar *var;
var=CocFindVar(varList, name);
if (var==NULL) ERR_MSG("undefined variable");
if (varList==serverVarList) { /* we are the server */
if (var->flag==&CocRD) ERR_MSG("variable is read only");
}
if (var->type==-1) {
*(int *)var->var=buf_get_int(buf);
} else if (var->type==-2) {
*(float *)var->var=buf_get_float(buf);
} else if (var->type>1) {
str_ncpy((char *)var->var, buf_get_str(buf), var->type);
} else {
ERR_MSG("unknown type");
}
if (varList==serverVarList) { /* we are the server */
if (var->flag!=NULL) (*var->flag)++;
}
return(0);
OnError: return(-1);
}
int CocPutVar(CocVar *varList, buf_type *buf, const char *name) {
CocVar *var;
char *c;
var=CocFindVar(varList, name);
if (var==NULL) ERR_MSG("undefined variable");
if (varList!=serverVarList) { /* we are a client */
if (var->flag==&CocRD) ERR_MSG("variable is read only");
}
if (var->type==-1) {
buf_put_int(buf, *(int *)var->var);
} else if (var->type==-2) {
buf_put_float(buf, *(float *)var->var);
} else if (var->type>1) {
c=var->var;
if (c[0]<=2 && c[0]!=0) { ERR_MSG("illegal string"); }
buf_put_str(buf, c);
} else {
ERR_MSG("unknown type");
}
if (varList!=serverVarList) { /* 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;
}

43
tecs/coc.h Normal file
View File

@ -0,0 +1,43 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <stdarg.h>
#include "errhdl.h"
#include "buf.h"
#include "util.h"
#define CocPORT 9751
#define CocPORTS 3
int CocCreateSockAdr(
struct sockaddr_in *sockaddrPtr, /* Socket address */
const char *host, /* Host. NULL implies INADDR_ANY */
int port); /* Port number */
int CocRecv(int fd, buf_type *buf);
typedef struct { void *next; char name[32]; void *var; int *flag; int type; } CocVar;
extern int CocRD;
extern int CocWR;
CocVar *serverVarList;
void CocDefVar(const char *name, void *var, int type, int *flag);
void CocVarList(CocVar **varlist);
void CocFreeVarList(CocVar **varList);
CocVar *CocFindVar(CocVar *varList, const char *name);
int CocPutVar(CocVar *varList, buf_type *buf, const char *name);
int CocGetVar(CocVar *varList, buf_type *buf, const char *name);
void CocDefFlag(int *flag);
#define CocDefInt(V,F) CocDefVar(#V,&V,-1,&F)
#define CocDefFlt(V,F) CocDefVar(#V,&V,-2,&F)
#define CocDefStr(V,F) CocDefVar(#V,V,sizeof(V),&F)
#define CocDefStrPtr(V,S,F) CocDefVar(#V,V,S,&F)

86
tecs/errhdl.c Normal file
View File

@ -0,0 +1,86 @@
#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);
}

81
tecs/errhdl.h Normal file
View File

@ -0,0 +1,81 @@
#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;

130
tecs/tecc.c Normal file
View File

@ -0,0 +1,130 @@
#include "errhdl.h"
#include "client.h"
#include "tecc.h"
char command[80], response[80], device[80];
float tempX, tempP, tempC;
pTecsClient TeccInit(char *server) {
CocConn *conn;
char buf[80];
ERR_SP(conn=(CocConn *)malloc(sizeof(*conn)));
#ifdef __VMS
sprintf(buf, "@start_tecs %s", server);
#else
sprintf(buf, "start_tecs %s", server);
#endif
CocInitClient(conn, "", "#rwacs", 0, buf);
CocDefFlt(tempX, CocRD);
CocDefFlt(tempP, CocRD);
CocDefFlt(tempC, CocWR);
CocDefStr(device, CocWR);
CocDefStr(command, CocWR);
CocDefStr(response, CocWR);
return((pTecsClient)conn);
OnError: return(NULL);
}
int TeccSetDev(pTecsClient conn, char *dev) {
str_copy(device, dev);
ERR_I(CocCmd((CocConn *)conn, "[device]"));
return(0);
OnError: return(-1);
}
char *TeccGetDev(pTecsClient conn) {
ERR_I(CocCmd((CocConn *)conn, "device"));
return(device);
OnError: return(NULL);
}
int TeccGet(pTecsClient conn, float *temp) {
ERR_I(CocCmd((CocConn *)conn, "tempP"));
*temp=tempP;
return(0);
OnError: return(-1);
}
int TeccGet3(pTecsClient conn, float temp[3]) {
ERR_I(CocCmd((CocConn *)conn, "tempC,tempX,tempP"));
temp[0]=tempC;
temp[1]=tempX;
temp[2]=tempP;
return(0);
OnError: return(-1);
}
int TeccSet(pTecsClient conn, float temp) {
tempC=temp;
ERR_I(CocCmd((CocConn *)conn, "[tempC]"));
return(0);
OnError: return(-1);
}
int TeccSend(pTecsClient conn, char *cmd, char *reply, int replyLen) {
command[0]='\0';
while (0!=strcmp(command, cmd)) {
str_copy(command, cmd);
strcpy(response,"<none>");
ERR_I(CocCmd((CocConn *)conn, "[command,response]"));
while (0==strcmp(response,"<none>") && 0==strcmp(command, cmd)) {
util_delay(250);
ERR_I(CocCmd((CocConn *)conn, "command,response"));
}
}
str_ncpy(reply, response, replyLen);
return(0);
OnError: return(-1);
}
void TeccClose(pTecsClient conn) {
CocCloseClient((CocConn *)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((CocConn *)conn, "[device]"));
return(0);
OnError: return(-1);
}
int TeccGetDevVms(pTecsClient conn, char **dev) {
int l, ld;
ERR_I(CocCmd((CocConn *)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';
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

39
tecs/tecc.h Normal file
View File

@ -0,0 +1,39 @@
/*
tecc.h: tecs client interface routines
M. Zolliker March 2000
------------------------------------------------------------------------*/
typedef struct { int tecc_private; } *pTecsClient;
/* hidden structure for a tecs client
------------------------------------------------------------------------*/
pTecsClient TeccInit(char *server);
/* 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
------------------------------------------------------------------------*/

182
tecs/util.c Normal file
View File

@ -0,0 +1,182 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <assert.h>
#include <string.h>
#include <ctype.h>
#include "errhdl.h"
#include "util.h"
/* when changing FBUF_LEN, change also the constant in the fscanf call in subroutine LscExeCmd */
#define FBUF_LEN 132
char *str_split(char *str, char sep, char *list[], int *n) {
int i;
char *s, *e;
s=str;
for (i=0; i<*n; i++) {
list[i]=s;
e=strchr(s, sep);
if (e==NULL) { *n=i+1; return(NULL); }
s=e+1;
e--;
while (e>str && *e==' ') e--; /* trim sequence */
e[1]='\0';
}
return(s);
}
char *str_split1(char *str, char sep) {
char *s, *e;
e=strchr(str, sep);
if (e==NULL) {
s=NULL;
e=str+strlen(str);
} else {
s=e+1;
}
e--;
while (e>str && *e==' ') e--; /* trim sequence */
e[1]='\0';
return(s);
}
char *str_ntrim(char *dest, int ldest, const char *src, int lsrc) {
char *s, *e;
if (lsrc<ldest) ldest=lsrc;
if (dest!=src) strncpy(dest, src, ldest);
e=dest+ldest-2;
while (e>dest && *e==' ') e--; /* trim sequence */
e[1]='\0';
return(s);
}
char *str_read_until(FILE *fil, char *term, char *buf, char *end) {
char *s;
char fmt[24];
int i, l, siz;
char ch;
siz=end-buf-1;
if (siz<1) return(NULL);
sprintf(fmt, "%s%d[^%s%s", "%", siz, term, "]%n%c");
i=fscanf(fil, fmt, buf, &l, &ch);
if (i<0) { /* eof */
buf[0]='\0';
return(&buf[0]);
} else if (i==0) { /* fscanf returns 0 if first char is terminator */
buf[0]=fgetc(fil);
return(&buf[0]);
} else if (i==1) { /* terminator not found -> read until eof */
buf[l]='\0';
return(&buf[l]);
} else {
buf[l]=ch;
if (l==siz && NULL==strchr(term, ch)) return(NULL);
return(&buf[l]);
}
}
char *str_read_arg(char *file, char *args[], int nargs) {
FILE *fil;
char *str, *s, *e, *p, *q;
char ch;
int i, l, size;
struct stat statbuf;
i=stat(file, &statbuf);
if (i<0) ERR_MSG("file not found");
size=statbuf.st_size+4;
if (nargs>0) size+=size/2+100; /* max size */
while (1) {
ERR_SP(str=malloc(size));
e=&str[size-1];
ERR_SP(fil=fopen(file, "r"));
s=str;
while (1) {
p=str_read_until(fil, "#!", s, e);
if (p==NULL) break;
if (*p=='!') {
q=str_read_until(fil, "\n", p, e);
if (q==NULL) { p=NULL; break; }
s=p; *s='\n'; s++;
} else if (*p=='#') {
ch=fgetc(fil);
i=ch-'0';
if (i<0 || i>=nargs) {
s=p+1; *s=ch; s++;
} else {
l=strlen(args[i]);
if (s+l>=e) { p=NULL; break; }
strcpy(p, args[i]);
s=p+l;
}
} else {
assert(*p=='\0');
break;
}
}
ERR_SI(fclose(fil));
if (p!=NULL) break;
size=size*3/2; /* allocation not sufficient -> try again */
free(str);
}
assert(strlen(str)<size);
return(str);
OnError: return(NULL);
}
void str_replace_char(char *str, char ch, char rep) {
char *s;
assert(ch!='\0' && ch!=rep);
s=strchr(str, ch);
while (s!=NULL) {
*s=rep;
s=strchr(s, ch);
}
}
void str_upcase(char *str) {
while (*str!='\0') {
*str=toupper(*str); str++;
}
}
int str_cmp(const char *str1, const char *str2) {
int i;
char ch1, ch2;
ch1=tolower(*(str1++)); ch2=tolower(*(str2++));
i=1;
while (ch1!='\0' && ch2!='\0' && ch1==ch2) {
ch1=tolower(*(str1++)); ch2=tolower(*(str2++)); i++;
}
if (ch1<ch2) {
return(-i);
} else if (ch1>ch2) {
return(i);
}
return(0);
}
int str_ncpy(char *dst, const char *src, int n) {
strncpy(dst, src, n);
if (dst[n-1]!='\0') {
dst[n-1]='\0';
ERR_MSG("destination string too short");
}
return(0);
OnError: return(-1);
}
void util_delay(int tmo_msec) {
struct timeval tmo;
tmo.tv_sec=tmo_msec / 1000;
tmo.tv_usec=(tmo_msec % 1000)*1000+1;
select(1,NULL,NULL,NULL,&tmo);
}

65
tecs/util.h Normal file
View File

@ -0,0 +1,65 @@
char *str_ntrim(char *dest, int ldest, const char *src, int lsrc);
/*
copy characters 0 to lsrc-1 from src to dest (max ldest chars).
*/
char *str_split1(char *str, char separator);
/*
trims text before separator in *str and returns
a pointer to the first character after separator
*/
char *str_split(char *str, char sep, char *list[], int *n);
/*
split string into *n strings using separator sep.
spaces at the end of the elements are trimmed
attention: *str is modified ('\0' placed at the end of the elements)
if *n separators are found, result points to string after *n-th separator
else result is NULL
*n contains number of elements stored in list
*/
char *str_read_arg(char *file, char *args[], int nargs);
/*
return one string containing the contents of file *file
the contents are treated in the following way:
- #0,#1,...#n is replaced by the corresponding argument *args[n] (n=0..nargs-1, nargs<10)
- at the end of each line spaces and comments separated by ! are trimmed
*/
void str_replace_char(char *str, char ch, char rep);
/*
replace all occurences of character ch by character rep in string *str
*/
void str_upcase(char *str);
/*
convert *str to uppercase
*/
int str_cmp(const char *str1, const char *str2);
/*
compare *str1 with *str2
the comparison is not case sensitive
if result=0: strings are equal
else
result>0 <==> *str1>*str2
first different character is at position abs(result)-1
*/
int str_ncpy(char *dst, const char *src, int n);
/*
same as strncpy, but dst has always a '\0' at end
use str_copy if dst is a character array
returns -1, if destination is to short, 0 otherwise
*/
#define str_copy(DST,SRC) str_ncpy(DST,SRC,sizeof(DST))
void util_delay(int tmo_msec);
/*
usleep is not available on VMS 6
*/