From daccad4f6a916f409d8ecdfc2a2ccb4036f9f5e9 Mon Sep 17 00:00:00 2001 From: Tomas Mlcoch Date: Mon, 12 Dec 2011 10:37:45 +0100 Subject: [PATCH 1/1] Initial commit --- .gitignore | 7 + Makefile | 40 ++++ main.c | 122 ++++++++++ package.c | 99 ++++++++ package.h | 73 ++++++ package.i | 8 + xml_dump.c | 143 +++++++++++ xml_dump.h | 25 ++ xml_dump.i | 11 + xml_dump_filelists.c | 196 +++++++++++++++ xml_dump_other.c | 258 ++++++++++++++++++++ xml_dump_primary.c | 660 +++++++++++++++++++++++++++++++++++++++++++++++++++ 12 files changed, 1642 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 main.c create mode 100644 package.c create mode 100644 package.h create mode 100644 package.i create mode 100644 xml_dump.c create mode 100644 xml_dump.h create mode 100644 xml_dump.i create mode 100644 xml_dump_filelists.c create mode 100644 xml_dump_other.c create mode 100644 xml_dump_primary.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..99145b6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +*.o +*.so +*.py +*.pyc +*_wrap.c +snippets/ +notes diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..283f2d2 --- /dev/null +++ b/Makefile @@ -0,0 +1,40 @@ +SWIG=/usr/bin/swig + +CFLAGS=-DDEBUG -I/usr/include/python2.7/ `pkg-config --cflags glib-2.0` `xml2-config --cflags` +LINKFLAGS=`pkg-config --libs glib-2.0` `xml2-config --libs` + +all: package.so xml_dump.so + +test: main + +package.o package_wrap.o: package.i package.c package.h + $(SWIG) -python -Wall package.i + gcc $(CFLAGS) -c package.c package_wrap.c + +xml_dump_wrap.o: xml_dump.i xml_dump.c xml_dump.h + $(SWIG) -python -Wall xml_dump.i + gcc $(CFLAGS) -c xml_dump_wrap.c xml_dump_wrap.c + +xml_dump.o: xml_dump.c xml_dump.h + gcc $(CFLAGS) -c xml_dump.c + +xml_dump_primary.o: xml_dump_primary.c xml_dump.h + gcc $(CFLAGS) -c xml_dump_primary.c + +xml_dump_filelists.o: xml_dump_filelists.c xml_dump.h + gcc $(CFLAGS) -c xml_dump_filelists.c + +xml_dump_other.o: xml_dump_other.c xml_dump.h + gcc $(CFLAGS) -c xml_dump_other.c + +package.so: package_wrap.o package.o + ld $(LINKFLAGS) -shared package.o package_wrap.o -o _package.so + +xml_dump.so: xml_dump_wrap.o xml_dump.o xml_dump_primary.o xml_dump_filelists.o xml_dump_other.o + ld $(LINKFLAGS) -shared xml_dump_wrap.o xml_dump.o xml_dump_primary.o xml_dump_filelists.o xml_dump_other.o -o _xml_dump.so + +main: package.o xml_dump.o xml_dump_primary.o xml_dump_filelists.o xml_dump_other.o + gcc $(LINKFLAGS) $(CFLAGS) package.o xml_dump.o xml_dump_primary.o xml_dump_filelists.o xml_dump_other.o main.c -o main + +clean: + rm -f *.o package_wrap.* _package.so main diff --git a/main.c b/main.c new file mode 100644 index 0000000..fa6b29f --- /dev/null +++ b/main.c @@ -0,0 +1,122 @@ +#include +#include "package.h" +#include "xml_dump.h" + +int main() { + Package *package = package_new(); + + package->name = "ŠŠŠJMÉNÓ"; + package->pkgKey = 111; + package->pkgId = "32543dsafchecksum"; + package->arch = "i386"; + package->version = "88"; + package->epoch = "11"; + package->release = "08"; + package->summary = "short summary"; + package->description = "long description"; + package->url = "http://foo.bar"; + package->time_file = 123456; + package->time_build = 234567; + package->rpm_license = "GPL"; + package->rpm_vendor = "we"; + package->rpm_group = "grupa"; + package->rpm_buildhost = "superman"; + package->rpm_sourcerpm = "neco.src.rpm"; + package->rpm_header_start = 1; + package->rpm_header_end = 100; + package->rpm_packager = "batman"; + package->size_package = 777; + package->size_installed = 888; + package->size_archive = 666; + package->location_href = "tady"; + package->location_base = ""; + package->checksum_type = "sha256"; + + + Dependency *file = dependency_new(); + file->name = "soubor"; + file->flags = "A"; + file->epoch = "1"; + file->version = "2"; + file->release = "3"; + file->pre = 1; + + package->requires = g_slist_append(package->requires, file); + package->requires = g_slist_append(package->requires, file); + package->requires = g_slist_append(package->requires, file); + package->requires = g_slist_append(package->requires, file); + + package->provides = g_slist_append(package->provides, file); + package->provides = g_slist_append(package->provides, file); + package->provides = g_slist_append(package->provides, file); + + package->conflicts = g_slist_append(package->conflicts, file); + package->conflicts = g_slist_append(package->conflicts, file); + + package->obsoletes = g_slist_append(package->obsoletes, file); + + + PackageFile *pkgfile = package_file_new(); + pkgfile->name = "/bin/neco"; + pkgfile->type = ""; + + PackageFile *pkgfile2 = package_file_new(); + pkgfile2->name = "/usr/addresar"; + pkgfile2->type = "dir"; + + PackageFile *pkgfile3 = package_file_new(); + pkgfile3->name = "/etc/neco.conf"; + pkgfile3->type = ""; + + PackageFile *pkgfile4 = package_file_new(); + pkgfile4->name = "/usr/lib/sendmail"; + pkgfile4->type = ""; + + PackageFile *pkgfile5 = package_file_new(); + pkgfile5->name = "/etc/neco.dir"; + pkgfile5->type = "dir"; + + PackageFile *pkgfile6 = package_file_new(); + pkgfile6->name = "/bin/neco.dir"; + pkgfile6->type = "dir"; + + PackageFile *pkgfile7 = package_file_new(); + pkgfile7->name = "/usr/lib/sendmail"; + pkgfile7->type = "dir"; + + package->files = g_slist_append(package->files, pkgfile); + package->files = g_slist_append(package->files, pkgfile2); + package->files = g_slist_append(package->files, pkgfile3); + package->files = g_slist_append(package->files, pkgfile4); + package->files = g_slist_append(package->files, pkgfile5); + package->files = g_slist_append(package->files, pkgfile6); + package->files = g_slist_append(package->files, pkgfile7); + + + ChangelogEntry *chlog = changelog_entry_new(); + chlog->author = "foobar"; + chlog->date = 1234567; + chlog->changelog = "very long changelog message"; + + ChangelogEntry *chlog2 = changelog_entry_new(); + chlog2->author = "foobar2"; + chlog2->date = 67890; + chlog2->changelog = "short changelog message"; + + package->changelogs = g_slist_append(package->changelogs, chlog); + package->changelogs = g_slist_append(package->changelogs, chlog2); + + + //printf("Jde se dumpovat\n"); + char *ret = xml_dump_primary(package, NULL); + printf("%s\n\n", ret); + + ret = xml_dump_filelists(package, NULL); + printf("%s\n\n", ret); + + ret = xml_dump_other(package, NULL); + printf("%s\n\n", ret); + + return 0; +} + diff --git a/package.c b/package.c new file mode 100644 index 0000000..dfd9ed9 --- /dev/null +++ b/package.c @@ -0,0 +1,99 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License, + * version 2, as published by the Free Software Foundation + * + * 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., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "package.h" + +#define PACKAGE_CHUNK_SIZE 2048 + +Dependency * +dependency_new (void) +{ + Dependency *dep; + + dep = g_new0 (Dependency, 1); + + return dep; +} + +PackageFile * +package_file_new (void) +{ + PackageFile *file; + + file = g_new0 (PackageFile, 1); + + return file; +} + +ChangelogEntry * +changelog_entry_new (void) +{ + ChangelogEntry *entry; + + entry = g_new0 (ChangelogEntry, 1); + + return entry; +} + +Package * +package_new (void) +{ + Package *package; + + package = g_new0 (Package, 1); + package->chunk = g_string_chunk_new (PACKAGE_CHUNK_SIZE); + + return package; +} + +void +package_free (Package *package) +{ + g_string_chunk_free (package->chunk); + + if (package->requires) { + g_slist_foreach (package->requires, (GFunc) g_free, NULL); + g_slist_free (package->requires); + } + + if (package->provides) { + g_slist_foreach (package->provides, (GFunc) g_free, NULL); + g_slist_free (package->provides); + } + + if (package->conflicts) { + g_slist_foreach (package->conflicts, (GFunc) g_free, NULL); + g_slist_free (package->conflicts); + } + + if (package->obsoletes) { + g_slist_foreach (package->obsoletes, (GFunc) g_free, NULL); + g_slist_free (package->obsoletes); + } + + if (package->files) { + g_slist_foreach (package->files, (GFunc) g_free, NULL); + g_slist_free (package->files); + } + + if (package->changelogs) { + g_slist_foreach (package->changelogs, (GFunc) g_free, NULL); + g_slist_free (package->changelogs); + } + + g_free (package); +} diff --git a/package.h b/package.h new file mode 100644 index 0000000..93b1b6c --- /dev/null +++ b/package.h @@ -0,0 +1,73 @@ +#ifndef __YUM_PACKAGE_H__ +#define __YUM_PACKAGE_H__ + +#include + +typedef struct { + char *name; + char *flags; + char *epoch; + char *version; + char *release; + gboolean pre; +} Dependency; + +typedef struct { + char *type; + char *name; +} PackageFile; + +typedef struct { + char *author; + gint64 date; + char *changelog; +} ChangelogEntry; + +typedef struct { + gint64 pkgKey; + char *pkgId; + char *name; + char *arch; + char *version; + char *epoch; + char *release; + char *summary; + char *description; + char *url; + gint64 time_file; + gint64 time_build; + char *rpm_license; + char *rpm_vendor; + char *rpm_group; + char *rpm_buildhost; + char *rpm_sourcerpm; + gint64 rpm_header_start; + gint64 rpm_header_end; + char *rpm_packager; + gint64 size_package; + gint64 size_installed; + gint64 size_archive; + char *location_href; + char *location_base; + char *checksum_type; + + GSList *requires; + GSList *provides; + GSList *conflicts; + GSList *obsoletes; + + GSList *files; + GSList *changelogs; + + GStringChunk *chunk; +} Package; + +typedef void (*PackageFn) (Package *pkg, gpointer data); + +Dependency *dependency_new (void); +PackageFile *package_file_new (void); +ChangelogEntry *changelog_entry_new (void); +Package *package_new (void); +void package_free (Package *package); + +#endif /* __YUM_PACKAGE_H__ */ diff --git a/package.i b/package.i new file mode 100644 index 0000000..ecce25b --- /dev/null +++ b/package.i @@ -0,0 +1,8 @@ +%module package + +%{ +#include "package.h" +%} + +%include "package.h" + diff --git a/xml_dump.c b/xml_dump.c new file mode 100644 index 0000000..b78662d --- /dev/null +++ b/xml_dump.c @@ -0,0 +1,143 @@ +#include +#include +#include +#include "xml_dump.h" + +//xmlCharEncodingHandlerPtr handler = NULL; + +xmlChar * +ConvertInput(const char *in, xmlCharEncodingHandlerPtr handler) +{ + xmlChar *out; + int ret; + int size; + int out_size; + int temp; + + if (in == 0) { + return NULL; + } + + if (!handler) { +// printf("Nic neprevadim\n"); + return (xmlChar*) in; + } + + + size = (int) strlen(in) + 1; + out_size = size * 2 - 1; + out = (unsigned char *) xmlMalloc((size_t) out_size); + printf("%s | size: %d, out_size: %d\n", in, size, out_size); + + + if (out != NULL) { + + temp = size - 1; +// printf("JDU PREVADET\n"); + ret = handler->input(out, &out_size, (const xmlChar *) in, &temp); +// printf("JDU PREVADET\n"); + if ((ret < 0) || (temp - size + 1)) { + if (ret < 0) { + printf("ConvertInput: conversion wasn't successful.\n"); + } else { + printf + ("ConvertInput: conversion wasn't successful. converted: %i octets.\n", + temp); + } + + xmlFree(out); + out = 0; + } else { + out = (unsigned char *) xmlRealloc(out, out_size + 1); + out[out_size] = 0; /*null terminating out */ + } + } else { + printf("ConvertInput: no mem\n"); + } + + return out; +} + + +GRegex *pri_re_1 = NULL; +GRegex *pri_re_2 = NULL; +GRegex *pri_re_3 = NULL; + +void +dump_files(xmlTextWriterPtr writer, Package *package, int primary, + xmlCharEncodingHandlerPtr handler) +{ +#ifdef DEBUG + printf("CALLED dump_files\n"); +#endif + + // Regex compilation + if (!pri_re_1) { + GRegexMatchFlags compile_flags = G_REGEX_OPTIMIZE|G_REGEX_MATCH_ANCHORED; + pri_re_1 = g_regex_new(".*bin/.*", compile_flags, 0, NULL); + pri_re_2 = g_regex_new("/etc/.*", compile_flags, 0, NULL); + pri_re_3 = g_regex_new("/usr/lib/sendmail$", compile_flags, 0, NULL); + } + + xmlChar *tmp = NULL; + + if (!package->files) { + return; + } + + GSList *element = NULL; + for(element = package->files; element; element=element->next) { + + PackageFile *entry = (PackageFile*) element->data; + + if (primary) { + // Only files or dirs could be primary - sorry ghost files :( + if (entry->type[0] != '\0' && strcmp(entry->type, "file") && strcmp(entry->type, "dir")) { + continue; + } + + // Check if file name match pattern for primary files + if (!g_regex_match(pri_re_1, entry->name, 0, NULL) + && !g_regex_match(pri_re_2, entry->name, 0, NULL) + && !g_regex_match(pri_re_3, entry->name, 0, NULL)) { + continue; + } + } + + + // *********************************** + // Element: file + // ************************************ + + int rc; + rc = xmlTextWriterStartElement(writer, BAD_CAST "file"); + if (rc < 0) { + printf("Error at xmlTextWriterWriteElement\n"); + return; + } + + // Write type + if (entry->type && strlen(entry->type)) { + tmp = ConvertInput(entry->type, handler); + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "type", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + } + + // Write text (file path) + tmp = ConvertInput(entry->name, handler); + xmlTextWriterWriteString(writer, BAD_CAST tmp); + if (handler && tmp != NULL) xmlFree(tmp); + + // Close file element + rc = xmlTextWriterEndElement(writer); + if (rc < 0) { + printf("Error at xmlTextWriterEndElement\n"); + return; + } + } +} + diff --git a/xml_dump.h b/xml_dump.h new file mode 100644 index 0000000..ceeab61 --- /dev/null +++ b/xml_dump.h @@ -0,0 +1,25 @@ +#ifndef __XML_DUMP__ +#define __XML_DUMP__ + +#include +#include +#include "package.h" + +/** + * ConvertInput: + * @in: string in a given encoding + * @encoding: the encoding used + * + * Converts @in into UTF-8 for processing with libxml2 APIs + * + * Returns the converted UTF-8 string, or NULL in case of error. + */ +xmlChar *ConvertInput(const char *, xmlCharEncodingHandlerPtr); + +void dump_files(xmlTextWriterPtr, Package *, int, xmlCharEncodingHandlerPtr); + +char *xml_dump_primary(Package *, const char *); +char *xml_dump_filelists(Package *, const char *); +char *xml_dump_other(Package *, const char *); + +#endif /* __XML_DUMP__ */ diff --git a/xml_dump.i b/xml_dump.i new file mode 100644 index 0000000..126f37b --- /dev/null +++ b/xml_dump.i @@ -0,0 +1,11 @@ +%module xml_dump + +%{ +#include "xml_dump.h" +%} + +//%include "xml_dump.h" + +char *xml_dump_primary(Package *, const char *); +char *xml_dump_filelists(Package *, const char *); +char *xml_dump_other(Package *, const char *); \ No newline at end of file diff --git a/xml_dump_filelists.c b/xml_dump_filelists.c new file mode 100644 index 0000000..bee7346 --- /dev/null +++ b/xml_dump_filelists.c @@ -0,0 +1,196 @@ +#include +#include +#include +#include +#include "package.h" +#include "xml_dump.h" + +#define MY_ENCODING "UTF-8" +//#define DEBUG +#undef DEBUG +//#define DEBUG_REQUIRES + +#define PROVIDES 0 +#define CONFLICTS 1 +#define OBSOLETES 2 +#define REQUIRES 3 + + +/** + * dump_base_items: + * @writer: + * @package: + * + * Converts @pkg_dict into xml string + * + * Returns the converted XML string, or NULL in case of error. + */ +void +dump_filelists_items(xmlTextWriterPtr writer, Package *package, xmlCharEncodingHandlerPtr handler) +{ + int rc; + xmlChar *tmp = NULL; + gchar *tmp2 = NULL; + +#ifdef DEBUG + printf("CALLED dump_filelists_items\n"); +#endif + + rc = xmlTextWriterStartDocument(writer, NULL, MY_ENCODING, NULL); + if (rc < 0) { + printf ("Error at xmlTextWriterStartDocument\n"); + return; + } + + + /*********************************** + Element: package + ************************************/ + rc = xmlTextWriterStartElement(writer, BAD_CAST "package"); + if (rc < 0) { + printf("Error at xmlTextWriterStartElement\n"); + return; + } + + /* Add an attribute to package */ + tmp = ConvertInput(package->pkgId, handler); + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "pkgid", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + tmp = ConvertInput(package->name, handler); + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "pkgid", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + tmp = ConvertInput(package->arch, handler); + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "pkgid", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + /*********************************** + Element: version + ************************************/ + rc = xmlTextWriterStartElement(writer, BAD_CAST "version"); + if (rc < 0) { + printf("Error at xmlTextWriterStartElement\n"); + return; + } + + /* Write version attribute epoch */ + tmp = ConvertInput(package->epoch, handler); + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "epoch", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + /* Write version attribute ver */ + tmp = ConvertInput(package->version, handler); + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "ver", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + /* Write version attribute rel */ + tmp = ConvertInput(package->release, handler); + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "rel", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + /* Close version element */ + rc = xmlTextWriterEndElement(writer); + if (rc < 0) { + printf("Error at xmlTextWriterEndElement\n"); + return; + } + + /* Files dump */ + dump_files(writer, package, 0, handler); + + /* Close package element */ + rc = xmlTextWriterEndElement(writer); + if (rc < 0) { + printf("Error at xmlTextWriterEndElement\n"); + return; + } + + /* Close document (and every still opened tags) */ + rc = xmlTextWriterEndDocument(writer); + if (rc < 0) { + printf("Error at xmlTextWriterEndDocument\n"); + return; + } +} + + +char * +xml_dump_filelists(Package *package, const char *encoding) +{ + + /* + * Global variable initialization + */ + + // Encoging handler for selected encoding + xmlCharEncodingHandlerPtr handler = NULL; + if (encoding) { + handler = xmlFindCharEncodingHandler(encoding); + if (!handler) { + printf("ConvertInput: no encoding handler found for 'utf-8'\n"); + return NULL; + } + } + + /* + * XML Gen + */ + + xmlBufferPtr buf = xmlBufferCreate(); + if (buf == NULL) { + printf("Error creating the xml buffer\n"); + return NULL; + } + + xmlTextWriterPtr writer = xmlNewTextWriterMemory(buf, 0); + if (writer == NULL) { + printf("Error creating the xml writer\n"); + return NULL; + } + +#ifdef DEBUG + printf("Xml buffer and writer created\n"); +#endif + + dump_filelists_items(writer, package, handler); + + xmlFreeTextWriter(writer); + + // Get rid off header + char *pkg_str = strstr((const char*) buf->content, "content; + } + + char *result = malloc(sizeof(char) * strlen(pkg_str) + 1); + strcpy(result, pkg_str); + + xmlBufferFree(buf); + return result; +} + diff --git a/xml_dump_other.c b/xml_dump_other.c new file mode 100644 index 0000000..2655a95 --- /dev/null +++ b/xml_dump_other.c @@ -0,0 +1,258 @@ +#include +#include +#include +#include +#include "package.h" +#include "xml_dump.h" + +#define MY_ENCODING "UTF-8" +//#define DEBUG +#undef DEBUG +//#define DEBUG_REQUIRES + +#define PROVIDES 0 +#define CONFLICTS 1 +#define OBSOLETES 2 +#define REQUIRES 3 + + +void +dump_changelog(xmlTextWriterPtr writer, Package *package, xmlCharEncodingHandlerPtr handler) +{ +#ifdef DEBUG + printf("CALLED dump_changelog\n"); +#endif + + xmlChar *tmp = NULL; + gchar *tmp2 = NULL; + + if (!package->changelogs) { + return; + } + + GSList *element = NULL; + for(element = package->changelogs; element; element=element->next) { + + ChangelogEntry *entry = (ChangelogEntry*) element->data; + // *********************************** + // Element: file + // ************************************ + + int rc; + rc = xmlTextWriterStartElement(writer, BAD_CAST "changelog"); + if (rc < 0) { + printf("Error at xmlTextWriterWriteElement\n"); + return; + } + + // Write param author + tmp = ConvertInput(entry->author, handler); + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "author", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + // Write param date + tmp2 = g_strdup_printf("%d", entry->date); + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "date", tmp2); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (tmp2 != NULL) g_free(tmp2); + + // Write text (file path) + tmp = ConvertInput(entry->changelog, handler); + xmlTextWriterWriteString(writer, BAD_CAST tmp); + if (handler && tmp != NULL) xmlFree(tmp); + + // Close file element + rc = xmlTextWriterEndElement(writer); + if (rc < 0) { + printf("Error at xmlTextWriterEndElement\n"); + return; + } + } +} + + +/** + * dump_base_items: + * @writer: + * @package: + * + * Converts @pkg_dict into xml string + * + * Returns the converted XML string, or NULL in case of error. + */ +void +dump_other_items(xmlTextWriterPtr writer, Package *package, xmlCharEncodingHandlerPtr handler) +{ + int rc; + xmlChar *tmp = NULL; + gchar *tmp2 = NULL; + +#ifdef DEBUG + printf("CALLED dump_other_items\n"); +#endif + + rc = xmlTextWriterStartDocument(writer, NULL, MY_ENCODING, NULL); + if (rc < 0) { + printf ("Error at xmlTextWriterStartDocument\n"); + return; + } + + + /*********************************** + Element: package + ************************************/ + rc = xmlTextWriterStartElement(writer, BAD_CAST "package"); + if (rc < 0) { + printf("Error at xmlTextWriterStartElement\n"); + return; + } + + /* Add an attribute to package */ + tmp = ConvertInput(package->pkgId, handler); + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "pkgid", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + tmp = ConvertInput(package->name, handler); + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "pkgid", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + tmp = ConvertInput(package->arch, handler); + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "pkgid", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + /*********************************** + Element: version + ************************************/ + rc = xmlTextWriterStartElement(writer, BAD_CAST "version"); + if (rc < 0) { + printf("Error at xmlTextWriterStartElement\n"); + return; + } + + /* Write version attribute epoch */ + tmp = ConvertInput(package->epoch, handler); + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "epoch", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + /* Write version attribute ver */ + tmp = ConvertInput(package->version, handler); + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "ver", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + /* Write version attribute rel */ + tmp = ConvertInput(package->release, handler); + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "rel", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + /* Close version element */ + rc = xmlTextWriterEndElement(writer); + if (rc < 0) { + printf("Error at xmlTextWriterEndElement\n"); + return; + } + + /* Files dump */ + dump_changelog(writer, package, handler); + + /* Close package element */ + rc = xmlTextWriterEndElement(writer); + if (rc < 0) { + printf("Error at xmlTextWriterEndElement\n"); + return; + } + + /* Close document (and every still opened tags) */ + rc = xmlTextWriterEndDocument(writer); + if (rc < 0) { + printf("Error at xmlTextWriterEndDocument\n"); + return; + } +} + + +char * +xml_dump_other(Package *package, const char *encoding) +{ + + /* + * Global variable initialization + */ + + // Encoging handler for selected encoding + xmlCharEncodingHandlerPtr handler = NULL; + if (encoding) { + handler = xmlFindCharEncodingHandler(encoding); + if (!handler) { + printf("ConvertInput: no encoding handler found for 'utf-8'\n"); + return NULL; + } + } + + /* + * XML Gen + */ + + xmlBufferPtr buf = xmlBufferCreate(); + if (buf == NULL) { + printf("Error creating the xml buffer\n"); + return NULL; + } + + xmlTextWriterPtr writer = xmlNewTextWriterMemory(buf, 0); + if (writer == NULL) { + printf("Error creating the xml writer\n"); + return NULL; + } + +#ifdef DEBUG + printf("Xml buffer and writer created\n"); +#endif + + dump_other_items(writer, package, handler); + + xmlFreeTextWriter(writer); + + // Get rid off header + char *pkg_str = strstr((const char*) buf->content, "content; + } + + char *result = malloc(sizeof(char) * strlen(pkg_str) + 1); + strcpy(result, pkg_str); + + xmlBufferFree(buf); + return result; +} + diff --git a/xml_dump_primary.c b/xml_dump_primary.c new file mode 100644 index 0000000..655cae9 --- /dev/null +++ b/xml_dump_primary.c @@ -0,0 +1,660 @@ +#include +#include +#include +#include +#include "package.h" +#include "xml_dump.h" + +#define MY_ENCODING "UTF-8" +//#define DEBUG +#undef DEBUG +//#define DEBUG_REQUIRES + +#define PROVIDES 0 +#define CONFLICTS 1 +#define OBSOLETES 2 +#define REQUIRES 3 + +void +dump_pco(xmlTextWriterPtr writer, Package *package, int pcotype, + xmlCharEncodingHandlerPtr handler) +{ +#ifdef DEBUG + printf("CALLED dump_pco\n"); +#endif + + xmlChar *tmp = NULL; + char provides[] = "rpm:provides"; + char conflicts[] = "rpm:conflicts"; + char obsoletes[] = "rpm:obsoletes"; + char requires[] = "rpm:requires"; + + char *elem_name = NULL; + GSList *files = NULL; + + if (pcotype == PROVIDES) { + elem_name = provides; + files = package->provides; + } else if (pcotype == CONFLICTS) { + elem_name = conflicts; + files = package->conflicts; + } else if (pcotype == OBSOLETES) { + elem_name = obsoletes; + files = package->obsoletes; + } else if (pcotype == REQUIRES) { + elem_name = requires; + files = package->requires; + } else { + return; + } + + if (!files) { + return; + } + + /*********************************** + PCP Element: provides, oboletes, conflicts, requires + ************************************/ + int rc; + tmp = ConvertInput(elem_name, handler); + rc = xmlTextWriterStartElement(writer, BAD_CAST elem_name); + if (rc < 0) { + printf("Error at xmlTextWriterWriteElement\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + GSList *element = NULL; + for(element = files; element; element=element->next) { + + Dependency *entry = (Dependency*) element->data; + + /*********************************** + Element: entry + ************************************/ + int rc; + rc = xmlTextWriterStartElement(writer, BAD_CAST "rpm:entry"); + if (rc < 0) { + printf("Error at xmlTextWriterWriteElement\n"); + return; + } + + tmp = ConvertInput(entry->name, handler); + if (!tmp || ! strlen(tmp)) { + if (handler && tmp != NULL) xmlFree(tmp); + goto close; + } + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "name", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + tmp = ConvertInput(entry->flags, handler); + if (!tmp || ! strlen(tmp)) { + if (handler && tmp != NULL) xmlFree(tmp); + goto close; + } + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "flags", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + tmp = ConvertInput(entry->epoch, handler); + if (tmp && strlen(tmp)) { + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "epoch", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + } + if (handler && tmp != NULL) xmlFree(tmp); + + tmp = ConvertInput(entry->version, handler); + if (tmp && strlen(tmp)) { + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "ver", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + } + if (handler && tmp != NULL) xmlFree(tmp); + + tmp = ConvertInput(entry->release, handler); + if (tmp && strlen(tmp)) { + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "rel", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + } + if (handler && tmp != NULL) xmlFree(tmp); + + close: + + if (pcotype == REQUIRES) { + /* Add pre attribute */ + if (entry->pre) { + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "pre", "1"); + } else { + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "pre", "0"); + } + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + } + + /* Close entry element */ + rc = xmlTextWriterEndElement(writer); + if (rc < 0) { + printf("Error at xmlTextWriterEndElement\n"); + return; + } + } + + rc = xmlTextWriterEndElement(writer); + if (rc < 0) { + printf("Error at xmlTextWriterEndElement\n"); + return; + } +} + + + +/** + * dump_base_items: + * @writer: + * @package: + * + * Converts @pkg_dict into xml string + * + * Returns the converted XML string, or NULL in case of error. + */ +void +dump_base_items(xmlTextWriterPtr writer, Package *package, xmlCharEncodingHandlerPtr handler) +{ + int rc; + xmlChar *tmp = NULL; + gchar *tmp2 = NULL; + +#ifdef DEBUG + printf("CALLED dump_base_items\n"); +#endif + + rc = xmlTextWriterStartDocument(writer, NULL, MY_ENCODING, NULL); + if (rc < 0) { + printf ("Error at xmlTextWriterStartDocument\n"); + return; + } + + + /*********************************** + Element: package + ************************************/ + rc = xmlTextWriterStartElement(writer, BAD_CAST "package"); + if (rc < 0) { + printf("Error at xmlTextWriterStartElement\n"); + return; + } + + /* Add an attribute with name type to package */ + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "type", BAD_CAST "rpm"); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + + /*********************************** + Element: name + ************************************/ + tmp = ConvertInput(package->name, handler); + rc = xmlTextWriterWriteElement(writer, BAD_CAST "name", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteElement\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + /*********************************** + Element: arch + ************************************/ + tmp = ConvertInput(package->arch, handler); + rc = xmlTextWriterWriteElement(writer, BAD_CAST "arch", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteElement\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + /*********************************** + Element: version + ************************************/ + rc = xmlTextWriterStartElement(writer, BAD_CAST "version"); + if (rc < 0) { + printf("Error at xmlTextWriterStartElement\n"); + return; + } + + /* Write version attribute epoch */ + tmp = ConvertInput(package->epoch, handler); + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "epoch", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + /* Write version attribute ver */ + tmp = ConvertInput(package->version, handler); + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "ver", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + /* Write version attribute rel */ + tmp = ConvertInput(package->release, handler); + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "rel", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + /* Close version element */ + rc = xmlTextWriterEndElement(writer); + if (rc < 0) { + printf("Error at xmlTextWriterEndElement\n"); + return; + } + + /*********************************** + Element: checksum + ************************************/ + rc = xmlTextWriterStartElement(writer, BAD_CAST "checksum"); + if (rc < 0) { + printf("Error at xmlTextWriterStartElement\n"); + return; + } + + /* Write checksum attribute pkgid */ + tmp = ConvertInput("YES", handler); + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "pkgid", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + /* Write checksum attribute checksum_type */ + tmp = ConvertInput(package->checksum_type, handler); + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "type", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + /* Write element string */ + tmp = ConvertInput(package->pkgId, handler); + rc = xmlTextWriterWriteString(writer, BAD_CAST tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteString\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + /* Close checksum element */ + rc = xmlTextWriterEndElement(writer); + if (rc < 0) { + printf("Error at xmlTextWriterEndElement\n"); + return; + } + + /*********************************** + Element: summary + ************************************/ + tmp = ConvertInput(package->summary, handler); + rc = xmlTextWriterWriteElement(writer, BAD_CAST "summary", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteElement\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + /*********************************** + Element: description + ************************************/ + tmp = ConvertInput(package->description, handler); + rc = xmlTextWriterWriteElement(writer, BAD_CAST "description", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteElement\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + /*********************************** + Element: packager + ************************************/ + tmp = ConvertInput(package->rpm_packager, handler); + rc = xmlTextWriterWriteElement(writer, BAD_CAST "packager", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteElement\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + /*********************************** + Element: url + ************************************/ + tmp = ConvertInput(package->url, handler); + rc = xmlTextWriterWriteElement(writer, BAD_CAST "url", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteElement\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + /*********************************** + Element: time + ************************************/ + rc = xmlTextWriterStartElement(writer, BAD_CAST "time"); + if (rc < 0) { + printf("Error at xmlTextWriterStartElement\n"); + return; + } + + /* Write time attribute file */ + tmp2 = g_strdup_printf("%d", package->time_file); + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "file", tmp2); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (tmp2 != NULL) g_free(tmp2); + + /* Write time attribute build */ + tmp2 = g_strdup_printf("%d", package->time_build); + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "build", tmp2); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (tmp2 != NULL) g_free(tmp2); + + /* Close time element */ + rc = xmlTextWriterEndElement(writer); + if (rc < 0) { + printf("Error at xmlTextWriterEndElement\n"); + return; + } + + /*********************************** + Element: size + ************************************/ + rc = xmlTextWriterStartElement(writer, BAD_CAST "size"); + if (rc < 0) { + printf("Error at xmlTextWriterStartElement\n"); + return; + } + + /* Write size attribute package */ + tmp2 = g_strdup_printf("%d", package->size_package); + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "package", tmp2); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (tmp2 != NULL) g_free(tmp2); + + /* Write size attribute installed */ + tmp2 = g_strdup_printf("%d", package->size_installed); + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "installed", tmp2); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (tmp2 != NULL) g_free(tmp2); + + /* Write size attribute archive */ + tmp2 = g_strdup_printf("%d", package->size_archive); + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "archive", tmp2); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (tmp2 != NULL) g_free(tmp2); + + /* Close size element */ + rc = xmlTextWriterEndElement(writer); + if (rc < 0) { + printf("Error at xmlTextWriterEndElement\n"); + return; + } + + /*********************************** + Element: location + ************************************/ + rc = xmlTextWriterStartElement(writer, BAD_CAST "location"); + if (rc < 0) { + printf("Error at xmlTextWriterStartElement\n"); + return; + } + + /* Write location attribute href */ + tmp = ConvertInput(package->location_href, handler); + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "href", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + /* Write location attribute base */ + tmp = ConvertInput(package->location_base, handler); + if (strlen(package->location_base)) { + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "base", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + } + if (handler && tmp != NULL) xmlFree(tmp); + + /* Close location element */ + rc = xmlTextWriterEndElement(writer); + if (rc < 0) { + printf("Error at xmlTextWriterEndElement\n"); + return; + } + + /*********************************** + Element: format + ************************************/ + rc = xmlTextWriterStartElement(writer, BAD_CAST "format"); + if (rc < 0) { + printf("Error at xmlTextWriterStartElement\n"); + return; + } + + /*********************************** + Element: license + ************************************/ + tmp = ConvertInput(package->rpm_license, handler); + rc = xmlTextWriterWriteElement(writer, BAD_CAST "rpm:license", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteElement\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + /*********************************** + Element: vendor + ************************************/ + tmp = ConvertInput(package->rpm_vendor, handler); + rc = xmlTextWriterWriteElement(writer, BAD_CAST "rpm:vendor", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteElement\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + /*********************************** + Element: group + ************************************/ + tmp = ConvertInput(package->rpm_group, handler); + rc = xmlTextWriterWriteElement(writer, BAD_CAST "rpm:group", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteElement\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + /*********************************** + Element: buildhost + ************************************/ + tmp = ConvertInput(package->rpm_buildhost, handler); + rc = xmlTextWriterWriteElement(writer, BAD_CAST "rpm:buildhost", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteElement\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + /*********************************** + Element: sourcerpm + ************************************/ + tmp = ConvertInput(package->rpm_sourcerpm, handler); + rc = xmlTextWriterWriteElement(writer, BAD_CAST "rpm:sourcerpm", tmp); + if (rc < 0) { + printf("Error at xmlTextWriterWriteElement\n"); + return; + } + if (handler && tmp != NULL) xmlFree(tmp); + + /*********************************** + Element: header-range + ************************************/ + rc = xmlTextWriterStartElement(writer, BAD_CAST "rpm:header-range"); + if (rc < 0) { + printf("Error at xmlTextWriterWriteElement\n"); + return; + } + + /* Write header-range attribute hdrstart */ + tmp2 = g_strdup_printf("%d", package->rpm_header_start); + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "start", tmp2); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (tmp2 != NULL) g_free(tmp2); + + /* Write header-range attribute hdrend */ + tmp2 = g_strdup_printf("%d", package->rpm_header_end); + rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "end", tmp2); + if (rc < 0) { + printf("Error at xmlTextWriterWriteAttribute\n"); + return; + } + if (tmp2 != NULL) g_free(tmp2); + + /* Close header-range element */ + rc = xmlTextWriterEndElement(writer); + if (rc < 0) { + printf("Error at xmlTextWriterEndElement\n"); + return; + } + + + /* Files dump */ + dump_pco(writer, package, PROVIDES, handler); + dump_pco(writer, package, REQUIRES, handler); + dump_pco(writer, package, CONFLICTS, handler); + dump_pco(writer, package, OBSOLETES, handler); + dump_files(writer, package, 1, handler); + + + /* Close format element */ + rc = xmlTextWriterEndElement(writer); + if (rc < 0) { + printf("Error at xmlTextWriterEndElement\n"); + return; + } + + /* Close package element */ + rc = xmlTextWriterEndElement(writer); + if (rc < 0) { + printf("Error at xmlTextWriterEndElement\n"); + return; + } + + /* Close document (and every still opened tags) */ + rc = xmlTextWriterEndDocument(writer); + if (rc < 0) { + printf("Error at xmlTextWriterEndDocument\n"); + return; + } +} + + +char * +xml_dump_primary(Package *package, const char *encoding) +{ + + /* + * Global variable initialization + */ + + // Encoging handler for selected encoding + xmlCharEncodingHandlerPtr handler = NULL; + if (encoding) { + handler = xmlFindCharEncodingHandler(encoding); + if (!handler) { + printf("ConvertInput: no encoding handler found for 'utf-8'\n"); + return NULL; + } + } + + /* + * XML Gen + */ + + xmlBufferPtr buf = xmlBufferCreate(); + if (buf == NULL) { + printf("Error creating the xml buffer\n"); + return NULL; + } + + xmlTextWriterPtr writer = xmlNewTextWriterMemory(buf, 0); + if (writer == NULL) { + printf("Error creating the xml writer\n"); + return NULL; + } + +#ifdef DEBUG + printf("Xml buffer and writer created\n"); +#endif + + dump_base_items(writer, package, handler); + + xmlFreeTextWriter(writer); + + // Get rid off header + char *pkg_str = strstr((const char*) buf->content, "content; + } + + char *result = malloc(sizeof(char) * strlen(pkg_str) + 1); + strcpy(result, pkg_str); + + xmlBufferFree(buf); + return result; +} + -- 2.7.4