intJobStat and related functions moved to state machine
authorJiří Filipovič <fila@ics.muni.cz>
Wed, 16 Feb 2011 09:01:07 +0000 (09:01 +0000)
committerJiří Filipovič <fila@ics.muni.cz>
Wed, 16 Feb 2011 09:01:07 +0000 (09:01 +0000)
org.glite.lb.server/src/bkindex.c
org.glite.lb.server/src/jobstat.c
org.glite.lb.server/src/jobstat.h
org.glite.lb.server/src/jobstat_supp.c
org.glite.lb.server/src/seqcode.c
org.glite.lb.server/src/store.c.T
org.glite.lb.state-machine/Makefile
org.glite.lb.state-machine/interface/intjobstat_supp.h [new file with mode: 0644]
org.glite.lb.state-machine/src/intjobstat_supp.c [new file with mode: 0644]

index cc8c064..e8fdc45 100644 (file)
@@ -446,7 +446,7 @@ static edg_wll_ErrorCode edg_wll_RefreshIColumns(edg_wll_Context ctx, void *job_
                                                        "cannot decode int_status for %s\n",res[4]);
                        }
                        if (stat != NULL) {
-                               edg_wll_IColumnsSQLPart(ctx, job_index_cols, &stat->pub, 0, NULL, &icvalues);
+                               edg_wll_IColumnsSQLPart(ctx, job_index_cols, intJobStat_to_JobStat(stat), 0, NULL, &icvalues);
                                trio_asprintf(&stmt, "update states set seq=%s%s where jobid='%|Ss'", res[2], icvalues, res[0]);
                                ret = edg_wll_ExecSQL(ctx, stmt, NULL);
                                free(icvalues);
index 67fe561..283ef35 100644 (file)
@@ -158,14 +158,14 @@ int edg_wll_JobStatusServer(
 
 
                if (!edg_wll_LoadIntState(ctx, job, DONT_LOCK, -1 /*all events*/, &ijsp)) {
-                       memcpy(stat, &(ijsp->pub), sizeof(ijsp->pub));
+                       memcpy(stat, intJobStat_to_JobStat(ijsp), sizeof(*stat));
                        destroy_intJobStat_extension(ijsp);
                        free(ijsp);
                } else {
                        if (edg_wll_intJobStatus(ctx, job, flags,&jobstat, js_enable_store, 0)) {
                                goto rollback;
                        }
-                       memcpy(stat, &(jobstat.pub), sizeof(jobstat.pub));
+                       memcpy(stat, intJobStat_to_JobStat(&jobstat), sizeof(*stat));
                }
                
                if (edg_wll_GetACL(ctx, job, &acl)) goto rollback;
@@ -224,7 +224,7 @@ int edg_wll_JobStatusServer(
                                                        if (!strcmp(INTSTAT_VERSION,out_stat[0])) {
                                                                js = dec_intJobStat(out_stat[1], &s_out);
                                                                if (s_out != NULL && js != NULL) {
-                                                                       stat->children_states[i] = js->pub;
+                                                                       stat->children_states[i] = *intJobStat_to_JobStat(js);
                                                                        destroy_intJobStat_extension(js);
                                                                        free(js);
                                                                        i++; // Careful, this value will also be used further
@@ -248,7 +248,7 @@ int edg_wll_JobStatusServer(
                                                                        goto rollback;
                                                                }
                                                                glite_jobid_free(subjob);
-                                                               stat->children_states[i] = js->pub;
+                                                               stat->children_states[i] = *intJobStat_to_JobStat(js);
                                                                destroy_intJobStat_extension(js);
                                                                i++; // Careful, this value will also be used further
                                                        }
@@ -325,7 +325,7 @@ int edg_wll_JobStatusServer(
                                                                                goto rollback;
                                                                        }
                                                                        glite_jobid_free(subjob);
-                                                                       num_f = js->pub.state;
+                                                                       num_f = intJobStat_to_JobStat(js)->state;
                                                                        if (num_f > EDG_WLL_JOB_UNDEF && num_f < EDG_WLL_NUMBER_OF_STATCODES)
                                                                                stat->children_hist[num_f+1]++;
 
@@ -404,7 +404,7 @@ int edg_wll_JobStatusServer(
                whole_cycle = 1;
 rollback:
                if (!whole_cycle) { 
-                       edg_wll_FreeStatus(&jobstat.pub);
+                       edg_wll_FreeStatus(intJobStat_to_JobStat(&jobstat));
                        memset(stat, 0, sizeof(*stat));
                }
                destroy_intJobStat_extension(&jobstat);
@@ -462,9 +462,9 @@ int edg_wll_intJobStatus(
        free(string_jobid);
 
        /* can be already filled by public edg_wll_JobStat() */
-       if (intstat->pub.owner == NULL) {
+       if (intJobStat_to_JobStat(intstat)->owner == NULL) {
                md5_jobid = edg_wlc_JobIdGetUnique(job);
-               if ( !(intstat->pub.owner = job_owner(ctx,md5_jobid)) ) {
+               if ( !(intJobStat_to_JobStat(intstat)->owner = job_owner(ctx,md5_jobid)) ) {
                        free(md5_jobid);
                        return edg_wll_Error(ctx,NULL,NULL);
                }
@@ -492,14 +492,14 @@ int edg_wll_intJobStatus(
                                if (edg_wll_Error(ctx, NULL, NULL) != ENOENT) {
                                        destroy_intJobStat(intstat);
                                        free(jqra);
-                                       free(intstat->pub.owner); intstat->pub.owner = NULL;
+                                       free(intJobStat_to_JobStat(intstat)->owner); intJobStat_to_JobStat(intstat)->owner = NULL;
                                        return edg_wll_Error(ctx, NULL, NULL);
                                }
                        }
                }
                else {
                        free(jqra);
-                       free(intstat->pub.owner); intstat->pub.owner = NULL;
+                       free(intJobStat_to_JobStat(intstat)->owner); intJobStat_to_JobStat(intstat)->owner = NULL;
                        return edg_wll_Error(ctx, NULL, NULL);
                }
        }
@@ -522,10 +522,10 @@ int edg_wll_intJobStatus(
                            || (ts.tv_sec == maxts.tv_sec && ts.tv_usec > maxts.tv_usec)) maxts = ts;
                }
                /* no events or status computation error */
-               if (intstat->pub.state == EDG_WLL_JOB_UNDEF) {
-                       intstat->pub.state = EDG_WLL_JOB_UNKNOWN;
-                       if (num_events) intstat->pub.lastUpdateTime = maxts;
-                       else intstat->pub.lastUpdateTime.tv_sec = 1;
+               if (intJobStat_to_JobStat(intstat)->state == EDG_WLL_JOB_UNDEF) {
+                       intJobStat_to_JobStat(intstat)->state = EDG_WLL_JOB_UNKNOWN;
+                       if (num_events) intJobStat_to_JobStat(intstat)->lastUpdateTime = maxts;
+                       else intJobStat_to_JobStat(intstat)->lastUpdateTime.tv_sec = 1;
                }
 
 
@@ -538,7 +538,7 @@ int edg_wll_intJobStatus(
                return edg_wll_SetError(ctx, EDG_WLL_ERROR_SERVER_RESPONSE, errstring);
        } else {
                /* XXX intstat->pub.expectUpdate = eval_expect_update(intstat, &intstat->pub.expectFrom); */
-               intErr = edg_wlc_JobIdDup(job, &intstat->pub.jobId);
+               intErr = edg_wlc_JobIdDup(job, &(intJobStat_to_JobStat(intstat)->jobId));
                if (intErr) return edg_wll_SetError(ctx, intErr, NULL);
 
                /* don't update status of grey jobs */
@@ -559,11 +559,11 @@ int edg_wll_intJobStatus(
                        int tsq = num_events - 1;
                        if (add_fqans && tsq == 0 && ctx->fqans != NULL) {
                                for (i=0; ctx->fqans[i]; i++);
-                               intstat->pub.user_fqans = malloc(sizeof(*ctx->fqans)*(i+1));
+                               intJobStat_to_JobStat(intstat)->user_fqans = malloc(sizeof(*ctx->fqans)*(i+1));
                                for (i=0; ctx->fqans[i]; i++) {
-                                       intstat->pub.user_fqans[i] = strdup(ctx->fqans[i]);
+                                       intJobStat_to_JobStat(intstat)->user_fqans[i] = strdup(ctx->fqans[i]);
                                }
-                               intstat->pub.user_fqans[i] = NULL;
+                               intJobStat_to_JobStat(intstat)->user_fqans[i] = NULL;
                        }
 
                        edg_wll_StoreIntState(ctx, intstat, tsq);
@@ -813,10 +813,10 @@ edg_wll_ErrorCode edg_wll_StoreIntState(edg_wll_Context ctx,
        assert(strlen(INTSTAT_VERSION) <= 32);
        
        update = (seq > 0);
-       jobid_md5 = edg_wlc_JobIdGetUnique(stat->pub.jobId);
+       jobid_md5 = edg_wlc_JobIdGetUnique(intJobStat_to_JobStat(stat)->jobId);
        stat_enc = enc_intJobStat(strdup(""), stat);
 
-       tagp = stat->pub.user_tags;
+       tagp = intJobStat_to_JobStat(stat)->user_tags;
        if (tagp) {
                while ((*tagp).tag != NULL) {
                        trio_asprintf(&stmt, "insert into status_tags"
@@ -842,18 +842,18 @@ edg_wll_ErrorCode edg_wll_StoreIntState(edg_wll_Context ctx,
                }
        }
 
-       parent_md5 = edg_wlc_JobIdGetUnique(stat->pub.parent_job);
+       parent_md5 = edg_wlc_JobIdGetUnique(intJobStat_to_JobStat(stat)->parent_job);
        if (parent_md5 == NULL) parent_md5 = strdup("*no parent job*");
 
 
-       edg_wll_IColumnsSQLPart(ctx, ctx->job_index_cols, &stat->pub, 0, NULL, &icvalues);
+       edg_wll_IColumnsSQLPart(ctx, ctx->job_index_cols, intJobStat_to_JobStat(stat), 0, NULL, &icvalues);
 
        trio_asprintf(&stmt,
                "update states set "
                "status=%d,seq=%d,int_status='%|Ss',version='%|Ss'"
                        ",parent_job='%|Ss'%s "
                "where jobid='%|Ss'",
-               stat->pub.state, seq, stat_enc, INTSTAT_VERSION,
+               intJobStat_to_JobStat(stat)->state, seq, stat_enc, INTSTAT_VERSION,
                parent_md5, icvalues,
                jobid_md5);
        free(icvalues);
@@ -863,14 +863,14 @@ edg_wll_ErrorCode edg_wll_StoreIntState(edg_wll_Context ctx,
        free(stmt); stmt = NULL;
 
        if (dbret == 0) {
-               edg_wll_IColumnsSQLPart(ctx, ctx->job_index_cols, &stat->pub, 1, &icnames, &icvalues);
+               edg_wll_IColumnsSQLPart(ctx, ctx->job_index_cols, intJobStat_to_JobStat(stat), 1, &icnames, &icvalues);
                trio_asprintf(&stmt,
                        "insert into states"
                        "(jobid,status,seq,int_status,version"
                                ",parent_job%s) "
                        "values ('%|Ss',%d,%d,'%|Ss','%|Ss','%|Ss'%s)",
                        icnames,
-                       jobid_md5, stat->pub.state, seq, stat_enc,
+                       jobid_md5, intJobStat_to_JobStat(stat)->state, seq, stat_enc,
                        INTSTAT_VERSION, parent_md5, icvalues);
                free(icnames); free(icvalues);
 
@@ -1033,7 +1033,7 @@ static edg_wll_ErrorCode load_parent_intJobStat(edg_wll_Context ctx, intJobStat
 {
        if (*pis) return edg_wll_Error(ctx, NULL, NULL); // already loaded and locked
 
-       if (edg_wll_LoadIntState(ctx, cis->pub.parent_job, LOCK, - 1, pis))
+       if (edg_wll_LoadIntState(ctx, intJobStat_to_JobStat(cis)->parent_job, LOCK, - 1, pis))
                goto err;
 
        assert(*pis);   // deadlock would happen with next call of this function
@@ -1058,12 +1058,12 @@ static int log_collectionState_event(edg_wll_Context ctx, edg_wll_JobStatCode st
        else
                event->any.user = strdup("LBProxy");
 
-       if (!edg_wll_SetSequenceCode(ctx,pis->last_seqcode,EDG_WLL_SEQ_NORMAL)) {
+       if (!edg_wll_SetSequenceCode(ctx,intJobStat_getLastSeqcode(pis),EDG_WLL_SEQ_NORMAL)) {
                ctx->p_source = EDG_WLL_SOURCE_LB_SERVER;
                 edg_wll_IncSequenceCode(ctx);
         }
        event->any.seqcode = edg_wll_GetSequenceCode(ctx);
-       edg_wlc_JobIdDup(pis->pub.jobId, &(event->any.jobId));
+       edg_wlc_JobIdDup(intJobStat_to_JobStat(pis)->jobId, &(event->any.jobId));
        gettimeofday(&event->any.timestamp,0);
        if (ctx->p_host) event->any.host = strdup(ctx->p_host);
        event->any.level = ctx->p_level;
@@ -1072,8 +1072,8 @@ static int log_collectionState_event(edg_wll_Context ctx, edg_wll_JobStatCode st
                                        
        event->collectionState.state = edg_wll_StatToString(state);
        event->collectionState.done_code = done_code;
-       event->collectionState.histogram = hist_to_string(pis->pub.children_hist);
-       edg_wlc_JobIdDup(cis->pub.jobId, &(event->collectionState.child));
+       event->collectionState.histogram = hist_to_string(intJobStat_to_JobStat(pis)->children_hist);
+       edg_wlc_JobIdDup(intJobStat_to_JobStat(cis)->jobId, &(event->collectionState.child));
        event->collectionState.child_event = edg_wll_EventToString(ce->any.type);
 
        ret = db_parent_store(ctx, event, pis);
@@ -1130,19 +1130,22 @@ static edg_wll_JobStatCode class_to_statCode(subjobClassCodes code)
 /* count parent state from subjob histogram */
 static edg_wll_JobStatCode process_Histogram(intJobStat *pis)
 {
-       if (pis->pub.children_hist[class_to_statCode(SUBJOB_CLASS_RUNNING)+1] > 0) {
+       if (intJobStat_to_JobStat(pis)->children_hist[class_to_statCode(SUBJOB_CLASS_RUNNING)+1] > 0) {
                return EDG_WLL_JOB_RUNNING;
        }
-       else if (pis->pub.children_hist[class_to_statCode(SUBJOB_CLASS_CLEARED)+1] == pis->pub.children_num) {
+       else if (intJobStat_to_JobStat(pis)->children_hist[class_to_statCode(SUBJOB_CLASS_CLEARED)+1] 
+               == intJobStat_to_JobStat(pis)->children_num) {
                return EDG_WLL_JOB_CLEARED;
        }
-       else if (pis->pub.children_hist[class_to_statCode(SUBJOB_CLASS_DONE)+1] 
-                       + pis->pub.children_hist[class_to_statCode(SUBJOB_CLASS_CLEARED)+1] == pis->pub.children_num) {
+       else if (intJobStat_to_JobStat(pis)->children_hist[class_to_statCode(SUBJOB_CLASS_DONE)+1] 
+                       + intJobStat_to_JobStat(pis)->children_hist[class_to_statCode(SUBJOB_CLASS_CLEARED)+1] 
+                       == intJobStat_to_JobStat(pis)->children_num) {
                return EDG_WLL_JOB_DONE;
        }
-       else if (pis->pub.children_hist[class_to_statCode(SUBJOB_CLASS_ABORTED)+1]
-                       + pis->pub.children_hist[class_to_statCode(SUBJOB_CLASS_DONE)+1]
-                       + pis->pub.children_hist[class_to_statCode(SUBJOB_CLASS_CLEARED)+1] == pis->pub.children_num) {
+       else if (intJobStat_to_JobStat(pis)->children_hist[class_to_statCode(SUBJOB_CLASS_ABORTED)+1]
+                       + intJobStat_to_JobStat(pis)->children_hist[class_to_statCode(SUBJOB_CLASS_DONE)+1]
+                       + intJobStat_to_JobStat(pis)->children_hist[class_to_statCode(SUBJOB_CLASS_CLEARED)+1] 
+                       == intJobStat_to_JobStat(pis)->children_num) {
                return EDG_WLL_JOB_ABORTED;
        }
        else
@@ -1156,22 +1159,22 @@ static edg_wll_ErrorCode update_parent_status(edg_wll_Context ctx, edg_wll_JobSt
        edg_wll_JobStatCode     parent_new_state;
 
 
-       subjob_class = class(&cis->pub);
+       subjob_class = class(intJobStat_to_JobStat(cis));
        subjob_class_old = class(subjob_stat_old);
 
 
        if (subjob_class_old != subjob_class) {
                if (load_parent_intJobStat(ctx, cis, &pis)) goto err;
 
-               pis->pub.children_hist[class_to_statCode(subjob_class)+1]++;
-               pis->pub.children_hist[class_to_statCode(subjob_class_old)+1]--;
+               intJobStat_to_JobStat(pis)->children_hist[class_to_statCode(subjob_class)+1]++;
+               intJobStat_to_JobStat(pis)->children_hist[class_to_statCode(subjob_class_old)+1]--;
 
-               edg_wll_StoreSubjobHistogram(ctx, cis->pub.parent_job, pis);
+               edg_wll_StoreSubjobHistogram(ctx, intJobStat_to_JobStat(cis)->parent_job, pis);
 
 
-               if (pis->pub.jobtype == EDG_WLL_STAT_COLLECTION) {
+               if (intJobStat_to_JobStat(pis)->jobtype == EDG_WLL_STAT_COLLECTION) {
                        parent_new_state = process_Histogram(pis);
-                       if (pis->pub.state != parent_new_state) {
+                       if (intJobStat_to_JobStat(pis)->state != parent_new_state) {
                                // XXX: we do not need  EDG_WLL_STAT_code any more
                                //      doneFailed subjob is stored in REST class and
                                //      inducting collection Waiting state
@@ -1212,7 +1215,7 @@ edg_wll_ErrorCode edg_wll_StepIntStateParent(edg_wll_Context ctx,
        char            *oldstat_rgmaline = NULL;
 
 
-       edg_wll_CpyStatus(&ijsp->pub,oldstat);
+       edg_wll_CpyStatus(intJobStat_to_JobStat(ijsp),oldstat);
 
        if (ctx->rgma_export) oldstat_rgmaline = write2rgma_statline(ijsp);
 
@@ -1225,12 +1228,12 @@ edg_wll_ErrorCode edg_wll_StepIntStateParent(edg_wll_Context ctx,
        // XXX: store it in update_parent status ?? 
        edg_wll_StoreIntState(ctx, ijsp, seq);
 
-       edg_wll_UpdateStatistics(ctx,oldstat,e,&ijsp->pub);
+       edg_wll_UpdateStatistics(ctx, oldstat, e, intJobStat_to_JobStat(ijsp));
 
        if (ctx->rgma_export) write2rgma_chgstatus(ijsp, oldstat_rgmaline);
 
        if (stat_out) {
-               edg_wll_CpyStatus(&ijsp->pub, stat_out);
+               edg_wll_CpyStatus(intJobStat_to_JobStat(ijsp), stat_out);
        }
 
        return edg_wll_Error(ctx, NULL, NULL);
@@ -1262,7 +1265,7 @@ edg_wll_ErrorCode edg_wll_StepIntState(edg_wll_Context ctx,
 
 
        if (!edg_wll_LoadIntState(ctx, job, DONT_LOCK, seq - 1, &ijsp)) {
-               edg_wll_CpyStatus(&ijsp->pub,oldstat);
+               edg_wll_CpyStatus(intJobStat_to_JobStat(ijsp),oldstat);
 
                if (ctx->rgma_export) oldstat_rgmaline = write2rgma_statline(ijsp);
 
@@ -1274,10 +1277,11 @@ edg_wll_ErrorCode edg_wll_StepIntState(edg_wll_Context ctx,
                }
                edg_wll_StoreIntState(ctx, ijsp, seq);
 
-               edg_wll_UpdateStatistics(ctx,oldstat,e,&ijsp->pub);
+               edg_wll_UpdateStatistics(ctx, oldstat, e, intJobStat_to_JobStat(ijsp));
 
                /* check whether subjob state change does not change parent state */
-               if ((ijsp->pub.parent_job) && (oldstat->state != ijsp->pub.state)) { 
+               if ((intJobStat_to_JobStat(ijsp)->parent_job) 
+                       && (oldstat->state != intJobStat_to_JobStat(ijsp)->state)) { 
                        if (update_parent_status(ctx, oldstat, ijsp, e)) {
                                edg_wll_FreeStatus(oldstat);
                                memset(oldstat,0,sizeof *oldstat);
@@ -1288,7 +1292,7 @@ edg_wll_ErrorCode edg_wll_StepIntState(edg_wll_Context ctx,
                if (ctx->rgma_export) write2rgma_chgstatus(ijsp, oldstat_rgmaline);
 
                if (stat_out) {
-                       memcpy(stat_out,&ijsp->pub,sizeof *stat_out);
+                       memcpy(stat_out,intJobStat_to_JobStat(ijsp),sizeof *stat_out);
                        destroy_intJobStat_extension(ijsp);
                }
                else destroy_intJobStat(ijsp);
@@ -1304,12 +1308,12 @@ edg_wll_ErrorCode edg_wll_StepIntState(edg_wll_Context ctx,
                   Right approach is computing parent status from scratch.
                */
 
-               edg_wll_UpdateStatistics(ctx,NULL,e,&jobstat.pub);
+               edg_wll_UpdateStatistics(ctx, NULL, e, intJobStat_to_JobStat(&jobstat));
 
                if (ctx->rgma_export) write2rgma_status(&jobstat);
 
                if (stat_out) {
-                       memcpy(stat_out,&jobstat.pub,sizeof *stat_out);
+                       memcpy(stat_out, intJobStat_to_JobStat(&jobstat), sizeof *stat_out);
                        destroy_intJobStat_extension(&jobstat);
                }
                else destroy_intJobStat(&jobstat);
@@ -1351,7 +1355,7 @@ edg_wll_ErrorCode edg_wll_GetSubjobHistogram(edg_wll_Context ctx, glite_jobid_co
                        // Ready to read the histogram from the record returned
                        rest = (char *)calloc(1,strlen(out));   
                        ijs = dec_intJobStat(out, &rest);
-                       for (i=0;i<=EDG_WLL_NUMBER_OF_STATCODES;i++) hist[i] = ijs->pub.children_hist[i];
+                       for (i=0;i<=EDG_WLL_NUMBER_OF_STATCODES;i++) hist[i] = intJobStat_to_JobStat(ijs)->children_hist[i];
                }
         }
         glite_lbu_FreeStmt(&sh);
@@ -1381,7 +1385,7 @@ edg_wll_ErrorCode edg_wll_StoreSubjobHistogram(edg_wll_Context ctx, glite_jobid_
                 "update states set "
                 "status=%d,int_status='%|Ss',version='%|Ss'"
                 "where jobid='%|Ss'",
-                ijs->pub.state, stat_enc, INTSTAT_VERSION, jobid_md5);
+                intJobStat_to_JobStat(ijs)->state, stat_enc, INTSTAT_VERSION, jobid_md5);
 
        free(jobid_md5);
 
index 5ceec21..8bbc5a7 100644 (file)
@@ -22,6 +22,7 @@ limitations under the License.
 
 #include "glite/lb/jobstat.h"
 #include "glite/lb/intjobstat.h"
+#include "glite/lb/intjobstat_supp.h"
 #include "glite/lbu/db.h"
 
 int edg_wll_JobStatusServer(edg_wll_Context, glite_jobid_const_t, int, edg_wll_JobStat *);
index 548d741..eb5d31d 100644 (file)
@@ -46,713 +46,6 @@ limitations under the License.
 #define UNUSED_VAR
 #endif
 
-static char* enc_strlist(char *, char **) UNUSED_VAR;
-static char **dec_strlist(char *, char **) UNUSED_VAR;
-
-/*
- * string encoding routines for safe DB store
- */
-
-static char *enc_string(char *old, char *item)
-{
-       char *out;
-       if (item == NULL) {
-               asprintf(&out,"%s-1 ", old);
-       } else {
-               asprintf(&out,"%s%ld %s",old, (long)strlen(item), item);
-       }
-       free(old);
-       return out;
-}
-
-static char *dec_string(char *in, char **rest)
-{
-       int scret;
-       long len = -1;
-       char *out;
-       
-       scret = sscanf(in, "%ld", &len);
-       if (scret < 1) {
-               *rest = NULL;
-               return NULL;
-       }
-       if (len == -1) {
-               out = NULL;
-               *rest = strchr(in, ' ') ? strchr(in, ' ') + 1 : NULL;
-       } else {
-               in = strchr(in, ' ') ? strchr(in, ' ') + 1 : NULL;
-               out = (char *)malloc(len+1);
-               if (out) {
-                       memcpy(out, in, len);
-                       *(out+len) = '\0';
-               }
-               *rest = in+len;
-       }
-       return out;
-}
-
-static char *enc_int(char *old, int item)
-{
-        char *out;
-        asprintf(&out,"%s%d ", old, item);
-       free(old);
-        return out;
-}
-
-static char *enc_int_array(char *old, int *item, int itemsNo)
-{
-        char *out;
-       int index;
-       char *strpom;
-
-       strpom=(char*)calloc(strlen(old)+1,sizeof(char));
-
-       for (index=0; index <= itemsNo; index++) sprintf(strpom+strlen(strpom),"%d%s", item[index],index==itemsNo?"":";");
-
-        asprintf(&out,"%s%s ", old, strpom);
-       free(strpom);
-        free(old);
-
-        return out;
-}
-
-static int dec_int(char* in, char **rest)
-{
-       int scret;
-       int out;
-
-       scret = sscanf(in, "%d", &out);
-       if (scret == 1) {
-               *rest = strchr(in, ' ') ? strchr(in, ' ') + 1 : NULL;
-       } else {
-               out = 0;
-               *rest = in;
-       }
-       return out;
-}
-
-static int dec_int_array(char* in, char **rest, int *out)      // Returns the number of items found in the array
-{
-       int charNo, itemsNo = 0, cindex, iindex = 0, lenindex;
-       char *tempstr;
-
-        /* Find out the number of items in the field first */
-
-       for (charNo = 0;charNo<strlen(in);charNo++)     {
-               if (in[charNo] == ' ') {        /* Only ' ' (space) is accepted as a separator. Should not be a broblem. */
-                       itemsNo++;
-                       break;
-               }
-               if (in[charNo] == ';') {
-                       itemsNo++;
-               }
-       }
-       if (!itemsNo) {         /* No separator has been found. This is the last input string */
-               itemsNo = 1;    /* - consider it an one-item array */
-               *rest = NULL;
-       }
-       else *rest = in + charNo + 1;
-
-       tempstr = (char*)calloc(charNo+1,sizeof(char));
-
-       strcpy(tempstr,"");
-
-       for (cindex = 0; cindex<charNo; cindex++) {
-               if ((in[cindex] == ';') || (in[cindex] == ' ')) {
-                       out[iindex] = atoi(tempstr);
-                       strcpy(tempstr,"");
-                       iindex++;
-               }
-               else {
-                       lenindex=strlen(tempstr);
-                       tempstr[lenindex]=in[cindex];
-                       tempstr[lenindex+1]=0;
-               }
-       }
-       if (in[cindex] != ' ') out[iindex] = atoi(tempstr);     /* string not terminated with a separator */
-
-       free(tempstr);
-       *rest = in + charNo + 1;
-
-        return itemsNo;
-}
-
-
-static char* enc_jobid(char *old, edg_wlc_JobId item)
-{
-       char *str;
-       char *out;
-
-       str = edg_wlc_JobIdUnparse(item);
-       out = enc_string(old, str);
-       free(str);
-       return out;
-}
-static edg_wlc_JobId dec_jobid(char *in, char **rest)
-{
-       char *str;
-       edg_wlc_JobId jobid;
-       
-       str = dec_string(in, rest);
-       if (str == NULL) return NULL;
-       edg_wlc_JobIdParse(str, &jobid);
-       free(str);
-       return jobid;
-}
-
-static char* enc_strlist(char *old, char **item)
-{
-       char *ret;
-
-       if (item == NULL) {
-               asprintf(&ret,"%s-1 ", old);
-               free(old);
-               return ret;
-       } else {
-               asprintf(&ret,"%s1 ",old);
-               free(old);
-               if (ret == NULL) return ret;
-       }
-       do {
-               ret = enc_string(ret, *item);
-       } while (*(item++) != NULL);
-       return ret;
-}
-
-static char **dec_strlist(char *in, char **rest)
-{
-       char **out;
-       int len = -1;
-       char *tmp_in, *tmp_ret;
-       int scret;
-
-       scret = sscanf(in, "%d", &len);
-       if (scret < 1) {
-               *rest = NULL;
-               return NULL;
-       }
-       if (len == -1) {
-               *rest = strchr(in, ' ') ? strchr(in, ' ') + 1 : NULL;
-               return NULL;
-       }
-
-       /* count number of fields only */
-       len = 0;
-       tmp_in = in = strchr(in, ' ') + 1 ;
-       do {
-               tmp_ret = dec_string(tmp_in, &tmp_in);
-               free(tmp_ret); 
-               len++;
-       }  while (tmp_ret != NULL);
-
-       out = (char**) malloc(len*sizeof(char*));
-
-       /* get them */
-       if (out) {
-               len = 0;
-               tmp_in = in;
-               do {
-                       out[len] = dec_string(tmp_in, &tmp_in);
-               } while  (out[len++] != NULL);
-       }
-       *rest = tmp_in;
-       return out;
-}
-
-static char *enc_branch_states(char *old, branch_state *item)
-{
-       char *ret;
-
-       if (item == NULL) {
-               asprintf(&ret,"%s-1 ", old);
-               free(old);
-               return ret;
-       } else {
-               asprintf(&ret,"%s1 ",old);
-               free(old);
-               if (ret == NULL) return ret;
-       }
-       do {
-               ret = enc_int(ret, (*item).branch);
-               ret = enc_string(ret, (*item).destination);
-               ret = enc_string(ret, (*item).ce_node);
-               ret = enc_string(ret, (*item).jdl);
-       } while ((*(item++)).branch != 0);
-       return ret;
-}
-
-static branch_state *dec_branch_states(char *in, char **rest)
-{
-       branch_state *out;
-       int len = -1, b = 0;
-       char *tmp_in, *tmp_ret;
-       int scret;
-
-       scret = sscanf(in, "%d", &len);
-       if (scret < 1) {
-               *rest = NULL;
-               return NULL;
-       }
-       if (len == -1) {
-               *rest = strchr(in, ' ') ? strchr(in, ' ') + 1 : NULL;
-               return NULL;
-       }
-
-       len = 0;
-       tmp_in = in = strchr(in, ' ') + 1 ;
-       do {
-               b = dec_int(tmp_in, &tmp_in);
-               tmp_ret = dec_string(tmp_in, &tmp_in); free(tmp_ret);
-               if (!tmp_in) { *rest = tmp_in; return NULL; }
-               tmp_ret = dec_string(tmp_in, &tmp_in); free(tmp_ret);
-               if (!tmp_in) { *rest = tmp_in; return NULL; }
-               tmp_ret = dec_string(tmp_in, &tmp_in); free(tmp_ret);
-               if (!tmp_in) { *rest = tmp_in; return NULL; }
-               len++;
-       }  while (b != 0);
-
-       out = (branch_state *) calloc(len+1, sizeof(branch_state));
-
-       if (out) {
-               len = 0;
-               tmp_in = in;
-
-               do {
-                       out[len].branch = dec_int(tmp_in, &tmp_in);
-                       out[len].destination = dec_string(tmp_in, &tmp_in);
-                       out[len].ce_node = dec_string(tmp_in, &tmp_in);
-                       out[len].jdl = dec_string(tmp_in, &tmp_in);
-               } while  (out[len++].branch != 0);
-               *rest = tmp_in;
-       }
-       else 
-               *rest = 0;
-
-       return out;
-
-}
-
-static char* enc_taglist(char *old, edg_wll_TagValue *item)
-{
-       char *ret;
-
-       if (item == NULL) {
-               asprintf(&ret,"%s-1 ", old);
-               free(old);
-               return ret;
-       } else {
-               asprintf(&ret,"%s1 ",old);
-               free(old);
-               if (ret == NULL) return ret;
-       }
-       do {
-               ret = enc_string(ret, (*item).tag);
-               ret = enc_string(ret, (*item).value);
-       } while ((*(item++)).tag != NULL);
-       return ret;
-}
-
-static edg_wll_TagValue *dec_taglist(char *in, char **rest)
-{
-       edg_wll_TagValue *out;
-       int len = -1;
-       char *tmp_in, *tmp_ret;
-       int scret, end = 0;
-
-       scret = sscanf(in, "%d", &len);
-       if (scret < 1) {
-               *rest = NULL;
-               return NULL;
-       }
-       if (len == -1) {
-               *rest = strchr(in, ' ') ? strchr(in, ' ') + 1 : NULL;
-               return NULL;
-       }
-
-       len = 0;
-       tmp_in = in = strchr(in, ' ') + 1 ;
-       do {
-               tmp_ret = dec_string(tmp_in, &tmp_in);
-               if (tmp_ret) free(tmp_ret); 
-               else end = 1;
-               if (!tmp_in) { *rest = tmp_in; return NULL; }
-               tmp_ret = dec_string(tmp_in, &tmp_in); 
-               free(tmp_ret);
-               if (!tmp_in) { *rest = tmp_in; return NULL; }
-               len++;
-       }  while (!end);
-
-       out = (edg_wll_TagValue *) malloc(len*sizeof(edg_wll_TagValue));
-
-       if (out) {
-               len = 0;
-               tmp_in = in;
-
-               do {
-                       out[len].tag = dec_string(tmp_in, &tmp_in);
-                       out[len].value = dec_string(tmp_in, &tmp_in);
-               } while  (out[len++].tag != NULL);
-               *rest = tmp_in;
-       }
-       else 
-               *rest = 0;
-
-       return out;
-}
-
-static char *enc_intlist(char *old, int *item)
-{
-       int len;
-       char *ret;
-
-       if (item == NULL) {
-               asprintf(&ret,"%s-1 ", old);
-               free(old);
-               return ret;
-       } else {
-               asprintf(&ret,"%s1 ",old);
-               free(old);
-               if (ret == NULL) return ret;
-       }
-       len = *item; item++;
-       ret = enc_int(ret, len);
-       for (; len > 0 ; len--, item++) {
-               ret = enc_int(ret, *item);
-       }
-
-       return ret;
-}
-
-static int *dec_intlist(char *in, char **rest)
-{
-       int len = -1;
-       int *out, *ptr;
-       char *tmp_in;
-       int scret;
-
-       scret = sscanf(in, "%d", &len);
-       if (scret < 1) {
-               *rest = NULL;
-               return NULL;
-       }
-       tmp_in = strchr(in, ' ') ? strchr(in, ' ') + 1 : NULL;
-       if (len == -1 || tmp_in == NULL) {
-               *rest = tmp_in;
-               return NULL;
-       }
-
-       len = dec_int(tmp_in, &tmp_in);
-       out = (int *)malloc( (len+1) *sizeof(int));
-       if (out) {
-               *out = len; 
-               ptr = out+1;
-               while (len) {
-                       *ptr = dec_int(tmp_in, &tmp_in);
-                       len--; ptr++;
-               }
-       }
-       *rest = tmp_in;
-       return out;
-}
-
-static char* enc_timeval(char *old, struct timeval item)
-{
-       char *ret;
-       
-       ret = enc_int(old, (int)item.tv_sec);
-       if (ret) {
-               ret = enc_int(ret, (int)item.tv_usec);
-       }
-       return ret;
-}
-
-static struct timeval dec_timeval(char *in, char **rest)
-{
-       struct timeval t;
-       char *tmp_in;
-       
-       t.tv_sec = dec_int(in, &tmp_in);
-       if (tmp_in != NULL) t.tv_usec = dec_int(tmp_in, &tmp_in);
-       *rest = tmp_in;
-       return t;
-}
-
-static char *enc_JobStat(char *old, edg_wll_JobStat* stat)
-{
-       char *ret;
-
-       ret = enc_int(old, stat->state);
-       if (ret) ret = enc_jobid(ret, stat->jobId);
-       if (ret) ret = enc_string(ret, stat->owner);
-       if (ret) ret = enc_int(ret, stat->jobtype);
-       if (ret) ret = enc_jobid(ret, stat->parent_job);
-       if (ret) ret = enc_string(ret, stat->seed);
-       if (ret) ret = enc_int(ret, stat->children_num);
-       if (ret) ret = enc_int_array(ret, stat->children_hist, EDG_WLL_NUMBER_OF_STATCODES);
-               /* children histogram stored in the DB, other children data not stored. */
-       if (ret) ret = enc_string(ret, stat->condorId);
-       if (ret) ret = enc_string(ret, stat->globusId);
-       if (ret) ret = enc_string(ret, stat->localId);
-       if (ret) ret = enc_string(ret, stat->jdl);
-       if (ret) ret = enc_string(ret, stat->matched_jdl);
-       if (ret) ret = enc_string(ret, stat->destination);
-       if (ret) ret = enc_string(ret, stat->condor_jdl);
-       if (ret) ret = enc_string(ret, stat->rsl);
-       if (ret) ret = enc_string(ret, stat->reason);
-       if (ret) ret = enc_string(ret, stat->location);
-       if (ret) ret = enc_string(ret, stat->ce_node);
-       if (ret) ret = enc_string(ret, stat->network_server);
-       if (ret) ret = enc_int(ret, stat->subjob_failed);
-       if (ret) ret = enc_int(ret, stat->done_code);
-       if (ret) ret = enc_int(ret, stat->exit_code);
-       if (ret) ret = enc_int(ret, stat->resubmitted);
-       if (ret) ret = enc_int(ret, stat->cancelling);
-       if (ret) ret = enc_string(ret, stat->cancelReason);
-       if (ret) ret = enc_int(ret, stat->cpuTime);
-       if (ret) ret = enc_taglist(ret, stat->user_tags);
-       if (ret) ret = enc_timeval(ret, stat->stateEnterTime);
-       if (ret) ret = enc_timeval(ret, stat->lastUpdateTime);
-       if (ret) ret = enc_intlist(ret, stat->stateEnterTimes);
-       if (ret) ret = enc_int(ret, stat->expectUpdate);
-       if (ret) ret = enc_string(ret, stat->expectFrom);
-       if (ret) ret = enc_string(ret, stat->acl);
-       if (ret) ret = enc_int(ret, stat->payload_running);
-       if (ret) ret = enc_strlist(ret, stat->possible_destinations);
-       if (ret) ret = enc_strlist(ret, stat->possible_ce_nodes);
-       if (ret) ret = enc_int(ret, stat->suspended);
-       if (ret) ret = enc_string(ret, stat->suspend_reason);
-       if (ret) ret = enc_string(ret, stat->failure_reasons);
-       if (ret) ret = enc_int(ret, stat->remove_from_proxy);
-       if (ret) ret = enc_string(ret, stat->ui_host);
-       if (ret) ret = enc_strlist(ret, stat->user_fqans);
-       if (ret) ret = enc_int(ret, stat->sandbox_retrieved);
-       if (ret) ret = enc_int(ret, stat->jw_status);
-       if (ret) ret = enc_jobid(ret, stat->isb_transfer);
-       if (ret) ret = enc_jobid(ret, stat->osb_transfer);
-       if (ret) ret = enc_string(ret, stat->pbs_state);
-       if (ret) ret = enc_string(ret, stat->pbs_queue);
-       if (ret) ret = enc_string(ret, stat->pbs_owner);
-       if (ret) ret = enc_string(ret, stat->pbs_name);
-       if (ret) ret = enc_string(ret, stat->pbs_reason);
-       if (ret) ret = enc_string(ret, stat->pbs_scheduler);
-       if (ret) ret = enc_string(ret, stat->pbs_dest_host);
-       if (ret) ret = enc_int(ret, stat->pbs_pid);
-       if (ret) ret = enc_string(ret, stat->pbs_resource_usage);
-       if (ret) ret = enc_int(ret, stat->pbs_exit_status);
-       if (ret) ret = enc_string(ret, stat->pbs_error_desc);
-       if (ret) ret = enc_string(ret, stat->condor_status);
-       if (ret) ret = enc_string(ret, stat->condor_universe);
-       if (ret) ret = enc_string(ret, stat->condor_owner);
-       if (ret) ret = enc_string(ret, stat->condor_preempting);
-       if (ret) ret = enc_int(ret, stat->condor_shadow_pid);
-       if (ret) ret = enc_int(ret, stat->condor_shadow_exit_status);
-       if (ret) ret = enc_int(ret, stat->condor_starter_pid);
-       if (ret) ret = enc_int(ret, stat->condor_starter_exit_status);
-       if (ret) ret = enc_int(ret, stat->condor_job_pid);
-       if (ret) ret = enc_int(ret, stat->condor_job_exit_status);
-       if (ret) ret = enc_string(ret, stat->condor_dest_host);
-       if (ret) ret = enc_string(ret, stat->condor_reason);
-       if (ret) ret = enc_string(ret, stat->condor_error_desc);
-       if (ret) ret = enc_int(ret, stat->cream_state);
-       if (ret) ret = enc_string(ret, stat->cream_id);
-       if (ret) ret = enc_string(ret, stat->cream_owner);
-       if (ret) ret = enc_string(ret, stat->cream_endpoint);
-       if (ret) ret = enc_string(ret, stat->cream_jdl);
-       if (ret) ret = enc_string(ret, stat->cream_reason);
-       if (ret) ret = enc_string(ret, stat->cream_failure_reason);
-       if (ret) ret = enc_string(ret, stat->cream_lrms_id);
-       if (ret) ret = enc_string(ret, stat->cream_node);
-       if (ret) ret = enc_int(ret, stat->cream_done_code);
-       if (ret) ret = enc_int(ret, stat->cream_exit_code);
-       if (ret) ret = enc_int(ret, stat->cream_cancelling);
-       if (ret) ret = enc_int(ret, stat->cream_cpu_time);
-       if (ret) ret = enc_int(ret, stat->cream_jw_status);
-       if (ret) ret = enc_jobid(ret, stat->ft_compute_job);
-       if (ret) ret = enc_int(ret, stat->ft_sandbox_type);
-       if (ret) ret = enc_string(ret, stat->ft_src);
-       if (ret) ret = enc_string(ret, stat->ft_dest);
-
-       return ret;
-}
-static edg_wll_JobStat* dec_JobStat(char *in, char **rest)
-{
-       char *tmp_in;
-       edg_wll_JobStat *stat;
-
-       stat = (edg_wll_JobStat *) calloc(1,sizeof(edg_wll_JobStat));
-       if (!stat) return stat;
-       tmp_in = in;
-
-        stat->state = dec_int(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->jobId = dec_jobid(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->owner = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->jobtype = dec_int(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->parent_job = dec_jobid(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->seed = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->children_num = dec_int(tmp_in, &tmp_in);
-        if (tmp_in != NULL) {
-                           stat->children_hist = (int*)calloc(EDG_WLL_NUMBER_OF_STATCODES+1, sizeof(int));
-                           dec_int_array(tmp_in, &tmp_in, stat->children_hist);
-       }
-                /* children histogram stored in the DB, other children data not stored. */
-        if (tmp_in != NULL) stat->condorId = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->globusId = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->localId = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->jdl = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->matched_jdl = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->destination = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->condor_jdl = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->rsl = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->reason = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->location = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->ce_node = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->network_server = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->subjob_failed = dec_int(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->done_code = dec_int(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->exit_code = dec_int(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->resubmitted = dec_int(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->cancelling = dec_int(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->cancelReason = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->cpuTime = dec_int(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->user_tags = dec_taglist(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->stateEnterTime = dec_timeval(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->lastUpdateTime = dec_timeval(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->stateEnterTimes = dec_intlist(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->expectUpdate = dec_int(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->expectFrom = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->acl = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->payload_running = dec_int(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->possible_destinations = dec_strlist(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->possible_ce_nodes = dec_strlist(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->suspended = dec_int(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->suspend_reason = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->failure_reasons = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->remove_from_proxy = dec_int(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->ui_host = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->user_fqans = dec_strlist(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->sandbox_retrieved = dec_int(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->jw_status = dec_int(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->isb_transfer = dec_jobid(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->osb_transfer = dec_jobid(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->pbs_state = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->pbs_queue = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->pbs_owner = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->pbs_name = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->pbs_reason = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->pbs_scheduler = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->pbs_dest_host = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->pbs_pid = dec_int(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->pbs_resource_usage = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->pbs_exit_status = dec_int(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->pbs_error_desc = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->condor_status = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->condor_universe = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->condor_owner = dec_string(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->condor_preempting = dec_string(tmp_in, &tmp_in);
-       if (tmp_in != NULL) stat->condor_shadow_pid = dec_int(tmp_in, &tmp_in);
-       if (tmp_in != NULL) stat->condor_shadow_exit_status = dec_int(tmp_in, &tmp_in);
-       if (tmp_in != NULL) stat->condor_starter_pid = dec_int(tmp_in, &tmp_in);
-       if (tmp_in != NULL) stat->condor_starter_exit_status = dec_int(tmp_in, &tmp_in);
-       if (tmp_in != NULL) stat->condor_job_pid = dec_int(tmp_in, &tmp_in);
-       if (tmp_in != NULL) stat->condor_job_exit_status = dec_int(tmp_in, &tmp_in);
-       if (tmp_in != NULL) stat->condor_dest_host = dec_string(tmp_in, &tmp_in);
-       if (tmp_in != NULL) stat->condor_reason = dec_string(tmp_in, &tmp_in);
-       if (tmp_in != NULL) stat->condor_error_desc = dec_string(tmp_in, &tmp_in);
-       if (tmp_in != NULL) stat->cream_state = dec_int(tmp_in, &tmp_in);
-       if (tmp_in != NULL) stat->cream_id = dec_string(tmp_in, &tmp_in);
-       if (tmp_in != NULL) stat->cream_owner = dec_string(tmp_in, &tmp_in);
-       if (tmp_in != NULL) stat->cream_endpoint = dec_string(tmp_in, &tmp_in);
-       if (tmp_in != NULL) stat->cream_jdl = dec_string(tmp_in, &tmp_in);
-       if (tmp_in != NULL) stat->cream_reason = dec_string(tmp_in, &tmp_in);
-       if (tmp_in != NULL) stat->cream_failure_reason = dec_string(tmp_in, &tmp_in);
-       if (tmp_in != NULL) stat->cream_lrms_id = dec_string(tmp_in, &tmp_in);
-       if (tmp_in != NULL) stat->cream_node = dec_string(tmp_in, &tmp_in);
-       if (tmp_in != NULL) stat->cream_done_code = dec_int(tmp_in, &tmp_in);
-       if (tmp_in != NULL) stat->cream_exit_code = dec_int(tmp_in, &tmp_in);
-       if (tmp_in != NULL) stat->cream_cancelling = dec_int(tmp_in, &tmp_in);
-       if (tmp_in != NULL) stat->cream_cpu_time = dec_int(tmp_in, &tmp_in);
-       if (tmp_in != NULL) stat->cream_jw_status = dec_int(tmp_in, &tmp_in);
-        if (tmp_in != NULL) stat->ft_compute_job = dec_jobid(tmp_in, &tmp_in);
-       if (tmp_in != NULL) stat->ft_sandbox_type = dec_int(tmp_in, &tmp_in);
-       if (tmp_in != NULL) stat->ft_src = dec_string(tmp_in, &tmp_in);
-       if (tmp_in != NULL) stat->ft_dest = dec_string(tmp_in, &tmp_in);
-       
-
-       *rest = tmp_in;
-
-       return stat;
-}
-
-char *enc_intJobStat(char *old, intJobStat* stat)
-{
-       char *ret;
-
-       ret = enc_JobStat(old, &stat->pub);
-       if (ret) ret = enc_int(ret, stat->resubmit_type);
-       if (ret) ret = enc_string(ret, stat->last_seqcode);
-       if (ret) ret = enc_string(ret, stat->last_cancel_seqcode);
-       if (ret) ret = enc_string(ret, stat->branch_tag_seqcode);
-       if (ret) ret = enc_string(ret, stat->last_branch_seqcode);
-       if (ret) ret = enc_string(ret, stat->deep_resubmit_seqcode);
-       if (ret) ret = enc_branch_states(ret, stat->branch_states);
-       if (ret) ret = enc_timeval(ret, stat->last_pbs_event_timestamp);
-       if (ret) ret = enc_int(ret, stat->pbs_reruning);
-       if (ret) ret = enc_strlist(ret, stat->tag_seq_codes);
-       return ret;
-}
-
-intJobStat* dec_intJobStat(char *in, char **rest)
-{
-       edg_wll_JobStat *pubstat;
-       intJobStat *stat = 0;
-       char *tmp_in;
-
-       pubstat = dec_JobStat(in, &tmp_in);
-
-       if (tmp_in != NULL) {
-               stat = (intJobStat *)calloc(1,sizeof(intJobStat));
-       } 
-       if (stat != NULL) {
-               stat->pub = *pubstat;
-               free(pubstat);
-               stat->resubmit_type = dec_int(tmp_in, &tmp_in);
-               if (tmp_in != NULL) {
-                       stat->last_seqcode = dec_string(tmp_in, &tmp_in);
-               }
-               if (tmp_in != NULL) {
-                       stat->last_cancel_seqcode = dec_string(tmp_in, &tmp_in);
-               }
-               if (tmp_in != NULL) {
-                       stat->branch_tag_seqcode = dec_string(tmp_in, &tmp_in);
-               }
-               if (tmp_in != NULL) {
-                       stat->last_branch_seqcode = dec_string(tmp_in, &tmp_in);
-               }
-               if (tmp_in != NULL) {
-                       stat->deep_resubmit_seqcode = dec_string(tmp_in, &tmp_in);
-               }
-               if (tmp_in != NULL) {
-                       stat->branch_states = dec_branch_states(tmp_in, &tmp_in);
-               }
-               if (tmp_in != NULL) {
-                       stat->last_pbs_event_timestamp = dec_timeval(tmp_in, &tmp_in);
-               }
-               if (tmp_in != NULL) {
-                       stat->pbs_reruning = dec_int(tmp_in, &tmp_in);
-               }
-               if (tmp_in != NULL) {
-                       stat->tag_seq_codes = dec_strlist(tmp_in, &tmp_in);
-               }
-       } else if (tmp_in != NULL) {
-               edg_wll_FreeStatus(pubstat);
-               free(pubstat);
-       }
-
-       *rest = tmp_in;
-       return stat;
-}
-
-
 static int compare_pevents_by_seq(const void *a, const void *b)
 {
         const edg_wll_Event **e = (const edg_wll_Event **) a;
index d5d0c1a..df09450 100644 (file)
@@ -22,6 +22,7 @@ limitations under the License.
 #include "glite/lbu/trio.h"
 #include "glite/lb/context-int.h"
 #include "glite/lbu/log.h"
+#include "glite/lb/intjobstat_supp.h"
 
 #include "get_events.h"
 #include "store.h"
@@ -65,8 +66,8 @@ int edg_wll_QuerySequenceCodeServer(edg_wll_Context ctx, edg_wlc_JobId jobid, co
 
        istat = dec_intJobStat(res, &res_rest);
        if ( res_rest  && istat ) {
-               *seqcode = istat->last_seqcode;
-               istat->last_seqcode = NULL;
+               *seqcode = intJobStat_getLastSeqcode(istat);
+               intJobStat_nullLastSeqcode(istat);
        }
        else edg_wll_SetError(ctx, EDG_WLL_ERROR_DB_CALL,
                                                "error decoding DB intJobStatus");
index 7ec4e7f..3a0cf77 100644 (file)
@@ -41,6 +41,7 @@ limitations under the License.
 #include "glite/lb/events_parse.h"
 #include "glite/lb/context-int.h"
 #include "glite/lb/log_proto.h"        /* for EDG_WLL_LOG_USER_DEFAULT */
+#include "glite/lb/intjobstat_supp.h"
 
 #include "store.h"
 #include "get_events.h"
@@ -682,14 +683,14 @@ edg_wll_ErrorCode intJobStat_embryonic(
        const edg_wll_RegJobEvent *e,
        intJobStat *stat)
 {
-       if (edg_wlc_JobIdDup(jobid, &stat->pub.jobId) ||
-               edg_wlc_JobIdDup(e->jobId, &stat->pub.parent_job)) goto err;
-       stat->pub.state = EDG_WLL_JOB_SUBMITTED;
-       stat->pub.owner = strdup(e->user);
-       stat->pub.jobtype = EDG_WLL_STAT_SIMPLE;
-       stat->pub.stateEnterTimes[1 + EDG_WLL_JOB_SUBMITTED] = (int)e->timestamp.tv_sec;
-       stat->pub.lastUpdateTime = e->timestamp;
-       stat->pub.stateEnterTime = e->timestamp;
+       if (edg_wlc_JobIdDup(jobid, &intJobStat_to_JobStat(stat)->jobId) ||
+               edg_wlc_JobIdDup(e->jobId, &intJobStat_to_JobStat(stat)->parent_job)) goto err;
+       intJobStat_to_JobStat(stat)->state = EDG_WLL_JOB_SUBMITTED;
+       intJobStat_to_JobStat(stat)->owner = strdup(e->user);
+       intJobStat_to_JobStat(stat)->jobtype = EDG_WLL_STAT_SIMPLE;
+       intJobStat_to_JobStat(stat)->stateEnterTimes[1 + EDG_WLL_JOB_SUBMITTED] = (int)e->timestamp.tv_sec;
+       intJobStat_to_JobStat(stat)->lastUpdateTime = e->timestamp;
+       intJobStat_to_JobStat(stat)->stateEnterTime = e->timestamp;
 
 err:
        return edg_wll_Error(ctx,NULL,NULL);
@@ -722,10 +723,10 @@ static edg_wll_ErrorCode states_values_embryonic(
        if (jobid_md5 == NULL || parent_md5 == NULL || stat_enc == NULL) goto err;
 
 
-       if (edg_wll_IColumnsSQLPart(ctx, ctx->job_index_cols, &stat->pub, 1, icnames, &icvalues)) goto err;
+       if (edg_wll_IColumnsSQLPart(ctx, ctx->job_index_cols, intJobStat_to_JobStat(stat), 1, icnames, &icvalues)) goto err;
        trio_asprintf(&stmt,
                "'%|Ss',%d,%d,'%|Ss','%|Ss','%|Ss'%s",
-               jobid_md5, stat->pub.state, 1, stat_enc,
+               jobid_md5, intJobStat_to_JobStat(stat)->state, 1, stat_enc,
                INTSTAT_VERSION, parent_md5, icvalues);
        free(icvalues);
 
index f289364..b94253d 100644 (file)
@@ -57,7 +57,7 @@ PLUGIN_LIBS:= -L${stagedir}/${libdir} -lglite_lb_common${default_flavour} \
        ${CLASSADS_LIBS} -lstdc++ ${EXPAT_LIBS}
 
 PLUGIN_LOBJS:=seqcode_aux.lo process_event.lo process_event_pbs.lo process_event_condor.lo process_event_cream.lo lb_plugin.lo  process_event_file_transfer.lo process_event_file_transfer_collection.lo
-MACHINE_OBJS:=seqcode_aux.o process_event.o process_event_pbs.o process_event_condor.o process_event_cream.o process_event_file_transfer.o process_event_file_transfer_collection.o
+MACHINE_OBJS:=seqcode_aux.o process_event.o process_event_pbs.o process_event_condor.o process_event_cream.o process_event_file_transfer.o process_event_file_transfer_collection.o intjobstat_supp.o
 
 PLUGIN_LIB=glite_lb_plugin.la
 MACHINE_LIB=libglite_lb_statemachine.a
@@ -89,6 +89,7 @@ install:
        install -m 644 lb-job-attrs2.xsd ${PREFIX}/interface
        install -m 644 ${top_srcdir}/interface/lb-job-record.xsd ${PREFIX}/interface
        install -m 644 ${top_srcdir}/interface/intjobstat.h ${PREFIX}/include/glite/lb
+       install -m 644 ${top_srcdir}/interface/intjobstat_supp.h ${PREFIX}/include/glite/lb
        install -m 644 ${top_srcdir}/interface/process_event.h ${PREFIX}/include/glite/lb
        install -m 644 ${top_srcdir}/interface/seqcode_aux.h ${PREFIX}/include/glite/lb
        install -m 644 job_attrs.h ${PREFIX}/include/glite/lb
diff --git a/org.glite.lb.state-machine/interface/intjobstat_supp.h b/org.glite.lb.state-machine/interface/intjobstat_supp.h
new file mode 100644 (file)
index 0000000..007effc
--- /dev/null
@@ -0,0 +1,12 @@
+#include "glite/lb/intjobstat.h"
+
+#ifndef GLITE_LB_INTJOBSTAT_SUPP_H
+#define GLITE_LB_INTJOBSTAT_SUPP_H
+
+char *enc_intJobStat(char *old, intJobStat* stat);
+intJobStat* dec_intJobStat(char *in, char **rest);
+edg_wll_JobStat* intJobStat_to_JobStat(intJobStat* intStat);
+char* intJobStat_getLastSeqcode(intJobStat* intStat);
+void intJobStat_nullLastSeqcode(intJobStat* intStat);
+
+#endif
diff --git a/org.glite.lb.state-machine/src/intjobstat_supp.c b/org.glite.lb.state-machine/src/intjobstat_supp.c
new file mode 100644 (file)
index 0000000..c427bc7
--- /dev/null
@@ -0,0 +1,763 @@
+#ident "$Header$"
+/*
+Copyright (c) Members of the EGEE Collaboration. 2004-2010.
+See http://www.eu-egee.org/partners for details on the copyright holders.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <stdarg.h>
+#include <regex.h>
+
+#include "glite/jobid/cjobid.h"
+#include "glite/lbu/trio.h"
+#include "glite/lbu/db.h"
+#include "glite/lb/context-int.h"
+#include "glite/lb/intjobstat.h"
+#include "glite/lb/seqcode_aux.h"
+
+#include "glite/lb/jobstat.h"
+
+
+/* TBD: share in whole logging or workload */
+#ifdef __GNUC__
+#define UNUSED_VAR __attribute__((unused))
+#else
+#define UNUSED_VAR
+#endif
+
+static char* enc_strlist(char *, char **) UNUSED_VAR;
+static char **dec_strlist(char *, char **) UNUSED_VAR;
+
+/*
+ * string encoding routines for safe DB store
+ */
+
+static char *enc_string(char *old, char *item)
+{
+       char *out;
+       if (item == NULL) {
+               asprintf(&out,"%s-1 ", old);
+       } else {
+               asprintf(&out,"%s%ld %s",old, (long)strlen(item), item);
+       }
+       free(old);
+       return out;
+}
+
+static char *dec_string(char *in, char **rest)
+{
+       int scret;
+       long len = -1;
+       char *out;
+       
+       scret = sscanf(in, "%ld", &len);
+       if (scret < 1) {
+               *rest = NULL;
+               return NULL;
+       }
+       if (len == -1) {
+               out = NULL;
+               *rest = strchr(in, ' ') ? strchr(in, ' ') + 1 : NULL;
+       } else {
+               in = strchr(in, ' ') ? strchr(in, ' ') + 1 : NULL;
+               out = (char *)malloc(len+1);
+               if (out) {
+                       memcpy(out, in, len);
+                       *(out+len) = '\0';
+               }
+               *rest = in+len;
+       }
+       return out;
+}
+
+static char *enc_int(char *old, int item)
+{
+        char *out;
+        asprintf(&out,"%s%d ", old, item);
+       free(old);
+        return out;
+}
+
+static char *enc_int_array(char *old, int *item, int itemsNo)
+{
+        char *out;
+       int index;
+       char *strpom;
+
+       strpom=(char*)calloc(strlen(old)+1,sizeof(char));
+
+       for (index=0; index <= itemsNo; index++) sprintf(strpom+strlen(strpom),"%d%s", item[index],index==itemsNo?"":";");
+
+        asprintf(&out,"%s%s ", old, strpom);
+       free(strpom);
+        free(old);
+
+        return out;
+}
+
+static int dec_int(char* in, char **rest)
+{
+       int scret;
+       int out;
+
+       scret = sscanf(in, "%d", &out);
+       if (scret == 1) {
+               *rest = strchr(in, ' ') ? strchr(in, ' ') + 1 : NULL;
+       } else {
+               out = 0;
+               *rest = in;
+       }
+       return out;
+}
+
+static int dec_int_array(char* in, char **rest, int *out)      // Returns the number of items found in the array
+{
+       int charNo, itemsNo = 0, cindex, iindex = 0, lenindex;
+       char *tempstr;
+
+        /* Find out the number of items in the field first */
+
+       for (charNo = 0;charNo<strlen(in);charNo++)     {
+               if (in[charNo] == ' ') {        /* Only ' ' (space) is accepted as a separator. Should not be a broblem. */
+                       itemsNo++;
+                       break;
+               }
+               if (in[charNo] == ';') {
+                       itemsNo++;
+               }
+       }
+       if (!itemsNo) {         /* No separator has been found. This is the last input string */
+               itemsNo = 1;    /* - consider it an one-item array */
+               *rest = NULL;
+       }
+       else *rest = in + charNo + 1;
+
+       tempstr = (char*)calloc(charNo+1,sizeof(char));
+
+       strcpy(tempstr,"");
+
+       for (cindex = 0; cindex<charNo; cindex++) {
+               if ((in[cindex] == ';') || (in[cindex] == ' ')) {
+                       out[iindex] = atoi(tempstr);
+                       strcpy(tempstr,"");
+                       iindex++;
+               }
+               else {
+                       lenindex=strlen(tempstr);
+                       tempstr[lenindex]=in[cindex];
+                       tempstr[lenindex+1]=0;
+               }
+       }
+       if (in[cindex] != ' ') out[iindex] = atoi(tempstr);     /* string not terminated with a separator */
+
+       free(tempstr);
+       *rest = in + charNo + 1;
+
+        return itemsNo;
+}
+
+
+static char* enc_jobid(char *old, edg_wlc_JobId item)
+{
+       char *str;
+       char *out;
+
+       str = edg_wlc_JobIdUnparse(item);
+       out = enc_string(old, str);
+       free(str);
+       return out;
+}
+static edg_wlc_JobId dec_jobid(char *in, char **rest)
+{
+       char *str;
+       edg_wlc_JobId jobid;
+       
+       str = dec_string(in, rest);
+       if (str == NULL) return NULL;
+       edg_wlc_JobIdParse(str, &jobid);
+       free(str);
+       return jobid;
+}
+
+static char* enc_strlist(char *old, char **item)
+{
+       char *ret;
+
+       if (item == NULL) {
+               asprintf(&ret,"%s-1 ", old);
+               free(old);
+               return ret;
+       } else {
+               asprintf(&ret,"%s1 ",old);
+               free(old);
+               if (ret == NULL) return ret;
+       }
+       do {
+               ret = enc_string(ret, *item);
+       } while (*(item++) != NULL);
+       return ret;
+}
+
+static char **dec_strlist(char *in, char **rest)
+{
+       char **out;
+       int len = -1;
+       char *tmp_in, *tmp_ret;
+       int scret;
+
+       scret = sscanf(in, "%d", &len);
+       if (scret < 1) {
+               *rest = NULL;
+               return NULL;
+       }
+       if (len == -1) {
+               *rest = strchr(in, ' ') ? strchr(in, ' ') + 1 : NULL;
+               return NULL;
+       }
+
+       /* count number of fields only */
+       len = 0;
+       tmp_in = in = strchr(in, ' ') + 1 ;
+       do {
+               tmp_ret = dec_string(tmp_in, &tmp_in);
+               free(tmp_ret); 
+               len++;
+       }  while (tmp_ret != NULL);
+
+       out = (char**) malloc(len*sizeof(char*));
+
+       /* get them */
+       if (out) {
+               len = 0;
+               tmp_in = in;
+               do {
+                       out[len] = dec_string(tmp_in, &tmp_in);
+               } while  (out[len++] != NULL);
+       }
+       *rest = tmp_in;
+       return out;
+}
+
+static char *enc_branch_states(char *old, branch_state *item)
+{
+       char *ret;
+
+       if (item == NULL) {
+               asprintf(&ret,"%s-1 ", old);
+               free(old);
+               return ret;
+       } else {
+               asprintf(&ret,"%s1 ",old);
+               free(old);
+               if (ret == NULL) return ret;
+       }
+       do {
+               ret = enc_int(ret, (*item).branch);
+               ret = enc_string(ret, (*item).destination);
+               ret = enc_string(ret, (*item).ce_node);
+               ret = enc_string(ret, (*item).jdl);
+       } while ((*(item++)).branch != 0);
+       return ret;
+}
+
+static branch_state *dec_branch_states(char *in, char **rest)
+{
+       branch_state *out;
+       int len = -1, b = 0;
+       char *tmp_in, *tmp_ret;
+       int scret;
+
+       scret = sscanf(in, "%d", &len);
+       if (scret < 1) {
+               *rest = NULL;
+               return NULL;
+       }
+       if (len == -1) {
+               *rest = strchr(in, ' ') ? strchr(in, ' ') + 1 : NULL;
+               return NULL;
+       }
+
+       len = 0;
+       tmp_in = in = strchr(in, ' ') + 1 ;
+       do {
+               b = dec_int(tmp_in, &tmp_in);
+               tmp_ret = dec_string(tmp_in, &tmp_in); free(tmp_ret);
+               if (!tmp_in) { *rest = tmp_in; return NULL; }
+               tmp_ret = dec_string(tmp_in, &tmp_in); free(tmp_ret);
+               if (!tmp_in) { *rest = tmp_in; return NULL; }
+               tmp_ret = dec_string(tmp_in, &tmp_in); free(tmp_ret);
+               if (!tmp_in) { *rest = tmp_in; return NULL; }
+               len++;
+       }  while (b != 0);
+
+       out = (branch_state *) calloc(len+1, sizeof(branch_state));
+
+       if (out) {
+               len = 0;
+               tmp_in = in;
+
+               do {
+                       out[len].branch = dec_int(tmp_in, &tmp_in);
+                       out[len].destination = dec_string(tmp_in, &tmp_in);
+                       out[len].ce_node = dec_string(tmp_in, &tmp_in);
+                       out[len].jdl = dec_string(tmp_in, &tmp_in);
+               } while  (out[len++].branch != 0);
+               *rest = tmp_in;
+       }
+       else 
+               *rest = 0;
+
+       return out;
+
+}
+
+static char* enc_taglist(char *old, edg_wll_TagValue *item)
+{
+       char *ret;
+
+       if (item == NULL) {
+               asprintf(&ret,"%s-1 ", old);
+               free(old);
+               return ret;
+       } else {
+               asprintf(&ret,"%s1 ",old);
+               free(old);
+               if (ret == NULL) return ret;
+       }
+       do {
+               ret = enc_string(ret, (*item).tag);
+               ret = enc_string(ret, (*item).value);
+       } while ((*(item++)).tag != NULL);
+       return ret;
+}
+
+static edg_wll_TagValue *dec_taglist(char *in, char **rest)
+{
+       edg_wll_TagValue *out;
+       int len = -1;
+       char *tmp_in, *tmp_ret;
+       int scret, end = 0;
+
+       scret = sscanf(in, "%d", &len);
+       if (scret < 1) {
+               *rest = NULL;
+               return NULL;
+       }
+       if (len == -1) {
+               *rest = strchr(in, ' ') ? strchr(in, ' ') + 1 : NULL;
+               return NULL;
+       }
+
+       len = 0;
+       tmp_in = in = strchr(in, ' ') + 1 ;
+       do {
+               tmp_ret = dec_string(tmp_in, &tmp_in);
+               if (tmp_ret) free(tmp_ret); 
+               else end = 1;
+               if (!tmp_in) { *rest = tmp_in; return NULL; }
+               tmp_ret = dec_string(tmp_in, &tmp_in); 
+               free(tmp_ret);
+               if (!tmp_in) { *rest = tmp_in; return NULL; }
+               len++;
+       }  while (!end);
+
+       out = (edg_wll_TagValue *) malloc(len*sizeof(edg_wll_TagValue));
+
+       if (out) {
+               len = 0;
+               tmp_in = in;
+
+               do {
+                       out[len].tag = dec_string(tmp_in, &tmp_in);
+                       out[len].value = dec_string(tmp_in, &tmp_in);
+               } while  (out[len++].tag != NULL);
+               *rest = tmp_in;
+       }
+       else 
+               *rest = 0;
+
+       return out;
+}
+
+static char *enc_intlist(char *old, int *item)
+{
+       int len;
+       char *ret;
+
+       if (item == NULL) {
+               asprintf(&ret,"%s-1 ", old);
+               free(old);
+               return ret;
+       } else {
+               asprintf(&ret,"%s1 ",old);
+               free(old);
+               if (ret == NULL) return ret;
+       }
+       len = *item; item++;
+       ret = enc_int(ret, len);
+       for (; len > 0 ; len--, item++) {
+               ret = enc_int(ret, *item);
+       }
+
+       return ret;
+}
+
+static int *dec_intlist(char *in, char **rest)
+{
+       int len = -1;
+       int *out, *ptr;
+       char *tmp_in;
+       int scret;
+
+       scret = sscanf(in, "%d", &len);
+       if (scret < 1) {
+               *rest = NULL;
+               return NULL;
+       }
+       tmp_in = strchr(in, ' ') ? strchr(in, ' ') + 1 : NULL;
+       if (len == -1 || tmp_in == NULL) {
+               *rest = tmp_in;
+               return NULL;
+       }
+
+       len = dec_int(tmp_in, &tmp_in);
+       out = (int *)malloc( (len+1) *sizeof(int));
+       if (out) {
+               *out = len; 
+               ptr = out+1;
+               while (len) {
+                       *ptr = dec_int(tmp_in, &tmp_in);
+                       len--; ptr++;
+               }
+       }
+       *rest = tmp_in;
+       return out;
+}
+
+static char* enc_timeval(char *old, struct timeval item)
+{
+       char *ret;
+       
+       ret = enc_int(old, (int)item.tv_sec);
+       if (ret) {
+               ret = enc_int(ret, (int)item.tv_usec);
+       }
+       return ret;
+}
+
+static struct timeval dec_timeval(char *in, char **rest)
+{
+       struct timeval t;
+       char *tmp_in;
+       
+       t.tv_sec = dec_int(in, &tmp_in);
+       if (tmp_in != NULL) t.tv_usec = dec_int(tmp_in, &tmp_in);
+       *rest = tmp_in;
+       return t;
+}
+
+char *enc_JobStat(char *old, edg_wll_JobStat* stat)
+{
+       char *ret;
+
+       ret = enc_int(old, stat->state);
+       if (ret) ret = enc_jobid(ret, stat->jobId);
+       if (ret) ret = enc_string(ret, stat->owner);
+       if (ret) ret = enc_int(ret, stat->jobtype);
+       if (ret) ret = enc_jobid(ret, stat->parent_job);
+       if (ret) ret = enc_string(ret, stat->seed);
+       if (ret) ret = enc_int(ret, stat->children_num);
+       if (ret) ret = enc_int_array(ret, stat->children_hist, EDG_WLL_NUMBER_OF_STATCODES);
+               /* children histogram stored in the DB, other children data not stored. */
+       if (ret) ret = enc_string(ret, stat->condorId);
+       if (ret) ret = enc_string(ret, stat->globusId);
+       if (ret) ret = enc_string(ret, stat->localId);
+       if (ret) ret = enc_string(ret, stat->jdl);
+       if (ret) ret = enc_string(ret, stat->matched_jdl);
+       if (ret) ret = enc_string(ret, stat->destination);
+       if (ret) ret = enc_string(ret, stat->condor_jdl);
+       if (ret) ret = enc_string(ret, stat->rsl);
+       if (ret) ret = enc_string(ret, stat->reason);
+       if (ret) ret = enc_string(ret, stat->location);
+       if (ret) ret = enc_string(ret, stat->ce_node);
+       if (ret) ret = enc_string(ret, stat->network_server);
+       if (ret) ret = enc_int(ret, stat->subjob_failed);
+       if (ret) ret = enc_int(ret, stat->done_code);
+       if (ret) ret = enc_int(ret, stat->exit_code);
+       if (ret) ret = enc_int(ret, stat->resubmitted);
+       if (ret) ret = enc_int(ret, stat->cancelling);
+       if (ret) ret = enc_string(ret, stat->cancelReason);
+       if (ret) ret = enc_int(ret, stat->cpuTime);
+       if (ret) ret = enc_taglist(ret, stat->user_tags);
+       if (ret) ret = enc_timeval(ret, stat->stateEnterTime);
+       if (ret) ret = enc_timeval(ret, stat->lastUpdateTime);
+       if (ret) ret = enc_intlist(ret, stat->stateEnterTimes);
+       if (ret) ret = enc_int(ret, stat->expectUpdate);
+       if (ret) ret = enc_string(ret, stat->expectFrom);
+       if (ret) ret = enc_string(ret, stat->acl);
+       if (ret) ret = enc_int(ret, stat->payload_running);
+       if (ret) ret = enc_strlist(ret, stat->possible_destinations);
+       if (ret) ret = enc_strlist(ret, stat->possible_ce_nodes);
+       if (ret) ret = enc_int(ret, stat->suspended);
+       if (ret) ret = enc_string(ret, stat->suspend_reason);
+       if (ret) ret = enc_string(ret, stat->failure_reasons);
+       if (ret) ret = enc_int(ret, stat->remove_from_proxy);
+       if (ret) ret = enc_string(ret, stat->ui_host);
+       if (ret) ret = enc_strlist(ret, stat->user_fqans);
+       if (ret) ret = enc_int(ret, stat->sandbox_retrieved);
+       if (ret) ret = enc_int(ret, stat->jw_status);
+       if (ret) ret = enc_jobid(ret, stat->isb_transfer);
+       if (ret) ret = enc_jobid(ret, stat->osb_transfer);
+       if (ret) ret = enc_string(ret, stat->pbs_state);
+       if (ret) ret = enc_string(ret, stat->pbs_queue);
+       if (ret) ret = enc_string(ret, stat->pbs_owner);
+       if (ret) ret = enc_string(ret, stat->pbs_name);
+       if (ret) ret = enc_string(ret, stat->pbs_reason);
+       if (ret) ret = enc_string(ret, stat->pbs_scheduler);
+       if (ret) ret = enc_string(ret, stat->pbs_dest_host);
+       if (ret) ret = enc_int(ret, stat->pbs_pid);
+       if (ret) ret = enc_string(ret, stat->pbs_resource_usage);
+       if (ret) ret = enc_int(ret, stat->pbs_exit_status);
+       if (ret) ret = enc_string(ret, stat->pbs_error_desc);
+       if (ret) ret = enc_string(ret, stat->condor_status);
+       if (ret) ret = enc_string(ret, stat->condor_universe);
+       if (ret) ret = enc_string(ret, stat->condor_owner);
+       if (ret) ret = enc_string(ret, stat->condor_preempting);
+       if (ret) ret = enc_int(ret, stat->condor_shadow_pid);
+       if (ret) ret = enc_int(ret, stat->condor_shadow_exit_status);
+       if (ret) ret = enc_int(ret, stat->condor_starter_pid);
+       if (ret) ret = enc_int(ret, stat->condor_starter_exit_status);
+       if (ret) ret = enc_int(ret, stat->condor_job_pid);
+       if (ret) ret = enc_int(ret, stat->condor_job_exit_status);
+       if (ret) ret = enc_string(ret, stat->condor_dest_host);
+       if (ret) ret = enc_string(ret, stat->condor_reason);
+       if (ret) ret = enc_string(ret, stat->condor_error_desc);
+       if (ret) ret = enc_int(ret, stat->cream_state);
+       if (ret) ret = enc_string(ret, stat->cream_id);
+       if (ret) ret = enc_string(ret, stat->cream_owner);
+       if (ret) ret = enc_string(ret, stat->cream_endpoint);
+       if (ret) ret = enc_string(ret, stat->cream_jdl);
+       if (ret) ret = enc_string(ret, stat->cream_reason);
+       if (ret) ret = enc_string(ret, stat->cream_failure_reason);
+       if (ret) ret = enc_string(ret, stat->cream_lrms_id);
+       if (ret) ret = enc_string(ret, stat->cream_node);
+       if (ret) ret = enc_int(ret, stat->cream_done_code);
+       if (ret) ret = enc_int(ret, stat->cream_exit_code);
+       if (ret) ret = enc_int(ret, stat->cream_cancelling);
+       if (ret) ret = enc_int(ret, stat->cream_cpu_time);
+       if (ret) ret = enc_int(ret, stat->cream_jw_status);
+       if (ret) ret = enc_jobid(ret, stat->ft_compute_job);
+       if (ret) ret = enc_int(ret, stat->ft_sandbox_type);
+       if (ret) ret = enc_string(ret, stat->ft_src);
+       if (ret) ret = enc_string(ret, stat->ft_dest);
+
+       return ret;
+}
+edg_wll_JobStat* dec_JobStat(char *in, char **rest)
+{
+       char *tmp_in;
+       edg_wll_JobStat *stat;
+
+       stat = (edg_wll_JobStat *) calloc(1,sizeof(edg_wll_JobStat));
+       if (!stat) return stat;
+       tmp_in = in;
+
+        stat->state = dec_int(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->jobId = dec_jobid(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->owner = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->jobtype = dec_int(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->parent_job = dec_jobid(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->seed = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->children_num = dec_int(tmp_in, &tmp_in);
+        if (tmp_in != NULL) {
+                           stat->children_hist = (int*)calloc(EDG_WLL_NUMBER_OF_STATCODES+1, sizeof(int));
+                           dec_int_array(tmp_in, &tmp_in, stat->children_hist);
+       }
+                /* children histogram stored in the DB, other children data not stored. */
+        if (tmp_in != NULL) stat->condorId = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->globusId = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->localId = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->jdl = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->matched_jdl = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->destination = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->condor_jdl = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->rsl = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->reason = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->location = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->ce_node = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->network_server = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->subjob_failed = dec_int(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->done_code = dec_int(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->exit_code = dec_int(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->resubmitted = dec_int(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->cancelling = dec_int(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->cancelReason = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->cpuTime = dec_int(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->user_tags = dec_taglist(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->stateEnterTime = dec_timeval(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->lastUpdateTime = dec_timeval(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->stateEnterTimes = dec_intlist(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->expectUpdate = dec_int(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->expectFrom = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->acl = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->payload_running = dec_int(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->possible_destinations = dec_strlist(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->possible_ce_nodes = dec_strlist(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->suspended = dec_int(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->suspend_reason = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->failure_reasons = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->remove_from_proxy = dec_int(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->ui_host = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->user_fqans = dec_strlist(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->sandbox_retrieved = dec_int(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->jw_status = dec_int(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->isb_transfer = dec_jobid(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->osb_transfer = dec_jobid(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->pbs_state = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->pbs_queue = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->pbs_owner = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->pbs_name = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->pbs_reason = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->pbs_scheduler = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->pbs_dest_host = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->pbs_pid = dec_int(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->pbs_resource_usage = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->pbs_exit_status = dec_int(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->pbs_error_desc = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->condor_status = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->condor_universe = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->condor_owner = dec_string(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->condor_preempting = dec_string(tmp_in, &tmp_in);
+       if (tmp_in != NULL) stat->condor_shadow_pid = dec_int(tmp_in, &tmp_in);
+       if (tmp_in != NULL) stat->condor_shadow_exit_status = dec_int(tmp_in, &tmp_in);
+       if (tmp_in != NULL) stat->condor_starter_pid = dec_int(tmp_in, &tmp_in);
+       if (tmp_in != NULL) stat->condor_starter_exit_status = dec_int(tmp_in, &tmp_in);
+       if (tmp_in != NULL) stat->condor_job_pid = dec_int(tmp_in, &tmp_in);
+       if (tmp_in != NULL) stat->condor_job_exit_status = dec_int(tmp_in, &tmp_in);
+       if (tmp_in != NULL) stat->condor_dest_host = dec_string(tmp_in, &tmp_in);
+       if (tmp_in != NULL) stat->condor_reason = dec_string(tmp_in, &tmp_in);
+       if (tmp_in != NULL) stat->condor_error_desc = dec_string(tmp_in, &tmp_in);
+       if (tmp_in != NULL) stat->cream_state = dec_int(tmp_in, &tmp_in);
+       if (tmp_in != NULL) stat->cream_id = dec_string(tmp_in, &tmp_in);
+       if (tmp_in != NULL) stat->cream_owner = dec_string(tmp_in, &tmp_in);
+       if (tmp_in != NULL) stat->cream_endpoint = dec_string(tmp_in, &tmp_in);
+       if (tmp_in != NULL) stat->cream_jdl = dec_string(tmp_in, &tmp_in);
+       if (tmp_in != NULL) stat->cream_reason = dec_string(tmp_in, &tmp_in);
+       if (tmp_in != NULL) stat->cream_failure_reason = dec_string(tmp_in, &tmp_in);
+       if (tmp_in != NULL) stat->cream_lrms_id = dec_string(tmp_in, &tmp_in);
+       if (tmp_in != NULL) stat->cream_node = dec_string(tmp_in, &tmp_in);
+       if (tmp_in != NULL) stat->cream_done_code = dec_int(tmp_in, &tmp_in);
+       if (tmp_in != NULL) stat->cream_exit_code = dec_int(tmp_in, &tmp_in);
+       if (tmp_in != NULL) stat->cream_cancelling = dec_int(tmp_in, &tmp_in);
+       if (tmp_in != NULL) stat->cream_cpu_time = dec_int(tmp_in, &tmp_in);
+       if (tmp_in != NULL) stat->cream_jw_status = dec_int(tmp_in, &tmp_in);
+        if (tmp_in != NULL) stat->ft_compute_job = dec_jobid(tmp_in, &tmp_in);
+       if (tmp_in != NULL) stat->ft_sandbox_type = dec_int(tmp_in, &tmp_in);
+       if (tmp_in != NULL) stat->ft_src = dec_string(tmp_in, &tmp_in);
+       if (tmp_in != NULL) stat->ft_dest = dec_string(tmp_in, &tmp_in);
+       
+
+       *rest = tmp_in;
+
+       return stat;
+}
+
+char *enc_intJobStat(char *old, intJobStat* stat)
+{
+       char *ret;
+
+       ret = enc_JobStat(old, &stat->pub);
+       if (ret) ret = enc_int(ret, stat->resubmit_type);
+       if (ret) ret = enc_string(ret, stat->last_seqcode);
+       if (ret) ret = enc_string(ret, stat->last_cancel_seqcode);
+       if (ret) ret = enc_string(ret, stat->branch_tag_seqcode);
+       if (ret) ret = enc_string(ret, stat->last_branch_seqcode);
+       if (ret) ret = enc_string(ret, stat->deep_resubmit_seqcode);
+       if (ret) ret = enc_branch_states(ret, stat->branch_states);
+       if (ret) ret = enc_timeval(ret, stat->last_pbs_event_timestamp);
+       if (ret) ret = enc_int(ret, stat->pbs_reruning);
+       if (ret) ret = enc_strlist(ret, stat->tag_seq_codes);
+       return ret;
+}
+
+intJobStat* dec_intJobStat(char *in, char **rest)
+{
+       edg_wll_JobStat *pubstat;
+       intJobStat *stat = 0;
+       char *tmp_in;
+
+       pubstat = dec_JobStat(in, &tmp_in);
+
+       if (tmp_in != NULL) {
+               stat = (intJobStat *)calloc(1,sizeof(intJobStat));
+       } 
+       if (stat != NULL) {
+               stat->pub = *pubstat;
+               free(pubstat);
+               stat->resubmit_type = dec_int(tmp_in, &tmp_in);
+               if (tmp_in != NULL) {
+                       stat->last_seqcode = dec_string(tmp_in, &tmp_in);
+               }
+               if (tmp_in != NULL) {
+                       stat->last_cancel_seqcode = dec_string(tmp_in, &tmp_in);
+               }
+               if (tmp_in != NULL) {
+                       stat->branch_tag_seqcode = dec_string(tmp_in, &tmp_in);
+               }
+               if (tmp_in != NULL) {
+                       stat->last_branch_seqcode = dec_string(tmp_in, &tmp_in);
+               }
+               if (tmp_in != NULL) {
+                       stat->deep_resubmit_seqcode = dec_string(tmp_in, &tmp_in);
+               }
+               if (tmp_in != NULL) {
+                       stat->branch_states = dec_branch_states(tmp_in, &tmp_in);
+               }
+               if (tmp_in != NULL) {
+                       stat->last_pbs_event_timestamp = dec_timeval(tmp_in, &tmp_in);
+               }
+               if (tmp_in != NULL) {
+                       stat->pbs_reruning = dec_int(tmp_in, &tmp_in);
+               }
+               if (tmp_in != NULL) {
+                       stat->tag_seq_codes = dec_strlist(tmp_in, &tmp_in);
+               }
+       } else if (tmp_in != NULL) {
+               edg_wll_FreeStatus(pubstat);
+               free(pubstat);
+       }
+
+       *rest = tmp_in;
+       return stat;
+}
+
+edg_wll_JobStat* intJobStat_to_JobStat(intJobStat* intStat){
+       return &(intStat->pub);
+}
+
+char* intJobStat_getLastSeqcode(intJobStat* intStat){
+       return intStat->last_seqcode;
+}
+
+void intJobStat_nullLastSeqcode(intJobStat* intStat){
+        intStat->last_seqcode = NULL;
+}
+