Improve detection of target file in relative symlinks.

If xbps-create(8) did not guess the target file of relative symlinks for
some reason, just compare the current symlink and what's stored as is,
without converting it to absolute.

This might happen with dangling relative symlinks or existing binary
packages that were not created with a newer xbps-create(8).
This commit is contained in:
Juan RP 2015-02-19 10:24:24 +01:00
parent 05f879ec09
commit 67eba7d912
4 changed files with 20 additions and 9 deletions

View File

@ -77,7 +77,7 @@ check_pkg_symlinks(struct xbps_handle *xhp, const char *pkgname, void *arg)
continue; continue;
} }
snprintf(path, sizeof(path), "%s/%s", xhp->rootdir, file); snprintf(path, sizeof(path), "%s/%s", xhp->rootdir, file);
if ((lnk = xbps_symlink_target(xhp, path)) == NULL) { if ((lnk = xbps_symlink_target(xhp, path, tgt)) == NULL) {
xbps_error_printf("%s: broken symlink %s (target: %s)\n", pkgname, file, tgt); xbps_error_printf("%s: broken symlink %s (target: %s)\n", pkgname, file, tgt);
broken = true; broken = true;
continue; continue;

View File

@ -48,7 +48,7 @@
* *
* This header documents the full API for the XBPS Library. * This header documents the full API for the XBPS Library.
*/ */
#define XBPS_API_VERSION "20150219" #define XBPS_API_VERSION "20150219-1"
#ifndef XBPS_VERSION #ifndef XBPS_VERSION
#define XBPS_VERSION "UNSET" #define XBPS_VERSION "UNSET"
@ -1937,7 +1937,7 @@ char *xbps_pubkey2fp(struct xbps_handle *xhp, xbps_data_t pubkey);
* Returns a buffer with a sanitized path from \a src. * Returns a buffer with a sanitized path from \a src.
* This removes multiple slashes. * This removes multiple slashes.
* *
* @param[in] src A path. * @param[in] src path component.
* *
* @return The sanitized path in a buffer. * @return The sanitized path in a buffer.
* The returned buffer must be free(3)d when it's no longer necessary. * The returned buffer must be free(3)d when it's no longer necessary.
@ -1948,12 +1948,14 @@ char *xbps_sanitize_path(const char *src);
* Returns a sanitized target file of \a path without the rootdir component. * Returns a sanitized target file of \a path without the rootdir component.
* *
* @param[in] xhp The pointer to an xbps_handle struct. * @param[in] xhp The pointer to an xbps_handle struct.
* @param[in] path A path to a filename. * @param[in] path path component.
* @param[in] target The stored target file of a symlink.
* *
* @return The sanitized path in a buffer. * @return The sanitized path in a buffer.
* The returned buffer must be free(3)d when it's no longer necessary. * The returned buffer must be free(3)d when it's no longer necessary.
*/ */
char *xbps_symlink_target(struct xbps_handle *xhp, const char *path); char *xbps_symlink_target(struct xbps_handle *xhp, const char *path,
const char *target);
/*@}*/ /*@}*/

View File

@ -211,14 +211,14 @@ remove_pkg_files(struct xbps_handle *xhp,
const char *target = NULL; const char *target = NULL;
char *lnk; char *lnk;
lnk = xbps_symlink_target(xhp, path); xbps_dictionary_get_cstring_nocopy(obj, "target", &target);
assert(target);
lnk = xbps_symlink_target(xhp, path, target);
if (lnk == NULL) { if (lnk == NULL) {
xbps_dbg_printf(xhp, "[remove] %s " xbps_dbg_printf(xhp, "[remove] %s "
"symlink_target: %s\n", path, strerror(errno)); "symlink_target: %s\n", path, strerror(errno));
continue; continue;
} }
xbps_dictionary_get_cstring_nocopy(obj, "target", &target);
assert(target);
if (strcmp(lnk, target)) { if (strcmp(lnk, target)) {
xbps_dbg_printf(xhp, "[remove] %s symlink " xbps_dbg_printf(xhp, "[remove] %s symlink "
"modified (stored %s current %s)\n", path, "modified (stored %s current %s)\n", path,

View File

@ -454,7 +454,7 @@ xbps_sanitize_path(const char *src)
} }
char * char *
xbps_symlink_target(struct xbps_handle *xhp, const char *path) xbps_symlink_target(struct xbps_handle *xhp, const char *path, const char *tgt)
{ {
struct stat sb; struct stat sb;
char *p, *p1, *dname, *res = NULL, *lnk = NULL; char *p, *p1, *dname, *res = NULL, *lnk = NULL;
@ -472,6 +472,15 @@ xbps_symlink_target(struct xbps_handle *xhp, const char *path)
return NULL; return NULL;
} }
lnk[sb.st_size] = '\0'; lnk[sb.st_size] = '\0';
if (tgt[0] != '/') {
/*
* target file is relative and wasn't converted to absolute by
* xbps-create(8), just compare it as is.
*/
return lnk;
}
if (strstr(lnk, "./") || lnk[0] != '/') { if (strstr(lnk, "./") || lnk[0] != '/') {
/* relative */ /* relative */
p = strdup(path); p = strdup(path);