- added new scriptcontext with devser
This commit is contained in:
22
ascon.c
22
ascon.c
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,9 +422,10 @@ void AsconKill(Ascon *a) {
|
|||||||
free(a);
|
free(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) {
|
||||||
|
3
ascon.h
3
ascon.h
@ -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
|
||||||
|
4
ascon.i
4
ascon.i
@ -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
|
||||||
|
12
conman.c
12
conman.c
@ -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);
|
||||||
}
|
}
|
||||||
/* --------------------------------------------------------------------------*/
|
/* --------------------------------------------------------------------------*/
|
||||||
|
14
conman.h
14
conman.h
@ -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
301
devser.c
Normal 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
113
devser.h
Normal 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
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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]
|
||||||
|
@ -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;
|
||||||
|
@ -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));
|
||||||
|
18
hdbqueue.c
18
hdbqueue.c
@ -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);
|
||||||
|
67
logger.c
67
logger.c
@ -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;
|
||||||
}
|
}
|
||||||
} else {
|
return 1;
|
||||||
i = mkdir(path, S_IRWXU+S_IRGRP+S_IXGRP+S_IROTH+S_IXOTH);
|
|
||||||
if (i < 0) return NULL; /* mkdir failed */
|
|
||||||
}
|
}
|
||||||
|
i = mkdir(path, S_IRWXU+S_IRGRP+S_IXGRP+S_IROTH+S_IXOTH);
|
||||||
|
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);
|
||||||
|
2
logger.h
2
logger.h
@ -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
|
||||||
|
77
logreader.c
77
logreader.c
@ -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 (dir2 == NULL) {
|
if (dirs[1] == NULL) {
|
||||||
dir2 = IFindOption(pSICSOptions, "LoggerDir2");
|
dirs[1] = IFindOption(pSICSOptions, "LoggerDir2");
|
||||||
if (dir2 == NULL) {
|
nows[1] = LoggerGetLastLife(dirs[1]);
|
||||||
dir2="";
|
}
|
||||||
|
} else {
|
||||||
|
snprintf(dirPathBuffer, sizeof dirPathBuffer, "%s", dirPath);
|
||||||
|
dirPath = dirPathBuffer;
|
||||||
|
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);
|
||||||
|
22
logsetup.c
22
logsetup.c
@ -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,16 +13,16 @@ 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;
|
||||||
}
|
}
|
||||||
return hdbContinue;
|
return hdbContinue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((mm = GetHdbUpdateMessage(message)) == NULL){
|
if((mm = GetHdbUpdateMessage(message)) == NULL){
|
||||||
return hdbContinue;
|
return hdbContinue;
|
||||||
}
|
}
|
||||||
|
|
||||||
value = *(mm->v);
|
value = *(mm->v);
|
||||||
@ -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 {
|
||||||
|
2
make_gen
2
make_gen
@ -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 \
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
2
ofac.c
@ -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);
|
||||||
|
2
proxy.c
2
proxy.c
@ -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");
|
||||||
|
2
remob.c
2
remob.c
@ -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 {
|
||||||
|
1929
scriptcontext.c
1929
scriptcontext.c
File diff suppressed because it is too large
Load Diff
@ -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,12 +200,12 @@ 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));
|
||||||
AddHipadabaChild(parent,node,pCon);
|
AddHipadabaChild(parent,node,pCon);
|
||||||
SCSendOK(pCon);
|
SCSendOK(pCon);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
12
statusfile.c
12
statusfile.c
@ -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]);
|
||||||
}
|
}
|
||||||
|
23
stringdict.c
23
stringdict.c
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user