diff -r 000000000000 -r ae7b3fa753dc get_attached_files.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/get_attached_files.c Thu Nov 16 08:30:26 2006 +0000 @@ -0,0 +1,148 @@ +/* + * This program parses the XML data provided by sourceforge to extract the + * list of "attached files" (which are not themselves included in the XML + * stream and therefore need to be seperately downloaded for archiving). + */ + +#include +#include +#include +#include +#include + +struct artifact_type { + char *name; + int id; +} artifact_types[] = { + "Bugs", 109746, + "Support Requests", 209746, + "Patches", 309746, + "Feature Requests", 359746, +}; + +#ifndef NO_ELEMS +#define NO_ELEMS(array) (sizeof(array)/sizeof(*(array))) +#endif + +void parse_history(xmlDocPtr doc,const xmlChar *artifact_id, + const xmlChar *artifact_type,xmlNodePtr node) +{ + xmlNodePtr field,cur; + xmlAttrPtr attr; + xmlChar *name=NULL; + xmlChar *field_name=NULL; + xmlChar *text; + int file_id,i; + for(field=node->xmlChildrenNode;field;field=field->next) + if (!xmlStrcmp(field->name,(const xmlChar *)"field")) + { + for(attr=field->properties;attr;attr=attr->next) + if (!xmlStrcmp(attr->name,(const xmlChar *)"name")) + { + name=xmlNodeListGetString(doc,attr->children,1); + if (!xmlStrcmp(name,(const xmlChar *)"field_name")) + field_name=xmlNodeListGetString(doc,field->children,1); + if (!xmlStrcmp(field_name,(const xmlChar *)"File Added") && + !xmlStrcmp(name,(const xmlChar *)"old_value")) + { + text=xmlNodeListGetString(doc,field->children,1); + if (sscanf(text,"%d",&file_id)==1) + { + for(i=NO_ELEMS(artifact_types)-1;i>=0;i--) + if (!strcmp(artifact_types[i].name, + (const char *)artifact_type)) + break; + if (i>=0) + printf("%d %s %d\n", + artifact_types[i].id,artifact_id,file_id); + else + fprintf(stderr, + "Warning: Unknown artifact type \"%s\" - " + "attached file %s ignored\n", + artifact_type,text); + } + xmlFree(text); + } + xmlFree(name); + } + } + if (field_name) + xmlFree(field_name); +} + +void parse_artifact(xmlDocPtr doc,xmlNodePtr node) +{ + xmlNodePtr field,cur; + xmlAttrPtr attr; + xmlChar *name=NULL; + xmlChar *id=NULL; + xmlChar *type=NULL; + xmlChar *text; + for(field=node->xmlChildrenNode;field;field=field->next) + if (!xmlStrcmp(field->name,(const xmlChar *)"field")) + { + for(attr=field->properties;attr;attr=attr->next) + if (!xmlStrcmp(attr->name,(const xmlChar *)"name")) + { + name=xmlNodeListGetString(doc,attr->children,1); + if (!xmlStrcmp(name,(const xmlChar *)"artifact_id")) + id=xmlNodeListGetString(doc,field->children,1); + if (!xmlStrcmp(name,(const xmlChar *)"artifact_type")) + type=xmlNodeListGetString(doc,field->children,1); + } + if (!xmlStrcmp(name,(const xmlChar *)"artifact_history")) + for(cur=field->xmlChildrenNode;cur;cur=cur->next) + if (!xmlStrcmp(cur->name,"history")) + parse_history(doc,id,type,cur); + if (name) + { + xmlFree(name); + name=NULL; + } + } + if (id) + xmlFree(id); + if (type) + xmlFree(type); +} + +int main(int argc,char **argv) +{ + xmlDocPtr doc; + xmlNodePtr cur; + doc=xmlParseFile(argv[1]); + if (!doc) + { + fprintf(stderr,"Document not parsed successfully.\n"); + exit(1); + } + cur=xmlDocGetRootElement(doc); + if (!cur) + { + fprintf(stderr,"Empty document.\n"); + xmlFreeDoc(doc); + exit(1); + } + if (xmlStrcmp(cur->name,(const xmlChar *)"project_export")) + { + fprintf(stderr,"%s does not appear to be a project export document.\n", + argv[1]); + xmlFreeDoc(doc); + exit(1); + } + for(cur=cur->xmlChildrenNode;cur;cur=cur->next) + if (!xmlStrcmp(cur->name,(const xmlChar *)"artifacts")) + break; + if (!cur) + { + fprintf(stderr,"%s does not appear to contain an artifacts node.\n", + argv[1]); + xmlFreeDoc(doc); + exit(1); + } + for(cur=cur->xmlChildrenNode;cur;cur=cur->next) + if (!xmlStrcmp(cur->name,(const xmlChar *)"artifact")) + parse_artifact(doc,cur); + xmlFreeDoc(doc); + exit(0); +}