[pacman-dev] [PATCH 1/4] pactest: add a few more checks to fileconflict checks
Signed-off-by: Dan McGee <dan@archlinux.org> --- test/pacman/tests/fileconflict001.py | 3 +++ test/pacman/tests/fileconflict002.py | 9 +++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/test/pacman/tests/fileconflict001.py b/test/pacman/tests/fileconflict001.py index 8c13911..dec6151 100644 --- a/test/pacman/tests/fileconflict001.py +++ b/test/pacman/tests/fileconflict001.py @@ -2,6 +2,7 @@ lp = pmpkg("dummy") lp.files = ["dir/realdir/", + "dir/realdir/realfile", "dir/symdir -> realdir"] self.addpkg2db("local", lp) @@ -18,5 +19,7 @@ self.addrule("PACMAN_RETCODE=1") self.addrule("!PKG_EXIST=pkg1") self.addrule("!PKG_EXIST=pkg2") +self.addrule("FILE_EXIST=dir/realdir/realfile") +self.addrule("!FILE_EXIST=dir/realdir/file") self.expectfailure = True diff --git a/test/pacman/tests/fileconflict002.py b/test/pacman/tests/fileconflict002.py index f70873b..e107cd2 100644 --- a/test/pacman/tests/fileconflict002.py +++ b/test/pacman/tests/fileconflict002.py @@ -1,12 +1,16 @@ self.description = "Fileconflict with symlinks (2)" p1 = pmpkg("pkg1") -p1.files = ["dir/realdir/file", +p1.files = ["dir/", + "dir/realdir/", + "dir/realdir/file", "dir/symdir -> realdir"] self.addpkg(p1) p2 = pmpkg("pkg2") -p2.files = ["dir/symdir/file"] +p2.files = ["dir/", + "dir/symdir/", + "dir/symdir/file"] self.addpkg(p2) self.args = "-U %s" % " ".join([p.filename() for p in p1, p2]) @@ -14,5 +18,6 @@ self.addrule("PACMAN_RETCODE=1") self.addrule("!PKG_EXIST=pkg1") self.addrule("!PKG_EXIST=pkg2") +self.addrule("!FILE_EXIST=dir/realdir/file") self.expectfailure = True -- 1.7.6
This allows us to capture size and mode data when building filelists from package files. Future patches will take advantage of this newly available information, and frontends can use it as well. Signed-off-by: Dan McGee <dan@archlinux.org> --- lib/libalpm/alpm.h | 7 ++++++ lib/libalpm/be_local.c | 13 ++++++---- lib/libalpm/be_package.c | 14 +++++++++-- lib/libalpm/conflict.c | 55 ++++++++++++++++++++++++++++++++------------- lib/libalpm/conflict.h | 3 ++ lib/libalpm/diskspace.c | 7 +++-- lib/libalpm/package.c | 38 ++++++++++++++++++++++++++++--- lib/libalpm/package.h | 4 +++ lib/libalpm/remove.c | 29 ++++++++++++----------- src/pacman/package.c | 8 +++--- src/pacman/query.c | 6 +++- 11 files changed, 133 insertions(+), 51 deletions(-) diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 7656427..88aef37 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -160,6 +160,13 @@ typedef struct _alpm_delta_t { off_t download_size; } alpm_delta_t; +/** File in a package */ +typedef struct _alpm_file_t { + char *name; + off_t size; + mode_t mode; +} alpm_file_t; + /** Local package or package file backup entry */ typedef struct _alpm_backup_t { char *name; diff --git a/lib/libalpm/be_local.c b/lib/libalpm/be_local.c index 63a95bb..29be1ed 100644 --- a/lib/libalpm/be_local.c +++ b/lib/libalpm/be_local.c @@ -666,9 +666,11 @@ static int local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t inforeq) _alpm_strtrim(line); if(strcmp(line, "%FILES%") == 0) { while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) { - char *linedup; - STRDUP(linedup, line, goto error); - info->files = alpm_list_add(info->files, linedup); + alpm_file_t *file; + CALLOC(file, 1, sizeof(alpm_file_t), goto error); + STRDUP(file->name, line, goto error); + /* TODO: lstat file, get mode/size */ + info->files = alpm_list_add(info->files, file); } } else if(strcmp(line, "%BACKUP%") == 0) { while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) { @@ -869,14 +871,15 @@ int _alpm_local_db_write(alpm_db_t *db, alpm_pkg_t *info, alpm_dbinfrq_t inforeq if(info->files) { fprintf(fp, "%%FILES%%\n"); for(lp = info->files; lp; lp = lp->next) { - fprintf(fp, "%s\n", (char *)lp->data); + const alpm_file_t *file = lp->data; + fprintf(fp, "%s\n", file->name); } fprintf(fp, "\n"); } if(info->backup) { fprintf(fp, "%%BACKUP%%\n"); for(lp = info->backup; lp; lp = lp->next) { - alpm_backup_t *backup = lp->data; + const alpm_backup_t *backup = lp->data; fprintf(fp, "%s\t%s\n", backup->name, backup->hash); } fprintf(fp, "\n"); diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c index a4c6c55..da5076e 100644 --- a/lib/libalpm/be_package.c +++ b/lib/libalpm/be_package.c @@ -328,7 +328,12 @@ alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle, const char *pkgfile, * already been handled (for future possibilities) */ } else if(full) { /* Keep track of all files for filelist generation */ - newpkg->files = alpm_list_add(newpkg->files, strdup(entry_name)); + alpm_file_t *file; + CALLOC(file, 1, sizeof(alpm_file_t), goto error); + STRDUP(file->name, entry_name, goto error); + file->size = archive_entry_size(entry); + file->mode = archive_entry_mode(entry); + newpkg->files = alpm_list_add(newpkg->files, file); files_count++; } @@ -368,11 +373,14 @@ alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle, const char *pkgfile, if(full) { /* "checking for conflicts" requires a sorted list, ensure that here */ _alpm_log(handle, PM_LOG_DEBUG, "sorting package filelist for %s\n", pkgfile); - newpkg->files = alpm_list_msort(newpkg->files, files_count, _alpm_str_cmp); + newpkg->files = alpm_list_msort(newpkg->files, files_count, + _alpm_files_cmp); newpkg->infolevel = INFRQ_ALL; } else { /* get rid of any partial filelist we may have collected, it is invalid */ - FREELIST(newpkg->files); + alpm_list_free_inner(newpkg->files, (alpm_list_fn_free)_alpm_files_free); + alpm_list_free(newpkg->files); + newpkg->files = NULL; newpkg->infolevel = INFRQ_BASE | INFRQ_DESC; } diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c index 5d9bbf2..6ed9981 100644 --- a/lib/libalpm/conflict.c +++ b/lib/libalpm/conflict.c @@ -34,6 +34,7 @@ /* libalpm */ #include "conflict.h" #include "alpm_list.h" +#include "alpm.h" #include "handle.h" #include "trans.h" #include "util.h" @@ -222,6 +223,7 @@ static const int DIFFERENCE = 0; static const int INTERSECT = 1; /* Returns a set operation on the provided two lists of files. * Pre-condition: both lists are sorted! + * When done, free the list but NOT the contained data. * * Operations: * DIFFERENCE - a difference operation is performed. filesA - filesB. @@ -234,8 +236,10 @@ static alpm_list_t *filelist_operation(alpm_list_t *filesA, alpm_list_t *filesB, alpm_list_t *pA = filesA, *pB = filesB; while(pA && pB) { - const char *strA = pA->data; - const char *strB = pB->data; + alpm_file_t *fileA = pA->data; + alpm_file_t *fileB = pB->data; + const char *strA = fileA->name; + const char *strB = fileB->name; /* skip directories, we don't care about them */ if(strA[strlen(strA)-1] == '/') { pA = pA->next; @@ -246,7 +250,7 @@ static alpm_list_t *filelist_operation(alpm_list_t *filesA, alpm_list_t *filesB, if(cmp < 0) { if(operation == DIFFERENCE) { /* item only in filesA, qualifies as a difference */ - ret = alpm_list_add(ret, strdup(strA)); + ret = alpm_list_add(ret, fileA); } pA = pA->next; } else if(cmp > 0) { @@ -254,7 +258,7 @@ static alpm_list_t *filelist_operation(alpm_list_t *filesA, alpm_list_t *filesB, } else { if(operation == INTERSECT) { /* item in both, qualifies as an intersect */ - ret = alpm_list_add(ret, strdup(strA)); + ret = alpm_list_add(ret, fileA); } pA = pA->next; pB = pB->next; @@ -264,10 +268,11 @@ static alpm_list_t *filelist_operation(alpm_list_t *filesA, alpm_list_t *filesB, /* if doing a difference, ensure we have completely emptied pA */ while(operation == DIFFERENCE && pA) { - const char *strA = pA->data; + alpm_file_t *fileA = pA->data; + const char *strA = fileA->name; /* skip directories */ if(strA[strlen(strA)-1] != '/') { - ret = alpm_list_add(ret, strdup(strA)); + ret = alpm_list_add(ret, fileA); } pA = pA->next; } @@ -314,13 +319,27 @@ void _alpm_fileconflict_free(alpm_fileconflict_t *conflict) FREE(conflict); } +const alpm_file_t *_alpm_filelist_contains(const alpm_list_t *haystack, + const char *needle) +{ + const alpm_list_t *lp = haystack; + while(lp) { + const alpm_file_t *file = lp->data; + if(strcmp(file->name, needle) == 0) { + return file; + } + lp = lp->next; + } + return NULL; +} + static int dir_belongsto_pkg(const char *root, const char *dirpath, alpm_pkg_t *pkg) { - struct dirent *ent = NULL; struct stat sbuf; char path[PATH_MAX]; char abspath[PATH_MAX]; + struct dirent *ent = NULL; DIR *dir; snprintf(abspath, PATH_MAX, "%s%s", root, dirpath); @@ -328,6 +347,7 @@ static int dir_belongsto_pkg(const char *root, const char *dirpath, if(dir == NULL) { return 1; } + while((ent = readdir(dir)) != NULL) { const char *name = ent->d_name; @@ -347,7 +367,7 @@ static int dir_belongsto_pkg(const char *root, const char *dirpath, return 0; } } else { - if(alpm_list_find_str(alpm_pkg_get_files(pkg), path)) { + if(_alpm_filelist_contains(alpm_pkg_get_files(pkg), path)) { continue; } else { closedir(dir); @@ -415,7 +435,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, return NULL; } } - FREELIST(common_files); + alpm_list_free(common_files); } } @@ -440,7 +460,9 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, for(j = tmpfiles; j; j = j->next) { struct stat lsbuf; - const char *filestr = j->data, *relative_path; + alpm_file_t *file = j->data; + const char *filestr = file->name; + const char *relative_path; /* have we acted on this conflict? */ int resolved_conflict = 0; @@ -475,7 +497,8 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, /* Check remove list (will we remove the conflicting local file?) */ for(k = remove; k && !resolved_conflict; k = k->next) { alpm_pkg_t *rempkg = k->data; - if(alpm_list_find_str(alpm_pkg_get_files(rempkg), relative_path)) { + if(rempkg && _alpm_filelist_contains(alpm_pkg_get_files(rempkg), + relative_path)) { _alpm_log(handle, PM_LOG_DEBUG, "local file will be removed, not a conflict: %s\n", relative_path); @@ -492,7 +515,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, alpm_pkg_t *localp2 = _alpm_db_get_pkgfromcache(handle->db_local, p2->name); /* localp2->files will be removed (target conflicts are handled by CHECK 1) */ - if(localp2 && alpm_list_find_str(alpm_pkg_get_files(localp2), filestr)) { + if(localp2 && _alpm_filelist_contains(alpm_pkg_get_files(localp2), filestr)) { /* skip removal of file, but not add. this will prevent a second * package from removing the file when it was already installed * by its new owner (whether the file is in backup array or not */ @@ -509,7 +532,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, if(!resolved_conflict && S_ISDIR(lsbuf.st_mode) && dbpkg) { char *dir = malloc(strlen(filestr) + 2); sprintf(dir, "%s/", filestr); - if(alpm_list_find_str(alpm_pkg_get_files(dbpkg),dir)) { + if(_alpm_filelist_contains(alpm_pkg_get_files(dbpkg), dir)) { _alpm_log(handle, PM_LOG_DEBUG, "check if all files in %s belongs to %s\n", dir, dbpkg->name); @@ -526,7 +549,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, continue; } relative_rpath = rpath + strlen(handle->root); - if(alpm_list_find_str(alpm_pkg_get_files(dbpkg), relative_rpath)) { + if(_alpm_filelist_contains(alpm_pkg_get_files(dbpkg), relative_rpath)) { resolved_conflict = 1; } free(rpath); @@ -539,7 +562,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, FREELIST(conflicts); if(dbpkg) { /* only freed if it was generated from filelist_operation() */ - FREELIST(tmpfiles); + alpm_list_free(tmpfiles); } return NULL; } @@ -547,7 +570,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, } if(dbpkg) { /* only freed if it was generated from filelist_operation() */ - FREELIST(tmpfiles); + alpm_list_free(tmpfiles); } } PROGRESS(trans, PM_TRANS_PROGRESS_CONFLICTS_START, "", 100, diff --git a/lib/libalpm/conflict.h b/lib/libalpm/conflict.h index 6c13cb2..f2ab625 100644 --- a/lib/libalpm/conflict.h +++ b/lib/libalpm/conflict.h @@ -33,6 +33,9 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, void _alpm_fileconflict_free(alpm_fileconflict_t *conflict); +const alpm_file_t *_alpm_filelist_contains(const alpm_list_t *haystack, + const char *needle); + #endif /* _ALPM_CONFLICT_H */ /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/diskspace.c b/lib/libalpm/diskspace.c index 7ca72c3..5fb36eb 100644 --- a/lib/libalpm/diskspace.c +++ b/lib/libalpm/diskspace.c @@ -151,14 +151,15 @@ static alpm_mountpoint_t *match_mount_point(const alpm_list_t *mount_points, static int calculate_removed_size(alpm_handle_t *handle, const alpm_list_t *mount_points, alpm_pkg_t *pkg) { - alpm_list_t *file; + alpm_list_t *i; alpm_list_t *files = alpm_pkg_get_files(pkg); - for(file = files; file; file = file->next) { + for(i = files; i; i = i->next) { alpm_mountpoint_t *mp; struct stat st; char path[PATH_MAX]; - const char *filename = file->data; + const alpm_file_t *file = i->data; + const char *filename = file->name; snprintf(path, PATH_MAX, "%s%s", handle->root, filename); _alpm_lstat(path, &st); diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c index 21984b3..f69ba0b 100644 --- a/lib/libalpm/package.c +++ b/lib/libalpm/package.c @@ -427,6 +427,33 @@ alpm_list_t SYMEXPORT *alpm_pkg_compute_requiredby(alpm_pkg_t *pkg) /** @} */ +void _alpm_files_free(alpm_file_t *file) +{ + free(file->name); + free(file); +} + +alpm_file_t *_alpm_files_dup(const alpm_file_t *file) +{ + alpm_file_t *newfile; + CALLOC(newfile, 1, sizeof(alpm_file_t), return NULL); + + STRDUP(newfile->name, file->name, return NULL); + newfile->size = file->size; + newfile->mode = file->mode; + + return newfile; +} + +/* Helper function for comparing files list entries + */ +int _alpm_files_cmp(const void *f1, const void *f2) +{ + const alpm_file_t *file1 = f1; + const alpm_file_t *file2 = f2; + return strcmp(file1->name, file2->name); +} + alpm_pkg_t *_alpm_pkg_new(void) { alpm_pkg_t* pkg; @@ -466,7 +493,9 @@ alpm_pkg_t *_alpm_pkg_dup(alpm_pkg_t *pkg) newpkg->licenses = alpm_list_strdup(pkg->licenses); newpkg->replaces = alpm_list_strdup(pkg->replaces); newpkg->groups = alpm_list_strdup(pkg->groups); - newpkg->files = alpm_list_strdup(pkg->files); + for(i = pkg->files; i; i = alpm_list_next(i)) { + newpkg->files = alpm_list_add(newpkg->files, _alpm_files_dup(i->data)); + } for(i = pkg->backup; i; i = alpm_list_next(i)) { newpkg->backup = alpm_list_add(newpkg->backup, _alpm_backup_dup(i->data)); } @@ -516,7 +545,8 @@ void _alpm_pkg_free(alpm_pkg_t *pkg) FREELIST(pkg->licenses); FREELIST(pkg->replaces); FREELIST(pkg->groups); - FREELIST(pkg->files); + alpm_list_free_inner(pkg->files, (alpm_list_fn_free)_alpm_files_free); + alpm_list_free(pkg->files); alpm_list_free_inner(pkg->backup, (alpm_list_fn_free)_alpm_backup_free); alpm_list_free(pkg->backup); alpm_list_free_inner(pkg->depends, (alpm_list_fn_free)_alpm_dep_free); @@ -566,8 +596,8 @@ int _alpm_pkg_compare_versions(alpm_pkg_t *spkg, alpm_pkg_t *localpkg) */ int _alpm_pkg_cmp(const void *p1, const void *p2) { - alpm_pkg_t *pkg1 = (alpm_pkg_t *)p1; - alpm_pkg_t *pkg2 = (alpm_pkg_t *)p2; + const alpm_pkg_t *pkg1 = p1; + const alpm_pkg_t *pkg2 = p2; return strcoll(pkg1->name, pkg2->name); } diff --git a/lib/libalpm/package.h b/lib/libalpm/package.h index 772c2f6..b602193 100644 --- a/lib/libalpm/package.h +++ b/lib/libalpm/package.h @@ -139,6 +139,10 @@ struct __alpm_pkg_t { struct pkg_operations *ops; }; +void _alpm_files_free(alpm_file_t *file); +alpm_file_t *_alpm_files_dup(const alpm_file_t *file); +int _alpm_files_cmp(const void *f1, const void *f2); + alpm_pkg_t* _alpm_pkg_new(void); alpm_pkg_t *_alpm_pkg_dup(alpm_pkg_t *pkg); void _alpm_pkg_free(alpm_pkg_t *pkg); diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c index 86571a4..96382da 100644 --- a/lib/libalpm/remove.c +++ b/lib/libalpm/remove.c @@ -43,6 +43,7 @@ #include "db.h" #include "deps.h" #include "handle.h" +#include "conflict.h" int SYMEXPORT alpm_remove_pkg(alpm_handle_t *handle, alpm_pkg_t *pkg) { @@ -191,25 +192,25 @@ int _alpm_remove_prepare(alpm_handle_t *handle, alpm_list_t **data) return 0; } -static int can_remove_file(alpm_handle_t *handle, const char *path, +static int can_remove_file(alpm_handle_t *handle, const alpm_file_t *file, alpm_list_t *skip_remove) { - char file[PATH_MAX]; + char filepath[PATH_MAX]; - snprintf(file, PATH_MAX, "%s%s", handle->root, path); + snprintf(filepath, PATH_MAX, "%s%s", handle->root, file->name); - if(alpm_list_find_str(skip_remove, file)) { + if(alpm_list_find_str(skip_remove, filepath)) { /* return success because we will never actually remove this file */ return 1; } /* If we fail write permissions due to a read-only filesystem, abort. * Assume all other possible failures are covered somewhere else */ - if(access(file, W_OK) == -1) { - if(errno != EACCES && errno != ETXTBSY && access(file, F_OK) == 0) { + if(access(filepath, W_OK) == -1) { + if(errno != EACCES && errno != ETXTBSY && access(filepath, F_OK) == 0) { /* only return failure if the file ACTUALLY exists and we can't write to * it - ignore "chmod -w" simple permission failures */ _alpm_log(handle, PM_LOG_ERROR, _("cannot remove file '%s': %s\n"), - file, strerror(errno)); + filepath, strerror(errno)); return 0; } } @@ -219,18 +220,18 @@ static int can_remove_file(alpm_handle_t *handle, const char *path, /* Helper function for iterating through a package's file and deleting them * Used by _alpm_remove_commit. */ -static void unlink_file(alpm_handle_t *handle, alpm_pkg_t *info, const char *filename, - alpm_list_t *skip_remove, int nosave) +static void unlink_file(alpm_handle_t *handle, alpm_pkg_t *info, + const alpm_file_t *fileobj, alpm_list_t *skip_remove, int nosave) { struct stat buf; char file[PATH_MAX]; - snprintf(file, PATH_MAX, "%s%s", handle->root, filename); + snprintf(file, PATH_MAX, "%s%s", handle->root, fileobj->name); /* check the remove skip list before removing the file. * see the big comment block in db_find_fileconflicts() for an * explanation. */ - if(alpm_list_find_str(skip_remove, filename)) { + if(alpm_list_find_str(skip_remove, fileobj->name)) { _alpm_log(handle, PM_LOG_DEBUG, "%s is in skip_remove, skipping removal\n", file); return; @@ -254,7 +255,7 @@ static void unlink_file(alpm_handle_t *handle, alpm_pkg_t *info, const char *fil } } else { /* if the file needs backup and has been modified, back it up to .pacsave */ - alpm_backup_t *backup = _alpm_needbackup(filename, alpm_pkg_get_backup(info)); + alpm_backup_t *backup = _alpm_needbackup(fileobj->name, alpm_pkg_get_backup(info)); if(backup) { if(nosave) { _alpm_log(handle, PM_LOG_DEBUG, "transaction is set to NOSAVE, not backing up '%s'\n", file); @@ -277,7 +278,7 @@ static void unlink_file(alpm_handle_t *handle, alpm_pkg_t *info, const char *fil if(unlink(file) == -1) { _alpm_log(handle, PM_LOG_ERROR, _("cannot remove file '%s': %s\n"), - filename, strerror(errno)); + file, strerror(errno)); } } } @@ -309,7 +310,7 @@ int _alpm_upgraderemove_package(alpm_handle_t *handle, for(b = alpm_pkg_get_backup(newpkg); b; b = b->next) { const alpm_backup_t *backup = b->data; /* safety check (fix the upgrade026 pactest) */ - if(!alpm_list_find_str(filelist, backup->name)) { + if(!_alpm_filelist_contains(filelist, backup->name)) { continue; } _alpm_log(handle, PM_LOG_DEBUG, "adding %s to the skip_remove array\n", diff --git a/src/pacman/package.c b/src/pacman/package.c index 6b48087..c394bf9 100644 --- a/src/pacman/package.c +++ b/src/pacman/package.c @@ -218,7 +218,7 @@ void dump_pkg_backups(alpm_pkg_t *pkg) */ void dump_pkg_files(alpm_pkg_t *pkg, int quiet) { - const char *pkgname, *root, *filestr; + const char *pkgname, *root; alpm_list_t *i, *pkgfiles; pkgname = alpm_pkg_get_name(pkg); @@ -226,11 +226,11 @@ void dump_pkg_files(alpm_pkg_t *pkg, int quiet) root = alpm_option_get_root(config->handle); for(i = pkgfiles; i; i = alpm_list_next(i)) { - filestr = alpm_list_getdata(i); + const alpm_file_t *file = alpm_list_getdata(i); if(!quiet){ - fprintf(stdout, "%s %s%s\n", pkgname, root, filestr); + fprintf(stdout, "%s %s%s\n", pkgname, root, file->name); } else { - fprintf(stdout, "%s%s\n", root, filestr); + fprintf(stdout, "%s%s\n", root, file->name); } } diff --git a/src/pacman/query.c b/src/pacman/query.c index 826c226..1547c24 100644 --- a/src/pacman/query.c +++ b/src/pacman/query.c @@ -193,7 +193,8 @@ static int query_fileowner(alpm_list_t *targets) for(j = alpm_pkg_get_files(info); j && !found; j = alpm_list_next(j)) { char *ppath, *pdname; - const char *pkgfile = alpm_list_getdata(j); + const alpm_file_t *file = alpm_list_getdata(j); + const char *pkgfile = file->name; /* avoid the costly resolve_path usage if the basenames don't match */ if(strcmp(mbasename(pkgfile), bname) != 0) { @@ -416,7 +417,8 @@ static int check(alpm_pkg_t *pkg) const char *pkgname = alpm_pkg_get_name(pkg); for(i = alpm_pkg_get_files(pkg); i; i = alpm_list_next(i)) { struct stat st; - const char *path = alpm_list_getdata(i); + const alpm_file_t *file = alpm_list_getdata(i); + const char *path = file->name; if(rootlen + 1 + strlen(path) > PATH_MAX) { pm_fprintf(stderr, PM_LOG_WARNING, _("path too long: %s%s\n"), root, path); -- 1.7.6
Now that the filelists capture mode and size information, we can read the data from there and prevent having to loop through and uncompress every archive to check required diskspace usage. Signed-off-by: Dan McGee <dan@archlinux.org> --- lib/libalpm/diskspace.c | 48 ++++++---------------------------------------- 1 files changed, 7 insertions(+), 41 deletions(-) diff --git a/lib/libalpm/diskspace.c b/lib/libalpm/diskspace.c index 5fb36eb..b5d2ed2 100644 --- a/lib/libalpm/diskspace.c +++ b/lib/libalpm/diskspace.c @@ -39,10 +39,6 @@ #include <sys/types.h> #endif -/* libarchive */ -#include <archive.h> -#include <archive_entry.h> - /* libalpm */ #include "diskspace.h" #include "alpm_list.h" @@ -189,39 +185,19 @@ static int calculate_removed_size(alpm_handle_t *handle, static int calculate_installed_size(alpm_handle_t *handle, const alpm_list_t *mount_points, alpm_pkg_t *pkg) { - int ret=0; - struct archive *archive; - struct archive_entry *entry; - - if((archive = archive_read_new()) == NULL) { - handle->pm_errno = PM_ERR_LIBARCHIVE; - ret = -1; - goto cleanup; - } - - archive_read_support_compression_all(archive); - archive_read_support_format_all(archive); - - if(archive_read_open_filename(archive, pkg->origin_data.file, - ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) { - handle->pm_errno = PM_ERR_PKG_OPEN; - ret = -1; - goto cleanup; - } + alpm_list_t *i; - while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) { + for(i = alpm_pkg_get_files(pkg); i; i = i->next) { + const alpm_file_t *file = i->data; alpm_mountpoint_t *mp; - const char *filename; - mode_t mode; char path[PATH_MAX]; - filename = archive_entry_pathname(entry); - mode = archive_entry_mode(entry); + const char *filename = file->name; /* libarchive reports these as zero size anyways */ /* NOTE: if we do start accounting for directory size, a dir matching a * mountpoint needs to be attributed to the parent, not the mountpoint. */ - if(S_ISDIR(mode) || S_ISLNK(mode)) { + if(S_ISDIR(file->mode) || S_ISLNK(file->mode)) { continue; } @@ -241,21 +217,11 @@ static int calculate_installed_size(alpm_handle_t *handle, /* the addition of (divisor - 1) performs ceil() with integer division */ mp->blocks_needed += - (archive_entry_size(entry) + mp->fsp.f_bsize - 1l) / mp->fsp.f_bsize; + (file->size + mp->fsp.f_bsize - 1l) / mp->fsp.f_bsize; mp->used |= USED_INSTALL; - - if(archive_read_data_skip(archive)) { - _alpm_log(handle, PM_LOG_ERROR, _("error while reading package %s: %s\n"), - pkg->name, archive_error_string(archive)); - handle->pm_errno = PM_ERR_LIBARCHIVE; - break; - } } - archive_read_finish(archive); - -cleanup: - return ret; + return 0; } int _alpm_check_diskspace(alpm_handle_t *handle) -- 1.7.6
We can take advantage of a few things on our new and improved filelist in this code. Signed-off-by: Dan McGee <dan@archlinux.org> --- lib/libalpm/conflict.c | 34 ++++++++++++++-------------------- 1 files changed, 14 insertions(+), 20 deletions(-) diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c index 6ed9981..3a6fb76 100644 --- a/lib/libalpm/conflict.c +++ b/lib/libalpm/conflict.c @@ -385,7 +385,7 @@ static int dir_belongsto_pkg(const char *root, const char *dirpath, alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, alpm_list_t *upgrade, alpm_list_t *remove) { - alpm_list_t *i, *j, *conflicts = NULL; + alpm_list_t *i, *conflicts = NULL; size_t numtargs = alpm_list_count(upgrade); size_t current; alpm_trans_t *trans = handle->trans; @@ -399,14 +399,9 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, * here as we do when we actually extract files in add.c with our 12 * different cases. */ for(current = 0, i = upgrade; i; i = i->next, current++) { - alpm_list_t *k, *tmpfiles; - alpm_pkg_t *p1, *p2, *dbpkg; - char path[PATH_MAX]; - - p1 = i->data; - if(!p1) { - continue; - } + alpm_pkg_t *p1 = i->data; + alpm_list_t *j, *tmpfiles; + alpm_pkg_t *dbpkg; int percent = (current * 100) / numtargs; PROGRESS(trans, PM_TRANS_PROGRESS_CONFLICTS_START, "", percent, @@ -416,14 +411,13 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, alpm_pkg_get_name(p1)); for(j = i->next; j; j = j->next) { alpm_list_t *common_files; - p2 = j->data; - if(!p2) { - continue; - } + alpm_pkg_t *p2 = j->data; common_files = filelist_operation(alpm_pkg_get_files(p1), alpm_pkg_get_files(p2), INTERSECT); if(common_files) { + alpm_list_t *k; + char path[PATH_MAX]; for(k = common_files; k; k = k->next) { snprintf(path, PATH_MAX, "%s%s", handle->root, (char *)k->data); conflicts = add_fileconflict(handle, conflicts, @@ -459,12 +453,14 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, } for(j = tmpfiles; j; j = j->next) { - struct stat lsbuf; alpm_file_t *file = j->data; const char *filestr = file->name; const char *relative_path; + alpm_list_t *k; /* have we acted on this conflict? */ int resolved_conflict = 0; + struct stat lsbuf; + char path[PATH_MAX]; snprintf(path, PATH_MAX, "%s%s", handle->root, filestr); @@ -473,7 +469,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, continue; } - if(path[strlen(path) - 1] == '/') { + if(S_ISDIR(file->mode)) { struct stat sbuf; if(S_ISDIR(lsbuf.st_mode)) { _alpm_log(handle, PM_LOG_DEBUG, "%s is a directory, not a conflict\n", path); @@ -500,15 +496,14 @@ 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, PM_LOG_DEBUG, - "local file will be removed, not a conflict: %s\n", - relative_path); + "local file will be removed, not a conflict: %s\n", path); resolved_conflict = 1; } } /* Look at all the targets to see if file has changed hands */ for(k = upgrade; k && !resolved_conflict; k = k->next) { - p2 = k->data; + alpm_pkg_t *p2 = k->data; if(!p2 || strcmp(p1->name, p2->name) == 0) { continue; } @@ -522,8 +517,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, PM_LOG_DEBUG, - "file changed packages, adding to remove skiplist: %s\n", - filestr); + "file changed packages, adding to remove skiplist: %s\n", path); resolved_conflict = 1; } } -- 1.7.6
participants (1)
-
Dan McGee