From cf6da173f62ee96703714e66f8538069a46a63e3 Mon Sep 17 00:00:00 2001 From: Judd Vinet Date: Thu, 28 Sep 2006 20:51:33 +0000 Subject: removed libtar support in favour of libarchive --- configure.ac | 20 +++++++++--- lib/libalpm/add.c | 43 ++++++++++++++----------- lib/libalpm/alpm.h | 3 +- lib/libalpm/error.c | 2 ++ lib/libalpm/package.c | 44 +++++++++++++------------- lib/libalpm/sync.c | 28 ++++++++--------- lib/libalpm/util.c | 87 ++++++++++++++++++++------------------------------- lib/libalpm/util.h | 6 +++- 8 files changed, 117 insertions(+), 116 deletions(-) diff --git a/configure.ac b/configure.ac index 7a0cc559..f2e49f69 100644 --- a/configure.ac +++ b/configure.ac @@ -157,13 +157,25 @@ dnl Check for zlib AC_CHECK_LIB([z], [gzsetparams], [AC_CHECK_HEADER([zlib.h], [LIBZ='-lz'])]) if test -n "$LIBZ"; then LDFLAGS="$LDFLAGS $LIBZ" +else + AC_MSG_ERROR("missing zlib headers/libraries"); fi -dnl Check for libtar -AC_CHECK_LIB([tar], [tar_open], [AC_CHECK_HEADER([libtar.h], [LIBTAR='-ltar'])]) -if test -n "$LIBTAR"; then +dnl Check for bzip2 +AC_CHECK_LIB([bz2], [BZ2_bzCompress], [AC_CHECK_HEADER([bzlib.h], [LIBBZ2='-lbz2'])]) +if test -n "$LIBBZ2"; then + LDFLAGS="$LDFLAGS $LIBBZ2" +else + AC_MSG_ERROR("missing bzip2 headers/libraries"); +fi + +dnl Check for libarchive +AC_CHECK_LIB([archive], [archive_read_data], [AC_CHECK_HEADER([archive.h], [LIBARCHIVE='-larchive'])]) +if test -n "$LIBARCHIVE"; then CFLAGS="$CFLAGS" - LDFLAGS="$LDFLAGS $LIBTAR" + LDFLAGS="$LDFLAGS $LIBARCHIVE" +else + AC_MSG_ERROR("missing libarchive headers/libraries"); fi CFLAGS="$CFLAGS $ENV_CFLAGS" diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c index 62ea3e00..66c36b8a 100644 --- a/lib/libalpm/add.c +++ b/lib/libalpm/add.c @@ -26,9 +26,7 @@ #include #include #include -#include #include -#include /* pacman */ #include "util.h" #include "error.h" @@ -275,7 +273,8 @@ int _alpm_add_prepare(pmtrans_t *trans, pmdb_t *db, PMList **data) int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db) { int i, ret = 0, errors = 0; - TAR *tar = NULL; + register struct archive *archive; + struct archive_entry *entry; char expath[PATH_MAX]; time_t t; PMList *targ, *lp; @@ -288,12 +287,6 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db) } for(targ = trans->packages; targ; targ = targ->next) { - tartype_t gztype = { - (openfunc_t)_alpm_gzopen_frontend, - (closefunc_t)gzclose, - (readfunc_t)gzread, - (writefunc_t)gzwrite - }; unsigned short pmo_upgrade; char pm_install[PATH_MAX]; pmpkg_t *info = (pmpkg_t *)targ->data; @@ -380,21 +373,28 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db) _alpm_log(PM_LOG_FLOW1, _("extracting files")); /* Extract the .tar.gz package */ - if(tar_open(&tar, info->data, &gztype, O_RDONLY, 0, TAR_GNU) == -1) { + if((archive = archive_read_new()) == NULL) { + RET_ERR(PM_ERR_LIBARCHIVE_ERROR, -1); + } + archive_read_support_compression_all(archive); + archive_read_support_format_all(archive); + + if(archive_read_open_file(archive, info->data, 10240) != ARCHIVE_OK) { RET_ERR(PM_ERR_PKG_OPEN, -1); } - for(i = 0; !th_read(tar); i++) { + chdir(handle->root); + for(i = 0; archive_read_next_header(archive, &entry) == ARCHIVE_OK; i++) { int nb = 0; int notouch = 0; char *md5_orig = NULL; char pathname[PATH_MAX]; struct stat buf; - STRNCPY(pathname, th_get_pathname(tar), PATH_MAX); + STRNCPY(pathname, archive_entry_pathname(entry), PATH_MAX); if(!strcmp(pathname, ".PKGINFO") || !strcmp(pathname, ".FILELIST")) { - tar_skip_regfile(tar); + archive_read_data_skip(archive); continue; } @@ -413,7 +413,7 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db) */ if(_alpm_list_is_strin(pathname, handle->noextract)) { alpm_logaction(_("notice: %s is in NoExtract -- skipping extraction"), pathname); - tar_skip_regfile(tar); + archive_read_data_skip(archive); continue; } @@ -442,7 +442,8 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db) /* extract the package's version to a temporary file and md5 it */ temp = strdup("/tmp/alpm_XXXXXX"); fd = mkstemp(temp); - if(tar_extract_file(tar, temp)) { + archive_entry_set_pathname(entry, temp); + if(archive_read_extract(archive, entry, ARCHIVE_EXTRACT_FLAGS) != ARCHIVE_OK) { alpm_logaction(_("could not extract %s (%s)"), pathname, strerror(errno)); errors++; unlink(temp); @@ -490,9 +491,11 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db) char newpath[PATH_MAX]; snprintf(newpath, PATH_MAX, "%s.pacorig", expath); if(rename(expath, newpath)) { + archive_entry_set_pathname(entry, expath); _alpm_log(PM_LOG_ERROR, _("could not rename %s (%s)"), pathname, strerror(errno)); alpm_logaction(_("error: could not rename %s (%s)"), expath, strerror(errno)); } + archive_entry_set_pathname(entry, expath); if(_alpm_copyfile(temp, expath)) { _alpm_log(PM_LOG_ERROR, _("could not copy %s to %s (%s)"), temp, pathname, strerror(errno)); alpm_logaction(_("error: could not copy %s to %s (%s)"), temp, expath, strerror(errno)); @@ -534,6 +537,7 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db) _alpm_log(PM_LOG_ERROR, _("could not copy %s to %s (%s)"), temp, pathname, strerror(errno)); errors++; } + archive_entry_set_pathname(entry, expath); } } @@ -561,9 +565,10 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db) */ unlink(expath); } - if(tar_extract_file(tar, expath)) { - _alpm_log(PM_LOG_ERROR, _("could not extract %s (%s)"), pathname, strerror(errno)); - alpm_logaction(_("error: could not extract %s (%s)"), pathname, strerror(errno)); + archive_entry_set_pathname(entry, expath); + if(archive_read_extract(archive, entry, ARCHIVE_EXTRACT_FLAGS) != ARCHIVE_OK) { + _alpm_log(PM_LOG_ERROR, _("could not extract %s (%s)"), expath, strerror(errno)); + alpm_logaction(_("error: could not extract %s (%s)"), expath, strerror(errno)); errors++; } /* calculate an md5 hash if this is in info->backup */ @@ -590,7 +595,7 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db) } } } - tar_close(tar); + archive_read_finish(archive); if(errors) { ret = 1; diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 9eefa76f..61702ce7 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -379,7 +379,8 @@ extern enum __pmerrno_t { PM_ERR_FILE_CONFLICTS, /* Misc */ PM_ERR_USER_ABORT, - PM_ERR_INTERNAL_ERROR + PM_ERR_INTERNAL_ERROR, + PM_ERR_LIBARCHIVE_ERROR } pm_errno; char *alpm_strerror(int err); diff --git a/lib/libalpm/error.c b/lib/libalpm/error.c index 24ca7476..9f36810c 100644 --- a/lib/libalpm/error.c +++ b/lib/libalpm/error.c @@ -111,6 +111,8 @@ char *alpm_strerror(int err) return _("user aborted"); case PM_ERR_INTERNAL_ERROR: return _("internal error"); + case PM_ERR_LIBARCHIVE_ERROR: + return _("libarchive error"); default: return _("unexpected error"); } diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c index 277b3946..c8822240 100644 --- a/lib/libalpm/package.c +++ b/lib/libalpm/package.c @@ -26,8 +26,6 @@ #include #include #include -#include -#include /* pacman */ #include "log.h" #include "util.h" @@ -247,14 +245,9 @@ pmpkg_t *_alpm_pkg_load(char *pkgfile) int config = 0; int filelist = 0; int scriptcheck = 0; - TAR *tar = NULL; + register struct archive *archive; + struct archive_entry *entry; pmpkg_t *info = NULL; - tartype_t gztype = { - (openfunc_t)_alpm_gzopen_frontend, - (closefunc_t)gzclose, - (readfunc_t)gzread, - (writefunc_t)gzwrite - }; if(pkgfile == NULL || strlen(pkgfile) == 0) { RET_ERR(PM_ERR_WRONG_ARGS, NULL); @@ -269,23 +262,30 @@ pmpkg_t *_alpm_pkg_load(char *pkgfile) goto error; } - if(tar_open(&tar, pkgfile, &gztype, O_RDONLY, 0, TAR_GNU) == -1) { + 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_file(archive, pkgfile, 10240) != ARCHIVE_OK) { pm_errno = PM_ERR_NOT_A_FILE; goto error; } - for(i = 0; !th_read(tar); i++) { + for(i = 0; archive_read_next_header(archive, &entry) == ARCHIVE_OK; i++) { if(config && filelist && scriptcheck) { /* we have everything we need */ break; } - if(!strcmp(th_get_pathname(tar), ".PKGINFO")) { + if(!strcmp(archive_entry_pathname(entry), ".PKGINFO")) { char *descfile; int fd; /* extract this file into /tmp. it has info for us */ descfile = strdup("/tmp/alpm_XXXXXX"); fd = mkstemp(descfile); - tar_extract_file(tar, descfile); + _alpm_archive_read_entry_data_into_fd(archive, fd); + close(fd); /* parse the info file */ if(parse_descfile(descfile, info, 0) == -1) { _alpm_log(PM_LOG_ERROR, _("could not parse the package description file")); @@ -300,10 +300,10 @@ pmpkg_t *_alpm_pkg_load(char *pkgfile) FREE(descfile); close(fd); continue; - } else if(!strcmp(th_get_pathname(tar), "._install") || !strcmp(th_get_pathname(tar), ".INSTALL")) { + } else if(!strcmp(archive_entry_pathname(entry), "._install") || !strcmp(archive_entry_pathname(entry), ".INSTALL")) { info->scriptlet = 1; scriptcheck = 1; - } else if(!strcmp(th_get_pathname(tar), ".FILELIST")) { + } else if(!strcmp(archive_entry_pathname(entry), ".FILELIST")) { /* Build info->files from the filelist */ FILE *fp; char *fn; @@ -316,7 +316,8 @@ pmpkg_t *_alpm_pkg_load(char *pkgfile) } fn = strdup("/tmp/alpm_XXXXXX"); fd = mkstemp(fn); - tar_extract_file(tar, fn); + _alpm_archive_read_entry_data_into_fd(archive, fd); + close(fd); fp = fopen(fn, "r"); while(!feof(fp)) { if(fgets(str, PATH_MAX, fp) == NULL) { @@ -339,19 +340,18 @@ pmpkg_t *_alpm_pkg_load(char *pkgfile) if(!filelist) { /* no .FILELIST present in this package.. build the filelist the */ /* old-fashioned way, one at a time */ - expath = strdup(th_get_pathname(tar)); + expath = strdup(archive_entry_pathname(entry)); info->files = _alpm_list_add(info->files, expath); } } - if(TH_ISREG(tar) && tar_skip_regfile(tar)) { + if(archive_read_data_skip(archive)) { _alpm_log(PM_LOG_ERROR, _("bad package file in %s"), pkgfile); goto error; } expath = NULL; } - tar_close(tar); - tar = NULL; + archive_read_finish(archive); if(!config) { _alpm_log(PM_LOG_ERROR, _("missing package info file in %s"), pkgfile); @@ -367,9 +367,7 @@ pmpkg_t *_alpm_pkg_load(char *pkgfile) error: FREEPKG(info); - if(tar) { - tar_close(tar); - } + archive_read_finish(archive); return(NULL); } diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index 3223c916..05746bbc 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -29,8 +29,6 @@ #endif #include #include -#include -#include /* pacman */ #include "log.h" #include "util.h" @@ -110,27 +108,27 @@ static pmsyncpkg_t *find_pkginsync(char *needle, PMList *haystack) PMList *_alpm_sync_load_dbarchive(char *archive) { PMList *lp = NULL; - TAR *tar = NULL; - tartype_t gztype = { - (openfunc_t)_alpm_gzopen_frontend, - (closefunc_t)gzclose, - (readfunc_t)gzread, - (writefunc_t)gzwrite - }; - - if(tar_open(&tar, archive, &gztype, O_RDONLY, 0, TAR_GNU) == -1) { + register struct archive *_archive; + struct archive_entry *entry; + + if((_archive = archive_read_new()) == NULL) { + pm_errno = PM_ERR_LIBARCHIVE_ERROR; + goto error; + } + archive_read_support_compression_all(_archive); + archive_read_support_format_all(_archive); + + if(archive_read_open_file(_archive, archive, 10240) != ARCHIVE_OK) { pm_errno = PM_ERR_NOT_A_FILE; goto error; } - tar_close(tar); + archive_read_finish(_archive); return(lp); error: - if(tar) { - tar_close(tar); - } + archive_read_finish(_archive); return(NULL); } diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c index f85f5ce3..50b5c5de 100644 --- a/lib/libalpm/util.c +++ b/lib/libalpm/util.c @@ -36,47 +36,12 @@ #ifdef CYGWIN #include /* PATH_MAX */ #endif -#include -#include /* pacman */ #include "log.h" #include "util.h" +#include "error.h" #include "alpm.h" -/* borrowed and modified from Per Liden's pkgutils (http://crux.nu) */ -long _alpm_gzopen_frontend(char *pathname, int oflags, int mode) -{ - char* gzoflags; - int fd; - gzFile gzf; - - switch (oflags & O_ACCMODE) { - case O_WRONLY: - gzoflags = "w"; - break; - case O_RDONLY: - gzoflags = "r"; - break; - case O_RDWR: - default: - return -1; - } - - if((fd = open(pathname, oflags, mode)) == -1) { - return -1; - } - if((oflags & O_CREAT) && fchmod(fd, mode)) { - close(fd); - return -1; - } - if(!(gzf = gzdopen(fd, gzoflags))) { - close(fd); - return -1; - } - - return (long)gzf; -} - /* does the same thing as 'mkdir -p' */ int _alpm_makepath(char *path) { @@ -207,40 +172,56 @@ int _alpm_lckrm(char *file) int _alpm_unpack(char *archive, const char *prefix, const char *fn) { - TAR *tar = NULL; + register struct archive *_archive; + struct archive_entry *entry; char expath[PATH_MAX]; - tartype_t gztype = { - (openfunc_t) _alpm_gzopen_frontend, - (closefunc_t)gzclose, - (readfunc_t) gzread, - (writefunc_t)gzwrite - }; + if((_archive = archive_read_new()) == NULL) { + pm_errno = PM_ERR_LIBARCHIVE_ERROR; + return(1); + } + archive_read_support_compression_all(_archive); + archive_read_support_format_all(_archive); /* open the .tar.gz package */ - if(tar_open(&tar, archive, &gztype, O_RDONLY, 0, TAR_GNU) == -1) { + if(archive_read_open_file(_archive, archive, 10240) != ARCHIVE_OK) { perror(archive); return(1); } - while(!th_read(tar)) { - if(fn && strcmp(fn, th_get_pathname(tar))) { - if(TH_ISREG(tar) && tar_skip_regfile(tar)) { - _alpm_log(PM_LOG_ERROR, _("bad tar archive: %s"), archive); - tar_close(tar); + while(!archive_read_next_header(_archive, &entry) == ARCHIVE_OK) { + if(fn && strcmp(fn, archive_entry_pathname(entry))) { + if(archive_read_data_skip(_archive) != ARCHIVE_OK) { + _alpm_log(PM_LOG_ERROR, _("bad archive: %s"), archive); return(1); } continue; } - snprintf(expath, PATH_MAX, "%s/%s", prefix, th_get_pathname(tar)); - if(tar_extract_file(tar, expath)) { - _alpm_log(PM_LOG_ERROR, _("could not extract %s (%s)"), th_get_pathname(tar), strerror(errno)); + snprintf(expath, PATH_MAX, "%s/%s", prefix, archive_entry_pathname(entry)); + if(archive_read_extract(_archive, entry, ARCHIVE_EXTRACT_FLAGS) != ARCHIVE_OK) { + _alpm_log(PM_LOG_ERROR, _("could not extract %s (%s)"), archive_entry_pathname(entry), archive_error_string(_archive)); + return(1); } if(fn) break; } - tar_close(tar); + archive_read_finish(_archive); return(0); } +int _alpm_archive_read_entry_data_into_fd(struct archive *archive, int fd) +{ + register size_t length; + char cache[10240]; + + if(fd == -1) { + return ARCHIVE_RETRY; + } + while((length = archive_read_data(archive, &cache, sizeof(cache))) > 0) { + write(fd, cache, length); + } + + return ARCHIVE_OK; +} + /* does the same thing as 'rm -rf' */ int _alpm_rmrf(char *path) { diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h index af8162b2..9b0c9a0d 100644 --- a/lib/libalpm/util.h +++ b/lib/libalpm/util.h @@ -22,6 +22,8 @@ #define _ALPM_UTIL_H #include +#include +#include #define FREE(p) do { if (p) { free(p); p = NULL; } } while(0) @@ -34,7 +36,8 @@ #define _(str) dgettext("libalpm", str) -long _alpm_gzopen_frontend(char *pathname, int oflags, int mode); +#define ARCHIVE_EXTRACT_FLAGS ARCHIVE_EXTRACT_OWNER | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_TIME + int _alpm_makepath(char *path); int _alpm_copyfile(char *src, char *dest); char *_alpm_strtoupper(char *str); @@ -43,6 +46,7 @@ int _alpm_lckmk(char *file); int _alpm_lckrm(char *file); int _alpm_unpack(char *archive, const char *prefix, const char *fn); int _alpm_rmrf(char *path); +int _alpm_archive_read_entry_data_into_fd(struct archive *archive, int fd); int _alpm_logaction(unsigned char usesyslog, FILE *f, char *fmt, ...); int _alpm_ldconfig(char *root); int _alpm_runscriptlet(char *util, char *installfn, char *script, char *ver, char *oldver); -- cgit v1.2.3-70-g09d2