Index: usr.sbin/pkg_install/lib/plist.c =================================================================== --- usr.sbin/pkg_install/lib/plist.c (revision 185325) +++ usr.sbin/pkg_install/lib/plist.c (working copy) @@ -544,45 +544,90 @@ delete_package(Boolean ign_err, Boolean nukedirs, int delete_hierarchy(const char *dir, Boolean ign_err, Boolean nukedirs) { - char *cp1, *cp2; + char *cp1, *cp2, *realdir; - cp1 = cp2 = strdup(dir); - if (!fexists(dir)) { + realdir = malloc(FILENAME_MAX); + if (realdir == NULL) { + warnx("Couldn't allocate enough memory\n"); + return (ign_err ? SUCCESS : FAIL); + } + + if (issymlink(dir) && readlink(dir, realdir, FILENAME_MAX-1) == -1) + return (ign_err ? SUCCESS : FAIL); + + strlcpy(realdir, dir, FILENAME_MAX); + + cp1 = cp2 = strdup(realdir); + if (cp1 == NULL) { + warnx("Couldn't allocate enough memory\n"); + return (ign_err ? SUCCESS : FAIL); + } + + if (!fexists(realdir)) { if (!ign_err) warnx("%s '%s' doesn't exist", - isdir(dir) ? "directory" : "file", dir); - return !ign_err; + isdir(realdir) ? "directory" : "file", realdir); + free(cp1); + free(realdir); + return (ign_err ? SUCCESS : FAIL); } else if (nukedirs) { - if (vsystem("%s -r%s %s", REMOVE_CMD, (ign_err ? "f" : ""), dir)) - return 1; + if (vsystem("%s -r%s %s", REMOVE_CMD, (ign_err ? "f" : ""), realdir)) { + free(cp1); + free(realdir); + return (ign_err ? SUCCESS : FAIL); + } } - else if (isdir(dir) && !issymlink(dir)) { - if (RMDIR(dir) && !ign_err) - return 1; + else if (isdir(realdir)) { + if (RMDIR(realdir)) { + free(cp1); + free(realdir); + return (ign_err ? SUCCESS : FAIL); + } } else { - if (REMOVE(dir, ign_err)) - return 1; + if (REMOVE(realdir, ign_err)) { + free(cp1); + free(realdir); + return (ign_err ? SUCCESS : FAIL); + } } - if (!nukedirs) - return 0; + if (!nukedirs) { + free(cp1); + free(realdir); + return (SUCCESS); + } while (cp2) { if ((cp2 = strrchr(cp1, '/')) != NULL) *cp2 = '\0'; - if (!isemptydir(dir)) - return 0; - if (RMDIR(dir) && !ign_err) { - if (!fexists(dir)) - warnx("directory '%s' doesn't exist", dir); - else - return 1; + if (!isemptydir(realdir)) { + free(cp1); + free(realdir); + return (SUCCESS); } + if (RMDIR(realdir) && !ign_err) { + if (!fexists(realdir)) { + warnx("directory '%s' doesn't exist", realdir); + return (SUCCESS); + } else { + free(cp1); + free(realdir); + return (FAIL); + } + } /* back up the pathname one component */ if (cp2) { - cp1 = strdup(dir); + free(cp1); + cp1 = strdup(realdir); + if (cp1 == NULL) { + warnx("Couldn't allocate enough memory\n"); + return (ign_err ? SUCCESS : FAIL); + } } } - return 0; + free(cp1); + free(realdir); + return (SUCCESS); } +