#include #include #include #include #include #include #include "tango_cache_xml.h" bool parse_uploadID_xml(const char *content, int len, char **uploadID) { xmlDoc *pdoc; xmlNode *pcur; if((pdoc = xmlParseMemory(content, len)) == NULL) { return false; } if((pcur = xmlDocGetRootElement(pdoc)) == NULL) { xmlFreeDoc(pdoc); return false; } while(pcur->type != XML_ELEMENT_NODE) pcur = pcur->next; if(xmlStrcmp(pcur->name, (const xmlChar *)"InitiateMultipartUploadResult")) { xmlFreeDoc(pdoc); return false; } pcur = pcur->children; while(pcur != NULL) { if(pcur->type != XML_ELEMENT_NODE || xmlStrcmp(pcur->name, (const xmlChar *)"UploadId")) { pcur = pcur->next; continue; } *uploadID = (char *)xmlNodeGetContent(pcur); xmlFreeDoc(pdoc); return true; } xmlFreeDoc(pdoc); return false; } void construct_complete_xml(struct tango_cache_ctx *ctx, char **xml, int *len) { struct multipart_etag_list *etag; xmlDoc *pdoc; xmlNode *root, *child; char number[20]; pdoc = xmlNewDoc((const xmlChar *)"1.0"); root = xmlNewNode(NULL, (const xmlChar *)"CompleteMultipartUpload"); xmlNewProp(root, (const xmlChar *)"xmlns",(const xmlChar *)"http://s3.amazonaws.com/doc/2006-03-01/"); xmlDocSetRootElement(pdoc, root); TAILQ_FOREACH(etag, &ctx->put.etag_head, node) { sprintf(number, "%u", etag->part_number); child = xmlNewChild(root, NULL, (const xmlChar*)"Part", NULL); xmlNewChild(child, NULL, (const xmlChar*)"ETag", (const xmlChar*)etag->etag); xmlNewChild(child, NULL, (const xmlChar*)"PartNumber", (const xmlChar*)number); } xmlDocDumpFormatMemory(pdoc, (xmlChar **)xml, len, 1); xmlFreeDoc(pdoc); } static void fill_multidelete_xml_errcode(xmlNode *error, char *out, int size) { xmlChar *errcode; xmlNode *child = error->children; while(child != NULL) { if(child->type != XML_ELEMENT_NODE || xmlStrcmp(child->name, (const xmlChar *)"Message")) { child = child->next; continue; } errcode = xmlNodeGetContent(child); snprintf(out, size, "%s", (char *)errcode); xmlFree(errcode); break; } } bool parse_multidelete_xml(const char *xml, int len, u_int32_t *errnum, char *errstr, int size) { xmlDoc *pdoc; xmlNode *pcur; int errornum=0; if((pdoc = xmlParseMemory(xml, len)) == NULL) { return false; } if((pcur = xmlDocGetRootElement(pdoc)) == NULL) { xmlFreeDoc(pdoc); return false; } while(pcur->type != XML_ELEMENT_NODE) pcur = pcur->next; if(xmlStrcmp(pcur->name, (const xmlChar *)"DeleteResult")) { xmlFreeDoc(pdoc); return false; } pcur = pcur->children; while(pcur != NULL) { if(pcur->type != XML_ELEMENT_NODE || xmlStrcmp(pcur->name, (const xmlChar *)"Error")) { pcur = pcur->next; continue; } if(errornum == 0) { fill_multidelete_xml_errcode(pcur, errstr, size); } errornum++; pcur = pcur->next; } *errnum = errornum; xmlFreeDoc(pdoc); return true; } void construct_multiple_delete_xml(const char *bucket, char *key[], u_int32_t num, int is_hash, char **xml, size_t *len) { xmlDoc *pdoc; xmlNode *root, *child; int xmllen; pdoc = xmlNewDoc((const xmlChar *)"1.0"); root = xmlNewNode(NULL, (const xmlChar *)"Delete"); xmlDocSetRootElement(pdoc, root); xmlNewChild(root, NULL, (const xmlChar*)"Quiet", (const xmlChar*)"true"); if(is_hash) { char hashkey[72], sha256[72]; for(u_int32_t i=0; i