static rc_t CC NodeDataReadAttribs(NodeData* data, const KXMLNode* node, const char* parentName, uint32_t idx) { rc_t rc = 0; assert(node && parentName && data); if (DEBUG_PRINT) OUTMSG(("<%s ", data->nodeName)); GET_ATTR(node, id); GET_ATTR(node, path); GET_ATTR(node, name); GET_ATTR(node, mtime); GET_ATTR(node, filetype); GET_ATTR(node, md5); GET_ATTR(node, crc32); READ_ATTR(node, size); READ_ATTR(node, offset); if (rc == 0) { /* TODO: what size is negative no error is detected */ char * attr = "size"; rc = KXMLNodeReadAttrAsU64(node, attr, &data->iSize); if (rc != 0) { if (GetRCState(rc) == rcNotFound) { rc = 0; } } attr = "offset"; rc = KXMLNodeReadAttrAsU64(node, attr, &data->iOffset); if (rc != 0) { if (GetRCState(rc) == rcNotFound) { rc = 0; } } /* else if (data->nodeName) { PLOGERR(klogErr, (klogErr, rc, "while calling KXMLNodeReadAttrAsU64($(name)/@$(attr))", "name=%s,attr=%s", data->nodeName, attr)); }*/ if (DEBUG_PRINT) { OUTMSG(("%s=\"%lu\" ", attr, data->iSize)); OUTMSG(("%s=\"%lu\" ", attr, data->iOffset)); } } if (DEBUG_PRINT) OUTMSG((">")); if (DEBUG_PRINT && data->nodeValue) OUTMSG(("%s", data->nodeValue)); if (DEBUG_PRINT) OUTMSG(("</%s>\n", data->nodeName)); return rc; }
static rc_t TarNode_MakeFileList(const KXMLNode* xml_node, const TarFileList** files, char* errmsg, const char* rel_path, const char* name) { rc_t rc = 0; time_t now = time(NULL); uint32_t count = 0; *files = NULL; if( (rc = KXMLNodeCountChildNodes(xml_node, &count)) == 0 ) { if( count == 0 ) { rc = RC(rcExe, rcDoc, rcValidating, rcData, rcEmpty); } else if( (rc = TarFileList_Make(files, count, name)) == 0 ) { uint32_t i = 0; while(rc == 0 && i < count) { const KXMLNode* n = NULL; const char* n_name; if( (rc = KXMLNodeGetNodeRead(xml_node, &n, i++)) == 0 && (rc = KXMLNodeElementName(n, &n_name)) == 0 ) { if( strcmp(n_name, "Item") != 0 ) { rc = RC(rcExe, rcDoc, rcValidating, rcNode, rcUnexpected); strcpy(errmsg, n_name); } else { size_t sz_read; char path[4096], name[4096]; KTime_t ts = now; uint64_t fsz = 0; bool exec = false; if( (rc = KXMLNodeReadAttrCString(n, "path", name, sizeof(name), &sz_read)) == 0 ) { if( name[0] == '\0' ) { rc = RC(rcExe, rcDoc, rcValidating, rcAttr, rcEmpty); } else if( name[0] == '/' ) { memmove(path, name, sz_read + 1); } else { KDirectory* dir = NULL; if( (rc = KDirectoryNativeDir(&dir)) == 0 && (rc = KDirectoryResolvePath(dir, true, path, sizeof(path), "%s/%s", rel_path, name)) == 0 ) { DEBUG_LINE(8, "%s/%s resolved to %s", rel_path, name, path); } KDirectoryRelease(dir); } if( rc != 0 ) { strcpy(errmsg, "TAR/Item/@path"); } } if( rc == 0 && (rc = XML_ParseTimestamp(n, "timestamp", &ts, true)) != 0 ) { strcpy(errmsg, "TAR/Item/@timestamp"); } if( rc == 0 && (rc = XML_ParseBool(n, "executable", &exec, true)) != 0 ) { strcpy(errmsg, "TAR/Item/@executable"); } if( rc == 0 && (rc = KXMLNodeReadAttrAsU64(n, "size", &fsz)) != 0 ) { strcpy(errmsg, "TAR/Item/@size"); } if( rc == 0 ) { name[0] = '\0'; rc = KXMLNodeReadAttrCString(n, "name", name, sizeof(name), &sz_read); if( (GetRCObject(rc) == (enum RCObject)rcAttr && GetRCState(rc) == rcNotFound) || name[0] == '\0' ) { char* x = strrchr(path, '/'); strcpy(name, x ? x + 1 : path); rc = 0; } else if( rc == 0 && name[0] == '/' ) { strcat(errmsg, "Item/@name cannot be absolute"); rc = RC(rcExe, rcDoc, rcValidating, rcName, rcInvalid); } else if( rc != 0 ) { strcpy(errmsg, "Item/@name"); } } if( rc == 0 ) { const KNamelist* attr = NULL; if( (rc = KXMLNodeListAttr(n, &attr)) == 0 ) { uint32_t j = 0, count = 0; if( (rc = KNamelistCount(attr, &count)) == 0 && count > 0 ) { while( rc == 0 && j < count ) { const char *attr_nm = NULL; if( (rc = KNamelistGet(attr, j++, &attr_nm)) != 0 ) { break; } if( strcmp("path", attr_nm) == 0 || strcmp("name", attr_nm) == 0 || strcmp("timestamp", attr_nm) == 0 || strcmp("size", attr_nm) == 0 || strcmp("executable", attr_nm) == 0 ) { continue; } rc = RC(rcExe, rcDoc, rcValidating, rcDirEntry, rcInvalid); strcpy(errmsg, "unknown attribute TAR/Item/@"); strcat(errmsg, attr_nm); } } ReleaseComplain(KNamelistRelease, attr); } } if( rc == 0 && (rc = TarFileList_Add(*files, path, name, fsz, ts, exec)) != 0 ) { strcpy(errmsg, "adding to TAR"); } } ReleaseComplain(KXMLNodeRelease, n); } } if( rc != 0 ) { TarFileList_Release(*files); *files = NULL; } } } return rc; }