edg_wll_JobStatCode state;
struct timeval timestamp;
char *reason;
+ char *destination;
+ int done_code;
} lb_historyStatus;
typedef struct _lb_handle {
if (h->fullStatusHistory) {
i = 0;
while (h->fullStatusHistory[i]) {
- if (h->fullStatusHistory[i]->reason) free(h->fullStatusHistory[i]->reason);
+ free(h->fullStatusHistory[i]->reason);
+ free(h->fullStatusHistory[i]->destination);
free (h->fullStatusHistory[i]);
i++;
}
}
static int get_classad_attr(const char* attr, glite_jp_context_t ctx, lb_handle *h, glite_jp_attrval_t **av){
- printf("attr = %s\n", attr);
+/* printf("attr = %s\n", attr); */
glite_jp_error_t err;
glite_jp_clear_error(ctx);
memset(&err,0,sizeof err);
av[0].timestamp = h->status.lastUpdateTime.tv_sec;
}
av[0].size = -1;
+ } else if (strcmp(attr, GLITE_JP_LB_finalDoneStatus) == 0) {
+
+ /* XXX: should be a string */
+ if (h->finalStatus && h->finalStatus->state == EDG_WLL_JOB_DONE) {
+ av = calloc(2, sizeof(glite_jp_attrval_t));
+ av[0].name = strdup(attr);
+
+ trio_asprintf(&av[0].value,"%d",h->status.done_code);
+ av[0].timestamp = h->finalStatus->timestamp.tv_sec;
+ }
+ else {
+ *attrval = NULL;
+ err.code = EINVAL;
+ err.desc = strdup("Final status is not Done");
+ return glite_jp_stack_error(ctx,&err);
+ }
+
} else if (strcmp(attr, GLITE_JP_LB_finalStatusDate) == 0) {
struct tm *t = NULL;
if ( (h->finalStatus) &&
t = calloc(1, sizeof(*t));
i = 0;
while (h->fullStatusHistory[i]) {
- s_str = edg_wll_StatToString(h->fullStatusHistory[i]->state);
+ int state;
+
+ s_str = edg_wll_StatToString(state = h->fullStatusHistory[i]->state);
for (j = 0; s_str[j]; j++) s_str[j] = toupper(s_str[j]);
if (gmtime_r(&h->fullStatusHistory[i]->timestamp.tv_sec,t) != NULL) {
/* dateTime format: yyyy-mm-ddThh:mm:ss:uuuuuu */
h->fullStatusHistory[i]->timestamp.tv_usec);
}
if (h->fullStatusHistory[i]->reason) {
- trio_asprintf(&r_str,"reason=\"%s\" ",h->fullStatusHistory[i]->reason);
+ trio_asprintf(&r_str,"reason=\"%|Xs\" ",h->fullStatusHistory[i]->reason);
}
+
+ if (h->fullStatusHistory[i]->destination &&
+ state >= EDG_WLL_JOB_READY &&
+ state <= EDG_WLL_JOB_DONE
+ ) {
+ char *aux;
+ trio_asprintf(&aux,"%s destination=\"%|Xs\"",
+ r_str ? r_str : "",
+ h->fullStatusHistory[i]->destination);
+ r_str = aux;
+ }
+
+ if (state == EDG_WLL_JOB_DONE) {
+ char *aux;
+ trio_asprintf(&aux,"%s doneCode=\"%d\"",
+ r_str ? r_str : "",
+ h->fullStatusHistory[i]->done_code);
+ r_str = aux;
+ }
+
trio_asprintf(&val,"%s\t\t<status xmlns=\"" GLITE_JP_LB_NS "\" name=\"%s\" %s%s/>\n",
old_val, s_str ? s_str : "", t_str ? t_str : "", r_str ? r_str : "");
if (s_str) free(s_str); s_str = NULL;
if ( (js->pub.state == EDG_WLL_JOB_CLEARED) && (nstates > 0) ) {
h->finalStatus = h->fullStatusHistory[nstates-1];
}
+
+ h->fullStatusHistory[nstates]->destination = check_strdup(js->pub.destination);
+ h->fullStatusHistory[nstates]->done_code = js->pub.done_code;
+
old_state = js->pub.state;
nstates++;
}
/*
+ * realloc the line to double size if needed
+ *
+ * \return 0 if failed, did nothing
+ * \return 1 if success
+ */
+int check_realloc_line(char **line, size_t *maxlen, size_t len) {
+ void *tmp;
+
+ if (len > *maxlen) {
+ *maxlen <<= 1;
+ tmp = realloc(*line, *maxlen);
+ if (!tmp) return 0;
+ *line = tmp;
+ }
+
+ return 1;
+}
+
+
+typedef struct _rl_buffer_t {
+ char *buf;
+ size_t pos, size;
+ off_t offset;
+} rl_buffer_t;
+
+
+/*
+ * read next line from stream
+ *
+ * \return error code
+ */
+int glite_jppsbe_readline(
+ glite_jp_context_t ctx,
+ void *handle,
+ rl_buffer_t *buffer,
+ char **line
+)
+{
+ size_t maxlen, len, i;
+ ssize_t nbytes;
+ int retval, z, end;
+
+ maxlen = BUFSIZ;
+ i = 0;
+ len = 0;
+ *line = malloc(maxlen);
+ end = 0;
+
+ do {
+ /* read next portion */
+ if (buffer->pos >= buffer->size) {
+ buffer->pos = 0;
+ buffer->size = 0;
+ if ((retval = glite_jppsbe_pread(ctx, handle, buffer->buf, BUFSIZ, buffer->offset, &nbytes)) == 0) {
+ if (nbytes < 0) {
+ retval = EINVAL;
+ goto fail;
+ } else {
+ if (nbytes) {
+ buffer->size = (size_t)nbytes;
+ buffer->offset += nbytes;
+ } else end = 1;
+ }
+ } else goto fail;
+ }
+
+ /* we have buffer->size - buffer->pos bytes */
+ i = buffer->pos;
+ do {
+ if (i >= buffer->size) z = '\0';
+ else {
+ z = buffer->buf[i];
+ if (z == '\n') z = '\0';
+ }
+ len++;
+
+ if (!check_realloc_line(line, &maxlen, len)) {
+ retval = ENOMEM;
+ goto fail;
+ }
+ (*line)[len - 1] = z;
+ i++;
+ } while (z && i < buffer->size);
+ buffer->pos = i;
+ } while (len && (*line)[len - 1] != '\0');
+
+ if ((!len || !(*line)[0]) && end) {
+ free(*line);
+ *line = NULL;
+ }
+
+ return 0;
+
+fail:
+ free(*line);
+ *line = NULL;
+ return retval;
+}
+
+char* glite_jpps_get_namespace(const char* attr){
+ char* namespace = strdup(attr);
+ char* colon = strrchr(namespace, ':');
+ if (colon)
+ namespace[strrchr(namespace, ':') - namespace] = 0;
+ else
+ namespace[0] = 0;
+ return namespace;
+}
+
+
+/*
* free the array of JP attr
*/
static void free_attrs(glite_jp_attrval_t *av) {
outfile = stdout;
}
+ jpctx = calloc(1,sizeof *jpctx);
/* use the plugin */
plugin_init(jpctx, &plugin_data);
+
+ jpctx->plugins = calloc(2,sizeof(*jpctx->plugins));
+ jpctx->plugins[0] = &plugin_data;
+
plugin_data.ops.open(jpctx, infile, "uri://", &data_handle);
if (data_handle) {
free_attrs(attrval);
}
+ plugin_data.ops.attr(jpctx, data_handle, GLITE_JP_LB_finalDoneStatus, &attrval);
+ if (attrval) {
+ fprintf(outfile,"\t<finalDoneStatus>%s</finalDoneStatus>\n", attrval->value);
+ free_attrs(attrval);
+ }
+
plugin_data.ops.attr(jpctx, data_handle, GLITE_JP_LB_finalStatusDate, &attrval);
if (attrval) {
fprintf(outfile,"\t<finalStatusDate>%s</finalStatusDate>\n", attrval->value);