# HG changeset patch # User Binki # Date 2009-08-16 19:52:36 # Node ID 45bf3be8fb9326e6478c6f623f03810de939fa91 # Parent 8bbd89b80b4669c72fc54872d521fb993d3b1ede initial XML parsing for distrenjob diff --git a/src/server/Makefile.am b/src/server/Makefile.am --- a/src/server/Makefile.am +++ b/src/server/Makefile.am @@ -1,4 +1,4 @@ -COMMON_SOURCES = slavefuncs.c slavefuncs.h blendjob.h +COMMON_SOURCES = slavefuncs.c slavefuncs.h distrenjob.c blendjob.h bin_PROGRAMS = distrend distrenslave distrend_SOURCES = distrend.c ${COMMON_SOURCES} diff --git a/src/server/blendjob.h b/src/server/blendjob.h --- a/src/server/blendjob.h +++ b/src/server/blendjob.h @@ -25,7 +25,7 @@ This file stores the blendjob and frameset structs and prototypes for some functions to manipulate/use these. */ -#include /* clock_t */ +#include /* clock_t, time_t */ typedef unsigned int jobnum_t; @@ -36,16 +36,15 @@ struct blendjob { struct blendjob *next; /*< next will be NULL unless if there is another blendjob */ char *name; char *submitter; - char *email; + char *email; /*< This should be looked up based on the value of submitter, not stored in this struct */ jobnum_t jobnum; int priority; // 1 is lowest, 10 is highest, 0 means the job is done - int percent_done; + float percent_done; int completed_frames; // number of completed frames for stats/etc int assigned_frames; // number of assigned frames (that are not yet completed) for stats/etc int total_frames; // how many frames are in the animation for stats/etc (unassigned frames) - int avg_render_time; // average seconds it took to render a frame - unsigned int time_remaining; // estimated seconds remaining till render is complete (up to 49, 710 days) - // we can have the client computer convert it into days, hours, etc if they wish to view it + time_t avg_render_time; // average seconds it took to render a frame + time_t time_remaining; /*< estimated seconds remaining till render is complete (up to 49, 710 days) */ struct frameset *frameset; }; @@ -63,4 +62,31 @@ struct frameset { }; /* Frameset array is generated by status_report_generator() */ +/* +related functions +*/ + +/** + + @param distrenjob the address where we will store the pointer of a malloc()ed + distrenjob struct. + @param pathtoxml filename/pathname of the xml file to be read into a blendjob struct + */ +int xml2distrenjob(struct blendjob **distrenjob, char *pathtoxml); + +/** + support function for xml2distrenjob() to help cleaning up a + struct blendjob when it is incompletely initialized. + Also acts as a general-purpose struct distrenjob free()er ;-) + */ +void distrenjob_free(struct blendjob **distrenjob); + +/** + initializes an empty, pointless struct distrenjob. This + DOES run malloc() for you. It could return nonzero on error, + but there are no errors to have yet (except for nomem). This + sets all char* to NULL. + */ +int distrenjob_new(struct blendjob **distrenjob); + #endif diff --git a/src/server/distrend.c b/src/server/distrend.c --- a/src/server/distrend.c +++ b/src/server/distrend.c @@ -54,6 +54,7 @@ #include "options.h" #include "blendjob.h" #include "protocol.h" +#include "slavefuncs.h" #include #include @@ -488,6 +489,20 @@ int distrend_do_config(int argc, char *a CFG_END() }; + struct blendjob *distrenjob; + + int tmp; + + xmlinit(); + /* + * test xml2distrenjob() + */ + tmp = xml2distrenjob(&distrenjob, "distrenjob.xml.example"); + if(tmp) + fprintf(stderr, "xml2distrenjob() returned %d. Try to cd to distren/doc if you want to test out the xml2distrenjob() function. (This will only fix this error if the error is due to an inability of the xml library to access distrenjob.xml.example)\n", tmp); + else + fprintf(stderr, "using email ``%s'' for user ``%s'' -- reading in XML files and pulling data from them using libxml2+XPath works!!!\n", distrenjob->email, distrenjob->submitter); + fprintf(stderr, "%s:%d running config\n", __FILE__, __LINE__); *config = malloc(sizeof(struct distrend_config)); @@ -497,6 +512,7 @@ int distrend_do_config(int argc, char *a fprintf(stderr, "using %s as datadir\n", (*config)->datadir); + xmlcleanup(); return 0; } int distrend_config_free(struct distrend_config *config) diff --git a/src/server/distrenjob.c b/src/server/distrenjob.c new file mode 100644 --- /dev/null +++ b/src/server/distrenjob.c @@ -0,0 +1,151 @@ +/* + Copyright 2009 Nathan Phillip Brink + + This file is a part of DistRen. + + DistRen is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + DistRen is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with DistRen. If not, see . +*/ + +#include "blendjob.h" +#include "slavefuncs.h" +#include "asprintf.h" + +#include +#include + +void distrenjob_free(struct blendjob **distrenjob) +{ + struct blendjob *dj; + + dj = *distrenjob; + xmlFree(dj->name); + xmlFree(dj->submitter); + xmlFree(dj->email); + + free(dj); + *distrenjob = NULL; +} + +int distrenjob_new(struct blendjob **distrenjob) +{ + struct blendjob *dj; + + dj = malloc(sizeof(struct blendjob)); + if(!dj) + { + /* try to catch code that doesn't respect return values + faster: */ + *distrenjob = NULL; + return 1; + } + *distrenjob = dj; + + 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->percent_done = 0; + dj->completed_frames = 0; + dj->assigned_frames = 0; + dj->avg_render_time = 0; + dj->time_remaining = (unsigned int)-1; + dj->frameset = (struct frameset *)NULL; /*< @todo does frameset need to be initialized here? */ + + return 0; +} + +/** + writes struct from xml +*/ +int xml2distrenjob(struct blendjob **distrenjob, char *pathtoxml) +{ + struct blendjob *dj; + + xmlDocPtr xmldoc; + xmlNodePtr xmlnode; + xmlChar *xmlchar; + + xmlXPathContextPtr xmlxpathcontext; + + int tmp; + + if(distrenjob_new(distrenjob)) + return 1; + dj = *distrenjob; + + xmldoc = xmlReadFile(pathtoxml, NULL, XML_PARSE_PEDANTIC); + if(!xmldoc) + { + /** + @todo are we able to depend on libxml2's printed errors or + channel them into syslog output (eventually)? Currently, + this error is repetitious of a libxml2 error printed on stderr + for us. + */ + fprintf(stderr, "error reading XML file ``%s''\n", pathtoxml); + + distrenjob_free(distrenjob); + return 2; + } + + xmlxpathcontext = xmlXPathNewContext(xmldoc); + xmlnode = xml_quickxpath(xmlxpathcontext, (xmlChar *)"/distren/job"); + if(!xmlnode) + { + distrenjob_free(distrenjob); + return 3; + } + + /*< @todo should we use xmlChar everywhere too? */ + dj->name = (char *)xmlGetProp(xmlnode, (xmlChar *)"name"); + if(!dj->name) + { + distrenjob_free(distrenjob); + return 4; + } + + /*< @todo validation needs to be done on usernames. e.g., currently, they shouldn't contain the '"' char */ + dj->submitter = (char *)xmlGetProp(xmlnode, (xmlChar *)"submitter"); + if(!dj->submitter) + { + distrenjob_free(distrenjob); + return 5; + } + + tmp = _distren_asprintf((char **)&xmlchar, "/distren/submitters/submitter[attribute::name=\"%s\"]", dj->submitter); + if(tmp <= 0 + || !xmlchar) + { + 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) + { + fprintf(stderr, "error getting email for user ``%s'' from ``%s''\n", + dj->submitter, pathtoxml); + distrenjob_free(distrenjob); + return 7; + } + + xmlXPathFreeContext(xmlxpathcontext); + xmlFreeDoc(xmldoc); + return 0; +} +