- query server and proxy example
authorJiří Škrábal <nykolas@ics.muni.cz>
Fri, 3 Dec 2004 07:29:33 +0000 (07:29 +0000)
committerJiří Škrábal <nykolas@ics.muni.cz>
Fri, 3 Dec 2004 07:29:33 +0000 (07:29 +0000)
org.glite.lb.client/examples/query_ext.c [new file with mode: 0644]

diff --git a/org.glite.lb.client/examples/query_ext.c b/org.glite.lb.client/examples/query_ext.c
new file mode 100644 (file)
index 0000000..2e9dacf
--- /dev/null
@@ -0,0 +1,877 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <ctype.h>
+#include <time.h>
+
+#include "glite/wmsutils/jobid/cjobid.h"
+#include "glite/lb/consumer.h"
+
+#define BUFF_LEN               1024
+#define MAX_AND_CONDS  20
+
+enum
+{
+       PQRV_ERR,
+       PQRV_EOF,
+       PQRV_EMPTY_LINE,
+};
+
+
+static void            printstat(edg_wll_JobStat);
+static int             cond_parse(edg_wll_QueryRec ***, int);
+static void            dgerr(edg_wll_Context, char *);
+static void            free_QueryRec(edg_wll_QueryRec *qr);
+static void            printconds(edg_wll_QueryRec **);
+static time_t  StrToTime(char *t);
+static char       *TimeToStr(time_t t);
+
+static char       *myname;
+static FILE       *fin;
+static char            buffer[BUFF_LEN+1],
+                               tmps[500];
+static int             query_jobs = 1;
+#define                query_events    (!query_jobs)
+static int             query_lbproxy = 0;
+#define                query_bkserver  (!query_lbproxy)
+static int             verbose = 0;
+
+
+static void usage(void)
+{
+       fprintf(stderr, "Usage: %s [-hvs] [-i file]\n", myname);
+       fprintf(stderr, "    -h                 show this help\n");
+       fprintf(stderr, "    -v                 increase verbosity level\n");
+       fprintf(stderr, "    -s                 results described verbosely (query jobs only)\n");
+       fprintf(stderr, "    -m                 server name\n");
+       fprintf(stderr, "    -i file            input file (default is stdin)\n\n");
+       fprintf(stderr, "    -e                 query events (default is 'query jobs')\n");
+       fprintf(stderr, "    -P                 query the L&B Proxy server\n");
+       fprintf(stderr, "    -p                 L&B Proxy socket path\n");
+       fprintf(stderr, "    -r type            returned results: limited | all | none\n\n");
+       fprintf(stderr, "    -J num             jobs soft limit\n\n");
+       fprintf(stderr, "    -E num             events soft limit (query events only)\n\n");
+}
+
+int main(int argc,char *argv[])
+{
+       edg_wll_Context                 ctx;
+       edg_wll_QueryResults    rslts           = EDG_WLL_QUERYRES_UNDEF;
+       edg_wll_QueryRec          **jc                  = NULL,
+                                                 **ec                  = NULL;
+       edg_wll_JobStat            *statesOut   = NULL;
+       edg_wlc_JobId              *jobsOut             = NULL;
+       edg_wll_Event              *eventsOut   = NULL;
+       char                               *fname               = NULL,
+                                                  *server              = NULL,
+                                                  *proxy_sock  = NULL,
+                                                  *s;
+       int                                             result          = 0,
+                                                       jobsLimit       = 0,
+                                                       stdisp          = 0,
+                                                       eventsLimit     = 0,
+                                                       i, j, ret,
+                                                       errCode;
+
+       myname  = argv[0];
+       ret             = 0;
+       do {
+               switch ( getopt(argc,argv,"hvsePp:i:m:r:J:E:") ) {
+               case 'h': usage();  exit(0);
+               case '?': usage(); exit(EINVAL);
+               case 'v': verbose = 1; break;
+               case 'i': fname = strdup(optarg); break;
+               case 'm': server = strdup(optarg); break;
+               case 's': stdisp = 1; break;
+               case 'e': query_jobs = 0; break;
+               case 'P': query_lbproxy = 1; break;
+               case 'p': proxy_sock = strdup(optarg); break;
+               case 'r':
+                       if ( !strcasecmp(optarg, "limited") ) rslts = EDG_WLL_QUERYRES_LIMITED;
+                       else if ( !strcasecmp(optarg, "none") ) rslts = EDG_WLL_QUERYRES_NONE;
+                       else if ( !strcasecmp(optarg, "all") ) rslts = EDG_WLL_QUERYRES_ALL;
+                       else { usage(); exit(EINVAL); }
+                       break;
+               case 'J': jobsLimit = atoi(optarg); break;
+               case 'E': eventsLimit = atoi(optarg); break;
+               case -1: ret = 1; break;
+               }
+       } while ( !ret );
+
+       if ( edg_wll_InitContext(&ctx) ) {
+               if ( verbose ) fprintf(stderr,"%s: cannot initialize edg_wll_Context\n",myname);
+               exit(1);
+       }
+
+       if ( jobsLimit > 0 ) {
+               edg_wll_SetParam(ctx, EDG_WLL_PARAM_QUERY_JOBS_LIMIT, jobsLimit);
+               if ( verbose ) printf("Soft query limit for jobs: %d\n", jobsLimit);
+       }
+       else if ( verbose ) printf("Soft query limit for jobs not set\n");
+
+       if ( query_events ) {
+               if ( eventsLimit > 0 ) {
+                       edg_wll_SetParam(ctx, EDG_WLL_PARAM_QUERY_EVENTS_LIMIT, eventsLimit);
+                       if ( verbose ) printf("Soft query limit for events: %d\n", eventsLimit);
+               }
+               else if ( verbose ) printf("Soft query limit for events not set\n");
+       }
+
+       if ( rslts != EDG_WLL_QUERYRES_UNDEF )
+               edg_wll_SetParam(ctx, EDG_WLL_PARAM_QUERY_RESULTS, rslts);
+       else
+               edg_wll_GetParam(ctx, EDG_WLL_PARAM_QUERY_RESULTS, &rslts);
+
+       if ( verbose ) printf("When any limit overflows, the returned result set is: %s\n",
+                                                       rslts==EDG_WLL_QUERYRES_LIMITED? "limited":
+                                                       (rslts==EDG_WLL_QUERYRES_ALL? "unlimited": "empty"));
+       
+       if ( server ) {
+               char *p = strchr(server, ':');
+               if ( p ) {
+                       edg_wll_SetParam(ctx, EDG_WLL_PARAM_QUERY_SERVER_PORT, atoi(p+1));
+                       *p = 0;
+               }
+               edg_wll_SetParam(ctx, EDG_WLL_PARAM_QUERY_SERVER, server);
+               free(server);
+       }
+
+       if ( proxy_sock ) {
+               edg_wll_SetParam(ctx, EDG_WLL_PARAM_LBPROXY_SERVE_SOCK, proxy_sock);
+               free(proxy_sock);
+       }
+
+       if ( fname ) {
+               fin = fopen(fname, "r");
+               if ( !fin ) {
+                       if ( verbose ) fprintf(stderr, "Can't open given input file %s. Using stdin.\n", fname);
+                       fin = stdin;
+               }
+               free(fname);
+       } else {
+               if ( verbose ) fprintf(stderr, "No input file given. Using stdin.\n");
+               fin = stdin;
+       }
+
+       jobsOut         = NULL;
+       statesOut       = NULL;
+       eventsOut       = NULL;
+
+
+       do
+       {
+               if ( verbose && (fin == stdin) ) printf("Enter job conditions:\n");
+               
+               ret = cond_parse(&jc, 1);
+               if ( ret == PQRV_ERR ) { result = 1; goto cleanup; }
+               if ( query_events && (ret != PQRV_EOF) ) {
+                       if ( verbose && (fin == stdin) ) printf("Enter event conditions:\n");
+                       ret = cond_parse(&ec, 0);
+                       if ( ret == PQRV_ERR ) { result = 1; goto cleanup; }
+               }
+
+               if ( (ret == PQRV_EOF) && !jc && (query_jobs || (query_events && !ec)) ) break;
+
+               if ( verbose ) {
+                       printf("job conditions list: ");
+                       printconds(jc);
+                       if ( query_events ) { printf("event condition list: "); printconds(ec); }
+               }
+
+               if ( query_jobs ) {
+                       if ( query_bkserver )
+                               errCode = edg_wll_QueryJobsExt(ctx,
+                                                               (const edg_wll_QueryRec **) jc,
+                                                               0, &jobsOut, stdisp? &statesOut: NULL);
+                       else
+                               errCode = edg_wll_QueryJobsExtProxy(ctx,
+                                                               (const edg_wll_QueryRec **) jc,
+                                                               0, &jobsOut, stdisp? &statesOut: NULL);
+               } else {
+                       if ( query_bkserver )
+                               errCode = edg_wll_QueryEventsExt(ctx,
+                                                               (const edg_wll_QueryRec **) jc,
+                                                               (const edg_wll_QueryRec **) ec,
+                                                               &eventsOut);
+                       else
+                               errCode = edg_wll_QueryEventsExtProxy(ctx,
+                                                               (const edg_wll_QueryRec **) jc,
+                                                               (const edg_wll_QueryRec **) ec,
+                                                               &eventsOut);
+               }
+
+               if ( errCode ) {
+                       dgerr(ctx, NULL);
+                       if ( (errCode != EPERM) && (errCode != E2BIG) ) goto cycle_cleanup;
+        } else if ( verbose ) {
+                       if ( query_jobs ) printf("Matched jobs: ");
+                       else printf("Matched events: ");
+               }
+
+               if ( verbose ) {
+                       if ( (query_jobs && jobsOut && jobsOut[0]) ||
+                                (query_events && eventsOut && eventsOut[0].type) )
+                               putchar('\n');
+                       else printf("No one matches\n");
+               }
+
+               if ( query_jobs && jobsOut && !stdisp ) {
+                       for ( i = 0; jobsOut[i]; i++ ) {
+                               s = edg_wlc_JobIdUnparse(jobsOut[i]);
+                               printf("jobId: %s\n", edg_wlc_JobIdUnparse(jobsOut[i]));
+                               free(s);
+                               edg_wlc_JobIdFree(jobsOut[i]);
+                       }
+                       free(jobsOut);
+                       jobsOut = NULL;
+               }
+               if ( query_jobs && statesOut ) {
+                       if ( stdisp ) for ( i = 0; statesOut[i].state; i++ ) printstat(statesOut[i]);
+                       for ( i = 0; statesOut[i].state; i++ ) edg_wll_FreeStatus(&statesOut[i]);
+                       free(statesOut);
+                       statesOut = NULL;
+               }
+               if ( query_events && eventsOut ) {
+                       for ( i = 0; eventsOut[i].type; i++ ) {
+                               s = edg_wlc_JobIdUnparse(eventsOut[i].any.jobId);
+                               printf("event: %-11s (jobid %s)\n", edg_wll_EventToString(eventsOut[i].type), s);
+                               free(s);
+                       }
+                       free(eventsOut);
+                       eventsOut = NULL;
+               }
+
+cycle_cleanup:
+               if ( jc ) {
+                       for ( i = 0; jc[i]; i++ ) {
+                               for ( j = 0; jc[i][j].attr; j++ ) free_QueryRec(&jc[i][j]);
+                               free(jc[i]);
+                       }
+                       free(jc);
+               }
+
+               if ( ec ) {
+                       for ( i = 0; ec[i]; i++ ) {
+                               for ( j = 0; ec[i][j].attr; j++ ) free_QueryRec(&ec[i][j]);
+                               free(ec[i]);
+                       }
+                       free(ec);
+               }
+       } while ( ret != PQRV_EOF );
+
+cleanup:
+       if ( fin != stdin ) fclose(fin);
+       edg_wll_FreeContext(ctx);
+
+       return result;
+}
+
+static void free_QueryRec(edg_wll_QueryRec *qr)
+{
+       switch ( qr->attr )
+       {
+       case EDG_WLL_QUERY_ATTR_JOBID:
+       case EDG_WLL_QUERY_ATTR_PARENT:
+               edg_wlc_JobIdFree(qr->value.j);
+               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:
+               break;
+
+       case EDG_WLL_QUERY_ATTR_OWNER:
+       case EDG_WLL_QUERY_ATTR_LOCATION: 
+       case EDG_WLL_QUERY_ATTR_DESTINATION:
+               free(qr->value.c);
+               break;
+
+       case EDG_WLL_QUERY_ATTR_USERTAG:
+               free(qr->attr_id.tag);
+               free(qr->value.c);
+               break;
+
+       default:
+               break;
+       }
+}
+
+#define isop(c)                ((c == '=') || (c == '<') || (c == '>') || (c == '@'))
+
+static char *get_attr_name(char *src, char *dest, int sz)
+{
+       int             i       = 0,
+                       ct      = 0;
+
+
+       while ( (src[i] != '\0') && isblank(src[i]) ) i++;                      /* skip whitespaces */
+       while ( (src[i] != '\n') && (src[i] != '\0') && !isop(src[i]) && !isblank(src[i]) )
+       {
+               if ( ct < sz ) 
+                       dest[ct++] = src[i];
+               i++;
+       }
+       dest[ct] = '\0';
+
+       return src+i;
+}
+
+static char *get_op(char *src, edg_wll_QueryOp *op)
+{
+       int             i = 0;
+
+
+       while ( (src[i] != '\0') && isblank(src[i]) ) i++;                      /* skip whitespaces */
+
+       if ( src[i] == '=' ) *op = EDG_WLL_QUERY_OP_EQUAL;
+       else if ( src[i] == '@' ) *op = EDG_WLL_QUERY_OP_WITHIN;
+       else if ( src[i] == '>' ) *op = EDG_WLL_QUERY_OP_GREATER;
+       else if ( src[i] == '<' )
+       {
+               if ( (src[i+1] != '\0') && (src[++i] == '>') )
+                       *op = EDG_WLL_QUERY_OP_UNEQUAL;
+               else
+                       *op = EDG_WLL_QUERY_OP_LESS;
+       } 
+       else return NULL;
+
+       return src+i+1;
+}
+
+static char *get_attr_value(char *src, char *dest, int sz)
+{
+       int             i       = 0,
+                       ct      = 0;
+
+
+       while ( (src[i] != '\0') && isblank(src[i]) ) i++;                      /* skip whitespaces */
+       if ( src[i] == '"' )
+       {
+               i++;
+               while ( (src[i] != '\n') && (src[i] != '\0') && (src[i] != '"') )
+               {
+                       if ( ct < sz ) 
+                               dest[ct++] = src[i];
+                       i++;
+               }
+               dest[ct] = '\0';
+               if ( src[i] != '"' )
+                       return NULL;
+
+               return src+i+1;
+       }
+
+       while ( (src[i] != '\n') && (src[i] != '\0') && (src[i] != ';') && !isblank(src[i]) )
+       {
+               if ( ct < sz ) 
+                       dest[ct++] = src[i];
+               i++;
+       }
+       dest[ct] = '\0';
+
+       return src+i;
+}
+
+static char *get_job_condition(char *src, edg_wll_QueryRec *cond)
+{
+       char       *s;
+
+
+       s = get_attr_name(src, tmps, 500);
+
+       if ( tmps[0] == '\0' ) return NULL;
+
+       if ( !strcmp(tmps, "jobid") ) cond->attr = EDG_WLL_QUERY_ATTR_JOBID;
+       else if ( !strcmp(tmps, "owner") ) cond->attr = EDG_WLL_QUERY_ATTR_OWNER;
+       else if ( !strcmp(tmps, "status") ) cond->attr = EDG_WLL_QUERY_ATTR_STATUS;
+       else if ( !strcmp(tmps, "location") ) cond->attr = EDG_WLL_QUERY_ATTR_LOCATION;
+       else if ( !strcmp(tmps, "destination") ) cond->attr = EDG_WLL_QUERY_ATTR_DESTINATION;
+       else if ( !strcmp(tmps, "done_code") ) cond->attr = EDG_WLL_QUERY_ATTR_DONECODE;
+       else if ( !strcmp(tmps, "exit_code") ) cond->attr = EDG_WLL_QUERY_ATTR_EXITCODE;
+       else if ( !strcmp(tmps, "parent_job") ) cond->attr = EDG_WLL_QUERY_ATTR_PARENT;
+       else if ( !strcmp(tmps, "time") ) cond->attr = EDG_WLL_QUERY_ATTR_TIME;
+       else
+       {
+               cond->attr = EDG_WLL_QUERY_ATTR_USERTAG;
+               cond->attr_id.tag = strdup(tmps);
+       }
+
+       if ( !(s = get_op(s, &(cond->op))) ) return NULL;
+
+       if ( !(s = get_attr_value(s, tmps, 500)) ) return NULL;
+
+       switch ( cond->attr )
+       {
+       case EDG_WLL_QUERY_ATTR_JOBID:
+       case EDG_WLL_QUERY_ATTR_PARENT:
+               if ( edg_wlc_JobIdParse(tmps, &cond->value.j) )
+               {
+                       fprintf(stderr,"%s: %s: cannot parse jobId\n", myname, tmps);
+                       return NULL;
+               }
+               break;
+
+       case EDG_WLL_QUERY_ATTR_OWNER:
+               if ( !strcmp("NULL", tmps) )
+                       cond->value.c = NULL;
+               else if ( !(cond->value.c = strdup(tmps)) )
+                       return 0;
+               break;
+
+       case EDG_WLL_QUERY_ATTR_LOCATION:
+       case EDG_WLL_QUERY_ATTR_DESTINATION:
+       case EDG_WLL_QUERY_ATTR_USERTAG:
+               if ( !(cond->value.c = strdup(tmps)) )
+                       return 0;
+               break;
+
+       case EDG_WLL_QUERY_ATTR_STATUS:
+               if ( !strcasecmp(tmps, "Submitted") ) cond->value.i = EDG_WLL_JOB_SUBMITTED;
+               else if ( !strcasecmp(tmps, "Waiting") ) cond->value.i = EDG_WLL_JOB_WAITING;
+               else if ( !strcasecmp(tmps, "Ready") ) cond->value.i = EDG_WLL_JOB_READY;
+               else if ( !strcasecmp(tmps, "Scheduled") ) cond->value.i = EDG_WLL_JOB_SCHEDULED;
+               else if ( !strcasecmp(tmps, "Running") ) cond->value.i = EDG_WLL_JOB_RUNNING;
+               else if ( !strcasecmp(tmps, "Done") ) cond->value.i = EDG_WLL_JOB_DONE;
+               else if ( !strcasecmp(tmps, "Aborted") ) cond->value.i = EDG_WLL_JOB_ABORTED;
+               else if ( !strcasecmp(tmps, "Cancelled") ) cond->value.i = EDG_WLL_JOB_CANCELLED;
+               else if ( !strcasecmp(tmps, "Cleared") ) cond->value.i = EDG_WLL_JOB_CLEARED;
+               else
+               {
+                       fprintf(stderr,"%s: invalid status value (%s)\n", myname, tmps);
+                       return 0;
+               }
+               break;
+
+       case EDG_WLL_QUERY_ATTR_DONECODE:
+       case EDG_WLL_QUERY_ATTR_EXITCODE:
+       case EDG_WLL_QUERY_ATTR_RESUBMITTED:
+               cond->value.i = atoi(tmps);
+               if ( cond->op == EDG_WLL_QUERY_OP_WITHIN )
+               {
+                       if ( !(s = get_attr_value(s, tmps, 500)) ) return NULL;
+                       if ( tmps[0] == '\0' )
+                       {
+                               fprintf(stderr,"%s: second interval boundary not set\n", myname);
+                               return NULL;
+                       }
+                       cond->value2.i = atoi(tmps);
+               }
+               break;
+
+       case EDG_WLL_QUERY_ATTR_TIME:
+               cond->value.t.tv_sec = StrToTime(tmps);
+               if ( cond->op == EDG_WLL_QUERY_OP_WITHIN )
+               {
+                       if ( !(s = get_attr_value(s, tmps, 500)) ) return NULL;
+                       if ( tmps[0] == '\0' )
+                       {
+                               fprintf(stderr,"%s: second interval boundary not set\n", myname);
+                               return NULL;
+                       }
+                       cond->value2.t.tv_sec = StrToTime(tmps);
+               }
+               if ( !(s = get_attr_value(s, tmps, 500)) ) return NULL;
+               if ( tmps[0] == '\0' )
+               {
+                       fprintf(stderr,"%s: time condition must be associated with state condition\n", myname);
+                       return NULL;
+               }
+               if ( !strcasecmp(tmps, "Submitted") ) cond->attr_id.state = EDG_WLL_JOB_SUBMITTED;
+               else if ( !strcasecmp(tmps, "Waiting") ) cond->attr_id.state = EDG_WLL_JOB_WAITING;
+               else if ( !strcasecmp(tmps, "Ready") ) cond->attr_id.state = EDG_WLL_JOB_READY;
+               else if ( !strcasecmp(tmps, "Scheduled") ) cond->attr_id.state = EDG_WLL_JOB_SCHEDULED;
+               else if ( !strcasecmp(tmps, "Running") ) cond->attr_id.state = EDG_WLL_JOB_RUNNING;
+               else if ( !strcasecmp(tmps, "Done") ) cond->attr_id.state = EDG_WLL_JOB_DONE;
+               else if ( !strcasecmp(tmps, "Aborted") ) cond->attr_id.state = EDG_WLL_JOB_ABORTED;
+               else if ( !strcasecmp(tmps, "Cancelled") ) cond->attr_id.state = EDG_WLL_JOB_CANCELLED;
+               else if ( !strcasecmp(tmps, "Cleared") ) cond->attr_id.state = EDG_WLL_JOB_CLEARED;
+               else
+               {
+                       fprintf(stderr,"%s: invalid status value (%s)\n", myname, tmps);
+                       return 0;
+               }
+        break;
+
+       default:
+               break;
+       }
+
+       while ( isblank(*s) || (*s == ';') ) s++;                       /* skip whitespaces */
+
+       return s;
+}
+
+static char *get_event_condition(char *src, edg_wll_QueryRec *cond)
+{
+       char       *s;
+
+
+       s = get_attr_name(src, tmps, 500);
+
+       if ( tmps[0] == '\0' ) return NULL;
+
+       if ( !strcmp(tmps, "time") ) cond->attr = EDG_WLL_QUERY_ATTR_TIME;
+       else if ( !strcmp(tmps, "level") ) cond->attr = EDG_WLL_QUERY_ATTR_LEVEL;
+       else if ( !strcmp(tmps, "host") ) cond->attr = EDG_WLL_QUERY_ATTR_HOST;
+       else if ( !strcmp(tmps, "source") ) cond->attr = EDG_WLL_QUERY_ATTR_SOURCE;
+       else if ( !strcmp(tmps, "instance") ) cond->attr = EDG_WLL_QUERY_ATTR_INSTANCE;
+       else if ( !strcmp(tmps, "event_type") ) cond->attr = EDG_WLL_QUERY_ATTR_EVENT_TYPE;
+       else
+       {
+               cond->attr = EDG_WLL_QUERY_ATTR_USERTAG;
+               cond->attr_id.tag = strdup(tmps);
+       }
+
+       if ( !(s = get_op(s, &(cond->op))) ) return NULL;
+
+       if ( !(s = get_attr_value(s, tmps, 500)) ) return NULL;
+
+       switch ( cond->attr )
+       {
+       case EDG_WLL_QUERY_ATTR_USERTAG:
+       case EDG_WLL_QUERY_ATTR_HOST:
+       case EDG_WLL_QUERY_ATTR_INSTANCE:
+               if ( !(cond->value.c = strdup(tmps)) )
+                       return 0;
+               break;
+
+       case EDG_WLL_QUERY_ATTR_SOURCE:
+               if ( !strcasecmp(tmps, "UserInterface") ) cond->value.i = EDG_WLL_SOURCE_USER_INTERFACE;
+               else if ( !strcasecmp(tmps, "NetworkServer") ) cond->value.i = EDG_WLL_SOURCE_NETWORK_SERVER;
+               else if ( !strcasecmp(tmps, "WorkloadManager") ) cond->value.i = EDG_WLL_SOURCE_WORKLOAD_MANAGER;
+               else if ( !strcasecmp(tmps, "BigHelper") ) cond->value.i = EDG_WLL_SOURCE_BIG_HELPER;
+               else if ( !strcasecmp(tmps, "JobController") ) cond->value.i = EDG_WLL_SOURCE_JOB_SUBMISSION;
+               else if ( !strcasecmp(tmps, "LogMonitor") ) cond->value.i = EDG_WLL_SOURCE_LOG_MONITOR;
+               else if ( !strcasecmp(tmps, "LRMS") ) cond->value.i = EDG_WLL_SOURCE_LRMS;
+               else if ( !strcasecmp(tmps, "Application") ) cond->value.i = EDG_WLL_SOURCE_APPLICATION;
+               else
+               {
+                       fprintf(stderr,"%s: invalid source value (%s)\n", myname, tmps);
+                       return NULL;
+               }
+               break;
+
+       case EDG_WLL_QUERY_ATTR_EVENT_TYPE:
+       case EDG_WLL_QUERY_ATTR_LEVEL:
+               cond->value.i = atoi(tmps);
+               if ( cond->op == EDG_WLL_QUERY_OP_WITHIN )
+               {
+                       if ( !(s = get_attr_value(s, tmps, 500)) ) return NULL;
+                       if ( tmps[0] == '\0' )
+                       {
+                               fprintf(stderr,"%s: second interval boundary not set\n", myname);
+                               return NULL;
+                       }
+                       cond->value2.i = atoi(tmps);
+               }
+               break;
+
+       case EDG_WLL_QUERY_ATTR_TIME:
+               cond->value.t.tv_sec = StrToTime(tmps);
+               if ( cond->op == EDG_WLL_QUERY_OP_WITHIN )
+               {
+                       if ( !(s = get_attr_value(s, tmps, 500)) ) return NULL;
+                       if ( tmps[0] == '\0' )
+                       {
+                               fprintf(stderr,"%s: second interval boundary not set\n", myname);
+                               return NULL;
+                       }
+                       cond->value2.t.tv_sec = StrToTime(tmps);
+               }
+               break;
+
+       default:
+               break;
+       }
+
+       while ( isblank(*s) || (*s == ';') ) s++;                       /* skip whitespaces */
+
+       return s;
+}
+
+static int cond_parse(edg_wll_QueryRec ***pcond, int jobs)
+{
+       edg_wll_QueryRec  **cond = NULL;
+       int                                     n,
+                                               icond,
+                                               ret;
+       char                       *s;
+
+
+       
+       n = 0;
+       if ( !(cond = malloc(sizeof(*cond))) )
+       {
+               perror("cond_parse()");
+               exit(ENOMEM);
+       }
+
+       while ( 1 )
+       {
+               if ( !fgets(buffer, BUFF_LEN, fin) )
+               {
+                       if ( !feof(fin) )
+                       {
+                               fprintf(stderr, "parse_query_cond(): file reading error\n");
+                               exit(EINVAL);
+                       }
+
+                       ret = PQRV_EOF;
+                       goto cleanup;
+               }
+
+               if ( buffer[0] == '\n' )
+               {
+                       ret = PQRV_EMPTY_LINE;
+                       goto cleanup;
+               }
+
+               if ( !(cond[n] = (edg_wll_QueryRec *) malloc(sizeof(edg_wll_QueryRec))) )
+               {
+                       perror("cond_parse()");
+                       exit(ENOMEM);
+               }
+               s = buffer;
+               icond = 0;
+               while ( 1 )
+               {
+                       if ( jobs )
+                               s = get_job_condition(s, &(cond[n][icond]));
+                       else
+                               s = get_event_condition(s, &(cond[n][icond]));
+
+                       if ( !s )
+                       {
+                               free(cond[n]);
+                               cond[n] = NULL;
+                               ret = PQRV_ERR;
+                               goto cleanup;
+                       }
+                       icond++;
+                       if ( !(cond[n] = realloc(cond[n], (icond+1)*sizeof(edg_wll_QueryRec))) )
+                       {
+                               perror("cond_parse()");
+                               exit(ENOMEM);
+                       }
+                       cond[n][icond].attr = EDG_WLL_QUERY_ATTR_UNDEF;
+                       if ( (*s == '\n') || (*s == '\0') )
+                               break;
+               }
+
+               n++;
+               if ( !(cond = realloc(cond, (n+1)*sizeof(*cond))) )
+               {
+                       perror("cond_parse()");
+                       exit(ENOMEM);
+               }
+               cond[n] = NULL;
+       }
+
+cleanup:
+       if ( !n )
+       {
+               free(cond);
+               *pcond = NULL;
+       }
+       else
+               *pcond = cond;
+
+       return ret;
+}
+
+static void printconds(edg_wll_QueryRec **cond)
+{
+       int             i, j;
+       int             any = 0;
+       char   *s;
+
+
+       if ( !cond )
+       {
+               printf("empty\n");
+               return ;
+       }
+
+       for ( i = 0; cond[i]; i++ )
+       {
+               if ( cond[i][0].attr )
+               {
+                       any = 1;
+                       if ( i )
+                               printf(" AND (");
+                       else
+                               printf("(");
+               }
+               for ( j = 0; cond[i][j].attr; j++ )
+               {
+                       if ( j )
+                               printf(" OR ");
+                       switch ( cond[i][j].attr )
+                       {
+                       case EDG_WLL_QUERY_ATTR_JOBID: printf("jobid"); break;
+                       case EDG_WLL_QUERY_ATTR_OWNER: printf("owner"); break;
+                       case EDG_WLL_QUERY_ATTR_STATUS: printf("status"); break;
+                       case EDG_WLL_QUERY_ATTR_LOCATION: printf("location"); break;
+                       case EDG_WLL_QUERY_ATTR_DESTINATION: printf("destination"); break;
+                       case EDG_WLL_QUERY_ATTR_DONECODE: printf("done_code"); break;
+                       case EDG_WLL_QUERY_ATTR_EXITCODE: printf("exit_code"); break;
+                       case EDG_WLL_QUERY_ATTR_PARENT: printf("parent_job"); break;
+                       case EDG_WLL_QUERY_ATTR_RESUBMITTED: printf("resubmitted"); break;
+                       case EDG_WLL_QUERY_ATTR_USERTAG: printf("%s",cond[i][j].attr_id.tag); break;
+                       case EDG_WLL_QUERY_ATTR_TIME: printf("time"); break;
+                       case EDG_WLL_QUERY_ATTR_LEVEL: printf("level"); break;
+                       case EDG_WLL_QUERY_ATTR_HOST: printf("host"); break;
+                       case EDG_WLL_QUERY_ATTR_SOURCE: printf("source"); break;
+                       case EDG_WLL_QUERY_ATTR_INSTANCE: printf("instance"); break;
+                       case EDG_WLL_QUERY_ATTR_EVENT_TYPE: printf("ev_type"); break;
+                       default: break;
+                       }
+                       switch ( cond[i][j].op )
+                       {
+                       case EDG_WLL_QUERY_OP_EQUAL: printf("="); break;
+                       case EDG_WLL_QUERY_OP_UNEQUAL: printf("<>"); break;
+                       case EDG_WLL_QUERY_OP_LESS: printf("<"); break;
+                       case EDG_WLL_QUERY_OP_GREATER: printf(">"); break;
+                       case EDG_WLL_QUERY_OP_WITHIN: printf("@"); break;
+                       }
+                       switch ( cond[i][j].attr )
+                       {
+                       case EDG_WLL_QUERY_ATTR_JOBID:
+                       case EDG_WLL_QUERY_ATTR_PARENT:
+                               s = edg_wlc_JobIdUnparse(cond[i][j].value.j);
+                               printf("%s", s);
+                               free(s);
+                               break;
+                       case EDG_WLL_QUERY_ATTR_OWNER:
+                       case EDG_WLL_QUERY_ATTR_LOCATION: 
+                       case EDG_WLL_QUERY_ATTR_DESTINATION:
+                       case EDG_WLL_QUERY_ATTR_HOST:
+                       case EDG_WLL_QUERY_ATTR_INSTANCE:
+                       case EDG_WLL_QUERY_ATTR_USERTAG:
+                               printf("%s", cond[i][j].value.c);
+                               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:
+                       case EDG_WLL_QUERY_ATTR_SOURCE:
+                               if ( cond[i][j].op == EDG_WLL_QUERY_OP_WITHIN )
+                                       printf("[%d,%d]", cond[i][j].value.i, cond[i][j].value2.i);
+                               else
+                                       printf("%d", cond[i][j].value.i);
+                               break;
+                       case EDG_WLL_QUERY_ATTR_TIME:
+                               if ( cond[i][j].op == EDG_WLL_QUERY_OP_WITHIN )
+                               {
+                                       printf("[%s,", TimeToStr(cond[i][j].value.t.tv_sec));
+                                       printf("%s] & state = %d", TimeToStr(cond[i][j].value2.t.tv_sec), cond[i][j].attr_id.state);
+                               }
+                               else
+                                       printf("%s & state = %d", TimeToStr(cond[i][j].value.t.tv_sec), cond[i][j].attr_id.state);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               if ( j )
+                       printf(")");
+       }
+       if ( any ) printf("\n");
+}
+
+static void printstat(edg_wll_JobStat stat)
+{
+       char            *s, *j;
+
+
+       s = edg_wll_StatToString(stat.state); 
+       printf("STATUS:\t%s\n\n",s);
+/* print whole flat structure */
+       printf("state : %s\n", s);
+       printf("jobId : %s\n", j = edg_wlc_JobIdUnparse(stat.jobId));
+       printf("owner : %s\n", stat.owner);
+       printf("jobtype : %d\n", stat.jobtype);
+       if (stat.jobtype) {;
+               printf("seed : %s\n", stat.seed);
+               printf("children_num : %d\n", stat.children_num);
+// XXX deal with subjobs (children, children_hist, children_states)
+       }
+       printf("condorId : %s\n", stat.condorId);
+       printf("globusId : %s\n", stat.globusId);
+       printf("localId : %s\n", stat.localId);
+       printf("jdl : %s\n", stat.jdl);
+       printf("matched_jdl : %s\n", stat.matched_jdl);
+       printf("destination : %s\n", stat.destination);
+       printf("network server : %s\n", stat.network_server);
+       printf("condor_jdl : %s\n", stat.condor_jdl);
+       printf("rsl : %s\n", stat.rsl);
+       printf("reason : %s\n", stat.reason);
+       printf("location : %s\n", stat.location);
+       printf("ce_node : %s\n", stat.ce_node);
+       printf("subjob_failed : %d\n", stat.subjob_failed);
+       printf("done_code : %d\n", stat.done_code);
+       printf("exit_code : %d\n", stat.exit_code);
+       printf("resubmitted : %d\n", stat.resubmitted);
+       printf("cancelling : %d\n", stat.cancelling);
+       printf("cancelReason : %s\n", stat.cancelReason);
+       printf("cpuTime : %d\n", stat.cpuTime);
+// XXX user_tags user_values
+       printf("stateEnterTime : %ld.%06ld\n", stat.stateEnterTime.tv_sec,stat.stateEnterTime.tv_usec);
+       printf("lastUpdateTime : %ld.%06ld\n", stat.lastUpdateTime.tv_sec,stat.lastUpdateTime.tv_usec);
+       printf("expectUpdate : %d\n", stat.expectUpdate);
+       printf("expectFrom : %s\n", stat.expectFrom);
+       
+       free(j);
+       free(s);
+}
+
+time_t StrToTime(char *t)
+{
+       struct tm       tm;
+
+       memset(&tm,0,sizeof(tm));
+       setenv("TZ","UTC",1);
+       tzset();
+       sscanf(t,"%4d-%02d-%02d %02d:%02d:%02d",
+                       &tm.tm_year,&tm.tm_mon,&tm.tm_mday,
+                       &tm.tm_hour,&tm.tm_min,&tm.tm_sec);
+       tm.tm_year -= 1900;
+       tm.tm_mon--;
+
+       return mktime(&tm);
+}
+
+static char     tbuf[256];
+
+char *TimeToStr(time_t t)
+{
+       struct tm       *tm = gmtime(&t);
+
+       sprintf(tbuf,"'%4d-%02d-%02d %02d:%02d:%02d'",
+                       tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
+                       tm->tm_hour,tm->tm_min,tm->tm_sec);
+
+       return tbuf;
+}
+
+static void dgerr(edg_wll_Context ctx, char *where)
+{
+       char       *errText,
+                          *errDesc;
+
+
+       edg_wll_Error(ctx, &errText, &errDesc);
+       fprintf(stderr, "%s", errText);
+       if ( where )
+               fprintf(stderr, ": %s", where);
+       if ( errDesc )
+               fprintf(stderr, " (%s)\n", errDesc);
+       else
+               putc('\n', stderr);
+       free(errText);
+       free(errDesc);
+}
+