1/* 2 * Copyright (c) 2005-2007 Rob Braun 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of Rob Braun nor the names of his contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 */ 29/* 30 * 04-Apr-2005 31 * DRI: Rob Braun <bbraun@synack.net> 32 */ 33 34#define _FILE_OFFSET_BITS 64 35 36#include <stdlib.h> 37#include <string.h> 38#include <assert.h> 39#include <libxml/xmlwriter.h> 40#include <libxml/xmlreader.h> 41#include "xar.h" 42#include "subdoc.h" 43#include "archive.h" 44#include "filetree.h" 45 46xar_subdoc_t xar_subdoc_new(xar_t x, const char *name) { 47 xar_subdoc_t ret; 48 49 if( xar_subdoc_find(x, name) ) 50 return NULL; 51 52 ret = malloc(sizeof(struct __xar_subdoc_t)); 53 if( ! ret ) 54 return NULL; 55 56 memset(XAR_SUBDOC(ret), 0, sizeof(struct __xar_subdoc_t)); 57 XAR_SUBDOC(ret)->name = strdup(name); 58 XAR_SUBDOC(ret)->next = XAR_SUBDOC(XAR(x)->subdocs); 59 XAR(x)->subdocs = ret; 60 XAR_SUBDOC(ret)->x = x; 61 62 return ret; 63} 64 65int32_t xar_subdoc_prop_set(xar_subdoc_t s, const char *key, const char *value){ 66 return xar_prop_set((xar_file_t)s, key, value); 67} 68 69int32_t xar_subdoc_prop_get(xar_subdoc_t s, const char *key, const char **value) { 70 return xar_prop_get((xar_file_t)s, key, value); 71} 72 73int32_t xar_subdoc_attr_set(xar_subdoc_t s, const char *prop, const char *key, const char *value){ 74 return xar_attr_set((xar_file_t)s, prop, key, value); 75} 76 77const char *xar_subdoc_attr_get(xar_subdoc_t s, const char *prop, const char *key) { 78 return xar_attr_get((xar_file_t)s, prop, key); 79} 80 81xar_subdoc_t xar_subdoc_first(xar_t x) { 82 return XAR(x)->subdocs; 83} 84 85xar_subdoc_t xar_subdoc_next(xar_subdoc_t s) { 86 return XAR_SUBDOC(s)->next; 87} 88 89const char *xar_subdoc_name(xar_subdoc_t s) { 90 return XAR_SUBDOC(s)->name; 91} 92 93xar_subdoc_t xar_subdoc_find(xar_t x, const char *name) 94{ 95 xar_subdoc_t i; 96 97 for(i = XAR(x)->subdocs; i; i = XAR_SUBDOC(i)->next) { 98 if( strcmp(name, XAR_SUBDOC(i)->name) == 0 ) 99 return i; 100 } 101 102 return NULL; 103} 104 105int32_t xar_subdoc_copyout(xar_subdoc_t s, unsigned char **ret, unsigned int *size) { 106 xmlBufferPtr buf; 107 xmlTextWriterPtr writer; 108 109 buf = xmlBufferCreate(); 110 if( !buf ) 111 return -1; 112 113 writer = xmlNewTextWriterMemory(buf, 0); 114 if( !writer ) { 115 xmlBufferFree(buf); 116 return -1; 117 } 118 119 xmlTextWriterSetIndent(writer, 4); 120 xar_subdoc_serialize(s, writer, 0); 121 122 xmlTextWriterEndDocument(writer); 123 xmlFreeTextWriter(writer); 124 125 if( size != NULL ) 126 *size = buf->use; 127 *ret = malloc(buf->size); 128 if( *ret == NULL ) { 129 xmlBufferFree(buf); 130 return -1; 131 } 132 133 assert(size != NULL); 134 memcpy(*ret, buf->content, *size); 135 xmlBufferFree(buf); 136 return 0; 137} 138 139int32_t xar_subdoc_copyin(xar_subdoc_t s, const unsigned char *buf, unsigned int len) { 140 xmlTextReaderPtr reader; 141 142 reader = xmlReaderForMemory((const char *)buf, len, NULL, NULL, 0); 143 if( !reader ) 144 return -1; 145 146 xar_subdoc_unserialize(s, reader); 147 xmlFreeTextReader(reader); 148 return 0; 149} 150 151/* xar_subdoc_serialize 152 * s: a subdoc structure allocated and initialized by xar_subdoc_new() 153 * writer: and xmlTextWriterPtr that has already been opend and initialized 154 * and is pointing to the place where the subdocument will be serialized. 155 * wrap: an integer describing whether the subdocument is to be wrapped 156 * for placement in the xml header of an archive, or if we are trying to 157 * reconstruct the original document. 1 for wrapping, 0 for original. 158 */ 159void xar_subdoc_serialize(xar_subdoc_t s, xmlTextWriterPtr writer, int wrap) { 160 if( !s ) return; 161 if( wrap ) { 162 xmlTextWriterStartElementNS(writer, BAD_CAST(XAR_SUBDOC(s)->prefix), BAD_CAST("subdoc"), BAD_CAST(XAR_SUBDOC(s)->ns)); 163 xmlTextWriterWriteAttribute(writer, BAD_CAST("subdoc_name"), BAD_CAST(XAR_SUBDOC(s)->name)); 164 if( XAR_SUBDOC(s)->value ) 165 xmlTextWriterWriteString(writer, BAD_CAST(XAR_SUBDOC(s)->value)); 166 } 167 xar_prop_serialize(XAR_SUBDOC(s)->props, writer); 168 xmlTextWriterEndElement(writer); 169} 170 171void xar_subdoc_remove(xar_subdoc_t s) { 172 xar_prop_t p; 173 xar_subdoc_t tmp = xar_subdoc_first(XAR_SUBDOC(s)->x); 174 175 if( tmp == s ) { 176 XAR(XAR_SUBDOC(s)->x)->subdocs = XAR_SUBDOC(s)->next; 177 } else { 178 while(XAR_SUBDOC(tmp)->next) { 179 if( XAR_SUBDOC(tmp)->next == s ) { 180 XAR_SUBDOC(tmp)->next = XAR_SUBDOC(s)->next; 181 break; 182 } 183 tmp = xar_subdoc_next(tmp); 184 } 185 } 186 187 while(XAR_SUBDOC(s)->props) { 188 p = XAR_SUBDOC(s)->props; 189 XAR_SUBDOC(s)->props = XAR_PROP(XAR_PROP(p)->next); 190 xar_prop_free(p); 191 } 192 free((char *)XAR_SUBDOC(s)->blank1); 193 free((char *)XAR_SUBDOC(s)->name); 194 free((void *)s); 195 return; 196} 197 198void xar_subdoc_unserialize(xar_subdoc_t s, xmlTextReaderPtr reader) { 199 int type; 200 201 while( xmlTextReaderRead(reader) == 1 ) { 202 type = xmlTextReaderNodeType(reader); 203 if( type == XML_READER_TYPE_ELEMENT ) { 204 xar_prop_unserialize((xar_file_t)s, NULL, reader); 205 } 206 if( type == XML_READER_TYPE_TEXT ) { 207 const char *value; 208 value = (const char *)xmlTextReaderConstValue(reader); 209 free((char*)XAR_SUBDOC(s)->value); 210 XAR_SUBDOC(s)->value = strdup(value); 211 } 212 if( type == XML_READER_TYPE_END_ELEMENT ) { 213 break; 214 } 215 } 216 217 return; 218} 219