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
This commit is contained in:
Juan RP 2011-06-04 13:37:53 +02:00
parent 2d6140f65b
commit 9673c4bd09
59 changed files with 1183 additions and 1416 deletions

View File

@ -1,7 +1,9 @@
XBPS includes the following software from third parties for XBPS includes the following software from third parties for
internal use in the code: internal use in the code:
- pkgmatch code from FreeBSD. - queue.h from NetBSD (include/queue.h).
- strlcat and strlcpy functions from OpenBSD. - package pattern matching code from NetBSD (lib/dewey.c lib/match.c).
- libfetch-2.31 from NetBSD. - strlcat and strlcpy functions from OpenBSD (lib/compat/strlc{at,cpy}.c)
- portableproplib-0.4.1 from http://code.google.com/p/portableproplib - libfetch-2.31 from NetBSD (lib/fetch).
- portableproplib-0.4.1 (lib/portableproplib) from
http://code.google.com/p/portableproplib

173
COPYING Normal file
View File

@ -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 <Todd.Miller@courtesan.com>
*
* 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.
*/

22
LICENSE
View File

@ -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.

View File

@ -1,6 +1,6 @@
-include config.mk -include config.mk
SUBDIRS = include lib bin SUBDIRS = include lib bin etc
ifdef BUILD_API_DOCS ifdef BUILD_API_DOCS
SUBDIRS += doc SUBDIRS += doc
@ -20,8 +20,10 @@ install:
@echo @echo
@echo "Binaries have been installed into $(DESTDIR)$(SBINDIR)." @echo "Binaries have been installed into $(DESTDIR)$(SBINDIR)."
@echo "Librares have been installed into $(DESTDIR)$(LIBDIR)." @echo "Librares have been installed into $(DESTDIR)$(LIBDIR)."
@echo "Configuration file has been installed into $(DESTDIR)$(ETCDIR)."
@echo @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 @echo
.PHONY: uninstall .PHONY: uninstall

23
NEWS
View File

@ -1,7 +1,26 @@
xbps-0.9.0 (???): xbps-0.9.0 (???):
* API/ABI break. Renamed some functions to reflect its description * Fixed some bugs with virtual packages, to not adding duplicate package
a bit better... expect some more breakage in the future as well. 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, * 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 and warns if any of them has been modified. For this to work, the package

2
TODO
View File

@ -1,8 +1,6 @@
- conflicts: the object is there but is not handled yet. - conflicts: the object is there but is not handled yet.
- properties: (hold) still unimplemented. - properties: (hold) still unimplemented.
- properties: (update-first) 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 - xbps-bin: a target to clean outdated binpkgs in cachedir
(like apt-get autoclean). (like apt-get autoclean).
- xbps-repo: support to verify PGP signed pkg-index.plist repo files - xbps-repo: support to verify PGP signed pkg-index.plist repo files

View File

@ -53,18 +53,15 @@
int int
xbps_check_pkg_integrity_all(void) xbps_check_pkg_integrity_all(void)
{ {
prop_dictionary_t d; const struct xbps_handle *xhp;
prop_object_t obj; prop_object_t obj;
prop_object_iterator_t iter = NULL; prop_object_iterator_t iter = NULL;
const char *pkgname, *version; const char *pkgname, *version;
int rv = 0; int rv = 0;
size_t npkgs = 0, nbrokenpkgs = 0; size_t npkgs = 0, nbrokenpkgs = 0;
d = xbps_regpkgdb_dictionary_get(); xhp = xbps_handle_get();
if (d == NULL) iter = xbps_array_iter_from_dict(xhp->regpkgdb_dictionary, "packages");
return ENODEV;
iter = xbps_array_iter_from_dict(d, "packages");
if (iter == NULL) { if (iter == NULL) {
rv = ENOENT; rv = ENOENT;
goto out; goto out;
@ -86,8 +83,6 @@ out:
if (iter) if (iter)
prop_object_iterator_release(iter); prop_object_iterator_release(iter);
xbps_regpkgdb_dictionary_release();
return rv; return rv;
} }

View File

@ -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))) { while ((obj = prop_object_iterator_next(iter))) {
prop_dictionary_get_cstring_nocopy(obj, "file", &filestr); prop_dictionary_get_cstring_nocopy(obj, "file", &filestr);
if ((strcmp(filestr, pattern) == 0) || 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); printf("%s: %s (%s)\n", pkgname, filestr, typestr);
} }
prop_object_iterator_release(iter); prop_object_iterator_release(iter);

View File

@ -181,13 +181,13 @@ unpack_progress_cb(void *data)
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
prop_dictionary_t dict; const struct xbps_handle *xhp;
struct xbps_handle xh; struct xbps_handle xh;
struct xbps_unpack_progress_data xupd; struct xbps_unpack_progress_data xupd;
struct xbps_fetch_progress_data xfpd; struct xbps_fetch_progress_data xfpd;
struct list_pkgver_cb lpc; struct list_pkgver_cb lpc;
struct sigaction sa; struct sigaction sa;
const char *rootdir, *cachedir; const char *rootdir, *cachedir, *conffile;
int i , c, flags, rv; int i , c, flags, rv;
bool yes, purge, with_debug, force_rm_with_deps, recursive_rm; bool yes, purge, with_debug, force_rm_with_deps, recursive_rm;
bool install_auto, install_manual, show_download_pkglist_url; 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; yes = purge = force_rm_with_deps = recursive_rm = with_debug = false;
install_auto = install_manual = show_download_pkglist_url = 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) { switch (c) {
case 'A': case 'A':
install_auto = true; install_auto = true;
break; break;
case 'C':
conffile = optarg;
break;
case 'c': case 'c':
cachedir = optarg; cachedir = optarg;
break; break;
@ -282,34 +285,23 @@ main(int argc, char **argv)
xh.rootdir = rootdir; xh.rootdir = rootdir;
xh.cachedir = cachedir; xh.cachedir = cachedir;
xh.flags = flags; xh.flags = flags;
xh.conffile = conffile;
xh.install_reason_manual = install_manual; xh.install_reason_manual = install_manual;
xh.install_reason_auto = install_auto; xh.install_reason_auto = install_auto;
xbps_init(&xh);
if ((dict = xbps_regpkgdb_dictionary_get()) == NULL) { if ((rv = xbps_init(&xh)) != 0) {
if (errno && errno != ENOENT) { xbps_error_printf("xbps-bin: couldn't initialize library: %s\n",
fprintf(stderr, strerror(errno));
"E: couldn't initialize regpkgdb dict: %s\n", exit(EXIT_FAILURE);
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;
}
} }
xhp = xbps_handle_get();
if (strcasecmp(argv[0], "list") == 0) { if (strcasecmp(argv[0], "list") == 0) {
/* Lists packages currently registered in database. */ /* Lists packages currently registered in database. */
if (argc < 1 || argc > 2) if (argc < 1 || argc > 2)
usage(); usage();
if (dict == NULL) { if (xhp->regpkgdb_dictionary == NULL) {
printf("No packages currently installed.\n"); printf("No packages currently installed.\n");
goto out; goto out;
} }
@ -335,9 +327,9 @@ main(int argc, char **argv)
/* /*
* Find the longest pkgver string to pretty print the output. * Find the longest pkgver string to pretty print the output.
*/ */
lpc.pkgver_len = find_longest_pkgver(dict); lpc.pkgver_len = find_longest_pkgver(xhp->regpkgdb_dictionary);
rv = xbps_callback_array_iter_in_dict(dict, "packages", rv = xbps_callback_array_iter_in_dict(xhp->regpkgdb_dictionary,
list_pkgs_in_dict, &lpc); "packages", list_pkgs_in_dict, &lpc);
} else if (strcasecmp(argv[0], "install") == 0) { } else if (strcasecmp(argv[0], "install") == 0) {
/* Installs a binary package and required deps. */ /* Installs a binary package and required deps. */
@ -472,8 +464,8 @@ main(int argc, char **argv)
if (argc != 1) if (argc != 1)
usage(); usage();
rv = xbps_callback_array_iter_in_dict(dict, "packages", rv = xbps_callback_array_iter_in_dict(xhp->regpkgdb_dictionary,
list_manual_packages, NULL); "packages", list_manual_packages, NULL);
} else if (strcasecmp(argv[0], "show-revdeps") == 0) { } else if (strcasecmp(argv[0], "show-revdeps") == 0) {
/* /*
@ -494,23 +486,6 @@ main(int argc, char **argv)
rv = find_files_in_packages(argv[1]); 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 { } else {
usage(); usage();
} }

View File

@ -37,31 +37,14 @@
int int
show_pkg_info_from_metadir(const char *pkgname) 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); d = xbps_dictionary_from_metadata_plist(pkgname, XBPS_PKGPROPS);
if (d == NULL) if (d == NULL)
return EINVAL; 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); show_pkg_info(d);
prop_object_release(d); prop_object_release(d);
out:
xbps_regpkgdb_dictionary_release();
return 0; return 0;
} }

View File

@ -187,7 +187,7 @@ show_pkg_files(prop_dictionary_t filesd)
prop_array_t array; prop_array_t array;
prop_object_iterator_t iter = NULL; prop_object_iterator_t iter = NULL;
prop_object_t obj; prop_object_t obj;
const char *file, *array_str; const char *file, *array_str, *target;
int i = 0; int i = 0;
/* This will print links, conf_files and files respectively. */ /* 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))) { while ((obj = prop_object_iterator_next(iter))) {
prop_dictionary_get_cstring_nocopy(obj, "file", &file); 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); prop_object_iterator_release(iter);
} }

View File

@ -1,13 +1,4 @@
'\" t .TH "XBPS\-BIN" "8" "06/04/2011" "\ \&" "\ \&"
.\" Title: xbps-bin
.\" Author: [see the "AUTHORS" section]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
.\" Date: 02/26/2011
.\" Manual: \ \&
.\" Source: \ \&
.\" Language: English
.\"
.TH "XBPS\-BIN" "8" "02/26/2011" "\ \&" "\ \&"
.\" ----------------------------------------------------------------- .\" -----------------------------------------------------------------
.\" * set default formatting .\" * set default formatting
.\" ----------------------------------------------------------------- .\" -----------------------------------------------------------------
@ -37,6 +28,11 @@ Use of this option takes effect in the \fIautoupdate\fR, \fIinstall\fR and
matched. matched.
.RE .RE
.PP .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 \fB\-c\fR \fIcachedir\fR
.RS 4 .RS 4
Sets the cache directory to store downloaded binary packages from remote repositories\&. By default it\(cqs set to 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\&. \fBremoved even if its SHA256 hash don\(cqt match\fR\&.
.RE .RE
.PP .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 \fBshow \fR\fB\fIpkgname\fR\fR
.RS 4 .RS 4
Shows information for installed package 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 .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\&. 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 .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 .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" .SH "FILES"
.PP .PP
\fB/etc/xbps-conf.plist\fR
.RS 4
Default XBPS configuration file\&.
.RE
.PP
\fB/var/db/xbps\fR \fB/var/db/xbps\fR
.RS 4 .RS 4
xbps global metadata directory\&. xbps global metadata directory\&.
@ -419,18 +374,6 @@ $ xbps\-bin \-yp remove proplib\-devel
$ xbps\-bin \-Rp remove bsdtar $ xbps\-bin \-Rp remove bsdtar
.RE .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" .SH "BUGS"
.sp .sp
Probably, but I try to make this not happen\&. Use it under your own responsability and enjoy your life\&. Probably, but I try to make this not happen\&. Use it under your own responsability and enjoy your life\&.

View File

@ -33,8 +33,6 @@
/* From index.c */ /* From index.c */
int xbps_repo_genindex(const char *); int xbps_repo_genindex(const char *);
/* From repository.c */ /* From repository.c */
int register_repository(const char *);
int unregister_repository(const char *);
int show_pkg_info_from_repolist(const char *); int show_pkg_info_from_repolist(const char *);
int show_pkg_deps_from_repolist(const char *); int show_pkg_deps_from_repolist(const char *);
int repository_sync(void); int repository_sync(void);

View File

@ -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); prop_dictionary_get_cstring_nocopy(obj, "file", &filestr);
if ((strcmp(filestr, pattern) == 0) || if ((strcmp(filestr, pattern) == 0) ||
(strstr(filestr, pattern)) || (strstr(filestr, pattern)) ||
(xbps_pkgpattern_match(filestr, __UNCONST(pattern)) == 1)) (xbps_pkgpattern_match(filestr, pattern) == 1))
printf(" %s: %s (%s)\n", pkgver, filestr, typestr); printf(" %s: %s (%s)\n", pkgver, filestr, typestr);
} }
prop_object_iterator_release(iter); prop_object_iterator_release(iter);

View File

@ -50,10 +50,16 @@ usage(void)
static int static int
repo_list_uri_cb(struct repository_pool_index *rpi, void *arg, bool *done) repo_list_uri_cb(struct repository_pool_index *rpi, void *arg, bool *done)
{ {
const char *pkgidx;
uint64_t npkgs;
(void)arg; (void)arg;
(void)done; (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; return 0;
} }
@ -80,19 +86,22 @@ main(int argc, char **argv)
struct xbps_handle xh; struct xbps_handle xh;
struct xbps_fetch_progress_data xfpd; struct xbps_fetch_progress_data xfpd;
prop_dictionary_t pkgd; prop_dictionary_t pkgd;
const char *rootdir, *cachedir; const char *rootdir = NULL, *cachedir = NULL, *conffile = NULL;
int c, rv = 0; int c, rv = 0;
bool with_debug = false; bool debug = false;
rootdir = cachedir = NULL; rootdir = cachedir = NULL;
while ((c = getopt(argc, argv, "Vc:dr:")) != -1) { while ((c = getopt(argc, argv, "C:c:dr:V")) != -1) {
switch (c) { switch (c) {
case 'C':
conffile = optarg;
break;
case 'c': case 'c':
cachedir = optarg; cachedir = optarg;
break; break;
case 'd': case 'd':
with_debug = true; debug = true;
break; break;
case 'r': case 'r':
/* To specify the root directory */ /* To specify the root directory */
@ -114,46 +123,29 @@ main(int argc, char **argv)
usage(); usage();
/* /*
* Initialize the function callbacks and debug in libxbps. * Initialize XBPS subsystems.
*/ */
memset(&xh, 0, sizeof(xh)); memset(&xh, 0, sizeof(xh));
xh.with_debug = with_debug; xh.with_debug = debug;
xh.xbps_fetch_cb = fetch_file_progress_cb; xh.xbps_fetch_cb = fetch_file_progress_cb;
xh.xfpd = &xfpd; xh.xfpd = &xfpd;
xh.rootdir = rootdir; xh.rootdir = rootdir;
xh.cachedir = cachedir; xh.cachedir = cachedir;
xbps_init(&xh); xh.conffile = conffile;
if ((rv = xbps_repository_pool_init()) != 0) { if ((rv = xbps_init(&xh)) != 0) {
if (rv != ENOENT) { xbps_error_printf("xbps-repo: couldn't initialize library: %s\n",
xbps_error_printf("xbps-repo: failed to initialize " strerror(errno));
"repository pool: %s\n", strerror(rv)); exit(EXIT_FAILURE);
exit(EXIT_FAILURE);
}
} }
if (strcasecmp(argv[0], "add") == 0) { if (strcasecmp(argv[0], "list") == 0) {
/* Adds a new repository to the pool. */
if (argc != 2)
usage();
rv = register_repository(argv[1]);
} else if (strcasecmp(argv[0], "list") == 0) {
/* Lists all repositories registered in pool. */ /* Lists all repositories registered in pool. */
if (argc != 1) if (argc != 1)
usage(); usage();
xbps_repository_pool_foreach(repo_list_uri_cb, NULL); 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) { } else if (strcasecmp(argv[0], "search") == 0) {
/* /*
* Search for a package by looking at pkgname/short_desc * Search for a package by looking at pkgname/short_desc

View File

@ -42,44 +42,6 @@ struct repoinfo {
uint64_t totalpkgs; 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 * static struct repoinfo *
pkgindex_verify(const char *plist, const char *uri) pkgindex_verify(const char *plist, const char *uri)
{ {
@ -137,106 +99,6 @@ out:
return rpi; 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 int
show_pkg_info_from_repolist(const char *pkgname) 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)) if (!xbps_check_is_repository_uri_remote(rpi->rpi_uri))
return 0; 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); rv = xbps_repository_sync_pkg_index(rpi->rpi_uri);
if (rv == -1) { if (rv == -1) {
xbps_error_printf("xbps-repo: failed to sync `%s': %s\n", xbps_error_printf("xbps-repo: failed to sync `%s': %s\n",

View File

@ -1,4 +1,4 @@
.TH "XBPS\-REPO" "8" "05/27/2011" "\ \&" "\ \&" .TH "XBPS\-REPO" "8" "06/04/2011" "\ \&" "\ \&"
.\" ----------------------------------------------------------------- .\" -----------------------------------------------------------------
.\" * set default formatting .\" * 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\&. 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" .SH "OPTIONS"
.PP .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 \fB\-c\fR \fIcachedir\fR
.RS 4 .RS 4
Sets the Sets the
@ -49,21 +54,12 @@ of
.PP .PP
\fB\-V\fR \fB\-V\fR
.RS 4 .RS 4
Shows the current XBPS release version (library and code)\&. Shows the current XBPS API and INDEX versions\&.
.RE .RE
.SH "TARGETS" .SH "TARGETS"
.sp .sp
Please note that all targets are \fBcase insensitive\fR\&. Please note that all targets are \fBcase insensitive\fR\&.
.PP .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 \fBfind\-files\fR \fIpattern\fR
.RS 4 .RS 4
Prints the name for any package registered in the repository pool, that owns Prints the name for any package registered in the repository pool, that owns
@ -86,18 +82,7 @@ will be removed automatically\&.
.PP .PP
\fBlist\fR \fBlist\fR
.RS 4 .RS 4
Lists all currently registered repositories in repository pool\&. Lists all working 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\&.
.RE .RE
.PP .PP
\fBsearch\fR \fIpattern\fR \fBsearch\fR \fIpattern\fR
@ -137,6 +122,11 @@ Syncs the package index file for all registered remote repositories\&. The new f
.RE .RE
.SH "FILES" .SH "FILES"
.PP .PP
\fB/etc/xbps-conf.plist\fR
.RS 4
Default XBPS configuration file\&.
.RE
.PP
\fB/var/db/xbps/repositories\&.plist\fR \fB/var/db/xbps/repositories\&.plist\fR
.RS 4 .RS 4
Registered repository list\&. Registered repository list\&.

View File

@ -60,6 +60,8 @@ write_plist_file(prop_dictionary_t dict, const char *file)
static void __attribute__((noreturn)) static void __attribute__((noreturn))
usage(void) usage(void)
{ {
xbps_end();
fprintf(stderr, fprintf(stderr,
"usage: xbps-uhelper [options] [action] [args]\n" "usage: xbps-uhelper [options] [action] [args]\n"
"\n" "\n"
@ -84,6 +86,7 @@ usage(void)
" version\t\t<pkgname>\n" " version\t\t<pkgname>\n"
"\n" "\n"
" Options shared by all actions:\n" " Options shared by all actions:\n"
" -C\t\tPath to xbps-conf.plist file.\n"
" -d\t\tDebugging messages to stderr.\n" " -d\t\tDebugging messages to stderr.\n"
" -r\t\t\t<rootdir>\n" " -r\t\t\t<rootdir>\n"
" -V\t\tPrints the xbps release version\n" " -V\t\tPrints the xbps release version\n"
@ -110,13 +113,16 @@ main(int argc, char **argv)
struct xbps_fetch_progress_data xfpd; struct xbps_fetch_progress_data xfpd;
prop_dictionary_t dict, pkgd; prop_dictionary_t dict, pkgd;
prop_array_t array; prop_array_t array;
const char *version, *rootdir = NULL; const char *version, *rootdir = NULL, *conffile = NULL;
char *plist, *pkgname, *pkgver, *in_chroot_env, *hash; char *plist, *pkgname, *pkgver, *in_chroot_env, *hash;
bool fromsrc = false, debug = false, in_chroot = false; bool fromsrc = false, debug = false, in_chroot = false;
int i, c, rv = 0; int i, c, rv = 0;
while ((c = getopt(argc, argv, "Vdr:")) != -1) { while ((c = getopt(argc, argv, "C:dr:V")) != -1) {
switch (c) { switch (c) {
case 'C':
conffile = optarg;
break;
case 'r': case 'r':
/* To specify the root directory */ /* To specify the root directory */
rootdir = optarg; rootdir = optarg;
@ -147,14 +153,18 @@ main(int argc, char **argv)
xh.xbps_fetch_cb = fetch_file_progress_cb; xh.xbps_fetch_cb = fetch_file_progress_cb;
xh.xfpd = &xfpd; xh.xfpd = &xfpd;
xh.rootdir = rootdir; 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, plist = xbps_xasprintf("%s/%s/%s", rootdir,
XBPS_META_PATH, XBPS_REGPKGDB); XBPS_META_PATH, XBPS_REGPKGDB);
if (plist == NULL) { if (plist == NULL) {
fprintf(stderr, xbps_end();
"%s=> ERROR: couldn't find regpkdb file (%s)%s\n",
MSG_ERROR, strerror(errno), MSG_RESET);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }

7
configure vendored
View File

@ -33,6 +33,7 @@ for instance \`--prefix=\$HOME'.
--includedir=DIR C header files [PREFIX/include] --includedir=DIR C header files [PREFIX/include]
--mandir=DIR man documentation [PREFIX/share/man] --mandir=DIR man documentation [PREFIX/share/man]
--datadir=DIR read-only architecture-independent data [PREFIX/share] --datadir=DIR read-only architecture-independent data [PREFIX/share]
--etcdir=DIR configuration files [PREFIX/etc]
--debug Build with debugging code and symbols --debug Build with debugging code and symbols
--silent Build silently, hidding compilation details. --silent Build silently, hidding compilation details.
@ -58,6 +59,7 @@ for x; do
--host) HOST=$var;; --host) HOST=$var;;
--target) TARGET=$var;; --target) TARGET=$var;;
--includedir) INCLUDEDIR=$var;; --includedir) INCLUDEDIR=$var;;
--etcdir) ETCDIR=$var;;
--libdir) LIBDIR=$var;; --libdir) LIBDIR=$var;;
--datadir|--infodir) ;; # ignore autotools --datadir|--infodir) ;; # ignore autotools
--with-api-docs) BUILD_API_DOCS=$var;; --with-api-docs) BUILD_API_DOCS=$var;;
@ -79,6 +81,7 @@ done
: ${SHAREDIR:=${PREFIX}/share} : ${SHAREDIR:=${PREFIX}/share}
: ${MANDIR:=${PREFIX}/share/man} : ${MANDIR:=${PREFIX}/share/man}
: ${INCLUDEDIR:=${PREFIX}/include} : ${INCLUDEDIR:=${PREFIX}/include}
: ${ETCDIR:=${PREFIX}/etc}
: ${TOPDIR:=..} : ${TOPDIR:=..}
_which() _which()
@ -137,6 +140,7 @@ echo "INCLUDEDIR ?= $INCLUDEDIR" >>$CONFIG_MK
echo "LIBDIR ?= $LIBDIR" >>$CONFIG_MK echo "LIBDIR ?= $LIBDIR" >>$CONFIG_MK
echo "MANDIR ?= $MANDIR" >>$CONFIG_MK echo "MANDIR ?= $MANDIR" >>$CONFIG_MK
echo "SHAREDIR ?= $SHAREDIR" >>$CONFIG_MK echo "SHAREDIR ?= $SHAREDIR" >>$CONFIG_MK
echo "ETCDIR ?= $ETCDIR" >>$CONFIG_MK
[ -z "$DEBUG" ] && DEBUG=no [ -z "$DEBUG" ] && DEBUG=no
[ -z "$BUILD_PIE" ] && BUILD_PIE_VAL=no [ -z "$BUILD_PIE" ] && BUILD_PIE_VAL=no
@ -172,6 +176,7 @@ if [ -n "$LDFLAGS" ]; then
fi fi
echo "CPPFLAGS = -I. -I\$(TOPDIR) -I\$(TOPDIR)/include" >>$CONFIG_MK echo "CPPFLAGS = -I. -I\$(TOPDIR) -I\$(TOPDIR)/include" >>$CONFIG_MK
echo "CPPFLAGS += -DHAVE_CONFIG_H" >>$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 if [ -n "$DEBUG" -a "$DEBUG" != no -a "$DEBUG" != false ]; then
echo "Building with debugging symbols." echo "Building with debugging symbols."
@ -510,6 +515,8 @@ echo " LIBDIR = $LIBDIR"
echo " INCLUDEDIR = $INCLUDEDIR" echo " INCLUDEDIR = $INCLUDEDIR"
echo " SHAREDIR = $SHAREDIR" echo " SHAREDIR = $SHAREDIR"
echo " MANDIR = $MANDIR" echo " MANDIR = $MANDIR"
echo " ETCDIR = $ETCDIR"
if [ -n "$CFLAGS" ]; then if [ -n "$CFLAGS" ]; then
echo " CFLAGS = $CFLAGS" echo " CFLAGS = $CFLAGS"
fi fi

19
etc/Makefile Normal file
View File

@ -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:

53
etc/xbps-conf.plist Normal file
View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>repositories</key>
<array>
<!-- You can specify here your list of repositories,
the first repository that contains a package will
be used for most targets in xbps-bin(8) and
xbps-repo(8), with the exception for updating
on which all repositories will be looked at and
the newest version will be choosen.
The order matters, and the top-most matching a package
pattern or name will be used.
By default we use the official "public" repository,
you can add your own local repositories by specifying
the path to the directory. -->
<string>http://xbps.nopcode.org/repos/stable</string>
</array>
<key>package-virtual</key>
<array>
<!-- This dictionary sets that we _always_ want
the "dcron" package to be the default cron-daemon
package, over other alternatives.
Another option might be to change it to the
"cronie" package, or any package that "provides"
"cron-daemon-0". -->
<dict>
<key>virtual-pkgver</key>
<string>cron-daemon-0</string>
<key>target-pkgpattern</key>
<string>dcron>=0</string>
</dict>
<!-- Uncomment this dictionary to prefer the "xbps-devel"
package (snapshot from mercurial repository) rather
than the official stable version (don't do this if
you are not a developer :-) -->
<!-- #### REMOVE THIS LINE TO ENABLE ####
<dict>
<key>virtual-pkgver</key>
<string>xbps-9999</string>
<key>target-pkgpattern</key>
<string>xbps-devel>=0</string>
</dict>
#### REMOVE THIS LINE TO ENABLE #### -->
</array>
</dict>
</plist>

View File

@ -59,7 +59,7 @@
* @def XBPS_RELVER * @def XBPS_RELVER
* Current library release date. * 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 * @def XBPS_META_PATH
@ -73,12 +73,6 @@
*/ */
#define XBPS_CACHE_PATH "/var/cache/xbps" #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 * @def XBPS_REGPKGDB
* Filename for the global package register database. * Filename for the global package register database.
@ -103,6 +97,19 @@
*/ */
#define XBPS_PKGINDEX "pkg-index.plist" #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 * @def XBPS_FLAG_VERBOSE
@ -138,6 +145,20 @@ void xbps_warn_printf(const char *, ...);
* the root and cache directory, flags, etc. * the root and cache directory, flags, etc.
*/ */
struct xbps_handle { 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 * @var xbps_unpack_cb
* *
@ -188,6 +209,12 @@ struct xbps_handle {
* If NULL default value in \a XBPS_CACHE_PATH is used. * If NULL default value in \a XBPS_CACHE_PATH is used.
*/ */
const char *cachedir; const char *cachedir;
/**
* @var conffile
*
* Full path to the XBPS_CONF_PLIST configuration file.
*/
const char *conffile;
/** /**
* @var with_debug * @var with_debug
* *
@ -217,16 +244,21 @@ struct xbps_handle {
* Initialize the XBPS library with the following steps: * Initialize the XBPS library with the following steps:
* *
* - Set function callbacks for fetching and unpacking. * - Set function callbacks for fetching and unpacking.
* - Set root directory. * - Set root directory (if not set, defaults to /).
* - Set cache directory. * - Set cache directory (if not set, defaults to XBPS_CACHE_PATH).
* - Set global flags. * - Set global flags.
* - Set default cache connections for libfetch. * - Set default cache connections for libfetch.
* - Initialize the debug printfs. * - 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 * @param[in] xh Pointer to an xbps_handle structure. It's
* assumed that this pointer is not NULL. * 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. * 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 * @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. * @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 */ /** @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 */ /** @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 */ /** @addtogroup repo_pkgs */
/*@{*/ /*@{*/
@ -993,29 +948,6 @@ struct repository_pool_index {
char *rpi_uri; 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 * Iterates over the repository pool and executes the \a fn function
* callback passing in the void * \a arg argument to it. The bool pointer * callback passing in the void * \a arg argument to it. The bool pointer

View File

@ -35,6 +35,10 @@
#include <archive_entry.h> #include <archive_entry.h>
#include <xbps_api.h> #include <xbps_api.h>
#include "queue.h"
#include "strlcpy.h"
#include "strlcat.h"
#include "fetch.h"
#define ARCHIVE_READ_BLOCKSIZE 10240 #define ARCHIVE_READ_BLOCKSIZE 10240
@ -74,6 +78,26 @@
__BEGIN_DECLS __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 * @private
* From lib/download.c * From lib/download.c

View File

@ -40,12 +40,12 @@ endif
OBJS = package_configure.o package_config_files.o package_orphans.o OBJS = package_configure.o package_config_files.o package_orphans.o
OBJS += package_remove.o package_remove_obsoletes.o package_state.o OBJS += package_remove.o package_remove_obsoletes.o package_state.o
OBJS += package_unpack.o package_requiredby.o package_register.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 += transaction_dictionary.o transaction_sortdeps.o
OBJS += cmpver.o download.o fexec.o humanize_number.o plist.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_archive_entry.o plist_find.o plist_remove.o
OBJS += plist_fetch.o util.o pkgmatch.o mkpath.o initend.o OBJS += plist_fetch.o util.o mkpath.o initend.o
OBJS += regpkgdb_dictionary.o repository_register.o OBJS += regpkgdb_dictionary.o match.o dewey.o
OBJS += repository_findpkg.o repository_finddeps.o OBJS += repository_findpkg.o repository_finddeps.o
OBJS += repository_pool.o repository_sync_index.o OBJS += repository_pool.o repository_sync_index.o
OBJS += $(COMPAT_SRCS) OBJS += $(COMPAT_SRCS)

View File

@ -25,7 +25,6 @@
#include <strings.h> #include <strings.h>
#include <ctype.h> #include <ctype.h>
#include <xbps_api.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
/* /*

View File

@ -19,7 +19,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <string.h> #include <string.h>
#include "strlcpy.h" #include "xbps_api_impl.h"
/* /*
* Copy src to string dst of size siz. At most siz-1 characters * Copy src to string dst of size siz. At most siz-1 characters

337
lib/dewey.c Normal file
View File

@ -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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <ctype.h>
#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;
}

View File

@ -40,7 +40,6 @@
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <xbps_api.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
#include "fetch.h" #include "fetch.h"

View File

@ -35,7 +35,6 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <xbps_api.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
static int static int

View File

@ -29,7 +29,6 @@
#include <errno.h> #include <errno.h>
#include <stdarg.h> #include <stdarg.h>
#include <xbps_api.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
/** /**
@ -43,9 +42,11 @@
static bool debug; static bool debug;
static struct xbps_handle *xhp; static struct xbps_handle *xhp;
void int
xbps_init(struct xbps_handle *xh) xbps_init(struct xbps_handle *xh)
{ {
int rv;
assert(xh != NULL); assert(xh != NULL);
xhp = xh; xhp = xh;
@ -59,6 +60,45 @@ xbps_init(struct xbps_handle *xh)
/* If cachedir not set, defaults to XBPS_CACHE_PATH */ /* If cachedir not set, defaults to XBPS_CACHE_PATH */
if (xhp->cachedir == NULL) if (xhp->cachedir == NULL)
xhp->cachedir = XBPS_CACHE_PATH; 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 void
@ -67,6 +107,12 @@ xbps_end(void)
xbps_regpkgdb_dictionary_release(); xbps_regpkgdb_dictionary_release();
xbps_repository_pool_release(); xbps_repository_pool_release();
xbps_fetch_unset_cache_connection(); 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; xhp = NULL;
} }

161
lib/match.c Normal file
View File

@ -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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fnmatch.h>
#include <ctype.h>
#include <sys/param.h>
#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;
}
}

View File

@ -36,7 +36,6 @@
#include <errno.h> #include <errno.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <xbps_api.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
int int

View File

@ -28,7 +28,6 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <xbps_api.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
/* /*

View File

@ -28,7 +28,6 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <xbps_api.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
/** /**
@ -51,21 +50,17 @@
int int
xbps_configure_packages(void) xbps_configure_packages(void)
{ {
prop_dictionary_t d; const struct xbps_handle *xhp;
prop_object_t obj; prop_object_t obj;
prop_object_iterator_t iter; prop_object_iterator_t iter;
const char *pkgname, *version; const char *pkgname, *version;
int rv = 0; 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; 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) { while ((obj = prop_object_iterator_next(iter)) != NULL) {
prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname);
prop_dictionary_get_cstring_nocopy(obj, "version", &version); prop_dictionary_get_cstring_nocopy(obj, "version", &version);
@ -74,8 +69,6 @@ xbps_configure_packages(void)
break; break;
} }
prop_object_iterator_release(iter); prop_object_iterator_release(iter);
out:
xbps_regpkgdb_dictionary_release();
return rv; return rv;
} }

View File

@ -29,7 +29,6 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <xbps_api.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
/** /**
@ -162,35 +161,30 @@ find_orphan_pkg(prop_object_t obj, void *arg, bool *loop_done)
prop_array_t prop_array_t
xbps_find_pkg_orphans(prop_array_t orphans_user) xbps_find_pkg_orphans(prop_array_t orphans_user)
{ {
const struct xbps_handle *xhp;
prop_array_t array = NULL; prop_array_t array = NULL;
prop_dictionary_t dict;
struct orphan_data od; struct orphan_data od;
int rv = 0; int rv = 0;
if ((dict = xbps_regpkgdb_dictionary_get()) == NULL) xhp = xbps_handle_get();
return NULL;
/* /*
* Prepare an array with all packages previously found. * Prepare an array with all packages previously found.
*/ */
if ((od.array = prop_array_create()) == NULL) if ((od.array = prop_array_create()) == NULL)
goto out; return NULL;
/* /*
* Find out all orphans by looking at the * Find out all orphans by looking at the
* regpkgdb dictionary and iterate in reverse order * regpkgdb dictionary and iterate in reverse order
* in which packages were installed. * in which packages were installed.
*/ */
od.orphans_user = orphans_user; od.orphans_user = orphans_user;
rv = xbps_callback_array_iter_reverse_in_dict(dict, "packages", rv = xbps_callback_array_iter_reverse_in_dict(xhp->regpkgdb_dictionary,
find_orphan_pkg, &od); "packages", find_orphan_pkg, &od);
if (rv != 0) { if (rv != 0) {
errno = rv; errno = rv;
prop_object_release(od.array); prop_object_release(od.array);
array = NULL; return NULL;
goto out;
} }
array = prop_array_copy(od.array); array = prop_array_copy(od.array);
out:
xbps_regpkgdb_dictionary_release();
return array; return array;
} }

View File

@ -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 <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <xbps_api.h>
#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;
}

View File

@ -29,7 +29,6 @@
#include <errno.h> #include <errno.h>
#include <dirent.h> #include <dirent.h>
#include <xbps_api.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
/** /**
@ -96,31 +95,23 @@ remove_pkg_metadata(const char *pkgname, const char *rootdir)
int int
xbps_purge_packages(void) xbps_purge_packages(void)
{ {
const struct xbps_handle *xhp;
prop_dictionary_t d;
prop_object_t obj; prop_object_t obj;
prop_object_iterator_t iter; prop_object_iterator_t iter;
const char *pkgname; const char *pkgname;
int rv = 0; 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; 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) { while ((obj = prop_object_iterator_next(iter)) != NULL) {
prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname);
if ((rv = xbps_purge_pkg(pkgname, true)) != 0) if ((rv = xbps_purge_pkg(pkgname, true)) != 0)
break; break;
} }
prop_object_iterator_release(iter); prop_object_iterator_release(iter);
out:
xbps_regpkgdb_dictionary_release();
return rv; return rv;
} }
@ -139,35 +130,31 @@ xbps_purge_pkg(const char *pkgname, bool check_state)
/* /*
* Firstly let's get the pkg dictionary from regpkgdb. * 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; return errno;
pkgd = xbps_find_pkg_in_dict_by_name(dict, "packages", pkgname);
if (pkgd == NULL) {
rv = errno;
goto out;
}
if (check_state) { if (check_state) {
/* /*
* Skip packages that aren't in "config-files" state. * Skip packages that aren't in "config-files" state.
*/ */
if ((rv = xbps_pkg_state_dictionary(pkgd, &state)) != 0) if ((rv = xbps_pkg_state_dictionary(pkgd, &state)) != 0)
goto out; return rv;
if (state != XBPS_PKG_STATE_CONFIG_FILES) if (state != XBPS_PKG_STATE_CONFIG_FILES)
goto out; return rv;
} }
/* /*
* Remove unmodified configuration files. * Remove unmodified configuration files.
*/ */
dict = xbps_dictionary_from_metadata_plist(pkgname, XBPS_PKGFILES); dict = xbps_dictionary_from_metadata_plist(pkgname, XBPS_PKGFILES);
if (dict == NULL) { if (dict == NULL)
rv = errno; return errno;
goto out;
}
if (prop_dictionary_get(dict, "conf_files")) { if (prop_dictionary_get(dict, "conf_files")) {
if ((rv = xbps_remove_pkg_files(dict, "conf_files")) != 0) { if ((rv = xbps_remove_pkg_files(dict, "conf_files")) != 0) {
prop_object_release(dict); 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); prop_object_release(dict);
xbps_error_printf("[purge] %s: cannot change to rootdir: %s.\n", xbps_error_printf("[purge] %s: cannot change to rootdir: %s.\n",
pkgname, strerror(rv)); pkgname, strerror(rv));
goto out; return rv;
} }
buf = xbps_xasprintf(".%s/metadata/%s/REMOVE", XBPS_META_PATH, pkgname); buf = xbps_xasprintf(".%s/metadata/%s/REMOVE", XBPS_META_PATH, pkgname);
if (buf == NULL) { if (buf == NULL) {
prop_object_release(dict); prop_object_release(dict);
rv = ENOMEM; rv = ENOMEM;
goto out; return rv;
} }
if (access(buf, X_OK) == 0) { if (access(buf, X_OK) == 0) {
prop_dictionary_get_cstring_nocopy(pkgd, "version", &version); 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, "REMOVE script: %s\n", pkgname,
strerror(errno)); strerror(errno));
prop_object_release(dict); 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) { if ((rv = remove_pkg_metadata(pkgname, xhp->rootdir)) != 0) {
xbps_error_printf("%s: couldn't remove metadata files: %s\n", xbps_error_printf("%s: couldn't remove metadata files: %s\n",
pkgname, strerror(rv)); pkgname, strerror(rv));
goto out; return rv;
} }
if ((rv = xbps_unregister_pkg(pkgname)) != 0) { if ((rv = xbps_unregister_pkg(pkgname)) != 0) {
xbps_error_printf("%s: couldn't unregister package: %s\n", xbps_error_printf("%s: couldn't unregister package: %s\n",
pkgname, strerror(rv)); pkgname, strerror(rv));
goto out; return rv;
} }
if (xhp->flags & XBPS_FLAG_VERBOSE) if (xhp->flags & XBPS_FLAG_VERBOSE)
xbps_printf("Package %s purged successfully.\n", pkgname); xbps_printf("Package %s purged successfully.\n", pkgname);
out:
xbps_regpkgdb_dictionary_release();
return rv; return rv;
} }

View File

@ -28,7 +28,6 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <xbps_api.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
/** /**

View File

@ -31,7 +31,6 @@
#include <dirent.h> #include <dirent.h>
#include <libgen.h> #include <libgen.h>
#include <xbps_api.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
/** /**

View File

@ -33,7 +33,6 @@
#include <unistd.h> #include <unistd.h>
#include <libgen.h> #include <libgen.h>
#include <xbps_api.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
int HIDDEN int HIDDEN

View File

@ -30,7 +30,6 @@
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
#include <xbps_api.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
int HIDDEN int HIDDEN
@ -41,7 +40,7 @@ xbps_repository_pkg_replaces(prop_dictionary_t transd,
prop_dictionary_t instd, reppkgd; prop_dictionary_t instd, reppkgd;
prop_object_t obj; prop_object_t obj;
prop_object_iterator_t iter; prop_object_iterator_t iter;
const char *pattern; const char *pattern, *pkgname, *curpkgname;
replaces = prop_dictionary_get(pkg_repod, "replaces"); replaces = prop_dictionary_get(pkg_repod, "replaces");
if (replaces == NULL || prop_array_count(replaces) == 0) 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); instd = xbps_find_pkg_dict_installed(pattern, true);
if (instd == NULL) if (instd == NULL)
continue; 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 contains replaces="pkgpattern", but the
* package that should be replaced is also in the * package that should be replaced is also in the

View File

@ -29,7 +29,6 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <xbps_api.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
static int static int

View File

@ -29,7 +29,6 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <xbps_api.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
struct state { struct state {

View File

@ -32,7 +32,6 @@
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <xbps_api.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
/** /**

View File

@ -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 <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <ctype.h>
#include <limits.h>
#include <fnmatch.h>
#include <xbps_api.h>
#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;
}

View File

@ -29,7 +29,6 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <xbps_api.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
/** /**

View File

@ -28,9 +28,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <zlib.h> #include <zlib.h>
#include <xbps_api.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
/* /*

View File

@ -31,7 +31,6 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <xbps_api.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
#include "fetch.h" #include "fetch.h"

View File

@ -29,7 +29,6 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <xbps_api.h>
#include "xbps_api_impl.h" #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, if (!prop_dictionary_get_cstring_nocopy(obj,
"pkgver", &pkgver)) "pkgver", &pkgver))
continue; continue;
if (xbps_pkgpattern_match(pkgver, __UNCONST(str))) if (xbps_pkgpattern_match(pkgver, str))
break; break;
} else { } else {
if (!prop_dictionary_get_cstring_nocopy(obj, 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 * 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; const struct xbps_handle *xhp;
prop_dictionary_t d;
prop_object_iterator_t iter; prop_object_iterator_t iter;
prop_object_t obj; prop_object_t obj;
const char *pkg = NULL; const char *vpkgver, *pkg = NULL;
bool found = false; 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; 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) { while ((obj = prop_object_iterator_next(iter)) != NULL) {
virtual = prop_dictionary_get(obj, "provides"); if (!prop_dictionary_get_cstring_nocopy(obj,
if (virtual == NULL) "virtual-pkgver", &vpkgver))
continue; continue;
if (bypattern)
found = xbps_find_pkgpattern_in_array(virtual, virtualpkg);
else
found = xbps_find_pkgname_in_array(virtual, virtualpkg);
if (!found) if (bypattern) {
continue; if (xbps_pkgpattern_match(vpkgver, vpkg)) {
if (bypattern) prop_dictionary_get_cstring_nocopy(obj,
prop_dictionary_get_cstring_nocopy(obj, "target-pkgpattern", &pkg);
"pkgpattern", &pkg); break;
else }
prop_dictionary_get_cstring_nocopy(obj, } else {
"pkgname", &pkg); vpkgname = xbps_pkgpattern_name(vpkgver);
if (vpkgname == NULL)
break; break;
if (strcmp(vpkg, vpkgname) == 0) {
pkg = vpkgname;
free(vpkgname);
break;
}
}
} }
prop_object_iterator_release(iter); prop_object_iterator_release(iter);
xbps_regpkgdb_dictionary_release();
return pkg; return pkg;
} }
@ -219,7 +218,7 @@ find_virtualpkg_user_in_array(prop_array_t array,
assert(array != NULL); assert(array != NULL);
assert(str != NULL); assert(str != NULL);
virtualpkg = find_virtualpkg_user_in_regpkgdb(str, bypattern); virtualpkg = find_virtualpkg_user_in_conf(str, bypattern);
if (virtualpkg == NULL) if (virtualpkg == NULL)
return NULL; return NULL;
@ -231,8 +230,7 @@ find_virtualpkg_user_in_array(prop_array_t array,
if (bypattern) { if (bypattern) {
prop_dictionary_get_cstring_nocopy(obj, prop_dictionary_get_cstring_nocopy(obj,
"pkgver", &pkgver); "pkgver", &pkgver);
if (xbps_pkgpattern_match(pkgver, if (xbps_pkgpattern_match(pkgver, virtualpkg))
__UNCONST(virtualpkg)))
break; break;
} else { } else {
prop_dictionary_get_cstring_nocopy(obj, 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 prop_dictionary_t
xbps_find_pkg_dict_installed(const char *str, bool bypattern) 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; pkg_state_t state = 0;
assert(str != NULL); assert(str != NULL);
if ((d = xbps_regpkgdb_dictionary_get()) == NULL) xhp = xbps_handle_get();
if (xhp->regpkgdb_dictionary == NULL)
return 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) if (pkgd == NULL)
goto out; return rpkgd;
if (xbps_pkg_state_dictionary(pkgd, &state) != 0) if (xbps_pkg_state_dictionary(pkgd, &state) != 0)
goto out; return rpkgd;
switch (state) { switch (state) {
case XBPS_PKG_STATE_INSTALLED: case XBPS_PKG_STATE_INSTALLED:
@ -331,8 +332,7 @@ xbps_find_pkg_dict_installed(const char *str, bool bypattern)
default: default:
break; break;
} }
out:
xbps_regpkgdb_dictionary_release();
return rpkgd; return rpkgd;
} }
@ -375,7 +375,7 @@ find_string_in_array(prop_array_t array, const char *str, int mode)
} else if (mode == 2) { } else if (mode == 2) {
/* match by pkgpattern */ /* match by pkgpattern */
pkgdep = prop_string_cstring_nocopy(obj); pkgdep = prop_string_cstring_nocopy(obj);
if (xbps_pkgpattern_match(pkgdep, __UNCONST(str))) { if (xbps_pkgpattern_match(pkgdep, str)) {
found = true; found = true;
break; break;
} }

View File

@ -29,7 +29,6 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <xbps_api.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
/** /**

View File

@ -28,9 +28,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <pthread.h>
#include <xbps_api.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
/** /**
@ -58,63 +56,47 @@
* dictionary. * dictionary.
*/ */
static prop_dictionary_t regpkgdb_dict;
static size_t regpkgdb_refcnt;
static bool regpkgdb_initialized; static bool regpkgdb_initialized;
static pthread_mutex_t refcnt_mtx = PTHREAD_MUTEX_INITIALIZER;
prop_dictionary_t int HIDDEN
xbps_regpkgdb_dictionary_get(void) xbps_regpkgdb_dictionary_init(struct xbps_handle *xhp)
{ {
const struct xbps_handle *xhp;
char *plist; char *plist;
if (regpkgdb_initialized) { if (regpkgdb_initialized)
pthread_mutex_lock(&refcnt_mtx); return 0;
regpkgdb_refcnt++;
pthread_mutex_unlock(&refcnt_mtx);
return regpkgdb_dict;
}
xhp = xbps_handle_get();
plist = xbps_xasprintf("%s/%s/%s", xhp->rootdir, plist = xbps_xasprintf("%s/%s/%s", xhp->rootdir,
XBPS_META_PATH, XBPS_REGPKGDB); XBPS_META_PATH, XBPS_REGPKGDB);
if (plist == NULL) if (plist == NULL)
return NULL; return ENOMEM;
regpkgdb_dict = prop_dictionary_internalize_from_zfile(plist); xhp->regpkgdb_dictionary =
if (regpkgdb_dict == NULL) { prop_dictionary_internalize_from_zfile(plist);
if (xhp->regpkgdb_dictionary == NULL) {
free(plist); free(plist);
if (errno != ENOENT) if (errno != ENOENT)
xbps_dbg_printf("[regpkgdb] cannot internalize " xbps_dbg_printf("[regpkgdb] cannot internalize "
"regpkgdb_dict %s\n", strerror(errno)); "regpkgdb dictionary: %s\n", strerror(errno));
return NULL; return errno;
} }
free(plist); free(plist);
regpkgdb_initialized = true; regpkgdb_initialized = true;
xbps_dbg_printf("%s: initialized ok.\n", __func__); xbps_dbg_printf("%s: initialized ok.\n", __func__);
pthread_mutex_lock(&refcnt_mtx); return 0;
regpkgdb_refcnt = 1;
pthread_mutex_unlock(&refcnt_mtx);
return regpkgdb_dict;
} }
void void HIDDEN
xbps_regpkgdb_dictionary_release(void) xbps_regpkgdb_dictionary_release(void)
{ {
size_t cnt; const struct xbps_handle *xhp;
pthread_mutex_lock(&refcnt_mtx); if (!regpkgdb_initialized)
cnt = regpkgdb_refcnt--;
pthread_mutex_unlock(&refcnt_mtx);
if (cnt != 1)
return; return;
prop_object_release(regpkgdb_dict); xhp = xbps_handle_get();
regpkgdb_dict = NULL; prop_object_release(xhp->regpkgdb_dictionary);
regpkgdb_initialized = false; regpkgdb_initialized = false;
xbps_dbg_printf("%s: released ok.\n", __func__); xbps_dbg_printf("%s: released ok.\n", __func__);
} }

View File

@ -28,7 +28,6 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <xbps_api.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
static int static int
@ -36,7 +35,7 @@ store_dependency(prop_dictionary_t transd, prop_dictionary_t repo_pkgd)
{ {
prop_dictionary_t dict; prop_dictionary_t dict;
prop_array_t array; prop_array_t array;
const char *pkgname, *pkgver, *repoloc; const char *pkgname, *pkgver, *repoloc, *reason;
int rv = 0; int rv = 0;
pkg_state_t state = 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); prop_object_release(dict);
return errno; 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 * Overwrite package state in dictionary with same state than the
* package currently uses, otherwise not-installed. * 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); prop_object_release(dict);
return rv; return rv;
} }
/* pkg not installed */
state = XBPS_PKG_STATE_NOT_INSTALLED; state = XBPS_PKG_STATE_NOT_INSTALLED;
} }
if ((rv = xbps_set_pkg_state_dictionary(dict, state)) != 0) { if ((rv = xbps_set_pkg_state_dictionary(dict, state)) != 0) {
prop_object_release(dict); prop_object_release(dict);
return rv; 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. * Add required objects into package dep's dictionary.
*/ */
@ -321,7 +326,7 @@ find_repo_deps(prop_dictionary_t transd, /* transaction dictionary */
break; break;
} }
free(pkgname); free(pkgname);
rv = xbps_pkgpattern_match(pkgver_q, __UNCONST(reqpkg)); rv = xbps_pkgpattern_match(pkgver_q, reqpkg);
if (rv == 0) { if (rv == 0) {
/* /*
* Package is installed but does not match * Package is installed but does not match

View File

@ -29,7 +29,6 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <xbps_api.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
/** /**
@ -56,20 +55,18 @@ static int
repository_find_pkg(const char *pattern, const char *reason) repository_find_pkg(const char *pattern, const char *reason)
{ {
prop_dictionary_t pkg_repod = NULL, origin_pkgrd = NULL; prop_dictionary_t pkg_repod = NULL, origin_pkgrd = NULL;
prop_dictionary_t transd, tmpd; prop_dictionary_t transd;
prop_array_t mdeps, unsorted; prop_array_t mdeps, unsorted;
const char *pkgname; const char *pkgname;
int rv = 0; int rv = 0;
bool install, bypattern, bestpkg; bool bypattern = false, bestpkg;
pkg_state_t state = 0; pkg_state_t state = 0;
assert(pattern != NULL); assert(pattern != NULL);
assert(reason != NULL); assert(reason != NULL);
install = bypattern = false;
if (strcmp(reason, "install") == 0) { if (strcmp(reason, "install") == 0) {
/* install */ /* install */
install = true;
bypattern = true; bypattern = true;
bestpkg = false; bestpkg = false;
} else { } else {
@ -109,23 +106,6 @@ repository_find_pkg(const char *pattern, const char *reason)
origin_pkgrd = prop_dictionary_copy(pkg_repod); origin_pkgrd = prop_dictionary_copy(pkg_repod);
prop_dictionary_get_cstring_nocopy(pkg_repod, "pkgname", &pkgname); 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 * Prepare required package dependencies and add them into the
* "unsorted" array in transaction dictionary. * "unsorted" array in transaction dictionary.
@ -193,25 +173,17 @@ out:
int int
xbps_repository_update_packages(void) xbps_repository_update_packages(void)
{ {
prop_dictionary_t dict; const struct xbps_handle *xhp;
prop_object_t obj; prop_object_t obj;
prop_object_iterator_t iter; prop_object_iterator_t iter;
const char *pkgname; const char *pkgname;
int rv = 0; int rv = 0;
bool newpkg_found = false; bool newpkg_found = false;
/* xhp = xbps_handle_get();
* Prepare dictionary with all registered packages. iter = xbps_array_iter_from_dict(xhp->regpkgdb_dictionary, "packages");
*/ if (iter == NULL)
dict = xbps_regpkgdb_dictionary_get();
if (dict == NULL)
return ENOENT; 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 * Find out if there is a newer version for all currently
* installed packages. * installed packages.
@ -236,7 +208,6 @@ xbps_repository_update_packages(void)
newpkg_found = true; newpkg_found = true;
} }
prop_object_iterator_release(iter); prop_object_iterator_release(iter);
xbps_regpkgdb_dictionary_release();
if (!newpkg_found) if (!newpkg_found)
rv = ENXIO; rv = ENXIO;

View File

@ -28,11 +28,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <pthread.h>
#include <xbps_api.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
#include "queue.h"
/** /**
* @file lib/repository_pool.c * @file lib/repository_pool.c
@ -48,56 +45,32 @@ struct repository_pool {
static SIMPLEQ_HEAD(rpool_head, repository_pool) rpool_queue = static SIMPLEQ_HEAD(rpool_head, repository_pool) rpool_queue =
SIMPLEQ_HEAD_INITIALIZER(rpool_queue); SIMPLEQ_HEAD_INITIALIZER(rpool_queue);
static size_t repolist_refcnt;
static bool repolist_initialized; static bool repolist_initialized;
static pthread_mutex_t mtx_refcnt = PTHREAD_MUTEX_INITIALIZER;
int int HIDDEN
xbps_repository_pool_init(void) xbps_repository_pool_init(void)
{ {
const struct xbps_handle *xhp; const struct xbps_handle *xhp;
prop_dictionary_t dict = NULL;
prop_array_t array; prop_array_t array;
prop_object_t obj; prop_object_t obj;
prop_object_iterator_t iter = NULL; prop_object_iterator_t iter = NULL;
struct repository_pool *rpool; struct repository_pool *rpool;
size_t ntotal = 0, nmissing = 0; size_t ntotal = 0, nmissing = 0;
const char *repouri;
char *plist; char *plist;
int rv = 0; int rv = 0;
bool duprepo;
xhp = xbps_handle_get(); xhp = xbps_handle_get();
xbps_dbg_printf("%s: repolist_refcnt %zu\n", __func__, repolist_refcnt);
if (repolist_initialized) { if (repolist_initialized)
pthread_mutex_lock(&mtx_refcnt);
repolist_refcnt++;
pthread_mutex_unlock(&mtx_refcnt);
return 0; return 0;
}
plist = xbps_xasprintf("%s/%s/%s", xhp->rootdir, array = prop_dictionary_get(xhp->conf_dictionary, "repositories");
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");
if (array == NULL) { if (array == NULL) {
rv = errno; rv = errno;
goto out; goto out;
} }
iter = prop_array_iterator(array); iter = prop_array_iterator(array);
if (iter == NULL) { if (iter == NULL) {
rv = errno; rv = errno;
@ -105,27 +78,58 @@ xbps_repository_pool_init(void)
} }
while ((obj = prop_object_iterator_next(iter)) != NULL) { 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++; ntotal++;
/* /*
* Iterate over the repository pool and add the dictionary * Iterate over the repository pool and add the dictionary
* for current repository into the queue. * 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)); rpool = malloc(sizeof(struct repository_pool));
if (rpool == NULL) { if (rpool == NULL) {
rv = errno; rv = errno;
free(plist);
goto out; goto out;
} }
rpool->rpi = malloc(sizeof(struct repository_pool_index)); rpool->rpi = malloc(sizeof(struct repository_pool_index));
if (rpool->rpi == NULL) { if (rpool->rpi == NULL) {
rv = errno; rv = errno;
free(plist);
free(rpool); free(rpool);
goto out; goto out;
} }
@ -147,6 +151,8 @@ xbps_repository_pool_init(void)
free(plist); free(plist);
if (errno == ENOENT) { if (errno == ENOENT) {
errno = 0; errno = 0;
xbps_dbg_printf("%s: missing pkg-index.plist "
"for '%s' repository.\n", __func__, repouri);
nmissing++; nmissing++;
continue; continue;
} }
@ -165,15 +171,10 @@ xbps_repository_pool_init(void)
goto out; goto out;
repolist_initialized = true; repolist_initialized = true;
pthread_mutex_lock(&mtx_refcnt);
repolist_refcnt = 1;
pthread_mutex_unlock(&mtx_refcnt);
xbps_dbg_printf("%s: initialized ok.\n", __func__); xbps_dbg_printf("%s: initialized ok.\n", __func__);
out: out:
if (iter) if (iter)
prop_object_iterator_release(iter); prop_object_iterator_release(iter);
if (dict)
prop_object_release(dict);
if (rv != 0) if (rv != 0)
xbps_repository_pool_release(); xbps_repository_pool_release();
@ -181,18 +182,12 @@ out:
} }
void void HIDDEN
xbps_repository_pool_release(void) xbps_repository_pool_release(void)
{ {
struct repository_pool *rpool; struct repository_pool *rpool;
size_t cnt;
pthread_mutex_lock(&mtx_refcnt); if (!repolist_initialized)
cnt = repolist_refcnt--;
pthread_mutex_unlock(&mtx_refcnt);
xbps_dbg_printf("%s: repolist_refcnt %zu\n", __func__, cnt);
if (cnt != 1)
return; return;
while ((rpool = SIMPLEQ_FIRST(&rpool_queue)) != NULL) { while ((rpool = SIMPLEQ_FIRST(&rpool_queue)) != NULL) {
@ -221,9 +216,7 @@ xbps_repository_pool_foreach(
bool done = false; bool done = false;
assert(fn != NULL); assert(fn != NULL);
assert(repolist_initialized != false);
if (!repolist_initialized)
return EINVAL;
SIMPLEQ_FOREACH_SAFE(rpool, &rpool_queue, rp_entries, rpool_new) { SIMPLEQ_FOREACH_SAFE(rpool, &rpool_queue, rp_entries, rpool_new) {
rv = (*fn)(rpool->rpi, arg, &done); 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; int rv = 0;
assert(pkg != NULL); assert(pkg != NULL);
assert(repolist_initialized != false);
rpf = calloc(1, sizeof(*rpf)); rpf = calloc(1, sizeof(*rpf));
if (rpf == NULL) if (rpf == NULL)
@ -411,15 +405,11 @@ xbps_repository_pool_dictionary_metadata_plist(const char *pkgname,
prop_dictionary_t pkgd = NULL, plistd = NULL; prop_dictionary_t pkgd = NULL, plistd = NULL;
const char *repoloc; const char *repoloc;
char *url; char *url;
int rv = 0;
assert(pkgname != NULL); assert(pkgname != NULL);
assert(plistf != 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 * Iterate over the the repository pool and search for a plist file
* in the binary package named 'pkgname'. The plist file will be * 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); free(url);
out: out:
xbps_repository_pool_release();
if (plistd == NULL) if (plistd == NULL)
errno = ENOENT; errno = ENOENT;
if (pkgd) if (pkgd)

View File

@ -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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <libgen.h>
#include <xbps_api.h>
#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;
}

View File

@ -30,7 +30,6 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <xbps_api.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
#include "fetch.h" #include "fetch.h"

View File

@ -29,7 +29,6 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <xbps_api.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
/** /**

View File

@ -28,10 +28,7 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <xbps_api.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
#include "queue.h"
#include "strlcpy.h"
/* /*
* Sorting algorithm for packages in the transaction dictionary. * 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 static void
pkgdep_end(prop_array_t sorted) pkgdep_end(prop_array_t sorted)
{ {
prop_dictionary_t sorted_pkgd;
struct pkgdep *pd; struct pkgdep *pd;
const char *trans;
while ((pd = TAILQ_FIRST(&pkgdep_list)) != NULL) { while ((pd = TAILQ_FIRST(&pkgdep_list)) != NULL) {
TAILQ_REMOVE(&pkgdep_list, pd, pkgdep_entries); TAILQ_REMOVE(&pkgdep_list, pd, pkgdep_entries);
if (sorted != NULL && pd->d != NULL) if (sorted != NULL && pd->d != NULL) {
prop_array_add(sorted, pd->d); /*
* 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); pkgdep_release(pd);
} }
} }

View File

@ -46,7 +46,7 @@
#include "config.h" #include "config.h"
#include <openssl/sha.h> #include <openssl/sha.h>
#include <xbps_api.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
/** /**