diff --git a/src/server/distrenjob.c b/src/server/distrenjob.c --- a/src/server/distrenjob.c +++ b/src/server/distrenjob.c @@ -32,7 +32,6 @@ void distrenjob_free(struct distrenjob * dj = *distrenjob; xmlFree(dj->name); xmlFree(dj->submitter); - xmlFree(dj->email); free(dj->frameset); @@ -57,7 +56,6 @@ int distrenjob_new(struct distrenjob **d dj->next = NULL; dj->name = (char *)NULL; dj->submitter = (char *)NULL; - dj->email = (char *)NULL; dj->jobnum = 0; /*< @todo there should be a central jobnum allocator and a way to save the maximum jobnumber allocated */ dj->priority = 0; dj->width = 0; @@ -75,11 +73,49 @@ int distrenjob_new(struct distrenjob **d } /** - writes struct from xml + read an unsigned integer property from an xmlNode + + convenience function for distrenjob_unserialize() + @param xmlnode may be NULL for convenience + @return 0 on success, other on error + */ +int _distrenjob_xml_readuint(xmlNodePtr xmlnode, xmlChar *propname, unsigned int *num) +{ + xmlChar *string; + + if(!xmlnode) + return 1; + + string = xmlGetProp(xmlnode, propname); + if(!string) + return 1; + + *num = (unsigned int)strtoul((char *)string, (char **)NULL, 10); +#ifndef NDEBUG + fprintf(stderr, "_distrenjob_xml_readuint(%zx, \"%s\", *(%zx)=%u): read %s=\"%d\"\n", + (size_t)xmlnode, propname, (size_t)num, *num, propname, *num); +#endif + + xmlFree(string); + return 0; +} + +/** + Loads a distrenjob that was serialized with distrenjob_serialize() + + @see distrenjob_serialize() + @param pathtoxml path to XML file + @param distrenjob will be set to a pointer */ int distrenjob_unserialize(struct distrenjob **distrenjob, char *pathtoxml) { struct distrenjob *dj; + struct frameset *fs; + unsigned int start_frame; + unsigned int end_frame; + unsigned int counter; + + struct tm tm; xmlDocPtr xmldoc; xmlNodePtr xmlnode; @@ -109,7 +145,7 @@ int distrenjob_unserialize(struct distre } xmlxpathcontext = xmlXPathNewContext(xmldoc); - xmlnode = xml_quickxpath(xmlxpathcontext, (xmlChar *)"/distren/job"); + xmlnode = xml_quickxpath(xmlxpathcontext, (xmlChar *)"/job"); if(!xmlnode) { distrenjob_free(distrenjob); @@ -131,28 +167,80 @@ int distrenjob_unserialize(struct distre distrenjob_free(distrenjob); return 5; } - - tmp = _distren_asprintf((char **)&xmlchar, "/distren/submitters/submitter[attribute::name=\"%s\"]", dj->submitter); - if(tmp <= 0 - || !xmlchar) + tmp = _distrenjob_xml_readuint(xmlnode, (xmlChar *)"priority", &dj->priority); + if(tmp) { - fprintf(stderr, "error using _distren_asprintf\n"); distrenjob_free(distrenjob); return 6; } - xmlnode = xml_quickxpath(xmlxpathcontext, xmlchar); - free(xmlchar); - dj->email = (char *)xmlGetProp(xmlnode, (xmlChar *)"email"); - if(!dj->email) + + dj->output_format = (char *)xmlGetProp(xmlnode, (xmlChar *)"output_format"); + if(!dj->output_format) { - fprintf(stderr, "error getting email for user ``%s'' from ``%s''\n", - dj->submitter, pathtoxml); + distrenjob_free(distrenjob); + + return 6; + } + + xmlnode = xml_quickxpath(xmlxpathcontext, (xmlChar *)"/job/resolution"); + tmp = _distrenjob_xml_readuint(xmlnode, (xmlChar *)"width" , &dj->width ); + tmp += _distrenjob_xml_readuint(xmlnode, (xmlChar *)"height" , &dj->height ); + + xmlnode = xml_quickxpath(xmlxpathcontext, (xmlChar *)"/job/video"); + tmp += _distrenjob_xml_readuint(xmlnode, (xmlChar *)"start_frame", &start_frame); + tmp += _distrenjob_xml_readuint(xmlnode, (xmlChar *)"end_frame", &end_frame); + + if(tmp) + { + fprintf(stderr, "distrenjob_unserialize(): error reading integer values from ``%s''\n", + pathtoxml); distrenjob_free(distrenjob); return 7; } + /** + total_render_time and watchdog stuff doesn't need error + checking, just good defaults + */ + xmlnode = xml_quickxpath(xmlxpathcontext, (xmlChar *)"/job/stats"); + dj->total_render_time = 0; + xmlchar = xmlGetProp(xmlnode, (xmlChar *)"total_render_time"); + if(xmlchar) + { + if(strptime((char *)xmlchar, "%D %T", &tm)) + dj->total_render_time = mktime(&tm); + xmlFree(xmlchar); + } + + xmlnode = xml_quickxpath(xmlxpathcontext, (xmlChar *)"/job/watchdog"); + dj->watchdog_forgiveness = 3600; + tmp =_distrenjob_xml_readuint(xmlnode, (xmlChar *)"forgiveness", &dj->watchdog_forgiveness); + if(tmp) + fprintf(stderr, "distrenjob_unserialize(): warning: watchdog forgiveness is unspecified in ``%s'', defaulting to 3600\n", pathtoxml); + xmlXPathFreeContext(xmlxpathcontext); xmlFreeDoc(xmldoc); + + /** + reconstruct the frameset + */ + dj->total_frames = end_frame - start_frame + 1; + dj->frameset = malloc(sizeof(struct frameset) * dj->total_frames); + if(!dj->frameset) + { + fprintf(stderr, "OOM!\n"); + distrenjob_free(distrenjob); + return 8; + } + fs = dj->frameset; + for(counter = start_frame; counter <= end_frame; counter ++) + { + fs->num = counter; + fs->status = FRAMESETSTATUS_UNASSIGNED; /*< @todo job partial completion and resumption support */ + + fs ++; + } + return 0; }