X-Git-Url: http://gitweb/?a=blobdiff_plain;f=pkgutil.cc;h=843c668f2876e588fd0c4181e9e67f9b1b5f57a7;hb=7e53648a28795a24c1310f57b915291f88aac995;hp=b4d419bde9a3d04ddf99be010a9c106aeac6d648;hpb=25efd91b9eec7755e4296591f531c923209dd1fa;p=pkgutils-cross.git diff --git a/pkgutil.cc b/pkgutil.cc index b4d419b..843c668 100644 --- a/pkgutil.cc +++ b/pkgutil.cc @@ -2,6 +2,7 @@ // pkgutils // // Copyright (c) 2000-2005 Per Liden +// Copyright (c) 2006-2010 by CRUX team (http://crux.nu) // // 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 @@ -38,11 +39,18 @@ #include #include #include -#include #include #include #include +#define INIT_ARCHIVE(ar) \ + archive_read_support_filter_gzip((ar)); \ + archive_read_support_filter_bzip2((ar)); \ + archive_read_support_filter_xz((ar)); \ + archive_read_support_format_tar((ar)) + +#define DEFAULT_BYTES_PER_BLOCK (20 * 512) + using __gnu_cxx::stdio_filebuf; pkgutil::pkgutil(const string& name) @@ -343,12 +351,11 @@ pair pkgutil::pkg_open(const string& filename) const result.second.version = version; archive = archive_read_new(); - archive_read_support_compression_all(archive); - archive_read_support_format_all(archive); + INIT_ARCHIVE(archive); if (archive_read_open_filename(archive, - const_cast(filename.c_str()), - ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) + filename.c_str(), + DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) throw runtime_error_with_errno("could not open " + filename, archive_errno(archive)); for (i = 0; archive_read_next_header(archive, &entry) == @@ -371,7 +378,7 @@ pair pkgutil::pkg_open(const string& filename) const throw runtime_error("could not read " + filename); } - archive_read_finish(archive); + archive_read_free(archive); return result; } @@ -381,23 +388,25 @@ void pkgutil::pkg_install(const string& filename, const set& keep_list, struct archive* archive; struct archive_entry* entry; unsigned int i; + char buf[PATH_MAX]; + string absroot; archive = archive_read_new(); - archive_read_support_compression_all(archive); - archive_read_support_format_all(archive); + INIT_ARCHIVE(archive); if (archive_read_open_filename(archive, - const_cast(filename.c_str()), - ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) + filename.c_str(), + DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) throw runtime_error_with_errno("could not open " + filename, archive_errno(archive)); chdir(root.c_str()); + absroot = getcwd(buf, sizeof(buf)); for (i = 0; archive_read_next_header(archive, &entry) == ARCHIVE_OK; ++i) { string archive_filename = archive_entry_pathname(entry); - string reject_dir = trim_filename(root + string("/") + string(PKG_REJECTED)); - string original_filename = trim_filename(root + string("/") + archive_filename); + string reject_dir = trim_filename(absroot + string("/") + string(PKG_REJECTED)); + string original_filename = trim_filename(absroot + string("/") + archive_filename); string real_filename = original_filename; // Check if file is filtered out via INSTALL @@ -422,8 +431,9 @@ void pkgutil::pkg_install(const string& filename, const set& keep_list, (real_filename.c_str())); // Extract file - if (archive_read_extract(archive, entry, ARCHIVE_EXTRACT_OWNER && ARCHIVE_EXTRACT_PERM) != - ARCHIVE_OK) { + unsigned int flags = ARCHIVE_EXTRACT_OWNER | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_UNLINK; + + if (archive_read_extract(archive, entry, flags) != ARCHIVE_OK) { // If a file fails to install we just print an error message and // continue trying to install the rest of the package. const char* msg = archive_error_string(archive); @@ -459,7 +469,7 @@ void pkgutil::pkg_install(const string& filename, const set& keep_list, throw runtime_error("could not read " + filename); } - archive_read_finish(archive); + archive_read_free(archive); } void pkgutil::ldconfig() const @@ -498,12 +508,11 @@ void pkgutil::pkg_footprint(string& filename) const // // FIXME the code duplication here is butt ugly archive = archive_read_new(); - archive_read_support_compression_all(archive); - archive_read_support_format_all(archive); + INIT_ARCHIVE(archive); if (archive_read_open_filename(archive, - const_cast(filename.c_str()), - ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) + filename.c_str(), + DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) throw runtime_error_with_errno("could not open " + filename, archive_errno(archive)); for (i = 0; archive_read_next_header(archive, &entry) == @@ -521,17 +530,16 @@ void pkgutil::pkg_footprint(string& filename) const throw runtime_error_with_errno("could not read " + filename, archive_errno(archive)); } - archive_read_finish(archive); + archive_read_free(archive); // Too bad, there doesn't seem to be a way to reuse our archive // instance archive = archive_read_new(); - archive_read_support_compression_all(archive); - archive_read_support_format_all(archive); + INIT_ARCHIVE(archive); if (archive_read_open_filename(archive, - const_cast(filename.c_str()), - ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) + filename.c_str(), + DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) throw runtime_error_with_errno("could not open " + filename, archive_errno(archive)); for (i = 0; archive_read_next_header(archive, &entry) == @@ -604,7 +612,7 @@ void pkgutil::pkg_footprint(string& filename) const throw runtime_error("could not read " + filename); } - archive_read_finish(archive); + archive_read_free(archive); } void pkgutil::print_version() const @@ -698,42 +706,6 @@ string mtos(mode_t mode) return s; } -int unistd_gzopen(char* pathname, int flags, mode_t mode) -{ - char* gz_mode; - - switch (flags & O_ACCMODE) { - case O_WRONLY: - gz_mode = "w"; - break; - - case O_RDONLY: - gz_mode = "r"; - break; - - case O_RDWR: - default: - errno = EINVAL; - return -1; - } - - int fd; - gzFile gz_file; - - if ((fd = open(pathname, flags, mode)) == -1) - return -1; - - if ((flags & O_CREAT) && fchmod(fd, mode)) - return -1; - - if (!(gz_file = gzdopen(fd, gz_mode))) { - errno = ENOMEM; - return -1; - } - - return (int)gz_file; -} - string trim_filename(const string& filename) { string search("//");