On Fri, Dec 07, 2007 at 05:56:32PM -0600, Aaron Griffin wrote:
True, we don't need to. The current function is returning a alpm_list_t that contains lines, but i guess it's not really needed. We can return the full text as one big string, and leave it up to front ends to do some sort of parsing if they wish
Something like this ? :
From 2be1e8094574a4071f14df9d6347c65c5422776d Mon Sep 17 00:00:00 2001 From: Chantry Xavier <shiningxc@gmail.com> Date: Sat, 8 Dec 2007 19:18:49 +0100 Subject: [PATCH] Improve changelog handling.
Allows dumping of changelog for both installed packages and from package files (See FS#7321). Moves querying of changelog file in alpm backend. Original patch from Allan McRae, I changed get_changelog to read directly from the archive instead of extracting to a temp file, and this function now returns a big string, instead of a list of lines. Signed-off-by: Chantry Xavier <shiningxc@gmail.com> --- lib/libalpm/alpm.h | 1 + lib/libalpm/package.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++ src/pacman/package.c | 28 ++++++----------- src/pacman/package.h | 2 +- src/pacman/query.c | 9 +----- 5 files changed, 93 insertions(+), 27 deletions(-) diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 1e18ad9..c931b07 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -216,6 +216,7 @@ alpm_list_t *alpm_pkg_get_deltas(pmpkg_t *pkg); alpm_list_t *alpm_pkg_get_replaces(pmpkg_t *pkg); alpm_list_t *alpm_pkg_get_files(pmpkg_t *pkg); alpm_list_t *alpm_pkg_get_backup(pmpkg_t *pkg); +char *alpm_pkg_get_changelog(pmpkg_t *pkg); unsigned short alpm_pkg_has_scriptlet(pmpkg_t *pkg); unsigned long alpm_pkg_download_size(pmpkg_t *newpkg, pmdb_t *db_local); diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c index 172456d..3d7e74d 100644 --- a/lib/libalpm/package.c +++ b/lib/libalpm/package.c @@ -491,6 +491,86 @@ alpm_list_t SYMEXPORT *alpm_pkg_get_backup(pmpkg_t *pkg) return pkg->backup; } +char SYMEXPORT *alpm_pkg_get_changelog(pmpkg_t *pkg) +{ + ALPM_LOG_FUNC; + + /* Sanity checks */ + ASSERT(handle != NULL, return(NULL)); + ASSERT(pkg != NULL, return(NULL)); + + int ret = ARCHIVE_OK; + char clfile[PATH_MAX]; + FILE *fp = NULL; + struct archive *archive = NULL; + struct archive_entry *entry; + char *changelog = NULL, *p = NULL; + int bufsize = 512, size = 0, n = 0; + int done = 0, found = 0; + + if(pkg->origin == PKG_FROM_CACHE) { + snprintf(clfile, PATH_MAX, "%s/%s/%s-%s/changelog", + alpm_option_get_dbpath(), + alpm_db_get_name(handle->db_local), + alpm_pkg_get_name(pkg), + alpm_pkg_get_version(pkg)); + fp = fopen(clfile, "r"); + if(fp != NULL) { + found = 1; + } + } else if(pkg->origin == PKG_FROM_FILE) { + const char *pkgfile = pkg->origin_data.file; + + if((archive = archive_read_new()) == NULL) { + RET_ERR(PM_ERR_LIBARCHIVE_ERROR, NULL); + } + + archive_read_support_compression_all(archive); + archive_read_support_format_all(archive); + + if (archive_read_open_filename(archive, pkgfile, + ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) { + RET_ERR(PM_ERR_PKG_OPEN, NULL); + } + + while((ret = archive_read_next_header(archive, &entry)) == ARCHIVE_OK) { + const char *entry_name = archive_entry_pathname(entry); + + if(strcmp(entry_name, ".CHANGELOG") == 0) { + found = 1; + break; + } + } + } + + if(!found) { + return(NULL); + } + + while(!done) { + changelog = realloc(changelog, size + bufsize); + p = changelog + size; + size += bufsize; + if(pkg->origin == PKG_FROM_CACHE) { + n = fread(p, 1, bufsize, fp); + } else if(pkg->origin == PKG_FROM_FILE) { + n = archive_read_data(archive, p, bufsize); + } + if(n != bufsize) { + done = 1; + *(p+n) = '\0'; + } + } + + if(pkg->origin == PKG_FROM_CACHE) { + fclose(fp); + } else if(pkg->origin == PKG_FROM_FILE) { + archive_read_finish(archive); + } + + return(changelog); +} + unsigned short SYMEXPORT alpm_pkg_has_scriptlet(pmpkg_t *pkg) { ALPM_LOG_FUNC; diff --git a/src/pacman/package.c b/src/pacman/package.c index ac3f820..fcade3b 100644 --- a/src/pacman/package.c +++ b/src/pacman/package.c @@ -232,29 +232,21 @@ void dump_pkg_files(pmpkg_t *pkg) fflush(stdout); } -/* Display the changelog of an installed package +/* Display the changelog of a package */ -void dump_pkg_changelog(char *clfile, const char *pkgname) +void dump_pkg_changelog(pmpkg_t *pkg) { - FILE* fp = NULL; - char line[PATH_MAX+1]; + char *changelog = alpm_pkg_get_changelog(pkg); - if((fp = fopen(clfile, "r")) == NULL) - { - fprintf(stderr, _("error: no changelog available for '%s'.\n"), pkgname); - return; - } - else - { - while(!feof(fp)) - { - fgets(line, (int)PATH_MAX, fp); - printf("%s", line); - line[0] = '\0'; - } - fclose(fp); + if(changelog == NULL) { + fprintf(stderr, _("error: no changelog available for '%s'.\n"), + alpm_pkg_get_name(pkg)); return; + } else { + fprintf(stdout, "%s", changelog); } + + free(changelog); } /* vim: set ts=2 sw=2 noet: */ diff --git a/src/pacman/package.h b/src/pacman/package.h index 0e4bb0f..7dfc054 100644 --- a/src/pacman/package.h +++ b/src/pacman/package.h @@ -28,7 +28,7 @@ void dump_pkg_sync(pmpkg_t *pkg, const char *treename); void dump_pkg_backups(pmpkg_t *pkg); void dump_pkg_files(pmpkg_t *pkg); -void dump_pkg_changelog(char *clfile, const char *pkgname); +void dump_pkg_changelog(pmpkg_t *pkg); #endif /* _PM_PACKAGE_H */ diff --git a/src/pacman/query.c b/src/pacman/query.c index 8a8765b..1307077 100644 --- a/src/pacman/query.c +++ b/src/pacman/query.c @@ -312,14 +312,7 @@ static void display(pmpkg_t *pkg) dump_pkg_files(pkg); } if(config->op_q_changelog) { - char changelog[PATH_MAX]; - /* TODO should be done in the backend- no raw DB stuff up front */ - snprintf(changelog, PATH_MAX, "%s/%s/%s-%s/changelog", - alpm_option_get_dbpath(), - alpm_db_get_name(db_local), - alpm_pkg_get_name(pkg), - alpm_pkg_get_version(pkg)); - dump_pkg_changelog(changelog, alpm_pkg_get_name(pkg)); + dump_pkg_changelog(pkg); } if(!config->op_q_info && !config->op_q_list && !config->op_q_changelog) { if (!config->quiet) { -- 1.5.3.7