From: Michael Tremer Date: Tue, 9 Mar 2021 18:01:09 +0000 (+0000) Subject: packager: Write package metadata X-Git-Tag: 0.9.28~1285^2~590 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=98e85f1c0bb9c5d61dfeb881f6202ff6b729d543;p=pakfire.git packager: Write package metadata Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/packager.c b/src/libpakfire/packager.c index f17a07e6e..da1fc5574 100644 --- a/src/libpakfire/packager.c +++ b/src/libpakfire/packager.c @@ -281,6 +281,44 @@ static int pakfire_packager_copy_data(struct pakfire_packager* packager, return 0; } +static int pakfire_packager_write_file_from_buffer(struct pakfire_packager* packager, + struct archive* a, const char* filename, const char* buffer) { + // Create a new file entry + struct archive_entry* entry = archive_entry_new(); + if (!entry) + return 1; + + // Set filename + archive_entry_set_pathname(entry, filename); + + // This is a regular file + archive_entry_set_filetype(entry, AE_IFREG); + archive_entry_set_perm(entry, 0644); + + // Set length + archive_entry_set_size(entry, strlen(buffer)); + + // This is the end of the header + int r = archive_write_header(a, entry); + if (r) { + ERROR(packager->pakfire, "Error writing header: %s\n", archive_error_string(a)); + archive_entry_free(entry); + return r; + } + + // Write content + r = archive_write_data(a, buffer, strlen(buffer)); + if (r < 0) { + ERROR(packager->pakfire, "Error writing data: %s\n", archive_error_string(a)); + archive_entry_free(entry); + return r; + } + + archive_entry_free(entry); + + return 0; +} + static int pakfire_packager_write_format(struct pakfire_packager* packager, struct archive* a) { const char buffer[] = TO_STRING(PACKAGE_FORMAT) "\n"; @@ -321,6 +359,255 @@ static int pakfire_packager_write_format(struct pakfire_packager* packager, return 0; } +static char* pakfire_package_make_metadata(struct pakfire_packager* packager) { + PakfirePackage pkg = packager->pkg; + + char* buffer = NULL; + int r; + + // Print version information + r = asprintf(&buffer, "# Pakfire %s\n\n", PACKAGE_VERSION); + if (r < 0) + goto ERROR; + + // Write package information + r = asprintf(&buffer, "%s# Package information\npackage\n", buffer); + if (r < 0) + goto ERROR; + + // Write package name + r = asprintf(&buffer, "%s\tname = %s\n", buffer, pakfire_package_get_name(pkg)); + if (r < 0) + goto ERROR; + + // Write package version + r = asprintf(&buffer, "%s\tversion = %s\n", buffer, pakfire_package_get_version(pkg)); + if (r < 0) + goto ERROR; + + // Write package release + r = asprintf(&buffer, "%s\trelease = %s\n", buffer, pakfire_package_get_release(pkg)); + if (r < 0) + goto ERROR; + + // Write package epoch + r = asprintf(&buffer, "%s\tepoch = %lu\n", buffer, pakfire_package_get_epoch(pkg)); + if (r < 0) + goto ERROR; + + // Write package arch + r = asprintf(&buffer, "%s\tarch = %s\n", buffer, pakfire_package_get_arch(pkg)); + if (r < 0) + goto ERROR; + + // Write package UUID + r = asprintf(&buffer, "%s\tuuid = %s\n", buffer, pakfire_package_get_uuid(pkg)); + if (r < 0) + goto ERROR; + + // Write package groups + const char* groups = pakfire_package_get_groups(pkg); + if (groups) { + r = asprintf(&buffer, "%s\tgroups = %s\n", buffer, groups); + if (r < 0) + goto ERROR; + } + + // Write package maintainer + const char* maintainer = pakfire_package_get_maintainer(pkg); + if (maintainer) { + r = asprintf(&buffer, "%s\tmaintainer = %s\n", buffer, maintainer); + if (r < 0) + goto ERROR; + } + + // Write package url + const char* url = pakfire_package_get_maintainer(pkg); + if (url) { + r = asprintf(&buffer, "%s\turl = %s\n", buffer, url); + if (r < 0) + goto ERROR; + } + + // Write package license + const char* license = pakfire_package_get_license(pkg); + if (license) { + r = asprintf(&buffer, "%s\tlicense = %s\n", buffer, license); + if (r < 0) + goto ERROR; + } + + // Write package summary + const char* summary = pakfire_package_get_summary(pkg); + if (summary) { + r = asprintf(&buffer, "%s\tsummary = %s\n", buffer, summary); + if (r < 0) + goto ERROR; + } + + // XXX description + + size_t size = pakfire_package_get_installsize(pkg); + r = asprintf(&buffer, "%s\tsize = %zu\n", buffer, size); + if (r < 0) + goto ERROR; + + // End package block + r = asprintf(&buffer, "%send\n\n", buffer); + if (r < 0) + goto ERROR; + + // Write build information + r = asprintf(&buffer, "%s# Build information\nbuild\n", buffer); + if (r < 0) + goto ERROR; + + // Write build host + const char* build_host = pakfire_package_get_build_host(pkg); + if (build_host) { + r = asprintf(&buffer, "%s\thost = %s\n", buffer, build_host); + if (r < 0) + goto ERROR; + } + +#if 0 + // Write build id + const char* build_id = pakfire_package_get_build_id(pkg); + if (build_id) { + r = asprintf(&buffer, "%s\tid = %s\n", buffer, build_id); + if (r < 0) + goto ERROR; + } +#endif + + // Write build host + time_t build_time = pakfire_package_get_build_time(pkg); + if (build_host) { + r = asprintf(&buffer, "%s\ttime = %lu\n", buffer, build_time); + if (r < 0) + goto ERROR; + } + + // End build block + r = asprintf(&buffer, "%send\n\n", buffer); + if (r < 0) + goto ERROR; + +#if 0 + // Write distribution information + r = asprintf(&buffer, "%s# Distribution information\ndistribution\n", buffer); + if (r < 0) + goto ERROR; + + // End distribution block + r = asprintf(&buffer, "%send\n\n", buffer); + if (r < 0) + goto ERROR; +#endif + + // Write dependency information + r = asprintf(&buffer, "%s# Dependency information\ndependencies\n", buffer); + if (r < 0) + goto ERROR; + + const struct dependencies { + const char* type; + PakfireRelationList (*func)(PakfirePackage pkg); + } dependencies[] = { + { "prerequires", pakfire_package_get_prerequires }, + { "requires", pakfire_package_get_requires }, + { "provides", pakfire_package_get_provides }, + { "conflicts", pakfire_package_get_conflicts }, + { "obsoletes", pakfire_package_get_obsoletes }, + { "recommends", pakfire_package_get_recommends }, + { "suggests", pakfire_package_get_suggests }, + { "supplements", pakfire_package_get_supplements }, + { "enhances", pakfire_package_get_enhances }, + { NULL }, + }; + + for (const struct dependencies* d = dependencies; d->type; d++) { + PakfireRelationList list = d->func(pkg); + if (!list) + continue; + + size_t l = pakfire_relationlist_size(list); + + // Skip for empty lists + if (l == 0) { + pakfire_relationlist_unref(list); + continue; + } + + // Write header + r = asprintf(&buffer, "%s\t%s\n", buffer, d->type); + if (r < 0) { + pakfire_relationlist_unref(list); + goto ERROR; + } + + for (unsigned int i = 0; i < l; i++) { + PakfireRelation rel = pakfire_relationlist_get(list, i); + + char* s = pakfire_relation_str(rel); + if (s) { + r = asprintf(&buffer, "%s\t\t%s\n", buffer, s); + free(s); + if (r < 0) { + pakfire_relationlist_unref(list); + pakfire_relation_unref(rel); + goto ERROR; + } + } + + pakfire_relation_unref(rel); + } + + // End block + r = asprintf(&buffer, "%s\tend\n", buffer); + if (r < 0) + goto ERROR; + + pakfire_relationlist_unref(list); + } + + // End dependencies block + r = asprintf(&buffer, "%send\n\n", buffer); + if (r < 0) + goto ERROR; + + // EOF + r = asprintf(&buffer, "%s# EOF\n", buffer); + if (r < 0) + goto ERROR; + + return buffer; + +ERROR: + if (buffer) + free(buffer); + + return NULL; +} + +static int pakfire_packager_write_metadata(struct pakfire_packager* packager, + struct archive* a) { + // Make metadata + char* buffer = pakfire_package_make_metadata(packager); + if (!buffer) + return 1; + + DEBUG(packager->pakfire, "Generated package metadata:\n%s", buffer); + + // Write buffer + int r = pakfire_packager_write_file_from_buffer(packager, a, + PAKFIRE_ARCHIVE_FN_METADATA, buffer); + + free(buffer); + + return r; +} + static int pakfire_packager_write_payload(struct pakfire_packager* packager, struct archive* a) { struct stat st; @@ -419,6 +706,11 @@ PAKFIRE_EXPORT char* pakfire_packager_finish(struct pakfire_packager* packager, if (r) goto ERROR; + // Write the metadata + r = pakfire_packager_write_metadata(packager, a); + if (r) + goto ERROR; + // Write the payload r = pakfire_packager_write_payload(packager, a); if (r)