[pacman-dev] [PATCH] Improve changelog handling
Nagy Gabor
ngaba at bibl.u-szeged.hu
Fri Dec 7 12:37:28 EST 2007
> Hi all,
>
> Below is a patch that tries to improve the handling of changelog
> dumping. Now changelogs should also get dumped when using "pacman -Qcp
> <file>" syntax as well as "pacman -Qc <pkg>" (See
> http://bugs.archlinux.org/task/7321)
>
> This is my first patch to the pacman/libalpm code base so it probably
> needs lots of checking. I stared at the code for a couple of hours
> before I started but I am probably using some libalpm functions wrongly.
> I would pay particular attention to the entirely new
> "alpm_pkg_get_changelog" function in libalpm/package.c.
>
> The code builds cleanly but I can't test much more than that at the
> moment due to my testing box having what I think is RAM issues leaving
> me only my work laptop...
>
> Cheers,
> Allan
>
>
>
> From 47affca982ec2d449bd6d96846172052dbdd3da6 Mon Sep 17 00:00:00 2001
> From: Allan McRae <mcrae_allan at hotmail.com>
> Date: Sat, 8 Dec 2007 02:35:00 +1000
> 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.
>
> Signed-off-by: Allan McRae <mcrae_allan at hotmail.com>
> ---
> lib/libalpm/alpm.h | 1 +
> lib/libalpm/package.c | 71
> +++++++++++++++++++++++++++++++++++++++++++++++++
> src/pacman/package.c | 33 ++++++++++------------
> src/pacman/package.h | 2 +-
> src/pacman/query.c | 9 +-----
> 5 files changed, 89 insertions(+), 27 deletions(-)
>
> diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
> index 1e18ad9..7f6c9eb 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);
> +alpm_list_t *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..bbdb95d 100644
> --- a/lib/libalpm/package.c
> +++ b/lib/libalpm/package.c
> @@ -491,6 +491,77 @@ alpm_list_t SYMEXPORT *alpm_pkg_get_backup(pmpkg_t
> *pkg)
> return pkg->backup;
> }
>
> +alpm_list_t 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;
> + alpm_list_t *cl = NULL;
> + char clfile[PATH_MAX];
> + char *tmpfile = NULL;
> + struct archive *archive;
> + struct archive_entry *entry;
> + int fd = -1;
> + char line[PATH_MAX];
> +
> + if(pkg->origin == PKG_FROM_CACHE) {
> + snprintf(clfile, PATH_MAX, "%s/%s/%s-%s/changelog",
> + alpm_option_get_dbpath(),
> + alpm_db_get_name(alpm_db_register_local()),
> + alpm_pkg_get_name(pkg),
> + alpm_pkg_get_version(pkg));
> + } 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) {
> + tmpfile = strdup("/tmp/alpm_XXXXXX");
> + fd = mkstemp(tmpfile);
> + archive_read_data_into_fd(archive, fd);
> + break;
> + }
> + }
> + snprintf(clfile, PATH_MAX, "%s", tmpfile);
> + }
> +
> + FILE* fp = fopen(clfile, "r");
> + if(fp == NULL){
> + return cl;
> + }
> +
> + while(!feof(fp)) {
> + fgets(line, (int)PATH_MAX, fp);
> + cl = alpm_list_add(cl, strdup(line));
> + }
> + fclose(fp);
> +
> + if(pkg->origin == PKG_FROM_FILE) {
> + unlink(tmpfile);
> + FREE(tmpfile);
> + close(fd);
> + }
> +
> + return cl;
> +}
> +
> 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..00c3535 100644
> --- a/src/pacman/package.c
> +++ b/src/pacman/package.c
> @@ -232,29 +232,26 @@ 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];
> -
> - if((fp = fopen(clfile, "r")) == NULL)
> - {
> - fprintf(stderr, _("error: no changelog available for '%s'.\n"),
> pkgname);
> + alpm_list_t *changelog = NULL;
> + alpm_list_t *i;
> + char line[PATH_MAX];
> +
> + changelog = alpm_pkg_get_changelog(pkg);
> + if(changelog == NULL) {
> + fprintf(stderr, _("error: no changelog available for '%s'.\n"),
> alpm_pkg_get_name(pkg));
> return;
> - }
> - else
> - {
> - while(!feof(fp))
> - {
> - fgets(line, (int)PATH_MAX, fp);
> - printf("%s", line);
> - line[0] = '\0';
> + } else {
> + for(i = changelog; i; i = alpm_list_next(i)) {
> + snprintf(line, PATH_MAX-1, "%s", (char*)alpm_list_getdata(i));
> + fprintf(stdout, "%s\n", line);
> }
> - fclose(fp);
> - return;
> }
> +
> + FREELIST(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
Well, personally I don't know too much about this changelog stuff so I may be
totally wrong, but if I understood your patch correctly, there is a changelog
file in our (local?)db or a .CHANGELOG file in the package (wow, db <-> package
format again). Probably this patch is good, but this doesn't follow our usual
methods to handle these things.
Since you said that you are new in pacman hacking, I can suggest you to give a
look at depends or desc handling for example.
These thinks are usually _loaded_ in be_files.c (on demand) and in package.c
(but hopefully the 2nd will be changed in the future), and these helper
low-lever functions fill in pmpkg_t accordingly.
So my suggestion: implement a .changelog field to pmpkg_t and follow our usual
method to query it, and modify _alpm_db_read and maybe _alpm_db_write. Since
this is a new file (descfile) we need a new INFRQ_CHANGELOG infolevel.
If this is implemented, we can "install" changelog to the localdb with the help
of pmpkg_t, not extract .CHANGELOG as changelog... (well, imho all low level
localdb manipulations should be done with _alpm_db_read and _alpm_db_write <-
see also: PM_TRANS_FLAG_DBONLY)
Bye
----------------------------------------------------
SZTE Egyetemi Könyvtár - http://www.bibl.u-szeged.hu
This mail sent through IMP: http://horde.org/imp/
More information about the pacman-dev
mailing list