enhancements / fixed various bugs
This commit is contained in:
506
remob.c
506
remob.c
@ -10,7 +10,7 @@ M. Zolliker July 04
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <tcl.h>
|
#include <netdb.h>
|
||||||
#include "fortify.h"
|
#include "fortify.h"
|
||||||
#include "sics.h"
|
#include "sics.h"
|
||||||
#include "devexec.h"
|
#include "devexec.h"
|
||||||
@ -31,9 +31,8 @@ typedef struct RemServer {
|
|||||||
char *name;
|
char *name;
|
||||||
char *host;
|
char *host;
|
||||||
int port;
|
int port;
|
||||||
char *user;
|
int actChan; /* 0 or 1 */
|
||||||
char *pass;
|
mkChannel *chans[2]; /* 0: Spy, 1: User */
|
||||||
mkChannel *chan;
|
|
||||||
int incomplete;
|
int incomplete;
|
||||||
char line[256];
|
char line[256];
|
||||||
Remob *objList;
|
Remob *objList;
|
||||||
@ -46,12 +45,13 @@ typedef struct RemServer {
|
|||||||
struct Remob {
|
struct Remob {
|
||||||
pObjectDescriptor desc;
|
pObjectDescriptor desc;
|
||||||
char *name;
|
char *name;
|
||||||
ObPar *ParArray;
|
|
||||||
pIDrivable pDrivInt;
|
pIDrivable pDrivInt;
|
||||||
pICallBack pCall;
|
pICallBack pCall;
|
||||||
RemServer *server;
|
RemServer *server;
|
||||||
int status;
|
int status;
|
||||||
Remob *next;
|
Remob *next;
|
||||||
|
int access;
|
||||||
|
int markForDel;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -81,10 +81,16 @@ static char *StartsWith(char *line, char *name) {
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
static int RemWrite(RemServer *remserver, char *line) {
|
static int RemWrite(RemServer *remserver, char *line) {
|
||||||
if (remserver->chan) {
|
int iret;
|
||||||
|
mkChannel *chan;
|
||||||
|
|
||||||
|
chan = remserver->chans[remserver->actChan];
|
||||||
|
if (chan) {
|
||||||
/* printf("> %s\n", line); */
|
/* printf("> %s\n", line); */
|
||||||
return NETWrite(remserver->chan, line, strlen(line));
|
iret = NETWrite(chan, line, strlen(line));
|
||||||
|
if (iret == 0) iret = -1;
|
||||||
|
return iret;
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -92,9 +98,11 @@ static int RemWrite(RemServer *remserver, char *line) {
|
|||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
static int RemRead(RemServer *remserver, long tmo) {
|
static int RemRead(RemServer *remserver, long tmo) {
|
||||||
int iRet;
|
int iRet;
|
||||||
|
mkChannel *chan;
|
||||||
|
|
||||||
if (remserver->chan == NULL) return 0; /* no data */
|
chan = remserver->chans[remserver->actChan];
|
||||||
iRet = NETReadTillTermNew(remserver->chan, tmo, "\n",
|
if (chan == NULL) return 0; /* no data */
|
||||||
|
iRet = NETReadTillTermNew(chan, tmo, "\n",
|
||||||
remserver->line+remserver->incomplete, sizeof(remserver->line)-remserver->incomplete);
|
remserver->line+remserver->incomplete, sizeof(remserver->line)-remserver->incomplete);
|
||||||
if (iRet == 0) {
|
if (iRet == 0) {
|
||||||
remserver->incomplete = strlen(remserver->line); /* number of chars already received */
|
remserver->incomplete = strlen(remserver->line); /* number of chars already received */
|
||||||
@ -141,14 +149,59 @@ static int RemHandle(RemServer *remserver) {
|
|||||||
}
|
}
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
static void RemCopy(RemServer *remserver, SConnection *pCon) {
|
static void RemCopy(RemServer *remserver, SConnection *pCon) {
|
||||||
char buf[256];
|
|
||||||
if (pCon != NULL && remserver->line[0] != '\0') {
|
if (pCon != NULL && remserver->line[0] != '\0') {
|
||||||
snprintf(buf, sizeof(buf), " %s", remserver->line);
|
SCPrintf(pCon, eStatus, " %s", remserver->line);
|
||||||
/* snprintf(buf, sizeof(buf), "%s (%s)", remserver->line, remserver->name); */
|
|
||||||
SCWrite(pCon, buf, eStatus);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
|
static void RemDisconnect(RemServer *remserver) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i=0; i<2; i++) {
|
||||||
|
if (remserver->chans[i] != NULL) {
|
||||||
|
NETClosePort(remserver->chans[i]);
|
||||||
|
free(remserver->chans[i]);
|
||||||
|
remserver->chans[i]=NULL;
|
||||||
|
/* printf("disconnected\n"); */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
static void RemConnect(RemServer *remserver) {
|
||||||
|
int iRet;
|
||||||
|
char buf[256];
|
||||||
|
mkChannel *chan;
|
||||||
|
|
||||||
|
chan = remserver->chans[remserver->actChan];
|
||||||
|
if (!chan) {
|
||||||
|
remserver->timeout = 0;
|
||||||
|
chan = NETConnect(remserver->host, remserver->port);
|
||||||
|
if (!chan) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
remserver->chans[remserver->actChan] = chan;
|
||||||
|
if (remserver->actChan == 0) {
|
||||||
|
iRet = RemWrite(remserver, "Spy 007\ntransact listexe interest\n");
|
||||||
|
} else {
|
||||||
|
iRet = RemWrite(remserver, "remuser sesam\ntransact listexe interest\n");
|
||||||
|
}
|
||||||
|
if (iRet < 0) goto close;
|
||||||
|
iRet = RemRead(remserver, 1000);
|
||||||
|
while (iRet > 0) { /* eat login response */
|
||||||
|
if (StartsWith(remserver->line, "TRANSACTIONFINISHED")) {
|
||||||
|
/* printf("connected\n"); */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
iRet = RemRead(remserver, 1000);
|
||||||
|
}
|
||||||
|
goto close;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
close:
|
||||||
|
RemDisconnect(remserver);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
static int RemServerTask(void *data) {
|
static int RemServerTask(void *data) {
|
||||||
RemServer *remserver=data;
|
RemServer *remserver=data;
|
||||||
int iRet;
|
int iRet;
|
||||||
@ -171,49 +224,10 @@ static int RemServerTask(void *data) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
static void RemDisconnect(RemServer *remserver) {
|
|
||||||
if (remserver->chan != NULL) {
|
|
||||||
NETClosePort(remserver->chan);
|
|
||||||
free(remserver->chan);
|
|
||||||
remserver->chan=NULL;
|
|
||||||
/* printf("disconnected\n"); */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*-------------------------------------------------------------------------*/
|
|
||||||
static void RemConnect(RemServer *remserver) {
|
|
||||||
int iRet;
|
|
||||||
char buf[256];
|
|
||||||
|
|
||||||
if (!remserver->chan) {
|
|
||||||
remserver->timeout = 0;
|
|
||||||
remserver->chan = NETConnect(remserver->host, remserver->port);
|
|
||||||
if (!remserver->chan) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
snprintf(buf, sizeof(buf), "%s %s\ntransact listexe interest\n"
|
|
||||||
, remserver->user, remserver->pass);
|
|
||||||
iRet = RemWrite(remserver, buf);
|
|
||||||
if (iRet < 0) goto close;
|
|
||||||
iRet = RemRead(remserver, 1000);
|
|
||||||
while (iRet > 0) { /* eat login response */
|
|
||||||
if (StartsWith(remserver->line, "TRANSACTIONFINISHED")) {
|
|
||||||
/* printf("connected\n"); */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
iRet = RemRead(remserver, 1000);
|
|
||||||
}
|
|
||||||
goto close;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
close:
|
|
||||||
RemDisconnect(remserver);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/*-------------------------------------------------------------------------*/
|
|
||||||
static int RemTransact(RemServer *remserver, SConnection *pCon, char *cmd, ...) {
|
static int RemTransact(RemServer *remserver, SConnection *pCon, char *cmd, ...) {
|
||||||
/* the variable arguments are for filtering:
|
/* the variable arguments are for filtering:
|
||||||
|
|
||||||
"<name", &val get float value named m
|
"<name", &val get float value named name
|
||||||
"!blabla" skip lines starting with blabla
|
"!blabla" skip lines starting with blabla
|
||||||
">" write untreated lines to pCon
|
">" write untreated lines to pCon
|
||||||
*/
|
*/
|
||||||
@ -285,11 +299,11 @@ close:
|
|||||||
remserver->timeout = 1;
|
remserver->timeout = 1;
|
||||||
return iRet;
|
return iRet;
|
||||||
}
|
}
|
||||||
snprintf(buf, sizeof(buf), "ERROR: no connection to %s", remserver->name);
|
|
||||||
SCWrite(pCon,buf,eError);
|
|
||||||
RemDisconnect(remserver);
|
RemDisconnect(remserver);
|
||||||
try--;
|
try--;
|
||||||
if (try>0) goto tryagain;
|
if (try>0) goto tryagain;
|
||||||
|
snprintf(buf, sizeof(buf), "ERROR: no connection to %s", remserver->name);
|
||||||
|
SCWrite(pCon,buf,eError);
|
||||||
return iRet;
|
return iRet;
|
||||||
}
|
}
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
@ -351,12 +365,11 @@ static float RemobGetValue(void *pData, SConnection *pCon) {
|
|||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
static int RemobSaveStatus(void *pData, char *name, FILE *fd) {
|
static int RemobSaveStatus(void *pData, char *name, FILE *fil) {
|
||||||
Remob *self = pData;
|
Remob *self = pData;
|
||||||
char buf[512];
|
|
||||||
|
|
||||||
assert(self);
|
assert(self);
|
||||||
assert(fd);
|
assert(fil);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
data is stored on remote server
|
data is stored on remote server
|
||||||
@ -364,6 +377,19 @@ static int RemobSaveStatus(void *pData, char *name, FILE *fd) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
static int RemServerSaveStatus(void *pData, char *name, FILE *fil) {
|
||||||
|
RemServer *remserver = pData;
|
||||||
|
Remob *remob;
|
||||||
|
|
||||||
|
assert(remserver);
|
||||||
|
assert(fil);
|
||||||
|
|
||||||
|
for (remob = remserver->objList; remob != NULL; remob = remob->next) {
|
||||||
|
fprintf(fil, "catch { remob new %s %s }\n", remob->name, remserver->name);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
static int RemobStatus(void *pData, SConnection *pCon) {
|
static int RemobStatus(void *pData, SConnection *pCon) {
|
||||||
Remob *remob=pData;
|
Remob *remob=pData;
|
||||||
|
|
||||||
@ -389,11 +415,9 @@ static long RemobRun(void *self, SConnection *pCon, float fNew) {
|
|||||||
assert(remob);
|
assert(remob);
|
||||||
assert(pCon);
|
assert(pCon);
|
||||||
|
|
||||||
/* check if I'am allowed to move this motor */
|
/* check if I'am allowed to drive this object */
|
||||||
if (!SCMatchRights(pCon,(int)ObVal(remob->ParArray,ACCESSCODE))) {
|
if (remob->access < SCGetRights(pCon)) {
|
||||||
snprintf(buf,sizeof(buf), "ERROR: You are not authorised to run %s",
|
SCPrintf(pCon, eError, "ERROR: You are not authorised to run %s", remob->name);
|
||||||
remob->name);
|
|
||||||
SCWrite(pCon,buf,eError);
|
|
||||||
SCSetInterrupt(pCon,eAbortBatch);
|
SCSetInterrupt(pCon,eAbortBatch);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -458,91 +482,40 @@ int RemobAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|||||||
float fValue;
|
float fValue;
|
||||||
long lID;
|
long lID;
|
||||||
char *endp;
|
char *endp;
|
||||||
ObPar *par;
|
|
||||||
char acce[128], inte[128];
|
char acce[128], inte[128];
|
||||||
|
|
||||||
assert(pCon);
|
assert(pCon);
|
||||||
assert(pSics);
|
assert(pSics);
|
||||||
assert(remob);
|
assert(remob);
|
||||||
|
|
||||||
argtolower(argc,argv);
|
if (SCGetRights(pCon) > usUser) {
|
||||||
|
remob->server->actChan = 0;
|
||||||
|
} else {
|
||||||
|
remob->server->actChan = 1;
|
||||||
|
}
|
||||||
SCSave(&remob->server->conn, pCon);
|
SCSave(&remob->server->conn, pCon);
|
||||||
if (argc == 1) {
|
if (argc == 1) {
|
||||||
iRet = RemTransact(remob->server, pCon, argv[0], ">", NULL);
|
iRet = RemTransact(remob->server, pCon, argv[0], ">", NULL);
|
||||||
} else if (strcmp(argv[1],"list") == 0) {
|
} else if (strcasecmp(argv[1],"list") == 0) {
|
||||||
snprintf(buf, sizeof(buf), "%s list", remob->name);
|
snprintf(buf, sizeof(buf), "%s ", remob->name);
|
||||||
|
i = strlen(buf);
|
||||||
|
Arg2Text(argc-1, argv+1, buf + i, sizeof buf - i);
|
||||||
|
/*
|
||||||
snprintf(acce, sizeof(acce), "!%s.accesscode", remob->name);
|
snprintf(acce, sizeof(acce), "!%s.accesscode", remob->name);
|
||||||
snprintf(inte, sizeof(inte), "!%s.interruptmode", remob->name);
|
snprintf(inte, sizeof(inte), "!%s.interruptmode", remob->name);
|
||||||
|
*/
|
||||||
|
|
||||||
RemTransact(remob->server, pCon, buf, acce, inte, ">", NULL);
|
RemTransact(remob->server, pCon, buf, ">", NULL);
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "%s = %.0f", acce+1, ObVal(remob->ParArray,ACCESSCODE));
|
|
||||||
SCWrite(pCon, buf, eStatus);
|
|
||||||
snprintf(buf, sizeof(buf), "%s = %.0f", inte+1, ObVal(remob->ParArray,INTERRUPTMODE));
|
|
||||||
SCWrite(pCon, buf, eStatus);
|
|
||||||
iRet=1;
|
iRet=1;
|
||||||
} else {
|
} else {
|
||||||
par=ObParFind(remob->ParArray, argv[1]);
|
pos=snprintf(buf, sizeof(buf), "%s ", remob->name);
|
||||||
if (par != NULL) {
|
|
||||||
if (argc == 3) {
|
|
||||||
fValue = strtod(argv[2], &endp);
|
|
||||||
if (endp == argv[2]) {
|
|
||||||
snprintf(buf, sizeof(buf), "number expected instead of %s", argv[2]);
|
|
||||||
SCWrite(pCon, buf, eError);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
iRet = ObParSet(remob->ParArray,argv[0],argv[1],fValue,pCon);
|
|
||||||
}
|
|
||||||
if (iRet) {
|
|
||||||
snprintf(buf, sizeof(buf), "%s.%s = %.0f", argv[0], argv[1], par->fVal);
|
|
||||||
SCWrite(pCon, buf, eStatus);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pos=snprintf(buf, sizeof(buf), "%s ", remob->name);
|
|
||||||
for (i=1; i<argc; i++) {
|
|
||||||
pos+=snprintf(buf+pos, sizeof(buf)-pos, "%s ", argv[i]);
|
|
||||||
}
|
|
||||||
iRet = RemTransact(remob->server, pCon, buf, ">", NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return iRet;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
int RemServerAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|
||||||
int argc, char *argv[]) {
|
|
||||||
RemServer *remserver = pData;
|
|
||||||
char buf[512];
|
|
||||||
TokenList *pList = NULL;
|
|
||||||
TokenList *pCurrent;
|
|
||||||
TokenList *pName;
|
|
||||||
int iRet;
|
|
||||||
int i;
|
|
||||||
int pos;
|
|
||||||
float fValue;
|
|
||||||
long lID;
|
|
||||||
char *endp;
|
|
||||||
ObPar *par;
|
|
||||||
char acce[128], inte[128];
|
|
||||||
|
|
||||||
assert(pCon);
|
|
||||||
assert(pSics);
|
|
||||||
assert(remserver);
|
|
||||||
|
|
||||||
argtolower(argc,argv);
|
|
||||||
|
|
||||||
if (argc == 1) {
|
|
||||||
snprintf(buf, sizeof(buf), "%s = %s:%d", argv[0], remserver->host, remserver->port);
|
|
||||||
SCWrite(pCon, buf, eStatus);
|
|
||||||
} else {
|
|
||||||
pos=0;
|
|
||||||
for (i=1; i<argc; i++) {
|
for (i=1; i<argc; i++) {
|
||||||
pos+=snprintf(buf+pos, sizeof(buf)-pos, "%s ", argv[i]);
|
pos+=snprintf(buf+pos, sizeof(buf)-pos, "%s ", argv[i]);
|
||||||
}
|
}
|
||||||
iRet = RemTransact(remserver, pCon, buf, ">", NULL);
|
iRet = RemTransact(remob->server, pCon, buf, ">", NULL);
|
||||||
return iRet;
|
|
||||||
}
|
}
|
||||||
return 1;
|
return iRet;
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
static void RemobKill(void *self) {
|
static void RemobKill(void *self) {
|
||||||
@ -574,19 +547,100 @@ static void RemobKill(void *self) {
|
|||||||
DeleteCallBackInterface(remob->pCall);
|
DeleteCallBackInterface(remob->pCall);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get rid of parameter space */
|
|
||||||
if (remob->ParArray) {
|
|
||||||
ObParDelete(remob->ParArray);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* kill Descriptor */
|
/* kill Descriptor */
|
||||||
DeleteDescriptor(remob->desc);
|
if (remob->desc) {
|
||||||
|
DeleteDescriptor(remob->desc);
|
||||||
|
}
|
||||||
free(remob);
|
free(remob);
|
||||||
}
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int RemServerAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]) {
|
||||||
|
RemServer *remserver = pData;
|
||||||
|
char buf[512];
|
||||||
|
TokenList *pList = NULL;
|
||||||
|
TokenList *pCurrent;
|
||||||
|
TokenList *pName;
|
||||||
|
int iRet;
|
||||||
|
int i;
|
||||||
|
int pos;
|
||||||
|
float fValue;
|
||||||
|
long lID;
|
||||||
|
char *endp, *serverport, *thishostname;
|
||||||
|
char acce[128], inte[128];
|
||||||
|
struct sockaddr_in adr;
|
||||||
|
struct hostent *thishost;
|
||||||
|
mkChannel *chan;
|
||||||
|
Remob *p, *next;
|
||||||
|
|
||||||
|
assert(pCon);
|
||||||
|
assert(pSics);
|
||||||
|
assert(remserver);
|
||||||
|
|
||||||
|
if (SCGetRights(pCon) > usUser) {
|
||||||
|
remserver->actChan = 0;
|
||||||
|
} else {
|
||||||
|
remserver->actChan = 1;
|
||||||
|
}
|
||||||
|
chan = remserver->chans[remserver->actChan];
|
||||||
|
if (argc == 1) {
|
||||||
|
serverport = IFindOption(pSICSOptions,"ServerPort");
|
||||||
|
i = sizeof adr;
|
||||||
|
thishostname = NULL;
|
||||||
|
if (chan) {
|
||||||
|
if (getsockname(chan->sockid, (void *)&adr, &i) >= 0) {
|
||||||
|
thishost = gethostbyaddr((char *)&adr.sin_addr,
|
||||||
|
sizeof adr.sin_addr, AF_INET);
|
||||||
|
if (thishost) {
|
||||||
|
thishostname = thishost->h_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (thishostname == NULL) thishostname = "undef";
|
||||||
|
SCPrintf(pCon, eStatus, "%s = %s:%d %s:%s",
|
||||||
|
argv[0], remserver->host, remserver->port, thishostname, serverport);
|
||||||
|
} else if (argc>2 && strcasecmp(argv[1],"nowait") == 0) {
|
||||||
|
RemConnect(remserver);
|
||||||
|
for (i=2; i<argc; i++) {
|
||||||
|
if (i>2) {
|
||||||
|
RemWrite(remserver, " ");
|
||||||
|
}
|
||||||
|
RemWrite(remserver, argv[i]);
|
||||||
|
}
|
||||||
|
RemWrite(remserver, "\n");
|
||||||
|
} else if (argc==2 && strcasecmp(argv[1],"markForDel") == 0) {
|
||||||
|
p = remserver->objList;
|
||||||
|
while (p) {
|
||||||
|
p->markForDel = 1;
|
||||||
|
p = p->next;
|
||||||
|
}
|
||||||
|
} else if (argc==2 && strcasecmp(argv[1],"delMarked") == 0) {
|
||||||
|
p = remserver->objList;
|
||||||
|
while (p) {
|
||||||
|
next = p->next;
|
||||||
|
if (p->markForDel) {
|
||||||
|
if (p->pDrivInt && pServ->pExecutor && isInRunMode(pServ->pExecutor)) {
|
||||||
|
SCWrite(pCon,"ERROR: cannot delete while running",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
RemoveCommand(pSics, p->name);
|
||||||
|
}
|
||||||
|
p = next;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pos=0;
|
||||||
|
for (i=1; i<argc; i++) {
|
||||||
|
pos+=snprintf(buf+pos, sizeof(buf)-pos, "%s ", argv[i]);
|
||||||
|
}
|
||||||
|
iRet = RemTransact(remserver, pCon, buf, ">", NULL);
|
||||||
|
return iRet;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
static void RemServerKill(void *self) {
|
static void RemServerKill(void *self) {
|
||||||
RemServer *remserver = self;
|
RemServer *remserver = self;
|
||||||
|
Remob *remob, *next;
|
||||||
|
|
||||||
assert(remserver);
|
assert(remserver);
|
||||||
|
|
||||||
@ -595,72 +649,60 @@ static void RemServerKill(void *self) {
|
|||||||
/* let the tasker kill me */
|
/* let the tasker kill me */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
remserver = (RemServer *)self;
|
remob = remserver->objList;
|
||||||
if (remserver->chan) {
|
while (remob) {
|
||||||
RemDisconnect(remserver);
|
next = remob->next;
|
||||||
|
RemoveCommand(pServ->pSics, remob->name);
|
||||||
|
remob = next;
|
||||||
}
|
}
|
||||||
|
RemDisconnect(remserver);
|
||||||
DeleteDescriptor(remserver->desc);
|
DeleteDescriptor(remserver->desc);
|
||||||
if (remserver->name) free(remserver->name);
|
if (remserver->name) free(remserver->name);
|
||||||
if (remserver->host) free(remserver->host);
|
if (remserver->host) free(remserver->host);
|
||||||
if (remserver->user) free(remserver->user);
|
|
||||||
if (remserver->pass) free(remserver->pass);
|
|
||||||
free(remserver);
|
free(remserver);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
static int RemobSetDriveable(Remob *remob, int driveable) {
|
||||||
|
if (driveable) {
|
||||||
|
/* initialise Drivable interface */
|
||||||
|
remob->pDrivInt = CreateDrivableInterface();
|
||||||
|
if (!remob->pDrivInt) return 0;
|
||||||
|
remob->pDrivInt->SetValue = RemobRun;
|
||||||
|
remob->pDrivInt->CheckLimits = RemobLimits;
|
||||||
|
remob->pDrivInt->CheckStatus = RemobStatus;
|
||||||
|
remob->pDrivInt->GetValue = RemobGetValue;
|
||||||
|
remob->pDrivInt->Halt = RemobHalt;
|
||||||
|
} else if (remob->pDrivInt) {
|
||||||
|
free(remob->pDrivInt);
|
||||||
|
remob->pDrivInt = NULL;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
static Remob *RemobInit(char *name, RemServer *remserver) {
|
static Remob *RemobInit(char *name, RemServer *remserver) {
|
||||||
Remob *remob, *p;
|
Remob *remob, *p;
|
||||||
|
|
||||||
assert(name);
|
assert(name);
|
||||||
|
|
||||||
/* get memory */
|
/* get memory */
|
||||||
remob = (Remob *)malloc(sizeof(Remob));
|
remob = (Remob *)calloc(1,sizeof(Remob));
|
||||||
if(!remob) {
|
if(!remob) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create and initialize parameters */
|
|
||||||
remob->ParArray = ObParCreate(2);
|
|
||||||
if (!remob->ParArray) {
|
|
||||||
free(remob);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
ObParInit(remob->ParArray,INTERRUPTMODE,"interruptmode",0.0,usUser);
|
|
||||||
ObParInit(remob->ParArray,ACCESSCODE,"accesscode",(float)usUser,usMugger);
|
|
||||||
|
|
||||||
/* copy arguments */
|
/* copy arguments */
|
||||||
remob->server = remserver;
|
remob->server = remserver;
|
||||||
remob->name = strdup(name);
|
remob->name = strdup(name);
|
||||||
|
|
||||||
/* initialise object descriptor */
|
/* initialise object descriptor */
|
||||||
remob->desc = CreateDescriptor("Remob");
|
remob->desc = CreateDescriptor("RemObject");
|
||||||
if (!remob->desc) {
|
if (!remob->desc) goto killit;
|
||||||
ObParDelete(remob->ParArray);
|
|
||||||
free(remob);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
remob->desc->GetInterface = RemobGetInterface;
|
remob->desc->GetInterface = RemobGetInterface;
|
||||||
remob->desc->SaveStatus = RemobSaveStatus;
|
remob->desc->SaveStatus = RemobSaveStatus;
|
||||||
|
|
||||||
/* initialise Drivable interface */
|
|
||||||
remob->pDrivInt = CreateDrivableInterface();
|
|
||||||
if (!remob->pDrivInt) {
|
|
||||||
DeleteDescriptor(remob->desc);
|
|
||||||
ObParDelete(remob->ParArray);
|
|
||||||
free(remob);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
remob->pDrivInt->SetValue = RemobRun;
|
|
||||||
remob->pDrivInt->CheckLimits = RemobLimits;
|
|
||||||
remob->pDrivInt->CheckStatus = RemobStatus;
|
|
||||||
remob->pDrivInt->GetValue = RemobGetValue;
|
|
||||||
remob->pDrivInt->Halt = RemobHalt;
|
|
||||||
|
|
||||||
/* initialise callback interface */
|
/* initialise callback interface */
|
||||||
remob->pCall = CreateCallBackInterface();
|
remob->pCall = CreateCallBackInterface();
|
||||||
if(!remob->pCall) {
|
if(!remob->pCall) goto killit;
|
||||||
RemobKill(remob);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check if not yet in object list */
|
/* check if not yet in object list */
|
||||||
for (p = remserver->objList; p != NULL; p=p->next) {
|
for (p = remserver->objList; p != NULL; p=p->next) {
|
||||||
@ -671,20 +713,20 @@ static Remob *RemobInit(char *name, RemServer *remserver) {
|
|||||||
remserver->objList = remob;
|
remserver->objList = remob;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!remserver->taskActive) {
|
remob->markForDel = 0;
|
||||||
remserver->taskActive = 1;
|
|
||||||
TaskRegister(pServ->pTasker, RemServerTask, NULL, RemServerKill, remserver, 1);
|
|
||||||
}
|
|
||||||
/* done */
|
/* done */
|
||||||
return remob;
|
return remob;
|
||||||
|
killit:
|
||||||
|
RemobKill(remob);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
static RemServer *RemServerInit(char *name, char *host, int port, char *user, char *pass) {
|
static RemServer *RemServerInit(char *name, char *host, int port) {
|
||||||
RemServer *remserver = NULL;
|
RemServer *remserver = NULL;
|
||||||
|
|
||||||
assert(name);
|
assert(name);
|
||||||
|
|
||||||
remserver = malloc(sizeof(RemServer));
|
remserver = calloc(1, sizeof(RemServer));
|
||||||
if (!remserver) {
|
if (!remserver) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -695,90 +737,124 @@ static RemServer *RemServerInit(char *name, char *host, int port, char *user, ch
|
|||||||
free(remserver);
|
free(remserver);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
remserver->taskActive = 0;
|
remserver->desc->SaveStatus = RemServerSaveStatus;
|
||||||
remserver->name = strdup(name);
|
remserver->name = strdup(name);
|
||||||
remserver->host = strdup(host);
|
remserver->host = strdup(host);
|
||||||
remserver->port = port;
|
remserver->port = port;
|
||||||
remserver->user = strdup(user);
|
|
||||||
remserver->pass = strdup(pass);
|
|
||||||
remserver->incomplete = 0;
|
remserver->incomplete = 0;
|
||||||
|
remserver->objList = NULL;
|
||||||
|
remserver->chans[0] = NULL;
|
||||||
|
remserver->chans[1] = NULL;
|
||||||
if (!remserver->name ||
|
if (!remserver->name ||
|
||||||
!remserver->host ||
|
!remserver->host ||
|
||||||
!remserver->port ||
|
!remserver->port) {
|
||||||
!remserver->pass) {
|
|
||||||
/* no success, clean up */
|
/* no success, clean up */
|
||||||
RemServerKill(remserver);
|
RemServerKill(remserver);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
remserver->taskActive = 1;
|
||||||
|
TaskRegister(pServ->pTasker, RemServerTask, NULL, RemServerKill, remserver, 1);
|
||||||
return remserver;
|
return remserver;
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------------
|
/*--------------------------------------------------------------------------
|
||||||
The Factory function for creating a remote driveable object.
|
The Factory function for creating a remote driveable object.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
Remob server serverName host port user pass
|
Remob server serverName host:port
|
||||||
Remob new remobName serverName
|
Remob obj remobName serverName
|
||||||
Remob del remobName (not yet implemented)
|
Remob drv remobName serverName
|
||||||
Remob del serverName (not yet implemented)
|
Remob del remobName
|
||||||
|
Remob del serverName
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int RemobCreate(SConnection *pCon, SicsInterp *pSics, void *pData,
|
int RemobCreate(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[]) {
|
int argc, char *argv[]) {
|
||||||
RemServer *remserver = NULL;
|
RemServer *remserver = NULL;
|
||||||
Remob *remob = NULL;
|
Remob *remob = NULL;
|
||||||
char buf[512];
|
char host[128];
|
||||||
|
char *p;
|
||||||
int iD, iRet;
|
int iD, iRet;
|
||||||
Tcl_Interp *pTcl = (Tcl_Interp *)pSics->pTcl;
|
char *obj;
|
||||||
|
|
||||||
assert(pCon);
|
assert(pCon);
|
||||||
assert(pSics);
|
assert(pSics);
|
||||||
|
|
||||||
if (argc <= 5) {
|
argtolower(argc,argv);
|
||||||
argtolower(argc,argv);
|
if (argc >= 4 && strcmp(argv[1], "server") == 0) {
|
||||||
} else {
|
if (argc == 5) {
|
||||||
argtolower(5,argv);
|
remserver = RemServerInit(argv[2], argv[3], atoi(argv[4]));
|
||||||
}
|
} else {
|
||||||
if (argc == 7 && strcmp(argv[1], "server") == 0) {
|
p = strchr(argv[3], ':');
|
||||||
remserver = RemServerInit(argv[2], argv[3], atoi(argv[4]), argv[5], argv[6]);
|
if (!p) {
|
||||||
|
SCPrintf(pCon, eError, "ERROR: illegal host:port");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
snprintf(host, sizeof host, "%.*s", p-argv[3], argv[3]);
|
||||||
|
remserver = RemServerInit(argv[2], host, atoi(p+1));
|
||||||
|
}
|
||||||
if (!remserver) {
|
if (!remserver) {
|
||||||
snprintf(buf, sizeof(buf), "Failure to create remote server connection %s", argv[2]);
|
SCPrintf(pCon, eError, "ERROR: Failure to create remote server connection %s", argv[2]);
|
||||||
SCWrite(pCon, buf, eError);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* create the interpreter command */
|
/* create the interpreter command */
|
||||||
iRet = AddCommand(pSics,argv[2],RemServerAction,RemServerKill,remserver);
|
iRet = AddCommand(pSics,argv[2],RemServerAction,RemServerKill,remserver);
|
||||||
if (!iRet) {
|
if (!iRet) {
|
||||||
snprintf(buf, sizeof(buf),"ERROR: duplicate command %s not created",argv[1]);
|
SCPrintf(pCon, eError, "ERROR: duplicate command %s not created",argv[2]);
|
||||||
SCWrite(pCon,buf,eError);
|
RemServerKill(remserver);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
} else if (argc == 4 && strcmp(argv[1], "new") == 0) {
|
} else if (argc == 4 && (strcmp(argv[1], "obj") == 0 || strcmp(argv[1], "drv") == 0)) {
|
||||||
remserver = FindCommandData(pServ->pSics, argv[3], "RemServer");
|
remserver = FindCommandData(pServ->pSics, argv[3], "RemServer");
|
||||||
if (!remserver) {
|
if (!remserver) {
|
||||||
snprintf(buf, sizeof(buf), "remote server %s not found", argv[3]);
|
SCPrintf(pCon, eError, "ERROR: remote server %s not found", argv[3]);
|
||||||
SCWrite(pCon, buf, eError);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
remob = FindCommandData(pServ->pSics, argv[2], "RemObject");
|
||||||
|
if (remob) {
|
||||||
|
if (remob->server == remserver) {
|
||||||
|
RemobSetDriveable(remob, strcmp(argv[1], "drv") == 0);
|
||||||
|
remob->markForDel = 0;
|
||||||
|
return 1; /* object exists already, silent return */
|
||||||
|
}
|
||||||
|
}
|
||||||
remob = RemobInit(argv[2], remserver);
|
remob = RemobInit(argv[2], remserver);
|
||||||
if (!remob) {
|
if (!remob) {
|
||||||
snprintf(buf, sizeof(buf), "Failure to create remote driveable object %s", argv[1]);
|
SCPrintf(pCon, eError, "ERROR: Failure to create remote object %s", argv[1]);
|
||||||
SCWrite(pCon, buf, eError);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
RemobSetDriveable(remob, strcmp(argv[1], "drv") == 0);
|
||||||
/* create the interpreter command */
|
/* create the interpreter command */
|
||||||
iRet = AddCommand(pSics,argv[2],RemobAction,RemobKill,remob);
|
iRet = AddCommand(pSics,argv[2],RemobAction,RemobKill,remob);
|
||||||
|
SCparChange(pCon);
|
||||||
if (!iRet) {
|
if (!iRet) {
|
||||||
snprintf(buf, sizeof(buf),"ERROR: duplicate command %s not created",argv[1]);
|
SCPrintf(pCon, eError, "ERROR: duplicate command %s not created",argv[2]);
|
||||||
SCWrite(pCon,buf,eError);
|
RemobKill(remob);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
} else if (argc == 3 && strcmp(argv[1], "del") == 0) {
|
||||||
|
remob = FindCommandData(pSics, argv[2], "RemObject");
|
||||||
|
if (remob) { /* its a remob */
|
||||||
|
if (remob->pDrivInt && pServ->pExecutor && isInRunMode(pServ->pExecutor)) {
|
||||||
|
SCPrintf(pCon,eError,"ERROR: cannot delete %s while running", argv[2]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return RemoveCommand(pSics, argv[2]);
|
||||||
|
}
|
||||||
|
if (pServ->pExecutor && isInRunMode(pServ->pExecutor)) {
|
||||||
|
SCPrintf(pCon,eError,"ERROR: cannot delete %s while running", argv[2]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
remserver = FindCommandData(pSics, argv[2], "RemServer");
|
||||||
|
if (remserver) { /* its a remserver */
|
||||||
|
return RemoveCommand(pSics, argv[2]);
|
||||||
|
}
|
||||||
|
SCWrite(pCon,"ERROR: remob object not found",eError);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
snprintf(buf, sizeof(buf),"ERROR: illegal arguments for command remob");
|
SCPrintf(pCon, eError, "ERROR: illegal arguments for command remob");
|
||||||
SCWrite(pCon,buf,eError);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user