[pacman-dev] [PATCH] Add functions for reading mtree file from local db
Dan McGee
dpmcgee at gmail.com
Tue May 1 08:18:47 EDT 2012
On Tue, May 1, 2012 at 3:17 AM, Allan McRae <allan at archlinux.org> wrote:
> Signed-off-by: Allan McRae <allan at archlinux.org>
> ---
>
> I have not tested this actually reads the mtree file correctly yet...
> but I would like some feedback if people think that this is the right approach
> to take before I spend more time on it.
>
> lib/libalpm/be_local.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++
> lib/libalpm/package.c | 21 +++++++++++++++++
> lib/libalpm/package.h | 8 +++++++
> 3 files changed, 89 insertions(+)
>
> diff --git a/lib/libalpm/be_local.c b/lib/libalpm/be_local.c
> index aab6718..dbd8138 100644
> --- a/lib/libalpm/be_local.c
> +++ b/lib/libalpm/be_local.c
> @@ -28,6 +28,10 @@
> #include <dirent.h>
> #include <limits.h> /* PATH_MAX */
>
> +/* libarchive */
> +#include <archive.h>
> +#include <archive_entry.h>
> +
> /* libalpm */
> #include "db.h"
> #include "alpm_list.h"
> @@ -210,6 +214,58 @@ static int _cache_changelog_close(const alpm_pkg_t UNUSED *pkg, void *fp)
> return fclose((FILE *)fp);
> }
>
> +static void *_cache_mtree_open(alpm_pkg_t *pkg)
> +{
> + int r;
> + struct archive *mtree;
> +
> + pkg->handle->pm_errno = 0;
> +
> + alpm_db_t *db = alpm_pkg_get_db(pkg);
> + char *mtfile = _alpm_local_db_pkgpath(db, pkg, "mtree");
> +
> + if(access(mtfile, F_OK) != 0) {
> + /* there is no mtree file for this package */
> + return NULL;
> + }
> +
> + if((mtree = archive_read_new()) == NULL) {
> + pkg->handle->pm_errno = ALPM_ERR_LIBARCHIVE;
free(mtfile);
> + return NULL;
> + }
> +
> + archive_read_support_filter_gzip(mtree);
Any reason to restrict the filter support here, other than you knew
you chose gzip? Might as well remain flexible.
> + archive_read_support_format_mtree(mtree);
> +
> + if((r = archive_read_open_file(mtree, mtfile, ALPM_BUFFER_SIZE))) {
> + _alpm_log(pkg->handle, ALPM_LOG_ERROR, _("error while reading file %s: %s\n"),
> + mtfile, archive_error_string(mtree));
> + pkg->handle->pm_errno = ALPM_ERR_LIBARCHIVE;
> + archive_read_finish(mtree);
free(mtfile);
This never frees itself.
> + return NULL;
> + }
> +
> + return mtree;
> +}
> +
> +static int _cache_mtree_read(void *entry, const alpm_pkg_t UNUSED *pkg,
> + void *archive)
> +{
> + int ret;
> + struct archive *mtree = archive;
> + struct archive_entry *details = entry;
> +
> + ret = archive_read_next_header(mtree, &details);
> +
> + return ret;
> +}
> +
> +static void _cache_mtree_close(const alpm_pkg_t UNUSED *pkg, void *archive)
> +{
> + struct archive *mtree = archive;
> + archive_read_free(mtree);
> +}
> +
> static int _cache_force_load(alpm_pkg_t *pkg)
> {
> return local_db_read(pkg, INFRQ_ALL);
> @@ -245,6 +301,10 @@ static struct pkg_operations local_pkg_ops = {
> .changelog_read = _cache_changelog_read,
> .changelog_close = _cache_changelog_close,
>
> + .mtree_open = _cache_mtree_open,
> + .mtree_read = _cache_mtree_read,
> + .mtree_close = _cache_mtree_close,
> +
> .force_load = _cache_force_load,
> };
>
> diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c
> index 46d1473..0f446d3 100644
> --- a/lib/libalpm/package.c
> +++ b/lib/libalpm/package.c
> @@ -121,6 +121,23 @@ static int _pkg_changelog_close(const alpm_pkg_t UNUSED *pkg,
> return EOF;
> }
>
> +static void *_pkg_mtree_open(alpm_pkg_t UNUSED *pkg)
> +{
> + return NULL;
> +}
> +
> +static int _pkg_mtree_read(void UNUSED *entry, const alpm_pkg_t UNUSED *pkg,
> + void UNUSED *archive)
> +{
> + return 0;
> +}
> +
> +static void _pkg_mtree_close(const alpm_pkg_t UNUSED *pkg,
> + void UNUSED *archive)
> +{
> + return;
> +}
> +
> static int _pkg_force_load(alpm_pkg_t UNUSED *pkg) { return 0; }
>
> /** The standard package operations struct. Get fields directly from the
> @@ -152,6 +169,10 @@ struct pkg_operations default_pkg_ops = {
> .changelog_read = _pkg_changelog_read,
> .changelog_close = _pkg_changelog_close,
>
> + .mtree_open = _pkg_mtree_open,
> + .mtree_read = _pkg_mtree_read,
> + .mtree_close = _pkg_mtree_close,
> +
Since we are including this file in the package itself, in the long
run, we can have an implementation in the be_package.c backend too.
But don't worry about that now since I have no idea how or why one
would use that yet.
> .force_load = _pkg_force_load,
> };
>
> diff --git a/lib/libalpm/package.h b/lib/libalpm/package.h
> index c473549..aff9075 100644
> --- a/lib/libalpm/package.h
> +++ b/lib/libalpm/package.h
> @@ -26,6 +26,10 @@
>
> #include <sys/types.h> /* off_t */
>
> +/* libarchive */
> +#include <archive.h>
> +#include <archive_entry.h>
> +
> #include "alpm.h"
> #include "backup.h"
> #include "db.h"
> @@ -64,6 +68,10 @@ struct pkg_operations {
> size_t (*changelog_read) (void *, size_t, const alpm_pkg_t *, void *);
> int (*changelog_close) (const alpm_pkg_t *, void *);
>
> + void *(*mtree_open) (alpm_pkg_t *);
> + int (*mtree_read) (void *, const alpm_pkg_t *, void *);
> + void (*mtree_close) (const alpm_pkg_t *, void *);
> +
> int (*force_load) (alpm_pkg_t *);
> };
>
> --
As to your original question- yes, this approach seems reasonable and
the right way to go about it. One issue here is you didn't actually
return the "details" object from _cache_mtree_read() here. In any
case, we can probably tailor this API to both receive and return (in a
pointer argument) libarchive stuff directly, as we can just designate
that as our public mtree interface.
-Dan
More information about the pacman-dev
mailing list