diff options
-rwxr-xr-x | contrib/paccache.in | 3 | ||||
-rw-r--r-- | lib/libalpm/add.c | 11 | ||||
-rw-r--r-- | lib/libalpm/be_package.c | 22 | ||||
-rw-r--r-- | lib/libalpm/be_sync.c | 2 | ||||
-rw-r--r-- | lib/libalpm/conflict.c | 33 | ||||
-rw-r--r-- | lib/libalpm/dload.c | 18 | ||||
-rw-r--r-- | lib/libalpm/util.c | 20 | ||||
-rw-r--r-- | lib/libalpm/util.h | 7 | ||||
-rw-r--r-- | src/util/Makefile.am | 2 | ||||
-rw-r--r-- | test/pacman/tests/fileconflict007.py | 2 | ||||
-rw-r--r-- | test/pacman/tests/symlink010.py | 24 | ||||
-rw-r--r-- | test/pacman/tests/symlink011.py | 24 | ||||
-rw-r--r-- | test/pacman/tests/symlink012.py | 24 |
13 files changed, 146 insertions, 46 deletions
diff --git a/contrib/paccache.in b/contrib/paccache.in index 4e185c27..eae547dc 100755 --- a/contrib/paccache.in +++ b/contrib/paccache.in @@ -154,6 +154,7 @@ summarize() { if (( verbose >= 3 )); then [[ $pkg =~ $pkg_re ]] && name=${BASH_REMATCH[1]} arch=${BASH_REMATCH[2]} if [[ -z $seen || $seenarch != "$arch" || $seen != "$name" ]]; then + seen=$name seenarch=$arch printf '%s (%s):\n' "$name" "$arch" fi printf ' %s\n' "$pkg" @@ -298,3 +299,5 @@ elif (( move )); then fi summarize "$pkgcount" "${candidates[@]}" + +# vim: set ts=2 sw=2 noet: diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c index 2ef41782..c6830dce 100644 --- a/lib/libalpm/add.c +++ b/lib/libalpm/add.c @@ -460,6 +460,7 @@ static int commit_single_pkg(alpm_handle_t *handle, alpm_pkg_t *newpkg, alpm_pkg_t *oldpkg = NULL; alpm_db_t *db = handle->db_local; alpm_trans_t *trans = handle->trans; + const char *pkgfile; ASSERT(trans != NULL, return -1); @@ -483,13 +484,15 @@ static int commit_single_pkg(alpm_handle_t *handle, alpm_pkg_t *newpkg, EVENT(handle, ALPM_EVENT_ADD_START, newpkg, NULL); } + pkgfile = newpkg->origin_data.file; + _alpm_log(handle, ALPM_LOG_DEBUG, "%s package %s-%s\n", is_upgrade ? "upgrading" : "adding", newpkg->name, newpkg->version); /* pre_install/pre_upgrade scriptlet */ if(alpm_pkg_has_scriptlet(newpkg) && !(trans->flags & ALPM_TRANS_FLAG_NOSCRIPTLET)) { const char *scriptlet_name = is_upgrade ? "pre_upgrade" : "pre_install"; - _alpm_runscriptlet(handle, newpkg->origin_data.file, + _alpm_runscriptlet(handle, pkgfile, scriptlet_name, newpkg->version, NULL, 1); } @@ -535,9 +538,9 @@ static int commit_single_pkg(alpm_handle_t *handle, alpm_pkg_t *newpkg, archive_read_support_compression_all(archive); archive_read_support_format_all(archive); - _alpm_log(handle, ALPM_LOG_DEBUG, "archive: %s\n", newpkg->origin_data.file); - if(archive_read_open_filename(archive, newpkg->origin_data.file, - ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) { + _alpm_log(handle, ALPM_LOG_DEBUG, "archive: %s\n", pkgfile); + if(archive_read_open_filename(archive, pkgfile, + ALPM_BUFFER_SIZE) != ARCHIVE_OK) { handle->pm_errno = ALPM_ERR_PKG_OPEN; ret = -1; goto cleanup; diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c index c20c703f..4d9d0e82 100644 --- a/lib/libalpm/be_package.c +++ b/lib/libalpm/be_package.c @@ -59,7 +59,7 @@ static void *_package_changelog_open(alpm_pkg_t *pkg) archive_read_support_format_all(archive); if(archive_read_open_filename(archive, pkgfile, - ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) { + ALPM_BUFFER_SIZE) != ARCHIVE_OK) { RET_ERR(pkg->handle, ALPM_ERR_PKG_OPEN, NULL); } @@ -390,7 +390,7 @@ alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle, archive_read_support_format_all(archive); if(archive_read_open_filename(archive, pkgfile, - ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) { + ALPM_BUFFER_SIZE) != ARCHIVE_OK) { alpm_pkg_free(newpkg); RET_ERR(handle, ALPM_ERR_PKG_OPEN, NULL); } @@ -482,17 +482,19 @@ alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle, newpkg->origin_data.file = strdup(pkgfile); newpkg->ops = get_file_pkg_ops(); newpkg->handle = handle; + newpkg->infolevel = INFRQ_BASE | INFRQ_DESC | INFRQ_SCRIPTLET; if(full) { - /* attempt to hand back any memory we don't need */ - files = realloc(files, sizeof(alpm_file_t) * files_count); - /* "checking for conflicts" requires a sorted list, ensure that here */ - _alpm_log(handle, ALPM_LOG_DEBUG, "sorting package filelist for %s\n", pkgfile); - newpkg->files.files = files_msort(files, files_count); + if(files) { + /* attempt to hand back any memory we don't need */ + files = realloc(files, sizeof(alpm_file_t) * files_count); + /* "checking for conflicts" requires a sorted list, ensure that here */ + _alpm_log(handle, ALPM_LOG_DEBUG, + "sorting package filelist for %s\n", pkgfile); + newpkg->files.files = files_msort(files, files_count); + } newpkg->files.count = files_count; - newpkg->infolevel = INFRQ_BASE | INFRQ_DESC | INFRQ_FILES | INFRQ_SCRIPTLET; - } else { - newpkg->infolevel = INFRQ_BASE | INFRQ_DESC | INFRQ_SCRIPTLET; + newpkg->infolevel |= INFRQ_FILES; } return newpkg; diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c index e9e816c0..3c990246 100644 --- a/lib/libalpm/be_sync.c +++ b/lib/libalpm/be_sync.c @@ -440,7 +440,7 @@ static int sync_db_populate(alpm_db_t *db) _alpm_log(db->handle, ALPM_LOG_DEBUG, "opening database archive %s\n", dbpath); if(archive_read_open_filename(archive, dbpath, - ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) { + ALPM_BUFFER_SIZE) != ARCHIVE_OK) { _alpm_log(db->handle, ALPM_LOG_ERROR, _("could not open file %s: %s\n"), dbpath, archive_error_string(archive)); archive_read_finish(archive); diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c index f686ca82..486f4bf3 100644 --- a/lib/libalpm/conflict.c +++ b/lib/libalpm/conflict.c @@ -473,16 +473,18 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, continue; } + _alpm_log(handle, ALPM_LOG_DEBUG, "checking possible conflict: %s\n", path); + if(S_ISDIR(file->mode)) { struct stat sbuf; if(S_ISDIR(lsbuf.st_mode)) { - _alpm_log(handle, ALPM_LOG_DEBUG, "%s is a directory, not a conflict\n", path); + _alpm_log(handle, ALPM_LOG_DEBUG, "file is a directory, not a conflict\n"); continue; } stat(path, &sbuf); if(S_ISLNK(lsbuf.st_mode) && S_ISDIR(sbuf.st_mode)) { _alpm_log(handle, ALPM_LOG_DEBUG, - "%s is a symlink to a dir, hopefully not a conflict\n", path); + "file is a symlink to a dir, hopefully not a conflict\n"); continue; } /* if we made it to here, we want all subsequent path comparisons to @@ -491,7 +493,6 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, path[strlen(path) - 1] = '\0'; } - _alpm_log(handle, ALPM_LOG_DEBUG, "checking possible conflict: %s\n", path); relative_path = path + strlen(handle->root); /* Check remove list (will we remove the conflicting local file?) */ @@ -500,7 +501,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, if(rempkg && _alpm_filelist_contains(alpm_pkg_get_files(rempkg), relative_path)) { _alpm_log(handle, ALPM_LOG_DEBUG, - "local file will be removed, not a conflict: %s\n", path); + "local file will be removed, not a conflict\n"); resolved_conflict = 1; } } @@ -521,7 +522,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, handle->trans->skip_remove = alpm_list_add(handle->trans->skip_remove, strdup(filestr)); _alpm_log(handle, ALPM_LOG_DEBUG, - "file changed packages, adding to remove skiplist: %s\n", path); + "file changed packages, adding to remove skiplist\n"); resolved_conflict = 1; } } @@ -539,16 +540,20 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, free(dir); } - if(!resolved_conflict && dbpkg) { + /* check if a component of the filepath was a link. canonicalize the path + * and look for it in the old package. note that the actual file under + * consideration cannot itself be a link, as it might be unowned- path + * components can be safely checked as all directories are "unowned". */ + if(!resolved_conflict && dbpkg && !S_ISLNK(lsbuf.st_mode)) { char *rpath = calloc(PATH_MAX, sizeof(char)); const char *relative_rpath; - if(!realpath(path, rpath)) { - free(rpath); - continue; - } - relative_rpath = rpath + strlen(handle->root); - if(_alpm_filelist_contains(alpm_pkg_get_files(dbpkg), relative_rpath)) { - resolved_conflict = 1; + if(realpath(path, rpath)) { + relative_rpath = rpath + strlen(handle->root); + if(_alpm_filelist_contains(alpm_pkg_get_files(dbpkg), relative_rpath)) { + _alpm_log(handle, ALPM_LOG_DEBUG, + "package contained the resolved realpath\n"); + resolved_conflict = 1; + } } free(rpath); } @@ -564,7 +569,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, } if(!found) { _alpm_log(handle, ALPM_LOG_DEBUG, - "file was unowned but in new backup list: %s\n", path); + "file was unowned but in new backup list\n"); resolved_conflict = 1; } } diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c index 9d919b0a..efd469d5 100644 --- a/lib/libalpm/dload.c +++ b/lib/libalpm/dload.c @@ -178,6 +178,14 @@ static int utimes_long(const char *path, long seconds) return 0; } +/* prefix to avoid possible future clash with getumask(3) */ +static mode_t _getumask(void) +{ + mode_t mask = umask(0); + umask(mask); + return mask; +} + static size_t parse_headers(void *ptr, size_t size, size_t nmemb, void *user) { size_t realsize = size * nmemb; @@ -295,9 +303,12 @@ static FILE *create_tempfile(struct dload_payload *payload, const char *localpat MALLOC(randpath, len, RET_ERR(payload->handle, ALPM_ERR_MEMORY, NULL)); snprintf(randpath, len, "%salpmtmp.XXXXXX", localpath); if((fd = mkstemp(randpath)) == -1 || + fchmod(fd, ~(_getumask()) & 0666) || !(fp = fdopen(fd, payload->tempfile_openmode))) { unlink(randpath); - close(fd); + if(fd >= 0) { + close(fd); + } _alpm_log(payload->handle, ALPM_LOG_ERROR, _("failed to create temporary file for download\n")); return NULL; @@ -334,9 +345,10 @@ static int curl_download_internal(struct dload_payload *payload, payload->tempfile_openmode = "wb"; if(!payload->remote_name) { - payload->remote_name = strdup(get_filename(payload->fileurl)); + STRDUP(payload->remote_name, get_filename(payload->fileurl), + RET_ERR(handle, ALPM_ERR_MEMORY, -1)); } - if(!payload->remote_name || curl_gethost(payload->fileurl, hostname, sizeof(hostname)) != 0) { + if(curl_gethost(payload->fileurl, hostname, sizeof(hostname)) != 0) { _alpm_log(handle, ALPM_LOG_ERROR, _("url '%s' is invalid\n"), payload->fileurl); RET_ERR(handle, ALPM_ERR_SERVER_BAD_URL, -1); } diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c index af9cf42f..a60062bc 100644 --- a/lib/libalpm/util.c +++ b/lib/libalpm/util.c @@ -129,8 +129,6 @@ int _alpm_makepath_mode(const char *path, mode_t mode) return ret; } -#define CPBUFSIZE 8 * 1024 - int _alpm_copyfile(const char *src, const char *dest) { FILE *in, *out; @@ -148,10 +146,10 @@ int _alpm_copyfile(const char *src, const char *dest) return 1; } - CALLOC(buf, (size_t)CPBUFSIZE, (size_t)1, ret = 1; goto cleanup;); + MALLOC(buf, (size_t)ALPM_BUFFER_SIZE, ret = 1; goto cleanup); /* do the actual file copy */ - while((len = fread(buf, 1, CPBUFSIZE, in))) { + while((len = fread(buf, 1, ALPM_BUFFER_SIZE, in))) { size_t nwritten = 0; nwritten = fwrite(buf, 1, len, out); if((nwritten != len) || ferror(out)) { @@ -172,7 +170,7 @@ int _alpm_copyfile(const char *src, const char *dest) cleanup: fclose(in); fclose(out); - FREE(buf); + free(buf); return ret; } @@ -286,7 +284,7 @@ int _alpm_unpack(alpm_handle_t *handle, const char *archive, const char *prefix, archive_read_support_format_all(_archive); if(archive_read_open_filename(_archive, archive, - ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) { + ALPM_BUFFER_SIZE) != ARCHIVE_OK) { _alpm_log(handle, ALPM_LOG_ERROR, _("could not open file %s: %s\n"), archive, archive_error_string(_archive)); RET_ERR(handle, ALPM_ERR_PKG_OPEN, 1); @@ -740,8 +738,6 @@ int _alpm_lstat(const char *path, struct stat *buf) } #ifdef HAVE_LIBSSL -#define BUFFER_SIZE 8192 - static int md5_file(const char *path, unsigned char output[16]) { FILE *f; @@ -749,7 +745,7 @@ static int md5_file(const char *path, unsigned char output[16]) MD5_CTX ctx; unsigned char *buf; - CALLOC(buf, BUFFER_SIZE, sizeof(unsigned char), return 1); + CALLOC(buf, ALPM_BUFFER_SIZE, sizeof(unsigned char), return 1); if((f = fopen(path, "rb")) == NULL) { free(buf); @@ -758,7 +754,7 @@ static int md5_file(const char *path, unsigned char output[16]) MD5_Init(&ctx); - while((n = fread(buf, 1, BUFFER_SIZE, f)) > 0) { + while((n = fread(buf, 1, ALPM_BUFFER_SIZE, f)) > 0) { MD5_Update(&ctx, buf, n); } @@ -784,7 +780,7 @@ static int sha2_file(const char *path, unsigned char output[32], int is224) SHA256_CTX ctx; unsigned char *buf; - CALLOC(buf, BUFFER_SIZE, sizeof(unsigned char), return 1); + CALLOC(buf, ALPM_BUFFER_SIZE, sizeof(unsigned char), return 1); if((f = fopen(path, "rb")) == NULL) { free(buf); @@ -797,7 +793,7 @@ static int sha2_file(const char *path, unsigned char output[32], int is224) SHA256_Init(&ctx); } - while((n = fread(buf, 1, BUFFER_SIZE, f)) > 0) { + while((n = fread(buf, 1, ALPM_BUFFER_SIZE, f)) > 0) { if(is224) { SHA224_Update(&ctx, buf, n); } else { diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h index 400a4eeb..8d20a281 100644 --- a/lib/libalpm/util.h +++ b/lib/libalpm/util.h @@ -74,6 +74,13 @@ #define CHECK_HANDLE(handle, action) do { if(!(handle)) { action; } (handle)->pm_errno = 0; } while(0) +/** Standard buffer size used throughout the library. */ +#ifdef BUFSIZ +#define ALPM_BUFFER_SIZE BUFSIZ +#else +#define ALPM_BUFFER_SIZE 8192 +#endif + /** * Used as a buffer/state holder for _alpm_archive_fgets(). */ diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 11308fbf..e4af56cf 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -31,6 +31,6 @@ testpkg_SOURCES = testpkg.c testpkg_LDADD = $(top_builddir)/lib/libalpm/.libs/libalpm.la vercmp_SOURCES = vercmp.c -vercmp_LDADD = $(top_builddir)/lib/libalpm/version.o +vercmp_LDADD = $(top_builddir)/lib/libalpm/version.lo # vim:set ts=2 sw=2 noet: diff --git a/test/pacman/tests/fileconflict007.py b/test/pacman/tests/fileconflict007.py index 7e6d85ef..4ee4624e 100644 --- a/test/pacman/tests/fileconflict007.py +++ b/test/pacman/tests/fileconflict007.py @@ -3,7 +3,7 @@ self.description = "Fileconflict with symlinks (klibc case)" lp = pmpkg("pkg") lp.files = ["dir/realdir/", "dir/symdir -> realdir", - "dir/realdir/file"] + "dir/realdir/file"] self.addpkg2db("local", lp) p = pmpkg("pkg", "1.0-2") diff --git a/test/pacman/tests/symlink010.py b/test/pacman/tests/symlink010.py new file mode 100644 index 00000000..a1e562e1 --- /dev/null +++ b/test/pacman/tests/symlink010.py @@ -0,0 +1,24 @@ +self.description = "Unowned identical symlink pointing to file in package" + +lp = pmpkg("dummy") +lp.files = ["usr/bin/myprog"] +self.addpkg2db("local", lp) + +self.filesystem = ["usr/bin/otherprog", + "usr/bin/myprogsuffix -> myprog"] + +p = pmpkg("dummy", "1.0-2") +p.files = ["usr/bin/myprog", + "usr/bin/myprogsuffix -> myprog"] +self.addpkg(p) + +self.args = "-U %s" % p.filename() + +self.addrule("PACMAN_RETCODE=1") +self.addrule("PKG_VERSION=dummy|1.0-1") +self.addrule("FILE_EXIST=usr/bin/myprog") +self.addrule("LINK_EXIST=usr/bin/myprogsuffix") +self.addrule("FILE_EXIST=usr/bin/otherprog") +self.addrule("FILE_TYPE=usr/bin/myprog|file") +self.addrule("FILE_TYPE=usr/bin/myprogsuffix|link") +self.addrule("FILE_TYPE=usr/bin/otherprog|file") diff --git a/test/pacman/tests/symlink011.py b/test/pacman/tests/symlink011.py new file mode 100644 index 00000000..93cd9ddf --- /dev/null +++ b/test/pacman/tests/symlink011.py @@ -0,0 +1,24 @@ +self.description = "Unowned broken symlink replaced by one in package" + +lp = pmpkg("dummy") +lp.files = ["usr/bin/myprog"] +self.addpkg2db("local", lp) + +self.filesystem = ["usr/bin/otherprog", + "usr/bin/myprogsuffix -> broken"] + +p = pmpkg("dummy", "1.0-2") +p.files = ["usr/bin/myprog", + "usr/bin/myprogsuffix -> myprog"] +self.addpkg(p) + +self.args = "-U %s" % p.filename() + +self.addrule("PACMAN_RETCODE=1") +self.addrule("PKG_VERSION=dummy|1.0-1") +self.addrule("FILE_EXIST=usr/bin/myprog") +self.addrule("LINK_EXIST=usr/bin/myprogsuffix") +self.addrule("FILE_EXIST=usr/bin/otherprog") +self.addrule("FILE_TYPE=usr/bin/myprog|file") +self.addrule("FILE_TYPE=usr/bin/myprogsuffix|link") +self.addrule("FILE_TYPE=usr/bin/otherprog|file") diff --git a/test/pacman/tests/symlink012.py b/test/pacman/tests/symlink012.py new file mode 100644 index 00000000..6a73bbbc --- /dev/null +++ b/test/pacman/tests/symlink012.py @@ -0,0 +1,24 @@ +self.description = "Unowned symlink when pointing to different file" + +lp = pmpkg("dummy") +lp.files = ["usr/bin/myprog"] +self.addpkg2db("local", lp) + +self.filesystem = ["usr/bin/otherprog", + "usr/bin/myprogsuffix -> otherprog"] + +p = pmpkg("dummy", "1.0-2") +p.files = ["usr/bin/myprog", + "usr/bin/myprogsuffix -> myprog"] +self.addpkg(p) + +self.args = "-U %s" % p.filename() + +self.addrule("PACMAN_RETCODE=1") +self.addrule("PKG_VERSION=dummy|1.0-1") +self.addrule("FILE_EXIST=usr/bin/myprog") +self.addrule("LINK_EXIST=usr/bin/myprogsuffix") +self.addrule("FILE_EXIST=usr/bin/otherprog") +self.addrule("FILE_TYPE=usr/bin/myprog|file") +self.addrule("FILE_TYPE=usr/bin/myprogsuffix|link") +self.addrule("FILE_TYPE=usr/bin/otherprog|file") |