- implemented multi-line response in AsconStdHandler
This commit is contained in:
74
ascon.c
74
ascon.c
@ -415,55 +415,70 @@ int AsconStdHandler(Ascon * a)
|
||||
{
|
||||
int result;
|
||||
char chr;
|
||||
int ret;
|
||||
int ret, l;
|
||||
char *cmd, *opt;
|
||||
|
||||
switch (a->state) {
|
||||
case AsconWriteStart:
|
||||
if (strstr(GetCharArray(a->wrBuffer), "@@NOSEND@@") != NULL) {
|
||||
cmd = GetCharArray(a->wrBuffer);
|
||||
a->lineCount = 1;
|
||||
if (a->separator != NULL) { /* multiline mode enabled */
|
||||
l = strlen(cmd);
|
||||
if (l> 0 && cmd[l-1] == '}') {
|
||||
opt = strrchr(cmd, '{');
|
||||
if (opt != NULL) {
|
||||
if (sscanf(opt, "{%d}", &a->lineCount) == 1) {
|
||||
/* remove option */
|
||||
for (l = strlen(opt); l > 0; l--) {
|
||||
DynStringBackspace(a->wrBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (strstr(GetCharArray(a->wrBuffer), "@@NOSEND@@") != NULL) {
|
||||
a->state = AsconWriteDone;
|
||||
return 1;
|
||||
}
|
||||
break; /* go to the base handler */
|
||||
case AsconWriting:
|
||||
if (a->readState) { /* last char was CR */
|
||||
ret = AsconReadChar(a->fd, &chr);
|
||||
if (ret > 0) {
|
||||
if (chr == '\n') {
|
||||
/* swallow LF after CR */
|
||||
a->readState = 0;
|
||||
} else {
|
||||
/* garbage character found -> swallow */
|
||||
}
|
||||
}
|
||||
}
|
||||
break; /* go to the base handler */
|
||||
case AsconReading:
|
||||
if (a->lineCount == 0) {
|
||||
/* no response expected */
|
||||
a->state = AsconReadDone;
|
||||
return 1;
|
||||
}
|
||||
result = AsconBaseHandler(a);
|
||||
if (result == 0)
|
||||
return 0;
|
||||
chr = a->lastChar;
|
||||
if (a->replyTerminator != NULL) {
|
||||
if (strchr(a->replyTerminator, chr) != NULL) {
|
||||
DynStringConcatChar(a->rdBuffer, '\0');
|
||||
a->state = AsconReadDone;
|
||||
if (chr == '\n' || chr == '\r') {
|
||||
DynStringBackspace(a->rdBuffer); /* remove LF or CR */
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (chr == '\n') {
|
||||
if (chr == '\n') { /* LF */
|
||||
DynStringBackspace(a->rdBuffer); /* remove LF */
|
||||
if (a->readState) { /* last char was CR */
|
||||
/* swallow LF after CR */
|
||||
/* LF after CR is not a terminator */
|
||||
a->readState = 0;
|
||||
} else {
|
||||
DynStringBackspace(a->rdBuffer); /* remove LF */
|
||||
DynStringConcatChar(a->rdBuffer, '\0');
|
||||
a->state = AsconReadDone;
|
||||
}
|
||||
} else if (chr == '\r') {
|
||||
a->readState = 1; /* set 'last char was CR' */
|
||||
} else if (chr == '\r') { /* CR */
|
||||
DynStringBackspace(a->rdBuffer); /* remove CR */
|
||||
DynStringConcatChar(a->rdBuffer, '\0');
|
||||
a->readState = 1; /* set 'last char was CR' */
|
||||
a->state = AsconReadDone;
|
||||
}
|
||||
}
|
||||
if (a->state == AsconReadDone && a->lineCount > 1) {
|
||||
if (a->separator != NULL) {
|
||||
DynStringConcat(a->rdBuffer, a->separator);
|
||||
}
|
||||
a->lineCount--;
|
||||
a->state = AsconReading;
|
||||
}
|
||||
return 1; /* base handler was already called */
|
||||
default:
|
||||
break;
|
||||
@ -488,6 +503,10 @@ int AsconStdInit(Ascon *a, SConnection *con, int argc, char *argv[])
|
||||
if (argc > 4 && argv[4][0] != '\0') {
|
||||
a->replyTerminator = strdup(argv[4]);
|
||||
}
|
||||
a->separator = NULL;
|
||||
if (argc > 5 && argv[5][0] != '\0') {
|
||||
a->separator = strdup(argv[5]);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -516,6 +535,8 @@ Ascon *AsconMake(SConnection * con, int argc, char *argv[])
|
||||
a->sendTerminator = NULL;
|
||||
a->hostport = NULL;
|
||||
a->responseValid = 0;
|
||||
a->readState = 0;
|
||||
a->lineCount = 1;
|
||||
|
||||
a->handler = AsconSetHandler(a, con, argc, argv);
|
||||
if (a->handler == NULL) {
|
||||
@ -545,12 +566,15 @@ void AsconKill(Ascon * a)
|
||||
if (a->hostport) {
|
||||
free(a->hostport);
|
||||
}
|
||||
if(a->sendTerminator){
|
||||
if (a->sendTerminator) {
|
||||
free(a->sendTerminator);
|
||||
}
|
||||
if(a->replyTerminator){
|
||||
if (a->replyTerminator) {
|
||||
free(a->replyTerminator);
|
||||
}
|
||||
if (a->separator) {
|
||||
free(a->separator);
|
||||
}
|
||||
if (a->private != NULL && a->killPrivate != NULL) {
|
||||
a->killPrivate(a->private);
|
||||
}
|
||||
|
Reference in New Issue
Block a user