[pacman-dev] [PATCH v2] pacman+libalpm: print version names for conflicting packages
When ever pacman prints a conflict, it now prints pkgname-version, instead of just pkgname. alpm_conflict_t now carries pointers to alpm_pkg_t instead of just the names of each package. Fixes FS#12536 (point 2) --- v2: dupe each alpm_pkg_t diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 956284bd..b0aa0671 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -247,10 +247,8 @@ typedef struct _alpm_depmissing_t { /** Conflict */ typedef struct _alpm_conflict_t { - unsigned long package1_hash; - unsigned long package2_hash; - char *package1; - char *package2; + alpm_pkg_t *package1; + alpm_pkg_t *package2; alpm_depend_t *reason; } alpm_conflict_t; diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c index 80827ed6..08ae86cb 100644 --- a/lib/libalpm/conflict.c +++ b/lib/libalpm/conflict.c @@ -49,11 +49,8 @@ static alpm_conflict_t *conflict_new(alpm_pkg_t *pkg1, alpm_pkg_t *pkg2, alpm_conflict_t *conflict; CALLOC(conflict, 1, sizeof(alpm_conflict_t), return NULL); - - conflict->package1_hash = pkg1->name_hash; - conflict->package2_hash = pkg2->name_hash; - STRDUP(conflict->package1, pkg1->name, goto error); - STRDUP(conflict->package2, pkg2->name, goto error); + ASSERT(_alpm_pkg_dup(pkg1, >package1) == 0, goto error); + ASSERT(_alpm_pkg_dup(pkg2, >package2) == 0, goto error); conflict->reason = reason; return conflict; @@ -69,8 +66,8 @@ error: void SYMEXPORT alpm_conflict_free(alpm_conflict_t *conflict) { ASSERT(conflict != NULL, return); - FREE(conflict->package2); - FREE(conflict->package1); + _alpm_pkg_free(conflict->package1); + _alpm_pkg_free(conflict->package2); FREE(conflict); } @@ -79,20 +76,7 @@ void SYMEXPORT alpm_conflict_free(alpm_conflict_t *conflict) */ alpm_conflict_t *_alpm_conflict_dup(const alpm_conflict_t *conflict) { - alpm_conflict_t *newconflict; - CALLOC(newconflict, 1, sizeof(alpm_conflict_t), return NULL); - - newconflict->package1_hash = conflict->package1_hash; - newconflict->package2_hash = conflict->package2_hash; - STRDUP(newconflict->package1, conflict->package1, goto error); - STRDUP(newconflict->package2, conflict->package2, goto error); - newconflict->reason = conflict->reason; - - return newconflict; - -error: - alpm_conflict_free(newconflict); - return NULL; + return conflict_new(conflict->package1, conflict->package2, conflict->reason); } /** @@ -108,10 +92,10 @@ static int conflict_isin(alpm_conflict_t *needle, alpm_list_t *haystack) alpm_list_t *i; for(i = haystack; i; i = i->next) { alpm_conflict_t *conflict = i->data; - if(needle->package1_hash == conflict->package1_hash - && needle->package2_hash == conflict->package2_hash - && strcmp(needle->package1, conflict->package1) == 0 - && strcmp(needle->package2, conflict->package2) == 0) { + if(needle->package1->name_hash == conflict->package2->name_hash + && needle->package2->name_hash == conflict->package2->name_hash + && strcmp(needle->package1->name, conflict->package1->name) == 0 + && strcmp(needle->package2->name, conflict->package2->name) == 0) { return 1; } } diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index 97a351fe..d26a1323 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -510,21 +510,23 @@ int _alpm_sync_prepare(alpm_handle_t *handle, alpm_list_t **data) for(i = deps; i; i = i->next) { alpm_conflict_t *conflict = i->data; + const char *name1 = conflict->package1->name; + const char *name2 = conflict->package2->name; alpm_pkg_t *rsync, *sync, *sync1, *sync2; /* have we already removed one of the conflicting targets? */ - sync1 = alpm_pkg_find(trans->add, conflict->package1); - sync2 = alpm_pkg_find(trans->add, conflict->package2); + sync1 = alpm_pkg_find(trans->add, name1); + sync2 = alpm_pkg_find(trans->add, name2); if(!sync1 || !sync2) { continue; } _alpm_log(handle, ALPM_LOG_DEBUG, "conflicting packages in the sync list: '%s' <-> '%s'\n", - conflict->package1, conflict->package2); + name1, name2); /* if sync1 provides sync2, we remove sync2 from the targets, and vice versa */ -
[pacman-dev] [PATCH 2/2] remove: Don't follow symlinks in checking if a file can be removed
Otherwise, symlinks to non-removable files will be logged as unable to be removed. Signed-off-by: Ryan Gonzalez --- lib/libalpm/remove.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c index 9030bfee..bb980e7d 100644 --- a/lib/libalpm/remove.c +++ b/lib/libalpm/remove.c @@ -339,7 +339,7 @@ static int can_remove_file(alpm_handle_t *handle, const alpm_file_t *file) /* If we fail write permissions due to a read-only filesystem, abort. * Assume all other possible failures are covered somewhere else */ - if(_alpm_access(handle, NULL, filepath, W_OK) == -1) { + if(_alpm_access_flags(handle, NULL, filepath, W_OK, AT_SYMLINK_NOFOLLOW) == -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 */ -- 2.23.0
[pacman-dev] [PATCH 1/2] util: Add _alpm_access_flags
This changes _alpm_access* to use faccessat, which allows behavior flags to be passed. Signed-off-by: Ryan Gonzalez --- lib/libalpm/util.c | 18 -- lib/libalpm/util.h | 2 ++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c index a4d62c7c..8d653b16 100644 --- a/lib/libalpm/util.c +++ b/lib/libalpm/util.c @@ -1333,16 +1333,22 @@ alpm_time_t _alpm_parsedate(const char *line) return (alpm_time_t)result; } -/** Wrapper around access() which takes a dir and file argument +int _alpm_access(alpm_handle_t *handle, const char *dir, const char *file, int amode) { + return _alpm_access_flags(handle, dir, file, amode, 0); +} + +/** Wrapper around faccessat() which takes a dir and file argument * separately and generates an appropriate error message. * If dir is NULL file will be treated as the whole path. * @param handle an alpm handle * @param dir directory path ending with and slash * @param file filename - * @param amode access mode as described in access() - * @return int value returned by access() + * @param amode access mode as described in faccessat() + * @param flags flags to pass as described in faccessat() + * @return int value returned by faccessat() */ -int _alpm_access(alpm_handle_t *handle, const char *dir, const char *file, int amode) +int _alpm_access_flags(alpm_handle_t *handle, const char *dir, const char *file, int amode, + int flags) { size_t len = 0; int ret = 0; @@ -1354,11 +1360,11 @@ int _alpm_access(alpm_handle_t *handle, const char *dir, const char *file, int a CALLOC(check_path, len, sizeof(char), RET_ERR(handle, ALPM_ERR_MEMORY, -1)); snprintf(check_path, len, "%s%s", dir, file); - ret = access(check_path, amode); + ret = faccessat(AT_FDCWD, check_path, amode, flags); free(check_path); } else { dir = ""; - ret = access(file, amode); + ret = faccessat(AT_FDCWD, file, amode, flags); } if(ret != 0) { diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h index 71dadc2c..1af79571 100644 --- a/lib/libalpm/util.h +++ b/lib/libalpm/util.h @@ -143,6 +143,8 @@ alpm_time_t _alpm_parsedate(const char *line); int _alpm_raw_cmp(const char *first, const char *second); int _alpm_raw_ncmp(const char *first, const char *second, size_t max); int _alpm_access(alpm_handle_t *handle, const char *dir, const char *file, int amode); +int _alpm_access_flags(alpm_handle_t *handle, const char *dir, const char *file, int amode, + int flags); int _alpm_fnmatch_patterns(alpm_list_t *patterns, const char *string); int _alpm_fnmatch(const void *pattern, const void *string); void *_alpm_realloc(void **data, size_t *current, const size_t required); -- 2.23.0
Re: [pacman-dev] [PATCH 2/3] libmakepkg: use readelf instead of file for finding ELF file types
On 11/27/19 12:32 PM, Ethan Sommer wrote: >>> --- a/scripts/libmakepkg/tidy/strip.sh.in >>> +++ b/scripts/libmakepkg/tidy/strip.sh.in >>> @@ -111,22 +111,20 @@ tidy_strip() { >>> >>> local binary strip_flags >>> find . -type f -perm -u+w -print0 2>/dev/null | while IFS= >>> read -rd '' binary ; do >>> - case "$(file -bi "$binary")" in >>> - *application/x-sharedlib*) # Libraries (.so) >>> + case "$(LC_ALL=C readelf -h "$binary" 2>/dev/null)" in >> >> More squelching of errors. > The error redirection to null is because readelf outputs an error when > the file it is run on isn't an ELF file at all, and obviously that error > is unwanted. Right, we just want all the other errors. >> Incidentally, is the output of this, documented, or can it arbitrarily >> change in the future? file is guaranteed to emit output in the >> RFC-documented IANA media type format. > These file types and their specification in the file header are part of > the ELF spec Let's pretend I stated from the beginning that I trust the readelf program to be able to also interpret future revisions of the file format. > , and the readelf output has remained consistent, at least > the part that matters to us, and the relevant part is the same across 4 > different implementations, and I doubt there will be some change of the > word 'Type:' being used, given that the ELF specification refers to those > file types as 'types'. I'll take that as a "no, but it's worked for long enough they probably won't change it now". Which I suppose is not so unreasonable... -- Eli Schwartz Bug Wrangler and Trusted User signature.asc Description: OpenPGP digital signature
[pacman-dev] [PATCH v2] pacman: print error when -Fx is given invalid regex
When processing the targets for -Fx, compile all the regex ahead of time, printing an error for each that failed to compile. Then, if they all compiled successfully, continue with printing files. Signed-off-by: morganamilo --- v2: Add comment about why we don't free targ Fix whitespace error I have vim set to display trialing whitespace so normally I catch it. Not sure why I didn't this time. Also I agree that running all the regex against each target before moving on to the next is a good improvement. This patch is already kinda long though, so I'll do it another time. diff --git a/src/pacman/files.c b/src/pacman/files.c index 3b6dc23b..6fcc6e9b 100644 --- a/src/pacman/files.c +++ b/src/pacman/files.c @@ -94,17 +94,27 @@ static void print_match(alpm_list_t *match, alpm_db_t *repo, alpm_pkg_t *pkg, in } } +struct filetarget { + char *targ; + int exact_file; + regex_t reg; +}; + +static void filetarget_free(struct filetarget *ftarg) { + regfree(>reg); + /* we don't own ftarg->targ so don't free it */ + free(ftarg); +} + static int files_search(alpm_list_t *syncs, alpm_list_t *targets, int regex) { int ret = 0; - alpm_list_t *t; + alpm_list_t *t, *filetargs = NULL; for(t = targets; t; t = alpm_list_next(t)) { char *targ = t->data; - alpm_list_t *s; - int found = 0; - regex_t reg; size_t len = strlen(targ); int exact_file = strchr(targ, '/') != NULL; + regex_t reg; if(exact_file) { while(len > 1 && targ[0] == '/') { @@ -115,11 +125,33 @@ static int files_search(alpm_list_t *syncs, alpm_list_t *targets, int regex) { if(regex) { if(regcomp(, targ, REG_EXTENDED | REG_NOSUB | REG_ICASE | REG_NEWLINE) != 0) { - /* TODO: error message */ - goto notfound; + pm_printf(ALPM_LOG_ERROR, + _("invalid regular expression '%s'\n"), targ); + ret = 1; + continue; } } + struct filetarget *ftarg = malloc(sizeof(struct filetarget)); + ftarg->targ = targ; + ftarg->exact_file = exact_file; + ftarg->reg = reg; + + filetargs = alpm_list_add(filetargs, ftarg); + } + + if(ret != 0) { + goto cleanup; + } + + for(t = filetargs; t; t = alpm_list_next(t)) { + struct filetarget *ftarg = t->data; + char *targ = ftarg->targ; + regex_t *reg = >reg; + int exact_file = ftarg->exact_file; + alpm_list_t *s; + int found = 0; + for(s = syncs; s; s = alpm_list_next(s)) { alpm_list_t *p; alpm_db_t *repo = s->data; @@ -135,7 +167,7 @@ static int files_search(alpm_list_t *syncs, alpm_list_t *targets, int regex) { if (regex) { for(size_t f = 0; f < files->count; f++) { char *c = files->files[f].name; - if(regexec(, c, 0, 0, 0) == 0) { + if(regexec(reg, c, 0, 0, 0) == 0) { match = alpm_list_add(match, files->files[f].name); found = 1; } @@ -151,7 +183,7 @@ static int files_search(alpm_list_t *syncs, alpm_list_t *targets, int regex) { char *c = strrchr(files->files[f].name, '/'); if(c && *(c + 1)) { if(regex) { - m = regexec(, (c + 1), 0, 0, 0); + m = regexec(reg, (c + 1), 0, 0, 0); } else { m = strcmp(c + 1, targ); } @@ -170,16 +202,15 @@ static int files_search(alpm_list_t *syncs, alpm_list_t *targets, int regex) { } } - if(regex) { - regfree(); - } - -notfound: if(!found) { ret = 1; } }
Re: [pacman-dev] [PATCH 2/3] libmakepkg: use readelf instead of file for finding ELF file types
> > --- a/scripts/libmakepkg/tidy/strip.sh.in > > +++ b/scripts/libmakepkg/tidy/strip.sh.in > > @@ -111,22 +111,20 @@ tidy_strip() { > > > > local binary strip_flags > > find . -type f -perm -u+w -print0 2>/dev/null | while IFS= > > read -rd '' binary ; do > > - case "$(file -bi "$binary")" in > > - *application/x-sharedlib*) # Libraries (.so) > > + case "$(LC_ALL=C readelf -h "$binary" 2>/dev/null)" in > > More squelching of errors. The error redirection to null is because readelf outputs an error when the file it is run on isn't an ELF file at all, and obviously that error is unwanted. > Incidentally, is the output of this, documented, or can it arbitrarily > change in the future? file is guaranteed to emit output in the > RFC-documented IANA media type format. These file types and their specification in the file header are part of the ELF spec, and the readelf output has remained consistent, at least the part that matters to us, and the relevant part is the same across 4 different implementations, and I doubt there will be some change of the word 'Type:' being used, given that the ELF specification refers to those file types as 'types'.
Re: [pacman-dev] [PATCH 2/3] libmakepkg: use readelf instead of file for finding ELF file types
On 11/26/19 4:29 PM, Ethan Sommer wrote: > Signed-off-by: Ethan Sommer > --- > scripts/libmakepkg/tidy/strip.sh.in | 26 -- > 1 file changed, 12 insertions(+), 14 deletions(-) > > diff --git a/scripts/libmakepkg/tidy/strip.sh.in > b/scripts/libmakepkg/tidy/strip.sh.in > index 1bd810f0..301d1989 100644 > --- a/scripts/libmakepkg/tidy/strip.sh.in > +++ b/scripts/libmakepkg/tidy/strip.sh.in > @@ -111,22 +111,20 @@ tidy_strip() { > > local binary strip_flags > find . -type f -perm -u+w -print0 2>/dev/null | while IFS= read > -rd '' binary ; do > - case "$(file -bi "$binary")" in > - *application/x-sharedlib*) # Libraries (.so) > + case "$(LC_ALL=C readelf -h "$binary" 2>/dev/null)" in More squelching of errors. Incidentally, is the output of this, documented, or can it arbitrarily change in the future? file is guaranteed to emit output in the RFC-documented IANA media type format. > + *Type:*'DYN (Shared object file)'*) # Libraries > (.so) or Relocatable binaries > strip_flags="$STRIP_SHARED";; > - *application/x-archive*)# Libraries (.a) > - strip_flags="$STRIP_STATIC";; > - *application/x-object*) > - case "$binary" in > - *.ko) # > Kernel module > - > strip_flags="$STRIP_SHARED";; > - *) > - continue;; > - esac;; > - *application/x-executable*) # Binaries > + *Type:*'EXEC (Executable file)'*) # Binaries > strip_flags="$STRIP_BINARIES";; > - *application/x-pie-executable*) # Relocatable > binaries > - strip_flags="$STRIP_SHARED";; > + *Type:*'REL (Relocatable file)'*) # Libraries > (.a) or objects > + if ar t "$binary" &>/dev/null; then # > Libraries (.a) > + strip_flags="$STRIP_STATIC" > + elif [[ $binary = *'.ko' ]]; then # > Kernel module > + strip_flags="$STRIP_SHARED" > + else > + continue > + fi > + ;; > *) > continue ;; > esac > -- Eli Schwartz Bug Wrangler and Trusted User signature.asc Description: OpenPGP digital signature
Re: [pacman-dev] [PATCH 1/3] libmakepkg: use extraction commands instead of file to find archive type
On 11/26/19 4:29 PM, Ethan Sommer wrote: > Previously, to determine which command we should use to extract an > archive, we would run file and match the output against our list of > possible extraction commands > > Instead, run the archive through each extraction command's -t (--test) > flag, if this succeeds then we know that the command is able to extract > the file and is the one to use Missing rationale why we care. > scripts/libmakepkg/source/file.sh.in | 39 > 1 file changed, 11 insertions(+), 28 deletions(-) > > diff --git a/scripts/libmakepkg/source/file.sh.in > b/scripts/libmakepkg/source/file.sh.in > index 7297a1c6..faace79b 100644 > --- a/scripts/libmakepkg/source/file.sh.in > +++ b/scripts/libmakepkg/source/file.sh.in > @@ -96,35 +96,18 @@ extract_file() { > fi > > # do not rely on extension for file type > - local file_type=$(@FILECMD@ -bizL -- "$file") > - local ext=${file##*.} > local cmd='' > - case "$file_type" in > - > *application/x-tar*|*application/zip*|*application/x-zip*|*application/x-cpio*) > - cmd="bsdtar" ;; > - *application/x-gzip*|*application/gzip*) > - case "$ext" in > - gz|z|Z) cmd="gzip" ;; > - *) return;; > - esac ;; > - *application/x-bzip*) > - case "$ext" in > - bz2|bz) cmd="bzip2" ;; > - *) return;; > - esac ;; > - *application/x-xz*) > - case "$ext" in > - xz) cmd="xz" ;; > - *) return;; > - esac ;; > - *) > - # See if bsdtar can recognize the file > - if bsdtar -tf "$file" -q '*' &>/dev/null; then > - cmd="bsdtar" > - else > - return 0 > - fi ;; > - esac > + if bsdtar -tf "$file" -q '*'; then > + cmd='bsdtar' > + elif gzip -t "$file"; then > + cmd='gzip' > + elif bzip2 -t "$file"; then > + cmd='bzip2' > + elif xz -t "$file"; then > + cmd='xz' > + else > + return 0 > + fi &>/dev/null I had to look at this three times before I realized you were redirecting both stdout and stderr of the entire if/elif block. Because these commands check to see if the file is "uncorrupted", not to see if they are "formatted in this compression format", I imagine this would falsely fail files if they have some class of recoverable error, but I'm not sure if we care. What we do care about, I think, is that you're silencing stderr due to the fact that it will noisily print diagnostic messages when the file is not compressed or is in a different compression format, and bsdtar will print listed filenames to stdout. So now, if these commands fail for *any* reason, we treat this as a successful analysis that the file is in a different format. One reason for it failing might be that xz is not installed... this is hardly a successful analysis, and printing an "error: command not found" message during the decompression, then dying with "Failed to extract %s" is a desirable feature. > local ret=0 > msg2 "$(gettext "Extracting %s with %s")" "$file" "$cmd" > -- Eli Schwartz Bug Wrangler and Trusted User signature.asc Description: OpenPGP digital signature