From 9673c4bd09f3ba840c678239c5d9862be834e9f3 Mon Sep 17 00:00:00 2001 From: Juan RP Date: Sat, 4 Jun 2011 13:37:53 +0200 Subject: [PATCH] XBPS major changes in June 2011. - A configuration file "xbps-conf.plist" replaces the (un)register target in xbps-repo(8) and (un)set-prop in xbps-bin(8). For now, you can set the repositories and prefered virtual packages. - New package pattern matching code from NetBSD. Supports more ways of matching patterns in packages. - Multiple bugs fixed in virtual packages related matching code. --HG-- rename : LICENSE => COPYING --- 3RDPARTY | 10 +- COPYING | 173 +++++++++++++++++ LICENSE | 22 --- Makefile | 6 +- NEWS | 23 ++- TODO | 2 - bin/xbps-bin/check.c | 11 +- bin/xbps-bin/find-files.c | 2 +- bin/xbps-bin/main.c | 61 ++---- bin/xbps-bin/show-info-files.c | 19 +- bin/xbps-bin/util.c | 8 +- bin/xbps-bin/xbps-bin.8 | 79 ++------ bin/xbps-repo/defs.h | 2 - bin/xbps-repo/find-files.c | 2 +- bin/xbps-repo/main.c | 52 +++-- bin/xbps-repo/repository.c | 140 +------------- bin/xbps-repo/xbps-repo.8 | 36 ++-- bin/xbps-uhelper/main.c | 22 ++- configure | 7 + etc/Makefile | 19 ++ etc/xbps-conf.plist | 53 ++++++ include/xbps_api.h | 154 +++++---------- include/xbps_api_impl.h | 24 +++ lib/Makefile | 6 +- lib/cmpver.c | 1 - lib/compat/strlcpy.c | 2 +- lib/dewey.c | 337 +++++++++++++++++++++++++++++++++ lib/download.c | 1 - lib/fexec.c | 1 - lib/initend.c | 50 ++++- lib/match.c | 161 ++++++++++++++++ lib/mkpath.c | 1 - lib/package_config_files.c | 1 - lib/package_configure.c | 15 +- lib/package_orphans.c | 18 +- lib/package_properties.c | 272 -------------------------- lib/package_purge.c | 52 ++--- lib/package_register.c | 1 - lib/package_remove.c | 1 - lib/package_remove_obsoletes.c | 1 - lib/package_replaces.c | 13 +- lib/package_requiredby.c | 1 - lib/package_state.c | 1 - lib/package_unpack.c | 1 - lib/pkgmatch.c | 188 ------------------ lib/plist.c | 1 - lib/plist_archive_entry.c | 3 +- lib/plist_fetch.c | 1 - lib/plist_find.c | 80 ++++---- lib/plist_remove.c | 1 - lib/regpkgdb_dictionary.c | 50 ++--- lib/repository_finddeps.c | 29 +-- lib/repository_findpkg.c | 41 +--- lib/repository_pool.c | 109 +++++------ lib/repository_register.c | 202 -------------------- lib/repository_sync_index.c | 1 - lib/transaction_dictionary.c | 1 - lib/transaction_sortdeps.c | 26 ++- lib/util.c | 2 +- 59 files changed, 1183 insertions(+), 1416 deletions(-) create mode 100644 COPYING delete mode 100644 LICENSE create mode 100644 etc/Makefile create mode 100644 etc/xbps-conf.plist create mode 100644 lib/dewey.c create mode 100644 lib/match.c delete mode 100644 lib/package_properties.c delete mode 100644 lib/pkgmatch.c delete mode 100644 lib/repository_register.c diff --git a/3RDPARTY b/3RDPARTY index a257c305..2c4a90ed 100644 --- a/3RDPARTY +++ b/3RDPARTY @@ -1,7 +1,9 @@ XBPS includes the following software from third parties for internal use in the code: -- pkgmatch code from FreeBSD. -- strlcat and strlcpy functions from OpenBSD. -- libfetch-2.31 from NetBSD. -- portableproplib-0.4.1 from http://code.google.com/p/portableproplib +- queue.h from NetBSD (include/queue.h). +- package pattern matching code from NetBSD (lib/dewey.c lib/match.c). +- strlcat and strlcpy functions from OpenBSD (lib/compat/strlc{at,cpy}.c) +- libfetch-2.31 from NetBSD (lib/fetch). +- portableproplib-0.4.1 (lib/portableproplib) from + http://code.google.com/p/portableproplib diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..54911b45 --- /dev/null +++ b/COPYING @@ -0,0 +1,173 @@ +Almost all code in XBPS uses the following license +(some exceptions are shown below): + +/* Copyright (c) 2008-2011 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. + */ + +This product uses some code with the following license +(lib/mkpath.c, include/queue.h): + +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. 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. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. + * + * @(#)queue.h 8.5 (Berkeley) 8/20/94 + */ + +This product uses some code with the following license (lib/dewey.c): + +/* + * Copyright © 2002 Alistair G. Crooks. 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. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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. + */ + +This product uses some code with the following license +(lib/download.c, lib/fetch): + +/*- + * Copyright (c) 2000-2004 Dag-Erling Coïdan Smørgrav + * 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 + * in this position and unchanged. + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * 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. + */ + +This product uses some code with the following license +(lib/compat/strlc{at,py}.c): + +/* + * Copyright (c) 1998 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +This product uses some code with the following license +(lib/humanize_number.c, lib/fexec.c): + +/* + * Copyright (c) 2003 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, + * NASA Ames Research Center, by Luke Mewburn and by Tomas Svensson. + * + * 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``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 FOUNDATION OR CONTRIBUTORS + * 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. + */ diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 122f9b27..00000000 --- a/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ - Copyright (c) 2008-2011 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. diff --git a/Makefile b/Makefile index a7005f00..87b10868 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ -include config.mk -SUBDIRS = include lib bin +SUBDIRS = include lib bin etc ifdef BUILD_API_DOCS SUBDIRS += doc @@ -20,8 +20,10 @@ install: @echo @echo "Binaries have been installed into $(DESTDIR)$(SBINDIR)." @echo "Librares have been installed into $(DESTDIR)$(LIBDIR)." + @echo "Configuration file has been installed into $(DESTDIR)$(ETCDIR)." @echo - @echo "WARNING: Don't forget to rerun ldconfig(1)." + @echo "WARNING: Don't forget to rerun ldconfig(1) if $(LIBDIR) is not" + @echo "WARNING: in your ld.so.conf by default." @echo .PHONY: uninstall diff --git a/NEWS b/NEWS index 75494cd9..912edbdf 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,26 @@ xbps-0.9.0 (???): - * API/ABI break. Renamed some functions to reflect its description - a bit better... expect some more breakage in the future as well. + * Fixed some bugs with virtual packages, to not adding duplicate package + dictionaries in the transaction dictionary. + + * xbps-bin(8)/xbps-repo(8): the 'show-files' target now prints the target + file on symlinks, i.e: "/sbin/foo -> /sbin/blah". + + * Changed the package pattern match code to the one available on NetBSD. + It's much better and provides more alternative pattern matching options. + + * A new configuration file in plist format to specify repositories and + virtual packages has been created, defaults to "/etc/xbps-conf.plist". + That means that you no longer need to register/unregister repositories; + just add your favourite local or remote repository and the first time + XBPS needs to access the pkg-index file it will be downloaded. + + More options and properties will be added to the configuration file in + the future. By default we use the official public remote repository, + and "dcron" package for a cron daemon package. + + The ABI/API is not compatible anymore with previous versions, you've + been advised :-) * xbps-bin(8): the 'check' target now also checks for modified symlinks, and warns if any of them has been modified. For this to work, the package diff --git a/TODO b/TODO index 91c48c56..839da06e 100644 --- a/TODO +++ b/TODO @@ -1,8 +1,6 @@ - conflicts: the object is there but is not handled yet. - properties: (hold) still unimplemented. - properties: (update-first) still unimplemented. -- A configuration file? I think we can survive without it... -- xbps-repo: a way to change the order of registered repos (push/pop enough?) - xbps-bin: a target to clean outdated binpkgs in cachedir (like apt-get autoclean). - xbps-repo: support to verify PGP signed pkg-index.plist repo files diff --git a/bin/xbps-bin/check.c b/bin/xbps-bin/check.c index 8a8be883..debb5c2f 100644 --- a/bin/xbps-bin/check.c +++ b/bin/xbps-bin/check.c @@ -53,18 +53,15 @@ int xbps_check_pkg_integrity_all(void) { - prop_dictionary_t d; + const struct xbps_handle *xhp; prop_object_t obj; prop_object_iterator_t iter = NULL; const char *pkgname, *version; int rv = 0; size_t npkgs = 0, nbrokenpkgs = 0; - d = xbps_regpkgdb_dictionary_get(); - if (d == NULL) - return ENODEV; - - iter = xbps_array_iter_from_dict(d, "packages"); + xhp = xbps_handle_get(); + iter = xbps_array_iter_from_dict(xhp->regpkgdb_dictionary, "packages"); if (iter == NULL) { rv = ENOENT; goto out; @@ -86,8 +83,6 @@ out: if (iter) prop_object_iterator_release(iter); - xbps_regpkgdb_dictionary_release(); - return rv; } diff --git a/bin/xbps-bin/find-files.c b/bin/xbps-bin/find-files.c index bf54ff91..2422231c 100644 --- a/bin/xbps-bin/find-files.c +++ b/bin/xbps-bin/find-files.c @@ -60,7 +60,7 @@ match_files_by_pattern(prop_dictionary_t pkg_filesd, prop_dictionary_keysym_t ke while ((obj = prop_object_iterator_next(iter))) { prop_dictionary_get_cstring_nocopy(obj, "file", &filestr); if ((strcmp(filestr, pattern) == 0) || - (xbps_pkgpattern_match(filestr, __UNCONST(pattern)) == 1)) + (xbps_pkgpattern_match(filestr, pattern) == 1)) printf("%s: %s (%s)\n", pkgname, filestr, typestr); } prop_object_iterator_release(iter); diff --git a/bin/xbps-bin/main.c b/bin/xbps-bin/main.c index feb1532b..3b91d52b 100644 --- a/bin/xbps-bin/main.c +++ b/bin/xbps-bin/main.c @@ -181,13 +181,13 @@ unpack_progress_cb(void *data) int main(int argc, char **argv) { - prop_dictionary_t dict; + const struct xbps_handle *xhp; struct xbps_handle xh; struct xbps_unpack_progress_data xupd; struct xbps_fetch_progress_data xfpd; struct list_pkgver_cb lpc; struct sigaction sa; - const char *rootdir, *cachedir; + const char *rootdir, *cachedir, *conffile; int i , c, flags, rv; bool yes, purge, with_debug, force_rm_with_deps, recursive_rm; bool install_auto, install_manual, show_download_pkglist_url; @@ -197,11 +197,14 @@ main(int argc, char **argv) yes = purge = force_rm_with_deps = recursive_rm = with_debug = false; install_auto = install_manual = show_download_pkglist_url = false; - while ((c = getopt(argc, argv, "Ac:dDFfMpRr:Vvy")) != -1) { + while ((c = getopt(argc, argv, "AC:c:dDFfMpRr:Vvy")) != -1) { switch (c) { case 'A': install_auto = true; break; + case 'C': + conffile = optarg; + break; case 'c': cachedir = optarg; break; @@ -282,34 +285,23 @@ main(int argc, char **argv) xh.rootdir = rootdir; xh.cachedir = cachedir; xh.flags = flags; + xh.conffile = conffile; xh.install_reason_manual = install_manual; xh.install_reason_auto = install_auto; - xbps_init(&xh); - if ((dict = xbps_regpkgdb_dictionary_get()) == NULL) { - if (errno && errno != ENOENT) { - fprintf(stderr, - "E: couldn't initialize regpkgdb dict: %s\n", - strerror(errno)); - goto out; - } - } - - if ((rv = xbps_repository_pool_init()) != 0) { - if (rv != ENOENT) { - fprintf(stderr, - "E: couldn't initialize repository pool: %s\n", - strerror(rv)); - goto out; - } + if ((rv = xbps_init(&xh)) != 0) { + xbps_error_printf("xbps-bin: couldn't initialize library: %s\n", + strerror(errno)); + exit(EXIT_FAILURE); } + xhp = xbps_handle_get(); if (strcasecmp(argv[0], "list") == 0) { /* Lists packages currently registered in database. */ if (argc < 1 || argc > 2) usage(); - if (dict == NULL) { + if (xhp->regpkgdb_dictionary == NULL) { printf("No packages currently installed.\n"); goto out; } @@ -335,9 +327,9 @@ main(int argc, char **argv) /* * Find the longest pkgver string to pretty print the output. */ - lpc.pkgver_len = find_longest_pkgver(dict); - rv = xbps_callback_array_iter_in_dict(dict, "packages", - list_pkgs_in_dict, &lpc); + lpc.pkgver_len = find_longest_pkgver(xhp->regpkgdb_dictionary); + rv = xbps_callback_array_iter_in_dict(xhp->regpkgdb_dictionary, + "packages", list_pkgs_in_dict, &lpc); } else if (strcasecmp(argv[0], "install") == 0) { /* Installs a binary package and required deps. */ @@ -472,8 +464,8 @@ main(int argc, char **argv) if (argc != 1) usage(); - rv = xbps_callback_array_iter_in_dict(dict, "packages", - list_manual_packages, NULL); + rv = xbps_callback_array_iter_in_dict(xhp->regpkgdb_dictionary, + "packages", list_manual_packages, NULL); } else if (strcasecmp(argv[0], "show-revdeps") == 0) { /* @@ -494,23 +486,6 @@ main(int argc, char **argv) rv = find_files_in_packages(argv[1]); - } else if (strcasecmp(argv[0], "set-prop") == 0) { - if (argc < 2 || argc > 3) - usage(); - /* - * Sets a property in a package. - */ - rv = xbps_property_set(argv[1], argv[2]); - - } else if (strcasecmp(argv[0], "unset-prop") == 0) { - /* - * Unsets a property in a package. - */ - if (argc < 2 || argc > 3) - usage(); - - rv = xbps_property_unset(argv[1], argv[2]); - } else { usage(); } diff --git a/bin/xbps-bin/show-info-files.c b/bin/xbps-bin/show-info-files.c index a89307bf..22e7bc49 100644 --- a/bin/xbps-bin/show-info-files.c +++ b/bin/xbps-bin/show-info-files.c @@ -37,31 +37,14 @@ int show_pkg_info_from_metadir(const char *pkgname) { - prop_dictionary_t d, regpkgd, pkgpropsd; + prop_dictionary_t d; d = xbps_dictionary_from_metadata_plist(pkgname, XBPS_PKGPROPS); if (d == NULL) return EINVAL; - regpkgd = xbps_regpkgdb_dictionary_get(); - pkgpropsd = xbps_find_pkg_in_dict_by_name(regpkgd, - "properties", pkgname); - if (pkgpropsd == NULL) { - show_pkg_info(d); - prop_object_release(d); - goto out; - } - if (prop_dictionary_get(pkgpropsd, "hold")) - prop_dictionary_set_bool(d, "hold", true); - if (prop_dictionary_get(pkgpropsd, "update-first")) - prop_dictionary_set_bool(d, "update-first", true); - if (prop_dictionary_get(pkgpropsd, "provides")) - prop_dictionary_set_bool(d, "virtual-prefer", true); - show_pkg_info(d); prop_object_release(d); -out: - xbps_regpkgdb_dictionary_release(); return 0; } diff --git a/bin/xbps-bin/util.c b/bin/xbps-bin/util.c index 4920d948..bec50ed0 100644 --- a/bin/xbps-bin/util.c +++ b/bin/xbps-bin/util.c @@ -187,7 +187,7 @@ show_pkg_files(prop_dictionary_t filesd) prop_array_t array; prop_object_iterator_t iter = NULL; prop_object_t obj; - const char *file, *array_str; + const char *file, *array_str, *target; int i = 0; /* This will print links, conf_files and files respectively. */ @@ -209,7 +209,11 @@ show_pkg_files(prop_dictionary_t filesd) while ((obj = prop_object_iterator_next(iter))) { prop_dictionary_get_cstring_nocopy(obj, "file", &file); - printf("%s\n", file); + printf("%s", file); + if (prop_dictionary_get_cstring_nocopy(obj, + "target", &target)) + printf(" -> %s", target); + printf("\n"); } prop_object_iterator_release(iter); } diff --git a/bin/xbps-bin/xbps-bin.8 b/bin/xbps-bin/xbps-bin.8 index c4740805..71d90d6b 100644 --- a/bin/xbps-bin/xbps-bin.8 +++ b/bin/xbps-bin/xbps-bin.8 @@ -1,13 +1,4 @@ -'\" t -.\" Title: xbps-bin -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 02/26/2011 -.\" Manual: \ \& -.\" Source: \ \& -.\" Language: English -.\" -.TH "XBPS\-BIN" "8" "02/26/2011" "\ \&" "\ \&" +.TH "XBPS\-BIN" "8" "06/04/2011" "\ \&" "\ \&" .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- @@ -37,6 +28,11 @@ Use of this option takes effect in the \fIautoupdate\fR, \fIinstall\fR and matched. .RE .PP +\fB\-C\fR \fIconffile\fR +.RS 4 +Full path to the \fIxbps-conf.plist\fR plist configuration file. +.RE +.PP \fB\-c\fR \fIcachedir\fR .RS 4 Sets the cache directory to store downloaded binary packages from remote repositories\&. By default it\(cqs set to @@ -243,26 +239,6 @@ option is used, package files will be \fBremoved even if its SHA256 hash don\(cqt match\fR\&. .RE .PP -\fBset\-prop \fR\fB\fIproperty\fR\fR\fB \fR\fB\fIpkgname\fR\fR -.RS 4 -Sets a -\fIproperty\fR -for a package as specified in -\fIpkgname\fR\&. See the -\fIPROPERTIES\fR -section below for more information\&. -.RE -.PP -\fBunset\-prop \fR\fB\fIproperty\fR\fR\fB \fR\fB\fIpkgname\fR\fR -.RS 4 -Unsets a -\fIproperty\fR -for a package as specified in -\fIpkgname\fR\&. See the -\fIPROPERTIES\fR -section below for more information\&. -.RE -.PP \fBshow \fR\fB\fIpkgname\fR\fR .RS 4 Shows information for installed package @@ -318,35 +294,14 @@ The package has been unpacked in destination root directory, but it is not fully .RS 4 The package has been removed but configuration files and its metadata directory are still available (and it is still registered in the package database)\&. You can purge safely packages that are in this state, modified configuration files will be preserved\&. .RE -.SH "PROPERTIES" -.sp -Properties can be specified for packages to control behaviour of some aspects in XBPS\&. The following is the list of properties currently implemented: .PP -\fBhold\fR -.RS 4 -When this property is set for a package, it will be put on -\fIhold\fR -i\&.e the package won\(cqt be updated even if there is a newer version in registered repositories\&. -.RE -.PP -\fBupdate\-first\fR -.RS 4 -When this property is set, the package will always be updated before all other packages, regardless of its package dependencies\&. -.RE -.PP -\fBvirtual\fR -.RS 4 -When this property is set, the virtual packages that target package supports via the -\fBprovides\fR -object will have preference over other packages matching its -\fIpackage name\fR\&. A real example is any package that -\fIprovides\fR -the -\fBsyslog\-daemon\-0\fR -virtual package, if there are two packages supporting this you can choose which one will be installed\&. -.RE .SH "FILES" .PP +\fB/etc/xbps-conf.plist\fR +.RS 4 +Default XBPS configuration file\&. +.RE +.PP \fB/var/db/xbps\fR .RS 4 xbps global metadata directory\&. @@ -419,18 +374,6 @@ $ xbps\-bin \-yp remove proplib\-devel $ xbps\-bin \-Rp remove bsdtar .RE -.PP -\fBSets\fR the \fIvirtual\fR property in the \fBxbps\-devel\fR package: -.RS 4 - -$ xbps\-bin set\-prop virtual xbps\-devel -.RE -.PP -\fBUnsets\fR the \fIhold\fR property in the \fBcoreutils\fR package: -.RS 4 - -$ xbps\-bin unset\-prop hold coreutils -.RE .SH "BUGS" .sp Probably, but I try to make this not happen\&. Use it under your own responsability and enjoy your life\&. diff --git a/bin/xbps-repo/defs.h b/bin/xbps-repo/defs.h index 38e2fdb1..6af83c09 100644 --- a/bin/xbps-repo/defs.h +++ b/bin/xbps-repo/defs.h @@ -33,8 +33,6 @@ /* From index.c */ int xbps_repo_genindex(const char *); /* From repository.c */ -int register_repository(const char *); -int unregister_repository(const char *); int show_pkg_info_from_repolist(const char *); int show_pkg_deps_from_repolist(const char *); int repository_sync(void); diff --git a/bin/xbps-repo/find-files.c b/bin/xbps-repo/find-files.c index fe40432e..9069949f 100644 --- a/bin/xbps-repo/find-files.c +++ b/bin/xbps-repo/find-files.c @@ -60,7 +60,7 @@ match_files_by_pattern(prop_dictionary_t pkg_filesd, prop_dictionary_keysym_t ke prop_dictionary_get_cstring_nocopy(obj, "file", &filestr); if ((strcmp(filestr, pattern) == 0) || (strstr(filestr, pattern)) || - (xbps_pkgpattern_match(filestr, __UNCONST(pattern)) == 1)) + (xbps_pkgpattern_match(filestr, pattern) == 1)) printf(" %s: %s (%s)\n", pkgver, filestr, typestr); } prop_object_iterator_release(iter); diff --git a/bin/xbps-repo/main.c b/bin/xbps-repo/main.c index 40e7b83b..4ee094d6 100644 --- a/bin/xbps-repo/main.c +++ b/bin/xbps-repo/main.c @@ -50,10 +50,16 @@ usage(void) static int repo_list_uri_cb(struct repository_pool_index *rpi, void *arg, bool *done) { + const char *pkgidx; + uint64_t npkgs; + (void)arg; (void)done; - printf("%s\n", rpi->rpi_uri); + prop_dictionary_get_cstring_nocopy(rpi->rpi_repod, + "pkgindex-version", &pkgidx); + prop_dictionary_get_uint64(rpi->rpi_repod, "total-pkgs", &npkgs); + printf("%s (index %s, %zu packages)\n", rpi->rpi_uri, pkgidx, npkgs); return 0; } @@ -80,19 +86,22 @@ main(int argc, char **argv) struct xbps_handle xh; struct xbps_fetch_progress_data xfpd; prop_dictionary_t pkgd; - const char *rootdir, *cachedir; + const char *rootdir = NULL, *cachedir = NULL, *conffile = NULL; int c, rv = 0; - bool with_debug = false; + bool debug = false; rootdir = cachedir = NULL; - while ((c = getopt(argc, argv, "Vc:dr:")) != -1) { + while ((c = getopt(argc, argv, "C:c:dr:V")) != -1) { switch (c) { + case 'C': + conffile = optarg; + break; case 'c': cachedir = optarg; break; case 'd': - with_debug = true; + debug = true; break; case 'r': /* To specify the root directory */ @@ -114,46 +123,29 @@ main(int argc, char **argv) usage(); /* - * Initialize the function callbacks and debug in libxbps. + * Initialize XBPS subsystems. */ memset(&xh, 0, sizeof(xh)); - xh.with_debug = with_debug; + xh.with_debug = debug; xh.xbps_fetch_cb = fetch_file_progress_cb; xh.xfpd = &xfpd; xh.rootdir = rootdir; xh.cachedir = cachedir; - xbps_init(&xh); + xh.conffile = conffile; - if ((rv = xbps_repository_pool_init()) != 0) { - if (rv != ENOENT) { - xbps_error_printf("xbps-repo: failed to initialize " - "repository pool: %s\n", strerror(rv)); - exit(EXIT_FAILURE); - } + if ((rv = xbps_init(&xh)) != 0) { + xbps_error_printf("xbps-repo: couldn't initialize library: %s\n", + strerror(errno)); + exit(EXIT_FAILURE); } - if (strcasecmp(argv[0], "add") == 0) { - /* Adds a new repository to the pool. */ - if (argc != 2) - usage(); - - rv = register_repository(argv[1]); - - } else if (strcasecmp(argv[0], "list") == 0) { + if (strcasecmp(argv[0], "list") == 0) { /* Lists all repositories registered in pool. */ if (argc != 1) usage(); xbps_repository_pool_foreach(repo_list_uri_cb, NULL); - } else if ((strcasecmp(argv[0], "rm") == 0) || - (strcasecmp(argv[0], "remove") == 0)) { - /* Remove a repository from the pool. */ - if (argc != 2) - usage(); - - rv = unregister_repository(argv[1]); - } else if (strcasecmp(argv[0], "search") == 0) { /* * Search for a package by looking at pkgname/short_desc diff --git a/bin/xbps-repo/repository.c b/bin/xbps-repo/repository.c index 9ce7fbde..f6e14b1e 100644 --- a/bin/xbps-repo/repository.c +++ b/bin/xbps-repo/repository.c @@ -42,44 +42,6 @@ struct repoinfo { uint64_t totalpkgs; }; -static const char * -sanitize_url(const char *path) -{ - static char buf[PATH_MAX]; - const char *res = NULL; - char *dirnp, *basenp, *dir, *base; - int r = 0; - - memset(&buf, 0, sizeof(buf)); - - if ((dir = strdup(path)) == NULL) - return NULL; - - if ((base = strdup(path)) == NULL) { - free(dir); - return NULL; - } - - dirnp = dirname(dir); - if (strcmp(dirnp, ".") == 0) - goto out; - - basenp = basename(base); - if (strcmp(basenp, base) == 0) - goto out; - - r = snprintf(buf, sizeof(buf) - 1, "%s/%s", dirnp, basenp); - if (r < 0 || r >= (int)sizeof(buf) - 1) - goto out; - - res = buf; -out: - free(dir); - free(base); - - return res; -} - static struct repoinfo * pkgindex_verify(const char *plist, const char *uri) { @@ -137,106 +99,6 @@ out: return rpi; } -int -unregister_repository(const char *uri) -{ - const char *idxstr = NULL; - int rv = 0; - - if ((idxstr = sanitize_url(uri)) == NULL) - return errno; - - if ((rv = xbps_repository_unregister(idxstr)) == 0) - return 0; - - if (rv == ENOENT) { - xbps_error_printf("Repository '%s' not " - "registered.\n", idxstr); - } else { - xbps_error_printf("xbps-repo: couldn't unregister " - "repository: %s\n", strerror(rv)); - } - - return rv; -} - -int -register_repository(const char *uri) -{ - const struct xbps_handle *xhp; - struct repoinfo *rpi = NULL; - const char *idxstr = NULL; - char *metadir, *plist; - int rv = 0; - - xhp = xbps_handle_get(); - if ((idxstr = sanitize_url(uri)) == NULL) - return errno; - - if (xbps_check_is_repository_uri_remote(idxstr)) { - printf("Fetching remote package index at %s...\n", idxstr); - rv = xbps_repository_sync_pkg_index(idxstr); - if (rv == -1) { - xbps_error_printf("xbps-repo: couldn't fetch pkg-index " - "file: %s.\n", xbps_fetch_error_string()); - return rv; - } else if (rv == 0) { - printf("Package index file is already " - "up to date.\n"); - return 0; - } - - plist = xbps_pkg_index_plist(idxstr); - } else { - /* - * Create metadir if necessary. - */ - metadir = xbps_xasprintf("%s/%s", xhp->rootdir, - XBPS_META_PATH); - if (metadir == NULL) - return errno; - - if (xbps_mkpath(metadir, 0755) == -1) { - xbps_error_printf("xbps-repo: couldn't create metadata " - "directory: %s.\n", strerror(errno)); - free(metadir); - return EXIT_FAILURE; - } - free(metadir); - plist = xbps_pkg_index_plist(idxstr); - } - - if (plist == NULL) - return errno; - - if ((rpi = pkgindex_verify(plist, idxstr)) == NULL) - goto out; - - if ((rv = xbps_repository_register(idxstr)) != 0) { - if (rv == EEXIST) { - xbps_warn_printf("repository already registered.\n"); - } else { - xbps_error_printf("xbps-repo: couldn't register " - "repository: %s.\n", strerror(errno)); - } - goto out; - } - - printf("Added package index at %s (v%s) with %ju packages.\n", - idxstr, rpi->pkgidxver, rpi->totalpkgs); - -out: - if (rpi != NULL) { - if (rpi->pkgidxver != NULL) - free(rpi->pkgidxver); - free(rpi); - } - if (plist != NULL) - free(plist); - - return rv; -} - int show_pkg_info_from_repolist(const char *pkgname) { @@ -286,7 +148,7 @@ repo_sync_pkg_index_cb(struct repository_pool_index *rpi, void *arg, bool *done) if (!xbps_check_is_repository_uri_remote(rpi->rpi_uri)) return 0; - printf("Syncing package index from: %s\n", rpi->rpi_uri); + printf("Synchronizing package index for `%s' ...\n", rpi->rpi_uri); rv = xbps_repository_sync_pkg_index(rpi->rpi_uri); if (rv == -1) { xbps_error_printf("xbps-repo: failed to sync `%s': %s\n", diff --git a/bin/xbps-repo/xbps-repo.8 b/bin/xbps-repo/xbps-repo.8 index 895840cf..f6a2b97d 100644 --- a/bin/xbps-repo/xbps-repo.8 +++ b/bin/xbps-repo/xbps-repo.8 @@ -1,4 +1,4 @@ -.TH "XBPS\-REPO" "8" "05/27/2011" "\ \&" "\ \&" +.TH "XBPS\-REPO" "8" "06/04/2011" "\ \&" "\ \&" .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- @@ -19,6 +19,11 @@ xbps-repo \- XBPS command for binary package repositories The xbps\-repo(8) command is used to handle local or remote binary package repositories in the \fBXBPS binary package system\fR\&. You can use it to create a package index for a local repository, add or remove local and remote repositories, search for packages and show information about a binary package in repository pool\&. .SH "OPTIONS" .PP +\fB\-C\fR \fIconffile\fR +.RS 4 +Full path to the \fIxbps-conf.plist\fR plist configuration file. +.RE +.PP \fB\-c\fR \fIcachedir\fR .RS 4 Sets the @@ -49,21 +54,12 @@ of .PP \fB\-V\fR .RS 4 -Shows the current XBPS release version (library and code)\&. +Shows the current XBPS API and INDEX versions\&. .RE .SH "TARGETS" .sp Please note that all targets are \fBcase insensitive\fR\&. .PP -\fBadd\fR \fIURI\fR -.RS 4 -Adds a repository as specified in -\fIURI\fR -to the repository pool\&. Local (by specifying a -\fBdirectory\fR) and remote (by specifiying an -\fBHTTP/HTTPS/FTP URL\fR) repositories can be specified\&. -.RE -.PP \fBfind\-files\fR \fIpattern\fR .RS 4 Prints the name for any package registered in the repository pool, that owns @@ -86,18 +82,7 @@ will be removed automatically\&. .PP \fBlist\fR .RS 4 -Lists all currently registered repositories in repository pool\&. -.RE -.PP -\fBremove\fR \fIURI\fR -.RS 4 -Removes a repository from repository pool as specified by the -\fIURI\fR -argument\&. You have to use the same -\fIURI\fR -that was used in the -\fBadd\fR -target\&. +Lists all working repositories in repository pool\&. .RE .PP \fBsearch\fR \fIpattern\fR @@ -137,6 +122,11 @@ Syncs the package index file for all registered remote repositories\&. The new f .RE .SH "FILES" .PP +\fB/etc/xbps-conf.plist\fR +.RS 4 +Default XBPS configuration file\&. +.RE +.PP \fB/var/db/xbps/repositories\&.plist\fR .RS 4 Registered repository list\&. diff --git a/bin/xbps-uhelper/main.c b/bin/xbps-uhelper/main.c index 8a588247..7d71143b 100644 --- a/bin/xbps-uhelper/main.c +++ b/bin/xbps-uhelper/main.c @@ -60,6 +60,8 @@ write_plist_file(prop_dictionary_t dict, const char *file) static void __attribute__((noreturn)) usage(void) { + xbps_end(); + fprintf(stderr, "usage: xbps-uhelper [options] [action] [args]\n" "\n" @@ -84,6 +86,7 @@ usage(void) " version\t\t\n" "\n" " Options shared by all actions:\n" + " -C\t\tPath to xbps-conf.plist file.\n" " -d\t\tDebugging messages to stderr.\n" " -r\t\t\t\n" " -V\t\tPrints the xbps release version\n" @@ -110,13 +113,16 @@ main(int argc, char **argv) struct xbps_fetch_progress_data xfpd; prop_dictionary_t dict, pkgd; prop_array_t array; - const char *version, *rootdir = NULL; + const char *version, *rootdir = NULL, *conffile = NULL; char *plist, *pkgname, *pkgver, *in_chroot_env, *hash; bool fromsrc = false, debug = false, in_chroot = false; int i, c, rv = 0; - while ((c = getopt(argc, argv, "Vdr:")) != -1) { + while ((c = getopt(argc, argv, "C:dr:V")) != -1) { switch (c) { + case 'C': + conffile = optarg; + break; case 'r': /* To specify the root directory */ rootdir = optarg; @@ -147,14 +153,18 @@ main(int argc, char **argv) xh.xbps_fetch_cb = fetch_file_progress_cb; xh.xfpd = &xfpd; xh.rootdir = rootdir; - xbps_init(&xh); + xh.conffile = conffile; + + if ((rv = xbps_init(&xh)) != 0) { + xbps_error_printf("xbps-uhelper: failed to " + "initialize libxbps.\n"); + exit(EXIT_FAILURE); + } plist = xbps_xasprintf("%s/%s/%s", rootdir, XBPS_META_PATH, XBPS_REGPKGDB); if (plist == NULL) { - fprintf(stderr, - "%s=> ERROR: couldn't find regpkdb file (%s)%s\n", - MSG_ERROR, strerror(errno), MSG_RESET); + xbps_end(); exit(EXIT_FAILURE); } diff --git a/configure b/configure index c98805be..c6ddab66 100755 --- a/configure +++ b/configure @@ -33,6 +33,7 @@ for instance \`--prefix=\$HOME'. --includedir=DIR C header files [PREFIX/include] --mandir=DIR man documentation [PREFIX/share/man] --datadir=DIR read-only architecture-independent data [PREFIX/share] +--etcdir=DIR configuration files [PREFIX/etc] --debug Build with debugging code and symbols --silent Build silently, hidding compilation details. @@ -58,6 +59,7 @@ for x; do --host) HOST=$var;; --target) TARGET=$var;; --includedir) INCLUDEDIR=$var;; + --etcdir) ETCDIR=$var;; --libdir) LIBDIR=$var;; --datadir|--infodir) ;; # ignore autotools --with-api-docs) BUILD_API_DOCS=$var;; @@ -79,6 +81,7 @@ done : ${SHAREDIR:=${PREFIX}/share} : ${MANDIR:=${PREFIX}/share/man} : ${INCLUDEDIR:=${PREFIX}/include} +: ${ETCDIR:=${PREFIX}/etc} : ${TOPDIR:=..} _which() @@ -137,6 +140,7 @@ echo "INCLUDEDIR ?= $INCLUDEDIR" >>$CONFIG_MK echo "LIBDIR ?= $LIBDIR" >>$CONFIG_MK echo "MANDIR ?= $MANDIR" >>$CONFIG_MK echo "SHAREDIR ?= $SHAREDIR" >>$CONFIG_MK +echo "ETCDIR ?= $ETCDIR" >>$CONFIG_MK [ -z "$DEBUG" ] && DEBUG=no [ -z "$BUILD_PIE" ] && BUILD_PIE_VAL=no @@ -172,6 +176,7 @@ if [ -n "$LDFLAGS" ]; then fi echo "CPPFLAGS = -I. -I\$(TOPDIR) -I\$(TOPDIR)/include" >>$CONFIG_MK echo "CPPFLAGS += -DHAVE_CONFIG_H" >>$CONFIG_MK +echo "CPPFLAGS += -DXBPS_CONF_PATH=\\\"${ETCDIR}\\\"" >>$CONFIG_MK if [ -n "$DEBUG" -a "$DEBUG" != no -a "$DEBUG" != false ]; then echo "Building with debugging symbols." @@ -510,6 +515,8 @@ echo " LIBDIR = $LIBDIR" echo " INCLUDEDIR = $INCLUDEDIR" echo " SHAREDIR = $SHAREDIR" echo " MANDIR = $MANDIR" +echo " ETCDIR = $ETCDIR" + if [ -n "$CFLAGS" ]; then echo " CFLAGS = $CFLAGS" fi diff --git a/etc/Makefile b/etc/Makefile new file mode 100644 index 00000000..b3c69e61 --- /dev/null +++ b/etc/Makefile @@ -0,0 +1,19 @@ +-include ../config.mk + +CONF_FILE = xbps-conf.plist + +.PHONY: all +all: + +.PHONY: install +install: + install -d $(DESTDIR)$(ETCDIR) + if [ ! -f $(DESTDIR)$(ETCDIR)/$(CONF_FILE) ]; then \ + install -m644 $(CONF_FILE) $(DESTDIR)$(ETCDIR); \ + fi + +.PHONY: uninstall +uninstall: + +.PHONY: clean +clean: diff --git a/etc/xbps-conf.plist b/etc/xbps-conf.plist new file mode 100644 index 00000000..a51db2c5 --- /dev/null +++ b/etc/xbps-conf.plist @@ -0,0 +1,53 @@ + + + + + repositories + + + http://xbps.nopcode.org/repos/stable + + package-virtual + + + + virtual-pkgver + cron-daemon-0 + target-pkgpattern + dcron>=0 + + + + + + + + diff --git a/include/xbps_api.h b/include/xbps_api.h index 654c8715..9f981d30 100644 --- a/include/xbps_api.h +++ b/include/xbps_api.h @@ -59,7 +59,7 @@ * @def XBPS_RELVER * Current library release date. */ -#define XBPS_RELVER "API: 20110601 INDEX: " XBPS_PKGINDEX_VERSION +#define XBPS_RELVER "API: 20110604 INDEX: " XBPS_PKGINDEX_VERSION /** * @def XBPS_META_PATH @@ -73,12 +73,6 @@ */ #define XBPS_CACHE_PATH "/var/cache/xbps" -/** - * @def XBPS_REPOLIST - * Filename for the global repository property list. - */ -#define XBPS_REPOLIST "repositories.plist" - /** * @def XBPS_REGPKGDB * Filename for the global package register database. @@ -103,6 +97,19 @@ */ #define XBPS_PKGINDEX "pkg-index.plist" +/** + * @def XBPS_CONF_PATH + * Default configuration PATH to find XBPS_CONF_PLIST. + */ +#ifndef XBPS_CONF_PATH +#define XBPS_CONF_PATH "/etc" +#endif + +/** + * @def XBPS_CONF_PLIST + * Filename for the XBPS plist configuration file. + */ +#define XBPS_CONF_PLIST "xbps-conf.plist" /** * @def XBPS_FLAG_VERBOSE @@ -138,6 +145,20 @@ void xbps_warn_printf(const char *, ...); * the root and cache directory, flags, etc. */ struct xbps_handle { + /** + * @private conf_dictionary + * + * Internalized proplib dictionary from conffile member. + * Used internally by xbps_init(). + */ + prop_dictionary_t conf_dictionary; + /** + * @var regpkgdb_dictionary. + * + * Internalized proplib dictionary with the registed package database + * stored in XBPS_META_PATH/XBPS_REGPKGDB. + */ + prop_dictionary_t regpkgdb_dictionary; /** * @var xbps_unpack_cb * @@ -188,6 +209,12 @@ struct xbps_handle { * If NULL default value in \a XBPS_CACHE_PATH is used. */ const char *cachedir; + /** + * @var conffile + * + * Full path to the XBPS_CONF_PLIST configuration file. + */ + const char *conffile; /** * @var with_debug * @@ -217,16 +244,21 @@ struct xbps_handle { * Initialize the XBPS library with the following steps: * * - Set function callbacks for fetching and unpacking. - * - Set root directory. - * - Set cache directory. + * - Set root directory (if not set, defaults to /). + * - Set cache directory (if not set, defaults to XBPS_CACHE_PATH). * - Set global flags. * - Set default cache connections for libfetch. * - Initialize the debug printfs. + * - Internalize the proplib dictionary in config file. + * - Internalize the regpkgdb dictionary (if available). + * - Initialize the repository pool interface (if available). * * @param[in] xh Pointer to an xbps_handle structure. It's * assumed that this pointer is not NULL. + * + * @return 0 on success, an errno value otherwise. */ -void xbps_init(struct xbps_handle *xh); +int xbps_init(struct xbps_handle *xh); /** * Releases all resources used by the XBPS library. @@ -268,31 +300,6 @@ int xbps_configure_packages(void); /*@}*/ -/** @addtogroup pkgprops */ -/*@{*/ - -/** - * Sets the property \a prop in a package matching the name \a pkgname. - * - * @param[in] prop Property key to be set. - * @param[in] pkgname Package name to set the property. - * - * @return 0 on success, otherwise an errno value. - */ -int xbps_property_set(const char *prop, const char *pkgname); - -/** - * Unsets the property \a prop in a package matching the name \a pkgname. - * - * @param[in] prop Property key to be unset. - * @param[in] pkgname Package name to unset the property. - * - * @return 0 on success, otherwise an errno value. - */ -int xbps_property_unset(const char *prop, const char *pkgname); - -/*@}*/ - /** * @ingroup vermatch * @@ -430,7 +437,7 @@ prop_array_t xbps_find_pkg_orphans(prop_array_t orphans); * * @return 1 if \a instpkg is matched against \a pattern, 0 if no match. */ -int xbps_pkgpattern_match(const char *instpkg, char *pattern); +int xbps_pkgpattern_match(const char *instpkg, const char *pattern); /** @addtogroup plist */ /*@{*/ @@ -795,35 +802,6 @@ int xbps_unregister_pkg(const char *pkgname); /*@}*/ -/** @addtogroup regpkgdb */ -/*@{*/ - -/** - * Initialize resources used by the registered packages database dictionary - * and returns the internalized proplib dictionary. - * - * @note This function is reference counted, if the database has - * been initialized previously, the counter will be increased by one - * and dictionary stored in memory will be returned. - * - * @warning Don't forget to always use xbps_regpkgdb_dictionary_release() - * when its dictionary is no longer needed. - * - * @return A dictionary as shown above in the Detailed description - * graph on success, or NULL otherwise and errno is set appropiately. - */ -prop_dictionary_t xbps_regpkgdb_dictionary_get(void); - -/** - * Release resources used by the registered packages database. - * - * @note This function is reference counted, if the database - * is in use (its reference count number is greater than 1), won't be released. - */ -void xbps_regpkgdb_dictionary_release(void); - -/*@}*/ - /** @addtogroup pkg_remove */ /*@{*/ @@ -855,29 +833,6 @@ int xbps_remove_pkg_files(prop_dictionary_t dict, const char *key); /*@}*/ -/** @addtogroup repo_register */ -/*@{*/ - -/** - * Registers a repository into the database. - * - * @param[in] uri URI pointing to the repository. - * - * @return 0 on success, otherwise an errno value. - */ -int xbps_repository_register(const char *uri); - -/** - * Unregisters a repository from the database. - * - * @param[in] uri URI pointing to the repository. - * - * @return 0 on success, otherwise an errno value. - */ -int xbps_repository_unregister(const char *uri); - -/*@}*/ - /** @addtogroup repo_pkgs */ /*@{*/ @@ -993,29 +948,6 @@ struct repository_pool_index { char *rpi_uri; }; -/** - * Initializes the repository pool. - * - * Once it's initialized, access to the repositories can be done - * through the \a xbps_repository_pool_foreach() and - * \a xbps_repository_pool_find_pkg() functions. - * - * @note This function is reference counted, don't forget to call - * xbps_repository_pool_release() when it's no longer needed. - * - * @return 0 on success, otherwise an errno value. - */ -int xbps_repository_pool_init(void); - -/** - * Releases the repository pool with all registered repositories - * in the database. - * - * @note This function is reference counted, it won't be released until - * its reference counter is 1. - */ -void xbps_repository_pool_release(void); - /** * Iterates over the repository pool and executes the \a fn function * callback passing in the void * \a arg argument to it. The bool pointer diff --git a/include/xbps_api_impl.h b/include/xbps_api_impl.h index e326f876..811e5686 100644 --- a/include/xbps_api_impl.h +++ b/include/xbps_api_impl.h @@ -35,6 +35,10 @@ #include #include +#include "queue.h" +#include "strlcpy.h" +#include "strlcat.h" +#include "fetch.h" #define ARCHIVE_READ_BLOCKSIZE 10240 @@ -74,6 +78,26 @@ __BEGIN_DECLS +/** + * @private + * From lib/dewey.c + */ +int HIDDEN dewey_match(const char *, const char *); + +/** + * @private + * From lib/regpkgdb_dictionary.c + */ +int HIDDEN xbps_regpkgdb_dictionary_init(struct xbps_handle *xhp); +void HIDDEN xbps_regpkgdb_dictionary_release(void); + +/** + * @private + * From lib/repository_pool.c + */ +int HIDDEN xbps_repository_pool_init(void); +void HIDDEN xbps_repository_pool_release(void); + /** * @private * From lib/download.c diff --git a/lib/Makefile b/lib/Makefile index 9dca9a91..fb7ba2db 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -40,12 +40,12 @@ endif OBJS = package_configure.o package_config_files.o package_orphans.o OBJS += package_remove.o package_remove_obsoletes.o package_state.o OBJS += package_unpack.o package_requiredby.o package_register.o -OBJS += package_purge.o package_replaces.o package_properties.o +OBJS += package_purge.o package_replaces.o OBJS += transaction_dictionary.o transaction_sortdeps.o OBJS += cmpver.o download.o fexec.o humanize_number.o plist.o OBJS += plist_archive_entry.o plist_find.o plist_remove.o -OBJS += plist_fetch.o util.o pkgmatch.o mkpath.o initend.o -OBJS += regpkgdb_dictionary.o repository_register.o +OBJS += plist_fetch.o util.o mkpath.o initend.o +OBJS += regpkgdb_dictionary.o match.o dewey.o OBJS += repository_findpkg.o repository_finddeps.o OBJS += repository_pool.o repository_sync_index.o OBJS += $(COMPAT_SRCS) diff --git a/lib/cmpver.c b/lib/cmpver.c index 4931abc3..3ae9f5ba 100644 --- a/lib/cmpver.c +++ b/lib/cmpver.c @@ -25,7 +25,6 @@ #include #include -#include #include "xbps_api_impl.h" /* diff --git a/lib/compat/strlcpy.c b/lib/compat/strlcpy.c index d50a2606..2ee0f2b6 100644 --- a/lib/compat/strlcpy.c +++ b/lib/compat/strlcpy.c @@ -19,7 +19,7 @@ #include #include -#include "strlcpy.h" +#include "xbps_api_impl.h" /* * Copy src to string dst of size siz. At most siz-1 characters diff --git a/lib/dewey.c b/lib/dewey.c new file mode 100644 index 00000000..5720baaf --- /dev/null +++ b/lib/dewey.c @@ -0,0 +1,337 @@ +/* $NetBSD: dewey.c,v 1.1.1.3 2009/03/08 14:51:37 joerg Exp $ */ + +/* + * Copyright © 2002 Alistair G. Crooks. 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. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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 "xbps_api_impl.h" + +#define PKG_PATTERN_MAX 1024 + +#ifndef MIN +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#endif +#ifndef MAX +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +enum { + DEWEY_LT, + DEWEY_LE, + DEWEY_EQ, + DEWEY_GE, + DEWEY_GT, + DEWEY_NE +}; + +/* do not modify these values, or things will NOT work */ +enum { + Alpha = -3, + Beta = -2, + RC = -1, + Dot = 0, + Patch = 1 +}; + +/* this struct defines a version number */ +typedef struct arr_t { + unsigned c; /* # of version numbers */ + unsigned size; /* size of array */ + int *v; /* array of decimal numbers */ + int netbsd; /* any "nb" suffix */ +} arr_t; + +/* this struct describes a test */ +typedef struct test_t { + const char *s; /* string representation */ + unsigned len; /* length of string */ + int t; /* enumerated type of test */ +} test_t; + + +/* the tests that are recognised. */ +const test_t tests[] = { + { "<=", 2, DEWEY_LE }, + { "<", 1, DEWEY_LT }, + { ">=", 2, DEWEY_GE }, + { ">", 1, DEWEY_GT }, + { "==", 2, DEWEY_EQ }, + { "!=", 2, DEWEY_NE }, + { NULL, 0, 0 } +}; + +const test_t modifiers[] = { + { "alpha", 5, Alpha }, + { "beta", 4, Beta }, + { "pre", 3, RC }, + { "rc", 2, RC }, + { "pl", 2, Dot }, + { "_", 1, Dot }, + { ".", 1, Dot }, + { NULL, 0, 0 } +}; + + + +/* locate the test in the tests array */ +static int +dewey_mktest(int *op, const char *test) +{ + const test_t *tp; + + for (tp = tests ; tp->s ; tp++) { + if (strncasecmp(test, tp->s, tp->len) == 0) { + *op = tp->t; + return tp->len; + } + } + return -1; +} + +/* + * make a component of a version number. + * '.' encodes as Dot which is '0' + * '_' encodes as 'patch level', or 'Dot', which is 0. + * 'pl' encodes as 'patch level', or 'Dot', which is 0. + * 'alpha' encodes as 'alpha version', or Alpha, which is -3. + * 'beta' encodes as 'beta version', or Beta, which is -2. + * 'rc' encodes as 'release candidate', or RC, which is -1. + * 'nb' encodes as 'netbsd version', which is used after all other tests + */ +static int +mkcomponent(arr_t *ap, const char *num) +{ + static const char alphas[] = "abcdefghijklmnopqrstuvwxyz"; + const test_t *modp; + int n; + const char *cp; + + if (ap->c == ap->size) { + if (ap->size == 0) { + ap->size = 62; + if ((ap->v = malloc(ap->size * sizeof(int))) == NULL) { + xbps_dbg_printf("%s: malloc ENOMEM\n", + __func__); + exit(EXIT_FAILURE); + } + } else { + ap->size *= 2; + if ((ap->v = realloc(ap->v, ap->size * sizeof(int))) + == NULL) { + xbps_dbg_printf("%s: realloc ENOMEM\n", + __func__); + exit(EXIT_FAILURE); + } + } + } + if (isdigit((unsigned char)*num)) { + for (cp = num, n = 0 ; isdigit((unsigned char)*num) ; num++) { + n = (n * 10) + (*num - '0'); + } + ap->v[ap->c++] = n; + return (int)(num - cp); + } + for (modp = modifiers ; modp->s ; modp++) { + if (strncasecmp(num, modp->s, modp->len) == 0) { + ap->v[ap->c++] = modp->t; + return modp->len; + } + } + if (strncasecmp(num, "nb", 2) == 0) { + for (cp = num, num += 2, n = 0 ; isdigit((unsigned char)*num) ; num++) { + n = (n * 10) + (*num - '0'); + } + ap->netbsd = n; + return (int)(num - cp); + } + if (isalpha((unsigned char)*num)) { + ap->v[ap->c++] = Dot; + cp = strchr(alphas, tolower((unsigned char)*num)); + if (ap->c == ap->size) { + ap->size *= 2; + if ((ap->v = realloc(ap->v, ap->size * sizeof(int))) == NULL) { + xbps_dbg_printf("%s: ENOMEM!\n", __func__); + exit(EXIT_FAILURE); + } + } + ap->v[ap->c++] = (int)(cp - alphas) + 1; + return 1; + } + return 1; +} + +/* make a version number string into an array of comparable ints */ +static int +mkversion(arr_t *ap, const char *num) +{ + ap->c = 0; + ap->size = 0; + ap->v = NULL; + ap->netbsd = 0; + + while (*num) { + num += mkcomponent(ap, num); + } + return 1; +} + +static void +freeversion(arr_t *ap) +{ + free(ap->v); + ap->v = NULL; + ap->c = 0; + ap->size = 0; +} + +#define DIGIT(v, c, n) (((n) < (c)) ? v[n] : 0) + +/* compare the result against the test we were expecting */ +static int +result(int cmp, int tst) +{ + switch(tst) { + case DEWEY_LT: + return cmp < 0; + case DEWEY_LE: + return cmp <= 0; + case DEWEY_GT: + return cmp > 0; + case DEWEY_GE: + return cmp >= 0; + case DEWEY_EQ: + return cmp == 0; + case DEWEY_NE: + return cmp != 0; + default: + return 0; + } +} + +/* do the test on the 2 vectors */ +static int +vtest(arr_t *lhs, int tst, arr_t *rhs) +{ + int cmp; + unsigned int c, i; + + for (i = 0, c = MAX(lhs->c, rhs->c) ; i < c ; i++) { + if ((cmp = DIGIT(lhs->v, lhs->c, i) - DIGIT(rhs->v, rhs->c, i)) != 0) { + return result(cmp, tst); + } + } + return result(lhs->netbsd - rhs->netbsd, tst); +} + +/* + * Compare two dewey decimal numbers + */ +static int +dewey_cmp(const char *lhs, int op, const char *rhs) +{ + arr_t right; + arr_t left; + int retval; + + if (!mkversion(&left, lhs)) + return 0; + if (!mkversion(&right, rhs)) { + freeversion(&left); + return 0; + } + retval = vtest(&left, op, &right); + freeversion(&left); + freeversion(&right); + return retval; +} + +/* + * Perform dewey match on "pkg" against "pattern". + * Return 1 on match, 0 on non-match, -1 on error. + */ +int HIDDEN +dewey_match(const char *pattern, const char *pkg) +{ + const char *version; + const char *sep, *sep2; + int op, op2; + int n; + + /* compare names */ + if ((version=strrchr(pkg, '-')) == NULL) { + return 0; + } + if ((sep = strpbrk(pattern, "<>")) == NULL) + return -1; + /* compare name lengths */ + if ((sep-pattern != version-pkg) || + strncmp(pkg, pattern, (size_t)(version-pkg)) != 0) + return 0; + version++; + + /* extract comparison operator */ + if ((n = dewey_mktest(&op, sep)) < 0) { + return 0; + } + /* skip operator */ + sep += n; + + /* if greater than, look for less than */ + sep2 = NULL; + if (op == DEWEY_GT || op == DEWEY_GE) { + if ((sep2 = strchr(sep, '<')) != NULL) { + if ((n = dewey_mktest(&op2, sep2)) < 0) { + return 0; + } + /* compare upper limit */ + if (!dewey_cmp(version, op2, sep2+n)) + return 0; + } + } + + /* compare only pattern / lower limit */ + if (sep2) { + char ver[PKG_PATTERN_MAX]; + + strlcpy(ver, sep, MIN((ssize_t)sizeof(ver), sep2-sep+1)); + if (dewey_cmp(version, op, ver)) + return 1; + } + else { + if (dewey_cmp(version, op, sep)) + return 1; + } + + return 0; +} + diff --git a/lib/download.c b/lib/download.c index 10d9583e..ac1463ad 100644 --- a/lib/download.c +++ b/lib/download.c @@ -40,7 +40,6 @@ #include #include -#include #include "xbps_api_impl.h" #include "fetch.h" diff --git a/lib/fexec.c b/lib/fexec.c index cd309c16..613eecca 100644 --- a/lib/fexec.c +++ b/lib/fexec.c @@ -35,7 +35,6 @@ #include #include -#include #include "xbps_api_impl.h" static int diff --git a/lib/initend.c b/lib/initend.c index 1f3b27e2..e926a4d2 100644 --- a/lib/initend.c +++ b/lib/initend.c @@ -29,7 +29,6 @@ #include #include -#include #include "xbps_api_impl.h" /** @@ -43,9 +42,11 @@ static bool debug; static struct xbps_handle *xhp; -void +int xbps_init(struct xbps_handle *xh) { + int rv; + assert(xh != NULL); xhp = xh; @@ -59,6 +60,45 @@ xbps_init(struct xbps_handle *xh) /* If cachedir not set, defaults to XBPS_CACHE_PATH */ if (xhp->cachedir == NULL) xhp->cachedir = XBPS_CACHE_PATH; + /* If conffile not set, defaults to XBPS_CONF_PATH */ + if (xhp->conffile == NULL) + xhp->conffile = XBPS_CONF_PATH "/" XBPS_CONF_PLIST; + + /* + * Internalize the XBPS_CONF_PLIST dictionary. + */ + xhp->conf_dictionary = + prop_dictionary_internalize_from_file(xhp->conffile); + if (xhp->conf_dictionary == NULL) { + xbps_dbg_printf("%s: cannot internalize conf " + "dictionary: %s\n", strerror(errno)); + xbps_end(); + return errno; + } + /* + * Initialize repository pool. + */ + if ((rv = xbps_repository_pool_init()) != 0) { + if (rv != ENOENT) { + xbps_dbg_printf("%s: couldn't initialize " + "repository pool: %s\n", strerror(rv)); + xbps_end(); + return rv; + } + } + /* + * Initialize regpkgdb dictionary. + */ + if ((rv = xbps_regpkgdb_dictionary_init(xhp)) != 0) { + if (rv != ENOENT) { + xbps_dbg_printf("%s: couldn't initialize " + "regpkgdb: %s\n", strerror(rv)); + xbps_end(); + return rv; + } + } + + return 0; } void @@ -67,6 +107,12 @@ xbps_end(void) xbps_regpkgdb_dictionary_release(); xbps_repository_pool_release(); xbps_fetch_unset_cache_connection(); + if (xhp == NULL) + return; + + if (prop_object_type(xhp->conf_dictionary) == PROP_TYPE_DICTIONARY) + prop_object_release(xhp->conf_dictionary); + xhp = NULL; } diff --git a/lib/match.c b/lib/match.c new file mode 100644 index 00000000..55843cd0 --- /dev/null +++ b/lib/match.c @@ -0,0 +1,161 @@ +/* $NetBSD: opattern.c,v 1.5 2009/02/02 12:35:01 joerg Exp $ */ + +/* + * FreeBSD install - a package for the installation and maintainance + * of non-core utilities. + * + * 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. + * + * Jordan K. Hubbard + * 18 July 1993 + * + * Miscellaneous string utilities. + * + */ + +#include +#include +#include +#include +#include +#include + +#include "xbps_api_impl.h" + +/* + * Perform alternate match on "pkg" against "pattern", + * calling pkg_match (recursively) to resolve any other patterns. + * Return 1 on match, 0 otherwise or -1 on error. + */ +static int +alternate_match(const char *pattern, const char *pkg) +{ + char *sep; + char buf[PATH_MAX]; + char *last; + char *alt; + char *cp; + int cnt; + int found; + + if ((sep = strchr(pattern, '{')) == (char *)NULL) + return -1; + + (void)strncpy(buf, pattern, (size_t)(sep - pattern)); + alt = &buf[sep - pattern]; + last = (char *)NULL; + for (cnt = 0, cp = sep; *cp && last == (char *)NULL; cp++) { + if (*cp == '{') { + cnt++; + } else if (*cp == '}' && --cnt == 0 && last == (char *)NULL) { + last = cp + 1; + } + } + if (cnt != 0) + return -1; + + for (found = 0, cp = sep + 1; *sep != '}'; cp = sep + 1) { + for (cnt = 0, sep = cp; cnt > 0 || (cnt == 0 && *sep != '}' && *sep != ','); sep++) { + if (*sep == '{') { + cnt++; + } else if (*sep == '}') { + cnt--; + } + } + (void)snprintf(alt, sizeof(buf) - (alt - buf), "%.*s%s", (int)(sep - cp), cp, last); + if (xbps_pkgpattern_match(buf, pkg) == 1) + found = 1; + } + return found; +} + +/* + * Perform glob match on "pkg" against "pattern". + * Return 1 on match, 0 otherwise + */ +static int +glob_match(const char *pattern, const char *pkg) +{ + return fnmatch(pattern, pkg, FNM_PERIOD) == 0; +} + +/* + * Perform simple match on "pkg" against "pattern". + * Return 1 on match, 0 otherwise + */ +static int +simple_match(const char *pattern, const char *pkg) +{ + return strcmp(pattern, pkg) == 0; +} + +/* + * Performs a fast check if pattern can ever match pkg. + * Returns 1 if a match is possible and 0 otherwise. + */ +static int +quick_pkg_match(const char *pattern, const char *pkg) +{ +#define simple(x) (isalnum((unsigned char)(x)) || (x) == '-') + if (!simple(pattern[0])) + return 1; + if (pattern[0] != pkg[0]) + return 0; + + if (!simple(pattern[1])) + return 1; + if (pattern[1] != pkg[1]) + return 0; + return 1; +#undef simple +} + +/* + * Match pkg against pattern, return 1 if matching, 0 otherwise or -1 on error. + */ +int +xbps_pkgpattern_match(const char *pkg, const char *pattern) +{ + if (!quick_pkg_match(pattern, pkg)) + return 0; + + if (strchr(pattern, '{') != (char *)NULL) { + /* emulate csh-type alternates */ + return alternate_match(pattern, pkg); + } + if (strpbrk(pattern, "<>") != (char *)NULL) { + /* perform relational dewey match on version number */ + return dewey_match(pattern, pkg); + } + if (strpbrk(pattern, "*?[]") != (char *)NULL) { + /* glob match */ + if (glob_match(pattern, pkg)) + return 1; + } + + /* no alternate, dewey or glob match -> simple compare */ + if (simple_match(pattern, pkg)) + return 1; + + /* globbing patterns and simple matches may be specified with or + * without the version number, so check for both cases. */ + { + char *pattern_ver; + int retval; + + pattern_ver = xbps_xasprintf("%s-[0-9]*", pattern); + if (pattern_ver == NULL) + return -1; + + retval = glob_match(pattern_ver, pkg); + free(pattern_ver); + return retval; + } +} diff --git a/lib/mkpath.c b/lib/mkpath.c index ef546499..ed17a625 100644 --- a/lib/mkpath.c +++ b/lib/mkpath.c @@ -36,7 +36,6 @@ #include #include -#include #include "xbps_api_impl.h" int diff --git a/lib/package_config_files.c b/lib/package_config_files.c index c96a3976..2c8a1f31 100644 --- a/lib/package_config_files.c +++ b/lib/package_config_files.c @@ -28,7 +28,6 @@ #include #include -#include #include "xbps_api_impl.h" /* diff --git a/lib/package_configure.c b/lib/package_configure.c index 63bdf1ac..65ddc0e3 100644 --- a/lib/package_configure.c +++ b/lib/package_configure.c @@ -28,7 +28,6 @@ #include #include -#include #include "xbps_api_impl.h" /** @@ -51,21 +50,17 @@ int xbps_configure_packages(void) { - prop_dictionary_t d; + const struct xbps_handle *xhp; prop_object_t obj; prop_object_iterator_t iter; const char *pkgname, *version; int rv = 0; - if ((d = xbps_regpkgdb_dictionary_get()) == NULL) + xhp = xbps_handle_get(); + iter = xbps_array_iter_from_dict(xhp->regpkgdb_dictionary, "packages"); + if (iter == NULL) return errno; - iter = xbps_array_iter_from_dict(d, "packages"); - if (iter == NULL) { - rv = errno; - goto out; - } - while ((obj = prop_object_iterator_next(iter)) != NULL) { prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); prop_dictionary_get_cstring_nocopy(obj, "version", &version); @@ -74,8 +69,6 @@ xbps_configure_packages(void) break; } prop_object_iterator_release(iter); -out: - xbps_regpkgdb_dictionary_release(); return rv; } diff --git a/lib/package_orphans.c b/lib/package_orphans.c index e7f66d89..7526e27b 100644 --- a/lib/package_orphans.c +++ b/lib/package_orphans.c @@ -29,7 +29,6 @@ #include #include -#include #include "xbps_api_impl.h" /** @@ -162,35 +161,30 @@ find_orphan_pkg(prop_object_t obj, void *arg, bool *loop_done) prop_array_t xbps_find_pkg_orphans(prop_array_t orphans_user) { + const struct xbps_handle *xhp; prop_array_t array = NULL; - prop_dictionary_t dict; struct orphan_data od; int rv = 0; - if ((dict = xbps_regpkgdb_dictionary_get()) == NULL) - return NULL; + xhp = xbps_handle_get(); /* * Prepare an array with all packages previously found. */ if ((od.array = prop_array_create()) == NULL) - goto out; + return NULL; /* * Find out all orphans by looking at the * regpkgdb dictionary and iterate in reverse order * in which packages were installed. */ od.orphans_user = orphans_user; - rv = xbps_callback_array_iter_reverse_in_dict(dict, "packages", - find_orphan_pkg, &od); + rv = xbps_callback_array_iter_reverse_in_dict(xhp->regpkgdb_dictionary, + "packages", find_orphan_pkg, &od); if (rv != 0) { errno = rv; prop_object_release(od.array); - array = NULL; - goto out; + return NULL; } array = prop_array_copy(od.array); -out: - xbps_regpkgdb_dictionary_release(); - return array; } diff --git a/lib/package_properties.c b/lib/package_properties.c deleted file mode 100644 index d25595cf..00000000 --- a/lib/package_properties.c +++ /dev/null @@ -1,272 +0,0 @@ -/*- - * Copyright (c) 2011 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" - -/** - * @file lib/package_properties.c - * @brief Package properties routines - * @defgroup pkgprops Package property functions - * - * Set and unset global properties for packages in the regpkgdb - * plist file and its "properties" array object. - */ -int -xbps_property_set(const char *key, const char *pkgname) -{ - const struct xbps_handle *xhp; - prop_dictionary_t d, repo_pkgd = NULL, pkgd = NULL; - prop_array_t props, provides = NULL, virtual = NULL; - prop_string_t virtualpkg; - char *plist; - int rv = 0; - bool regpkgd_alloc, pkgd_alloc, virtual_alloc, propbool; - - assert(key != NULL); - assert(pkgname != NULL); - - regpkgd_alloc = pkgd_alloc = virtual_alloc = propbool = false; - xhp = xbps_handle_get(); - - if ((d = xbps_regpkgdb_dictionary_get()) == NULL) { - /* - * If regpkgdb dictionary doesn't exist, create it - * and the properties array. - */ - d = prop_dictionary_create(); - if (d == NULL) { - rv = ENOMEM; - goto out; - } - regpkgd_alloc = true; - props = prop_array_create(); - if (props == NULL) { - rv = ENOMEM; - goto out; - } - if (!prop_dictionary_set(d, "properties", props)) { - rv = EINVAL; - prop_object_release(props); - goto out; - } - prop_object_release(props); - } - props = prop_dictionary_get(d, "properties"); - if (prop_object_type(props) != PROP_TYPE_ARRAY) { - rv = EINVAL; - goto out; - } - /* - * If package dictionary doesn't exist, create it. - */ - pkgd = xbps_find_pkg_in_array_by_name(props, pkgname); - if (pkgd == NULL) { - pkgd = prop_dictionary_create(); - if (pkgd == NULL) { - rv = ENOMEM; - goto out; - } - pkgd_alloc = true; - prop_dictionary_set_cstring_nocopy(pkgd, "pkgname", pkgname); - if (!prop_array_add(props, pkgd)) { - rv = EINVAL; - goto out; - } - } - - if (strcmp(key, "virtual") == 0) { - /* - * Sets the "virtual" property in package. - */ - virtual = prop_dictionary_get(pkgd, "provides"); - if (virtual == NULL) { - virtual = prop_array_create(); - if (virtual == NULL) { - rv = ENOMEM; - goto out; - } - virtual_alloc = true; - virtualpkg = prop_string_create_cstring(pkgname); - if (virtualpkg == NULL) { - rv = ENOMEM; - goto out; - } - prop_string_append_cstring(virtualpkg, ">=0"); - prop_dictionary_set(pkgd, "pkgpattern", virtualpkg); - prop_object_release(virtualpkg); - virtualpkg = NULL; - } else { - /* property already set */ - xbps_dbg_printf("%s: property `%s' already set!\n", - pkgname, key); - rv = EEXIST; - goto out; - } - /* - * Get the package object from repository pool. - */ - repo_pkgd = xbps_repository_pool_find_pkg(pkgname, false, false); - if (repo_pkgd == NULL) { - xbps_dbg_printf("%s: cannot find pkg dictionary " - "in repository pool.\n", pkgname); - rv = ENOENT; - goto out; - } - provides = prop_dictionary_get(repo_pkgd, "provides"); - if (provides == NULL) { - xbps_dbg_printf("%s: pkg dictionary no provides " - "array!\n", pkgname); - prop_object_release(repo_pkgd); - rv = EINVAL; - goto out; - } - if (!prop_dictionary_set(pkgd, "provides", provides)) { - prop_object_release(repo_pkgd); - rv = EINVAL; - goto out; - } - prop_object_release(repo_pkgd); - - } else if ((strcmp(key, "hold") == 0) || - (strcmp(key, "update-first") == 0)) { - /* - * Sets the property "key" in package. - */ - if (prop_dictionary_get_bool(pkgd, key, &propbool)) { - rv = EEXIST; - goto out; - } - prop_dictionary_set_bool(pkgd, key, true); - } else { - /* invalid property */ - rv = EINVAL; - goto out; - } - /* - * Add array with new properties set into the regpkgdb - * dictionary. - */ - if (!prop_dictionary_set(d, "properties", props)) { - rv = errno; - goto out; - } - /* - * Write regpkgdb dictionary to plist file. - */ - plist = xbps_xasprintf("%s/%s/%s", xhp->rootdir, - XBPS_META_PATH, XBPS_REGPKGDB); - if (plist == NULL) { - rv = ENOMEM; - goto out; - } - if (!prop_dictionary_externalize_to_zfile(d, plist)) { - rv = errno; - goto out; - } -out: - if (virtual_alloc) - prop_object_release(virtual); - if (pkgd_alloc) - prop_object_release(pkgd); - if (regpkgd_alloc) - prop_object_release(d); - - xbps_regpkgdb_dictionary_release(); - return rv; -} - -int -xbps_property_unset(const char *key, const char *pkgname) -{ - const struct xbps_handle *xhp; - prop_dictionary_t d, pkgd; - prop_array_t props; - char *plist; - int rv = 0; - - assert(key != NULL); - assert(pkgname != NULL); - xhp = xbps_handle_get(); - - if ((d = xbps_regpkgdb_dictionary_get()) == NULL) - return ENODEV; - - props = prop_dictionary_get(d, "properties"); - if (prop_object_type(props) != PROP_TYPE_ARRAY) { - rv = ENODEV; - goto out; - } - pkgd = xbps_find_pkg_in_array_by_name(props, pkgname); - if (pkgd == NULL) { - rv = ENODEV; - goto out; - } - if ((strcmp(key, "virtual") == 0) || - (strcmp(key, "hold") == 0) || - (strcmp(key, "update-first") == 0)) { - /* remove the property object matching the key */ - prop_dictionary_remove(pkgd, key); - } else { - /* invalid property */ - rv = EINVAL; - goto out; - } - /* - * If pkg dictionary does not contain any property, remove - * the object completely. - */ - if (!prop_dictionary_get(d, "virtual") && - !prop_dictionary_get(d, "hold") && - !prop_dictionary_get(d, "update-first")) - xbps_remove_pkg_from_array_by_name(props, pkgname); - - if (!prop_dictionary_set(d, "properties", props)) { - rv = EINVAL; - goto out; - } - /* - * Write regpkgdb dictionary to plist file. - */ - plist = xbps_xasprintf("%s/%s/%s", xhp->rootdir, - XBPS_META_PATH, XBPS_REGPKGDB); - if (plist == NULL) { - rv = ENOMEM; - goto out; - } - if (!prop_dictionary_externalize_to_zfile(d, plist)) { - rv = errno; - goto out; - } -out: - xbps_regpkgdb_dictionary_release(); - return rv; -} diff --git a/lib/package_purge.c b/lib/package_purge.c index 43b1d381..784873e6 100644 --- a/lib/package_purge.c +++ b/lib/package_purge.c @@ -29,7 +29,6 @@ #include #include -#include #include "xbps_api_impl.h" /** @@ -96,31 +95,23 @@ remove_pkg_metadata(const char *pkgname, const char *rootdir) int xbps_purge_packages(void) { - - prop_dictionary_t d; + const struct xbps_handle *xhp; prop_object_t obj; prop_object_iterator_t iter; const char *pkgname; int rv = 0; - if ((d = xbps_regpkgdb_dictionary_get()) == NULL) + xhp = xbps_handle_get(); + iter = xbps_array_iter_from_dict(xhp->regpkgdb_dictionary, "packages"); + if (iter == NULL) return errno; - iter = xbps_array_iter_from_dict(d, "packages"); - if (iter == NULL) { - rv = errno; - goto out; - } - while ((obj = prop_object_iterator_next(iter)) != NULL) { prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); if ((rv = xbps_purge_pkg(pkgname, true)) != 0) break; } prop_object_iterator_release(iter); -out: - xbps_regpkgdb_dictionary_release(); - return rv; } @@ -139,35 +130,31 @@ xbps_purge_pkg(const char *pkgname, bool check_state) /* * Firstly let's get the pkg dictionary from regpkgdb. */ - if ((dict = xbps_regpkgdb_dictionary_get()) == NULL) + pkgd = xbps_find_pkg_in_dict_by_name(xhp->regpkgdb_dictionary, + "packages", pkgname); + if (pkgd == NULL) return errno; - pkgd = xbps_find_pkg_in_dict_by_name(dict, "packages", pkgname); - if (pkgd == NULL) { - rv = errno; - goto out; - } if (check_state) { /* * Skip packages that aren't in "config-files" state. */ if ((rv = xbps_pkg_state_dictionary(pkgd, &state)) != 0) - goto out; + return rv; if (state != XBPS_PKG_STATE_CONFIG_FILES) - goto out; + return rv; } /* * Remove unmodified configuration files. */ dict = xbps_dictionary_from_metadata_plist(pkgname, XBPS_PKGFILES); - if (dict == NULL) { - rv = errno; - goto out; - } + if (dict == NULL) + return errno; + if (prop_dictionary_get(dict, "conf_files")) { if ((rv = xbps_remove_pkg_files(dict, "conf_files")) != 0) { prop_object_release(dict); - goto out; + return rv; } } /* @@ -178,13 +165,13 @@ xbps_purge_pkg(const char *pkgname, bool check_state) prop_object_release(dict); xbps_error_printf("[purge] %s: cannot change to rootdir: %s.\n", pkgname, strerror(rv)); - goto out; + return rv; } buf = xbps_xasprintf(".%s/metadata/%s/REMOVE", XBPS_META_PATH, pkgname); if (buf == NULL) { prop_object_release(dict); rv = ENOMEM; - goto out; + return rv; } if (access(buf, X_OK) == 0) { prop_dictionary_get_cstring_nocopy(pkgd, "version", &version); @@ -198,7 +185,7 @@ xbps_purge_pkg(const char *pkgname, bool check_state) "REMOVE script: %s\n", pkgname, strerror(errno)); prop_object_release(dict); - goto out; + return rv; } } } @@ -210,18 +197,15 @@ xbps_purge_pkg(const char *pkgname, bool check_state) if ((rv = remove_pkg_metadata(pkgname, xhp->rootdir)) != 0) { xbps_error_printf("%s: couldn't remove metadata files: %s\n", pkgname, strerror(rv)); - goto out; + return rv; } if ((rv = xbps_unregister_pkg(pkgname)) != 0) { xbps_error_printf("%s: couldn't unregister package: %s\n", pkgname, strerror(rv)); - goto out; + return rv; } if (xhp->flags & XBPS_FLAG_VERBOSE) xbps_printf("Package %s purged successfully.\n", pkgname); -out: - xbps_regpkgdb_dictionary_release(); - return rv; } diff --git a/lib/package_register.c b/lib/package_register.c index 7edf2da6..67ea5107 100644 --- a/lib/package_register.c +++ b/lib/package_register.c @@ -28,7 +28,6 @@ #include #include -#include #include "xbps_api_impl.h" /** diff --git a/lib/package_remove.c b/lib/package_remove.c index 5fee39e9..6780f2f0 100644 --- a/lib/package_remove.c +++ b/lib/package_remove.c @@ -31,7 +31,6 @@ #include #include -#include #include "xbps_api_impl.h" /** diff --git a/lib/package_remove_obsoletes.c b/lib/package_remove_obsoletes.c index 83cd0c06..65e06e0e 100644 --- a/lib/package_remove_obsoletes.c +++ b/lib/package_remove_obsoletes.c @@ -33,7 +33,6 @@ #include #include -#include #include "xbps_api_impl.h" int HIDDEN diff --git a/lib/package_replaces.c b/lib/package_replaces.c index b9859a0f..7e30ebed 100644 --- a/lib/package_replaces.c +++ b/lib/package_replaces.c @@ -30,7 +30,6 @@ #include #include -#include #include "xbps_api_impl.h" int HIDDEN @@ -41,7 +40,7 @@ xbps_repository_pkg_replaces(prop_dictionary_t transd, prop_dictionary_t instd, reppkgd; prop_object_t obj; prop_object_iterator_t iter; - const char *pattern; + const char *pattern, *pkgname, *curpkgname; replaces = prop_dictionary_get(pkg_repod, "replaces"); if (replaces == NULL || prop_array_count(replaces) == 0) @@ -61,6 +60,16 @@ xbps_repository_pkg_replaces(prop_dictionary_t transd, instd = xbps_find_pkg_dict_installed(pattern, true); if (instd == NULL) continue; + /* + * Check that we are not replacing the same package, due + * to virtual packages. + */ + prop_dictionary_get_cstring_nocopy(pkg_repod, "pkgname", &pkgname); + prop_dictionary_get_cstring_nocopy(instd, "pkgname", &curpkgname); + if (strcmp(pkgname, curpkgname) == 0) { + prop_object_release(instd); + continue; + } /* * Package contains replaces="pkgpattern", but the * package that should be replaced is also in the diff --git a/lib/package_requiredby.c b/lib/package_requiredby.c index b1d02009..a2dccd54 100644 --- a/lib/package_requiredby.c +++ b/lib/package_requiredby.c @@ -29,7 +29,6 @@ #include #include -#include #include "xbps_api_impl.h" static int diff --git a/lib/package_state.c b/lib/package_state.c index 6d6989b5..8f686e7b 100644 --- a/lib/package_state.c +++ b/lib/package_state.c @@ -29,7 +29,6 @@ #include #include -#include #include "xbps_api_impl.h" struct state { diff --git a/lib/package_unpack.c b/lib/package_unpack.c index 358f270c..cf0e9e95 100644 --- a/lib/package_unpack.c +++ b/lib/package_unpack.c @@ -32,7 +32,6 @@ #include #include -#include #include "xbps_api_impl.h" /** diff --git a/lib/pkgmatch.c b/lib/pkgmatch.c deleted file mode 100644 index c8aa9fde..00000000 --- a/lib/pkgmatch.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * FreeBSD install - a package for the installation and maintenance - * of non-core utilities. - * - * 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. - * - * Maxim Sobolev - * 31 July 2001 - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "config.h" - -/** - * @file lib/pkgmatch.c - * @brief Package version matching routines - * @defgroup vermatch Package version matching functions - */ - -static int -csh_match(const char *pattern, const char *string, int flags) -{ - const char *nextchoice = pattern, *current = NULL; - int ret = FNM_NOMATCH, prefixlen = -1, curlen = 0, level = 0; - - do { - const char *pos = nextchoice; - const char *postfix = NULL; - bool quoted = false; - - nextchoice = NULL; - do { - const char *eb; - if (!*pos) { - postfix = pos; - } else if (quoted) { - quoted = false; - } else { - switch (*pos) { - case '{': - ++level; - if (level == 1) { - current = pos + 1; - prefixlen = pos - pattern; - } - break; - case ',': - if (level == 1 && !nextchoice) { - nextchoice = pos + 1; - curlen = pos - current; - } - break; - case '}': - if (level == 1) { - postfix = pos + 1; - if (!nextchoice) - curlen = pos - current; - } - level--; - break; - case '[': - eb = pos+1; - if (*eb == '!' || *eb == '^') - eb++; - if (*eb == ']') - eb++; - while (*eb && *eb != ']') - eb++; - if (*eb) - pos = eb; - break; - case '\\': - quoted = true; - break; - default: - ; - } - } - pos++; - } while (!postfix); - - if (current) { - char buf[FILENAME_MAX]; - snprintf(buf, sizeof(buf), "%.*s%.*s%s", prefixlen, - pattern, curlen, current, postfix); - ret = csh_match(buf, string, flags); - if (ret) { - current = nextchoice; - level = 1; - } else - current = NULL; - } else - ret = fnmatch(pattern, string, flags); - } while (current); - - return ret; -} - -int -xbps_pkgpattern_match(const char *instpkg, char *pattern) -{ - const char *fname = instpkg; - char *basefname = NULL, condchar = '\0', *condition; - size_t len = 0; - int rv = 0; - - /* Check for a full match with strcmp, otherwise try csh_match() */ - if (strcmp(instpkg, pattern) == 0) - return 1; - - condition = strpbrk(pattern, "><="); - if (condition) { - const char *ch; - if (condition > pattern && condition[-1] == '!') - condition--; - condchar = *condition; - *condition = '\0'; - ch = strrchr(fname, '-'); - if (ch && ch - fname < PATH_MAX) { - len = ch - fname + 1; - basefname = malloc(len); - if (basefname == NULL) - return -1; - strlcpy(basefname, fname, len); - fname = basefname; - } - } - - rv = (csh_match(pattern, fname, 0) == 0) ? 1 : 0; - - while (condition) { - *condition = condchar; - if (rv == 1) { - char *nextcondition; - int match = 0; - if (*++condition == '=') { - match = 2; - condition++; - } - switch (condchar) { - case '<': - match |= 1; - break; - case '>': - match |= 4; - break; - case '=': - match |= 2; - break; - case '!': - match = 5; - break; - } - nextcondition = strpbrk(condition, "<>=!"); - if (nextcondition) { - condchar = *nextcondition; - *nextcondition = '\0'; - } - if ((match & - (1 << (xbps_cmpver(instpkg, condition) + 1))) == 0) - rv = 0; - condition = nextcondition; - } else { - break; - } - } - if (basefname) - free(basefname); - - return rv; -} diff --git a/lib/plist.c b/lib/plist.c index 5ade76c2..023836ca 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -29,7 +29,6 @@ #include #include -#include #include "xbps_api_impl.h" /** diff --git a/lib/plist_archive_entry.c b/lib/plist_archive_entry.c index e1e353c7..6c57c3ea 100644 --- a/lib/plist_archive_entry.c +++ b/lib/plist_archive_entry.c @@ -28,9 +28,8 @@ #include #include #include - #include -#include + #include "xbps_api_impl.h" /* diff --git a/lib/plist_fetch.c b/lib/plist_fetch.c index 88724c6d..7628ec56 100644 --- a/lib/plist_fetch.c +++ b/lib/plist_fetch.c @@ -31,7 +31,6 @@ #include #include -#include #include "xbps_api_impl.h" #include "fetch.h" diff --git a/lib/plist_find.c b/lib/plist_find.c index 85462f0e..3e6eff14 100644 --- a/lib/plist_find.c +++ b/lib/plist_find.c @@ -29,7 +29,6 @@ #include #include -#include #include "xbps_api_impl.h" /** @@ -128,7 +127,7 @@ find_pkg_in_array(prop_array_t array, const char *str, bool bypattern) if (!prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver)) continue; - if (xbps_pkgpattern_match(pkgver, __UNCONST(str))) + if (xbps_pkgpattern_match(pkgver, str)) break; } else { if (!prop_dictionary_get_cstring_nocopy(obj, @@ -165,44 +164,44 @@ xbps_find_pkg_in_array_by_pattern(prop_array_t array, const char *pattern) } static const char * -find_virtualpkg_user_in_regpkgdb(const char *virtualpkg, bool bypattern) +find_virtualpkg_user_in_conf(const char *vpkg, bool bypattern) { - prop_array_t virtual; - prop_dictionary_t d; + const struct xbps_handle *xhp; prop_object_iterator_t iter; prop_object_t obj; - const char *pkg = NULL; - bool found = false; + const char *vpkgver, *pkg = NULL; + char *vpkgname = NULL; - if ((d = xbps_regpkgdb_dictionary_get()) == NULL) + xhp = xbps_handle_get(); + + if ((iter = xbps_array_iter_from_dict(xhp->conf_dictionary, + "package-virtual")) == NULL) return NULL; - if ((iter = xbps_array_iter_from_dict(d, "properties")) == NULL) { - xbps_regpkgdb_dictionary_release(); - return NULL; - } while ((obj = prop_object_iterator_next(iter)) != NULL) { - virtual = prop_dictionary_get(obj, "provides"); - if (virtual == NULL) + if (!prop_dictionary_get_cstring_nocopy(obj, + "virtual-pkgver", &vpkgver)) continue; - if (bypattern) - found = xbps_find_pkgpattern_in_array(virtual, virtualpkg); - else - found = xbps_find_pkgname_in_array(virtual, virtualpkg); - if (!found) - continue; - if (bypattern) - prop_dictionary_get_cstring_nocopy(obj, - "pkgpattern", &pkg); - else - prop_dictionary_get_cstring_nocopy(obj, - "pkgname", &pkg); - - break; + if (bypattern) { + if (xbps_pkgpattern_match(vpkgver, vpkg)) { + prop_dictionary_get_cstring_nocopy(obj, + "target-pkgpattern", &pkg); + break; + } + } else { + vpkgname = xbps_pkgpattern_name(vpkgver); + if (vpkgname == NULL) + break; + + if (strcmp(vpkg, vpkgname) == 0) { + pkg = vpkgname; + free(vpkgname); + break; + } + } } prop_object_iterator_release(iter); - xbps_regpkgdb_dictionary_release(); return pkg; } @@ -219,7 +218,7 @@ find_virtualpkg_user_in_array(prop_array_t array, assert(array != NULL); assert(str != NULL); - virtualpkg = find_virtualpkg_user_in_regpkgdb(str, bypattern); + virtualpkg = find_virtualpkg_user_in_conf(str, bypattern); if (virtualpkg == NULL) return NULL; @@ -231,8 +230,7 @@ find_virtualpkg_user_in_array(prop_array_t array, if (bypattern) { prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver); - if (xbps_pkgpattern_match(pkgver, - __UNCONST(virtualpkg))) + if (xbps_pkgpattern_match(pkgver, virtualpkg)) break; } else { prop_dictionary_get_cstring_nocopy(obj, @@ -303,20 +301,23 @@ xbps_find_virtualpkg_user_in_dict_by_pattern(prop_dictionary_t d, prop_dictionary_t xbps_find_pkg_dict_installed(const char *str, bool bypattern) { - prop_dictionary_t d, pkgd, rpkgd = NULL; + const struct xbps_handle *xhp; + prop_dictionary_t pkgd, rpkgd = NULL; pkg_state_t state = 0; assert(str != NULL); - if ((d = xbps_regpkgdb_dictionary_get()) == NULL) + xhp = xbps_handle_get(); + if (xhp->regpkgdb_dictionary == NULL) return NULL; - pkgd = find_pkg_in_dict(d, "packages", str, bypattern, false); + pkgd = find_pkg_in_dict(xhp->regpkgdb_dictionary, + "packages", str, bypattern, false); if (pkgd == NULL) - goto out; + return rpkgd; if (xbps_pkg_state_dictionary(pkgd, &state) != 0) - goto out; + return rpkgd; switch (state) { case XBPS_PKG_STATE_INSTALLED: @@ -331,8 +332,7 @@ xbps_find_pkg_dict_installed(const char *str, bool bypattern) default: break; } -out: - xbps_regpkgdb_dictionary_release(); + return rpkgd; } @@ -375,7 +375,7 @@ find_string_in_array(prop_array_t array, const char *str, int mode) } else if (mode == 2) { /* match by pkgpattern */ pkgdep = prop_string_cstring_nocopy(obj); - if (xbps_pkgpattern_match(pkgdep, __UNCONST(str))) { + if (xbps_pkgpattern_match(pkgdep, str)) { found = true; break; } diff --git a/lib/plist_remove.c b/lib/plist_remove.c index 329baed7..9d66bf64 100644 --- a/lib/plist_remove.c +++ b/lib/plist_remove.c @@ -29,7 +29,6 @@ #include #include -#include #include "xbps_api_impl.h" /** diff --git a/lib/regpkgdb_dictionary.c b/lib/regpkgdb_dictionary.c index 1d0a09d4..13e78046 100644 --- a/lib/regpkgdb_dictionary.c +++ b/lib/regpkgdb_dictionary.c @@ -28,9 +28,7 @@ #include #include #include -#include -#include #include "xbps_api_impl.h" /** @@ -58,63 +56,47 @@ * dictionary. */ -static prop_dictionary_t regpkgdb_dict; -static size_t regpkgdb_refcnt; static bool regpkgdb_initialized; -static pthread_mutex_t refcnt_mtx = PTHREAD_MUTEX_INITIALIZER; -prop_dictionary_t -xbps_regpkgdb_dictionary_get(void) +int HIDDEN +xbps_regpkgdb_dictionary_init(struct xbps_handle *xhp) { - const struct xbps_handle *xhp; char *plist; - if (regpkgdb_initialized) { - pthread_mutex_lock(&refcnt_mtx); - regpkgdb_refcnt++; - pthread_mutex_unlock(&refcnt_mtx); - return regpkgdb_dict; - } + if (regpkgdb_initialized) + return 0; - xhp = xbps_handle_get(); plist = xbps_xasprintf("%s/%s/%s", xhp->rootdir, XBPS_META_PATH, XBPS_REGPKGDB); if (plist == NULL) - return NULL; + return ENOMEM; - regpkgdb_dict = prop_dictionary_internalize_from_zfile(plist); - if (regpkgdb_dict == NULL) { + xhp->regpkgdb_dictionary = + prop_dictionary_internalize_from_zfile(plist); + if (xhp->regpkgdb_dictionary == NULL) { free(plist); if (errno != ENOENT) xbps_dbg_printf("[regpkgdb] cannot internalize " - "regpkgdb_dict %s\n", strerror(errno)); - return NULL; + "regpkgdb dictionary: %s\n", strerror(errno)); + return errno; } free(plist); regpkgdb_initialized = true; xbps_dbg_printf("%s: initialized ok.\n", __func__); - pthread_mutex_lock(&refcnt_mtx); - regpkgdb_refcnt = 1; - pthread_mutex_unlock(&refcnt_mtx); - - return regpkgdb_dict; + return 0; } -void +void HIDDEN xbps_regpkgdb_dictionary_release(void) { - size_t cnt; + const struct xbps_handle *xhp; - pthread_mutex_lock(&refcnt_mtx); - cnt = regpkgdb_refcnt--; - pthread_mutex_unlock(&refcnt_mtx); - - if (cnt != 1) + if (!regpkgdb_initialized) return; - prop_object_release(regpkgdb_dict); - regpkgdb_dict = NULL; + xhp = xbps_handle_get(); + prop_object_release(xhp->regpkgdb_dictionary); regpkgdb_initialized = false; xbps_dbg_printf("%s: released ok.\n", __func__); } diff --git a/lib/repository_finddeps.c b/lib/repository_finddeps.c index 390114be..4ae3b567 100644 --- a/lib/repository_finddeps.c +++ b/lib/repository_finddeps.c @@ -28,7 +28,6 @@ #include #include -#include #include "xbps_api_impl.h" static int @@ -36,7 +35,7 @@ store_dependency(prop_dictionary_t transd, prop_dictionary_t repo_pkgd) { prop_dictionary_t dict; prop_array_t array; - const char *pkgname, *pkgver, *repoloc; + const char *pkgname, *pkgver, *repoloc, *reason; int rv = 0; pkg_state_t state = 0; @@ -63,15 +62,6 @@ store_dependency(prop_dictionary_t transd, prop_dictionary_t repo_pkgd) prop_object_release(dict); return errno; } - /* - * Always set "not-installed" package state. Will be overwritten - * to its correct state later. - */ - rv = xbps_set_pkg_state_dictionary(dict, XBPS_PKG_STATE_NOT_INSTALLED); - if (rv != 0) { - prop_object_release(dict); - return rv; - } /* * Overwrite package state in dictionary with same state than the * package currently uses, otherwise not-installed. @@ -81,12 +71,27 @@ store_dependency(prop_dictionary_t transd, prop_dictionary_t repo_pkgd) prop_object_release(dict); return rv; } + /* pkg not installed */ state = XBPS_PKG_STATE_NOT_INSTALLED; } if ((rv = xbps_set_pkg_state_dictionary(dict, state)) != 0) { prop_object_release(dict); return rv; } + /* + * If pkg dependency is already installed, skip it if the transaction + * reason is "install". + */ + if (state == XBPS_PKG_STATE_INSTALLED) { + prop_dictionary_get_cstring_nocopy(repo_pkgd, + "transaction", &reason); + if (strcmp(reason, "install") == 0) { + xbps_dbg_printf("%s: skipping, already installed.\n", + pkgver); + prop_object_release(dict); + return 0; + } + } /* * Add required objects into package dep's dictionary. */ @@ -321,7 +326,7 @@ find_repo_deps(prop_dictionary_t transd, /* transaction dictionary */ break; } free(pkgname); - rv = xbps_pkgpattern_match(pkgver_q, __UNCONST(reqpkg)); + rv = xbps_pkgpattern_match(pkgver_q, reqpkg); if (rv == 0) { /* * Package is installed but does not match diff --git a/lib/repository_findpkg.c b/lib/repository_findpkg.c index 2e33a1f9..dd8cc7a0 100644 --- a/lib/repository_findpkg.c +++ b/lib/repository_findpkg.c @@ -29,7 +29,6 @@ #include #include -#include #include "xbps_api_impl.h" /** @@ -56,20 +55,18 @@ static int repository_find_pkg(const char *pattern, const char *reason) { prop_dictionary_t pkg_repod = NULL, origin_pkgrd = NULL; - prop_dictionary_t transd, tmpd; + prop_dictionary_t transd; prop_array_t mdeps, unsorted; const char *pkgname; int rv = 0; - bool install, bypattern, bestpkg; + bool bypattern = false, bestpkg; pkg_state_t state = 0; assert(pattern != NULL); assert(reason != NULL); - install = bypattern = false; if (strcmp(reason, "install") == 0) { /* install */ - install = true; bypattern = true; bestpkg = false; } else { @@ -109,23 +106,6 @@ repository_find_pkg(const char *pattern, const char *reason) origin_pkgrd = prop_dictionary_copy(pkg_repod); prop_dictionary_get_cstring_nocopy(pkg_repod, "pkgname", &pkgname); - /* - * Check that this pkg hasn't been added previously into - * the transaction. - */ - if (install) { - tmpd = xbps_find_pkg_in_dict_by_pattern(transd, - "unsorted_pkgs", pattern); - } else { - tmpd = xbps_find_pkg_in_dict_by_name(transd, - "unsorted_pkgs", pattern); - - } - if (tmpd) { - xbps_dbg_printf("package '%s' already queued in transaction\n", - pattern); - goto out; - } /* * Prepare required package dependencies and add them into the * "unsorted" array in transaction dictionary. @@ -193,25 +173,17 @@ out: int xbps_repository_update_packages(void) { - prop_dictionary_t dict; + const struct xbps_handle *xhp; prop_object_t obj; prop_object_iterator_t iter; const char *pkgname; int rv = 0; bool newpkg_found = false; - /* - * Prepare dictionary with all registered packages. - */ - dict = xbps_regpkgdb_dictionary_get(); - if (dict == NULL) + xhp = xbps_handle_get(); + iter = xbps_array_iter_from_dict(xhp->regpkgdb_dictionary, "packages"); + if (iter == NULL) return ENOENT; - - iter = xbps_array_iter_from_dict(dict, "packages"); - if (iter == NULL) { - xbps_regpkgdb_dictionary_release(); - return ENOENT; - } /* * Find out if there is a newer version for all currently * installed packages. @@ -236,7 +208,6 @@ xbps_repository_update_packages(void) newpkg_found = true; } prop_object_iterator_release(iter); - xbps_regpkgdb_dictionary_release(); if (!newpkg_found) rv = ENXIO; diff --git a/lib/repository_pool.c b/lib/repository_pool.c index 82fdea4a..8a9cf72e 100644 --- a/lib/repository_pool.c +++ b/lib/repository_pool.c @@ -28,11 +28,8 @@ #include #include #include -#include -#include #include "xbps_api_impl.h" -#include "queue.h" /** * @file lib/repository_pool.c @@ -48,56 +45,32 @@ struct repository_pool { static SIMPLEQ_HEAD(rpool_head, repository_pool) rpool_queue = SIMPLEQ_HEAD_INITIALIZER(rpool_queue); -static size_t repolist_refcnt; static bool repolist_initialized; -static pthread_mutex_t mtx_refcnt = PTHREAD_MUTEX_INITIALIZER; -int +int HIDDEN xbps_repository_pool_init(void) { const struct xbps_handle *xhp; - prop_dictionary_t dict = NULL; prop_array_t array; prop_object_t obj; prop_object_iterator_t iter = NULL; struct repository_pool *rpool; size_t ntotal = 0, nmissing = 0; + const char *repouri; char *plist; int rv = 0; + bool duprepo; xhp = xbps_handle_get(); - xbps_dbg_printf("%s: repolist_refcnt %zu\n", __func__, repolist_refcnt); - if (repolist_initialized) { - pthread_mutex_lock(&mtx_refcnt); - repolist_refcnt++; - pthread_mutex_unlock(&mtx_refcnt); + if (repolist_initialized) return 0; - } - plist = xbps_xasprintf("%s/%s/%s", xhp->rootdir, - XBPS_META_PATH, XBPS_REPOLIST); - if (plist == NULL) { - rv = errno; - goto out; - } - - dict = prop_dictionary_internalize_from_zfile(plist); - if (dict == NULL) { - rv = errno; - free(plist); - xbps_dbg_printf("%s: cannot internalize plist %s: %s\n", - __func__, plist, strerror(errno)); - goto out; - } - free(plist); - - array = prop_dictionary_get(dict, "repository-list"); + array = prop_dictionary_get(xhp->conf_dictionary, "repositories"); if (array == NULL) { rv = errno; goto out; } - iter = prop_array_iterator(array); if (iter == NULL) { rv = errno; @@ -105,27 +78,58 @@ xbps_repository_pool_init(void) } while ((obj = prop_object_iterator_next(iter)) != NULL) { + /* + * Check that we do not register duplicate repositories. + */ + duprepo = false; + repouri = prop_string_cstring_nocopy(obj); + SIMPLEQ_FOREACH(rpool, &rpool_queue, rp_entries) { + if (strcmp(rpool->rpi->rpi_uri, repouri) == 0) { + duprepo = true; + break; + } + } + if (duprepo) + continue; + + plist = xbps_pkg_index_plist(repouri); + if (plist == NULL) { + rv = errno; + goto out; + } + /* + * For remote repositories, check that its pkg-index.plist + * file is there, otherwise we have to fetch it. + */ + if (xbps_check_is_repository_uri_remote(repouri)) { + if ((access(plist, R_OK) == -1) && errno == ENOENT) { + /* file not found, fetch it */ + xbps_printf("Synchronizing package index for " + "`%s'...\n", repouri); + if (xbps_repository_sync_pkg_index(repouri) == -1) { + xbps_error_printf("failed to fetch " + "pkg-index.plist for `%s': %s\n", + repouri, xbps_fetch_error_string()); + } + } + } ntotal++; /* * Iterate over the repository pool and add the dictionary * for current repository into the queue. */ - plist = - xbps_pkg_index_plist(prop_string_cstring_nocopy(obj)); - if (plist == NULL) { - rv = errno; - goto out; - } rpool = malloc(sizeof(struct repository_pool)); if (rpool == NULL) { rv = errno; + free(plist); goto out; } rpool->rpi = malloc(sizeof(struct repository_pool_index)); if (rpool->rpi == NULL) { rv = errno; + free(plist); free(rpool); goto out; } @@ -147,6 +151,8 @@ xbps_repository_pool_init(void) free(plist); if (errno == ENOENT) { errno = 0; + xbps_dbg_printf("%s: missing pkg-index.plist " + "for '%s' repository.\n", __func__, repouri); nmissing++; continue; } @@ -165,15 +171,10 @@ xbps_repository_pool_init(void) goto out; repolist_initialized = true; - pthread_mutex_lock(&mtx_refcnt); - repolist_refcnt = 1; - pthread_mutex_unlock(&mtx_refcnt); xbps_dbg_printf("%s: initialized ok.\n", __func__); out: if (iter) prop_object_iterator_release(iter); - if (dict) - prop_object_release(dict); if (rv != 0) xbps_repository_pool_release(); @@ -181,18 +182,12 @@ out: } -void +void HIDDEN xbps_repository_pool_release(void) { struct repository_pool *rpool; - size_t cnt; - pthread_mutex_lock(&mtx_refcnt); - cnt = repolist_refcnt--; - pthread_mutex_unlock(&mtx_refcnt); - - xbps_dbg_printf("%s: repolist_refcnt %zu\n", __func__, cnt); - if (cnt != 1) + if (!repolist_initialized) return; while ((rpool = SIMPLEQ_FIRST(&rpool_queue)) != NULL) { @@ -221,9 +216,7 @@ xbps_repository_pool_foreach( bool done = false; assert(fn != NULL); - - if (!repolist_initialized) - return EINVAL; + assert(repolist_initialized != false); SIMPLEQ_FOREACH_SAFE(rpool, &rpool_queue, rp_entries, rpool_new) { rv = (*fn)(rpool->rpi, arg, &done); @@ -354,6 +347,7 @@ xbps_repository_pool_find_pkg(const char *pkg, bool bypattern, bool best) int rv = 0; assert(pkg != NULL); + assert(repolist_initialized != false); rpf = calloc(1, sizeof(*rpf)); if (rpf == NULL) @@ -411,15 +405,11 @@ xbps_repository_pool_dictionary_metadata_plist(const char *pkgname, prop_dictionary_t pkgd = NULL, plistd = NULL; const char *repoloc; char *url; - int rv = 0; assert(pkgname != NULL); assert(plistf != NULL); + assert(repolist_initialized != false); - if ((rv = xbps_repository_pool_init()) != 0) { - errno = rv; - return NULL; - } /* * Iterate over the the repository pool and search for a plist file * in the binary package named 'pkgname'. The plist file will be @@ -443,7 +433,6 @@ xbps_repository_pool_dictionary_metadata_plist(const char *pkgname, free(url); out: - xbps_repository_pool_release(); if (plistd == NULL) errno = ENOENT; if (pkgd) diff --git a/lib/repository_register.c b/lib/repository_register.c deleted file mode 100644 index df8cd29a..00000000 --- a/lib/repository_register.c +++ /dev/null @@ -1,202 +0,0 @@ -/*- - * Copyright (c) 2008-2011 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" - -/** - * @file lib/repository_register.c - * @brief Repository registration routines - * @defgroup repo_register Repository registration functions - */ -int -xbps_repository_register(const char *uri) -{ - const struct xbps_handle *xhp; - prop_dictionary_t dict; - prop_array_t array; - prop_object_t obj = NULL; - char *plist; - int rv = 0; - - assert(uri != NULL); - xhp = xbps_handle_get(); - - plist = xbps_xasprintf("%s/%s/%s", xhp->rootdir, - XBPS_META_PATH, XBPS_REPOLIST); - if (plist == NULL) - return errno; - - /* First check if we have the repository plist file. */ - dict = prop_dictionary_internalize_from_zfile(plist); - if (dict == NULL) { - /* Looks like not, create it. */ - dict = prop_dictionary_create(); - if (dict == NULL) { - free(plist); - return errno; - } - /* Create the array and add the repository URI on it. */ - array = prop_array_create(); - if (array == NULL) { - rv = errno; - goto out; - } - - if (!prop_array_set_cstring_nocopy(array, 0, uri)) { - rv = errno; - goto out; - } - /* Add the array obj into the main dictionary. */ - if (!xbps_add_obj_to_dict(dict, array, "repository-list")) { - rv = errno; - goto out; - } - xbps_dbg_printf("Added repository into plist: %s\n", uri); - } else { - /* Append into the array, the plist file exists. */ - array = prop_dictionary_get(dict, "repository-list"); - if (array == NULL) { - rv = errno; - goto out; - } - /* It seems that this object is already there */ - if (xbps_find_string_in_array(array, uri)) { - rv = EEXIST; - goto out; - } - - obj = prop_string_create_cstring(uri); - if (!xbps_add_obj_to_array(array, obj)) { - prop_object_release(obj); - rv = errno; - goto out; - } - xbps_dbg_printf("Added repository into plist: %s\n", uri); - } - - /* Write dictionary into plist file. */ - if (!prop_dictionary_externalize_to_zfile(dict, plist)) { - rv = errno; - xbps_dbg_printf("%s: cannot externalize '%s' for '%s': %s\n", - __func__, plist, uri, strerror(errno)); - if (obj) - prop_object_release(obj); - } - -out: - prop_object_release(dict); - free(plist); - - return rv; -} - -int -xbps_repository_unregister(const char *uri) -{ - const struct xbps_handle *xhp; - prop_dictionary_t dict; - prop_array_t array; - const char *pkgindexdir; - char *plist, *pkgindex; - int rv = 0; - - assert(uri != NULL); - xhp = xbps_handle_get(); - - plist = xbps_xasprintf("%s/%s/%s", xhp->rootdir, - XBPS_META_PATH, XBPS_REPOLIST); - if (plist == NULL) - return errno; - - dict = prop_dictionary_internalize_from_zfile(plist); - if (dict == NULL) { - free(plist); - return errno; - } - - array = prop_dictionary_get(dict, "repository-list"); - if (array == NULL) { - rv = errno; - goto out; - } - - if (!xbps_remove_string_from_array(array, uri)) { - rv = errno; - goto out; - } - - /* Update plist file. */ - if (!prop_dictionary_externalize_to_zfile(dict, plist)) { - rv = errno; - goto out; - } - - xbps_dbg_printf("Removed repository from plist: %s\n", uri); - /* - * If it's a remote repository, also remove the stored XBPS_PKGINDEX - * file and its directory. - */ - if (xbps_check_is_repository_uri_remote(uri)) { - pkgindex = xbps_pkg_index_plist(uri); - if (pkgindex == NULL) { - rv = errno; - goto out; - } - - if (unlink(pkgindex) == -1) { - rv = errno; - if (errno == ENOENT) { - free(pkgindex); - goto out; - } - xbps_dbg_printf("%s cannot remove pkgindex file at " - "%s: %s\n", __func__, pkgindex, strerror(errno)); - free(pkgindex); - goto out; - } - pkgindexdir = dirname(pkgindex); - if (rmdir(pkgindexdir) == -1) { - rv = errno; - xbps_dbg_printf("%s: cannot remove pkgindex dir at " - "%s: %s\n", __func__, pkgindexdir, strerror(errno)); - free(pkgindex); - goto out; - } - free(pkgindex); - } - -out: - prop_object_release(dict); - free(plist); - - return rv; -} diff --git a/lib/repository_sync_index.c b/lib/repository_sync_index.c index 6908f111..faedaf31 100644 --- a/lib/repository_sync_index.c +++ b/lib/repository_sync_index.c @@ -30,7 +30,6 @@ #include #include -#include #include "xbps_api_impl.h" #include "fetch.h" diff --git a/lib/transaction_dictionary.c b/lib/transaction_dictionary.c index 55bb5871..93443116 100644 --- a/lib/transaction_dictionary.c +++ b/lib/transaction_dictionary.c @@ -29,7 +29,6 @@ #include #include -#include #include "xbps_api_impl.h" /** diff --git a/lib/transaction_sortdeps.c b/lib/transaction_sortdeps.c index bdbd1dad..833f588f 100644 --- a/lib/transaction_sortdeps.c +++ b/lib/transaction_sortdeps.c @@ -28,10 +28,7 @@ #include #include -#include #include "xbps_api_impl.h" -#include "queue.h" -#include "strlcpy.h" /* * Sorting algorithm for packages in the transaction dictionary. @@ -144,12 +141,31 @@ pkgdep_alloc(prop_dictionary_t d, const char *name, const char *trans) static void pkgdep_end(prop_array_t sorted) { + prop_dictionary_t sorted_pkgd; struct pkgdep *pd; + const char *trans; while ((pd = TAILQ_FIRST(&pkgdep_list)) != NULL) { TAILQ_REMOVE(&pkgdep_list, pd, pkgdep_entries); - if (sorted != NULL && pd->d != NULL) - prop_array_add(sorted, pd->d); + if (sorted != NULL && pd->d != NULL) { + /* + * Do not add duplicate pkg dictionaries with the + * same transaction reason into the sorted array. + */ + sorted_pkgd = xbps_find_pkg_in_array_by_name(sorted, + pd->name); + if (sorted_pkgd == NULL) { + prop_array_add(sorted, pd->d); + pkgdep_release(pd); + continue; + } + prop_dictionary_get_cstring_nocopy(sorted_pkgd, + "transaction", &trans); + if (strcmp(trans, pd->trans) == 0) { + pkgdep_release(pd); + continue; + } + } pkgdep_release(pd); } } diff --git a/lib/util.c b/lib/util.c index 21e03495..014460fa 100644 --- a/lib/util.c +++ b/lib/util.c @@ -46,7 +46,7 @@ #include "config.h" #include -#include + #include "xbps_api_impl.h" /**