/*- * Copyright (c) 2009-2012 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include "xbps_api_impl.h" prop_array_t xbps_find_pkg_obsoletes(struct xbps_handle *xhp, prop_dictionary_t instd, prop_dictionary_t newd) { prop_array_t array, array2, obsoletes; prop_object_t obj, obj2; prop_string_t oldstr, newstr; size_t i, x; const char *array_str = "files"; const char *oldhash; char *file; int rv = 0; bool found, dodirs, dolinks, docffiles; dodirs = dolinks = docffiles = false; assert(prop_object_type(instd) == PROP_TYPE_DICTIONARY); assert(prop_object_type(newd) == PROP_TYPE_DICTIONARY); obsoletes = prop_array_create(); assert(obsoletes); again: array = prop_dictionary_get(instd, array_str); if (array == NULL || prop_array_count(array) == 0) goto out1; /* * Iterate over files list from installed package. */ for (i = 0; i < prop_array_count(array); i++) { found = false; obj = prop_array_get(array, i); if (prop_object_type(obj) != PROP_TYPE_DICTIONARY) continue; oldstr = prop_dictionary_get(obj, "file"); if (oldstr == NULL) continue; file = xbps_xasprintf(".%s", prop_string_cstring_nocopy(oldstr)); if ((strcmp(array_str, "files") == 0) || (strcmp(array_str, "conf_files") == 0)) { prop_dictionary_get_cstring_nocopy(obj, "sha256", &oldhash); rv = xbps_file_hash_check(file, oldhash); if (rv == ENOENT || rv == ERANGE) { /* * Skip unexistent and files that do not * match the hash. */ free(file); continue; } } array2 = prop_dictionary_get(newd, array_str); if (array2 && prop_array_count(array2)) { for (x = 0; x < prop_array_count(array2); x++) { obj2 = prop_array_get(array2, x); newstr = prop_dictionary_get(obj2, "file"); assert(newstr); /* * Skip files with same path. */ if (prop_string_equals(oldstr, newstr)) { found = true; break; } } } if (found) { free(file); continue; } /* * Do not add required symlinks for the * system transition to /usr. */ if ((strcmp(file, "./bin") == 0) || (strcmp(file, "./bin/") == 0) || (strcmp(file, "./sbin") == 0) || (strcmp(file, "./sbin/") == 0) || (strcmp(file, "./lib") == 0) || (strcmp(file, "./lib/") == 0) || (strcmp(file, "./lib64/") == 0) || (strcmp(file, "./lib64") == 0)) { free(file); continue; } /* * Obsolete found, add onto the array. */ xbps_dbg_printf(xhp, "found obsolete: %s (%s)\n", file, array_str); prop_array_add_cstring(obsoletes, file); free(file); } out1: if (!dolinks) { dolinks = true; array_str = "links"; goto again; } else if (!docffiles) { docffiles = true; array_str = "conf_files"; goto again; } else if (!dodirs) { dodirs = true; array_str = "dirs"; goto again; } return obsoletes; }