summaryrefslogtreecommitdiffstats
path: root/lib/libalpm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libalpm')
-rw-r--r--lib/libalpm/add.c43
-rw-r--r--lib/libalpm/alpm.h3
-rw-r--r--lib/libalpm/error.c2
-rw-r--r--lib/libalpm/package.c44
-rw-r--r--lib/libalpm/sync.c28
-rw-r--r--lib/libalpm/util.c87
-rw-r--r--lib/libalpm/util.h6
7 files changed, 101 insertions, 112 deletions
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 <fcntl.h>
#include <string.h>
#include <limits.h>
-#include <zlib.h>
#include <libintl.h>
-#include <libtar.h>
/* 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 <fcntl.h>
#include <string.h>
#include <libintl.h>
-#include <libtar.h>
-#include <zlib.h>
/* 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 <dirent.h>
#include <libintl.h>
-#include <libtar.h>
-#include <zlib.h>
/* 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 <limits.h> /* PATH_MAX */
#endif
-#include <zlib.h>
-#include <libtar.h>
/* 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 <stdio.h>
+#include <archive.h>
+#include <archive_entry.h>
#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);