From: Zdeněk Salvet Date: Thu, 22 Jul 2004 13:54:53 +0000 (+0000) Subject: Support for EDG 2.1-compatible queries. X-Git-Tag: merge_gss2scm_dst~62 X-Git-Url: http://scientific.zcu.cz/git/?a=commitdiff_plain;h=4c6e84d277ba4ceef4a591c6bd81244f2866c1c3;p=jra1mw.git Support for EDG 2.1-compatible queries. --- diff --git a/org.glite.lb.common/interface/context-int.h b/org.glite.lb.common/interface/context-int.h index e7a2954..55d4a61 100644 --- a/org.glite.lb.common/interface/context-int.h +++ b/org.glite.lb.common/interface/context-int.h @@ -59,6 +59,7 @@ struct _edg_wll_Context { int rgma_export; int strict_locking; /* lock jobs for storing event too */ + int is_V21; /* true if old (V21) request arrived */ /* server limits */ int softLimit; diff --git a/org.glite.lb.common/interface/mini_http.h b/org.glite.lb.common/interface/mini_http.h index beea6e7..c3d7bb0 100644 --- a/org.glite.lb.common/interface/mini_http.h +++ b/org.glite.lb.common/interface/mini_http.h @@ -8,10 +8,12 @@ /* XXX: not a good place for the folowing #def's but we ain't got better currently */ /** protocol version */ #define PROTO_VERSION "3.0" +#define PROTO_VERSION_V21 "2.1" /** backward protocol compatibility */ /* version separated by comma */ /* e.g. "1.0,1.2,1.3" */ #define COMP_PROTO "3.0" +#define COMP_PROTO_V21 "2.0,2.1" /* subset of HTTP codes we return */ diff --git a/org.glite.lb.common/interface/xml_conversions.h b/org.glite.lb.common/interface/xml_conversions.h index bb1d307..246c488 100644 --- a/org.glite.lb.common/interface/xml_conversions.h +++ b/org.glite.lb.common/interface/xml_conversions.h @@ -43,6 +43,7 @@ typedef struct _edg_wll_XML_ctx { edg_wll_QueryRec **job_conditions; /* temporal results */ edg_wll_QueryRec **event_conditions; enum edg_wll_QueryType type; + edg_wll_QueryRec **conditions; int flags; edg_wlc_JobId *jobsOutGlobal; edg_wll_Event *eventsOutGlobal; diff --git a/org.glite.lb.common/src/xml_conversions.c b/org.glite.lb.common/src/xml_conversions.c index a953fae..d9a6dce 100644 --- a/org.glite.lb.common/src/xml_conversions.c +++ b/org.glite.lb.common/src/xml_conversions.c @@ -35,6 +35,7 @@ void edg_wll_initXMLCtx(edg_wll_XML_ctx *c) { c->job_conditions = NULL; c->event_conditions = NULL; c->type = EDG_WLL_QUERY_TYPE_UNDEF; + c->conditions = NULL; c->flags = 0; c->jobsOutGlobal = NULL; c->eventsOutGlobal = NULL; diff --git a/org.glite.lb.server/Makefile b/org.glite.lb.server/Makefile index dff25cb..b2b2106 100644 --- a/org.glite.lb.server/Makefile +++ b/org.glite.lb.server/Makefile @@ -70,6 +70,7 @@ HELPERS:= -L${stagedir}/lib -lglite_wms_tls_ssl_helpers SERVER_OBJS:= bkserverd.o get_events.o index.o jobstat.o jobstat_supp.o \ write2rgma.o lbs_db.o lb_html.o lb_http.o lb_proto.o lb_xml_parse.o \ + lb_xml_parse_V21.o \ lock.o openserver.o query.o userjobs.o db_store.o request.o store.o \ stored_master.o srv_purge.o server_state.o dump.o lb_authz.o load.o \ notification.o il_notification.o notif_match.o diff --git a/org.glite.lb.server/src/lb_proto.c b/org.glite.lb.server/src/lb_proto.c index 240f795..4ab0453 100644 --- a/org.glite.lb.server/src/lb_proto.c +++ b/org.glite.lb.server/src/lb_proto.c @@ -21,12 +21,12 @@ #include "get_events.h" #include "purge.h" #include "lb_xml_parse.h" +#include "lb_xml_parse_V21.h" #define METHOD_GET "GET " #define METHOD_POST "POST " -#define KEY_JOBS "/userJobs/" #define KEY_QUERY_JOBS "/queryJobs " #define KEY_QUERY_EVENTS "/queryEvents " #define KEY_PURGE_REQUEST "/purgeRequest " @@ -85,6 +85,47 @@ char *edg_wll_HTTPErrorMessage(int errCode) return msg; } + +/* returns non-zero if old style (V21) protocols incompatible */ +static int is_protocol_incompatibleV21(char *user_agent) +{ + char *version, *comp_proto, *needle; + double v, c, my_v = strtod(PROTO_VERSION_V21, (char **) NULL), my_c; + + + /* get version od the other side */ + if ((version = strstr(user_agent,"/")) == NULL) return(-1); + else v = strtod(++version, &needle); + + /* sent the other side list of compatible protocols? */ + if ( needle[0] == '\0' ) return(-2); + + /* test compatibility if server newer*/ + if (my_v > v) { + comp_proto=COMP_PROTO_V21; + do { + my_c = strtod(comp_proto, &needle); + if (my_c == v) return(0); + comp_proto = needle + 1; + } while (needle[0] != '\0'); + return(1); + } + + /* test compatibility if server is older */ + else if (my_v < v) { + do { + comp_proto = needle + 1; + c = strtod(comp_proto, &needle); + if (my_v == c) return(0); + } while (needle[0] != '\0'); + return(1); + } + + /* version match */ + return(0); +} + + /* returns non-zero if protocols incompatible */ static int is_protocol_incompatible(char *user_agent) { @@ -144,11 +185,199 @@ static int outputHTML(char **headers) + +edg_wll_ErrorCode edg_wll_ProtoV21(edg_wll_Context ctx, + char *request,char **headers,char *messageBody, + char **response,char ***headersOut,char **bodyOut) +{ + char *requestPTR, *message = NULL; + int ret = HTTP_OK; + int html = outputHTML(headers); + int i; + + edg_wll_ResetError(ctx); + + for (i=0; headers[i]; i++) /* find line with version number in headers */ + if ( strstr(headers[i], KEY_AGENT) ) break; + + if (headers[i] == NULL) { ret = HTTP_BADREQ; goto errV21; } /* if not present */ + switch (is_protocol_incompatibleV21(headers[i])) { + case 0 : /* protocols compatible */ + ctx->is_V21 = 1; + break; + case -1 : /* malformed 'User Agent:' line */ + ret = HTTP_BADREQ; + goto errV21; + break; + case -2 : /* version of one protocol unknown */ + /* fallthrough */ + case 1 : /* protocols incompatible */ + /* fallthrough */ + default : ret = HTTP_UNSUPPORTED; + edg_wll_SetError(ctx,ENOTSUP,"Protocol versions are incompatible."); + goto errV21; + break; + } + + +/* GET */ + if (!strncmp(request, METHOD_GET, sizeof(METHOD_GET)-1)) { + // Not supported + ret = HTTP_BADREQ; +/* POST */ + } else if (!strncmp(request,METHOD_POST,sizeof(METHOD_POST)-1)) { + + requestPTR = request + sizeof(METHOD_POST)-1; + + if (!strncmp(requestPTR,KEY_QUERY_EVENTS,sizeof(KEY_QUERY_EVENTS)-1)) { + edg_wll_Event *eventsOut = NULL; + edg_wll_QueryRec **job_conditions = NULL, **event_conditions = NULL; + int i,j; + + if (parseQueryEventsRequestV21(ctx, messageBody, &job_conditions, &event_conditions)) + ret = HTTP_BADREQ; + + else { + int fatal = 0; + + switch (edg_wll_QueryEventsServer(ctx,ctx->noAuth, + (const edg_wll_QueryRec **)job_conditions, + (const edg_wll_QueryRec **)event_conditions, &eventsOut)) { + + case 0: if (html) ret = HTTP_NOTIMPL; + else ret = HTTP_OK; + break; + case ENOENT: ret = HTTP_NOTFOUND; break; + case EPERM : ret = HTTP_UNAUTH; break; + case EDG_WLL_ERROR_NOINDEX: ret = HTTP_UNAUTH; break; + case ENOMEM: fatal = 1; ret = HTTP_INTERNAL; break; + default: ret = HTTP_INTERNAL; break; + } + /* glue errors (if eny) to XML responce */ + if (!html && !fatal) + if (edg_wll_QueryEventsToXMLV21(ctx, eventsOut, &message)) + ret = HTTP_INTERNAL; + } + + if (job_conditions) { + for (j = 0; job_conditions[j]; j++) { + for (i = 0 ; (job_conditions[j][i].attr != EDG_WLL_QUERY_ATTR_UNDEF); i++ ) + edg_wll_QueryRecFree(&job_conditions[j][i]); + free(job_conditions[j]); + } + free(job_conditions); + } + + if (event_conditions) { + for (j = 0; event_conditions[j]; j++) { + for (i = 0 ; (event_conditions[j][i].attr != EDG_WLL_QUERY_ATTR_UNDEF); i++ ) + edg_wll_QueryRecFree(&event_conditions[j][i]); + free(event_conditions[j]); + } + free(event_conditions); + } + + if (eventsOut != NULL) { + for (i=0; eventsOut[i].type != EDG_WLL_EVENT_UNDEF; i++) + edg_wll_FreeEvent(&(eventsOut[i])); + edg_wll_FreeEvent(&(eventsOut[i])); /* free last line */ + free(eventsOut); + } + } + else if (!strncmp(requestPTR,KEY_QUERY_JOBS,sizeof(KEY_QUERY_JOBS)-1)) { + edg_wlc_JobId *jobsOut = NULL; + edg_wll_JobStat *statesOut = NULL; + edg_wll_QueryRec **conditions = NULL; + int i,j, flags = 0; + + if (parseQueryJobsRequestV21(ctx, messageBody, &conditions, &flags)) + ret = HTTP_BADREQ; + + else { + int fatal = 0, + retCode; + + if (flags & EDG_WLL_STAT_NO_JOBS) { + flags -= EDG_WLL_STAT_NO_JOBS; + jobsOut = NULL; + if (flags & EDG_WLL_STAT_NO_STATES) { + flags -= EDG_WLL_STAT_NO_STATES; + statesOut = NULL; + retCode = edg_wll_QueryJobsServer(ctx, (const edg_wll_QueryRec **)conditions, flags, NULL, NULL); + } + else + retCode = edg_wll_QueryJobsServer(ctx, (const edg_wll_QueryRec **)conditions, flags, NULL, &statesOut); + } + else { + if (flags & EDG_WLL_STAT_NO_STATES) { + flags -= EDG_WLL_STAT_NO_STATES; + statesOut = NULL; + retCode = edg_wll_QueryJobsServer(ctx, (const edg_wll_QueryRec **)conditions, flags, &jobsOut, NULL); + } + else + retCode = edg_wll_QueryJobsServer(ctx, (const edg_wll_QueryRec **)conditions, flags, &jobsOut, &statesOut); + } + + switch ( retCode ) { + // case EPERM : ret = HTTP_UNAUTH; + // /* soft-error fall through */ + case 0: if (html) ret = HTTP_NOTIMPL; + else ret = HTTP_OK; + + break; + case ENOENT: ret = HTTP_NOTFOUND; break; + case EPERM: ret = HTTP_UNAUTH; break; + case EDG_WLL_ERROR_NOINDEX: ret = HTTP_UNAUTH; break; + case ENOMEM: fatal = 1; ret = HTTP_INTERNAL; break; + default: ret = HTTP_INTERNAL; break; + } + if (!html && !fatal) + if (edg_wll_QueryJobsToXMLV21(ctx, jobsOut, statesOut, &message)) + ret = HTTP_INTERNAL; + } + + if (conditions) { + for (j = 0; conditions[j]; j++) { + for (i = 0; (conditions[j][i].attr != EDG_WLL_QUERY_ATTR_UNDEF); i++ ) + edg_wll_QueryRecFree(&conditions[j][i]); + free(conditions[j]); + } + free(conditions); + } + + if (jobsOut) { + for (i=0; jobsOut[i]; i++) edg_wlc_JobIdFree(jobsOut[i]); + free(jobsOut); + } + if (statesOut) { + for (i=0; statesOut[i].state != EDG_WLL_JOB_UNDEF; i++) + edg_wll_FreeStatus(&(statesOut[i])); + edg_wll_FreeStatus(&(statesOut[i])); /* free last line */ + free(statesOut); + } + } + /* POST [something else]: not understood */ + else ret = HTTP_BADREQ; + +/* other HTTP methods */ + } else ret = HTTP_NOTALLOWED; + +errV21: asprintf(response,"HTTP/1.1 %d %s",ret,edg_wll_HTTPErrorMessage(ret)); + *headersOut = (char **) response_headers; + if ((ret != HTTP_OK) && html) + *bodyOut = edg_wll_ErrorToHTML(ctx,ret); + else + *bodyOut = message; + + return edg_wll_Error(ctx,NULL,NULL); +} + + + edg_wll_ErrorCode edg_wll_Proto(edg_wll_Context ctx, char *request,char **headers,char *messageBody, char **response,char ***headersOut,char **bodyOut) { - //char *requestPTR, *pom, *message = NULL; Ely 16/10 unused variable `pom' char *requestPTR, *message = NULL; int ret = HTTP_OK; int html = outputHTML(headers); @@ -162,14 +391,21 @@ edg_wll_ErrorCode edg_wll_Proto(edg_wll_Context ctx, if (headers[i] == NULL) { ret = HTTP_BADREQ; goto err; } /* if not present */ switch (is_protocol_incompatible(headers[i])) { case 0 : /* protocols compatible */ + ctx->is_V21 = 0; break; case -1 : /* malformed 'User Agent:' line */ ret = HTTP_BADREQ; goto err; break; - case -2 : /* version of one protocol unknown */ - /* fallthrough */ case 1 : /* protocols incompatible */ + /* try old (V21) version compatibility */ + edg_wll_ProtoV21(ctx, request, headers, messageBody, + response, headersOut, bodyOut); + + /* and propagate errors or results */ + return edg_wll_Error(ctx,NULL,NULL); + break; + case -2 : /* version of one protocol unknown */ /* fallthrough */ default : ret = HTTP_UNSUPPORTED; edg_wll_SetError(ctx,ENOTSUP,"Protocol versions are incompatible."); @@ -552,9 +788,6 @@ edg_wll_ErrorCode edg_wll_Proto(edg_wll_Context ctx, } else ret = HTTP_NOTALLOWED; err: asprintf(response,"HTTP/1.1 %d %s",ret,edg_wll_HTTPErrorMessage(ret)); - //(*headersOut) = malloc(2*sizeof(**headersOut)); - //(*headersOut)[0] = strdup("Cache-Control: no-cache"); - //(*headersOut)[1] = NULL; *headersOut = (char **) response_headers; if ((ret != HTTP_OK) && html) *bodyOut = edg_wll_ErrorToHTML(ctx,ret); diff --git a/org.glite.lb.server/src/lb_xml_parse.c.T b/org.glite.lb.server/src/lb_xml_parse.c.T index 92fcefd..3a42b20 100644 --- a/org.glite.lb.server/src/lb_xml_parse.c.T +++ b/org.glite.lb.server/src/lb_xml_parse.c.T @@ -1459,7 +1459,7 @@ int edg_wll_UserJobsToXML(edg_wll_Context ctx, edg_wlc_JobId *jobsOut, char **me return 0; } -void edg_wll_add_stslist_to_XMLBody(edg_wll_Context ctx, char **body, const edg_wll_JobStat *toAdd, const char *tag, const char *UNUSED_subTag, const int null) +static void edg_wll_add_stslist_to_XMLBody(edg_wll_Context ctx, char **body, const edg_wll_JobStat *toAdd, const char *tag, const char *UNUSED_subTag, const int null) { char *pomA, *pomB, *newBody; char **list = NULL; diff --git a/org.glite.lb.server/src/lb_xml_parse.h b/org.glite.lb.server/src/lb_xml_parse.h index 51db4cf..c602823 100644 --- a/org.glite.lb.server/src/lb_xml_parse.h +++ b/org.glite.lb.server/src/lb_xml_parse.h @@ -27,6 +27,5 @@ int edg_wll_DumpResultToXML(edg_wll_Context ctx, edg_wll_DumpResult *result, cha int edg_wll_LoadResultToXML(edg_wll_Context ctx, edg_wll_LoadResult *result, char **message); int edg_wll_IndexedAttrsToXML(edg_wll_Context ctx, char **message); int edg_wll_NotifResultToXML(edg_wll_Context ctx, time_t validity, char **message); -void edg_wll_ErrorToXML(edg_wll_Context, char **); #endif diff --git a/org.glite.lb.server/src/lb_xml_parse_V21.c.T b/org.glite.lb.server/src/lb_xml_parse_V21.c.T new file mode 100644 index 0000000..caec4f8 --- /dev/null +++ b/org.glite.lb.server/src/lb_xml_parse_V21.c.T @@ -0,0 +1,1239 @@ +#ident "$Header$" + +#include +#include +#include +#include +#include + +#include "glite/wms/jobid/cjobid.h" + +#include "glite/lb/consumer.h" +#include "glite/lb/escape.h" +#include "glite/lb/context-int.h" +#include "glite/lb/trio.h" +#include "glite/lb/xml_conversions.h" + +#include "glite/lb/purge.h" +#include "glite/lb/dump.h" + +#include "lb_xml_parse_V21.h" + +#ifdef __GNUC__ +#define UNUSED_VAR __attribute__((unused)) +#else +#define UNUSED_VAR +#endif + +#define QUERY_EVENTS_BEGIN "\r\n" +#define QUERY_JOBS_BEGIN "\r\n" +#define PURGE_RESULT_BEGIN "\r\n" +#define DUMP_RESULT_BEGIN "\r\n" + +// XXX will be redundant soon +#define USERJOBS_BEGIN "\r\n" + + +static char *ops[] = { "equal","less","greater","within" }, + *attrs[] = { "jobid","owner","status","location","destination", + "donecode","usertag","time","level","host","source", + "instance","type","chkpt_tag", "resubmitted", "parent_job", "exitcode" }; + +static const struct timeval null_timeval = {0,0}; + +#define unexp() {\ + char *e;\ +\ + if (XMLCtx->errtxt) {\ + asprintf(&e,"%s\nunexpected <%s> at line %d",XMLCtx->errtxt,\ + el,XML_GetCurrentLineNumber(XMLCtx->p));\ + free(XMLCtx->errtxt);\ + } else asprintf(&e,"unexpected <%s> at line %d",\ + el,XML_GetCurrentLineNumber(XMLCtx->p));\ + XMLCtx->errtxt = e;\ +} + + +/* Dummy function, returns only const string "el"; just for compatibility */ +static char *return_string_el(edg_wll_JobStatCode statCode) { + return("el"); +} + + +static void startQueryJobsRequest(void *data, const char *el, const char **attr) +{ + unsigned int i; + edg_wll_XML_ctx *XMLCtx = data; + + + strcpy(XMLCtx->element, el); + + switch (XMLCtx->level) { + case 0: if (strcasecmp(el,"edg_wll_QueryJobsRequest")) { unexp() break; } + for ( i = 0; attr[i] && attr[i+1]; i += 2 ) + { + if ( !strcmp(attr[i],"softLimit") ) + XMLCtx->ctx->softLimit = atoi(attr[i+1]); + else if ( !strcmp(attr[i],"queryRes") ) + XMLCtx->ctx->p_query_results = atoi(attr[i+1]); + else { unexp() break; } + } + break; + case 1: if (strcasecmp(el,"and") && strcasecmp(el,"flags")) unexp() + break; + case 2: if (strcasecmp(el,"or")) unexp() + else { + XMLCtx->position = -1; + XMLCtx->conditions = realloc(XMLCtx->conditions, + (++XMLCtx->row+2)*sizeof(*XMLCtx->conditions)); + XMLCtx->conditions[XMLCtx->row] = NULL; + XMLCtx->conditions[XMLCtx->row+1] = NULL; + } + break; + case 3: + for (i=0; iconditions[XMLCtx->row] = realloc(XMLCtx->conditions[XMLCtx->row], + (++XMLCtx->position+2)*sizeof(**XMLCtx->conditions)); + memset(&XMLCtx->conditions[XMLCtx->row][XMLCtx->position],0,2*sizeof(**XMLCtx->conditions)); + XMLCtx->conditions[XMLCtx->row][XMLCtx->position].op = i; + XMLCtx->bound = 0; + } + break; + case 4: for (i=0; iconditions[XMLCtx->row][XMLCtx->position].attr_id.tag = strdup(attr[1]); + } + else if ( (i+1) == EDG_WLL_QUERY_ATTR_TIME) { + if (!attr[0] || !attr[1]) { unexp() break;} + if (attr[0] && strcmp(attr[0],"state")) { unexp() break;} + XMLCtx->conditions[XMLCtx->row][XMLCtx->position].attr_id.state = edg_wll_StringToStat(attr[1]); + } + XMLCtx->conditions[XMLCtx->row][XMLCtx->position].attr = i+1; + } + break; + default: unexp(); break; + } + XMLCtx->level++; +} + + +static void startQueryEventsRequest(void *data, const char *el, const char **attr UNUSED_VAR) +{ + unsigned int i; + edg_wll_XML_ctx *XMLCtx = data; + + + strcpy(XMLCtx->element, el); + + switch (XMLCtx->level) { + case 0: if (strcasecmp(el,"edg_wll_QueryEventsRequest")) { unexp() break; } + for ( i = 0; attr[i] && attr[i+1]; i += 2 ) + { + if ( !strcmp(attr[i],"softLimit") ) + XMLCtx->ctx->softLimit = atoi(attr[i+1]); + else if ( !strcmp(attr[i],"queryRes") ) + XMLCtx->ctx->p_query_results = atoi(attr[i+1]); + else { unexp() break; } + } + break; + case 1: if (strcasecmp(el,"and")) unexp() + break; + case 2: if (!strcasecmp(el,"orJobConditions")) { + XMLCtx->type = EDG_WLL_QUERY_TYPE_JOB_CONDITION; + XMLCtx->position = -1; + XMLCtx->job_conditions = realloc(XMLCtx->job_conditions, + (++XMLCtx->row+2)*sizeof(*XMLCtx->job_conditions)); + XMLCtx->job_conditions[XMLCtx->row] = NULL; + XMLCtx->job_conditions[XMLCtx->row+1] = NULL; + + } + else if (!strcasecmp(el,"orEventConditions")) { + XMLCtx->type = EDG_WLL_QUERY_TYPE_EVENT_CONDITION; + XMLCtx->position2 = -1; + XMLCtx->event_conditions = realloc(XMLCtx->event_conditions, + (++XMLCtx->row2+2)*sizeof(*XMLCtx->event_conditions)); + XMLCtx->event_conditions[XMLCtx->row2] = NULL; + XMLCtx->event_conditions[XMLCtx->row2+1] = NULL; + } + else unexp() + break; + case 3: + for (i=0; itype == EDG_WLL_QUERY_TYPE_JOB_CONDITION) { + /* malloc also terminator and set it to 0 (= EDG_WLL_QUERY_ATTR_UNDEF) */ + XMLCtx->job_conditions[XMLCtx->row] = realloc(XMLCtx->job_conditions[XMLCtx->row], + (++XMLCtx->position+2)*sizeof(**XMLCtx->job_conditions)); + memset(&XMLCtx->job_conditions[XMLCtx->row][XMLCtx->position],0,2*sizeof(**XMLCtx->job_conditions)); + XMLCtx->job_conditions[XMLCtx->row][XMLCtx->position].op = i; + XMLCtx->bound = 0; + } + else if (XMLCtx->type == EDG_WLL_QUERY_TYPE_EVENT_CONDITION) { + /* malloc also terminator and set it to 0 (= EDG_WLL_QUERY_ATTR_UNDEF) */ + XMLCtx->event_conditions[XMLCtx->row2] = realloc(XMLCtx->event_conditions[XMLCtx->row2], + (++XMLCtx->position2+2)*sizeof(**XMLCtx->event_conditions)); + memset(&XMLCtx->event_conditions[XMLCtx->row2][XMLCtx->position2],0,2*sizeof(**XMLCtx->event_conditions)); + XMLCtx->event_conditions[XMLCtx->row2][XMLCtx->position2].op = i; + XMLCtx->bound = 0; + } + + break; + case 4: for (i=0; itype == EDG_WLL_QUERY_TYPE_JOB_CONDITION) { + if ( (i+1) == EDG_WLL_QUERY_ATTR_USERTAG) { + if (!attr[0] || !attr[1]) { unexp() break;} + if (attr[0] && strcmp(attr[0],"name")) { unexp() break;} + XMLCtx->job_conditions[XMLCtx->row][XMLCtx->position].attr_id.tag = strdup(attr[1]); + } + else if ( (i+1) == EDG_WLL_QUERY_ATTR_TIME) { + if (!attr[0] || !attr[1]) { unexp() break;} + if (attr[0] && strcmp(attr[0],"state")) { unexp() break;} + XMLCtx->job_conditions[XMLCtx->row][XMLCtx->position].attr_id.state = edg_wll_StringToStat(attr[1]); + printf("\nchecking time attr\n%s = %s (%d)\n\n", attr[0], attr[1], edg_wll_StringToStat(attr[1])); + } + XMLCtx->job_conditions[XMLCtx->row][XMLCtx->position].attr = i+1; + } + else if (XMLCtx->type == EDG_WLL_QUERY_TYPE_EVENT_CONDITION) { + if ( (i+1) == EDG_WLL_QUERY_ATTR_USERTAG) { + if (!attr[0] || !attr[1]) { unexp() break;} + if (attr[0] && strcmp(attr[0],"name")) { unexp() break;} + XMLCtx->event_conditions[XMLCtx->row2][XMLCtx->position].attr_id.tag = strdup(attr[1]); + } + else if ( (i+1) == EDG_WLL_QUERY_ATTR_TIME) { + if (!attr[0] || !attr[1]) { unexp() break;} + if (attr[0] && strcmp(attr[0],"state")) { unexp() break;} + XMLCtx->event_conditions[XMLCtx->row2][XMLCtx->position].attr_id.state = edg_wll_StringToStat(attr[1]); + } + XMLCtx->event_conditions[XMLCtx->row2][XMLCtx->position2].attr = i+1; + } + break; + default: unexp(); break; + } + XMLCtx->level++; +} + + + +static void startPurgeRequest(void *data, const char *el, const char **attr) +{ + edg_wll_XML_ctx *XMLCtx = data; + + + strcpy(XMLCtx->element, el); + + switch (XMLCtx->level) { + case 0: if (strcasecmp(el,"edg_wll_PurgeRequest")) unexp() + break; + case 1: if (strcasecmp(el,"jobs") && strcasecmp(el,"timeout") + && strcasecmp(el,"flags")) unexp() + else + XMLCtx->position = 0; + break; + case 2: if (!strcasecmp(el,"jobId")) { + XMLCtx->purgeRequestGlobal.jobs = realloc(XMLCtx->purgeRequestGlobal.jobs, + (XMLCtx->position+2) * sizeof(XMLCtx->purgeRequestGlobal.jobs)); + + if (!XMLCtx->purgeRequestGlobal.jobs) { + edg_wll_SetError(XMLCtx->ctx, ENOMEM, NULL); + unexp() return; + } + XMLCtx->purgeRequestGlobal.jobs[XMLCtx->position+1] = NULL; + } + else if (!strcasecmp(el,"time")) { + /* static array, no need to initialize & allocate anything */ + } + else + unexp() + break; + default: unexp() + break; + } + XMLCtx->level++; +} + + +static void startDumpRequest(void *data, const char *el, const char **attr) +{ + edg_wll_XML_ctx *XMLCtx = data; + + + strcpy(XMLCtx->element, el); + + switch (XMLCtx->level) { + case 0: if (strcasecmp(el,"edg_wll_DumpRequest")) unexp() + break; + case 1: if (strcasecmp(el,"from") && strcasecmp(el,"to")) unexp() + break; + default: unexp() + break; + } + XMLCtx->level++; +} + +#undef unexp + + +static void char_handler(void *data, const char *s, int len) +{ + edg_wll_XML_ctx *XMLCtx = data; + int i, found = -1, temp_len1; + char *temp_s, *temp_s1; + + + /* if date are only spaces, t\, \r, \n ... don't bother with them */ + for (i=0; ichar_buf_len) XMLCtx->char_buf = + realloc(XMLCtx->char_buf,XMLCtx->char_buf_len+temp_len1 + 1); + else XMLCtx->char_buf = malloc(temp_len1 + 1); + + memcpy(XMLCtx->char_buf+XMLCtx->char_buf_len,temp_s1,temp_len1 + 1); + XMLCtx->char_buf_len += temp_len1; + free(temp_s1); + free(temp_s); +} + + + +static void endQueryJobsRequest(void *data, const char *el UNUSED_VAR) +{ + edg_wll_XML_ctx *XMLCtx = data; + char *e; + + + if (XMLCtx->level == 2) { + if (!strcmp(XMLCtx->element,"flags") && XMLCtx->char_buf) { +// XXX: check if it works + XMLCtx->flags = edg_wll_string_to_stat_flags(XMLCtx->char_buf); + } + } + else if (XMLCtx->level == 5) { + switch (XMLCtx->conditions[XMLCtx->row][XMLCtx->position].attr) { + case EDG_WLL_QUERY_ATTR_JOBID: + case EDG_WLL_QUERY_ATTR_PARENT: + if ( (XMLCtx->conditions[XMLCtx->row][XMLCtx->position].value.j = + edg_wll_from_string_to_jobid(XMLCtx)) == NULL ) + { + if (XMLCtx->errtxt) { + asprintf(&e,"%s\n%s: invalid JobId at line %d", + XMLCtx->errtxt, XMLCtx->char_buf, + XML_GetCurrentLineNumber(XMLCtx->p)); + free(XMLCtx->errtxt); + } else asprintf(&e,"%s: invalid JobId at line %d", + XMLCtx->char_buf,XML_GetCurrentLineNumber(XMLCtx->p)); + XMLCtx->errtxt = e; + } + break; + case EDG_WLL_QUERY_ATTR_OWNER: + // XXX - this is way how to pass NULL, user will be extracted from ssl partner later + if (XMLCtx->char_buf != NULL && !strcmp(XMLCtx->char_buf,"NULL")) { + XMLCtx->conditions[XMLCtx->row][XMLCtx->position].value.c = NULL; + break; + } + else /* fall through */ + case EDG_WLL_QUERY_ATTR_LOCATION: + case EDG_WLL_QUERY_ATTR_DESTINATION: + case EDG_WLL_QUERY_ATTR_USERTAG: + XMLCtx->conditions[XMLCtx->row][XMLCtx->position].value.c = + edg_wll_from_string_to_string(XMLCtx); + break; + case EDG_WLL_QUERY_ATTR_STATUS: + case EDG_WLL_QUERY_ATTR_DONECODE: + case EDG_WLL_QUERY_ATTR_EXITCODE: + case EDG_WLL_QUERY_ATTR_RESUBMITTED: + if ( !XMLCtx->bound ) + { + XMLCtx->conditions[XMLCtx->row][XMLCtx->position].value.i = + edg_wll_from_string_to_int(XMLCtx); + XMLCtx->bound++; + } + else + XMLCtx->conditions[XMLCtx->row][XMLCtx->position].value2.i = + edg_wll_from_string_to_int(XMLCtx); + + break; + case EDG_WLL_QUERY_ATTR_TIME: + if ( !XMLCtx->bound ) + { + XMLCtx->conditions[XMLCtx->row][XMLCtx->position].value.t.tv_sec = + edg_wll_from_string_to_time_t(XMLCtx); + XMLCtx->bound++; + } + else + XMLCtx->conditions[XMLCtx->row][XMLCtx->position].value2.t.tv_sec = + edg_wll_from_string_to_time_t(XMLCtx); + break; + default: + edg_wll_freeBuf(XMLCtx); + XMLCtx->level--; + if (XMLCtx->errtxt) { + asprintf(&e,"%s\n%s: invalid attribute type at line %d", + XMLCtx->errtxt, XMLCtx->char_buf, + XML_GetCurrentLineNumber(XMLCtx->p)); + free(XMLCtx->errtxt); + } else asprintf(&e,"%s: invalid attribute type at line %d", + XMLCtx->char_buf,XML_GetCurrentLineNumber(XMLCtx->p)); + XMLCtx->errtxt = e; + break; + } + } + XMLCtx->char_buf = NULL; + XMLCtx->char_buf_len = 0; + XMLCtx->level--; +} + + +static void endQueryEventsRequest(void *data, const char *el UNUSED_VAR) +{ + edg_wll_XML_ctx *XMLCtx = data; + char *e; + + if (XMLCtx->level == 2) { + if (!strcmp(XMLCtx->element,"orJobConditions")) { + /* make end-of-row */ + XMLCtx->job_conditions[XMLCtx->row] = realloc(XMLCtx->job_conditions[XMLCtx->row], + (++XMLCtx->position+1)*sizeof(**XMLCtx->job_conditions)); + memset(&XMLCtx->job_conditions[XMLCtx->row][XMLCtx->position],0,sizeof(**XMLCtx->job_conditions)); + } + else if (!strcmp(XMLCtx->element,"orEventConditions")) { + /* make end-of-row */ + XMLCtx->event_conditions[XMLCtx->row2] = realloc(XMLCtx->event_conditions[XMLCtx->row2], + (++XMLCtx->position2+1)*sizeof(**XMLCtx->event_conditions)); + memset(&XMLCtx->event_conditions[XMLCtx->row2][XMLCtx->position2],0,sizeof(**XMLCtx->event_conditions)); + } + } + else if (XMLCtx->level == 5) { + if (XMLCtx->type == EDG_WLL_QUERY_TYPE_JOB_CONDITION) { + switch (XMLCtx->job_conditions[XMLCtx->row][XMLCtx->position].attr) { + case EDG_WLL_QUERY_ATTR_JOBID: + case EDG_WLL_QUERY_ATTR_PARENT: + if ( (XMLCtx->job_conditions[XMLCtx->row][XMLCtx->position].value.j = + edg_wll_from_string_to_jobid(XMLCtx)) == NULL ) + { + if (XMLCtx->errtxt) { + asprintf(&e,"%s\n%s: invalid JobId at line %d", + XMLCtx->errtxt, XMLCtx->char_buf, + XML_GetCurrentLineNumber(XMLCtx->p)); + free(XMLCtx->errtxt); + } else asprintf(&e,"%s: invalid JobId at line %d", + XMLCtx->char_buf,XML_GetCurrentLineNumber(XMLCtx->p)); + XMLCtx->errtxt = e; + } + break; + case EDG_WLL_QUERY_ATTR_OWNER: + case EDG_WLL_QUERY_ATTR_LOCATION: + case EDG_WLL_QUERY_ATTR_DESTINATION: + case EDG_WLL_QUERY_ATTR_USERTAG: + XMLCtx->job_conditions[XMLCtx->row][XMLCtx->position].value.c = + edg_wll_from_string_to_string(XMLCtx); + break; + case EDG_WLL_QUERY_ATTR_STATUS: + case EDG_WLL_QUERY_ATTR_DONECODE: + case EDG_WLL_QUERY_ATTR_EXITCODE: + case EDG_WLL_QUERY_ATTR_RESUBMITTED: + if ( !XMLCtx->bound ) + { + XMLCtx->job_conditions[XMLCtx->row][XMLCtx->position].value.i = + edg_wll_from_string_to_int(XMLCtx); + XMLCtx->bound++; + } + else + XMLCtx->job_conditions[XMLCtx->row][XMLCtx->position].value2.i = + edg_wll_from_string_to_int(XMLCtx); + break; + case EDG_WLL_QUERY_ATTR_TIME: + if ( !XMLCtx->bound ) + { + XMLCtx->job_conditions[XMLCtx->row][XMLCtx->position].value.t.tv_sec = + edg_wll_from_string_to_time_t(XMLCtx); + XMLCtx->bound++; + } + else + XMLCtx->job_conditions[XMLCtx->row][XMLCtx->position].value2.t.tv_sec = + edg_wll_from_string_to_time_t(XMLCtx); + break; + default: + edg_wll_freeBuf(XMLCtx); + XMLCtx->level--; + if (XMLCtx->errtxt) { + asprintf(&e,"%s\n%s: invalid attribute type at line %d", + XMLCtx->errtxt, XMLCtx->char_buf, + XML_GetCurrentLineNumber(XMLCtx->p)); + free(XMLCtx->errtxt); + } else asprintf(&e,"%s: invalid attribute type at line %d", + XMLCtx->char_buf,XML_GetCurrentLineNumber(XMLCtx->p)); + XMLCtx->errtxt = e; + break; + } + } + else if (XMLCtx->type == EDG_WLL_QUERY_TYPE_EVENT_CONDITION) { + switch (XMLCtx->event_conditions[XMLCtx->row2][XMLCtx->position2].attr) { + case EDG_WLL_QUERY_ATTR_TIME: + if ( !XMLCtx->bound ) + { + XMLCtx->event_conditions[XMLCtx->row2][XMLCtx->position2].value.t.tv_sec = + edg_wll_from_string_to_time_t(XMLCtx); + XMLCtx->bound++; + } + else + XMLCtx->event_conditions[XMLCtx->row2][XMLCtx->position2].value2.t.tv_sec = + edg_wll_from_string_to_time_t(XMLCtx); + break; + case EDG_WLL_QUERY_ATTR_LEVEL: + case EDG_WLL_QUERY_ATTR_SOURCE: + case EDG_WLL_QUERY_ATTR_EVENT_TYPE: + if ( !XMLCtx->bound ) + { + XMLCtx->event_conditions[XMLCtx->row2][XMLCtx->position2].value.i = + edg_wll_from_string_to_int(XMLCtx); + XMLCtx->bound++; + } + else + XMLCtx->event_conditions[XMLCtx->row2][XMLCtx->position2].value2.i = + edg_wll_from_string_to_int(XMLCtx); + break; + case EDG_WLL_QUERY_ATTR_HOST: + case EDG_WLL_QUERY_ATTR_INSTANCE: + case EDG_WLL_QUERY_ATTR_USERTAG: + XMLCtx->event_conditions[XMLCtx->row2][XMLCtx->position2].value.c = + edg_wll_from_string_to_string(XMLCtx); + break; + default: + edg_wll_freeBuf(XMLCtx); + XMLCtx->level--; + if (XMLCtx->errtxt) { + asprintf(&e,"%s\n%s: invalid attribute type at line %d", + XMLCtx->errtxt, XMLCtx->char_buf, + XML_GetCurrentLineNumber(XMLCtx->p)); + free(XMLCtx->errtxt); + } else asprintf(&e,"%s: invalid attribute type at line %d", + XMLCtx->char_buf,XML_GetCurrentLineNumber(XMLCtx->p)); + XMLCtx->errtxt = e; + break; + } + } + + XMLCtx->char_buf = NULL; + XMLCtx->char_buf_len = 0; + } + XMLCtx->level--; +} + + +static void endPurgeRequest(void *data, const char *el UNUSED_VAR) +{ + edg_wll_XML_ctx *XMLCtx = data; + char *e; + + if (XMLCtx->level == 2) { + if (!strcmp(XMLCtx->element,"flags")) + XMLCtx->purgeRequestGlobal.flags = edg_wll_from_string_to_int(XMLCtx); + } + else if (XMLCtx->level == 3) { + if (!strcmp(XMLCtx->element,"jobId")) { + if ( (XMLCtx->purgeRequestGlobal.jobs[XMLCtx->position++] = + edg_wll_from_string_to_string(XMLCtx)) == NULL ) + { + if (XMLCtx->errtxt) { + asprintf(&e,"%s\n%s: invalid JobId at line %d", + XMLCtx->errtxt, XMLCtx->char_buf, + XML_GetCurrentLineNumber(XMLCtx->p)); + free(XMLCtx->errtxt); + } else asprintf(&e,"%s: invalid JobId at line %d", + XMLCtx->char_buf,XML_GetCurrentLineNumber(XMLCtx->p)); + XMLCtx->errtxt = e; + } + } + else if (!strcmp(XMLCtx->element,"time") && XMLCtx->char_buf) { + XMLCtx->purgeRequestGlobal.timeout[XMLCtx->position++] = + edg_wll_from_string_to_time_t(XMLCtx); + } + } + + XMLCtx->char_buf = NULL; + XMLCtx->char_buf_len = 0; + XMLCtx->level--; +} + + +static void endDumpRequest(void *data, const char *el UNUSED_VAR) +{ + edg_wll_XML_ctx *XMLCtx = data; + + if (XMLCtx->level == 2) { + if (!strcmp(XMLCtx->element,"from")) + XMLCtx->dumpRequestGlobal.from = edg_wll_from_string_to_time_t(XMLCtx); + else if (!strcmp(XMLCtx->element,"to")) + XMLCtx->dumpRequestGlobal.to = edg_wll_from_string_to_time_t(XMLCtx); + } + + XMLCtx->char_buf = NULL; + XMLCtx->char_buf_len = 0; + XMLCtx->level--; +} + +/* parse queryJobs request from client */ +int parseQueryJobsRequestV21(edg_wll_Context ctx, char *messageBody, edg_wll_QueryRec ***conditions, int *flags) +{ + int ret; + edg_wll_XML_ctx XMLCtx; + XML_Char *encoding = "ISO-8859-1"; + + errno = 0; + edg_wll_initXMLCtx(&XMLCtx); + XMLCtx.row = -1; + XMLCtx.ctx = ctx; + edg_wll_ResetError(ctx); + + + /* initialize parser */ + XMLCtx.p = XML_ParserCreate(encoding); + XML_SetElementHandler(XMLCtx.p, startQueryJobsRequest, endQueryJobsRequest); + XML_SetCharacterDataHandler(XMLCtx.p, char_handler); + XML_SetUserData(XMLCtx.p, (void *) &XMLCtx); + + + if (! XML_Parse(XMLCtx.p, messageBody, strlen(messageBody), 1)) { + char *errorMessage; + + asprintf(&errorMessage, "Parse error at line %d:\n%s\n", + XML_GetCurrentLineNumber(XMLCtx.p), + XML_ErrorString(XML_GetErrorCode(XMLCtx.p))); + + edg_wll_SetError(ctx, EDG_WLL_ERROR_XML_PARSE, errorMessage); + free(errorMessage); + } else if (XMLCtx.errtxt) edg_wll_SetError(ctx, EDG_WLL_ERROR_XML_PARSE, XMLCtx.errtxt); + + + if ((ret = edg_wll_Error(ctx,NULL,NULL))) { + int i,j; + + if (XMLCtx.conditions) { + for (j = 0; XMLCtx.conditions[j]; j++) { + for (i = 0; (XMLCtx.conditions[j][i].attr != EDG_WLL_QUERY_ATTR_UNDEF); i++ ) + edg_wll_QueryRecFree(&XMLCtx.conditions[j][i]); + free(XMLCtx.conditions[j]); + } + free(XMLCtx.conditions); + } + + /* empty list terminators */ + conditions[0] = NULL; + *flags = 0; + } else { + *conditions = XMLCtx.conditions; + *flags = XMLCtx.flags; + } + + + XML_ParserFree(XMLCtx.p); + edg_wll_freeXMLCtx(&XMLCtx); + return ret; +} + + +/* parse queryEvents request from client */ +int parseQueryEventsRequestV21(edg_wll_Context ctx, char *messageBody, edg_wll_QueryRec ***job_conditions, edg_wll_QueryRec ***event_conditions) +{ + int ret; + edg_wll_XML_ctx XMLCtx; + XML_Char *encoding = "ISO-8859-1"; + + errno = 0; + edg_wll_initXMLCtx(&XMLCtx); + XMLCtx.row = -1; + XMLCtx.row2 = -1; + XMLCtx.ctx = ctx; + edg_wll_ResetError(ctx); + + + /* initialize parser */ + XMLCtx.p = XML_ParserCreate(encoding); + XML_SetElementHandler(XMLCtx.p, startQueryEventsRequest, endQueryEventsRequest); + XML_SetCharacterDataHandler(XMLCtx.p, char_handler); + XML_SetUserData(XMLCtx.p, (void *) &XMLCtx); + + + if (! XML_Parse(XMLCtx.p, messageBody, strlen(messageBody), 1)) { + char *errorMessage; + + asprintf(&errorMessage, "Parse error at line %d:\n%s\n", + XML_GetCurrentLineNumber(XMLCtx.p), + XML_ErrorString(XML_GetErrorCode(XMLCtx.p))); + + edg_wll_SetError(ctx, EDG_WLL_ERROR_XML_PARSE, errorMessage); + free(errorMessage); + } else if (XMLCtx.errtxt) edg_wll_SetError(ctx, EDG_WLL_ERROR_XML_PARSE, XMLCtx.errtxt); + + + if ((ret = edg_wll_Error(ctx,NULL,NULL))) { + int i,j; + + if (XMLCtx.job_conditions) { + for (j = 0; XMLCtx.job_conditions[j]; j++) { + for (i = 0 ; (XMLCtx.job_conditions[j][i].attr != EDG_WLL_QUERY_ATTR_UNDEF); i++ ) + edg_wll_QueryRecFree(&XMLCtx.job_conditions[j][i]); + free(XMLCtx.job_conditions[j]); + } + free(XMLCtx.job_conditions); + } + if (XMLCtx.event_conditions) { + for (j = 0; XMLCtx.event_conditions[j]; j++) { + for (i = 0 ; (XMLCtx.event_conditions[j][i].attr != EDG_WLL_QUERY_ATTR_UNDEF); i++ ) + edg_wll_QueryRecFree(&XMLCtx.event_conditions[j][i]); + free(XMLCtx.event_conditions[j]); + } + free(XMLCtx.event_conditions); + } + + /* empty list terminators */ + job_conditions[0] = NULL; + event_conditions[0] = NULL; + } else { + *job_conditions = XMLCtx.job_conditions; + *event_conditions = XMLCtx.event_conditions; + } + + + XML_ParserFree(XMLCtx.p); + edg_wll_freeXMLCtx(&XMLCtx); + return ret; +} + + + +/* parse purge request from client */ +int parsePurgeRequestV21(edg_wll_Context ctx, char *messageBody, edg_wll_PurgeRequest *request) +{ + int ret; + edg_wll_XML_ctx XMLCtx; + XML_Char *encoding = "ISO-8859-1"; + + errno = 0; + edg_wll_initXMLCtx(&XMLCtx); + XMLCtx.ctx = ctx; + edg_wll_ResetError(ctx); + + + /* initialize parser */ + XMLCtx.p = XML_ParserCreate(encoding); + XML_SetElementHandler(XMLCtx.p, startPurgeRequest, endPurgeRequest); + XML_SetCharacterDataHandler(XMLCtx.p, char_handler); + XML_SetUserData(XMLCtx.p, (void *) &XMLCtx); + + + if (! XML_Parse(XMLCtx.p, messageBody, strlen(messageBody), 1)) { + char *errorMessage; + + asprintf(&errorMessage, "Parse error at line %d:\n%s\n", + XML_GetCurrentLineNumber(XMLCtx.p), + XML_ErrorString(XML_GetErrorCode(XMLCtx.p))); + + edg_wll_SetError(ctx, EDG_WLL_ERROR_XML_PARSE, errorMessage); + free(errorMessage); + } else if (XMLCtx.errtxt) edg_wll_SetError(ctx, EDG_WLL_ERROR_XML_PARSE, XMLCtx.errtxt); + + + if ((ret = edg_wll_Error(ctx,NULL,NULL))) { + int i; + + if (XMLCtx.purgeRequestGlobal.jobs) { + for (i=0; XMLCtx.purgeRequestGlobal.jobs[i]; i++) + free(XMLCtx.purgeRequestGlobal.jobs[i]); + free(XMLCtx.purgeRequestGlobal.jobs); + } + memset(request,0,sizeof(*request)); + + } else { + memcpy(request, &XMLCtx.purgeRequestGlobal, sizeof(XMLCtx.purgeRequestGlobal)); + } + + + XML_ParserFree(XMLCtx.p); + edg_wll_freeXMLCtx(&XMLCtx); + return ret; +} + + + +/* parse dump request from client */ +int parseDumpRequestV21(edg_wll_Context ctx, char *messageBody, edg_wll_DumpRequest *request) +{ + int ret; + edg_wll_XML_ctx XMLCtx; + XML_Char *encoding = "ISO-8859-1"; + + errno = 0; + edg_wll_initXMLCtx(&XMLCtx); + XMLCtx.ctx = ctx; + edg_wll_ResetError(ctx); + + + /* initialize parser */ + XMLCtx.p = XML_ParserCreate(encoding); + XML_SetElementHandler(XMLCtx.p, startDumpRequest, endDumpRequest); + XML_SetCharacterDataHandler(XMLCtx.p, char_handler); + XML_SetUserData(XMLCtx.p, (void *) &XMLCtx); + + + if (! XML_Parse(XMLCtx.p, messageBody, strlen(messageBody), 1)) { + char *errorMessage; + + asprintf(&errorMessage, "Parse error at line %d:\n%s\n", + XML_GetCurrentLineNumber(XMLCtx.p), + XML_ErrorString(XML_GetErrorCode(XMLCtx.p))); + + edg_wll_SetError(ctx, EDG_WLL_ERROR_XML_PARSE, errorMessage); + free(errorMessage); + } else if (XMLCtx.errtxt) edg_wll_SetError(ctx, EDG_WLL_ERROR_XML_PARSE, XMLCtx.errtxt); + + + if ((ret = edg_wll_Error(ctx,NULL,NULL))) + memset(request,0,sizeof(*request)); + + else { + memcpy(request, &XMLCtx.dumpRequestGlobal, sizeof(XMLCtx.dumpRequestGlobal)); + } + + + XML_ParserFree(XMLCtx.p); + edg_wll_freeXMLCtx(&XMLCtx); + return ret; +} + + + +int edg_wll_QueryEventsToXMLV21(edg_wll_Context ctx UNUSED_VAR, edg_wll_Event *eventsOut, char **message) +{ + char *pomA, *pomB; + char **list = NULL; + int i = 0, len, tot_len = 0; + int *len_list = NULL; + + + while (eventsOut && eventsOut[i].any.type != EDG_WLL_EVENT_UNDEF) { + pomB = edg_wll_EventToString(eventsOut[i].any.type); + trio_asprintf(&pomA," \r\n", pomB); + free(pomB); + pomB = pomA; + + +@@@{ + selectType $event '_common_'; + for (getFieldsOrdered $event) { + my $f = selectField $event $_; + my $ft = $f->{type}; + my $n = $f->{null}; + gen "\tedg_wll_add_$ft\_to_XMLBody(&pomB, eventsOut[i].any.$_, \"$_\", $n);\n"; + } + + gen "\tswitch (eventsOut[i].any.type) {\n"; + for my $t (sort { $event->{order}->{$a} <=> $event->{order}->{$b} } getTypes $event) { + if ($t ne 'any') { + selectType $event $t; + my $u = uc $t; + gen "\t case EDG_WLL_EVENT_$u :\n"; + for (getFieldsOrdered $event) { + my $f = selectField $event $_; + my $ft = $f->{type}; + my $n = $f->{null}; + $t = lcfirst $t; + gen "\t\tedg_wll_add_$ft\_to_XMLBody(&pomB, eventsOut[i].$t.$_, \"$_\", $n);\n"; + } + gen "\t\tbreak;\n"; + } + } + gen "\t default : break;\n"; + gen "\t}\n"; +@@@} + + + + len = asprintf(&pomA,"%s \r\n", pomB); + free(pomB); + i++; + tot_len += len; + + list = (char **) realloc(list, i * sizeof(*list)); + list[i-1] = pomA; + len_list = (int *) realloc(len_list, i * sizeof(*len_list)); + len_list[i-1] = len; + + } + + /* list termination */ + list = (char **) realloc(list, (i+1) * sizeof(*list)); + list[i] = NULL; + + /* test errors */ + if (ctx->errDesc || ctx->errCode) + len = trio_asprintf(&pomB," code=\"%d\" desc=\"%|Xs\">\r\n",ctx->errCode,ctx->errDesc); + else + len = asprintf(&pomB,">\r\n"); + + /* glueing all list fields together & freeing the list */ + pomA = (char *) malloc(tot_len * sizeof(char) + + sizeof(QUERY_EVENTS_BEGIN) + len + sizeof(QUERY_EVENTS_END) - 1); + + memcpy(pomA, QUERY_EVENTS_BEGIN, sizeof(QUERY_EVENTS_BEGIN)); + memcpy(pomA + sizeof(QUERY_EVENTS_BEGIN) - 1, pomB, len); + free(pomB); + pomB = pomA + sizeof(QUERY_EVENTS_BEGIN) + len - 1; + + i = 0; + while (list[i]) { + memcpy(pomB, list[i], len_list[i] ); + pomB += len_list[i]; + + /* freeing the list */ + free(list[i]); + + i++; + } + + strcpy(pomB, QUERY_EVENTS_END); + + + free(list); + free(len_list); + + + *message = pomA; + + return 0; +} + +int edg_wll_QueryJobsToXMLV21(edg_wll_Context ctx, edg_wlc_JobId *jobsIn, edg_wll_JobStat *statesIn, char **message) +{ + char *pomA, *pomB, *pomC; + char **list = NULL; + int i = 0, len, tot_len = 0, nres = 0; + int *len_list = NULL; + + + if (jobsIn) for (nres = 0; jobsIn[nres]; nres++); + else if (statesIn) for (nres = 0; statesIn[nres].state; nres++); + + while (i < nres) { + trio_asprintf(&pomA,"\t\r\n"); + pomB = pomA; + + if (jobsIn) { + trio_asprintf(&pomA,"%s\t\t%|Xs\r\n", + pomB, pomC=edg_wlc_JobIdUnparse(jobsIn[i])); + free(pomC); + free(pomB); + pomB = pomA; + } + + if (statesIn) { + edg_wll_JobStatusToXMLV21(ctx, statesIn[i], &pomC); + trio_asprintf(&pomA,"%s\t\t%s",pomB,pomC); + } + else { + pomC = edg_wll_StatToString(EDG_WLL_JOB_UNKNOWN); + trio_asprintf(&pomA,"%s\t\t\r\n\r\n\t\t\r\n", + pomB, pomC); + } + + free(pomB); + free(pomC); + pomB = pomA; + + + len = asprintf(&pomA,"%s\t\r\n", pomB); + free(pomB); + i++; + tot_len += len; + + list = (char **) realloc(list, i * sizeof(*list)); + list[i-1] = pomA; + len_list = (int *) realloc(len_list, i * sizeof(*len_list)); + len_list[i-1] = len; + } + + /* list termination */ + list = (char **) realloc(list, (i+1) * sizeof(*list)); + list[i] = NULL; + + /* test errors */ + if (ctx->errDesc || ctx->errCode) + len = trio_asprintf(&pomB," code=\"%d\" desc=\"%|Xs\">\r\n",ctx->errCode,ctx->errDesc); + else + len = asprintf(&pomB,">\r\n"); + + /* glueing all list fields together & freeing the list */ + pomA = (char *) malloc(tot_len * sizeof(char) + + sizeof(QUERY_JOBS_BEGIN) + len + sizeof(QUERY_JOBS_END) - 1); + + memcpy(pomA, QUERY_JOBS_BEGIN, sizeof(QUERY_JOBS_BEGIN)); + memcpy((pomA + sizeof(QUERY_JOBS_BEGIN) - 1), pomB, len); + free(pomB); + pomB = pomA + sizeof(QUERY_JOBS_BEGIN) + len - 1; + + i = 0; + while (list[i]) { + memcpy(pomB, list[i], len_list[i] ); + pomB += len_list[i]; + + /* freeing the list */ + free(list[i]); + + i++; + } + + strcpy(pomB, QUERY_JOBS_END); + + + free(list); + free(len_list); + + + *message = pomA; + + return 0; +} + +/* construct Message-Body of Response-Line for edg_wll_UserJobs */ +int edg_wll_UserJobsToXMLV21(edg_wll_Context ctx UNUSED_VAR, edg_wlc_JobId *jobsOut, char **message) +{ + char *pomA, *pomB; + char **list = NULL; + int i = 0, len, tot_len = 0; + int *len_list = NULL; + + + while (jobsOut[i]) { + len = trio_asprintf(&pomA," %|Xs\r\n", + pomB=edg_wlc_JobIdUnparse(jobsOut[i])); + + free(pomB); + + i++; + tot_len += len; + + list = (char **) realloc(list, i * sizeof(*list)); + list[i-1] = pomA; + pomA = NULL; + len_list = (int *) realloc(len_list, i * sizeof(*len_list)); + len_list[i-1] = len; + + } + + /* list termination */ + list = (char **) realloc(list, (i+1) * sizeof(*list)); + list[i] = NULL; + + /* test errors */ + if (ctx->errDesc || ctx->errCode) + len = trio_asprintf(&pomB," code=\"%d\" desc=\"%|Xs\">\r\n",ctx->errCode,ctx->errDesc); + else + len = asprintf(&pomB,">\r\n"); + + /* glueing all list fields together & freeing the list */ + pomA = (char *) malloc(tot_len * sizeof(char) + + sizeof(USERJOBS_BEGIN) + len + sizeof(USERJOBS_END) - 1); + + memcpy(pomA, USERJOBS_BEGIN, sizeof(USERJOBS_BEGIN)); + memcpy((pomA + sizeof(USERJOBS_BEGIN) - 1), pomB, len); + free(pomB); + pomB = pomA + sizeof(USERJOBS_BEGIN) + len - 1; + + i = 0; + while (list[i]) { + memcpy(pomB, list[i], len_list[i] ); + pomB += len_list[i]; + + /* freeing the list */ + free(list[i]); + + i++; + } + + strcpy(pomB, USERJOBS_END); + + + free(list); + free(len_list); + + + *message = pomA; + + return 0; +} + +static void edg_wll_add_stslist_to_XMLBodyV21(edg_wll_Context ctx, char **body, const edg_wll_JobStat *toAdd, const char *tag, const char *UNUSED_subTag, const int null) +{ + char *pomA, *pomB, *newBody; + char **list = NULL; + int i = 0, len, tot_len = 0; + int *len_list = NULL; + + + while (toAdd[i].state != null) { + edg_wll_JobStatusToXMLV21(ctx, toAdd[i], &pomA); + len = strlen(pomA); + + i++; + tot_len += len; + + list = (char **) realloc(list, i * sizeof(*list)); + list[i-1] = pomA; + pomA = NULL; + len_list = (int *) realloc(len_list, i * sizeof(*len_list)); + len_list[i-1] = len; + } + + /* list termination */ + list = (char **) realloc(list, (i+1) * sizeof(*list)); + list[i] = NULL; + + /* glueing all list fields together & freeing the list */ + pomA = (char *) malloc(tot_len * sizeof(char) + 1); + pomB = pomA; + + i = 0; + while (list[i]) { + memcpy(pomB, list[i], len_list[i] ); + pomB += len_list[i]; + + /* freeing the list */ + free(list[i]); + + i++; + } + *pomB = '\0'; + free(list); + free(len_list); + + asprintf(&newBody,"%s\t\t\t<%s>\r\n%s\t\t\t\r\n", *body, tag, pomA, tag); + free(*body); + free(pomA); + *body = newBody; +} + + +/* construct Message-Body of Response-Line for edg_wll_JobStatus */ +int edg_wll_JobStatusToXMLV21(edg_wll_Context ctx, edg_wll_JobStat stat, char **message) +{ + char *pomA, *pomB, *pomC; + + + pomB = strdup(""); + +@@@{ + selectType $status '_common_'; + for (getFieldsOrdered $status) { + my $f = selectField $status $_; + next if defined($f->{special}) && $f->{special} eq 'XMLstructured'; + my $ft = $f->{type}; + my $n = $f->{null}; + gen "edg_wll_add_$ft\_to_XMLBody(&pomB, stat.$_, \"$_\", $n);\n"; + } +@@@} + if (stat.children) edg_wll_add_strlist_to_XMLBody(&pomB, stat.children, "children", "jobId", "\t\t\t", NULL); + if (stat.children_hist) edg_wll_add_intlist_to_XMLBody(&pomB, stat.children_hist, "children_hist", return_string_el, "\t\t\t", 1, stat.children_hist[0]); + if (stat.children_states) edg_wll_add_stslist_to_XMLBodyV21(ctx, &pomB, stat.children_states, "children_states", "", EDG_WLL_JOB_UNDEF); + if (stat.user_tags) edg_wll_add_taglist_to_XMLBody(&pomB, stat.user_tags, "user_tags", "tag", "name", "\t\t\t", NULL); + if (stat.stateEnterTimes) edg_wll_add_intlist_to_XMLBody(&pomB, stat.stateEnterTimes, "stateEnterTimes", return_string_el, "\t\t\t",1, stat.stateEnterTimes[0]); + + pomC = edg_wll_StatToString(stat.state); + + if (ctx->errDesc || ctx->errCode) + trio_asprintf(&pomA,"\r\n%s", + pomC, ctx->errCode,ctx->errDesc, pomB); + else + trio_asprintf(&pomA,"\r\n%s", + pomC, pomB); + + free(pomB); + free(pomC); + + *message = pomA; + + return 0; +} + + + +/* construct Message-Body of Request-Line for edg_wll_Purge */ +int edg_wll_PurgeResultToXMLV21( + edg_wll_Context ctx, + edg_wll_PurgeResult *result, + char **message) +{ + char *pomA, *pomB; + + + if (!result) { *message = NULL; return(-1); } + + pomA = strdup(""); + edg_wll_add_strlist_to_XMLBody(&pomA, result->jobs, "jobs", "jobId", "\t", NULL); + edg_wll_add_string_to_XMLBody(&pomA, result->server_file, "server_file", NULL); + + if (ctx->errDesc || ctx->errCode) + trio_asprintf(&pomA,"%s code=\"%d\" desc=\"%|Xs\">\r\n%s%s", + PURGE_RESULT_BEGIN, ctx->errCode, ctx->errDesc, pomA, PURGE_RESULT_END); + else + trio_asprintf(&pomB,"%s>\r\n%s%s", PURGE_RESULT_BEGIN, pomA, PURGE_RESULT_END); + free(pomA); + + *message = pomB; + return 0; +} + + + +/* construct Message-Body of Request-Line for edg_wll_Dump */ +int edg_wll_DumpResultToXMLV21( + edg_wll_Context ctx, + edg_wll_DumpResult *result, + char **message) +{ + char *pomA, *pomB; + + + if (!result) { *message = NULL; return(-1); } + + pomA = strdup(""); + edg_wll_add_string_to_XMLBody(&pomA, result->server_file, "server_file", NULL); + edg_wll_add_time_t_to_XMLBody(&pomA, result->from, "from", 0); + edg_wll_add_time_t_to_XMLBody(&pomA, result->to, "to", 0); + + if (ctx->errDesc || ctx->errCode) + trio_asprintf(&pomB,"%s code=\"%d\" desc=\"%|Xs\">\r\n%s%s", + DUMP_RESULT_BEGIN, ctx->errCode, ctx->errDesc, pomA, DUMP_RESULT_END); + else + trio_asprintf(&pomB,"%s>\r\n%s%s", DUMP_RESULT_BEGIN, pomA, DUMP_RESULT_END); + free(pomA); + + *message = pomB; + return 0; +} diff --git a/org.glite.lb.server/src/lb_xml_parse_V21.h b/org.glite.lb.server/src/lb_xml_parse_V21.h new file mode 100644 index 0000000..ea731dc --- /dev/null +++ b/org.glite.lb.server/src/lb_xml_parse_V21.h @@ -0,0 +1,21 @@ +#ifndef _LB_XML_PARSE_H_V21 +#define _LB_XML_PARSE_H_V21 + +#ident "$Header$" + +#include "glite/lb/consumer.h" + +/* function for parsing/unparsing XML requests from client */ + +int parseQueryJobsRequestV21(edg_wll_Context ctx, char *messageBody, edg_wll_QueryRec ***conditions, int *flags); +int parseQueryEventsRequestV21(edg_wll_Context ctx, char *messageBody, edg_wll_QueryRec ***job_conditions, edg_wll_QueryRec ***event_conditions); +int parsePurgeRequestV21(edg_wll_Context ctx, char *messageBody, edg_wll_PurgeRequest *request); +int parseDumpRequestV21(edg_wll_Context ctx, char *messageBody, edg_wll_DumpRequest *request); +int edg_wll_QueryEventsToXMLV21(edg_wll_Context, edg_wll_Event *, char **); +int edg_wll_QueryJobsToXMLV21(edg_wll_Context, edg_wlc_JobId *, edg_wll_JobStat *, char **); +int edg_wll_JobStatusToXMLV21(edg_wll_Context, edg_wll_JobStat, char **); +int edg_wll_UserJobsToXMLV21(edg_wll_Context, edg_wlc_JobId *, char **); +int edg_wll_PurgeResultToXMLV21(edg_wll_Context ctx, edg_wll_PurgeResult *result, char **message); +int edg_wll_DumpResultToXMLV21(edg_wll_Context ctx, edg_wll_DumpResult *result, char **message); + +#endif