Do we need the old mappings for unpacking only listed files with specific set of permissions? If not, this is Ack. This was the only question I was thinking about when playing with this a month ago.. -- Martin SivÃk msivak@xxxxxxxxxx Red Hat Czech Anaconda team / Brno, CZ ----- "David Cantrell" <dcantrell@xxxxxxxxxx> wrote: > Created some helper functions for loader's interaction with > libarchive. There are 3 functions currently: > > 1) A function to initialize a new archive object > 2) A function to extract all archive members to a specific > destination (if NULL, extract to current directory) > 3) A function wrapping #1 and #2 to extract a compressed > archive file > --- > loader/Makefile.am | 3 +- > loader/unpack.c | 132 > ++++++++++++++++++++++++++++++++++++++++++++++++++++ > loader/unpack.h | 31 ++++++++++++ > 3 files changed, 165 insertions(+), 1 deletions(-) > create mode 100644 loader/unpack.c > create mode 100644 loader/unpack.h > > diff --git a/loader/Makefile.am b/loader/Makefile.am > index a11b569..336c442 100644 > --- a/loader/Makefile.am > +++ b/loader/Makefile.am > @@ -53,7 +53,8 @@ loader_SOURCES = loader.c copy.c moduleinfo.c > loadermisc.c \ > selinux.c mediacheck.c kickstart.c > driverselect.c \ > getparts.c dirbrowser.c fwloader.c ibft.c > hardware.c \ > method.c cdinstall.c hdinstall.c nfsinstall.c \ > - urlinstall.c net.c urls.c rpmextract.c > readvars.c > + urlinstall.c net.c urls.c rpmextract.c > readvars.c \ > + unpack.c > > init_CFLAGS = $(COMMON_CFLAGS) $(GLIB_CFLAGS) > init_LDADD = $(GLIB_LIBS) > $(top_srcdir)/pyanaconda/isys/libisys.la > diff --git a/loader/unpack.c b/loader/unpack.c > new file mode 100644 > index 0000000..0721a2e > --- /dev/null > +++ b/loader/unpack.c > @@ -0,0 +1,132 @@ > +/* > + * unpack.c - libarchive helper functions > + * > + * Copyright (C) 2010 Red Hat, Inc. > + * > + * This program is free software; you can redistribute it and/or > modify > + * it under the terms of the GNU General Public License as published > by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program. If not, see > <http://www.gnu.org/licenses/>. > + * > + * Author(s): David Cantrell <dcantrell@xxxxxxxxxx> > + */ > + > +#include <limits.h> > +#include <unistd.h> > + > +#include <archive.h> > +#include <archive_entry.h> > +#include <glib.h> > + > +#include "../pyanaconda/isys/log.h" > + > +/* > + * Initialize libarchive object for unpacking an archive file. > + * Args: > + * struct archive **a The archive object to use. > + * Returns: ARCHIVE_OK on success, ARCHIVE_* on failure > + */ > +int unpack_init(struct archive **a) { > + int r = ARCHIVE_OK; > + > + if ((*a = archive_read_new()) == NULL) > + return ARCHIVE_FATAL; > + > + if ((r = archive_read_support_compression_all(*a)) != > ARCHIVE_OK) > + return r; > + > + if ((r = archive_read_support_format_all(*a)) != ARCHIVE_OK) > + return r; > + > + return r; > +} > + > +/* > + * Extract all of the archive members of the specified archive > + * object. If dest is not NULL, extract archive members to that > + * directory. If dest is not NULL and does not exist as a > directory, > + * create it first. > + */ > +void unpack_members(struct archive *a, char *dest) { > + int restore = 0; > + char prevcwd[PATH_MAX]; > + struct archive_entry *e = NULL; > + > + if (getcwd(prevcwd, PATH_MAX) == NULL) > + logMessage(ERROR, "unable to getcwd() (%s:%d): %m", > __func__, > + > __LINE__); > + else > + restore = 1; > + > + if (dest != NULL && access(dest, R_OK|W_OK|X_OK)) { > + if (g_mkdir_with_parents(dest, 0755) == -1) > + logMessage(ERROR, "unable to mkdir %s (%s:%d): %m", > + dest, __func__, __LINE__); > + } else if (chdir(dest) == -1) { > + logMessage(ERROR, "unable to chdir %s (%s:%d): %m", > + dest, __func__, __LINE__); > + } > + > + while (archive_read_next_header(a, &e) == ARCHIVE_OK) { > + if (archive_read_extract(a, e, 0) != ARCHIVE_OK) > + logMessage(ERROR, "error unpacking %s (%s:%d): %s", > + archive_entry_pathname(e), __func__, > __LINE__, > + archive_error_string(a)); > + } > + > + if (restore && chdir(prevcwd) == -1) > + logMessage(ERROR, "unable to chdir %s (%s:%d): %m", > + dest, __func__, __LINE__); > + > + return; > +} > + > +/* > + * Extract an archive (optionally compressed). > + * Args: > + * filename Full path to archive to unpack. > + * dest Directory to unpack in, or NULL for current > dir. > + * Returns ARCHIVE_OK on success, or appropriate ARCHIVE_* value > + * on failure (see /usr/include/archive.h). > + */ > +int unpack_archive_file(char *filename, char *dest) { > + int rc = 0; > + struct archive *a = NULL; > + > + if (filename == NULL || access(filename, R_OK) == -1) { > + logMessage(ERROR, "unable to read %s (%s:%d): %m", > + filename, __func__, __LINE__); > + return ARCHIVE_FATAL; > + } > + > + if ((rc = unpack_init(&a)) != ARCHIVE_OK) { > + logMessage(ERROR, "unable to initialize libarchive"); > + return rc; > + } > + > + rc = archive_read_open_filename(a, filename, > + > ARCHIVE_DEFAULT_BYTES_PER_BLOCK); > + if (rc != ARCHIVE_OK) { > + logMessage(ERROR, "error opening %s (%s:%d): %s", > + filename, __func__, __LINE__, > + archive_error_string(a)); > + return rc; > + } > + > + unpack_members(a, dest); > + > + if ((rc = archive_read_finish(a)) != ARCHIVE_OK) > + logMessage(ERROR, "error closing %s (%s:%d): %s", > + filename, __func__, __LINE__, > + archive_error_string(a)); > + > + return rc; > +} > diff --git a/loader/unpack.h b/loader/unpack.h > new file mode 100644 > index 0000000..c8c1b5e > --- /dev/null > +++ b/loader/unpack.h > @@ -0,0 +1,31 @@ > +/* > + * unpack.h - libarchive helper functions > + * > + * Copyright (C) 2010 Red Hat, Inc. > + * > + * This program is free software; you can redistribute it and/or > modify > + * it under the terms of the GNU General Public License as published > by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program. If not, see > <http://www.gnu.org/licenses/>. > + * > + * Author(s): David Cantrell <dcantrell@xxxxxxxxxx> > + */ > + > +#ifndef UNPACK_H > +#define UNPACK_H > + > +#include <archive.h> > + > +int unpack_init(struct archive **); > +void unpack_members(struct archive *, char *); > +int unpack_archive_file(char *, char *); > + > +#endif > -- > 1.7.2.3 > > _______________________________________________ > Anaconda-devel-list mailing list > Anaconda-devel-list@xxxxxxxxxx > https://www.redhat.com/mailman/listinfo/anaconda-devel-list _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list