Sophie

Sophie

distrib > Fedora > 20 > x86_64 > by-pkgid > bedf91032ed70d54171ed9de07e5acac > files > 33

glite-lb-client-devel-6.0.10-1.fc20.i686.rpm

#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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <unistd.h>

#include "glite/lb/context-int.h"
#ifdef BUILDING_LB_CLIENT
#include "consumer.h"
#else
#include "glite/lb/consumer.h"
#endif
#include "glite/lb/xml_conversions.h"
#include "glite/lb/jobstat.h"

static void dgerr(edg_wll_Context,char *);
static void printstat(edg_wll_JobStat,int);

#define MAX_SERVERS	20

/* these are defined in pbs_ifl.h or qstat.c */
#define PBS_MAXSEQNUM           8
#define PBS_MAXJOBARRAYLEN      6
#define PBS_MINNAMELEN         16
#define PBS_NAMELEN            16
#define OWNERL                 15
#define TIMEUL                  8
#define STATEL                  1
#define LOCL                   15

/* original qstat options */
#define GETOPT_ARGS "aeE:filn1qrsu:xGMQRBW:-:"

/* defines for alternative display formats */
#define ALT_DISPLAY_a 1 /* -a option - show all jobs */
#define ALT_DISPLAY_i 2 /* -i option - show not running */
#define ALT_DISPLAY_r 4 /* -r option - show only running */
#define ALT_DISPLAY_u 8 /* -u option - list user's jobs */
#define ALT_DISPLAY_n 0x10 /* -n option - add node list */
#define ALT_DISPLAY_s 0x20 /* -s option - add scheduler comment */
#define ALT_DISPLAY_R 0x40 /* -R option - add SRFS info */
#define ALT_DISPLAY_q 0x80 /* -q option - alt queue display */
#define ALT_DISPLAY_Mb 0x100 /* show sizes in MB */
#define ALT_DISPLAY_Mw 0x200 /* -M option - show sizes in MW */
#define ALT_DISPLAY_G  0x400 /* -G option - show sizes in GB */
#define ALT_DISPLAY_o  0x800   /* -1 option - add node list on same line */
#define ALT_DISPLAY_l 0x1000 /* -l option - show long job name */

#define MAXLINESIZE 65536

static char 	*myname;

/* globals */
int linesize = 77;
int alias_opt = 0;

static void usage(char *);
static int query_all(edg_wll_Context, edg_wll_JobStat **, edg_wlc_JobId **);

/*
 * print a attribute value string, formating to break a comma if possible
 */

void prt_attr(
	
	char *n,  /* I name */
	char *r,  /* I resource (optional) */
	char *v)  /* I value */
	
{
	char *c;
	char *comma = ",";
	int   first = 1;
	int   l;
	int   start;
	
	start = strlen(n) + 7; /* 4 spaces + ' = ' is 7 */
	
	printf("    %s",  n);
	
	if (r != NULL)
	{
		start += strlen(r) + 1;
		
		printf(".%s", r);
	}
	
	printf(" = ");
	
	c = strtok(v, comma);
	
	while (c != NULL)
	{
		if ((l = strlen(c)) + start < linesize)
		{
			printf("%s", c);
			start += l;
		}
		else
		{
			if (!first)
			{
				printf("\n\t");
				start = 9;
			}
			
			while (*c)
			{
				putchar(*c++);
				
				if (++start > linesize)
				{
					start = 8;
					printf("\n\t");
				}
			}
		}

		if ((c = strtok(NULL, comma)) != NULL)
		{
			first = 0;
			putchar(',');
		}
	}
	
	return;
}  /* END prt_attr() */


/* display when a normal "qstat" is executed */

void display_statjob(

	edg_wll_JobStat      *status,    /* I (data) */
	int                  prtheader, /* I (boolean) */
	int                  full)      /* I (boolean) */
	
{
	edg_wll_TagValue *a;
	int i;

	int l;
	char *c;
	char *jid;
	char *name;
	char *owner;
	char *timeu;
	char *state;
	char *location;
	char format[80];
	char long_name[17];
	time_t epoch;
		
	if (!full)
	{
		sprintf(format, "%%-%ds %%-%ds %%-%ds %%%ds %%%ds %%-%ds\n",
			PBS_MAXSEQNUM + PBS_MAXJOBARRAYLEN + 11,
			PBS_MINNAMELEN,
			OWNERL,
			TIMEUL,
			STATEL,
			LOCL);
		
		if (prtheader)
		{
			/* display summary header TODO - the sizes of these fields should be determined from
			   #defines in pbs_ifl.h */
			printf("Job id                    Name             User            Time Use S Queue\n");
			printf("------------------------- ---------------- --------------- -------- - -----\n");
		}
	}    /* END if (!full) */
		

	for(i = 0; status[i].state; i++)
	{
		jid = NULL;
		name = NULL;
		owner = NULL;
		timeu = NULL;
		state = NULL;
		location = NULL;
		
		if (full)
		{
			printf("Job Id: %s\n", jid = glite_jobid_getUnique(status[i].jobId));
			free(jid);
			
			printstat(status[i], 1);

		}   /* END if (full) */
		else
		{
			/* display summary data */

			/* Job ID (PBS style, so truncated unique part of LB jobid) */
			jid = glite_jobid_getUnique(status[i].jobId);
			if(jid != NULL) {

				c = jid;
				while ((*c != '.') && (*c != '\0'))
					c++;
				
				if (alias_opt)
				{
					/* show the alias as well as the first part of the server name */
					if (*c == '.')
					{
						c++;
						while((*c != '.') && (*c != '\0'))
							c++;
					}
				}
				
				c++;    /* List the first part of the server name, too. */
				while ((*c != '.') && (*c != '\0'))
					c++;
				*c = '\0';
				
				l = strlen(jid);
				
				if (l > (PBS_MAXSEQNUM + PBS_MAXJOBARRAYLEN + 8))
				{
					/* truncate job name */
					c = jid + PBS_MAXSEQNUM + PBS_MAXJOBARRAYLEN + 14;
					
					*c = '\0';
				}
			}
			
			if(status[i].pbs_name) 
			{
				l = strlen(status[i].pbs_name);
					
				/* truncate AName */
				if (l > PBS_NAMELEN)
				{
					l = l - PBS_NAMELEN + 3;
					c = status[i].pbs_name + l;
						
					while ((*c != '/') && (*c != '\0'))
						c++;
						
					if (*c == '\0')
						c = a->value + l;
					
					strcpy(long_name, "...");
					strcat(long_name, c);
					c = long_name;
				}
				else
				{
					c = status[i].pbs_name;
				}
					
				name = c;
			}
			
			if(status[i].pbs_owner)
			{
				c = status[i].pbs_owner;
						
				while ((*c != '@') && (*c != '\0'))
					c++;
				
				*c = '\0';
						
				l = strlen(status[i].pbs_owner);
				if (l > OWNERL)
				{
					c = status[i].pbs_owner + OWNERL;
					*c = '\0';
				}
				owner = status[i].pbs_owner;
			}

			if(status[i].pbs_resource_usage) {
				edg_wll_TagValue *tag;

				for(tag = status[i].pbs_resource_usage; tag->tag; tag++) {
					if(!strcmp(tag->tag, "cput")) {

						l = strlen(tag->value);
						if (l > TIMEUL)
						{
							c = tag->value + TIMEUL;
								*c = '\0';
						}
						timeu = tag->value;
						break;
					}
				}
			}

			if(status[i].pbs_state) {
				l = strlen(status[i].pbs_state);
				if (l > STATEL)
				{
					c = status[i].pbs_state + STATEL;
					*c = '\0';
				}
				state = status[i].pbs_state;
			}

			if(status[i].pbs_queue) {
				c = status[i].pbs_queue;
					
				while ((*c != '@') && (*c != '\0'))
					c++;
				
				*c = '\0';
					
				l = strlen(status[i].pbs_queue);
				if (l > LOCL)
				{
					c = status[i].pbs_queue + LOCL;
					*c = '\0';
				}
				location = status[i].pbs_queue;
				
			}

			if (timeu == NULL)
				timeu = "0";
			
			/* display summary data */
			
			printf(format,
			       jid,
			       name,
			       owner,
			       timeu,
			       state,
			       location);
		}  /* END else (full) */
		
		if (full)
			printf("\n");

	}  /* END for */
	
	return;
}  /* END display_statjob() */


int main(int argc,char *argv[])
{
	edg_wll_Context	sctx[MAX_SERVERS];
	char		*pc, *servers[MAX_SERVERS];
	int		c, i, result=0, nsrv=0, histflags = 0;
	int             f_opt = 0, alt_opt = 0;
	
	myname = argv[0];
	printf("\n");

	while((c = getopt(argc, argv, GETOPT_ARGS)) != EOF) {
		switch(c) {
		case '1':
			/* do not break lines in output */
			alt_opt |= ALT_DISPLAY_o;
			break;

		case 'a':
			/* alternative display */
			alt_opt |= ALT_DISPLAY_a;
			break;

		case 'e':
			/* display only jobs in executable queues */
			break;

		case 'E':
			/* not documented */
			break;

		case 'i':
			/* do not display running jobs */
			alt_opt |= ALT_DISPLAY_i;
			break;
			
		case 'n':
			/* display also allocated nodes */
			alt_opt |= ALT_DISPLAY_n;
			break;

		case 'q':
			/* display queue status */
			alt_opt |= ALT_DISPLAY_q;
			break;

		case 'r':
			/* display only running (or suspended) jobs */
			alt_opt |= ALT_DISPLAY_r;
			break;
		       
		case 's':
			/* display also job comments */
			alt_opt |= ALT_DISPLAY_s;
			break;

		case 'u':
			/* display jobs owned by given users */
			alt_opt |= ALT_DISPLAY_u;
			break;

		case 'R':
			/* display also disk reservation information */
			alt_opt |= ALT_DISPLAY_R;
			break;

		case 'G':
			/* show size in GB units */
			alt_opt |= ALT_DISPLAY_G;
			break;

		case 'M':
			/* display size in Megawords */
			alt_opt |= ALT_DISPLAY_Mw;
			break;

		case 'f':
			/* display full job status */
			if(alt_opt) {
				fprintf(stderr, "%s: option -f conflicts with other display options\n", myname);
				usage(myname);
				exit(2);
			}
			f_opt = 1;
			break;

		case 'x':
			/* display output in XML (implies -f) */
			break;

		case 'B':
			/* display batch server status */
			break;

		case 'l':
			/* display long name of job */
			alt_opt |= ALT_DISPLAY_l;
			break;

		case 'Q':
			/* display queue status */
			break;

		case '-':
			/* handle '--' options */
			if(optarg && !strcmp(optarg, "version")) {
			}
			if(optarg && !strcmp(optarg, "about")) {
			}
			if(optarg && !strcmp(optarg, "help")) {
			}
			break;

		case 'W':
			/* display format options */
			pc = optarg;
			
			while (*pc) {
				switch (*pc) {
					
				case 'a':
					alt_opt |= ALT_DISPLAY_a;
					break;

				case 'i':
					alt_opt |= ALT_DISPLAY_i;
					break;

				case 'r':
					alt_opt |= ALT_DISPLAY_r;
					break;

				case 'u':
					/* note - u option is assumed to be last in  */
					/* string and all remaining is the name list */
					alt_opt |= ALT_DISPLAY_u;
					while (*++pc == ' ');
					pc = pc + strlen(pc) - 1; /* for the later incr */
					break;
					
				case 'n':
					alt_opt |= ALT_DISPLAY_n;
					break;

				case 's':
					alt_opt |= ALT_DISPLAY_s;
					break;

				case 'q':
					break;

				case 'R':
					alt_opt |= ALT_DISPLAY_R;
					break;

				case 'G':
					alt_opt |= ALT_DISPLAY_G;
					break;

				case 'M':
					alt_opt |= ALT_DISPLAY_Mw;
					break;

				case ' ':
					break;  /* ignore blanks */
					
				default:
					break;
				}
				
				++pc;
			}

		case '?':
			break;

		default:
			break;
		}
	}

	/* certain combinations are not allowed */

	c = alt_opt & (ALT_DISPLAY_a | ALT_DISPLAY_i | ALT_DISPLAY_r | ALT_DISPLAY_q);

	if ((c != 0) &&
	    (c != ALT_DISPLAY_a) &&
	    (c != ALT_DISPLAY_i) &&
	    (c != ALT_DISPLAY_r) &&
	    (c != ALT_DISPLAY_q)) {
		fprintf(stderr, "%s: conflicting options\n", myname);
		usage(myname);
		exit(2);
	}

	c = alt_opt & (ALT_DISPLAY_Mw | ALT_DISPLAY_G);
	if (c == (ALT_DISPLAY_Mw | ALT_DISPLAY_G))  {
		fprintf(stderr, "%s: conflicting options\n", myname);
		usage(myname);
		exit(2);
	}

	if ((alt_opt & ALT_DISPLAY_q) && (f_opt == 1)) {
		fprintf(stderr, "%s: conflicting options\n", myname);
		usage(myname);
		exit(2);
	}

	if ((alt_opt & ALT_DISPLAY_o) && !((alt_opt & ALT_DISPLAY_n) || (f_opt)))
	{
		fprintf(stderr, "%s: conflicting options\n", myname);
		usage(myname);
		exit(2);
	}

	if (alt_opt & ALT_DISPLAY_o)
	{
		linesize = MAXLINESIZE;
		alt_opt &= ~ALT_DISPLAY_o;
	}

	if ( edg_wll_InitContext(&sctx[0]) ) {
		fprintf(stderr,"cannot initialize edg_wll_Context\n");
		exit(1);
	}

	if ( optind >= argc )  {
		edg_wll_JobStat		*statesOut;
		edg_wlc_JobId		*jobsOut;

		jobsOut = NULL;
		statesOut = NULL;
		if ( (result = query_all(sctx[0], &statesOut, &jobsOut)) ) 
			dgerr(sctx[0], "edg_wll_QueryJobs");
		else 
			display_statjob(statesOut, 1, f_opt);

		if ( jobsOut ) {
			for (i=0; jobsOut[i]; i++) edg_wlc_JobIdFree(jobsOut[i]);
			free(jobsOut);
		}
		if ( statesOut ) {
			for (i=0; statesOut[i].state; i++) edg_wll_FreeStatus(&statesOut[i]);
			free(statesOut);
		}
		edg_wll_FreeContext(sctx[0]);

		return result;
	} 

	for (i = optind ; i < argc; i++ ) {
		int		j;
		char		*bserver;
		edg_wlc_JobId 	job;		
		edg_wll_JobStat status[2];

		memset(&status, 0, sizeof status);
	
		if (edg_wlc_JobIdParse(argv[i], &job)) {
			fprintf(stderr,"%s: %s: cannot parse jobId\n", myname, argv[i]);
			continue;
		}
		bserver = edg_wlc_JobIdGetServer(job);
		if (!bserver) {
			fprintf(stderr,"%s: %s: cannot extract bookkeeping server address\n", myname, argv[i]);
			edg_wlc_JobIdFree(job);
			continue;
		}
		for ( j = 0; j < nsrv && strcmp(bserver, servers[j]); j++ );
		if ( j == nsrv ) {
			if ( i > optind ) 
				edg_wll_InitContext(&sctx[j]);
			nsrv++;
			servers[j] = bserver;
		}

		if (edg_wll_JobStatus(sctx[j], job, EDG_WLL_STAT_CLASSADS | EDG_WLL_STAT_CHILDREN |  EDG_WLL_STAT_CHILDSTAT | histflags, status)) {
			dgerr(sctx[j],"edg_wll_JobStatus"); result = 1; 
		} else display_statjob(status, 1, f_opt);

		if (job) edg_wlc_JobIdFree(job);
		if (status[0].state) edg_wll_FreeStatus(status);
		
	}
	for ( i = 0; i < nsrv; i++ ) edg_wll_FreeContext(sctx[i]);
	
	return result;
}


static void
usage(char *name)
{
	fprintf(stderr, 
		"Usage: \n\n"
		"%s [-f [-1]] [-l] [-W site_specific] [-x] [job_identifier... | destination...]\n\n"
		"%s [-a|-i|-r|-e] [-l] [-n [-1]] [-s]  [-G|-M]  [-R]  [-u  user_list] [job_identifier... |  destination...]\n",
		name, name);
}


static int
query_all(edg_wll_Context ctx, edg_wll_JobStat **statesOut, edg_wlc_JobId **jobsOut)
{
	edg_wll_QueryRec        jc[2];
	int			ret;

	memset(jc, 0, sizeof jc);
	jc[0].attr = EDG_WLL_QUERY_ATTR_OWNER;
       	jc[0].op = EDG_WLL_QUERY_OP_EQUAL;
	jc[0].value.c = NULL;	/* is NULL, peerName filled in on server side */
	jc[1].attr = EDG_WLL_QUERY_ATTR_UNDEF;

	if ( (ret = edg_wll_QueryJobs(ctx, jc, 0, jobsOut, statesOut)) ) {
		if ( ret == E2BIG ) {
			int r;
			if ( edg_wll_GetParam(ctx, EDG_WLL_PARAM_QUERY_RESULTS, &r) ) return ret;
			if ( r != EDG_WLL_QUERYRES_LIMITED ) return ret;

			printf("Warning: only limited result returned!\n");
			return 0;
		} else return ret;
	}

	return ret;
}

static void
dgerr(edg_wll_Context ctx,char *where)
{
	char 	*etxt,*edsc;

	edg_wll_Error(ctx,&etxt,&edsc);
	fprintf(stderr,"%s: %s: %s",myname,where,etxt);
	if (edsc) fprintf(stderr," (%s)",edsc);
	putc('\n',stderr);
	free(etxt); free(edsc);
}

static void printstat(edg_wll_JobStat stat, int level)
{
	char		*s, *j1,*j2, ind[10];
	int 		i;


	for (i=0; i < level; i++)
		ind[i]='\t';
	ind[i]='\0';
	
	s = edg_wll_StatToString(stat.state); 
/* print whole flat structure */
	printf("%sstate : %s\n", ind, s);
	printf("%sjobId : %s\n", ind, j1 = edg_wlc_JobIdUnparse(stat.jobId)); free(j1);
	printf("%sowner : %s\n", ind, stat.owner);
	printf("%spayload_owner : %s\n", ind, stat.payload_owner);
	switch (stat.jobtype) {
		case EDG_WLL_STAT_SIMPLE:
			printf("%sjobtype : SIMPLE\n", ind);
			break;
		case EDG_WLL_STAT_DAG:
			printf("%sjobtype : DAG\n", ind);
                        break;
		case EDG_WLL_STAT_COLLECTION:
			printf("%sjobtype : COLLECTION\n", ind);
                        break;
		case EDG_WLL_STAT_PBS:
			printf("%sjobtype : PBS\n", ind);
                        break;
		case EDG_WLL_STAT_CONDOR:
			printf("%sjobtype : CONDOR\n", ind);
                        break;
		case EDG_WLL_STAT_CREAM:
			printf("%sjobtype : CREAM\n", ind);
                        break;
		case EDG_WLL_STAT_FILE_TRANSFER:
			printf("%sjobtype : FILE_TRANSFER\n", ind);
                        break;
		case EDG_WLL_STAT_FILE_TRANSFER_COLLECTION:
			printf("%sjobtype : FILE_TRANSFER_COLLECTION\n", ind);
                        break;
		default:
			printf("%sjobtype : UNKNOWN\n", ind);
			break;
	}
	printf("%sparent_job : %s\n", ind,
			j2 = edg_wlc_JobIdUnparse(stat.parent_job));
	if (stat.jobtype) {;
		printf("%sseed : %s\n", ind, stat.seed);
		printf("%schildren_num : %d\n", ind, stat.children_num);
		printf("%schildren :\n", ind);
		if (stat.children) 
			for  (i=0; stat.children[i]; i++) 
				printf("%s\tchildren : %s\n", ind, stat.children[i]);
		printf("%schildren_states :\n", ind);
		if (stat.children_states)
		 	for  (i=0; stat.children_states[i].state; i++)
		 		printstat(stat.children_states[i], level+1);
		printf("%schildren_hist :\n",ind);
		if (stat.children_hist) 
			for (i=1; i<=stat.children_hist[0]; i++) 
				printf("%s%14s  %d\n", ind, edg_wll_StatToString(i-1),stat.children_hist[i]);
	}
	printf("%scondorId : %s\n", ind, stat.condorId);
	printf("%sglobusId : %s\n", ind, stat.globusId);
	printf("%slocalId : %s\n", ind, stat.localId);
	printf("%sjdl : %s\n", ind, stat.jdl);
	printf("%smatched_jdl : %s\n", ind, stat.matched_jdl);
	printf("%sdestination : %s\n", ind, stat.destination);
	printf("%snetwork server : %s\n", ind, stat.network_server);
	printf("%scondor_jdl : %s\n", ind, stat.condor_jdl);
	printf("%srsl : %s\n", ind, stat.rsl);
	printf("%sreason : %s\n", ind, stat.reason);
	printf("%slocation : %s\n", ind, stat.location);
	printf("%sce_node : %s\n", ind, stat.ce_node);
	printf("%ssubjob_failed : %d\n", ind, stat.subjob_failed);
	printf("%sdone_code : %s\n", ind, edg_wll_done_codeToString(stat.done_code));
	printf("%sexit_code : %d\n", ind, stat.exit_code);
	printf("%sresubmitted : %d\n", ind, stat.resubmitted);
	printf("%scancelling : %d\n", ind, stat.cancelling);
	printf("%scancelReason : %s\n", ind, stat.cancelReason);
	printf("%scpuTime : %d\n", ind, stat.cpuTime);
	printf("%suser_tags :\n",ind);
	if (stat.user_tags) 
		for (i=0; stat.user_tags[i].tag; i++) printf("%s%14s = \"%s\"\n", ind, 
						      stat.user_tags[i].tag,stat.user_tags[i].value);
	printf("%sstateEnterTime : %ld.%06ld\n", ind, stat.stateEnterTime.tv_sec,stat.stateEnterTime.tv_usec);
	printf("%sstateEnterTimes : \n",ind);
	if (stat.stateEnterTimes)  
                for (i=1; i<=stat.stateEnterTimes[0]; i++) {
			time_t	st = stat.stateEnterTimes[i];

			printf("%s%14s  %s", ind, edg_wll_StatToString(i-1), st == 0 ? 
			"    - not available -\n" : ctime(&st));
		}
	printf("%slastUpdateTime : %ld.%06ld\n", ind, stat.lastUpdateTime.tv_sec,stat.lastUpdateTime.tv_usec);
	printf("%sexpectUpdate : %d\n", ind, stat.expectUpdate);
	printf("%sexpectFrom : %s\n", ind, stat.expectFrom);
	printf("%sacl : %s\n", ind, stat.acl);
	printf("%saccess rights : \n%s", ind, stat.access_rights);
	printf("%spayload_running: %d\n", ind, stat.payload_running);
	if (stat.possible_destinations) {
		printf("%spossible_destinations : \n", ind);
		for (i=0; stat.possible_destinations[i]; i++) 
			printf("%s\t%s \n", ind, stat.possible_destinations[i]);
	}
	if (stat.possible_ce_nodes) {
		printf("%spossible_ce_nodes : \n", ind);
		for (i=0; stat.possible_ce_nodes[i]; i++) 
			printf("%s\t%s \n", ind, stat.possible_ce_nodes[i]);
	}
	printf("%ssuspended : %d\n", ind, stat.suspended);
	printf("%ssuspend_reason : %s\n", ind, stat.suspend_reason);
	printf("%sfailure_reasons : %s\n", ind, stat.failure_reasons);
	printf("%sremove_from_proxy : %d\n", ind, stat.remove_from_proxy);
	printf("%sui_host : %s\n", ind, stat.ui_host);
	if (stat.user_fqans) {
                printf("%suser_fqans : \n", ind);
                for (i=0; stat.user_fqans[i]; i++) 
                        printf("%s\t%s \n", ind, stat.user_fqans[i]);
        }
	printf("%ssandbox_retrieved : %d\n", ind, stat.sandbox_retrieved);
	printf("%sjw_status : %s\n", ind, edg_wll_JWStatToString(stat.jw_status));
	
	printf("%sisb_transfer : %s\n", ind, j1 = edg_wlc_JobIdUnparse(stat.isb_transfer)); free(j1);
	printf("%sosb_transfer : %s\n", ind, j1 = edg_wlc_JobIdUnparse(stat.osb_transfer)); free(j1);
	
	/* PBS state section */
	if (stat.jobtype == EDG_WLL_STAT_PBS) {
		printf("%spbs_state : %s\n", ind, stat.pbs_state);
		printf("%spbs_queue : %s\n", ind, stat.pbs_queue);
		printf("%spbs_owner : %s\n", ind, stat.pbs_owner);
		printf("%spbs_name : %s\n", ind, stat.pbs_name);
		printf("%spbs_reason : %s\n", ind, stat.pbs_reason);
		printf("%spbs_scheduler : %s\n", ind, stat.pbs_scheduler);
		printf("%spbs_dest_host : %s\n", ind, stat.pbs_dest_host);
		printf("%spbs_pid : %d\n", ind, stat.pbs_pid);
		printf("%spbs_resource_usage : %s\n", ind, edg_wll_TagListToString(stat.pbs_resource_usage));
		printf("%spbs_exit_status : %d\n", ind, stat.pbs_exit_status);
		printf("%spbs_error_desc : %s%s\n", ind, 
			(stat.pbs_error_desc) ? "\n" : "", stat.pbs_error_desc);
	}

	/* CREAM state section */
	char *cream_stat_name = edg_wll_CreamStatToString(stat.cream_state);
	if (stat.jobtype == EDG_WLL_STAT_CREAM || cream_stat_name) {
		printf("%scream_state : %s\n", ind, cream_stat_name);
		printf("%scream_owner : %s\n", ind, stat.cream_owner);
		printf("%scream_endpoint : %s\n", ind, stat.cream_endpoint);
		printf("%scream_jdl : %s\n", ind, stat.cream_jdl);
		printf("%scream_reason : %s\n", ind, stat.cream_reason);
		printf("%scream_lrms_id : %s\n", ind, stat.cream_lrms_id);
		printf("%scream_node : %s\n", ind, stat.cream_node);
		printf("%scream_done_code : %d\n", ind, stat.cream_done_code);
		printf("%scream_exit_code : %d\n", ind, stat.cream_exit_code);
		printf("%scream_cancelling : %d\n", ind, stat.cream_cancelling);
		printf("%scream_cpu_time : %d\n", ind, stat.cream_cpu_time);
		printf("%scream_jw_status : %s\n", ind,  edg_wll_JWStatToString(stat.cream_jw_status));
	}
	if (cream_stat_name) free(cream_stat_name);

	/* File Transfer section */
	printf("%sft_compute_job : %s\n", ind, j1 = edg_wlc_JobIdUnparse(stat.ft_compute_job)); free(j1);
	if (stat.ft_sandbox_type == EDG_WLL_STAT_INPUT)
		printf("%sft_sandbox_type : INPUT\n", ind);
	else  if (stat.ft_sandbox_type == EDG_WLL_STAT_OUTPUT)
		printf("%sft_sandbox_type : OUTPUT\n", ind);
	else
		printf("%sft_sandbox_type : UNKNOWN\n", ind);
	printf("%sft_src : %s\n", ind, stat.ft_src);
	printf("%sft_dest : %s\n", ind, stat.ft_dest);
	

	printf("\n");	
	
	free(j2);
	free(s);
}