[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