- added new scriptcontext with devser

This commit is contained in:
zolliker
2008-05-14 14:23:16 +00:00
parent bbb0b971a9
commit 3967dc8844
28 changed files with 1307 additions and 1363 deletions

20
ascon.c
View File

@ -52,7 +52,9 @@ static int CreateSocketAdress(
double DoubleTime(void) { double DoubleTime(void) {
struct timeval now; struct timeval now;
/* the resolution of this function is usec, if the machine supports this
and the mantissa of a double is 51 bits or more (31 for sec and 20 for micro)
*/
gettimeofday(&now, NULL); gettimeofday(&now, NULL);
return now.tv_sec + now.tv_usec / 1e6; return now.tv_sec + now.tv_usec / 1e6;
} }
@ -128,6 +130,7 @@ void AsconStdInit(Ascon *a, char *hostport) {
a->fd = -1; a->fd = -1;
a->state = AsconConnectStart; a->state = AsconConnectStart;
a->timeout = 2.0; /* sec */ a->timeout = 2.0; /* sec */
a->reconnectInterval = 10;
a->hostport = strdup(hostport); a->hostport = strdup(hostport);
} }
@ -399,6 +402,9 @@ Ascon *AsconMake(SConnection *con, int argc, char *argv[]) {
a->wrBuffer = CreateDynString(60, 63); a->wrBuffer = CreateDynString(60, 63);
a->errList.head = NULL; a->errList.head = NULL;
a->responseValid = 0; a->responseValid = 0;
a->timeout = 2.0;
a->reconnectInterval = 10;
a->lastReconnect = 0;
return a; return a;
} }
@ -417,8 +423,9 @@ void AsconKill(Ascon *a) {
} }
AsconStatus AsconTask(Ascon *a) { AsconStatus AsconTask(Ascon *a) {
a->handler(a); double now;
while (1) {
while (a->handler(a)) {
switch (a->state) { switch (a->state) {
case AsconReading: case AsconReading:
case AsconWriting: case AsconWriting:
@ -448,6 +455,11 @@ AsconStatus AsconTask(Ascon *a) {
return AsconPending; return AsconPending;
case AsconFailed: case AsconFailed:
if (a->state <= AsconConnectFailed) { if (a->state <= AsconConnectFailed) {
now = DoubleTime();
if (now > a->lastReconnect + a->reconnectInterval) {
a->lastReconnect = now;
a->state = AsconConnectStart;
}
return AsconUnconnected; return AsconUnconnected;
} }
return AsconFailure; return AsconFailure;
@ -458,8 +470,8 @@ AsconStatus AsconTask(Ascon *a) {
return AsconReady; return AsconReady;
} }
} }
a->handler(a);
} }
return AsconIdle;
} }
int AsconWrite(Ascon *a, char *command, int noResponse) { int AsconWrite(Ascon *a, char *command, int noResponse) {

View File

@ -1,6 +1,7 @@
#ifndef ASCON_H #ifndef ASCON_H
#define ASCON_H #define ASCON_H
#include "sics.h"
#include "errormsg.h" #include "errormsg.h"
/** \file /** \file
@ -42,7 +43,7 @@ void AsconKill(Ascon *a);
*/ */
AsconStatus AsconTask(Ascon *a); AsconStatus AsconTask(Ascon *a);
/** \brief write to the connection. allowed only when the state is ascon_ready /** \brief write to the connection. allowed only when the state is AsconReady
* \param a the connection * \param a the connection
* \param command the command to be sent * \param command the command to be sent
* \param noResponse 0 normally, 1 if no reponse is expected * \param noResponse 0 normally, 1 if no reponse is expected

View File

@ -62,7 +62,7 @@ struct Ascon {
pDynString rdBuffer;/**< read buffer */ pDynString rdBuffer;/**< read buffer */
pDynString wrBuffer;/**< write buffer */ pDynString wrBuffer;/**< write buffer */
int wrPos; /**< write buffer position */ int wrPos; /**< write buffer position */
float timeout; /**< read timeout (sec) */ double timeout; /**< read timeout (sec) */
char *hostport; /**< host:port to connect */ char *hostport; /**< host:port to connect */
ErrMsgList errList; /**< error message list */ ErrMsgList errList; /**< error message list */
double start; /**< unix time when read was started */ double start; /**< unix time when read was started */
@ -70,6 +70,8 @@ struct Ascon {
int noResponse; /**< no response expected */ int noResponse; /**< no response expected */
int responseValid; /**< a valid response is ready */ int responseValid; /**< a valid response is ready */
AsconHandler handler; /**< handler function */ AsconHandler handler; /**< handler function */
double reconnectInterval; /**< reconnect interval */
double lastReconnect; /**< last connect try */
}; };
#define ASCON_SELECT_ERROR -1 #define ASCON_SELECT_ERROR -1

View File

@ -2230,7 +2230,7 @@ int SCActive(SConnection *self)
return 0; return 0;
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
SCStore SCSave(SConnection *pCon, SCStore oldStore) { SCStore *SCSave(SConnection *pCon, SCStore *oldStore) {
commandContext cc; commandContext cc;
if (oldStore == NULL) { if (oldStore == NULL) {
@ -2247,7 +2247,7 @@ SCStore SCSave(SConnection *pCon, SCStore oldStore) {
return oldStore; return oldStore;
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
SConnection *SCLoad(SCStore conStore) { SConnection *SCLoad(SCStore *conStore) {
SConnection *pCon = NULL; SConnection *pCon = NULL;
commandContext old; commandContext old;
@ -2266,7 +2266,7 @@ SConnection *SCLoad(SCStore conStore) {
return pServ->dummyCon; return pServ->dummyCon;
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
SConnection *SCStorePush(SCStore conStore) { SConnection *SCStorePush(SCStore *conStore) {
SConnection *pCon; SConnection *pCon;
pCon = SCLoad(conStore); pCon = SCLoad(conStore);
@ -2281,7 +2281,7 @@ SConnection *SCStorePush(SCStore conStore) {
return pCon; return pCon;
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
void SCStorePop(SCStore conStore) { void SCStorePop(SCStore *conStore) {
SConnection *pCon; SConnection *pCon;
pCon = SCLoad(conStore); pCon = SCLoad(conStore);
@ -2294,13 +2294,13 @@ void SCStorePop(SCStore conStore) {
} }
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
int SCStoreConnected(SCStore conStore) { int SCStoreConnected(SCStore *conStore) {
return (conStore && return (conStore &&
conStore->pCon && conStore->pCon &&
conStore->pCon->ident == conStore->ident); conStore->pCon->ident == conStore->ident);
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
void SCStoreFree(SCStore conStore) { void SCStoreFree(SCStore *conStore) {
free(conStore); free(conStore);
} }
/* --------------------------------------------------------------------------*/ /* --------------------------------------------------------------------------*/

View File

@ -168,24 +168,24 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
int ConSicsAction(SConnection *pCon, SicsInterp *pSics, void *pData, int ConSicsAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]); int argc, char *argv[]);
/******************************** Store ************************************/ /******************************** Store ************************************/
typedef struct SCStore *SCStore; typedef struct SCStore SCStore;
SCStore SCSave(SConnection *pCon, SCStore oldStore); SCStore *SCSave(SConnection *pCon, SCStore *oldStore);
/* save a connection and its context for later use. */ /* save a connection and its context for later use. */
SConnection *SCLoad(SCStore conStore); SConnection *SCLoad(SCStore *conStore);
/* check con and return SConnection if still valid or a dummy connection otherwise. */ /* check con and return SConnection if still valid or a dummy connection otherwise. */
SConnection *SCStorePush(SCStore conStore); SConnection *SCStorePush(SCStore *conStore);
/* load connection and push stored context. Must be paired with an SCStorePop command */ /* load connection and push stored context. Must be paired with an SCStorePop command */
void SCStorePop(SCStore conStore); void SCStorePop(SCStore *conStore);
/* pop context */ /* pop context */
int SCStoreConnected(SCStore conStore); int SCStoreConnected(SCStore *conStore);
/* check if a stored connection is not closed */ /* check if a stored connection is not closed */
void SCStoreFree(SCStore conStore); void SCStoreFree(SCStore *conStore);
/* free an SCStore */ /* free an SCStore */
void KillFreeConnections(void); void KillFreeConnections(void);

301
devser.c Normal file
View File

@ -0,0 +1,301 @@
#include <math.h>
#include "ascon.h"
#include "devser.h"
typedef struct DevAction {
struct DevAction *next;
void *data;
DevActionHandler *hdl;
DevPrio prio;
DevKillActionData *kill;
} DevAction;
typedef struct SchedHeader {
struct SchedHeader *next;
DevAction *actions; /* list of actions for given interval and prio */
DevAction *followingAction;
double interval;
double timeDue;
DevPrio prio;
} SchedHeader;
struct DevSer {
Ascon *asyncConn; /* connection */
DevAction *current;
int killCurrent;
DevAction *actions; /* the action queue */
SchedHeader *headers;
int killMe;
int steps;
};
static char *devPrio[NumberOfPRIO] = {
"null", "slow", "read", "progress", "write", "halt"
};
char *DevPrio2Text(DevPrio prio) {
if (prio <= 0 || prio >= NumberOfPRIO) {
prio = NullPRIO;
}
return devPrio[prio];
}
DevPrio DevText2Prio(char *text) {
DevPrio prio;
for (prio = 0; prio < NumberOfPRIO; prio++) {
if (strcasecmp(text, devPrio[prio]) == 0) return prio;
}
return NullPRIO;
}
static void DevFreeActionList(DevAction *actions) {
DevAction *victim;
while (actions != NULL) {
victim = actions;
actions = victim->next;
if (victim->kill != NULL) victim->kill(victim->data);
free(victim);
}
}
static void DevKillTask(void *devser) {
free(devser);
}
DevAction *DevNextAction(DevSer *devser) {
DevPrio prio;
double now;
SchedHeader *header;
devser->current = NULL;
if (devser->actions) {
prio = devser->actions->prio;
} else {
prio = NullPRIO;
}
now = DoubleTime();
for (header = devser->headers;
header != NULL && header->prio > prio;
header = header->next) {
if (header->followingAction == NULL) {
if (now >= header->timeDue) {
header->followingAction = header->actions;
header->timeDue = (floor(now / header->interval) + 1)
* header->interval;
}
}
if (header->followingAction != NULL) {
devser->current = header->followingAction;
devser->killCurrent = 0;
header->followingAction = header->followingAction->next;
return devser->current;
}
}
if (devser->actions) {
devser->current = devser->actions;
devser->killCurrent = 1;
devser->actions = devser->actions->next;
}
return devser->current;
}
int DevQueueTask(void *ds) {
DevSer *devser = ds;
AsconStatus status;
DevAction *action;
char *sendData;
char *replyData;
if (devser->steps == 0) return 1;
if (devser->killMe) {
return 0;
}
action = devser->current;
if (action == NULL) {
action = DevNextAction(devser);
}
while (action != NULL) {
status = AsconTask(devser->asyncConn);
if (status == AsconFailure) {
/* TODO: error handling */
} else if (status != AsconReady) {
return 1;
}
if (devser->steps > 0) { /* debugging mode */
devser->steps--;
}
replyData = AsconRead(devser->asyncConn);
sendData = action->hdl(action->data, replyData);
if (sendData != NULL) {
AsconWrite(devser->asyncConn, sendData, 0);
return 1;
}
if (devser->killCurrent) {
if (action->kill != NULL) action->kill(action->data);
devser->killCurrent = 0;
free(action);
devser->current = NULL;
}
action = DevNextAction(devser);
}
return 1;
}
DevSer *DevMake(SConnection *con, int argc, char *argv[]) {
DevSer *devser;
Ascon *asyncConn;
asyncConn = AsconMake(con, argc, argv);
if (!asyncConn) {
return NULL;
}
devser = calloc(1, sizeof(*devser));
assert(devser);
devser->asyncConn = asyncConn;
devser->current = NULL;
devser->killCurrent = 0;
devser->actions = NULL;
devser->headers = NULL;
devser->killMe = 0;
devser->steps = -1; /* no debugging by default */
TaskRegister(pServ->pTasker, DevQueueTask, NULL, DevKillTask, devser, 0);
return devser;
}
void DevDebugMode(DevSer *devser, int steps) {
devser->steps = steps;
}
DevAction *DevNewAction(void *data, DevActionHandler hdl,
DevKillActionData *killFunc, DevPrio prio) {
DevAction *action;
action = calloc(1, sizeof(*action));
assert(action);
action->data = data;
action->hdl = hdl;
action->kill = killFunc;
action->prio = prio;
action->next = NULL;
return action;
}
void DevKill(DevSer *devser) {
SchedHeader *h, *victim;
if (devser->asyncConn) {
AsconKill(devser->asyncConn);
}
DevFreeActionList(devser->actions);
h = devser->headers;
while (h != NULL) {
victim = h;
h = victim->next;
DevFreeActionList(victim->actions);
free(victim);
}
devser->killMe = 1;
}
void DevQueue(DevSer *devser, void *actionData, DevPrio prio,
DevActionHandler hdl, DevActionMatch *matchFunc,
DevKillActionData *killFunc) {
DevAction *action, **ptr2Last;
DevAction *new;
if (prio <= NullPRIO) prio = NullPRIO + 1;
if (prio >= NumberOfPRIO) prio = NumberOfPRIO - 1;
ptr2Last = &devser->actions;
for (action = devser->actions; action != NULL && action->prio >= prio; action = action->next) {
if (matchFunc(actionData, action->data) && action->hdl == hdl) {
return; /* there is already an identic action */
}
ptr2Last = &action->next;
}
new = DevNewAction(actionData, hdl, killFunc, prio);
new->next = action;
*ptr2Last = new;
}
int DevUnschedule(DevSer *devser, void *actionData,
DevActionHandler hdl, DevActionMatch *matchFunc) {
SchedHeader *header = NULL;
DevAction **ptr2Last = NULL;
DevAction *action = NULL;
int cnt=0;
/* scan through all headers */
for (header = devser->headers; header != NULL; header = header->next) {
ptr2Last = &header->actions;
for (action = header->actions; action != NULL; action = *ptr2Last) {
if (matchFunc(actionData, action->data) && action->hdl == hdl) {
if (action == header->followingAction) {
/* advance followingAction if equal*/
header->followingAction = action->next;
}
cnt++;
/* remove from list */
*ptr2Last = action->next;
if (action->kill != NULL) action->kill(action->data);
free(action);
} else {
ptr2Last = &action->next;
}
}
}
return cnt;
}
void DevSchedule(DevSer *devser, void *actionData,
DevPrio prio, double interval,
DevActionHandler hdl, DevActionMatch *matchFunc,
DevKillActionData *killFunc) {
SchedHeader *header = NULL;
SchedHeader **ptr2LastHeader = NULL;
SchedHeader *newHeader;
DevAction *action = NULL;
DevAction **ptr2Last = NULL;
DevAction *newAction;
if (prio <= NullPRIO) prio = NullPRIO + 1;
if (prio >= NumberOfPRIO) prio = NumberOfPRIO - 1;
DevUnschedule(devser, actionData, hdl, matchFunc);
newAction = DevNewAction(actionData, hdl, killFunc, prio);
/* find matching header */
ptr2LastHeader = &devser->headers;
for (header = devser->headers; header != NULL; header = *ptr2LastHeader) {
if (header->prio == newAction->prio && header->interval == interval) {
/* append new action at the tail */
ptr2Last = &header->actions;
for (action = header->actions; action != NULL; action=action->next) {
ptr2Last = &action->next;
}
*ptr2Last = newAction;
assert(newAction->next == NULL);
return;
} else if (header->prio < newAction->prio ||
(header->prio == newAction->prio
&& header->interval > interval)) {
break;
}
if (header->actions == NULL) {
/* remove empty header */
*ptr2LastHeader = header->next;
free(header);
} else {
ptr2LastHeader = &header->next;
}
}
/* insert new header */
newHeader = calloc(1, sizeof(*newHeader));
assert(newHeader);
newHeader->actions = newAction;
newHeader->followingAction = NULL;
newHeader->prio = newAction->prio;
newHeader->interval = interval;
newHeader->next = header;
newHeader->timeDue = DoubleTime() + interval;
*ptr2LastHeader = newHeader;
return;
}

113
devser.h Normal file
View File

@ -0,0 +1,113 @@
#ifndef DEVSER_H
#define DEVSER_H
/** \file
* \brief Device Serializer
*/
typedef struct DevSer DevSer;
/** \brief The action handler to be called
* \param actionData the data stored with the action
* \param lastReply the last reply or NULL when no command was
* sent in the last action
* \return the command to be sent or NULL if no command has to be sent
*/
typedef char *DevActionHandler(void *actionData, char *lastReply);
/** \brief Check if two actions match
* \param actionData1 the first action data
* \param actionData2 the second action data
* \return 1 on a match, 0 on no match
*/
typedef int DevActionMatch(void *actionData1, void *actionData2);
/** \brief Kill ActionData
* \param actionData action data
*/
typedef void DevKillActionData(void *actionData);
/** \brief possible priorities.
* NullPRIO and NumberOfPRIO must not be used as priority
*/
typedef enum {
NullPRIO, SlowPRIO, ReadPRIO, ProgressPRIO, WritePRIO, HaltPRIO, NumberOfPRIO
} DevPrio;
/** \brief Make a new device serializer and async connection.
* \param con the SICS connection (for error messages)
* \param argc the number of args for specifying the protocol
* \param argv the args
* \return the created device serializer or NULL on failure
*/
DevSer *DevMake(SConnection *con, int argc, char *argv[]);
/** \brief put the device serializer into debug mode
* \param devser the device serializer
* \param steps the number of steps to be executed or -1 for disable debugging mode
*/
void DevDebugMode(DevSer *devser, int steps);
/** \brief Kill the device serializer and its async connection.
* \param devser the device serializer
*/
void DevKill(DevSer *devser);
/** \brief Queue an action
*
* If a matching action with the same action handler
* exists already, no new action is queued.
* \param devser the device serializer
* \param actionData the action data
* \param prio the priority
* \param hdl the action handler
* \param matchFunc the match function
* \param killFunc the action data kill function (called from DevKill and
* after the action has finished, i.e. when hdl returned NULL)
* or NULL if no kill function is needed.
*/
void DevQueue(DevSer *devser, void *actionData, DevPrio prio,
DevActionHandler hdl, DevActionMatch *matchFunc,
DevKillActionData *killFunc) ;
/** \brief Schedule a periodic action
*
* If a matching action exists already,
* it is overwritten with a possibly changed interval and priority.
* \param devser the device serializer
* \param actionData the action data
* \param prio the priority
* \param interval the interval in seconds (0 is allowed)
* \param hdl the action handler
* \param matchFunc the match function
* \param killFunc the action data kill function (called from DevKill and
* from DevUnschedule) or NULL if no kill function is needed.
*/
void DevSchedule(DevSer *devser, void *actionData,
DevPrio prio, double interval,
DevActionHandler hdl, DevActionMatch *matchFunc,
DevKillActionData *killFunc);
/** \brief Unschedule matching actions
* \param devser the device serializer
* \param actionData the action data to be compared for a match
* \param hdl the action handler
* \param matchFunc the match function
*/
int DevUnschedule(DevSer *devser, void *actionData,
DevActionHandler hdl, DevActionMatch *matchFunc);
/** \brief Convert integer priority to text
* \param prio
* \return text
*/
char *DevPrio2Text(DevPrio prio);
/** \brief Convert text priority to integer
* \param text
* \return prio
*/
DevPrio DevText2Prio(char *text);
#endif

View File

@ -376,7 +376,7 @@
} }
/*---------------------------- Error Handlers --------------------------------*/ /*---------------------------- Error Handlers --------------------------------*/
static void ErrWrite(char *txt, SCStore conn) static void ErrWrite(char *txt, SCStore *conn)
{ {
pExeList pExe; pExeList pExe;
SConnection *pCon = NULL; SConnection *pCon = NULL;

View File

@ -41,7 +41,7 @@
int iWarned; int iWarned;
int iTcl; int iTcl;
int iStop; int iStop;
SCStore conn; SCStore *conn;
char *creationArgs; char *creationArgs;
char *runScript; char *runScript;
void *pPrivate; void *pPrivate;

View File

@ -52,13 +52,13 @@ $\langle$evdata {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ int iWarned;@\\ \mbox{}\verb@ int iWarned;@\\
\mbox{}\verb@ int iTcl;@\\ \mbox{}\verb@ int iTcl;@\\
\mbox{}\verb@ int iStop;@\\ \mbox{}\verb@ int iStop;@\\
\mbox{}\verb@ SCStore conn;@\\ \mbox{}\verb@ SCStore *conn;@\\
\mbox{}\verb@ char *creationArgs;@\\ \mbox{}\verb@ char *creationArgs;@\\
\mbox{}\verb@ char *runScript;@\\ \mbox{}\verb@ char *runScript;@\\
\mbox{}\verb@ void *pPrivate;@\\ \mbox{}\verb@ void *pPrivate;@\\
\mbox{}\verb@ void (*KillPrivate)(void *pData);@\\ \mbox{}\verb@ void (*KillPrivate)(void *pData);@\\
\mbox{}\verb@ } EVControl;@\\ \mbox{}\verb@ } EVControl;@\\
\mbox{}\verb@@$\diamond$ \mbox{}\verb@@$\Diamond$
\end{list} \end{list}
\vspace{-1ex} \vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex} \footnotesize\addtolength{\baselineskip}{-1ex}
@ -123,7 +123,7 @@ $\langle$evdriv {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ void *pPrivate;@\\ \mbox{}\verb@ void *pPrivate;@\\
\mbox{}\verb@ void (*KillPrivate)(void *pData);@\\ \mbox{}\verb@ void (*KillPrivate)(void *pData);@\\
\mbox{}\verb@ } EVDriver;@\\ \mbox{}\verb@ } EVDriver;@\\
\mbox{}\verb@@$\diamond$ \mbox{}\verb@@$\Diamond$
\end{list} \end{list}
\vspace{-1ex} \vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex} \footnotesize\addtolength{\baselineskip}{-1ex}
@ -208,7 +208,7 @@ $\langle$dvfunc {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ int argc, char *argv[]);@\\ \mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@ @\\ \mbox{}\verb@ @\\
\mbox{}\verb@@\\ \mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$ \mbox{}\verb@@$\Diamond$
\end{list} \end{list}
\vspace{-1ex} \vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex} \footnotesize\addtolength{\baselineskip}{-1ex}
@ -286,7 +286,7 @@ See the documentation for commands understood.
\mbox{}\verb@#include "varlog.h"@\\ \mbox{}\verb@#include "varlog.h"@\\
\mbox{}\verb@@$\langle$dvfunc {\footnotesize ?}$\rangle$\verb@@\\ \mbox{}\verb@@$\langle$dvfunc {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#endif@\\ \mbox{}\verb@#endif@\\
\mbox{}\verb@@$\diamond$ \mbox{}\verb@@$\Diamond$
\end{list} \end{list}
\vspace{-2ex} \vspace{-2ex}
\end{minipage}\\[4ex] \end{minipage}\\[4ex]
@ -315,7 +315,7 @@ See the documentation for commands understood.
\mbox{}\verb@#define SETTLE 8@\\ \mbox{}\verb@#define SETTLE 8@\\
\mbox{}\verb@@\\ \mbox{}\verb@@\\
\mbox{}\verb@@$\langle$evdata {\footnotesize ?}$\rangle$\verb@@\\ \mbox{}\verb@@$\langle$evdata {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@$\diamond$ \mbox{}\verb@@$\Diamond$
\end{list} \end{list}
\vspace{-2ex} \vspace{-2ex}
\end{minipage}\\[4ex] \end{minipage}\\[4ex]
@ -340,7 +340,7 @@ See the documentation for commands understood.
\mbox{}\verb@/*-------------------- life & death of a driver --------------------------*/@\\ \mbox{}\verb@/*-------------------- life & death of a driver --------------------------*/@\\
\mbox{}\verb@ pEVDriver CreateEVDriver(int argc, char *argv[]);@\\ \mbox{}\verb@ pEVDriver CreateEVDriver(int argc, char *argv[]);@\\
\mbox{}\verb@ void DeleteEVDriver(pEVDriver pDriv);@\\ \mbox{}\verb@ void DeleteEVDriver(pEVDriver pDriv);@\\
\mbox{}\verb@@$\diamond$ \mbox{}\verb@@$\Diamond$
\end{list} \end{list}
\vspace{-2ex} \vspace{-2ex}
\end{minipage}\\[4ex] \end{minipage}\\[4ex]

View File

@ -47,7 +47,7 @@ used by EVControl:
int iWarned; int iWarned;
int iTcl; int iTcl;
int iStop; int iStop;
SCStore conn; SCStore *conn;
char *creationArgs; char *creationArgs;
char *runScript; char *runScript;
void *pPrivate; void *pPrivate;

View File

@ -593,13 +593,13 @@ int GenControllerFactory(SConnection *pCon, SicsInterp *pSics,
pNew->KillPrivate = killGeneric; pNew->KillPrivate = killGeneric;
textValue = MakeHdbText("Undefined"); textValue = MakeHdbText("Undefined");
funcValue = makeHdbData(HIPFUNC,1,EnqueFunc); funcValue = MakeHdbFunc((voidFunc *)EnqueFunc);
node = MakeSICSHdbPar("enqueue",usUser, funcValue); node = MakeSICSHdbPar("enqueue",usUser, funcValue);
AddSICSHdbPar(node,"node",usUser,textValue); AddSICSHdbPar(node,"node",usUser,textValue);
AppendHipadabaCallback(node,MakeSICSFuncCallback(pNew)); AppendHipadabaCallback(node,MakeSICSFuncCallback(pNew));
AddHipadabaChild(pNew->objectNode,node,NULL); AddHipadabaChild(pNew->objectNode,node,NULL);
funcValue = makeHdbData(HIPFUNC,1,EnqueHeadFunc); funcValue = MakeHdbFunc((voidFunc *)EnqueHeadFunc);
node = MakeSICSHdbPar("enqueuehead",usUser, funcValue); node = MakeSICSHdbPar("enqueuehead",usUser, funcValue);
AddSICSHdbPar(node,"node",usUser,textValue); AddSICSHdbPar(node,"node",usUser,textValue);
AppendHipadabaCallback(node,MakeSICSFuncCallback(pNew)); AppendHipadabaCallback(node,MakeSICSFuncCallback(pNew));

View File

@ -425,52 +425,52 @@ static void Configure(pSICSOBJ self){
n = MakeHipadabaNode("queue",HIPNONE,1); n = MakeHipadabaNode("queue",HIPNONE,1);
AddHipadabaChild(obj,n, NULL); AddHipadabaChild(obj,n, NULL);
funcValue = makeHdbData(HIPFUNC,1,EnqueFunc); funcValue = MakeHdbFunc((voidFunc *)EnqueFunc);
n = MakeSICSHdbPar("enqueue",usUser, funcValue); n = MakeSICSHdbPar("enqueue",usUser, funcValue);
AddSICSHdbPar(n,"description",usUser,textValue); AddSICSHdbPar(n,"description",usUser,textValue);
AddHipadabaChild(obj,n,NULL); AddHipadabaChild(obj,n,NULL);
AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self)); AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self));
funcValue = makeHdbData(HIPFUNC,1,AddCmdData); funcValue = MakeHdbFunc((voidFunc *)AddCmdData);
n = MakeSICSHdbPar("addcommand",usUser, funcValue); n = MakeSICSHdbPar("addcommand",usUser, funcValue);
AddSICSHdbPar(n,"command",usUser,textValue); AddSICSHdbPar(n,"command",usUser,textValue);
AddHipadabaChild(obj,n,NULL); AddHipadabaChild(obj,n,NULL);
AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self)); AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self));
funcValue = makeHdbData(HIPFUNC,1,Dequeue); funcValue = MakeHdbFunc((voidFunc *)Dequeue);
n = MakeSICSHdbPar("dequeue",usUser,funcValue); n = MakeSICSHdbPar("dequeue",usUser,funcValue);
AddHipadabaChild(obj,n,NULL); AddHipadabaChild(obj,n,NULL);
AddSICSHdbPar(n,"index",usUser,intValue); AddSICSHdbPar(n,"index",usUser,intValue);
AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self)); AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self));
funcValue = makeHdbData(HIPFUNC,1,Clean); funcValue = MakeHdbFunc((voidFunc *)Clean);
n = MakeSICSHdbPar("clean",usUser, funcValue); n = MakeSICSHdbPar("clean",usUser, funcValue);
AddHipadabaChild(obj,n,NULL); AddHipadabaChild(obj,n,NULL);
AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self)); AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self));
funcValue = makeHdbData(HIPFUNC,1,CleanAll); funcValue = MakeHdbFunc((voidFunc *)CleanAll);
n = MakeSICSHdbPar("cleanall",usUser, funcValue); n = MakeSICSHdbPar("cleanall",usUser, funcValue);
AddHipadabaChild(obj,n,NULL); AddHipadabaChild(obj,n,NULL);
AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self)); AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self));
funcValue = makeHdbData(HIPFUNC,1,Start); funcValue = MakeHdbFunc((voidFunc *)Start);
n = MakeSICSHdbPar("start",usUser, funcValue); n = MakeSICSHdbPar("start",usUser, funcValue);
AddHipadabaChild(obj,n,NULL); AddHipadabaChild(obj,n,NULL);
AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self)); AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self));
funcValue = makeHdbData(HIPFUNC,1,Restart); funcValue = MakeHdbFunc((voidFunc *)Restart);
n = MakeSICSHdbPar("restart",usUser, funcValue); n = MakeSICSHdbPar("restart",usUser, funcValue);
AddHipadabaChild(obj,n,NULL); AddHipadabaChild(obj,n,NULL);
AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self)); AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self));
funcValue = makeHdbData(HIPFUNC,1,Stop); funcValue = MakeHdbFunc((voidFunc *)Stop);
n = MakeSICSHdbPar("stop",usUser, funcValue); n = MakeSICSHdbPar("stop",usUser, funcValue);
AddHipadabaChild(obj,n,NULL); AddHipadabaChild(obj,n,NULL);
AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self)); AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self));
funcValue = makeHdbData(HIPFUNC,1,Move); funcValue = MakeHdbFunc((voidFunc *)Move);
n = MakeSICSHdbPar("move",usUser,funcValue); n = MakeSICSHdbPar("move",usUser,funcValue);
AddHipadabaChild(obj,n,NULL); AddHipadabaChild(obj,n,NULL);
AddSICSHdbPar(n,"moveindex",usUser,intValue); AddSICSHdbPar(n,"moveindex",usUser,intValue);

View File

@ -76,7 +76,7 @@ time_t LoggerGetLastLife(char *dirarg) {
} }
fclose(fil); fclose(fil);
} else { } else {
printf("can not read %s\n", path); /* printf("can not read %s\n", path); */
} }
return t; return t;
} }
@ -108,16 +108,17 @@ char *LoggerGetDir(void) {
return dir; return dir;
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
int LoggerVarPath(char *dir, char *path, int pathLen, char *name) { int LoggerVarPath(char *dir, char *path, int pathLen, char *name, struct tm *t) {
int l; int l;
l = strlen(dir); l = strlen(dir);
if (l + strlen(name) + 2 >= pathLen) { if (l + strlen(name) + 8 >= pathLen) {
path[0]='\0'; path[0]='\0';
return 0; return 0;
} }
strcpy(path, dir); strcpy(path, dir);
path[l] = '/'; l++; strftime(path + l, pathLen - l, "/%Y/", t);
l += 6;
for (;*name != '\0'; name++, l++) { for (;*name != '\0'; name++, l++) {
path[l] = tolower(*name); path[l] = tolower(*name);
} }
@ -140,7 +141,7 @@ int LoggerWrite0(Logger *log, time_t now, int period, char *value) {
} }
lasttm = *localtime(&log->last); lasttm = *localtime(&log->last);
tm = *localtime(&now); tm = *localtime(&now);
l = LoggerVarPath(dir, path, sizeof path, log->name); l = LoggerVarPath(dir, path, sizeof path, log->name, &tm);
strftime(path + l, sizeof path - l, "%m-%d.log", &tm); strftime(path + l, sizeof path - l, "%m-%d.log", &tm);
strftime(stim, sizeof stim, "#%Y-%m-%d %H:%M:%S", &tm); strftime(stim, sizeof stim, "#%Y-%m-%d %H:%M:%S", &tm);
@ -226,7 +227,7 @@ int LoggerWrite(Logger *log, time_t now, int period, char *value) {
yday = tm->tm_yday; yday = tm->tm_yday;
/* -- debug logging if dir/debug exists */ /* -- debug logging if dir/debug exists */
l = LoggerVarPath(dir, path, sizeof path, "debug"); l = LoggerVarPath(dir, path, sizeof path, "debug", tm);
strftime(path + l, sizeof path - l, "%m-%d.log", tm); strftime(path + l, sizeof path - l, "%m-%d.log", tm);
fil=fopen(path, "a"); fil=fopen(path, "a");
if (fil) { if (fil) {
@ -279,25 +280,53 @@ void LoggerKill(Logger *log) {
} }
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
Logger *LoggerMake(char *name, int period, int exact) { static int LoggerMakeDir(char *path) {
Logger *log; static char buffer[4096];
char path[256];
struct stat st; struct stat st;
int i; int i, lpath, l;
time_t t; char *slash;
LoggerGetDir();
if (dir == NULL) return NULL;
LoggerVarPath(dir, path, sizeof path, name);
i = stat(path, &st); i = stat(path, &st);
if (i >= 0) { if (i >= 0) {
if (((st.st_mode >> 12) & 15) != 4) { /* exists, but is no directory */ if (((st.st_mode >> 12) & 15) != 4) { /* exists, but is no directory */
return NULL; return 0;
}
return 1;
} }
} else {
i = mkdir(path, S_IRWXU+S_IRGRP+S_IXGRP+S_IROTH+S_IXOTH); i = mkdir(path, S_IRWXU+S_IRGRP+S_IXGRP+S_IROTH+S_IXOTH);
if (i < 0) return NULL; /* mkdir failed */ if (i < 0) {
if (errno != ENOENT) return 0; /* mkdir failed */
snprintf(buffer, sizeof buffer, "%s", path);
lpath = strlen(buffer);
do {
slash = strrchr(buffer, '/');
if (!slash) return 0;
*slash='\0';
i = mkdir(buffer, S_IRWXU+S_IRGRP+S_IXGRP+S_IROTH+S_IXOTH);
} while (i < 0 && errno == ENOENT);
l = strlen(buffer);
while (l<lpath) {
buffer[l] = '/';
i = mkdir(buffer, S_IRWXU+S_IRGRP+S_IXGRP+S_IROTH+S_IXOTH);
if (i< 0) return 0;
l = strlen(buffer);
} }
}
return 1;
}
/*--------------------------------------------------------------------------*/
Logger *LoggerMake(char *name, int period, int exact) {
Logger *log;
char path[256];
time_t t;
struct tm tm;
LoggerGetDir();
if (dir == NULL) return NULL;
time(&t);
tm = *localtime(&t);
LoggerVarPath(dir, path, sizeof path, name, &tm);
if (LoggerMakeDir(path) == 0) return NULL;
log = LoggerFind(name); /* look if logger already exists */ log = LoggerFind(name); /* look if logger already exists */
if (log == NULL) { if (log == NULL) {
log = calloc(1, sizeof *log); log = calloc(1, sizeof *log);

View File

@ -23,7 +23,7 @@ void LoggerWriteOld(Logger *log, time_t now);
time_t LoggerLastTime(Logger *log); time_t LoggerLastTime(Logger *log);
int LoggerPeriod(Logger *log); int LoggerPeriod(Logger *log);
void LoggerSetPeriod(Logger *log, int period); void LoggerSetPeriod(Logger *log, int period);
int LoggerVarPath(char *dir, char *path, int pathLen, char *name); int LoggerVarPath(char *dir, char *path, int pathLen, char *name, struct tm *t);
void LoggerFreeAll(void); void LoggerFreeAll(void);
#endif #endif

View File

@ -11,6 +11,8 @@
#define LOGGER_NAN -999999. #define LOGGER_NAN -999999.
#define ONE_YEAR (366*24*3600) #define ONE_YEAR (366*24*3600)
#define LLEN 1024 #define LLEN 1024
/* max. number of dirs in path */
#define MAX_DIRS 16
typedef enum { NUMERIC, TEXT } CompType; typedef enum { NUMERIC, TEXT } CompType;
@ -36,8 +38,8 @@ typedef struct {
int omitEqual; int omitEqual;
} Compressor; } Compressor;
static char *dir = NULL; static char *dirs[MAX_DIRS] = {NULL};
static char *dir2 = NULL; static int ndirs=0;
static void InitCompressor(Compressor *c, SConnection *pCon, time_t step) { static void InitCompressor(Compressor *c, SConnection *pCon, time_t step) {
c->pCon = pCon; c->pCon = pCon;
@ -127,7 +129,7 @@ static void PutFinish(Compressor *c, time_t now) {
if (c->tlim != 0) { /* there is data already */ if (c->tlim != 0) { /* there is data already */
c->omitEqual = 0; c->omitEqual = 0;
if (c->type == NUMERIC) { if (c->type == NUMERIC) {
if (now > c->last.t) { /* copy last value to the actual time */ if (now > c->last.t + c->period) { /* copy last value to the actual time */
if (c->last.y != LOGGER_NAN) { if (c->last.y != LOGGER_NAN) {
snprintf(value, sizeof value, "%g", c->last.y); snprintf(value, sizeof value, "%g", c->last.y);
PutValue(c, now, value); PutValue(c, now, value);
@ -214,7 +216,7 @@ static int LogReader(SConnection *pCon, SicsInterp *pSics, void *pData,
*/ */
time_t from, to, step, xs, lastt; time_t from, to, step, xs, lastt;
char *p, *varp; char *p, *varp;
int i, j, iarg, l, iret, loss, np; int i, j, iarg, pathLen, iret, loss, np;
int inRange; int inRange;
int yday=0; int yday=0;
time_t t, startim; time_t t, startim;
@ -229,8 +231,12 @@ static int LogReader(SConnection *pCon, SicsInterp *pSics, void *pData,
char *opt; char *opt;
int isdst; int isdst;
int overflow; int overflow;
time_t now, now1, now2, nowi; time_t now, nows[MAX_DIRS], nowi;
char var[256]; char var[256];
char dirPathBuffer[1024];
char *dirPath;
int idir;
char *colon;
/* argtolower(argc, argv); */ /* argtolower(argc, argv); */
if (argc < 4) goto illarg; if (argc < 4) goto illarg;
@ -288,22 +294,39 @@ static int LogReader(SConnection *pCon, SicsInterp *pSics, void *pData,
snprintf(line, sizeof line, "%ld\n", (long)now); snprintf(line, sizeof line, "%ld\n", (long)now);
SCWrite(pCon, line, eWarning); SCWrite(pCon, line, eWarning);
if (dir == NULL) { dirPath = IFindOption(pSICSOptions, "LogReaderPath");
dir = IFindOption(pSICSOptions, "LoggerDir"); if (dirPath == NULL) { /* for compatibility, check */
if (dir == NULL) { dirs[0] = IFindOption(pSICSOptions, "LoggerDir");
SCWrite(pCon, "ERROR: LoggerDir not found", eError); if (dirs[0] == NULL) {
SCWrite(pCon, "ERROR: LoggerPath not found", eError);
return 0; return 0;
} }
nows[0] = LoggerGetLastLife(NULL);
if (dirs[1] == NULL) {
dirs[1] = IFindOption(pSICSOptions, "LoggerDir2");
nows[1] = LoggerGetLastLife(dirs[1]);
} }
if (dir2 == NULL) { } else {
dir2 = IFindOption(pSICSOptions, "LoggerDir2"); snprintf(dirPathBuffer, sizeof dirPathBuffer, "%s", dirPath);
if (dir2 == NULL) { dirPath = dirPathBuffer;
dir2=""; for (ndirs = 0; ndirs < MAX_DIRS; ndirs++) {
dirs[ndirs] = dirPath;
colon = strchr(dirPath, ':');
if (colon != NULL) {
*colon = '\0';
}
if (ndirs == 0) {
nows[0] = LoggerGetLastLife(NULL);
} else {
nows[ndirs] = LoggerGetLastLife(dirPath);
}
if (colon == NULL) {
ndirs++;
break;
}
dirPath = colon + 1;
} }
} }
now1 = LoggerGetLastLife(NULL);
if (now1 == 0) now1 = now;
now2 = 0;
loss = 0; loss = 0;
overflow = 0; overflow = 0;
@ -331,21 +354,15 @@ static int LogReader(SConnection *pCon, SicsInterp *pSics, void *pData,
var[j] = '\0'; var[j] = '\0';
c.type = type0; c.type = type0;
c.np = np; c.np = np;
l = LoggerVarPath(dir, path, sizeof path, var); tm = *localtime(&from);
dr = opendir(path); pathLen = 0;
if (dr) { for (idir = 0; idir < ndirs; idir++) {
nowi = now1; pathLen = LoggerVarPath(dirs[idir], path, sizeof path, var, &tm);
closedir(dr);
} else {
if (now2 == 0) {
now2 = LoggerGetLastLife(dir2);
if (now2 == 0) now2 = now;
}
l = LoggerVarPath(dir2, path, sizeof path, var);
nowi = now2;
dr = opendir(path); dr = opendir(path);
if (dr) { if (dr) {
nowi = nows[idir];
closedir(dr); closedir(dr);
break;
} }
} }
@ -361,7 +378,7 @@ static int LogReader(SConnection *pCon, SicsInterp *pSics, void *pData,
} }
if (fil == NULL) { if (fil == NULL) {
yday = tm.tm_yday; yday = tm.tm_yday;
strftime(path + l, sizeof path - l, "%m-%d.log", &tm); strftime(path + pathLen, sizeof path - pathLen, "%m-%d.log", &tm);
fil = fopen(path, "r"); fil = fopen(path, "r");
if (fil != NULL) { /* check if file is from the given year */ if (fil != NULL) { /* check if file is from the given year */
strftime(stim, sizeof stim, "#%Y-%m-%d", &tm); strftime(stim, sizeof stim, "#%Y-%m-%d", &tm);

View File

@ -2,8 +2,10 @@
#include "sics.h" #include "sics.h"
#include "sicshipadaba.h" #include "sicshipadaba.h"
static hdbCallbackReturn LoggerUpdateCallback(pHdb node, void *userData, static char *loggerID = "loggerID";
pHdbMessage message) {
static hdbCallbackReturn LoggerUpdateCallback(pHdb node,
void *userData, pHdbMessage message) {
Logger *logger = userData; Logger *logger = userData;
pDynString str; pDynString str;
SConnection *conn = NULL; SConnection *conn = NULL;
@ -11,8 +13,8 @@ static hdbCallbackReturn LoggerUpdateCallback(pHdb node, void *userData,
pHdbDataMessage mm = NULL; pHdbDataMessage mm = NULL;
pHdbDataSearch dsm = NULL; pHdbDataSearch dsm = NULL;
if((dsm = GetHdbDataSearchMessage(message)) != NULL){ if ((dsm = GetHdbDataSearchMessage(message)) != NULL) {
if(dsm->testFunc == LoggerUpdateCallback){ if (dsm->testPtr == loggerID) {
dsm->result = userData; dsm->result = userData;
return hdbAbort; return hdbAbort;
} }
@ -92,7 +94,7 @@ static int LogSetup(SConnection *pCon, SicsInterp *pSics, void *pData,
} else { } else {
numeric = 0; numeric = 0;
} }
logger = FindHdbCallbackData(node, LoggerUpdateCallback, NULL); logger = FindHdbCallbackData(node, loggerID);
if (logger != 0) { /* logger exists already, changed only period */ if (logger != 0) { /* logger exists already, changed only period */
LoggerSetPeriod(logger, period); LoggerSetPeriod(logger, period);
} else { } else {

View File

@ -32,7 +32,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
mcstashm.o initializer.o remob.o tclmotdriv.o protocol.o \ mcstashm.o initializer.o remob.o tclmotdriv.o protocol.o \
sinfox.o sicslist.o cone.o hipadaba.o sicshipadaba.o statistics.o \ sinfox.o sicslist.o cone.o hipadaba.o sicshipadaba.o statistics.o \
ascon.o errormsg.o scriptcontext.o logger.o logreader.o logsetup.o \ ascon.o errormsg.o scriptcontext.o logger.o logreader.o logsetup.o \
savehdb.o statusfile.o sicshdbfactory.o proxy.o \ savehdb.o statusfile.o sicshdbfactory.o proxy.o devser.o \
moregress.o multicounter.o regresscter.o histregress.o \ moregress.o multicounter.o regresscter.o histregress.o \
sicshdbadapter.o polldriv.o sicspoll.o statemon.o hmslave.o \ sicshdbadapter.o polldriv.o sicspoll.o statemon.o hmslave.o \
nwatch.o asyncqueue.o asyncprotocol.o sicsobj.o \ nwatch.o asyncqueue.o asyncprotocol.o sicsobj.o \

View File

@ -26,8 +26,9 @@ SUBLIBS = psi/libpsi.a psi/hardsup/libhlib.a matrix/libmatrix.a \
LIBS = -L$(HDFROOT)/lib $(SUBLIBS) $(NILIB)\ LIBS = -L$(HDFROOT)/lib $(SUBLIBS) $(NILIB)\
-ltcl $(HDFROOT)/lib/libhdf5.a \ -ltcl $(HDFROOT)/lib/libhdf5.a \
$(HDFROOT)/lib/libmfhdf.a $(HDFROOT)/lib/libdf.a \ $(HDFROOT)/lib/libmfhdf.a $(HDFROOT)/lib/libdf.a \
$(HDFROOT)/lib/libjpeg.a -lsz $(HDFROOT)/lib/libjson.a \ $(HDFROOT)/lib/libjpeg.a $(HDFROOT)/lib/libsz.a \
-ldl -lz -lmxml -lghttp -lm -lc $(HDFROOT)/lib/libjson.a \
-ldl -lz -lmxml $(HDFROOT)/lib/libghttp.a -lm -lc
include make_gen include make_gen

View File

@ -510,8 +510,8 @@ CreateSocketAdress(
if (l > 0) { if (l > 0) {
self->iType = 0; self->iType = 0;
if (!disconnected) { /* do not write an error message on disconnect */ if (!disconnected) { /* do not write an error message on disconnect */
snprintf(buf, sizeof buf, "NETWrite: timeout, only %ld of %ld bytes sent (socket %d)", snprintf(buf, sizeof buf, "NETWrite: timeout, only %ld of %ld bytes sent (socket %d) %ld.%6.6ld",
lLen - l, lLen, self->sockid); lLen - l, lLen, self->sockid, tmo.tv_sec, tmo.tv_usec);
NetError(buf); NetError(buf);
} }
return 0; return 0;

2
ofac.c
View File

@ -443,7 +443,7 @@
INIT(StatisticsInit); INIT(StatisticsInit);
INIT(InitializerInit); INIT(InitializerInit);
INIT(SaveHdbInit); /* must be after InitializerInit */ INIT(SaveHdbInit); /* must be after InitializerInit */
INIT(SctStartup); INIT(SctInit);
INIT(LogReaderInit); INIT(LogReaderInit);
INIT(LogSetupInit); INIT(LogSetupInit);
INIT(StatusFileInit); INIT(StatusFileInit);

View File

@ -452,7 +452,7 @@ int ProxyFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
AppendHipadabaCallback(pNew->objectNode, AppendHipadabaCallback(pNew->objectNode,
MakeHipadabaCallback(ProxyCallback, pNew,NULL)); MakeHipadabaCallback(ProxyCallback, pNew,NULL));
v = makeHdbData(HIPFUNC,1,MapFunc); v = MakeHdbFunc((voidFunc *)MapFunc);
mapFunc = MakeSICSHdbPar("map", usMugger, v); mapFunc = MakeSICSHdbPar("map", usMugger, v);
SetHdbProperty(mapFunc,"visible","false"); SetHdbProperty(mapFunc,"visible","false");
v = MakeHdbText("Undefined"); v = MakeHdbText("Undefined");

View File

@ -45,7 +45,7 @@ typedef struct RemServer {
int taskActive; int taskActive;
int interestActive; int interestActive;
int forwardMessages; int forwardMessages;
SCStore conn; SCStore *conn;
} RemServer; } RemServer;
struct Remob { struct Remob {

File diff suppressed because it is too large Load Diff

View File

@ -106,7 +106,7 @@ static int invokeOBJFunction(pSICSOBJ object, pHdb commandNode, SConnection *pCo
count++; count++;
} }
pFunc = (SICSOBJFunc)commandNode->value.v.obj; pFunc = (SICSOBJFunc)commandNode->value.v.func;
if(pFunc == NULL){ if(pFunc == NULL){
SCWrite(pCon,"ERROR: internal error, function not found",eError); SCWrite(pCon,"ERROR: internal error, function not found",eError);
return 0; return 0;
@ -200,7 +200,7 @@ static int MakeScriptFunc(pSICSOBJ self, SConnection *pCon,
SCWrite(pCon,"ERROR: root path error or out of memory",eError); SCWrite(pCon,"ERROR: root path error or out of memory",eError);
return 0; return 0;
} }
node->value.v.obj = ScriptObjFunc; node->value = MakeHdbFunc((voidFunc *)ScriptObjFunc);
SetHdbProperty(node,"script",argv[3]); SetHdbProperty(node,"script",argv[3]);
SetHdbProperty(node,"priv",argv[4]); SetHdbProperty(node,"priv",argv[4]);
AppendHipadabaCallback(node,MakeSICSFuncCallback(self)); AppendHipadabaCallback(node,MakeSICSFuncCallback(self));

View File

@ -239,8 +239,16 @@ static int listRestoreErr(pRestoreObj self, SConnection *pCon){
} }
else else
{ {
if(strcmp(argv[1],"listerr") == 0){ if(strcasecmp(argv[1],"listerr") == 0){
return listRestoreErr(self,pCon); return listRestoreErr(self,pCon);
} else if(strcasecmp(argv[1],"killerr") == 0){
if(self->errList >= 0){
LLDdeleteBlob(self->errList);
}
self->errList = LLDstringCreate();
StatusFileDirty();
SCSendOK(pCon);
return 1;
} else { } else {
sprintf(pBueffel,"%s",argv[1]); sprintf(pBueffel,"%s",argv[1]);
} }

View File

@ -179,6 +179,11 @@
else else
{ {
strncpy(pResult,sVal.value,iLen); strncpy(pResult,sVal.value,iLen);
/* strncpy is not guaranteed to be '\0' terminated */
if (iLen > 0 && pResult[iLen-1] != '\0') {
/* overflow */
pResult[iLen-1] = '\0';
}
return 1; return 1;
} }
} }
@ -186,6 +191,24 @@
} }
return 0; return 0;
} }
/*--------------------------------------------------------------------------*/
char *StringDictGetShort(pStringDict self, char *name)
{
SDE sVal;
int iRet;
iRet = LLDnodePtr2First(self->iList);
while(iRet != 0)
{
LLDnodeDataTo(self->iList,&sVal);
if(strcmp(sVal.name,name) == 0)
{
return sVal.value;
}
iRet = LLDnodePtr2Next(self->iList);
}
return NULL;
}
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
int StringDictDelete(pStringDict self, char *name) int StringDictDelete(pStringDict self, char *name)
{ {

View File

@ -25,6 +25,10 @@
int StringDictExists(pStringDict self, char *name); int StringDictExists(pStringDict self, char *name);
int StringDictUpdate(pStringDict self, char *name, char *value); int StringDictUpdate(pStringDict self, char *name, char *value);
int StringDictGet(pStringDict self, char *name, char *pResult, int iLen); int StringDictGet(pStringDict self, char *name, char *pResult, int iLen);
/* the result of StringDictGetShort is only valid as long that the entry is not changed */
char *StringDictGetShort(pStringDict self, char *name);
int StringDictGetAsNumber(pStringDict self, char *name, float *fVal); int StringDictGetAsNumber(pStringDict self, char *name, float *fVal);
int StringDictDelete(pStringDict self, char *name); int StringDictDelete(pStringDict self, char *name);