- Adapted indenation to new agreed upon system

- Added support for second generation scriptcontext based counter
This commit is contained in:
koennecke
2009-02-13 09:00:03 +00:00
parent a3dcad2bfa
commit 91d4af0541
405 changed files with 88101 additions and 88173 deletions

282
ascon.c
View File

@ -18,13 +18,12 @@
CreateSocketAdress stolen from Tcl. Thanks to John Ousterhout
*/
static int CreateSocketAdress(
struct sockaddr_in *sockaddrPtr, /* Socket address */
char *host, /* Host. NULL implies INADDR_ANY */
int port) /* Port number */
{
struct hostent *hostent; /* Host database entry */
struct in_addr addr; /* For 64/32 bit madness */
static int CreateSocketAdress(struct sockaddr_in *sockaddrPtr, /* Socket address */
char *host, /* Host. NULL implies INADDR_ANY */
int port)
{ /* Port number */
struct hostent *hostent; /* Host database entry */
struct in_addr addr; /* For 64/32 bit madness */
(void) memset((char *) sockaddrPtr, '\0', sizeof(struct sockaddr_in));
sockaddrPtr->sin_family = AF_INET;
@ -35,11 +34,11 @@ static int CreateSocketAdress(
hostent = gethostbyname(host);
if (hostent != NULL) {
memcpy((char *) &addr,
(char *) hostent->h_addr_list[0], (size_t) hostent->h_length);
(char *) hostent->h_addr_list[0], (size_t) hostent->h_length);
} else {
addr.s_addr = inet_addr(host);
if (addr.s_addr == (unsigned long)-1) {
return 0; /* error */
if (addr.s_addr == (unsigned long) -1) {
return 0; /* error */
}
}
}
@ -51,39 +50,45 @@ static int CreateSocketAdress(
return 1;
}
double DoubleTime(void) {
double DoubleTime(void)
{
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);
return now.tv_sec + now.tv_usec / 1e6;
}
void AsconError(Ascon *a, char *msg, int errorno) {
static char *stateText[]={
void AsconError(Ascon * a, char *msg, int errorno)
{
static char *stateText[] = {
"state 0", "kill", "state 2", "notConnected",
"connect", "start connect", "connect finished", "connect failed",
"write", "start write", "write finished", "write failed",
"read", "start read", "read finished", "read failed",
"connect", "start connect", "connect finished", "connect failed",
"write", "start write", "write finished", "write failed",
"read", "start read", "read finished", "read failed",
"state 16", "state 17", "state 18", "idle"
};
char *state;
if (a->state < 0 || a->state > 19) {
state = "bad state";
} else {
state = stateText[a->state];
}
if (errorno != 0) {
a->errList = ErrPutMsg(a->errList, "ASCERR: %s %s (during %s)", msg, strerror(errorno), state);
a->errList =
ErrPutMsg(a->errList, "ASCERR: %s %s (during %s)", msg,
strerror(errorno), state);
} else {
a->errList = ErrPutMsg(a->errList, "ASCERR: %s (during %s)", msg, state);
a->errList =
ErrPutMsg(a->errList, "ASCERR: %s (during %s)", msg, state);
}
a->state |= AsconFailed;
}
static void AsconConnect(Ascon *a) {
static void AsconConnect(Ascon * a)
{
/* input state: AsconConnectStart
output state: AsconFailed or AsconConnecting */
int ret;
@ -91,17 +96,18 @@ static void AsconConnect(Ascon *a) {
char *colon;
int port;
int oldopts;
if (a->fd < 0) {
a->fd = socket(AF_INET,SOCK_STREAM,0);
a->fd = socket(AF_INET, SOCK_STREAM, 0);
if (a->fd < 0) {
AsconError(a, "socket failed:", errno);
return;
}
}
colon = strchr(a->hostport, ':');
if (colon == NULL) return;
port = atoi(colon+1);
if (colon == NULL)
return;
port = atoi(colon + 1);
if (port <= 0) {
AsconError(a, "bad port number", 0);
return;
@ -116,48 +122,50 @@ static void AsconConnect(Ascon *a) {
/* should we insert the workaround for lantronix server ? see network.c */
oldopts = fcntl(a->fd, F_GETFL, 0);
fcntl(a->fd, F_SETFL, oldopts | O_NONBLOCK);
ret = connect(a->fd, (struct sockaddr *)&adr, sizeof(struct sockaddr_in));
ret =
connect(a->fd, (struct sockaddr *) &adr, sizeof(struct sockaddr_in));
if (ret < 0) {
switch(errno) {
case EINPROGRESS:
case EALREADY:
case EISCONN:
a->state = AsconConnecting;
break;
default:
AsconError(a, "connect failed:", errno);
return;
}
switch (errno) {
case EINPROGRESS:
case EALREADY:
case EISCONN:
a->state = AsconConnecting;
break;
default:
AsconError(a, "connect failed:", errno);
return;
}
}
a->state = AsconConnecting;
return;
}
int AsconStdInit(Ascon *a, SConnection *con,
int argc, char *argv[]) {
int AsconStdInit(Ascon * a, SConnection * con, int argc, char *argv[])
{
a->fd = -1;
a->state = AsconConnectStart;
a->reconnectInterval = 10;
a->hostport = strdup(argv[1]);
if(argc > 2){
a->sendTerminator = strdup(argv[2]);
if (argc > 2) {
a->sendTerminator = strdup(argv[2]);
} else {
a->sendTerminator = strdup("\n");
a->sendTerminator = strdup("\n");
}
if(argc > 3){
a->timeout = atof(argv[3]);
if (argc > 3) {
a->timeout = atof(argv[3]);
} else {
a->timeout = 2.0; /* sec */
a->timeout = 2.0; /* sec */
}
return 1;
}
int AsconReadGarbage(int fd) {
int AsconReadGarbage(int fd)
{
fd_set rmask;
struct timeval tmo = {0,0};
struct timeval tmo = { 0, 0 };
int l, ret, result;
char garbage[100];
FD_ZERO(&rmask);
result = 0;
do {
@ -179,7 +187,8 @@ int AsconReadGarbage(int fd) {
return result;
}
void PrintChar(char chr) {
void PrintChar(char chr)
{
if (chr <= 32 || chr >= 127) {
printf("%2.2x ", chr);
} else {
@ -187,15 +196,16 @@ void PrintChar(char chr) {
}
}
int AsconConnectSuccess(int fd) {
int AsconConnectSuccess(int fd)
{
fd_set wmask, rmask;
struct timeval tmo = {0,0};
struct timeval tmo = { 0, 0 };
int oldopts;
int ret;
oldopts = fcntl(fd, F_GETFL, 0);
assert(oldopts | O_NONBLOCK); /* fd must be in non-blocking mode */
FD_ZERO(&wmask);
FD_ZERO(&rmask);
FD_SET(fd, &wmask);
@ -203,33 +213,36 @@ int AsconConnectSuccess(int fd) {
ret = uselect(fd + 1, &rmask, &wmask, NULL, &tmo);
if (ret > 0) {
assert(FD_ISSET(fd, &wmask));
if (FD_ISSET(fd, &rmask)) { /* there may already be data for read */
if (recv(fd, NULL, 0, 0) < 0) { /* zero length, check only return value */
if (FD_ISSET(fd, &rmask)) { /* there may already be data for read */
if (recv(fd, NULL, 0, 0) < 0) { /* zero length, check only return value */
ret = ASCON_RECV_ERROR; /* first recv failed */
}
} else {
if (send(fd, NULL, 0, 0) < 0) { /* zero length, check only return value */
if (send(fd, NULL, 0, 0) < 0) { /* zero length, check only return value */
ret = ASCON_SEND_ERROR; /* first send failed */
}
}
}
fcntl(fd, F_SETFL, oldopts & ~ O_NONBLOCK); /* reset to blocking mode */
fcntl(fd, F_SETFL, oldopts & ~O_NONBLOCK); /* reset to blocking mode */
return ret;
}
int AsconReadChar(int fd, char *chr) {
int AsconReadChar(int fd, char *chr)
{
fd_set rmask;
struct timeval tmo = {0,0};
struct timeval tmo = { 0, 0 };
int ret;
FD_ZERO(&rmask);
FD_SET(fd, &rmask);
ret = uselect(fd + 1, &rmask, NULL, NULL, &tmo);
if (ret <= 0) return ret;
if (ret <= 0)
return ret;
ret = recv(fd, chr, 1, 0);
/* PrintChar(*chr); */
fflush(stdout);
if (ret > 0) return 1;
if (ret > 0)
return 1;
if (ret == 0) {
errno = ECONNRESET;
return ASCON_DISCONNECTED;
@ -237,26 +250,30 @@ int AsconReadChar(int fd, char *chr) {
return ASCON_RECV_ERROR;
}
int AsconWriteChars(int fd, char *data, int length) {
int AsconWriteChars(int fd, char *data, int length)
{
fd_set wmask;
struct timeval tmo = {0,0};
struct timeval tmo = { 0, 0 };
int ret;
if (length <= 0) return 0;
if (length <= 0)
return 0;
/*
{ int i;
for (i=0; i<length; i++) {
PrintChar(data[i]);
}
}
printf("<written\n");
*/
{ int i;
for (i=0; i<length; i++) {
PrintChar(data[i]);
}
}
printf("<written\n");
*/
FD_ZERO(&wmask);
FD_SET(fd, &wmask);
ret = uselect(fd + 1, NULL, &wmask, NULL, &tmo);
if (ret <= 0) return ASCON_SELECT_ERROR;
if (ret <= 0)
return ASCON_SELECT_ERROR;
ret = send(fd, data, length, 0);
if (ret > 0) return ret;
if (ret > 0)
return ret;
if (ret == 0) {
errno = ECONNRESET;
return ASCON_DISCONNECTED;
@ -266,14 +283,15 @@ int AsconWriteChars(int fd, char *data, int length) {
static double lastCall = 0;
int AsconStdHandler(Ascon *a) {
int AsconStdHandler(Ascon * a)
{
int ret;
int l;
char chr;
double now = DoubleTime();
if (now > lastCall + 0.5) { /* AsconStdHandler was not called since a long time (0.5 sec) */
if (lastCall != 0) { /* extend timeout time (for debugging purposes) */
if (now > lastCall + 0.5) { /* AsconStdHandler was not called since a long time (0.5 sec) */
if (lastCall != 0) { /* extend timeout time (for debugging purposes) */
a->start += now - lastCall - 0.5;
}
}
@ -287,17 +305,18 @@ int AsconStdHandler(Ascon *a) {
if (ret == 0) {
/* in progress */
} else if (ret > 0) {
a->state = AsconConnectDone; /* success */
a->state = AsconConnectDone; /* success */
} else if (ret < 0) {
AsconError(a, "AsconConnectSuccess failed:", errno);
}
break;
case AsconWriteStart:
DynStringConcat(a->wrBuffer, a->sendTerminator);
a->wrPos = 0;
a->state = AsconWriting;
if(strstr(GetCharArray(a->wrBuffer),"@@NOSEND@@") != NULL){
a->state = AsconWriteDone;
if (strstr(GetCharArray(a->wrBuffer), "@@NOSEND@@") != NULL) {
a->state = AsconWriteDone;
} else {
DynStringConcat(a->wrBuffer, a->sendTerminator);
a->wrPos = 0;
a->state = AsconWriting;
}
break;
case AsconWriting:
@ -305,8 +324,8 @@ int AsconStdHandler(Ascon *a) {
l = GetDynStringLength(a->wrBuffer) - a->wrPos;
ret = AsconWriteChars(a->fd, GetCharArray(a->wrBuffer) + a->wrPos, l);
if (ret < 0) {
if(errno != EINTR && errno != EAGAIN){
AsconError(a, "send failed:", errno);
if (errno != EINTR && errno != EAGAIN) {
AsconError(a, "send failed:", errno);
}
/*
* Ooops: which state shall we go to after a write fail?
@ -328,7 +347,7 @@ int AsconStdHandler(Ascon *a) {
ret = AsconReadChar(a->fd, &chr);
while (ret > 0) {
a->start = DoubleTime();
if (chr == '\n') {
if (a->readState) {
/* swallow LF after CR */
@ -355,8 +374,8 @@ int AsconStdHandler(Ascon *a) {
}
if (ret < 0) {
/* EINTR means we shall retry */
if(errno != EINTR && errno != EAGAIN){
AsconError(a, "AsconReadChar failed:", errno);
if (errno != EINTR && errno != EAGAIN) {
AsconError(a, "AsconReadChar failed:", errno);
}
return 1;
}
@ -373,7 +392,7 @@ int AsconStdHandler(Ascon *a) {
break;
default:
return 1;
}
}
return 1;
}
@ -381,28 +400,32 @@ int AsconStdHandler(Ascon *a) {
#define MC_NAME(T) AsconProtocol##T
#include "mclist.c"
static AsconProtocolList protocols={0};
static AsconProtocolList protocols = { 0 };
void AsconInsertProtocol(AsconProtocol *protocol) {
void AsconInsertProtocol(AsconProtocol * protocol)
{
AsconProtocolAdd(&protocols, protocol);
}
AsconHandler AsconSetHandler(Ascon *a, SConnection *con,
int argc, char *argv[]) {
AsconHandler AsconSetHandler(Ascon * a, SConnection * con,
int argc, char *argv[])
{
AsconProtocol *p;
if (argc < 1) return NULL;
if (argc < 1)
return NULL;
if (strcasecmp(argv[0], "std") == 0) {
if (argc < 2) return NULL;
if (argc < 2)
return NULL;
AsconStdInit(a, con, argc, argv);
return AsconStdHandler;
}
for (p = protocols.head; p!= NULL; p=p->next) {
for (p = protocols.head; p != NULL; p = p->next) {
if (strcasecmp(p->name, argv[0]) == 0) {
if(p->init(a, con, argc, argv)){
return p->handler;
if (p->init(a, con, argc, argv)) {
return p->handler;
} else {
return NULL;
return NULL;
}
}
}
@ -411,14 +434,16 @@ AsconHandler AsconSetHandler(Ascon *a, SConnection *con,
/* --- implementation of higher level interface ---- */
char *ConcatArgs(int argc, char *argv[]) {
char *ConcatArgs(int argc, char *argv[])
{
return Arg2Tcl(argc, argv, NULL, -1);
}
Ascon *AsconMake(SConnection *con, int argc, char *argv[]) {
Ascon *AsconMake(SConnection * con, int argc, char *argv[])
{
Ascon *a;
char *args;
a = calloc(1, sizeof(*a));
if (a == NULL) {
SCWrite(con, "ERROR: no memory", eError);
@ -427,7 +452,8 @@ Ascon *AsconMake(SConnection *con, int argc, char *argv[]) {
a->handler = AsconSetHandler(a, con, argc, argv);
if (a->handler == NULL) {
args = ConcatArgs(argc, argv);
if (!args) return NULL;
if (!args)
return NULL;
SCPrintf(con, eError, "ERROR: illegal protocol: %s", args);
free(args);
return NULL;
@ -441,7 +467,8 @@ Ascon *AsconMake(SConnection *con, int argc, char *argv[]) {
return a;
}
void AsconKill(Ascon *a) {
void AsconKill(Ascon * a)
{
if (a->fd > 0) {
close(a->fd);
}
@ -450,25 +477,28 @@ void AsconKill(Ascon *a) {
if (a->hostport) {
free(a->hostport);
}
if(a->sendTerminator){
free(a->sendTerminator);
if (a->sendTerminator) {
free(a->sendTerminator);
}
if(a->private != NULL && a->killPrivate != NULL){
a->killPrivate(a->private);
if (a->private != NULL && a->killPrivate != NULL) {
a->killPrivate(a->private);
}
free(a);
}
void AsconDisconnect(Ascon *a){
if(a->fd > 0){
close(a->fd);
}
a->fd = -1;
a->state = AsconConnectStart;
void AsconDisconnect(Ascon * a)
{
if (a->fd > 0) {
close(a->fd);
}
a->fd = -1;
a->state = AsconConnectStart;
}
AsconStatus AsconTask(Ascon *a) {
AsconStatus AsconTask(Ascon * a)
{
double now;
while (a->handler(a)) {
switch (a->state) {
case AsconReading:
@ -503,7 +533,7 @@ AsconStatus AsconTask(Ascon *a) {
if (now > a->lastReconnect + a->reconnectInterval) {
a->lastReconnect = now;
close(a->fd);
/* allow the system to cleanup the socket, otherwise a reconnect will fail*/
/* allow the system to cleanup the socket, otherwise a reconnect will fail */
sleep(1);
a->fd = -1;
a->state = AsconConnectStart;
@ -521,8 +551,10 @@ AsconStatus AsconTask(Ascon *a) {
return AsconIdle;
}
int AsconWrite(Ascon *a, char *command, int noResponse) {
if (a->state <= AsconConnectFailed || a->state % 4 < AsconFinished) return 0;
int AsconWrite(Ascon * a, char *command, int noResponse)
{
if (a->state <= AsconConnectFailed || a->state % 4 < AsconFinished)
return 0;
DynStringCopy(a->wrBuffer, command);
a->noResponse = noResponse;
a->state = AsconWriteStart;
@ -531,9 +563,10 @@ int AsconWrite(Ascon *a, char *command, int noResponse) {
return 1;
}
char *AsconRead(Ascon *a) {
char *AsconRead(Ascon * a)
{
if (a->noResponse) {
a->noResponse=0;
a->noResponse = 0;
return "";
}
if (a->state % 4 == AsconFailed) {
@ -547,6 +580,7 @@ char *AsconRead(Ascon *a) {
return NULL;
}
ErrMsg *AsconGetErrList(Ascon *a) {
ErrMsg *AsconGetErrList(Ascon * a)
{
return a->errList;
}