Added the concept of package properties in the API.
See the NEWS file and xbps-bin(8) for more information.
This commit is contained in:
parent
d25bc35711
commit
de296d8192
18
NEWS
18
NEWS
@ -1,5 +1,23 @@
|
|||||||
xbps-0.8.0 (???):
|
xbps-0.8.0 (???):
|
||||||
|
|
||||||
|
* Added the concept of package properties in the API. At this moment
|
||||||
|
only one property is fully working, "virtual". When xbps-bin(8)
|
||||||
|
sets this property for a package, its virtual package list will be
|
||||||
|
set in the XBPS_REGPKGDB plist in a package dictionary and the matching
|
||||||
|
logic will always prefer its virtual packages over the real ones.
|
||||||
|
You can do wonderful things with this, like always using development
|
||||||
|
package versions, or simply customize what packages you want to
|
||||||
|
install rather than the default ones. As a real example, you can now
|
||||||
|
use the 'xbps-devel' package rather than the stable package version
|
||||||
|
'xbps' before installing the system and package dependencies will
|
||||||
|
still be resolved:
|
||||||
|
|
||||||
|
"$ xbps-bin set-prop virtual xbps-devel"
|
||||||
|
"$ xbps-bin install xbps-base-system"
|
||||||
|
|
||||||
|
Only packages that have the "provides" object are valid for the
|
||||||
|
"virtual" property.
|
||||||
|
|
||||||
* Moved the "replaces" handling logic into the API. But instead of
|
* Moved the "replaces" handling logic into the API. But instead of
|
||||||
removing any package, the packages that should be replaced are
|
removing any package, the packages that should be replaced are
|
||||||
added into the transaction dictionary and marked as "remove".
|
added into the transaction dictionary and marked as "remove".
|
||||||
|
@ -46,6 +46,7 @@ struct list_pkgver_cb {
|
|||||||
static void __attribute__((noreturn))
|
static void __attribute__((noreturn))
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
|
xbps_end();
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Usage: xbps-bin [options] [target] [arguments]\n"
|
"Usage: xbps-bin [options] [target] [arguments]\n"
|
||||||
"See xbps-bin(8) for more information.\n");
|
"See xbps-bin(8) for more information.\n");
|
||||||
@ -434,6 +435,23 @@ 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();
|
||||||
}
|
}
|
||||||
|
@ -37,15 +37,31 @@
|
|||||||
int
|
int
|
||||||
show_pkg_info_from_metadir(const char *pkgname)
|
show_pkg_info_from_metadir(const char *pkgname)
|
||||||
{
|
{
|
||||||
prop_dictionary_t d;
|
prop_dictionary_t d, regpkgd, pkgpropsd;
|
||||||
|
|
||||||
d = xbps_get_pkg_dict_from_metadata_plist(pkgname, XBPS_PKGPROPS);
|
d = xbps_get_pkg_dict_from_metadata_plist(pkgname, XBPS_PKGPROPS);
|
||||||
if (d == NULL)
|
if (d == NULL)
|
||||||
return errno;
|
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, false);
|
||||||
|
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, false);
|
show_pkg_info(d, false);
|
||||||
prop_object_release(d);
|
prop_object_release(d);
|
||||||
|
out:
|
||||||
|
xbps_regpkgdb_dictionary_release();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +73,7 @@ show_pkg_files_from_metadir(const char *pkgname)
|
|||||||
|
|
||||||
d = xbps_get_pkg_dict_from_metadata_plist(pkgname, XBPS_PKGFILES);
|
d = xbps_get_pkg_dict_from_metadata_plist(pkgname, XBPS_PKGFILES);
|
||||||
if (d == NULL)
|
if (d == NULL)
|
||||||
return errno;
|
return EINVAL;
|
||||||
|
|
||||||
rv = show_pkg_files(d);
|
rv = show_pkg_files(d);
|
||||||
prop_object_release(d);
|
prop_object_release(d);
|
||||||
|
@ -1,4 +1,13 @@
|
|||||||
.TH "XBPS\-BIN" "8" "30/01/2011" "\ \&" "\ \&"
|
'\" t
|
||||||
|
.\" Title: xbps-bin
|
||||||
|
.\" Author: [see the "AUTHORS" section]
|
||||||
|
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
|
||||||
|
.\" Date: 02/05/2011
|
||||||
|
.\" Manual: \ \&
|
||||||
|
.\" Source: \ \&
|
||||||
|
.\" Language: English
|
||||||
|
.\"
|
||||||
|
.TH "XBPS\-BIN" "8" "02/05/2011" "\ \&" "\ \&"
|
||||||
.\" -----------------------------------------------------------------
|
.\" -----------------------------------------------------------------
|
||||||
.\" * set default formatting
|
.\" * set default formatting
|
||||||
.\" -----------------------------------------------------------------
|
.\" -----------------------------------------------------------------
|
||||||
@ -16,18 +25,15 @@ xbps-bin \- XBPS command for binary packages
|
|||||||
\fBxbps\-bin\fR [\fIoptions\fR] \fItarget\fR [\fIpkgname\fR]
|
\fBxbps\-bin\fR [\fIoptions\fR] \fItarget\fR [\fIpkgname\fR]
|
||||||
.SH "DESCRIPTION"
|
.SH "DESCRIPTION"
|
||||||
.sp
|
.sp
|
||||||
The xbps\-bin(8) command is used to handle binary packages created for the \fBXBPS binary package system\fR\&. You can use it to install, remove, list or show information about any binary package\&. Binary packages can be installed from local (\fIdirectory\fR) or remote repositories (\fIhttp\fR, \fIhttps\fR or \fIftp\fR), see xbps\-repo(8) for information about repositories\&.
|
The xbps\-bin(8) command is used to handle binary packages created for the XBPS binary package system\&. You can use it to install, remove, update, list or show information about any binary package\&. Binary packages can be installed from \fIlocal (directories)\fR or \fIremote repositories (http, https or ftp)\fR, see xbps\-repo(8) for information about repositories\&.
|
||||||
.SH "OPTIONS"
|
.SH "OPTIONS"
|
||||||
.PP
|
.PP
|
||||||
\fB\-c\fR \fIcachedir\fR
|
\fB\-c\fR \fIcachedir\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Sets the
|
Sets the cache directory to store downloaded binary packages from remote repositories\&. By default it\(cqs set to
|
||||||
\fIcache\fR
|
|
||||||
directory to store downloaded binary packages from remote repositories\&. By default it\(cqs set to
|
|
||||||
\fI/var/cache/xbps\fR
|
\fI/var/cache/xbps\fR
|
||||||
and it\(cqs always relative to the
|
and it\(cqs always relative to the
|
||||||
\fIroot\fR
|
\fIroot directory\fR\&. So if you use a
|
||||||
directory\&. So if you use a
|
|
||||||
\fIrootdir\fR
|
\fIrootdir\fR
|
||||||
of
|
of
|
||||||
\fI/blah\fR, it will become
|
\fI/blah\fR, it will become
|
||||||
@ -36,22 +42,22 @@ of
|
|||||||
.PP
|
.PP
|
||||||
\fB\-d\fR
|
\fB\-d\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Enables extra debugging output to be shown to stderr.
|
Enables extra debugging output to be shown to stderr\&.
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fB\-D\fR
|
\fB\-D\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Only show the URLs to download the binary packages from repositories.
|
Only show the URLs to download the binary packages from repositories\&. This is useful if you want to download them by other means, and later you can move them to the
|
||||||
This is useful if you want to download them by other means, and later you
|
\fIcachedir\fR
|
||||||
can move them to the \fIcachedir\fR to start the installation.
|
to start the installation\&. This option can be used for the install, update and autoupdate targets\&.
|
||||||
This option can be used for the \fIinstall\fR, \fIupdate\fR and \fIautoupdate\fR
|
|
||||||
targets.
|
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fB\-F\fR
|
\fB\-F\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Used currently in the \fIremove\fR target. If set, package will be removed even if other packages
|
Used currently in the
|
||||||
are currently depending on it, i.e package is a dependency of other packages. Use this option with care.
|
\fIremove\fR
|
||||||
|
target\&. If set, package will be removed even if other packages are currently depending on it, i\&.e package is a dependency of other packages\&.
|
||||||
|
\fIUse this option with care\fR\&.
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fB\-f\fR
|
\fB\-f\fR
|
||||||
@ -61,8 +67,14 @@ Used currently in the
|
|||||||
\fIreconfigure\fR
|
\fIreconfigure\fR
|
||||||
and
|
and
|
||||||
\fIremove\fR
|
\fIremove\fR
|
||||||
targets\&. If set, package(s) will be reconfigured regardless of its state if working with the
|
targets\&. If set,
|
||||||
\fIreconfigure target, or to force removal of package files even if its hash doesn\(cqt match in the "purge\fR"
|
\fIpackage(s)\fR
|
||||||
|
will be
|
||||||
|
\fIreconfigured\fR
|
||||||
|
regardless of its state in the reconfigure target, or to
|
||||||
|
\fIforce\fR
|
||||||
|
removal of package files even if its hash doesn\(cqt match in the
|
||||||
|
\fIpurge\fR
|
||||||
and
|
and
|
||||||
\fIremove\fR
|
\fIremove\fR
|
||||||
targets\&.
|
targets\&.
|
||||||
@ -81,8 +93,7 @@ targets, if enabled after removing a package it is also purged\&.
|
|||||||
.RS 4
|
.RS 4
|
||||||
Used currently in the
|
Used currently in the
|
||||||
\fIremove\fR
|
\fIremove\fR
|
||||||
target, to recursively remove packages that aren\(cqt required by other installed
|
target, to recursively remove packages that aren\(cqt required by other installed packages and that were installed by the package that we want to remove\&.
|
||||||
packages and that were installed by the package that we want to remove\&.
|
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fB\-r\fR \fIrootdir\fR
|
\fB\-r\fR \fIrootdir\fR
|
||||||
@ -93,9 +104,7 @@ directory\&. By default the root directory is set to
|
|||||||
\fI/\fR\&. Please note that the database directory is always set to
|
\fI/\fR\&. Please note that the database directory is always set to
|
||||||
\fI/var/db/xbps\fR
|
\fI/var/db/xbps\fR
|
||||||
independently of
|
independently of
|
||||||
\fIrootdir\fR\&. So if you use a
|
\fIrootdir\fR\&. So if you use a rootdir of
|
||||||
\fIrootdir\fR
|
|
||||||
of
|
|
||||||
\fI/blah\fR, metadata stuff will go into
|
\fI/blah\fR, metadata stuff will go into
|
||||||
\fI/blah/var/db/xbps\fR\&.
|
\fI/blah/var/db/xbps\fR\&.
|
||||||
.RE
|
.RE
|
||||||
@ -107,7 +116,9 @@ Shows verbose messages\&. Useful while installing and removing packages\&.
|
|||||||
.PP
|
.PP
|
||||||
\fB\-y\fR
|
\fB\-y\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Assume "yes" to all questions\&. This will bypass all questions and immediately proceed with the task, use this option with care\&.
|
Assume
|
||||||
|
\fIyes\fR
|
||||||
|
to all questions\&. This will bypass all questions and immediately proceed with the task, use this option with care\&.
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fB\-V\fR
|
\fB\-V\fR
|
||||||
@ -116,14 +127,11 @@ Shows the current XBPS release version (library and code)\&.
|
|||||||
.RE
|
.RE
|
||||||
.SH "TARGETS"
|
.SH "TARGETS"
|
||||||
.sp
|
.sp
|
||||||
Please note that all targets are \fBcase insensitive\fR\&.
|
Please note that all targets are case insensitive\&.
|
||||||
.PP
|
.PP
|
||||||
\fBautoremove\fR
|
\fBautoremove\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Removes
|
Removes leaf packages\&. These packages were installed as dependencies and currently there is not any package depending on it, directly or indirectly\&. Usually it is safe to always answer yes\&.
|
||||||
\fIleaf\fR
|
|
||||||
packages\&. These packages were installed as dependencies and currently there is not any package depending on it, directly or indirectly\&. Usually it is safe to always answer
|
|
||||||
\fIyes\fR\&.
|
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBautoupdate\fR
|
\fBautoupdate\fR
|
||||||
@ -131,108 +139,117 @@ packages\&. These packages were installed as dependencies and currently there is
|
|||||||
Updates all currently installed packages to the most newer version available in repository pool\&.
|
Updates all currently installed packages to the most newer version available in repository pool\&.
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBcheck \fR\fB\fIpkgname(s)\fR\fR\fB | \fR\fB\fIall\fR\fR
|
\fBcheck \fR\fB\fIpkgname(s) | all\fR\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Checks for integrity errors in installed packages\&. The checks are to found missing run\-time dependencies, missing and modified package files and metadata files\&. If the
|
Checks for integrity errors in installed packages\&. The checks are to found missing run\-time dependencies, missing and modified package files and metadata files\&. If the
|
||||||
\fBall\fR
|
|
||||||
keyword is used,
|
|
||||||
\fIall\fR
|
\fIall\fR
|
||||||
packages currently installed will be checked, otherwise only
|
keyword is used, all packages currently installed will be checked, otherwise only
|
||||||
\fBpkgname\fR\&.
|
\fIpkgname(s)\fR\&.
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBfind-files\fR \fR\fB\fIpattern\fR\fR
|
\fBfind\-files \fR\fB\fIpattern\fR\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Prints the name of the installed "\fBpackage(s)\fR" matching the \fBpattern\fR on its file list.
|
Prints the name of the installed
|
||||||
|
\fIpackage(s)\fR
|
||||||
|
matching the pattern on its file list\&.
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBinstall \fR\fB\fIpkgname(s)\fR\fR\fB | \fR\fB\fIpkgpattern(s)\fR\fR
|
\fBinstall \fR\fB\fIpkgname(s) | pkgpattern(s)\fR\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Install binary package(s) from repository pool by specifying "\fBpkgname(s)\fR" or "\fBpackage pattern(s)\fR"\&. The first repository matching the arguments will be used\&. The package(s) will be
|
Install binary package(s) from repository pool by specifying
|
||||||
|
\fIpkgname(s)\fR
|
||||||
|
or
|
||||||
|
\fIpackage pattern(s)\fR\&. The first repository matching the arguments will be used\&. The package(s) will be
|
||||||
\fIdownloaded\fR
|
\fIdownloaded\fR
|
||||||
(if found in a remote repository),
|
(if found in a remote repository),
|
||||||
\fIunpacked\fR
|
\fIunpacked\fR
|
||||||
and
|
and
|
||||||
\fIconfigured\fR\&. The
|
\fIconfigured\fR\&. The
|
||||||
\fIunpack stage will execute the \fR\fI\fBpre\-install\fR\fR\fI action on its \fR\fI\fBINSTALL\fR\fR\fI script, and unpack its files\&. The "configure\fR"
|
\fIunpack\fR
|
||||||
stage will run the
|
stage will execute the pre\-install action on its INSTALL script, and unpack its files\&. The
|
||||||
\fBpost\-install\fR
|
\fIconfigure\fR
|
||||||
action set on its
|
stage will run the post\-install action set on its INSTALL script and will change its
|
||||||
\fBINSTALL\fR
|
\fIstate\fR
|
||||||
script and will change its state to
|
to installed in the package database\&.
|
||||||
\fBinstalled\fR
|
|
||||||
in the package database\&.
|
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBlist [\fR\fB\fIstate\fR\fR]
|
\fBlist [\fR\fB\fIstate\fR\fR\fB]\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Lists all currently installed packages\&. Optionally another argument can be specified to
|
Lists all currently installed packages\&. Optionally another argument can be specified to list only packages with the specified
|
||||||
list only packages with the specified \fIstate\fR. By default only packages that are fully
|
\fIstate\fR\&. By default only packages that are
|
||||||
installed will be listed if no \fIstate\fR has been specified. Accepted states are:
|
\fIfully installed\fR
|
||||||
\fBconfig\-files\fR, \fBunpacked\fR and \fBinstalled\fR.
|
will be listed if
|
||||||
|
\fIstate\fR
|
||||||
|
has not been specified\&. Accepted states are:
|
||||||
|
\fIconfig\-files\fR,
|
||||||
|
\fIunpacked\fR
|
||||||
|
and
|
||||||
|
\fIinstalled\fR\&.
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBlist\-manual\fR
|
\fBlist\-manual\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Lists packages that were installed
|
Lists packages that were installed manually by the user, i\&.e not as dependencies of any other package\&.
|
||||||
\fImanually\fR
|
|
||||||
by the user, i\&.e not as dependencies of any other package\&.
|
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBpurge \fR\fB\fIpkgname\fR\fR\fB | \fR\fB\fIall\fR\fR
|
\fBpurge \fR\fB\fIpkgname | all\fR\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Purge an installed package,
|
Purge an installed package:
|
||||||
\fBpkgname\fR
|
\fIpkgname\fR
|
||||||
or
|
or
|
||||||
\fBall\fR
|
\fIall\fR
|
||||||
packages\&. The
|
packages\&. The purge stage runs the post\-remove action set in the REMOVE script in its metadata directory
|
||||||
\fIpurge\fR
|
\fI(/var/db/xbps/metadata/pkgname)\fR
|
||||||
stage runs the
|
and will remove configuration (if they were not modified by the user) and metadata files\&. The package will be fully removed from the system once it has been purged\&. If
|
||||||
\fBpost\-remove\fR
|
|
||||||
action set in the
|
|
||||||
\fBREMOVE\fR
|
|
||||||
script in its metadata directory ( /var/db/xbps/metadata/\fIpkgname\fR
|
|
||||||
) and will remove configuration (if they were not modified by the user) and metadata files\&. The package will be fully removed from the system once it has been
|
|
||||||
\fBpurged\fR\&. If
|
|
||||||
\fB\-f\fR
|
\fB\-f\fR
|
||||||
option is used, configuration files that have been modified
|
option is used, configuration files that have been
|
||||||
\fBWILL BE REMOVED, BEWARE WITH THIS!\fR\&.
|
\fImodified WILL BE REMOVED\&. BEWARE WITH THIS!\fR
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBreconfigure \fR\fB\fIpkgname\fR\fR\fB | \fR\fB\fIall\fR\fR
|
\fBreconfigure \fR\fB\fIpkgname | all\fR\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Reconfigure an
|
Reconfigure an unpacked package\&. Packages in this state are not fully installed, because they were not configured for whatever reason\&. The configure stage will run the post\-install action set on its INSTALL script and will change its state to installed in the package database\&. The
|
||||||
\fBunpacked\fR
|
|
||||||
package\&. Packages in this state are not fully installed, because they were not configured for whatever reason\&. The
|
|
||||||
\fIconfigure\fR
|
|
||||||
stage will run the
|
|
||||||
\fIpost\-install\fR
|
|
||||||
action set on its
|
|
||||||
\fBINSTALL\fR
|
|
||||||
script and will change its state to
|
|
||||||
\fBinstalled\fR
|
|
||||||
in the package database\&. The
|
|
||||||
\fIall\fR
|
\fIall\fR
|
||||||
keyword can be used to reconfigure all not configured packages\&. If
|
keyword can be used to reconfigure all not configured packages\&. If
|
||||||
\fB\-f\fR
|
\fB\-f\fR
|
||||||
option is used, the package will be reconfigured even if its state is already
|
option is used, the package will be reconfigured even if its state is already installed\&.
|
||||||
\fBinstalled\fR\&.
|
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBremove \fR\fB\fIpkgname(s)\fR\fR
|
\fBremove \fR\fB\fIpkgname(s)\fR\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Removes the installed package
|
Removes the installed package
|
||||||
\fIpkgname(s)\fR\&. Its files will be removed and its state will be changed to
|
\fIpkgname(s)\fR\&. Its files will be removed and its state will be changed to
|
||||||
\fBconfig\-files\fR
|
\fIconfig\-files\fR
|
||||||
in the package database\&. Configuration files, its metadata directory/files and its information in the package database are preserved\&. To fully remove a package in
|
in the package database\&. Configuration files, its metadata directory/files and its information in the package database are preserved\&. To fully remove a package in
|
||||||
\fBconfig\-files\fR
|
\fIconfig\-files\fR
|
||||||
state, it must be
|
state, it must be purged with the
|
||||||
\fBpurged\fR
|
\fIpurge\fR
|
||||||
with the
|
command or alternatively use the
|
||||||
\fBpurge\fR
|
\fB\-p\fR
|
||||||
command or alternatively use the \fI\-p\fR flag \&. If
|
flag \&. If
|
||||||
\fB\-f\fR
|
\fB\-f\fR
|
||||||
option is used, package files will be removed even if its SHA256 hash doesn\(cqt match\&.
|
option is used, package files will be
|
||||||
|
\fBremoved even if its SHA256 hash don\(cqt match\fR\&.
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
\fBset\-prop \fR\fB\fIproperty\fR\fR\fB \fR\fB\fIpkgname\fR\fR
|
||||||
|
.RS 4
|
||||||
|
Sets a
|
||||||
|
\fIproperty\fR
|
||||||
|
for a package as specified in
|
||||||
|
\fIpkgname\fR\&. See the
|
||||||
|
\fIPROPERTIES\fR
|
||||||
|
section below for more information\&.
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
\fBunset\-prop \fR\fB\fIproperty\fR\fR\fB \fR\fB\fIpkgname\fR\fR
|
||||||
|
.RS 4
|
||||||
|
Unsets a
|
||||||
|
\fIproperty\fR
|
||||||
|
for a package as specified in
|
||||||
|
\fIpkgname\fR\&. See the
|
||||||
|
\fIPROPERTIES\fR
|
||||||
|
section below for more information\&.
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBshow \fR\fB\fIpkgname\fR\fR
|
\fBshow \fR\fB\fIpkgname\fR\fR
|
||||||
@ -243,31 +260,23 @@ Shows information for installed package
|
|||||||
.PP
|
.PP
|
||||||
\fBshow\-deps \fR\fB\fIpkgname\fR\fR
|
\fBshow\-deps \fR\fB\fIpkgname\fR\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Shows the list of dependencies that
|
Shows the list of dependencies that pkgname requires at run time\&.
|
||||||
\fIpkgname\fR
|
|
||||||
requires at run time\&.
|
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBshow\-files \fR\fB\fIpkgname\fR\fR
|
\fBshow\-files \fR\fB\fIpkgname\fR\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Shows the list of files that
|
Shows the list of files that pkgname contains\&.
|
||||||
\fIpkgname\fR
|
|
||||||
contains\&.
|
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBshow\-orphans\fR
|
\fBshow\-orphans\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Shows the list of package orphans currently installed. Package orphans
|
Shows the list of package orphans currently installed\&. Package orphans are packages that were installed as dependencies of another package, but no other package currently depends on\&.
|
||||||
are packages that were installed as dependencies of another package, but
|
|
||||||
no other package currently depends on.
|
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBshow\-revdeps \fR\fB\fIpkgname\fR\fR
|
\fBshow\-revdeps \fR\fB\fIpkgname\fR\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Shows the reverse dependencies for
|
Shows the reverse dependencies for
|
||||||
\fIpkgname\fR\&. Reverse dependencies are packages that are currently depending in
|
\fIpkgname\fR\&. Reverse dependencies are packages that are currently depending in pkgname directly\&.
|
||||||
\fIpkgname\fR
|
|
||||||
directly\&.
|
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBupdate \fR\fB\fIpkgname(s)\fR\fR
|
\fBupdate \fR\fB\fIpkgname(s)\fR\fR
|
||||||
@ -276,8 +285,8 @@ Updates
|
|||||||
\fIpkgname(s)\fR
|
\fIpkgname(s)\fR
|
||||||
to the most newer version available in repository pool\&. This can be used if only
|
to the most newer version available in repository pool\&. This can be used if only
|
||||||
\fIpkgname(s)\fR
|
\fIpkgname(s)\fR
|
||||||
needs to be updated, unlike the
|
need to be updated, unlike the
|
||||||
\fBautoupdate\fR
|
\fIautoupdate\fR
|
||||||
target that will update all currently installed packages\&.
|
target that will update all currently installed packages\&.
|
||||||
.RE
|
.RE
|
||||||
.SH "PACKAGE STATES"
|
.SH "PACKAGE STATES"
|
||||||
@ -296,17 +305,40 @@ The package has been unpacked in destination root directory, but it is not fully
|
|||||||
.PP
|
.PP
|
||||||
\fBconfig\-files\fR
|
\fBconfig\-files\fR
|
||||||
.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
|
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\&.
|
||||||
\fIpurge\fR
|
.RE
|
||||||
safely packages that are in this state, modified configuration files will be preserved\&.
|
.SH "PROPERTIES"
|
||||||
|
.sp
|
||||||
|
Properties can be specified for packages to control behaviour of some aspects in XBPS\&. The following is the list of properties currently implemented:
|
||||||
|
.PP
|
||||||
|
\fBhold\fR
|
||||||
|
.RS 4
|
||||||
|
When this property is set for a package, it will be put on
|
||||||
|
\fIhold\fR
|
||||||
|
i\&.e the package won\(cqt be updated even if there is a newer version in registered repositories\&.
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
\fBupdate\-first\fR
|
||||||
|
.RS 4
|
||||||
|
When this property is set, the package will always be updated before all other packages, regardless of its package dependencies\&.
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
\fBvirtual\fR
|
||||||
|
.RS 4
|
||||||
|
When this property is set, the virtual packages that target package supports via the
|
||||||
|
\fBproperties\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
|
.RE
|
||||||
.SH "FILES"
|
.SH "FILES"
|
||||||
.PP
|
.PP
|
||||||
\fB/var/db/xbps\fR
|
\fB/var/db/xbps\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
xbps global
|
xbps global metadata directory\&.
|
||||||
\fImetadata\fR
|
|
||||||
directory\&.
|
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fB/var/db/xbps/metadata/<pkgname>\fR
|
\fB/var/db/xbps/metadata/<pkgname>\fR
|
||||||
@ -326,64 +358,80 @@ Installed package metadata properties\&.
|
|||||||
.PP
|
.PP
|
||||||
\fB/var/db/xbps/regpkgdb\&.plist\fR
|
\fB/var/db/xbps/regpkgdb\&.plist\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Registered packages plist database\&.
|
xbps master packages/properties database plist file\&.
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fB/var/cache/xbps\fR
|
\fB/var/cache/xbps\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
xbps
|
xbps cache directory for downloaded binary packages\&.
|
||||||
\fIcache\fR
|
|
||||||
directory for downloaded binary packages\&.
|
|
||||||
.RE
|
.RE
|
||||||
.SH "EXAMPLES"
|
.SH "EXAMPLES"
|
||||||
.PP
|
.PP
|
||||||
Install a package by specifying its name:
|
\fBInstall\fR a package by specifying its \fBname\fR:
|
||||||
.RS 4
|
.RS 4
|
||||||
|
|
||||||
$ xbps\-bin install foo
|
$ xbps\-bin install foo
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
Install a package by specifying a package pattern:
|
\fBInstall\fR a package by specifying a \fBpackage pattern\fR:
|
||||||
.RS 4
|
.RS 4
|
||||||
$ xbps\-bin install "\fBfoo>=3\&.0\fR"
|
|
||||||
|
$ xbps\-bin install "foo>=3\&.0"
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
Install multiple packages by specifying names and package patterns:
|
\fBInstall multiple\fR packages by specifying \fBnames\fR and \fBpackage patterns\fR:
|
||||||
.RS 4
|
.RS 4
|
||||||
$ xbps\-bin install foo "\fBblah⇐4\&.0\fR" baz\-2\&.0 "\fBblob>4\&.[0\-9]\fR"
|
|
||||||
|
$ xbps\-bin install foo "blah<=4\&.0" baz\-2\&.0 "blob>4\&.[0\-9]"
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
Find the package that owns the file \fB/bin/mount\fR:
|
\fBFind\fR the package that owns the file \fB/bin/mount\fR:
|
||||||
.RS 4
|
.RS 4
|
||||||
|
|
||||||
$ xbps\-bin find\-files /bin/mount
|
$ xbps\-bin find\-files /bin/mount
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
Find the packages that match the pattern "\fB/usr/lib/libav\&*\fR":
|
\fBFind\fR the packages that match the pattern \fB"/usr/lib/libav\fR"*:
|
||||||
.RS 4
|
.RS 4
|
||||||
$ xbps\-bin find\-files "/usr/lib/libav\&*"
|
|
||||||
|
$ xbps\-bin find\-files "/usr/lib/libav*"
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
Remove and purge the package \fBproplib-devel\fR:
|
\fBRemove and purge\fR the package \fBproplib\-devel\fR:
|
||||||
.RS 4
|
.RS 4
|
||||||
$ xbps\-bin -yp remove proplib\-devel
|
|
||||||
|
$ xbps\-bin \-yp remove proplib\-devel
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
Remove and purge the package \fBbsdtar\fR and recursively all packages that
|
\fBRemove and purge\fR the package \fBbsdtar\fR and \fBrecursively\fR all packages that were installed automatically by it:
|
||||||
were installed automatically by it:
|
|
||||||
.RS 4
|
.RS 4
|
||||||
$ xbps\-bin -Rp remove bsdtar
|
|
||||||
|
$ xbps\-bin \-Rp remove bsdtar
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
\fBSets\fR the \fIvirtual\fR property in the \fBxbps\-devel\fR package:
|
||||||
|
.RS 4
|
||||||
|
|
||||||
|
$ xbps\-bin set\-prop virtual xbps\-devel
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
\fBUnsets\fR the \fIhold\fR property in the \fBcoreutils\fR package:
|
||||||
|
.RS 4
|
||||||
|
|
||||||
|
$ xbps\-bin unset\-prop hold coreutils
|
||||||
.RE
|
.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\&.
|
||||||
.sp
|
.sp
|
||||||
Report bugs in \fIhttp://code\&.google\&.com/p/xbps\fR\&.
|
Report bugs in http://code\&.google\&.com/p/xbps\&.
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
.sp
|
.sp
|
||||||
xbps\-repo(8), xbps\-src(8)
|
xbps\-repo(8), xbps\-src(8)
|
||||||
.sp
|
.sp
|
||||||
The XBPS project: \fIhttp://code\&.google\&.com/p/xbps\fR
|
The XBPS project: http://code\&.google\&.com/p/xbps
|
||||||
.sp
|
.sp
|
||||||
To build binary packages, the xbps\-src(8) shell script is the command designed for this task\&. This must be retrieved from a Mercurial repository, available at \fIhttp://xbps\-src\&.xbps\&.googlecode\&.com/hg/\fR\&.
|
To build binary packages, the xbps\-src(8) shell script is the command designed for this task\&. This must be retrieved from a Mercurial repository, available at http://xbps\-src\&.xbps\&.googlecode\&.com/hg/\&.
|
||||||
.SH "AUTHORS"
|
.SH "AUTHORS"
|
||||||
.sp
|
.sp
|
||||||
The \fBXBPS binary package system\fR has been designed and implemented by Juan Romero Pardines <xtraeme@gmail\&.com>\&.
|
The X Binary Package System has been designed and implemented by Juan Romero Pardines <xtraeme@gmail\&.com>\&.
|
||||||
|
@ -216,7 +216,8 @@ main(int argc, char **argv)
|
|||||||
if (argc != 2)
|
if (argc != 2)
|
||||||
usage();
|
usage();
|
||||||
|
|
||||||
dict = xbps_find_pkg_dict_from_plist_by_name(plist, argv[1]);
|
dict = xbps_find_pkg_dict_from_plist_by_name(plist,
|
||||||
|
"packages", argv[1]);
|
||||||
if (dict == NULL)
|
if (dict == NULL)
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
* @def XBPS_RELVER
|
* @def XBPS_RELVER
|
||||||
* Current library release date.
|
* Current library release date.
|
||||||
*/
|
*/
|
||||||
#define XBPS_RELVER "20110201"
|
#define XBPS_RELVER "20110205"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @def XBPS_META_PATH
|
* @def XBPS_META_PATH
|
||||||
@ -174,6 +174,31 @@ int xbps_configure_all_pkgs(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
|
||||||
*
|
*
|
||||||
@ -436,7 +461,8 @@ prop_dictionary_t xbps_find_pkg_in_dict_by_pattern(prop_dictionary_t dict,
|
|||||||
* a package name.
|
* a package name.
|
||||||
*
|
*
|
||||||
* @param[in] plist Path to a plist file.
|
* @param[in] plist Path to a plist file.
|
||||||
* @param[in] pkgname Package name to look for.
|
* @param[in] key Proplib array's key name.
|
||||||
|
* @param[in] pkgname Package name to match in array.
|
||||||
*
|
*
|
||||||
* @return The package's proplib dictionary on success, NULL otherwise and
|
* @return The package's proplib dictionary on success, NULL otherwise and
|
||||||
* errno is set appropiately. Returned dictionary is copied via
|
* errno is set appropiately. Returned dictionary is copied via
|
||||||
@ -444,8 +470,25 @@ prop_dictionary_t xbps_find_pkg_in_dict_by_pattern(prop_dictionary_t dict,
|
|||||||
* release the object with prop_object_release() when done.
|
* release the object with prop_object_release() when done.
|
||||||
*/
|
*/
|
||||||
prop_dictionary_t xbps_find_pkg_dict_from_plist_by_name(const char *plist,
|
prop_dictionary_t xbps_find_pkg_dict_from_plist_by_name(const char *plist,
|
||||||
|
const char *key,
|
||||||
const char *pkgname);
|
const char *pkgname);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the package's proplib dictionary in a plist file by specifying
|
||||||
|
* a package pattern.
|
||||||
|
*
|
||||||
|
* @param[in] plist Path to a plist file.
|
||||||
|
* @param[in] key Proplib array's key name.
|
||||||
|
* @param[in] pattern Package pattern to match in array.
|
||||||
|
*
|
||||||
|
* @return The package's proplib dictionary on success, NULL otherwise and
|
||||||
|
* errno is set appropiately. Returned dictionary should be released with
|
||||||
|
* prop_object_release() when it's not any longer needed.
|
||||||
|
*/
|
||||||
|
prop_dictionary_t xbps_find_pkg_dict_from_plist_by_pattern(const char *plist,
|
||||||
|
const char *key,
|
||||||
|
const char *pattern);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds a package's dictionary searching in the registered packages
|
* Finds a package's dictionary searching in the registered packages
|
||||||
* database by using a package name or a package pattern.
|
* database by using a package name or a package pattern.
|
||||||
|
@ -199,6 +199,19 @@ int HIDDEN xbps_file_chdir_exec(const char *path, const char *arg, ...);
|
|||||||
int HIDDEN xbps_repository_pkg_replaces(prop_dictionary_t,
|
int HIDDEN xbps_repository_pkg_replaces(prop_dictionary_t,
|
||||||
prop_dictionary_t);
|
prop_dictionary_t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* From lib/plist.c
|
||||||
|
*/
|
||||||
|
prop_dictionary_t HIDDEN
|
||||||
|
xbps_find_virtualpkg_user_in_dict_by_name(prop_dictionary_t,
|
||||||
|
const char *,
|
||||||
|
const char *);
|
||||||
|
prop_dictionary_t HIDDEN
|
||||||
|
xbps_find_virtualpkg_user_in_dict_by_pattern(prop_dictionary_t,
|
||||||
|
const char *,
|
||||||
|
const char *);
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
#endif /* !_XBPS_API_IMPL_H_ */
|
#endif /* !_XBPS_API_IMPL_H_ */
|
||||||
|
@ -40,10 +40,10 @@ 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 initend.o
|
OBJS += package_purge.o package_replaces.o package_properties.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 += util.o pkgmatch.o mkpath.o
|
OBJS += util.o pkgmatch.o mkpath.o initend.o
|
||||||
OBJS += regpkgdb_dictionary.o repository_register.o
|
OBJS += regpkgdb_dictionary.o repository_register.o
|
||||||
OBJS += repository_findpkg.o repository_plist.o repository_finddeps.o
|
OBJS += repository_findpkg.o repository_plist.o repository_finddeps.o
|
||||||
OBJS += repository_pool.o repository_sync_index.o
|
OBJS += repository_pool.o repository_sync_index.o
|
||||||
|
268
lib/package_properties.c
Normal file
268
lib/package_properties.c
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
/*-
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
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", xbps_get_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)
|
||||||
|
{
|
||||||
|
prop_dictionary_t d, pkgd;
|
||||||
|
prop_array_t props;
|
||||||
|
char *plist;
|
||||||
|
int rv = 0;
|
||||||
|
|
||||||
|
assert(key != NULL);
|
||||||
|
assert(pkgname != NULL);
|
||||||
|
|
||||||
|
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", xbps_get_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;
|
||||||
|
}
|
@ -216,10 +216,13 @@ xbps_set_pkg_state_installed(const char *pkgname, pkg_state_t state)
|
|||||||
}
|
}
|
||||||
array = prop_dictionary_get(dict, "packages");
|
array = prop_dictionary_get(dict, "packages");
|
||||||
if (array == NULL) {
|
if (array == NULL) {
|
||||||
rv = EINVAL;
|
array = prop_array_create();
|
||||||
if (newpkg)
|
if (!prop_dictionary_set(dict, "packages", array)) {
|
||||||
prop_object_release(pkgd);
|
rv = EINVAL;
|
||||||
goto out;
|
if (newpkg)
|
||||||
|
prop_object_release(pkgd);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ((rv = set_new_state(pkgd, state)) != 0) {
|
if ((rv = set_new_state(pkgd, state)) != 0) {
|
||||||
if (newpkg)
|
if (newpkg)
|
||||||
|
237
lib/plist.c
237
lib/plist.c
@ -167,27 +167,32 @@ xbps_callback_array_iter_reverse_in_dict(prop_dictionary_t dict,
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
prop_dictionary_t
|
static prop_dictionary_t
|
||||||
xbps_find_pkg_dict_from_plist_by_name(const char *plist, const char *pkgname)
|
find_pkg_dict_from_plist(const char *plist,
|
||||||
|
const char *key,
|
||||||
|
const char *str,
|
||||||
|
bool bypattern)
|
||||||
{
|
{
|
||||||
prop_dictionary_t dict, obj, res;
|
prop_dictionary_t dict, obj, res;
|
||||||
|
|
||||||
assert(plist != NULL);
|
assert(plist != NULL);
|
||||||
assert(pkgname != NULL);
|
assert(str != NULL);
|
||||||
|
|
||||||
dict = prop_dictionary_internalize_from_zfile(plist);
|
dict = prop_dictionary_internalize_from_zfile(plist);
|
||||||
if (dict == NULL) {
|
if (dict == NULL) {
|
||||||
xbps_dbg_printf("cannot internalize %s for pkg %s: %s",
|
xbps_dbg_printf("cannot internalize %s for pkg %s: %s",
|
||||||
plist, pkgname, strerror(errno));
|
plist, str, strerror(errno));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (bypattern)
|
||||||
|
obj = xbps_find_pkg_in_dict_by_pattern(dict, key, str);
|
||||||
|
else
|
||||||
|
obj = xbps_find_pkg_in_dict_by_name(dict, key, str);
|
||||||
|
|
||||||
obj = xbps_find_pkg_in_dict_by_name(dict, "packages", pkgname);
|
|
||||||
if (obj == NULL) {
|
if (obj == NULL) {
|
||||||
prop_object_release(dict);
|
prop_object_release(dict);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = prop_dictionary_copy(obj);
|
res = prop_dictionary_copy(obj);
|
||||||
prop_object_release(dict);
|
prop_object_release(dict);
|
||||||
|
|
||||||
@ -195,42 +200,19 @@ xbps_find_pkg_dict_from_plist_by_name(const char *plist, const char *pkgname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
prop_dictionary_t
|
prop_dictionary_t
|
||||||
xbps_find_pkg_dict_installed(const char *str, bool bypattern)
|
xbps_find_pkg_dict_from_plist_by_name(const char *plist,
|
||||||
|
const char *key,
|
||||||
|
const char *pkgname)
|
||||||
{
|
{
|
||||||
prop_dictionary_t d, pkgd, rpkgd = NULL;
|
return find_pkg_dict_from_plist(plist, key, pkgname, false);
|
||||||
pkg_state_t state = 0;
|
}
|
||||||
|
|
||||||
assert(str != NULL);
|
prop_dictionary_t
|
||||||
|
xbps_find_pkg_dict_from_plist_by_pattern(const char *plist,
|
||||||
if ((d = xbps_regpkgdb_dictionary_get()) == NULL)
|
const char *key,
|
||||||
return NULL;
|
const char *pattern)
|
||||||
|
{
|
||||||
if (bypattern)
|
return find_pkg_dict_from_plist(plist, key, pattern, true);
|
||||||
pkgd = xbps_find_pkg_in_dict_by_pattern(d, "packages", str);
|
|
||||||
else
|
|
||||||
pkgd = xbps_find_pkg_in_dict_by_name(d, "packages", str);
|
|
||||||
if (pkgd == NULL)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (xbps_get_pkg_state_dictionary(pkgd, &state) != 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
switch (state) {
|
|
||||||
case XBPS_PKG_STATE_INSTALLED:
|
|
||||||
case XBPS_PKG_STATE_UNPACKED:
|
|
||||||
rpkgd = prop_dictionary_copy(pkgd);
|
|
||||||
break;
|
|
||||||
case XBPS_PKG_STATE_CONFIG_FILES:
|
|
||||||
errno = ENOENT;
|
|
||||||
xbps_dbg_printf("'%s' installed but its state is "
|
|
||||||
"config-files\n",str);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
xbps_regpkgdb_dictionary_release();
|
|
||||||
return rpkgd;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -254,7 +236,7 @@ static prop_dictionary_t
|
|||||||
find_pkg_in_array(prop_array_t array, const char *str, bool bypattern)
|
find_pkg_in_array(prop_array_t array, const char *str, bool bypattern)
|
||||||
{
|
{
|
||||||
prop_object_iterator_t iter;
|
prop_object_iterator_t iter;
|
||||||
prop_object_t obj;
|
prop_object_t obj = NULL;
|
||||||
const char *pkgver, *dpkgn;
|
const char *pkgver, *dpkgn;
|
||||||
|
|
||||||
assert(array != NULL);
|
assert(array != NULL);
|
||||||
@ -266,19 +248,29 @@ find_pkg_in_array(prop_array_t array, const char *str, bool bypattern)
|
|||||||
|
|
||||||
while ((obj = prop_object_iterator_next(iter))) {
|
while ((obj = prop_object_iterator_next(iter))) {
|
||||||
if (bypattern) {
|
if (bypattern) {
|
||||||
if (xbps_find_virtual_pkg_in_dict(obj, str, true))
|
/*
|
||||||
break;
|
* Check if package pattern matches the
|
||||||
prop_dictionary_get_cstring_nocopy(obj,
|
* pkgver string object in dictionary.
|
||||||
"pkgver", &pkgver);
|
*/
|
||||||
|
if (!prop_dictionary_get_cstring_nocopy(obj,
|
||||||
|
"pkgver", &pkgver))
|
||||||
|
continue;
|
||||||
if (xbps_pkgpattern_match(pkgver, __UNCONST(str)))
|
if (xbps_pkgpattern_match(pkgver, __UNCONST(str)))
|
||||||
break;
|
break;
|
||||||
} else {
|
/*
|
||||||
if (xbps_find_virtual_pkg_in_dict(obj, str, false))
|
* Finally check if package pattern matches
|
||||||
|
* any virtual package version in dictionary.
|
||||||
|
*/
|
||||||
|
if (xbps_find_virtual_pkg_in_dict(obj, str, true))
|
||||||
break;
|
break;
|
||||||
prop_dictionary_get_cstring_nocopy(obj,
|
} else {
|
||||||
"pkgname", &dpkgn);
|
if (!prop_dictionary_get_cstring_nocopy(obj,
|
||||||
|
"pkgname", &dpkgn))
|
||||||
|
continue;
|
||||||
if (strcmp(dpkgn, str) == 0)
|
if (strcmp(dpkgn, str) == 0)
|
||||||
break;
|
break;
|
||||||
|
if (xbps_find_virtual_pkg_in_dict(obj, str, false))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prop_object_iterator_release(iter);
|
prop_object_iterator_release(iter);
|
||||||
@ -301,11 +293,93 @@ xbps_find_pkg_in_array_by_pattern(prop_array_t array, const char *pattern)
|
|||||||
return find_pkg_in_array(array, pattern, true);
|
return find_pkg_in_array(array, pattern, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
find_virtualpkg_user_in_regpkgdb(const char *virtualpkg, bool bypattern)
|
||||||
|
{
|
||||||
|
prop_array_t virtual;
|
||||||
|
prop_dictionary_t d;
|
||||||
|
prop_object_iterator_t iter;
|
||||||
|
prop_object_t obj;
|
||||||
|
const char *pkg = NULL;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
if ((d = xbps_regpkgdb_dictionary_get()) == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if ((iter = xbps_get_array_iter_from_dict(d, "properties")) == NULL) {
|
||||||
|
xbps_regpkgdb_dictionary_release();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
while ((obj = prop_object_iterator_next(iter)) != NULL) {
|
||||||
|
virtual = prop_dictionary_get(obj, "provides");
|
||||||
|
if (virtual == NULL)
|
||||||
|
continue;
|
||||||
|
if (bypattern)
|
||||||
|
found = xbps_find_pkgpattern_in_array(virtual, virtualpkg);
|
||||||
|
else
|
||||||
|
found = xbps_find_pkgname_in_array(virtual, virtualpkg);
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
continue;
|
||||||
|
if (bypattern)
|
||||||
|
prop_dictionary_get_cstring_nocopy(obj,
|
||||||
|
"pkgpattern", &pkg);
|
||||||
|
else
|
||||||
|
prop_dictionary_get_cstring_nocopy(obj,
|
||||||
|
"pkgname", &pkg);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prop_object_iterator_release(iter);
|
||||||
|
xbps_regpkgdb_dictionary_release();
|
||||||
|
|
||||||
|
return pkg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static prop_dictionary_t
|
||||||
|
find_virtualpkg_user_in_array(prop_array_t array,
|
||||||
|
const char *str,
|
||||||
|
bool bypattern)
|
||||||
|
{
|
||||||
|
prop_object_t obj = NULL;
|
||||||
|
prop_object_iterator_t iter;
|
||||||
|
const char *pkgver, *dpkgn, *virtualpkg;
|
||||||
|
|
||||||
|
assert(array != NULL);
|
||||||
|
assert(str != NULL);
|
||||||
|
|
||||||
|
virtualpkg = find_virtualpkg_user_in_regpkgdb(str, bypattern);
|
||||||
|
if (virtualpkg == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
iter = prop_array_iterator(array);
|
||||||
|
if (iter == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
while ((obj = prop_object_iterator_next(iter))) {
|
||||||
|
if (bypattern) {
|
||||||
|
prop_dictionary_get_cstring_nocopy(obj,
|
||||||
|
"pkgver", &pkgver);
|
||||||
|
if (xbps_pkgpattern_match(pkgver,
|
||||||
|
__UNCONST(virtualpkg)))
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
prop_dictionary_get_cstring_nocopy(obj,
|
||||||
|
"pkgname", &dpkgn);
|
||||||
|
if (strcmp(dpkgn, virtualpkg) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prop_object_iterator_release(iter);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
static prop_dictionary_t
|
static prop_dictionary_t
|
||||||
find_pkg_in_dict(prop_dictionary_t d,
|
find_pkg_in_dict(prop_dictionary_t d,
|
||||||
const char *key,
|
const char *key,
|
||||||
const char *str,
|
const char *str,
|
||||||
bool bypattern)
|
bool bypattern,
|
||||||
|
bool virtual)
|
||||||
{
|
{
|
||||||
prop_array_t array;
|
prop_array_t array;
|
||||||
|
|
||||||
@ -317,23 +391,78 @@ find_pkg_in_dict(prop_dictionary_t d,
|
|||||||
if (prop_object_type(array) != PROP_TYPE_ARRAY)
|
if (prop_object_type(array) != PROP_TYPE_ARRAY)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (virtual)
|
||||||
|
return find_virtualpkg_user_in_array(array, str, bypattern);
|
||||||
|
|
||||||
return find_pkg_in_array(array, str, bypattern);
|
return find_pkg_in_array(array, str, bypattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
prop_dictionary_t
|
prop_dictionary_t
|
||||||
xbps_find_pkg_in_dict_by_name(prop_dictionary_t dict,
|
xbps_find_pkg_in_dict_by_name(prop_dictionary_t d,
|
||||||
const char *key,
|
const char *key,
|
||||||
const char *pkgname)
|
const char *pkgname)
|
||||||
{
|
{
|
||||||
return find_pkg_in_dict(dict, key, pkgname, false);
|
return find_pkg_in_dict(d, key, pkgname, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
prop_dictionary_t
|
prop_dictionary_t
|
||||||
xbps_find_pkg_in_dict_by_pattern(prop_dictionary_t dict,
|
xbps_find_pkg_in_dict_by_pattern(prop_dictionary_t d,
|
||||||
const char *key,
|
const char *key,
|
||||||
const char *pattern)
|
const char *pattern)
|
||||||
{
|
{
|
||||||
return find_pkg_in_dict(dict, key, pattern, true);
|
return find_pkg_in_dict(d, key, pattern, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
prop_dictionary_t HIDDEN
|
||||||
|
xbps_find_virtualpkg_user_in_dict_by_name(prop_dictionary_t d,
|
||||||
|
const char *key,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
return find_pkg_in_dict(d, key, name, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
prop_dictionary_t HIDDEN
|
||||||
|
xbps_find_virtualpkg_user_in_dict_by_pattern(prop_dictionary_t d,
|
||||||
|
const char *key,
|
||||||
|
const char *pattern)
|
||||||
|
{
|
||||||
|
return find_pkg_in_dict(d, key, pattern, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
prop_dictionary_t
|
||||||
|
xbps_find_pkg_dict_installed(const char *str, bool bypattern)
|
||||||
|
{
|
||||||
|
prop_dictionary_t d, pkgd, rpkgd = NULL;
|
||||||
|
pkg_state_t state = 0;
|
||||||
|
|
||||||
|
assert(str != NULL);
|
||||||
|
|
||||||
|
if ((d = xbps_regpkgdb_dictionary_get()) == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
pkgd = find_pkg_in_dict(d, "packages", str, bypattern, false);
|
||||||
|
if (pkgd == NULL)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (xbps_get_pkg_state_dictionary(pkgd, &state) != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case XBPS_PKG_STATE_INSTALLED:
|
||||||
|
case XBPS_PKG_STATE_UNPACKED:
|
||||||
|
rpkgd = prop_dictionary_copy(pkgd);
|
||||||
|
break;
|
||||||
|
case XBPS_PKG_STATE_CONFIG_FILES:
|
||||||
|
errno = ENOENT;
|
||||||
|
xbps_dbg_printf("'%s' installed but its state is "
|
||||||
|
"config-files\n",str);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
xbps_regpkgdb_dictionary_release();
|
||||||
|
return rpkgd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -235,9 +235,34 @@ struct repo_pool_fpkg {
|
|||||||
prop_dictionary_t pkgd;
|
prop_dictionary_t pkgd;
|
||||||
const char *pattern;
|
const char *pattern;
|
||||||
bool bypattern;
|
bool bypattern;
|
||||||
bool newpkg_found;
|
bool pkgfound;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
repo_find_virtualpkg_cb(struct repository_pool_index *rpi, void *arg, bool *done)
|
||||||
|
{
|
||||||
|
struct repo_pool_fpkg *rpf = arg;
|
||||||
|
|
||||||
|
if (rpf->bypattern) {
|
||||||
|
rpf->pkgd =
|
||||||
|
xbps_find_virtualpkg_user_in_dict_by_pattern(rpi->rpi_repod,
|
||||||
|
"packages", rpf->pattern);
|
||||||
|
} else {
|
||||||
|
rpf->pkgd =
|
||||||
|
xbps_find_virtualpkg_user_in_dict_by_name(rpi->rpi_repod,
|
||||||
|
"packages", rpf->pattern);
|
||||||
|
}
|
||||||
|
if (rpf->pkgd) {
|
||||||
|
prop_dictionary_set_cstring(rpf->pkgd, "repository",
|
||||||
|
rpi->rpi_uri);
|
||||||
|
*done = true;
|
||||||
|
rpf->pkgfound = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* not found */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
repo_find_pkg_cb(struct repository_pool_index *rpi, void *arg, bool *done)
|
repo_find_pkg_cb(struct repository_pool_index *rpi, void *arg, bool *done)
|
||||||
{
|
{
|
||||||
@ -250,7 +275,6 @@ repo_find_pkg_cb(struct repository_pool_index *rpi, void *arg, bool *done)
|
|||||||
rpf->pkgd = xbps_find_pkg_in_dict_by_name(rpi->rpi_repod,
|
rpf->pkgd = xbps_find_pkg_in_dict_by_name(rpi->rpi_repod,
|
||||||
"packages", rpf->pattern);
|
"packages", rpf->pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rpf->pkgd) {
|
if (rpf->pkgd) {
|
||||||
/*
|
/*
|
||||||
* Package dictionary found, add the "repository"
|
* Package dictionary found, add the "repository"
|
||||||
@ -259,11 +283,10 @@ repo_find_pkg_cb(struct repository_pool_index *rpi, void *arg, bool *done)
|
|||||||
prop_dictionary_set_cstring(rpf->pkgd, "repository",
|
prop_dictionary_set_cstring(rpf->pkgd, "repository",
|
||||||
rpi->rpi_uri);
|
rpi->rpi_uri);
|
||||||
*done = true;
|
*done = true;
|
||||||
errno = 0;
|
rpf->pkgfound = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* Not found */
|
/* Not found */
|
||||||
errno = ENOENT;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,6 +313,8 @@ repo_find_best_pkg_cb(struct repository_pool_index *rpi,
|
|||||||
* the version currently installed.
|
* the version currently installed.
|
||||||
*/
|
*/
|
||||||
instpkgd = xbps_find_pkg_dict_installed(rpf->pattern, false);
|
instpkgd = xbps_find_pkg_dict_installed(rpf->pattern, false);
|
||||||
|
if (instpkgd == NULL)
|
||||||
|
return 0;
|
||||||
prop_dictionary_get_cstring_nocopy(instpkgd,
|
prop_dictionary_get_cstring_nocopy(instpkgd,
|
||||||
"version", &instver);
|
"version", &instver);
|
||||||
prop_dictionary_get_cstring_nocopy(rpf->pkgd,
|
prop_dictionary_get_cstring_nocopy(rpf->pkgd,
|
||||||
@ -303,11 +328,11 @@ repo_find_best_pkg_cb(struct repository_pool_index *rpi,
|
|||||||
/*
|
/*
|
||||||
* New package version found, exit from the loop.
|
* New package version found, exit from the loop.
|
||||||
*/
|
*/
|
||||||
rpf->newpkg_found = true;
|
|
||||||
prop_dictionary_set_cstring(rpf->pkgd, "repository",
|
prop_dictionary_set_cstring(rpf->pkgd, "repository",
|
||||||
rpi->rpi_uri);
|
rpi->rpi_uri);
|
||||||
errno = 0;
|
|
||||||
*done = true;
|
*done = true;
|
||||||
|
errno = 0;
|
||||||
|
rpf->pkgfound = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
xbps_dbg_printf("Skipping '%s-%s' (installed: %s) "
|
xbps_dbg_printf("Skipping '%s-%s' (installed: %s) "
|
||||||
@ -315,7 +340,6 @@ repo_find_best_pkg_cb(struct repository_pool_index *rpi,
|
|||||||
rpi->rpi_uri);
|
rpi->rpi_uri);
|
||||||
errno = EEXIST;
|
errno = EEXIST;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,14 +359,41 @@ xbps_repository_pool_find_pkg(const char *pkg, bool bypattern, bool best)
|
|||||||
rpf->pattern = pkg;
|
rpf->pattern = pkg;
|
||||||
rpf->bypattern = bypattern;
|
rpf->bypattern = bypattern;
|
||||||
|
|
||||||
if (best)
|
if (best) {
|
||||||
|
/*
|
||||||
|
* Look for the best package version of a package name or
|
||||||
|
* pattern in all repositories.
|
||||||
|
*/
|
||||||
rv = xbps_repository_pool_foreach(repo_find_best_pkg_cb, rpf);
|
rv = xbps_repository_pool_foreach(repo_find_best_pkg_cb, rpf);
|
||||||
else
|
if (rv != 0) {
|
||||||
rv = xbps_repository_pool_foreach(repo_find_pkg_cb, rpf);
|
errno = rv;
|
||||||
|
goto out;
|
||||||
if (rv != 0 || (rv == 0 && (errno == ENOENT || errno == EEXIST)))
|
} else if (rpf->pkgfound == false) {
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Look for any virtual package set by the user matching
|
||||||
|
* the package name or pattern.
|
||||||
|
*/
|
||||||
|
rv = xbps_repository_pool_foreach(repo_find_virtualpkg_cb, rpf);
|
||||||
|
if (rv != 0) {
|
||||||
|
errno = rv;
|
||||||
|
goto out;
|
||||||
|
} else if (rpf->pkgfound == false) {
|
||||||
|
/*
|
||||||
|
* No virtual package found. Look for real package
|
||||||
|
* names or patterns instead.
|
||||||
|
*/
|
||||||
|
rv = xbps_repository_pool_foreach(repo_find_pkg_cb, rpf);
|
||||||
|
if (rv != 0) {
|
||||||
|
errno = rv;
|
||||||
|
goto out;
|
||||||
|
} else if (rpf->pkgfound == false) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
pkgd = prop_dictionary_copy(rpf->pkgd);
|
pkgd = prop_dictionary_copy(rpf->pkgd);
|
||||||
out:
|
out:
|
||||||
free(rpf);
|
free(rpf);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user