[pacman-dev] [PATCH] Improve changelog handling

Xavier shiningxc at gmail.com
Sat Dec 8 13:20:36 EST 2007


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 at 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 at 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





More information about the pacman-dev mailing list