From afaeae05544c18ae3a0d9834c42b3aae5e09fad9 Mon Sep 17 00:00:00 2001 From: zolliker Date: Thu, 17 Nov 2005 07:51:16 +0000 Subject: [PATCH] - remob uses now two connections (spy/user), bug fixes --- remob.c | 278 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 177 insertions(+), 101 deletions(-) diff --git a/remob.c b/remob.c index a2628c4d..06531426 100644 --- a/remob.c +++ b/remob.c @@ -26,19 +26,23 @@ M. Zolliker July 04 /*------------------------------------------------------------------------ */ typedef struct Remob Remob; +typedef struct RemChannel { + mkChannel *chan; + int timeout; + int incomplete; + char line[256]; +} RemChannel; + typedef struct RemServer { pObjectDescriptor desc; char *name; char *host; int port; - int actChan; /* 0 or 1 */ - mkChannel *chans[2]; /* 0: Spy, 1: User */ - int incomplete; - char line[256]; + RemChannel rc[2]; Remob *objList; int matchMap; - int timeout; int taskActive; + int interestActive; SCStore conn; } RemServer; @@ -80,14 +84,12 @@ static char *StartsWith(char *line, char *name) { return str; } /*-------------------------------------------------------------------------*/ -static int RemWrite(RemServer *remserver, char *line) { +static int RemWrite(RemChannel *rc, char *line) { int iret; - mkChannel *chan; - chan = remserver->chans[remserver->actChan]; - if (chan) { + if (rc->chan) { /* printf("> %s\n", line); */ - iret = NETWrite(chan, line, strlen(line)); + iret = NETWrite(rc->chan, line, strlen(line)); if (iret == 0) iret = -1; return iret; } else { @@ -95,19 +97,17 @@ static int RemWrite(RemServer *remserver, char *line) { } } /*-------------------------------------------------------------------------*/ -static int RemRead(RemServer *remserver, long tmo) { +static int RemRead(RemChannel *rc, long tmo) { int iRet; - mkChannel *chan; - chan = remserver->chans[remserver->actChan]; - if (chan == NULL) return 0; /* no data */ - iRet = NETReadTillTermNew(chan, tmo, "\n", - remserver->line+remserver->incomplete, sizeof(remserver->line)-remserver->incomplete); + if (rc->chan == NULL) return 0; /* no data */ + iRet = NETReadTillTermNew(rc->chan, tmo, "\n", rc->line + rc->incomplete, + sizeof(rc->line) - rc->incomplete); if (iRet == 0) { - remserver->incomplete = strlen(remserver->line); /* number of chars already received */ + rc->incomplete = strlen(rc->line); /* number of chars already received */ return 0; /* timeout */ } else { - remserver->incomplete=0; + rc->incomplete=0; } return iRet; } @@ -115,16 +115,21 @@ static int RemRead(RemServer *remserver, long tmo) { static int RemHandle(RemServer *remserver) { char *line, *par, *str; Remob *remob; + RemChannel *rc; + + rc = &remserver->rc[0]; /* drivstat messages appear only on the spy channel */ /* skip whitespace at the beginning */ - line=remserver->line; + line=rc->line; + if (line[0] == '\0') return 0; /* return when line is empty */ while (*line < ' ' && *line != '\0') { line++; } - memmove(remserver->line, line, strlen(line)); + memmove(rc->line, line, strlen(line)); /* handle drivstat messages */ - line = remserver->line; + line = rc->line; + for (remob = remserver->objList; remob != NULL; remob = remob->next) { par=StartsWith(line, remob->name); if (par != NULL) { @@ -147,51 +152,74 @@ static int RemHandle(RemServer *remserver) { return 0; } /*-------------------------------------------------------------------------*/ -static void RemCopy(RemServer *remserver, SConnection *pCon) { - if (pCon != NULL && remserver->line[0] != '\0') { - SCPrintf(pCon, eStatus, " %s", remserver->line); +static void RemCopy(RemChannel *rc, SConnection *pCon) { + if (pCon != NULL && rc->line[0] != '\0') { + SCPrintf(pCon, eStatus, " %s", rc->line); } } /*-------------------------------------------------------------------------*/ static void RemDisconnect(RemServer *remserver) { - int i; + int isUser; + RemChannel *rc; - for (i=0; i<2; i++) { - if (remserver->chans[i] != NULL) { - NETClosePort(remserver->chans[i]); - free(remserver->chans[i]); - remserver->chans[i]=NULL; + for (isUser=0; isUser<=1; isUser++) { + rc = &remserver->rc[isUser]; + if (rc->chan != NULL) { + NETClosePort(rc->chan); + free(rc->chan); + rc->chan = NULL; /* printf("disconnected\n"); */ } } } /*-------------------------------------------------------------------------*/ -static void RemConnect(RemServer *remserver) { +static int RemSetInterest(RemChannel *rc) { + int iRet; + + if (rc->chan != NULL) { /* already connected */ + iRet = RemWrite(rc, "transact listexe interest\n"); + if (iRet >= 0) { + iRet = RemRead(rc, 1000); + while (iRet > 0) { /* eat response */ + if (StartsWith(rc->line, "TRANSACTIONFINISHED")) { + return 1; + } + iRet = RemRead(rc, 1000); + } + } + } + return 0; +} +/*-------------------------------------------------------------------------*/ +static void RemConnect(RemServer *remserver, RemChannel *rc) { + /* open channel rc, if not yet opened */ int iRet; char buf[256]; mkChannel *chan; - chan = remserver->chans[remserver->actChan]; - if (!chan) { - remserver->timeout = 0; + if (!rc->chan) { + rc->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"); + rc->chan = chan; + if (rc != &remserver->rc[0]) { /* open the user channel */ + iRet = RemWrite(rc, "remuser sesam\n"); + } else { /* open spy channel */ + iRet = RemWrite(rc, "Spy 007\n"); } if (iRet < 0) goto close; - iRet = RemRead(remserver, 1000); + iRet = RemRead(rc, 1000); while (iRet > 0) { /* eat login response */ - if (StartsWith(remserver->line, "TRANSACTIONFINISHED")) { + if (StartsWith(rc->line, "Login OK")) { /* printf("connected\n"); */ + if (remserver->interestActive && rc == &remserver->rc[0]) { /* open the user channel */ + if (!RemSetInterest(rc)) goto close; + } return; } - iRet = RemRead(remserver, 1000); + iRet = RemRead(rc, 1000); } goto close; } @@ -205,25 +233,34 @@ static int RemServerTask(void *data) { RemServer *remserver=data; int iRet; SConnection *pCon; + int isUser; + RemChannel *rc; if (!remserver->taskActive) return 0; /* remove task */ - if (RemRead(remserver, 0) <= 0) return 1; /* continue */ + + for (isUser = 0; isUser <= 1; isUser++) { + rc = &remserver->rc[isUser]; + if (RemRead(rc, 0) <= 0) continue; - /* printf("< %s\n", buf); */ + /* printf("< %s\n", buf); */ - if (RemHandle(remserver)) { /* handle drivstat messages */ - return 1; - } + if (isUser == 0) { + if (RemHandle(remserver)) { /* handle drivstat messages */ + continue; + } + } - /* forward oll other messages */ - pCon = SCLoad(&remserver->conn); - if (pCon) { - RemCopy(remserver, pCon); + /* forward all other messages */ + pCon = SCLoad(&remserver->conn); + if (pCon) { + RemCopy(rc, pCon); + } } return 1; } /*-------------------------------------------------------------------------*/ -static int RemTransact(RemServer *remserver, SConnection *pCon, char *cmd, ...) { +static int RemTransact(RemServer *remserver, RemChannel *rc, SConnection *pCon, + char *cmd, ...) { /* the variable arguments are for filtering: "timeout) { /* eat old responses */ - while (RemRead(remserver, 0) > 0) { + if (rc->timeout) { /* eat old responses */ + while (RemRead(rc, 0) > 0) { RemHandle(remserver); } } @@ -249,13 +286,13 @@ tryagain: strcpy(buf, "transact "); strcat(buf, cmd); strcat(buf,"\n"); - RemConnect(remserver); - iRet = RemWrite(remserver, buf); + RemConnect(remserver, rc); + iRet = RemWrite(rc, buf); if (iRet < 0) goto close; - iRet = RemRead(remserver, 2000); + iRet = RemRead(rc, 2000); if (iRet <= 0) goto close; - while (!StartsWith(remserver->line, "TRANSACTIONFINISHED")) { + while (!StartsWith(rc->line, "TRANSACTIONFINISHED")) { RemHandle(remserver); va_start(ap, cmd); arg = va_arg(ap, char *); @@ -263,10 +300,10 @@ tryagain: remserver->matchMap = 0; while (arg != NULL) { if (*arg == '>') { - RemCopy(remserver, pCon); + RemCopy(rc, pCon); } else if (*arg == '<') { f = va_arg(ap, float *); - val = StartsWith(remserver->line, arg+1); + val = StartsWith(rc->line, arg+1); if (val != NULL) { val = StartsWith(val, "="); if (val != NULL) { @@ -275,7 +312,7 @@ tryagain: } } } else if (*arg == '!') { - if (StartsWith(remserver->line, arg+1)) { + if (StartsWith(rc->line, arg+1)) { remserver->matchMap |= argMask; argMask = argMask*2; break; @@ -287,7 +324,7 @@ tryagain: arg = va_arg(ap, char *); } va_end(ap); - iRet = RemRead(remserver, 2000); + iRet = RemRead(rc, 2000); if (iRet <= 0) goto close; } return 1; @@ -295,7 +332,7 @@ close: if (iRet == 0) { snprintf(buf, sizeof(buf), "ERROR: timeout on %s", remserver->name); SCWrite(pCon,buf,eError); - remserver->timeout = 1; + rc->timeout = 1; return iRet; } RemDisconnect(remserver); @@ -320,14 +357,14 @@ static void *RemobGetInterface(void *pData, int iID) { /*------------------------------------------------------------------------*/ static int RemobHalt(void *self) { Remob *remob=self; - RemServer *remserver; + RemServer *remserver = remob->server; + RemChannel *rc = &remserver->rc[1]; /* Halt is only called with at least user priv. */ char buf[64]; assert(remob); - remserver = remob->server; - RemConnect(remserver); + RemConnect(remserver, rc); snprintf(buf, sizeof(buf), "stopexe %s\n", remob->name); - return RemWrite(remserver, buf); + return RemWrite(rc, buf); } /*--------------------------------------------------------------------------*/ @@ -336,23 +373,25 @@ static int RemobLimits(void *self, float fVal, char *error, int iErrLen) { Remob *remob=self; assert(remob); - /* check is done one remote server */ + /* check is done on remote server */ return 1; } /*---------------------------------------------------------------------------*/ static float RemobGetValue(void *pData, SConnection *pCon) { Remob *remob=pData; + RemServer *remserver = remob->server; char buf[80]; float none, value; int iRet; assert(remob); - SCSave(&remob->server->conn, pCon); + SCSave(&remserver->conn, pCon); none = -1.25e6; value= none; snprintf(buf, sizeof(buf), "<%s", remob->name); - iRet = RemTransact(remob->server, pCon, remob->name, buf, &value, ">", NULL); + /* get value needs only spy priviledge */ + iRet = RemTransact(remserver, &remserver->rc[0], pCon, remob->name, buf, &value, ">", NULL); if (iRet <= 0) { return 0.0; } @@ -384,7 +423,11 @@ static int RemServerSaveStatus(void *pData, char *name, FILE *fil) { assert(fil); for (remob = remserver->objList; remob != NULL; remob = remob->next) { - fprintf(fil, "catch { remob new %s %s }\n", remob->name, remserver->name); + if (remob->pDrivInt) { + fprintf(fil, "catch { remob drv %s %s }\n", remob->name, remserver->name); + } else { + fprintf(fil, "catch { remob obj %s %s }\n", remob->name, remserver->name); + } } return 1; } @@ -408,30 +451,46 @@ static long RemobRun(void *self, SConnection *pCon, float fNew) { RemServer *remserver; long lTime; float fDelta; + int rights; + RemChannel *rc; remserver = remob->server; SCSave(&remserver->conn, pCon); assert(remob); assert(pCon); + rights = SCGetRights(pCon); + rc = &remserver->rc[rights <= usUser]; + RemConnect(remserver, &remserver->rc[0]); /* connect spy for listexe interest */ + remob->status = HWIdle; snprintf(buf, sizeof(buf), "run %s %f", remob->name, fNew); - iRet = RemTransact(remserver, pCon, buf, "!ERROR: somebody else", "!ERROR: cannot", ">", NULL); + iRet = RemTransact(remserver, rc, pCon, buf, "!ERROR: somebody else", "!ERROR: cannot", ">", NULL); if (iRet <= 0) return 0; if (remserver->matchMap & 1) { /* already running, stop first */ remob->status = HWBusy; snprintf(sBuf, sizeof(sBuf), "stopexe %s", remob->name); - iRet = RemTransact(remserver, pCon, sBuf, ">", NULL); + iRet = RemTransact(remserver, rc, pCon, sBuf, ">", NULL); if (iRet <= 0) return 0; while (remob->status == HWBusy) { - iRet = RemRead(remserver, 1000); + iRet = RemRead(rc, 1000); if (iRet <= 0) break; - RemCopy(remserver, pCon); + if (! RemHandle(remserver)) { + RemCopy(rc, pCon); + } } - iRet = RemTransact(remserver, pCon, buf, ">", NULL); + iRet = RemTransact(remserver, rc, pCon, buf, ">", NULL); if (iRet <= 0) return 0; } + /* wait for "started" message */ + while (remob->status != HWBusy) { + iRet = RemRead(&remserver->rc[0], 1000); + if (iRet <= 0) break; + if (! RemHandle(remserver)) { + RemCopy(&remserver->rc[0], pCon); + } + } if (remob->status != HWBusy) { return 0; } @@ -464,6 +523,7 @@ static int InterestCallback(int iEvent, void *pEvent, void *pUser) { int RemobAction(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) { Remob *remob = pData; + RemServer *remserver = remob->server; char buf[512]; TokenList *pList = NULL; TokenList *pCurrent; @@ -475,19 +535,20 @@ int RemobAction(SConnection *pCon, SicsInterp *pSics, void *pData, long lID; char *endp; char acce[128], inte[128]; + int rights; + RemChannel *rc; assert(pCon); assert(pSics); assert(remob); - if (SCGetRights(pCon) > usUser) { - remob->server->actChan = 0; - } else { - remob->server->actChan = 1; + rights = SCGetRights(pCon); + rc = &remserver->rc[rights <= usUser]; + if (rights >= usUser) { + SCSave(&remserver->conn, pCon); } - SCSave(&remob->server->conn, pCon); if (argc == 1) { - iRet = RemTransact(remob->server, pCon, argv[0], ">", NULL); + iRet = RemTransact(remserver, rc, pCon, argv[0], ">", NULL); } else if (strcasecmp(argv[1],"list") == 0) { snprintf(buf, sizeof(buf), "%s ", remob->name); i = strlen(buf); @@ -497,7 +558,7 @@ int RemobAction(SConnection *pCon, SicsInterp *pSics, void *pData, snprintf(inte, sizeof(inte), "!%s.interruptmode", remob->name); */ - RemTransact(remob->server, pCon, buf, ">", NULL); + RemTransact(remserver, rc, pCon, buf, ">", NULL); iRet=1; } else { @@ -505,7 +566,7 @@ int RemobAction(SConnection *pCon, SicsInterp *pSics, void *pData, for (i=1; iserver, pCon, buf, ">", NULL); + iRet = RemTransact(remserver, rc, pCon, buf, ">", NULL); } return iRet; } @@ -562,25 +623,25 @@ int RemServerAction(SConnection *pCon, SicsInterp *pSics, void *pData, char acce[128], inte[128]; struct sockaddr_in adr; struct hostent *thishost; - mkChannel *chan; Remob *p, *next; + int rights; + RemChannel *rc; assert(pCon); assert(pSics); assert(remserver); - if (SCGetRights(pCon) > usUser) { - remserver->actChan = 0; - } else { - remserver->actChan = 1; + rights = SCGetRights(pCon); + rc = &remserver->rc[rights <= usUser]; + if (rights >= usUser) { + SCSave(&remserver->conn, pCon); } - 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) { + if (rc->chan) { + if (getsockname(rc->chan->sockid, (void *)&adr, &i) >= 0) { thishost = gethostbyaddr((char *)&adr.sin_addr, sizeof adr.sin_addr, AF_INET); if (thishost) { @@ -592,14 +653,14 @@ int RemServerAction(SConnection *pCon, SicsInterp *pSics, void *pData, 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); + RemConnect(remserver, rc); for (i=2; i2) { - RemWrite(remserver, " "); + RemWrite(rc, " "); } - RemWrite(remserver, argv[i]); + RemWrite(rc, argv[i]); } - RemWrite(remserver, "\n"); + RemWrite(rc, "\n"); } else if (argc==2 && strcasecmp(argv[1],"markForDel") == 0) { p = remserver->objList; while (p) { @@ -624,7 +685,7 @@ int RemServerAction(SConnection *pCon, SicsInterp *pSics, void *pData, for (i=1; i", NULL); + iRet = RemTransact(remserver, rc, pCon, buf, ">", NULL); return iRet; } return 1; @@ -655,6 +716,8 @@ static void RemServerKill(void *self) { } /*-----------------------------------------------------------------------*/ static int RemobSetDriveable(Remob *remob, int driveable) { + RemChannel *rc; + if (driveable) { /* initialise Drivable interface */ remob->pDrivInt = CreateDrivableInterface(); @@ -664,6 +727,13 @@ static int RemobSetDriveable(Remob *remob, int driveable) { remob->pDrivInt->CheckStatus = RemobStatus; remob->pDrivInt->GetValue = RemobGetValue; remob->pDrivInt->Halt = RemobHalt; + if (remob->server->interestActive == 0) { + rc = &remob->server->rc[0]; + remob->server->interestActive = 1; + if (! RemSetInterest(rc)) { + RemDisconnect(remob->server); /* disconnect on error, RemSetInterest will be called again on connect */ + } + } } else if (remob->pDrivInt) { free(remob->pDrivInt); remob->pDrivInt = NULL; @@ -715,7 +785,9 @@ killit: /*-----------------------------------------------------------------------*/ static RemServer *RemServerInit(char *name, char *host, int port) { RemServer *remserver = NULL; - + RemChannel *rc; + int isUser; + assert(name); remserver = calloc(1, sizeof(RemServer)); @@ -733,10 +805,13 @@ static RemServer *RemServerInit(char *name, char *host, int port) { remserver->name = strdup(name); remserver->host = strdup(host); remserver->port = port; - remserver->incomplete = 0; + for (isUser=0; isUser <= 1; isUser++) { + rc = &remserver->rc[isUser]; + rc->incomplete = 0; + rc->chan = NULL; + rc->timeout = 0; + } remserver->objList = NULL; - remserver->chans[0] = NULL; - remserver->chans[1] = NULL; if (!remserver->name || !remserver->host || !remserver->port) { @@ -745,6 +820,7 @@ static RemServer *RemServerInit(char *name, char *host, int port) { return NULL; } remserver->taskActive = 1; + remserver->interestActive = 0; TaskRegister(pServ->pTasker, RemServerTask, NULL, RemServerKill, remserver, 1); return remserver; }