From 72a9788cdba68cd68398f1a2b986b705aa0b2a66 Mon Sep 17 00:00:00 2001 From: Tomas Mlcoch Date: Thu, 9 May 2013 11:21:07 +0200 Subject: [PATCH] parsepkg: Add GError support. --- src/createrepo_c.c | 2 +- src/error.c | 6 ++ src/error.h | 2 + src/parsepkg.c | 201 +++++++++++++++++++++++++---------------------- src/parsepkg.h | 11 ++- src/python/parsepkg-py.c | 19 +++-- 6 files changed, 138 insertions(+), 103 deletions(-) diff --git a/src/createrepo_c.c b/src/createrepo_c.c index 5116b97..1604420 100644 --- a/src/createrepo_c.c +++ b/src/createrepo_c.c @@ -257,7 +257,7 @@ dumper_thread(gpointer data, gpointer user_data) // Load package from file pkg = cr_package_from_rpm(task->full_path, udata->checksum_type, location_href, udata->location_base, - udata->changelog_limit, NULL); + udata->changelog_limit, NULL, NULL); if (!pkg) { g_warning("Cannot read package: %s", task->full_path); goto task_cleanup; diff --git a/src/error.c b/src/error.c index 4df40d1..078d193 100644 --- a/src/error.c +++ b/src/error.c @@ -61,3 +61,9 @@ cr_checksum_error_quark(void) return g_quark_from_static_string("cr_checksum_error"); } +GQuark +cr_parsepkg_error_quark(void) +{ + return g_quark_from_static_string("cr_parsepkg_error"); +} + diff --git a/src/error.h b/src/error.h index 0371781..752a287 100644 --- a/src/error.h +++ b/src/error.h @@ -48,6 +48,7 @@ typedef enum { #define CR_REPOMD_ERROR cr_repomd_error_quark() #define CR_REPOMD_RECORD_ERROR cr_repomd_record_error_quark() #define CR_CHECKSUM_ERROR cr_checksum_error_quark() +#define CR_PARSEPKG_ERROR cr_parsepkg_error_quark() GQuark cr_db_error_quark(void); GQuark cr_xml_dump_primary_error_quark(void); @@ -56,5 +57,6 @@ GQuark cr_xml_dump_other_error_quark(void); GQuark cr_repomd_error_quark(void); GQuark cr_repomd_record_error_quark(void); GQuark cr_checksum_error_quark(void); +GQuark cr_parsepkg_error_quark(void); #endif diff --git a/src/parsepkg.c b/src/parsepkg.c index cf2a601..52ab854 100644 --- a/src/parsepkg.c +++ b/src/parsepkg.c @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -29,6 +30,7 @@ #include #include #include "logging.h" +#include "error.h" #include "constants.h" #include "parsehdr.h" #include "misc.h" @@ -68,51 +70,22 @@ cr_package_parser_cleanup() } -cr_Package * -cr_package_from_rpm(const char *filename, - cr_ChecksumType checksum_type, - const char *location_href, - const char *location_base, - int changelog_limit, - struct stat *stat_buf) +static int +read_header(const char *filename, Header *hdr, GError **err) { - cr_Package *result = NULL; - const char *checksum_type_str; + assert(filename); + assert(!err || *err == NULL); - // Set checksum type - - switch (checksum_type) { - case CR_CHECKSUM_MD5: - checksum_type_str = "md5"; - break; - case CR_CHECKSUM_SHA1: - checksum_type_str = "sha1"; - break; - case CR_CHECKSUM_SHA256: - checksum_type_str = "sha256"; - break; - default: - g_warning("%s: Unknown checksum type", __func__); - return result; - break; - }; - - - // Open rpm file - - FD_t fd = NULL; - fd = Fopen(filename, "r.ufdio"); + FD_t fd = Fopen(filename, "r.ufdio"); if (!fd) { g_warning("%s: Fopen of %s failed %s", __func__, filename, strerror(errno)); - return result; + g_set_error(err, CR_PARSEPKG_ERROR, CRE_IO, + "Fopen failed: %s", strerror(errno)); + return CRE_IO; } - - // Read package - - Header hdr; - int rc = rpmReadPackageFile(cr_ts, fd, NULL, &hdr); + int rc = rpmReadPackageFile(cr_ts, fd, NULL, hdr); if (rc != RPMRC_OK) { switch (rc) { case RPMRC_NOKEY: @@ -126,14 +99,60 @@ cr_package_from_rpm(const char *filename, default: g_warning("%s: rpmReadPackageFile() error (%s)", __func__, strerror(errno)); - return result; + g_set_error(err, CR_PARSEPKG_ERROR, CRE_IO, + "rpmReadPackageFile() error: %s", strerror(errno)); + Fclose(fd); + return CRE_IO; } } + Fclose(fd); + return CRE_OK; +} + +cr_Package * +cr_package_from_rpm(const char *filename, + cr_ChecksumType checksum_type, + const char *location_href, + const char *location_base, + int changelog_limit, + struct stat *stat_buf, + GError **err) +{ + cr_Package *pkg = NULL; + const char *checksum_type_str; + GError *tmp_err = NULL; + + assert(filename); - // Cleanup + // Set checksum type + + switch (checksum_type) { + case CR_CHECKSUM_MD5: + checksum_type_str = "md5"; + break; + case CR_CHECKSUM_SHA1: + checksum_type_str = "sha1"; + break; + case CR_CHECKSUM_SHA256: + checksum_type_str = "sha256"; + break; + default: + g_warning("%s: Unknown checksum type", __func__); + g_set_error(err, CR_PARSEPKG_ERROR, CRE_UNKNOWNCHECKSUMTYPE, + "Unknown/Unsupported checksum type: %d", checksum_type); + return NULL; + }; - Fclose(fd); + + // Read header + + Header hdr; + read_header(filename, &hdr, &tmp_err); + if (tmp_err) { + g_propagate_error(err, tmp_err); + return NULL; + } // Get file stat @@ -145,7 +164,9 @@ cr_package_from_rpm(const char *filename, struct stat stat_buf_own; if (stat(filename, &stat_buf_own) == -1) { g_warning("%s: stat() error (%s)", __func__, strerror(errno)); - return result; + g_set_error(err, CR_PARSEPKG_ERROR, CRE_IO, "stat() failed"); + headerFree(hdr); + return NULL; } mtime = stat_buf_own.st_mtime; size = stat_buf_own.st_size; @@ -157,7 +178,13 @@ cr_package_from_rpm(const char *filename, // Compute checksum - char *checksum = cr_compute_file_checksum(filename, checksum_type, NULL); + char *checksum = cr_compute_file_checksum(filename, checksum_type, &tmp_err); + if (tmp_err) { + g_propagate_prefixed_error(err, tmp_err, + "Error while checksum calculation:"); + headerFree(hdr); + return NULL; + } // Get header range @@ -167,30 +194,34 @@ cr_package_from_rpm(const char *filename, // Get package object - result = cr_package_from_header(hdr, mtime, size, checksum, checksum_type_str, + pkg = cr_package_from_header(hdr, mtime, size, checksum, checksum_type_str, location_href, location_base, changelog_limit, - hdr_r.start, hdr_r.end, NULL); - - - // Cleanup - + hdr_r.start, hdr_r.end, &tmp_err); free(checksum); headerFree(hdr); - return result; + if (tmp_err) { + g_propagate_prefixed_error(err, tmp_err, + "Error while checksum calculation:"); + return NULL; + } + + return pkg; } struct cr_XmlStruct cr_xml_from_rpm(const char *filename, - cr_ChecksumType checksum_type, - const char *location_href, - const char *location_base, - int changelog_limit, - struct stat *stat_buf) + cr_ChecksumType checksum_type, + const char *location_href, + const char *location_base, + int changelog_limit, + struct stat *stat_buf, + GError **err) { const char *checksum_type_str; + GError *tmp_err = NULL; struct cr_XmlStruct result; result.primary = NULL; @@ -212,48 +243,22 @@ cr_xml_from_rpm(const char *filename, break; default: g_warning("%s: Unknown checksum type", __func__); + g_set_error(err, CR_PARSEPKG_ERROR, CRE_UNKNOWNCHECKSUMTYPE, + "Unknown/Unsupported checksum type: %d", checksum_type); return result; - break; }; - // Open rpm file - - FD_t fd = NULL; - fd = Fopen(filename, "r.ufdio"); - if (!fd) { - g_warning("%s: Fopen failed %s", __func__, strerror(errno)); - return result; - } - - - // Read package + // Read header Header hdr; - int rc = rpmReadPackageFile(cr_ts, fd, NULL, &hdr); - if (rc != RPMRC_OK) { - switch (rc) { - case RPMRC_NOKEY: - g_debug("%s: %s: Public key is unavailable.", - __func__, filename); - break; - case RPMRC_NOTTRUSTED: - g_debug("%s: %s: Signature is OK, but key is not trusted.", - __func__, filename); - break; - default: - g_warning("%s: rpmReadPackageFile() error (%s)", - __func__, strerror(errno)); - return result; - } + read_header(filename, &hdr, &tmp_err); + if (tmp_err) { + g_propagate_error(err, tmp_err); + return result; } - // Cleanup - - Fclose(fd); - - // Get file stat gint64 mtime; @@ -263,6 +268,8 @@ cr_xml_from_rpm(const char *filename, struct stat stat_buf_own; if (stat(filename, &stat_buf_own) == -1) { g_warning("%s: stat() error (%s)", __func__, strerror(errno)); + g_set_error(err, CR_PARSEPKG_ERROR, CRE_IO, "stat() failed"); + headerFree(hdr); return result; } mtime = stat_buf_own.st_mtime; @@ -276,6 +283,12 @@ cr_xml_from_rpm(const char *filename, // Compute checksum char *checksum = cr_compute_file_checksum(filename, checksum_type, NULL); + if (tmp_err) { + g_propagate_prefixed_error(err, tmp_err, + "Error while checksum calculation:"); + headerFree(hdr); + return result; + } // Get header range @@ -287,13 +300,15 @@ cr_xml_from_rpm(const char *filename, result = cr_xml_from_header(hdr, mtime, size, checksum, checksum_type_str, location_href, location_base, changelog_limit, - hdr_r.start, hdr_r.end, NULL); - - - // Cleanup - + hdr_r.start, hdr_r.end, &tmp_err); free(checksum); headerFree(hdr); + if (tmp_err) { + g_propagate_prefixed_error(err, tmp_err, + "Error while checksum calculation:"); + return result; + } + return result; } diff --git a/src/parsepkg.h b/src/parsepkg.h index bc57e73..5c7d4d6 100644 --- a/src/parsepkg.h +++ b/src/parsepkg.h @@ -55,13 +55,16 @@ void cr_package_parser_cleanup(); * @param changelog_limit number of changelog entries * @param stat_buf struct stat of the filename * (optional - could be NULL) + * @param err GError ** + * @return cr_Package */ cr_Package *cr_package_from_rpm(const char *filename, cr_ChecksumType checksum_type, const char *location_href, const char *location_base, int changelog_limit, - struct stat *stat_buf); + struct stat *stat_buf, + GError **err); /** Generate XML for the specified package. * @param filename rpm filename @@ -71,13 +74,17 @@ cr_Package *cr_package_from_rpm(const char *filename, * @param changelog_limit number of changelog entries * @param stat_buf struct stat of the filename * (optional - could be NULL) + * @param err GError ** + * @return struct cr_XmlStruct with primary, filelists and + * other xmls */ struct cr_XmlStruct cr_xml_from_rpm(const char *filename, cr_ChecksumType checksum_type, const char *location_href, const char *location_base, int changelog_limit, - struct stat *stat_buf); + struct stat *stat_buf, + GError **err); /** @} */ diff --git a/src/python/parsepkg-py.c b/src/python/parsepkg-py.c index bac5231..d4155a4 100644 --- a/src/python/parsepkg-py.c +++ b/src/python/parsepkg-py.c @@ -37,6 +37,7 @@ py_package_from_rpm(PyObject *self, PyObject *args) cr_Package *pkg; int checksum_type, changelog_limit; char *filename, *location_href, *location_base; + GError *tmp_err = NULL; if (!PyArg_ParseTuple(args, "sizzi:py_package_from_rpm", &filename, @@ -53,9 +54,11 @@ py_package_from_rpm(PyObject *self, PyObject *args) } pkg = cr_package_from_rpm(filename, checksum_type, location_href, - location_base, changelog_limit, NULL); - if (!pkg) { - PyErr_Format(CrErr_Exception, "Cannot load %s", filename); + location_base, changelog_limit, NULL, &tmp_err); + if (tmp_err) { + PyErr_Format(CrErr_Exception, "Cannot load %s: %s", + filename, tmp_err->message); + g_clear_error(&tmp_err); return NULL; } @@ -72,6 +75,7 @@ py_xml_from_rpm(PyObject *self, PyObject *args) int checksum_type, changelog_limit; char *filename, *location_href, *location_base; struct cr_XmlStruct xml_res; + GError *tmp_err = NULL; if (!PyArg_ParseTuple(args, "sizzi:py_xml_from_rpm", &filename, @@ -89,10 +93,11 @@ py_xml_from_rpm(PyObject *self, PyObject *args) xml_res = cr_xml_from_rpm(filename, checksum_type, location_href, - location_base, changelog_limit, NULL); - - if (!xml_res.primary && !xml_res.filelists && !xml_res.other) { - PyErr_Format(CrErr_Exception, "Cannot load %s", filename); + location_base, changelog_limit, NULL, &tmp_err); + if (tmp_err) { + PyErr_Format(CrErr_Exception, "Cannot load %s: %s", + filename, tmp_err->message); + g_clear_error(&tmp_err); return NULL; } -- 2.7.4