diff --git a/utils/plist.c b/utils/plist.c index 262be0217fc..1088bdd498b 100644 --- a/utils/plist.c +++ b/utils/plist.c @@ -35,7 +35,7 @@ struct callback_args { const char *string; - int number; + int64_t number; }; bool @@ -176,6 +176,51 @@ xbps_get_pkgidx_string(const char *repofile) return res; } +bool +xbps_remove_pkg_dict_from_file(const char *pkg, const char *plist) +{ + prop_dictionary_t pdict; + prop_array_t array; + prop_object_t obj; + prop_object_iterator_t iter; + const char *curpkg; + int i = 0; + + pdict = prop_dictionary_internalize_from_file(plist); + if (pdict == NULL) + return false; + + array = prop_dictionary_get(pdict, "packages"); + if (array == NULL || prop_object_type(array) != PROP_TYPE_ARRAY) + return false; + + iter = prop_array_iterator(array); + if (iter == NULL) + return false; + + /* Iterate over the array of dictionaries to find its index. */ + while ((obj = prop_object_iterator_next(iter))) { + prop_dictionary_get_cstring_nocopy(obj, "pkgname", &curpkg); + if ((curpkg && (strcmp(curpkg, pkg) == 0))) { + /* Found, remove it and write plist file. */ + prop_array_remove(array, i); + prop_object_iterator_release(iter); + goto wr_plist; + } + i++; + } + + prop_object_iterator_release(iter); + errno = ENODEV; + return false; + +wr_plist: + if (!prop_dictionary_externalize_to_file(pdict, plist)) + return false; + + return true; +} + bool xbps_remove_string_from_array(prop_object_t obj, void *arg, bool *loop_done) { diff --git a/utils/plist.h b/utils/plist.h index 4bc4f38c04b..c38465965a0 100644 --- a/utils/plist.h +++ b/utils/plist.h @@ -115,6 +115,19 @@ xbps_get_array_iter_from_dict(prop_dictionary_t, const char *); bool xbps_register_repository(const char *); bool xbps_unregister_repository(const char *); +/* + * Remove package's dictionary from the "packages" array in + * the specified plist file. + * + * Arguments: + * - 1st const char *: package name. + * - 2nd const char *: full path to plist file. + * + * Returns true on success, or false and an appropiate errno value otherwise. + */ +bool +xbps_remove_pkg_dict_from_file(const char *, const char *); + /* * Shows information of a package by looking at its dictionary. * All known objects on it will be showed up. diff --git a/utils/xbps-pkgdb.c b/utils/xbps-pkgdb.c index 3f041bb9d7d..5cecb047f17 100644 --- a/utils/xbps-pkgdb.c +++ b/utils/xbps-pkgdb.c @@ -40,7 +40,6 @@ typedef struct pkg_data { static prop_dictionary_t make_dict_from_pkg(pkg_data_t *); static void register_pkg(prop_dictionary_t, pkg_data_t *, const char *); -static void unregister_pkg(prop_dictionary_t, const char *, const char *); static void write_plist_file(prop_dictionary_t, const char *); static prop_dictionary_t @@ -83,42 +82,6 @@ register_pkg(prop_dictionary_t dict, pkg_data_t *pkg, const char *dbfile) write_plist_file(dict, dbfile); } -static void -unregister_pkg(prop_dictionary_t dict, const char *pkgname, const char *dbfile) -{ - prop_array_t array; - prop_object_t obj; - prop_object_iterator_t iter; - const char *curpkgn; - int i = 0; - bool found = false; - - assert(dict != NULL || pkgname != NULL); - array = prop_dictionary_get(dict, "packages"); - assert(array != NULL); - assert(prop_object_type(array) == PROP_TYPE_ARRAY); - iter = prop_array_iterator(array); - assert(iter != NULL); - - /* Iterate over the array of dictionaries to find its index. */ - while ((obj = prop_object_iterator_next(iter))) { - prop_dictionary_get_cstring_nocopy(obj, "pkgname", &curpkgn); - if (strcmp(curpkgn, pkgname) == 0) { - found = true; - break; - } - i++; - } - - if (found == false) { - printf("=> ERROR: %s not registered in database.\n", pkgname); - exit(1); - } - - prop_array_remove(array, i); - write_plist_file(dict, dbfile); -} - static void write_plist_file(prop_dictionary_t dict, const char *file) { @@ -248,8 +211,16 @@ main(int argc, char **argv) if (argc != 4) usage(); - unregister_pkg(prop_dictionary_internalize_from_file(dbfile), - argv[2], dbfile); + if (!xbps_remove_pkg_dict_from_file(argv[2], dbfile)) { + if (errno == ENODEV) + printf("=> ERROR: %s not registered " + "in database.\n", argv[2]); + else + printf("=> ERROR: couldn't unregister %s " + "from database (%s)\n", argv[2], + strerror(errno)); + exit(EINVAL); + } printf("%s=> %s-%s unregistered successfully.\n", in_chroot ? "[chroot] " : "", argv[2], argv[3]);