/
niceSOFT
/
createrepo_c
Обзор
Документация
Войти
/
niceSOFT
/
createrepo_c
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/xml_dump_primary.c
422 строки
12 KB
Aleš Matěj
Internally use package_internal.h to access cr_package fields
26 июн 2026, 17:40
26 июн 2026, 17:40
3a39893
Код
Авторство
О чём код?
/* createrepo_c - Library of routines for manipulation with repodata * Copyright (C) 2012 Tomas Mlcoch * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. */ #include <glib.h> #include <assert.h> #include <stdio.h> #include <string.h> #include <libxml/encoding.h> #include <libxml/xmlwriter.h> #include "error.h" #include "package_internal.h" #include "xml_dump.h" #include "xml_dump_internal.h" #define ERR_DOMAIN CREATEREPO_C_ERROR typedef enum { PCO_TYPE_PROVIDES, PCO_TYPE_CONFLICTS, PCO_TYPE_OBSOLETES, PCO_TYPE_REQUIRES, PCO_TYPE_SUGGESTS, PCO_TYPE_ENHANCES, PCO_TYPE_RECOMMENDS, PCO_TYPE_SUPPLEMENTS, PCO_TYPE_SENTINEL, } PcoType; typedef struct { const char *elemname; size_t listoffset; } PcoInfo; // Order of this list MUST be the same as the order of the related constants above! static PcoInfo pco_info[] = { { "rpm:provides", offsetof(cr_Package, provides) }, { "rpm:conflicts", offsetof(cr_Package, conflicts) }, { "rpm:obsoletes", offsetof(cr_Package, obsoletes) }, { "rpm:requires", offsetof(cr_Package, requires) }, { "rpm:suggests", offsetof(cr_Package, suggests) }, { "rpm:enhances", offsetof(cr_Package, enhances) }, { "rpm:recommends", offsetof(cr_Package, recommends) }, { "rpm:supplements", offsetof(cr_Package, supplements) }, { NULL, 0 }, }; void cr_xml_dump_primary_dump_pco(xmlNodePtr root, cr_Package *package, PcoType pcotype) { const char *elem_name; GSList *list = NULL; if (pcotype >= PCO_TYPE_SENTINEL) return; elem_name = pco_info[pcotype].elemname; list = *((GSList **) ((size_t) package + pco_info[pcotype].listoffset)); if (!list) return; /*********************************** PCOR Element: provides, oboletes, conflicts, requires ************************************/ xmlNodePtr pcor_node; pcor_node = xmlNewChild(root, NULL, BAD_CAST elem_name, NULL); GSList *element = NULL; for(element = list; element; element=element->next) { cr_Dependency *entry = (cr_Dependency*) element->data; assert(entry); if (!entry->name || entry->name[0] == '\0') { continue; } /*********************************** Element: entry ************************************/ xmlNodePtr entry_node; entry_node = xmlNewChild(pcor_node, NULL, BAD_CAST "rpm:entry", NULL); cr_xmlNewProp(entry_node, BAD_CAST "name", BAD_CAST entry->name); if (entry->flags && entry->flags[0] != '\0') { cr_xmlNewProp(entry_node, BAD_CAST "flags", BAD_CAST entry->flags); if (entry->epoch && entry->epoch[0] != '\0') { cr_xmlNewProp(entry_node, BAD_CAST "epoch", BAD_CAST entry->epoch); } if (entry->version && entry->version[0] != '\0') { cr_xmlNewProp(entry_node, BAD_CAST "ver", BAD_CAST entry->version); } if (entry->release && entry->release[0] != '\0') { cr_xmlNewProp(entry_node, BAD_CAST "rel", BAD_CAST entry->release); } } if (pcotype == PCO_TYPE_REQUIRES && entry->pre) { // Add pre attribute xmlNewProp(entry_node, BAD_CAST "pre", BAD_CAST "1"); } } } void cr_xml_dump_primary_base_items(xmlNodePtr root, cr_Package *package) { /*********************************** Element: package ************************************/ // Add an attribute with type to package xmlNewProp(root, BAD_CAST "type", BAD_CAST "rpm"); /*********************************** Element: name ************************************/ cr_xmlNewTextChild(root, NULL, BAD_CAST "name", BAD_CAST package->name); /*********************************** Element: arch ************************************/ cr_xmlNewTextChild(root, NULL, BAD_CAST "arch", BAD_CAST package->arch); /*********************************** Element: version ************************************/ xmlNodePtr version; // Add version element version = xmlNewChild(root, NULL, BAD_CAST "version", NULL); // Write version attribute epoch cr_xmlNewProp(version, BAD_CAST "epoch", BAD_CAST package->epoch); // Write version attribute ver cr_xmlNewProp(version, BAD_CAST "ver", BAD_CAST package->version); // Write version attribute rel cr_xmlNewProp(version, BAD_CAST "rel", BAD_CAST package->release); /*********************************** Element: checksum ************************************/ xmlNodePtr checksum; checksum = cr_xmlNewTextChild(root, NULL, BAD_CAST "checksum", BAD_CAST package->pkgId); // Write checksum attribute checksum_type cr_xmlNewProp(checksum, BAD_CAST "type", BAD_CAST package->checksum_type); // Write checksum attribute pkgid xmlNewProp(checksum, BAD_CAST "pkgid", BAD_CAST "YES"); /*********************************** Element: summary ************************************/ cr_xmlNewTextChild(root, NULL, BAD_CAST "summary", BAD_CAST package->summary); /*********************************** Element: description ************************************/ cr_xmlNewTextChild(root, NULL, BAD_CAST "description", BAD_CAST package->description); /*********************************** Element: packager ************************************/ cr_xmlNewTextChild(root, NULL, BAD_CAST "packager", BAD_CAST package->rpm_packager); /*********************************** Element: url ************************************/ cr_xmlNewTextChild(root, NULL, BAD_CAST "url", BAD_CAST package->url); /*********************************** Element: time ************************************/ xmlNodePtr time; char date_str[DATE_STR_MAX_LEN]; time = xmlNewChild(root, NULL, BAD_CAST "time", NULL); // Write time attribute file g_snprintf(date_str, DATE_STR_MAX_LEN, "%"G_GINT64_FORMAT, package->time_file); xmlNewProp(time, BAD_CAST "file", BAD_CAST date_str); // Write time attribute build g_snprintf(date_str, DATE_STR_MAX_LEN, "%"G_GINT64_FORMAT, package->time_build); xmlNewProp(time, BAD_CAST "build", BAD_CAST date_str); /*********************************** Element: size ************************************/ xmlNodePtr size; char size_str[SIZE_STR_MAX_LEN]; size = xmlNewChild(root, NULL, BAD_CAST "size", NULL); // Write size attribute package g_snprintf(size_str, SIZE_STR_MAX_LEN, "%"G_GINT64_FORMAT, package->size_package); xmlNewProp(size, BAD_CAST "package", BAD_CAST size_str); // Write size attribute installed g_snprintf(size_str, SIZE_STR_MAX_LEN, "%"G_GINT64_FORMAT, package->size_installed); xmlNewProp(size, BAD_CAST "installed", BAD_CAST size_str); // Write size attribute archive g_snprintf(size_str, SIZE_STR_MAX_LEN, "%"G_GINT64_FORMAT, package->size_archive); xmlNewProp(size, BAD_CAST "archive", BAD_CAST size_str); /*********************************** Element: location ************************************/ xmlNodePtr location; location = xmlNewChild(root, NULL, BAD_CAST "location", NULL); // Write location attribute base if (package->location_base && package->location_base[0] != '\0') { gchar *location_base_with_protocol = NULL; location_base_with_protocol = cr_prepend_protocol(package->location_base); cr_xmlNewProp(location, BAD_CAST "xml:base", BAD_CAST location_base_with_protocol); g_free(location_base_with_protocol); } // Write location attribute href cr_xmlNewProp(location, BAD_CAST "href", BAD_CAST package->location_href); /*********************************** Element: format ************************************/ xmlNodePtr format; format = xmlNewChild(root, NULL, BAD_CAST "format", NULL); /*********************************** Element: license ************************************/ cr_xmlNewTextChild(format, NULL, BAD_CAST "rpm:license", BAD_CAST package->rpm_license); /*********************************** Element: vendor ************************************/ cr_xmlNewTextChild(format, NULL, BAD_CAST "rpm:vendor", BAD_CAST package->rpm_vendor); /*********************************** Element: group ************************************/ cr_xmlNewTextChild(format, NULL, BAD_CAST "rpm:group", BAD_CAST package->rpm_group); /*********************************** Element: buildhost ************************************/ cr_xmlNewTextChild(format, NULL, BAD_CAST "rpm:buildhost", BAD_CAST package->rpm_buildhost); /*********************************** Element: sourcerpm ************************************/ cr_xmlNewTextChild(format, NULL, BAD_CAST "rpm:sourcerpm", BAD_CAST package->rpm_sourcerpm); /*********************************** Element: header-range ************************************/ xmlNodePtr header_range; header_range = xmlNewChild(format, NULL, BAD_CAST "rpm:header-range", NULL); // Write header-range attribute hdrstart g_snprintf(size_str, SIZE_STR_MAX_LEN, "%"G_GINT64_FORMAT, package->rpm_header_start); xmlNewProp(header_range, BAD_CAST "start", BAD_CAST size_str); // Write header-range attribute hdrend g_snprintf(size_str, SIZE_STR_MAX_LEN, "%"G_GINT64_FORMAT, package->rpm_header_end); xmlNewProp(header_range, BAD_CAST "end", BAD_CAST size_str); // Files dump cr_xml_dump_primary_dump_pco(format, package, PCO_TYPE_PROVIDES); cr_xml_dump_primary_dump_pco(format, package, PCO_TYPE_REQUIRES); cr_xml_dump_primary_dump_pco(format, package, PCO_TYPE_CONFLICTS); cr_xml_dump_primary_dump_pco(format, package, PCO_TYPE_OBSOLETES); cr_xml_dump_primary_dump_pco(format, package, PCO_TYPE_SUGGESTS); cr_xml_dump_primary_dump_pco(format, package, PCO_TYPE_ENHANCES); cr_xml_dump_primary_dump_pco(format, package, PCO_TYPE_RECOMMENDS); cr_xml_dump_primary_dump_pco(format, package, PCO_TYPE_SUPPLEMENTS); cr_xml_dump_files(format, package, 1, FALSE); } char * cr_xml_dump_primary(cr_Package *package, GError **err) { xmlNodePtr root; char *result; gboolean xml_dump_pretty = cr_xml_dump_get_parameter(CR_XML_DUMP_DO_PRETTY_PRINT); assert(!err || *err == NULL); if (!package) { g_set_error(err, CREATEREPO_C_ERROR, CRE_BADARG, "No package object to dump specified"); return NULL; } // Dump IT! xmlBufferPtr buf = xmlBufferCreate(); if (buf == NULL) { g_critical("%s: Error creating the xml buffer", __func__); g_set_error(err, ERR_DOMAIN, CRE_MEMORY, "Cannot create an xml buffer"); return NULL; } root = xmlNewNode(NULL, BAD_CAST "package"); cr_xml_dump_primary_base_items(root, package); // xmlNodeDump seems to be a little bit faster than xmlDocDumpFormatMemory xmlNodeDump(buf, NULL, root, 0, xml_dump_pretty); assert(buf->content); result = g_strndup((char *) buf->content, (buf->use+1)); result[buf->use] = '\n'; result[buf->use+1] = '\0'; // Cleanup xmlBufferFree(buf); xmlFreeNode(root); return result; }