Mega-commit to document the API with doxygen.

Some changes were made to the API when making the documentation:

- A few exported functions are now hidden, because they were only used
  internally in the library.
- A few exported symbols were renamed to document them better than
  previously.
- Cosmetic changes all along the way, as well as some fixes here and there.

--HG--
extra : convert_revision : xtraeme%40gmail.com-20100121021019-onbsivlrhdb7t3ou
This commit is contained in:
Juan RP 2010-01-21 03:10:19 +01:00
parent 61d2ea8896
commit c0b280c118
40 changed files with 1977 additions and 761 deletions

View File

@ -110,7 +110,7 @@ xbps_check_pkg_integrity(const char *pkgname)
assert(pkgname != NULL); assert(pkgname != NULL);
pkgd = xbps_find_pkg_installed_from_plist(pkgname); pkgd = xbps_find_pkg_dict_installed(pkgname, false);
if (pkgd == NULL) { if (pkgd == NULL) {
printf("Package %s is not installed.\n", pkgname); printf("Package %s is not installed.\n", pkgname);
return 0; return 0;

View File

@ -37,22 +37,11 @@ struct transaction {
prop_dictionary_t dict; prop_dictionary_t dict;
prop_object_iterator_t iter; prop_object_iterator_t iter;
bool yes; bool yes;
size_t inst_pkgcnt;
size_t up_pkgcnt;
size_t cf_pkgcnt;
}; };
static int exec_transaction(struct transaction *);
static void show_missing_deps(prop_dictionary_t);
static int show_missing_dep_cb(prop_object_t, void *, bool *);
static void show_package_list(prop_object_iterator_t, const char *);
static void
show_missing_deps(prop_dictionary_t d)
{
fprintf(stderr,
"xbps-bin: unable to locate some required packages:\n");
(void)xbps_callback_array_iter_in_dict(d, "missing_deps",
show_missing_dep_cb, NULL);
}
static int static int
show_missing_dep_cb(prop_object_t obj, void *arg, bool *loop_done) show_missing_dep_cb(prop_object_t obj, void *arg, bool *loop_done)
{ {
@ -69,6 +58,15 @@ show_missing_dep_cb(prop_object_t obj, void *arg, bool *loop_done)
return 0; return 0;
} }
static void
show_missing_deps(prop_dictionary_t d)
{
fprintf(stderr,
"xbps-bin: unable to locate some required packages:\n");
(void)xbps_callback_array_iter_in_dict(d, "missing_deps",
show_missing_dep_cb, NULL);
}
static bool static bool
check_binpkg_hash(const char *path, const char *filename, check_binpkg_hash(const char *path, const char *filename,
const char *sha256) const char *sha256)
@ -125,7 +123,7 @@ download_package_list(prop_object_iterator_t iter)
/* /*
* If package is in a local repository, check its hash * If package is in a local repository, check its hash
* and pass no next one. * and pass to next one.
*/ */
if (!xbps_check_is_repo_string_remote(repoloc)) { if (!xbps_check_is_repo_string_remote(repoloc)) {
if (!check_binpkg_hash(lbinfile, filename, sha256)) { if (!check_binpkg_hash(lbinfile, filename, sha256)) {
@ -167,11 +165,12 @@ download_package_list(prop_object_iterator_t iter)
rv = xbps_fetch_file(binfile, cachedir, false, NULL); rv = xbps_fetch_file(binfile, cachedir, false, NULL);
free(binfile); free(binfile);
if (rv == -1) { if (rv == -1) {
fprintf(stderr, "xbps-bin: couldn't download %s " fprintf(stderr, "xbps-bin: couldn't download `%s'\n",
"from %s (%s)\n", filename, repoloc, filename);
xbps_fetch_error_string()); fprintf(stderr, "xbps-bin: %s returned: `%s'\n",
repoloc, xbps_fetch_error_string());
free(lbinfile); free(lbinfile);
return errno; return -1;
} }
if (!check_binpkg_hash(lbinfile, filename, sha256)) { if (!check_binpkg_hash(lbinfile, filename, sha256)) {
fprintf(stderr, "W: removing wrong %s file ...\n", fprintf(stderr, "W: removing wrong %s file ...\n",
@ -221,66 +220,62 @@ show_package_list(prop_object_iterator_t iter, const char *match)
} }
static int static int
show_transaction_sizes(prop_object_iterator_t iter) show_transaction_sizes(struct transaction *trans)
{ {
prop_object_t obj; prop_object_t obj;
uint64_t tsize = 0, dlsize = 0, instsize = 0; uint64_t dlsize = 0, instsize = 0;
const char *tract; const char *tract;
char size[64]; char size[64];
bool trans_inst, trans_up, trans_conf; bool trans_inst, trans_up, trans_conf;
trans_inst = trans_up = trans_conf = false; trans_inst = trans_up = trans_conf = false;
while ((obj = prop_object_iterator_next(iter)) != NULL) { while ((obj = prop_object_iterator_next(trans->iter))) {
if (!prop_dictionary_get_uint64(obj, "filename-size", &tsize))
return errno;
dlsize += tsize;
tsize = 0;
if (!prop_dictionary_get_uint64(obj, "installed_size", &tsize))
return errno;
instsize += tsize;
tsize = 0;
}
prop_object_iterator_reset(iter);
while ((obj = prop_object_iterator_next(iter))) {
if (!prop_dictionary_get_cstring_nocopy(obj, if (!prop_dictionary_get_cstring_nocopy(obj,
"trans-action", &tract)) "trans-action", &tract))
return errno; return errno;
if (strcmp(tract, "install") == 0) if (strcmp(tract, "install") == 0) {
trans->inst_pkgcnt++;
trans_inst = true; trans_inst = true;
else if (strcmp(tract, "update") == 0) } else if (strcmp(tract, "update") == 0) {
trans->up_pkgcnt++;
trans_up = true; trans_up = true;
else if (strcmp(tract, "configure") == 0) } else if (strcmp(tract, "configure") == 0) {
trans->cf_pkgcnt++;
trans_conf = true; trans_conf = true;
} }
prop_object_iterator_reset(iter); }
prop_object_iterator_reset(trans->iter);
/* /*
* Show the list of packages that will be installed. * Show the list of packages that will be installed.
*/ */
if (trans_inst) { if (trans_inst) {
printf("The following packages will be installed:\n\n"); printf("The following packages will be installed:\n\n");
show_package_list(iter, "install"); show_package_list(trans->iter, "install");
printf("\n\n"); printf("\n\n");
} }
if (trans_up) { if (trans_up) {
printf("The following packages will be updated:\n\n"); printf("The following packages will be updated:\n\n");
show_package_list(iter, "update"); show_package_list(trans->iter, "update");
printf("\n\n"); printf("\n\n");
} }
if (trans_conf) { if (trans_conf) {
printf("The following packages will be configured:\n\n"); printf("The following packages will be configured:\n\n");
show_package_list(iter, "configure"); show_package_list(trans->iter, "configure");
printf("\n\n"); printf("\n\n");
} }
/* /*
* Show total download/installed size for all required packages. * Show total download/installed size for all required packages.
*/ */
if (!prop_dictionary_get_uint64(trans->dict,
"total-download-size", &dlsize))
return errno;
if (!prop_dictionary_get_uint64(trans->dict,
"total-installed-size", &instsize))
return errno;
if (xbps_humanize_number(size, 5, (int64_t)dlsize, if (xbps_humanize_number(size, 5, (int64_t)dlsize,
"", HN_AUTOSCALE, HN_B|HN_DECIMAL|HN_NOSPACE) == -1) { "", HN_AUTOSCALE, HN_B|HN_DECIMAL|HN_NOSPACE) == -1) {
fprintf(stderr, "xbps-bin: error: humanize_number returns " fprintf(stderr, "xbps-bin: error: humanize_number returns "
@ -334,14 +329,14 @@ pkgname_from_pkgmatch(const char *pkg)
* *
* XXX REALLY FIX THIS CRAP! I haven't found much easier ways... * XXX REALLY FIX THIS CRAP! I haven't found much easier ways...
*/ */
if ((version = xbps_get_pkgdep_version(pkg))) { if ((version = xbps_get_pkgpattern_version(pkg))) {
while (*version) { while (*version) {
if (!isdigit((unsigned char)*version)) { if (!isdigit((unsigned char)*version)) {
version++; version++;
continue; continue;
} }
if (xbps_cmpver("0", version) <= 0) if (xbps_cmpver("0", version) <= 0)
return xbps_get_pkgdep_name(pkg); return xbps_get_pkgpattern_name(pkg);
} }
} }
if ((version = xbps_get_pkg_version(pkg))) { if ((version = xbps_get_pkg_version(pkg))) {
@ -394,7 +389,7 @@ xbps_install_new_pkg(const char *pkg)
/* /*
* Find a package in a repository and prepare for installation. * Find a package in a repository and prepare for installation.
*/ */
if ((pkgd = xbps_find_pkg_installed_from_plist(pkgname))) { if ((pkgd = xbps_find_pkg_dict_installed(pkgname, false))) {
printf("Package '%s' is already installed.\n", pkgname); printf("Package '%s' is already installed.\n", pkgname);
prop_object_release(pkgd); prop_object_release(pkgd);
if (pkgmatch) if (pkgmatch)
@ -424,7 +419,7 @@ xbps_update_pkg(const char *pkgname)
prop_dictionary_t pkgd; prop_dictionary_t pkgd;
int rv = 0; int rv = 0;
pkgd = xbps_find_pkg_installed_from_plist(pkgname); pkgd = xbps_find_pkg_dict_installed(pkgname, false);
printf("Finding new '%s' package...\n", pkgname); printf("Finding new '%s' package...\n", pkgname);
if (pkgd) { if (pkgd) {
rv = xbps_repository_update_pkg(pkgname, pkgd); rv = xbps_repository_update_pkg(pkgname, pkgd);
@ -445,70 +440,12 @@ xbps_update_pkg(const char *pkgname)
return rv; return rv;
} }
int
xbps_exec_transaction(bool yes)
{
struct transaction *trans;
prop_array_t array;
int rv = 0;
trans = calloc(1, sizeof(struct transaction));
if (trans == NULL)
goto out;
trans->dict = xbps_repository_get_transaction_dict();
if (trans->dict == NULL)
goto out;
/*
* Bail out if there are unresolved deps.
*/
array = prop_dictionary_get(trans->dict, "missing_deps");
if (prop_array_count(array) > 0) {
show_missing_deps(trans->dict);
goto out;
}
DPRINTF(("%s", prop_dictionary_externalize(trans->dict)));
/*
* Sort the package transaction dictionary.
*/
if ((rv = xbps_sort_pkg_deps(trans->dict)) != 0) {
fprintf(stderr, "xbps-bin: error while sorting "
"packages: %s\n", strerror(rv));
goto out;
}
/*
* It's time to run the transaction!
*/
trans->iter = xbps_get_array_iter_from_dict(trans->dict, "packages");
if (trans->iter == NULL) {
fprintf(stderr, "xbps-bin: error allocating array mem! (%s)\n",
strerror(errno));
goto out;
}
trans->yes = yes;
rv = exec_transaction(trans);
out:
if (trans->iter)
prop_object_iterator_release(trans->iter);
if (trans->dict)
prop_object_release(trans->dict);
if (trans)
free(trans);
return rv;
}
static int static int
replace_packages(prop_object_iterator_t iter, const char *pkgver) replace_packages(prop_object_iterator_t iter, const char *pkgver)
{ {
prop_dictionary_t instd; prop_dictionary_t instd;
prop_object_t obj; prop_object_t obj;
const char *reppkgn, *version; const char *pattern, *reppkgn, *reppkgver, *version;
int rv = 0; int rv = 0;
/* /*
@ -516,16 +453,23 @@ replace_packages(prop_object_iterator_t iter, const char *pkgver)
* them before upgrading or installing new one. * them before upgrading or installing new one.
*/ */
while ((obj = prop_object_iterator_next(iter))) { while ((obj = prop_object_iterator_next(iter))) {
reppkgn = prop_string_cstring_nocopy(obj); pattern = prop_string_cstring_nocopy(obj);
if (reppkgn == NULL) if (pattern == NULL)
return errno; return errno;
instd = xbps_find_pkg_installed_from_plist(reppkgn); /*
* If pattern matches an installed package, replace it.
*/
instd = xbps_find_pkg_dict_installed(pattern, true);
if (instd == NULL) if (instd == NULL)
continue; continue;
printf("Replacing package '%s' with '%s' ...\n", prop_dictionary_get_cstring_nocopy(instd, "pkgname", &reppkgn);
reppkgn, pkgver); prop_dictionary_get_cstring_nocopy(instd, "pkgver", &reppkgver);
printf("Replacing package '%s' with '%s' "
"(matched by '%s')...\n", reppkgver, pkgver, pattern);
prop_object_release(instd);
version = xbps_get_pkg_version(pkgver); version = xbps_get_pkg_version(pkgver);
if ((rv = xbps_remove_pkg(reppkgn, version, false)) != 0) { if ((rv = xbps_remove_pkg(reppkgn, version, false)) != 0) {
fprintf(stderr, "xbps-bin: couldn't remove %s (%s)\n", fprintf(stderr, "xbps-bin: couldn't remove %s (%s)\n",
@ -562,8 +506,7 @@ exec_transaction(struct transaction *trans)
/* /*
* Show download/installed size for the transaction. * Show download/installed size for the transaction.
*/ */
rv = show_transaction_sizes(trans->iter); if ((rv = show_transaction_sizes(trans)) != 0)
if (rv != 0)
return rv; return rv;
/* /*
@ -580,12 +523,14 @@ exec_transaction(struct transaction *trans)
* Download binary packages (if they come from a remote repository) * Download binary packages (if they come from a remote repository)
* and check its SHA256 hash. * and check its SHA256 hash.
*/ */
printf("[1/3] Downloading/integrity check\n\n");
if ((rv = download_package_list(trans->iter)) != 0) if ((rv = download_package_list(trans->iter)) != 0)
return rv; return rv;
/* /*
* Iterate over the transaction dictionary. * Iterate over the transaction dictionary.
*/ */
printf("\n[2/3] Unpacking\n\n");
while ((obj = prop_object_iterator_next(trans->iter)) != NULL) { while ((obj = prop_object_iterator_next(trans->iter)) != NULL) {
if (!prop_dictionary_get_cstring_nocopy(obj, if (!prop_dictionary_get_cstring_nocopy(obj,
"pkgname", &pkgname)) "pkgname", &pkgname))
@ -631,7 +576,7 @@ exec_transaction(struct transaction *trans)
} }
if (strcmp(tract, "update") == 0) { if (strcmp(tract, "update") == 0) {
instpkgd = xbps_find_pkg_installed_from_plist(pkgname); instpkgd = xbps_find_pkg_dict_installed(pkgname, false);
if (instpkgd == NULL) { if (instpkgd == NULL) {
fprintf(stderr, "xbps-bin: error: unable to " fprintf(stderr, "xbps-bin: error: unable to "
"find %s installed dict!\n", pkgname); "find %s installed dict!\n", pkgname);
@ -648,29 +593,26 @@ exec_transaction(struct transaction *trans)
/* /*
* If package is marked as 'essential' remove old * If package is marked as 'essential' remove old
* requiredby entries and overwrite pkg files; otherwise * requiredby entries and overwrite pkg files; otherwise
* remove old package and install new one. * remove old package and install new one. This
* is all handled internally in xbps_remove_pkg()
* and xbps_unpack_binary_pkg().
*/ */
if (essential) { if (essential)
rv = xbps_requiredby_pkg_remove(pkgname); printf("Replacing %s-%s with %s-%s ...\n",
if (rv != 0) { pkgname, instver, pkgname, version);
fprintf(stderr, "xbps-bin: error: " else
"couldn't remove reqby" printf("Removing %s-%s before installing new "
" entries for %s-%s (%s)\n", "version ...\n", pkgname, instver);
pkgname, instver, strerror(rv));
return rv;
}
} else {
printf("Removing %s-%s ...\n",
pkgname, instver);
rv = xbps_remove_pkg(pkgname, version, true); rv = xbps_remove_pkg(pkgname, version, true);
if (rv != 0) { if (rv != 0) {
fprintf(stderr, "xbps-bin: error " fprintf(stderr, "xbps-bin: error "
"removing %s-%s (%s)\n", "%s %s-%s (%s)\n", essential ?
pkgname, instver, strerror(rv)); "replacing" : "removing", pkgname,
instver, strerror(rv));
return rv; return rv;
} }
} }
}
/* /*
* Unpack binary package. * Unpack binary package.
*/ */
@ -694,6 +636,7 @@ exec_transaction(struct transaction *trans)
/* /*
* Configure all unpacked packages. * Configure all unpacked packages.
*/ */
printf("\n[3/3] Configuring\n\n");
while ((obj = prop_object_iterator_next(trans->iter)) != NULL) { while ((obj = prop_object_iterator_next(trans->iter)) != NULL) {
if (!prop_dictionary_get_cstring_nocopy(obj, if (!prop_dictionary_get_cstring_nocopy(obj,
"pkgname", &pkgname)) "pkgname", &pkgname))
@ -713,7 +656,60 @@ exec_transaction(struct transaction *trans)
"package %s (%s)\n", pkgname, strerror(rv)); "package %s (%s)\n", pkgname, strerror(rv));
return rv; return rv;
} }
trans->cf_pkgcnt++;
} }
printf("\nxbps-bin: %zu installed, %zu updated, "
"%zu configured.\n", trans->inst_pkgcnt, trans->up_pkgcnt,
trans->cf_pkgcnt);
return 0; return 0;
} }
int
xbps_exec_transaction(bool yes)
{
struct transaction *trans;
prop_array_t array;
int rv = 0;
trans = calloc(1, sizeof(struct transaction));
if (trans == NULL)
goto out;
trans->dict = xbps_repository_get_transaction_dict();
if (trans->dict == NULL)
goto out;
/*
* Bail out if there are unresolved deps.
*/
array = prop_dictionary_get(trans->dict, "missing_deps");
if (prop_array_count(array) > 0) {
show_missing_deps(trans->dict);
goto out;
}
DPRINTF(("%s", prop_dictionary_externalize(trans->dict)));
/*
* It's time to run the transaction!
*/
trans->iter = xbps_get_array_iter_from_dict(trans->dict, "packages");
if (trans->iter == NULL) {
fprintf(stderr, "xbps-bin: error allocating array mem! (%s)\n",
strerror(errno));
goto out;
}
trans->yes = yes;
rv = exec_transaction(trans);
out:
if (trans->iter)
prop_object_iterator_release(trans->iter);
if (trans->dict)
prop_object_release(trans->dict);
if (trans)
free(trans);
return rv;
}

View File

@ -34,10 +34,6 @@
#include "defs.h" #include "defs.h"
#include "../xbps-repo/defs.h" #include "../xbps-repo/defs.h"
static void cleanup(int);
static void usage(void);
static int list_pkgs_in_dict(prop_object_t, void *, bool *);
static void static void
usage(void) usage(void)
{ {
@ -109,6 +105,14 @@ list_manual_packages(prop_object_t obj, void *arg, bool *loop_done)
return 0; return 0;
} }
static void
cleanup(int signum)
{
xbps_regpkgs_dictionary_release();
exit(signum);
}
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
@ -332,10 +336,3 @@ main(int argc, char **argv)
out: out:
cleanup(rv); cleanup(rv);
} }
static void
cleanup(int signum)
{
xbps_regpkgs_dictionary_release();
exit(signum);
}

View File

@ -130,7 +130,7 @@ xbps_remove_installed_pkgs(int argc, char **argv, bool force)
* First check if package is required by other packages. * First check if package is required by other packages.
*/ */
for (i = 1; i < argc; i++) { for (i = 1; i < argc; i++) {
dict = xbps_find_pkg_installed_from_plist(argv[i]); dict = xbps_find_pkg_dict_installed(argv[i], false);
if (dict == NULL) { if (dict == NULL) {
printf("Package %s is not installed.\n", argv[i]); printf("Package %s is not installed.\n", argv[i]);
continue; continue;
@ -155,7 +155,7 @@ xbps_remove_installed_pkgs(int argc, char **argv, bool force)
*/ */
printf("The following packages will be removed:\n\n"); printf("The following packages will be removed:\n\n");
for (i = 1; i < argc; i++) { for (i = 1; i < argc; i++) {
dict = xbps_find_pkg_installed_from_plist(argv[i]); dict = xbps_find_pkg_dict_installed(argv[i], false);
if (dict == NULL) if (dict == NULL)
continue; continue;
prop_dictionary_get_cstring_nocopy(dict, "version", &version); prop_dictionary_get_cstring_nocopy(dict, "version", &version);
@ -180,7 +180,7 @@ xbps_remove_installed_pkgs(int argc, char **argv, bool force)
printf("Forcing removal!\n"); printf("Forcing removal!\n");
for (i = 1; i < argc; i++) { for (i = 1; i < argc; i++) {
dict = xbps_find_pkg_installed_from_plist(argv[i]); dict = xbps_find_pkg_dict_installed(argv[i], false);
if (dict == NULL) if (dict == NULL)
continue; continue;
prop_dictionary_get_cstring_nocopy(dict, "version", &version); prop_dictionary_get_cstring_nocopy(dict, "version", &version);

View File

@ -42,7 +42,7 @@ xbps_show_pkg_deps(const char *pkgname)
assert(pkgname != NULL); assert(pkgname != NULL);
pkgd = xbps_find_pkg_installed_from_plist(pkgname); pkgd = xbps_find_pkg_dict_installed(pkgname, false);
if (pkgd == NULL) { if (pkgd == NULL) {
printf("Package %s is not installed.\n", pkgname); printf("Package %s is not installed.\n", pkgname);
return 0; return 0;
@ -79,7 +79,7 @@ xbps_show_pkg_reverse_deps(const char *pkgname)
prop_dictionary_t pkgd; prop_dictionary_t pkgd;
int rv = 0; int rv = 0;
pkgd = xbps_find_pkg_installed_from_plist(pkgname); pkgd = xbps_find_pkg_dict_installed(pkgname, false);
if (pkgd == NULL) { if (pkgd == NULL) {
printf("Package %s is not installed.\n", pkgname); printf("Package %s is not installed.\n", pkgname);
return 0; return 0;

View File

@ -34,8 +34,6 @@
#include <xbps_api.h> #include <xbps_api.h>
#include "defs.h" #include "defs.h"
static void usage(void);
static void static void
usage(void) usage(void)
{ {
@ -122,7 +120,7 @@ main(int argc, char **argv)
if (argc != 1) if (argc != 1)
usage(); usage();
SIMPLEQ_FOREACH(rpool, &repopool_queue, chain) SIMPLEQ_FOREACH(rpool, &rp_queue, rp_entries)
printf("%s\n", rpool->rp_uri); printf("%s\n", rpool->rp_uri);
} else if ((strcasecmp(argv[0], "rm") == 0) || } else if ((strcasecmp(argv[0], "rm") == 0) ||
@ -141,7 +139,7 @@ main(int argc, char **argv)
if (argc != 2) if (argc != 2)
usage(); usage();
SIMPLEQ_FOREACH(rpool, &repopool_queue, chain) { SIMPLEQ_FOREACH(rpool, &rp_queue, rp_entries) {
printf("From %s repository ...\n", rpool->rp_uri); printf("From %s repository ...\n", rpool->rp_uri);
(void)xbps_callback_array_iter_in_dict(rpool->rp_repod, (void)xbps_callback_array_iter_in_dict(rpool->rp_repod,
"packages", show_pkg_namedesc, argv[1]); "packages", show_pkg_namedesc, argv[1]);

View File

@ -222,7 +222,7 @@ show_pkg_info_from_repolist(const char *pkgname)
prop_dictionary_t repo_pkgd, pkg_propsd; prop_dictionary_t repo_pkgd, pkg_propsd;
int rv = 0; int rv = 0;
SIMPLEQ_FOREACH(rp, &repopool_queue, chain) { SIMPLEQ_FOREACH(rp, &rp_queue, rp_entries) {
char *url = NULL; char *url = NULL;
repo_pkgd = xbps_find_pkg_in_dict_by_name(rp->rp_repod, repo_pkgd = xbps_find_pkg_in_dict_by_name(rp->rp_repod,
"packages", pkgname); "packages", pkgname);
@ -264,7 +264,7 @@ show_pkg_deps_from_repolist(const char *pkgname)
const char *ver; const char *ver;
int rv = 0; int rv = 0;
SIMPLEQ_FOREACH(rd, &repopool_queue, chain) { SIMPLEQ_FOREACH(rd, &rp_queue, rp_entries) {
pkgd = xbps_find_pkg_in_dict_by_name(rd->rp_repod, pkgd = xbps_find_pkg_in_dict_by_name(rd->rp_repod,
"packages", pkgname); "packages", pkgname);
if (pkgd == NULL) { if (pkgd == NULL) {
@ -294,7 +294,7 @@ repository_sync(void)
char *plist; char *plist;
int rv = 0; int rv = 0;
SIMPLEQ_FOREACH(rp, &repopool_queue, chain) { SIMPLEQ_FOREACH(rp, &rp_queue, rp_entries) {
if (!xbps_check_is_repo_string_remote(rp->rp_uri)) if (!xbps_check_is_repo_string_remote(rp->rp_uri))
continue; continue;

View File

@ -191,7 +191,7 @@ show_pkg_namedesc(prop_object_t obj, void *arg, bool *loop_done)
prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver); prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver);
prop_dictionary_get_cstring_nocopy(obj, "short_desc", &desc); prop_dictionary_get_cstring_nocopy(obj, "short_desc", &desc);
if (xbps_pkgdep_match(pkgver, pattern) == 1) if (xbps_pkgpattern_match(pkgver, pattern) == 1)
printf(" %s - %s\n", pkgver, desc); printf(" %s - %s\n", pkgver, desc);
else if (strcmp(pkgname, pattern) == 0) else if (strcmp(pkgname, pattern) == 0)
printf(" %s - %s\n", pkgver, desc); printf(" %s - %s\n", pkgver, desc);

View File

@ -273,7 +273,7 @@ main(int argc, char **argv)
if (argc != 2) if (argc != 2)
usage(); usage();
pkgname = xbps_get_pkgdep_name(argv[1]); pkgname = xbps_get_pkgpattern_name(argv[1]);
if (pkgname == NULL) if (pkgname == NULL)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -285,7 +285,7 @@ main(int argc, char **argv)
if (argc != 3) if (argc != 3)
usage(); usage();
exit(xbps_pkgdep_match(argv[1], argv[2])); exit(xbps_pkgpattern_match(argv[1], argv[2]));
} else if (strcasecmp(argv[0], "cmpver") == 0) { } else if (strcasecmp(argv[0], "cmpver") == 0) {
/* Compare two version strings, installed vs required */ /* Compare two version strings, installed vs required */

View File

@ -44,8 +44,8 @@ typedef struct _SHA256_CTX {
uint8_t buffer[SHA256_BLOCK_LENGTH]; uint8_t buffer[SHA256_BLOCK_LENGTH];
} SHA256_CTX; } SHA256_CTX;
int XBPS_SHA256_Init(SHA256_CTX *); int HIDDEN XBPS_SHA256_Init(SHA256_CTX *);
int XBPS_SHA256_Update(SHA256_CTX *, const uint8_t *, size_t); int HIDDEN XBPS_SHA256_Update(SHA256_CTX *, const uint8_t *, size_t);
char *XBPS_SHA256_End(SHA256_CTX *, uint8_t *); char HIDDEN *XBPS_SHA256_End(SHA256_CTX *, uint8_t *);
#endif /* !_SHA2_DIGEST_H_ */ #endif /* !_SHA2_DIGEST_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -12,6 +12,7 @@ LIBFETCH_OBJS = fetch/common.o fetch/fetch.o fetch/file.o
LIBFETCH_OBJS += fetch/ftp.o fetch/http.o LIBFETCH_OBJS += fetch/ftp.o fetch/http.o
LIBFETCH_CPPFLAGS = -DFTP_COMBINE_CWDS -DNETBSD -DINET6 -DWITH_SSL LIBFETCH_CPPFLAGS = -DFTP_COMBINE_CWDS -DNETBSD -DINET6 -DWITH_SSL
LIBFETCH_CFLAGS = -Wno-unused-macros -Wno-conversion -Wno-stack-protector LIBFETCH_CFLAGS = -Wno-unused-macros -Wno-conversion -Wno-stack-protector
LIBFETCH_SHLIBCFLAGS = -fvisibility=hidden
LIBFETCH_INCS = fetch/common.h LIBFETCH_INCS = fetch/common.h
LIBFETCH_GEN = fetch/ftperr.h fetch/httperr.h LIBFETCH_GEN = fetch/ftperr.h fetch/httperr.h
@ -37,7 +38,7 @@ fetch/httperr.h: fetch/http.errors
$(LIBFETCH_OBJS): %.o: %.c $(LIBFETCH_INCS) $(LIBFETCH_GEN) $(LIBFETCH_OBJS): %.o: %.c $(LIBFETCH_INCS) $(LIBFETCH_GEN)
@echo " [CC]\t\t$@" @echo " [CC]\t\t$@"
@$(CC) $(CPPFLAGS) $(LIBFETCH_CPPFLAGS) $(CFLAGS) \ @$(CC) $(CPPFLAGS) $(LIBFETCH_CPPFLAGS) $(CFLAGS) \
$(LIBFETCH_CFLAGS) $(SHAREDLIB_CFLAGS) -c $< -o $@ $(LIBFETCH_CFLAGS) $(LIBFETCH_SHLIBCFLAGS) -c $< -o $@
$(OBJS): %.o: %.c $(OBJS): %.o: %.c
@echo " [CC]\t\t$@" @echo " [CC]\t\t$@"

View File

@ -223,7 +223,7 @@ get_component(const char *position, version_component *component)
* of the version should conform to the porting guidelines. It can contain * of the version should conform to the porting guidelines. It can contain
* multiple components, separated by a period, including letters. * multiple components, separated by a period, including letters.
*/ */
int SYMEXPORT int
xbps_cmpver(const char *pkg1, const char *pkg2) xbps_cmpver(const char *pkg1, const char *pkg2)
{ {
const char *v1, *v2, *ve1, *ve2; const char *v1, *v2, *ve1, *ve2;

View File

@ -32,7 +32,7 @@
#include <xbps_api.h> #include <xbps_api.h>
int int HIDDEN
xbps_config_file_from_archive_entry(prop_dictionary_t d, xbps_config_file_from_archive_entry(prop_dictionary_t d,
struct archive_entry *entry, struct archive_entry *entry,
const char *pkgname, const char *pkgname,

View File

@ -28,12 +28,25 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
/**
* @file lib/configure.c
* @brief Package configuration routines
* @defgroup configure Package configuration functions
*
* Configure a package or all packages. Only packages in <b>unpacked</b>
* state will be processed (unless overriden). Package configuration steps:
*
* 1- Its <b>post-install</b> target in the INSTALL script will be executed.
*
* 2- Its state will be changed to <b>installed</b> if previous step
* ran successful.
*
* If the \a XBPS_FLAG_FORCE is set through xbps_set_flags(), the package
* (or packages) will be reconfigured even if its state is <b>installed</b>.
*/
#include <xbps_api.h> #include <xbps_api.h>
/* int
* Configure all packages currently in unpacked state.
*/
int SYMEXPORT
xbps_configure_all_pkgs(void) xbps_configure_all_pkgs(void)
{ {
prop_dictionary_t d; prop_dictionary_t d;
@ -78,12 +91,7 @@ out:
return rv; return rv;
} }
/* int
* Configure a package that is in unpacked state. This runs the
* post INSTALL action if required and updates package state to
* to installed.
*/
int SYMEXPORT
xbps_configure_pkg(const char *pkgname, const char *version, bool check_state, xbps_configure_pkg(const char *pkgname, const char *version, bool check_state,
bool update) bool update)
{ {
@ -111,7 +119,7 @@ xbps_configure_pkg(const char *pkgname, const char *version, bool check_state,
} else if (state != XBPS_PKG_STATE_UNPACKED) } else if (state != XBPS_PKG_STATE_UNPACKED)
return EINVAL; return EINVAL;
pkgd = xbps_find_pkg_installed_from_plist(pkgname); pkgd = xbps_find_pkg_dict_installed(pkgname, false);
if (pkgd == NULL) if (pkgd == NULL)
return errno; return errno;

View File

@ -42,6 +42,13 @@
#include <xbps_api.h> #include <xbps_api.h>
#include "fetch.h" #include "fetch.h"
/**
* @file lib/download.c
* @brief Download routines
* @defgroup download Internal download functions
*
* These functions allow you to download files.
*/
struct xferstat { struct xferstat {
struct timeval start; struct timeval start;
struct timeval last; struct timeval last;
@ -164,7 +171,7 @@ stat_end(struct xferstat *xsp)
fprintf(stderr, "\033[K\n"); fprintf(stderr, "\033[K\n");
} }
const char SYMEXPORT * const char *
xbps_fetch_error_string(void) xbps_fetch_error_string(void)
{ {
return fetchLastErrString; return fetchLastErrString;
@ -183,11 +190,7 @@ print_time(time_t *t)
} }
#endif #endif
/* int
* Returns -1 on error, 0 if not download (because local/remote
* size and/or mtime match) and 1 if downloaded successfully.
*/
int SYMEXPORT
xbps_fetch_file(const char *uri, const char *outputdir, bool refetch, xbps_fetch_file(const char *uri, const char *outputdir, bool refetch,
const char *flags) const char *flags)
{ {

View File

@ -36,15 +36,16 @@
#include <xbps_api.h> #include <xbps_api.h>
static int vfcexec(const char *, int, const char *, va_list); /**
static int pfcexec(const char *, const char *, const char **); * @file lib/fexec.c
* @brief Generic file execution routines
/* * @defgroup fexec File execution functions
* Fork, then if /bin/sh exists change root directory to *
* path; otherwise just change current working directory. * These functions will fork and execute a program in cwd (current working
* Execute the command and arguments in the argv array. * directory), destination directory or changing root directory to
* wait for the command to finish, then return the exit status. * destination directory and passing an arbitrary number of arguments to it.
*/ */
static int static int
pfcexec(const char *path, const char *file, const char **argv) pfcexec(const char *path, const char *file, const char **argv)
{ {
@ -128,7 +129,7 @@ vfcexec(const char *path, int skipempty, const char *arg, va_list ap)
return retval; return retval;
} }
int SYMEXPORT int
xbps_file_exec(const char *arg, ...) xbps_file_exec(const char *arg, ...)
{ {
va_list ap; va_list ap;
@ -141,7 +142,7 @@ xbps_file_exec(const char *arg, ...)
return result; return result;
} }
int SYMEXPORT int
xbps_file_exec_skipempty(const char *arg, ...) xbps_file_exec_skipempty(const char *arg, ...)
{ {
va_list ap; va_list ap;
@ -154,7 +155,7 @@ xbps_file_exec_skipempty(const char *arg, ...)
return result; return result;
} }
int SYMEXPORT int
xbps_file_chdir_exec(const char *path, const char *arg, ...) xbps_file_chdir_exec(const char *path, const char *arg, ...)
{ {
va_list ap; va_list ap;

View File

@ -39,7 +39,7 @@
#include <xbps_api.h> #include <xbps_api.h>
int SYMEXPORT int
xbps_humanize_number(char *buf, size_t len, int64_t bytes, xbps_humanize_number(char *buf, size_t len, int64_t bytes,
const char *suffix, int scale, int flags) const char *suffix, int scale, int flags)
{ {

View File

@ -37,11 +37,13 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <xbps_api.h> #include <xbps_api.h>
/*
* mkpath -- create directories. /**
* path - path * @file lib/mkpath.c
* mode - file mode of terminal directory * @brief Generic directory creation routines
* @defgroup dircreate Generic directory creation functions
*/ */
int int
xbps_mkpath(char *path, mode_t mode) xbps_mkpath(char *path, mode_t mode)
{ {

View File

@ -31,6 +31,12 @@
#include <xbps_api.h> #include <xbps_api.h>
/**
* @file lib/orphans.c
* @brief Package orphans handling routines
* @defgroup pkg_orphans Package orphans handling functions
*/
struct orphan_pkg { struct orphan_pkg {
SIMPLEQ_ENTRY(orphan_pkg) chain; SIMPLEQ_ENTRY(orphan_pkg) chain;
prop_dictionary_t dict; prop_dictionary_t dict;
@ -128,7 +134,7 @@ cleanup(void)
xbps_regpkgs_dictionary_release(); xbps_regpkgs_dictionary_release();
} }
prop_array_t SYMEXPORT prop_array_t
xbps_find_orphan_packages(void) xbps_find_orphan_packages(void)
{ {
prop_array_t array; prop_array_t array;

View File

@ -27,6 +27,12 @@
#include <xbps_api.h> #include <xbps_api.h>
/**
* @file lib/pkgmatch.c
* @brief Package version matching routines
* @defgroup vermatch Package version matching functions
*/
static int static int
csh_match(const char *pattern, const char *string, int flags) csh_match(const char *pattern, const char *string, int flags)
{ {
@ -106,8 +112,8 @@ csh_match(const char *pattern, const char *string, int flags)
return ret; return ret;
} }
int SYMEXPORT int
xbps_pkgdep_match(const char *instpkg, char *pattern) xbps_pkgpattern_match(const char *instpkg, char *pattern)
{ {
const char *fname = instpkg; const char *fname = instpkg;
char basefname[PATH_MAX], condchar = '\0', *condition; char basefname[PATH_MAX], condchar = '\0', *condition;

View File

@ -31,7 +31,15 @@
#include <xbps_api.h> #include <xbps_api.h>
bool SYMEXPORT /**
* @file lib/plist.c
* @brief PropertyList generic routines
* @defgroup plist PropertyList generic functions
*
* These functions manipulate plist files and objects shared by almost
* all library functions.
*/
bool
xbps_add_obj_to_dict(prop_dictionary_t dict, prop_object_t obj, xbps_add_obj_to_dict(prop_dictionary_t dict, prop_object_t obj,
const char *key) const char *key)
{ {
@ -48,7 +56,7 @@ xbps_add_obj_to_dict(prop_dictionary_t dict, prop_object_t obj,
return true; return true;
} }
bool SYMEXPORT bool
xbps_add_obj_to_array(prop_array_t array, prop_object_t obj) xbps_add_obj_to_array(prop_array_t array, prop_object_t obj)
{ {
assert(array != NULL); assert(array != NULL);
@ -63,7 +71,7 @@ xbps_add_obj_to_array(prop_array_t array, prop_object_t obj)
return true; return true;
} }
int SYMEXPORT int
xbps_callback_array_iter_in_dict(prop_dictionary_t dict, const char *key, xbps_callback_array_iter_in_dict(prop_dictionary_t dict, const char *key,
int (*fn)(prop_object_t, void *, bool *), int (*fn)(prop_object_t, void *, bool *),
void *arg) void *arg)
@ -91,7 +99,7 @@ xbps_callback_array_iter_in_dict(prop_dictionary_t dict, const char *key,
return rv; return rv;
} }
int SYMEXPORT int
xbps_callback_array_iter_reverse_in_dict(prop_dictionary_t dict, xbps_callback_array_iter_reverse_in_dict(prop_dictionary_t dict,
const char *key, int (*fn)(prop_object_t, void *, bool *), void *arg) const char *key, int (*fn)(prop_object_t, void *, bool *), void *arg)
{ {
@ -122,7 +130,7 @@ xbps_callback_array_iter_reverse_in_dict(prop_dictionary_t dict,
return rv; return rv;
} }
prop_dictionary_t SYMEXPORT prop_dictionary_t
xbps_find_pkg_from_plist(const char *plist, const char *pkgname) xbps_find_pkg_from_plist(const char *plist, const char *pkgname)
{ {
prop_dictionary_t dict, obj, res; prop_dictionary_t dict, obj, res;
@ -146,8 +154,8 @@ xbps_find_pkg_from_plist(const char *plist, const char *pkgname)
return res; return res;
} }
prop_dictionary_t SYMEXPORT prop_dictionary_t
xbps_find_pkg_installed_from_plist(const char *pkgname) xbps_find_pkg_dict_installed(const char *str, bool bypattern)
{ {
prop_dictionary_t d, pkgd; prop_dictionary_t d, pkgd;
pkg_state_t state = 0; pkg_state_t state = 0;
@ -155,7 +163,10 @@ xbps_find_pkg_installed_from_plist(const char *pkgname)
if ((d = xbps_regpkgs_dictionary_init()) == NULL) if ((d = xbps_regpkgs_dictionary_init()) == NULL)
return NULL; return NULL;
pkgd = xbps_find_pkg_in_dict_by_name(d, "packages", pkgname); if (bypattern)
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) if (pkgd == NULL)
goto fail; goto fail;
@ -178,8 +189,9 @@ fail:
return NULL; return NULL;
} }
prop_dictionary_t SYMEXPORT prop_dictionary_t
xbps_find_pkg_in_dict_by_name(prop_dictionary_t dict, const char *key, xbps_find_pkg_in_dict_by_name(prop_dictionary_t dict,
const char *key,
const char *pkgname) const char *pkgname)
{ {
prop_object_iterator_t iter; prop_object_iterator_t iter;
@ -207,9 +219,10 @@ xbps_find_pkg_in_dict_by_name(prop_dictionary_t dict, const char *key,
return obj; return obj;
} }
prop_dictionary_t SYMEXPORT prop_dictionary_t
xbps_find_pkg_in_dict_by_pkgmatch(prop_dictionary_t dict, const char *key, xbps_find_pkg_in_dict_by_pattern(prop_dictionary_t dict,
const char *pkgmatch) const char *key,
const char *pattern)
{ {
prop_object_iterator_t iter; prop_object_iterator_t iter;
prop_object_t obj = NULL; prop_object_t obj = NULL;
@ -226,7 +239,7 @@ xbps_find_pkg_in_dict_by_pkgmatch(prop_dictionary_t dict, const char *key,
if (!prop_dictionary_get_cstring_nocopy(obj, if (!prop_dictionary_get_cstring_nocopy(obj,
"pkgver", &pkgver)) "pkgver", &pkgver))
break; break;
if (xbps_pkgdep_match(pkgver, __UNCONST(pkgmatch))) if (xbps_pkgpattern_match(pkgver, __UNCONST(pattern)))
break; break;
} }
prop_object_iterator_release(iter); prop_object_iterator_release(iter);
@ -236,7 +249,7 @@ xbps_find_pkg_in_dict_by_pkgmatch(prop_dictionary_t dict, const char *key,
return obj; return obj;
} }
bool SYMEXPORT bool
xbps_find_string_in_array(prop_array_t array, const char *val) xbps_find_string_in_array(prop_array_t array, const char *val)
{ {
prop_object_iterator_t iter; prop_object_iterator_t iter;
@ -262,7 +275,7 @@ xbps_find_string_in_array(prop_array_t array, const char *val)
return false; return false;
} }
prop_object_iterator_t SYMEXPORT prop_object_iterator_t
xbps_get_array_iter_from_dict(prop_dictionary_t dict, const char *key) xbps_get_array_iter_from_dict(prop_dictionary_t dict, const char *key)
{ {
prop_array_t array; prop_array_t array;
@ -277,7 +290,7 @@ xbps_get_array_iter_from_dict(prop_dictionary_t dict, const char *key)
return prop_array_iterator(array); return prop_array_iterator(array);
} }
int SYMEXPORT int
xbps_remove_string_from_array(prop_array_t array, const char *str) xbps_remove_string_from_array(prop_array_t array, const char *str)
{ {
prop_object_t obj; prop_object_t obj;
@ -308,7 +321,7 @@ xbps_remove_string_from_array(prop_array_t array, const char *str)
return 0; return 0;
} }
int SYMEXPORT int
xbps_remove_pkg_from_dict(prop_dictionary_t dict, const char *key, xbps_remove_pkg_from_dict(prop_dictionary_t dict, const char *key,
const char *pkgname) const char *pkgname)
{ {
@ -353,7 +366,7 @@ xbps_remove_pkg_from_dict(prop_dictionary_t dict, const char *key,
return 0; return 0;
} }
int SYMEXPORT int
xbps_remove_pkg_dict_from_file(const char *pkg, const char *plist) xbps_remove_pkg_dict_from_file(const char *pkg, const char *plist)
{ {
prop_dictionary_t pdict; prop_dictionary_t pdict;
@ -382,7 +395,7 @@ xbps_remove_pkg_dict_from_file(const char *pkg, const char *plist)
return 0; return 0;
} }
prop_dictionary_t SYMEXPORT prop_dictionary_t
xbps_read_dict_from_archive_entry(struct archive *ar, xbps_read_dict_from_archive_entry(struct archive *ar,
struct archive_entry *entry) struct archive_entry *entry)
{ {

View File

@ -31,9 +31,77 @@
#include <xbps_api.h> #include <xbps_api.h>
static int remove_pkg_metadata(const char *); /**
* @file lib/purge.c
* @brief Package purging routines
* @defgroup purge Package purging functions
*
* These functions will purge an specified package or all packages.
* Only packages in <b>config-files</b> state will be processed
* (unless overriden). Package purging steps:
*
* 1- Its <b>post-remove</b> target specified in the REMOVE script
* will be executed.
*
* 2- Unmodified configuration files and directories containing them
* will be removed (if empty).
*
* 3- Its metadata directory and all its files will be removed.
*
* 4- It will be unregistered from the installed packages database with
* xbps_unregister_pkg().
*/
int SYMEXPORT static int
remove_pkg_metadata(const char *pkgname)
{
struct dirent *dp;
DIR *dirp;
char *metadir, *path;
int flags = 0, rv = 0;
assert(pkgname != NULL);
flags = xbps_get_flags();
metadir = xbps_xasprintf("%s/%s/metadata/%s", xbps_get_rootdir(),
XBPS_META_PATH, pkgname);
if (metadir == NULL)
return errno;
dirp = opendir(metadir);
if (dirp == NULL) {
free(metadir);
return errno;
}
while ((dp = readdir(dirp)) != NULL) {
if ((strcmp(dp->d_name, ".") == 0) ||
(strcmp(dp->d_name, "..") == 0))
continue;
path = xbps_xasprintf("%s/%s", metadir, dp->d_name);
if (path == NULL) {
(void)closedir(dirp);
free(metadir);
return -1;
}
if ((rv = unlink(path)) == -1) {
if (flags & XBPS_FLAG_VERBOSE)
printf("WARNING: can't remove %s (%s)\n",
pkgname, strerror(errno));
}
free(path);
}
(void)closedir(dirp);
rv = rmdir(metadir);
free(metadir);
return rv;
}
int
xbps_purge_all_pkgs(void) xbps_purge_all_pkgs(void)
{ {
@ -73,12 +141,7 @@ out:
return rv; return rv;
} }
/* int
* Purge a package that is currently in "config-files" state.
* This removes configuration files if they weren't modified,
* removes metadata files and fully unregisters the package.
*/
int SYMEXPORT
xbps_purge_pkg(const char *pkgname, bool check_state) xbps_purge_pkg(const char *pkgname, bool check_state)
{ {
prop_dictionary_t dict; prop_dictionary_t dict;
@ -129,59 +192,13 @@ xbps_purge_pkg(const char *pkgname, bool check_state)
* Remove metadata dir and unregister package. * Remove metadata dir and unregister package.
*/ */
if ((rv = remove_pkg_metadata(pkgname)) == 0) { if ((rv = remove_pkg_metadata(pkgname)) == 0) {
if ((rv = xbps_unregister_pkg(pkgname)) == 0) if ((rv = xbps_unregister_pkg(pkgname)) == 0) {
printf("Package %s has been purged successfully.\n", if (flags & XBPS_FLAG_VERBOSE) {
pkgname); printf("Package %s purged "
"successfully.\n", pkgname);
}
}
} }
return rv; return rv;
} }
static int
remove_pkg_metadata(const char *pkgname)
{
struct dirent *dp;
DIR *dirp;
char *metadir, *path;
int flags = 0, rv = 0;
assert(pkgname != NULL);
flags = xbps_get_flags();
metadir = xbps_xasprintf("%s/%s/metadata/%s", xbps_get_rootdir(),
XBPS_META_PATH, pkgname);
if (metadir == NULL)
return errno;
dirp = opendir(metadir);
if (dirp == NULL) {
free(metadir);
return errno;
}
while ((dp = readdir(dirp)) != NULL) {
if ((strcmp(dp->d_name, ".") == 0) ||
(strcmp(dp->d_name, "..") == 0))
continue;
path = xbps_xasprintf("%s/%s", metadir, dp->d_name);
if (path == NULL) {
(void)closedir(dirp);
free(metadir);
return -1;
}
if ((rv = unlink(path)) == -1) {
if (flags & XBPS_FLAG_VERBOSE)
printf("WARNING: can't remove %s (%s)\n",
pkgname, strerror(errno));
}
free(path);
}
(void)closedir(dirp);
rv = rmdir(metadir);
free(metadir);
return rv;
}

View File

@ -30,7 +30,16 @@
#include <xbps_api.h> #include <xbps_api.h>
int SYMEXPORT /**
* @file lib/register.c
* @brief Package (un)registration routines
* @defgroup pkg_register Package (un)registration functions
*
* Register and unregister packages into/from the installed
* packages database.
*/
int
xbps_register_pkg(prop_dictionary_t pkgrd, bool automatic) xbps_register_pkg(prop_dictionary_t pkgrd, bool automatic)
{ {
prop_dictionary_t dict, pkgd; prop_dictionary_t dict, pkgd;
@ -129,7 +138,7 @@ out:
return rv; return rv;
} }
int SYMEXPORT int
xbps_unregister_pkg(const char *pkgname) xbps_unregister_pkg(const char *pkgname)
{ {
char *plist; char *plist;

View File

@ -31,11 +31,22 @@
#include <xbps_api.h> #include <xbps_api.h>
/**
* @file lib/regpkgs_dictionary.c
* @brief Installed packages database init/fini routines
* @defgroup regpkgdb Installed packages database init/fini functions
*
* These functions will initialize the installed packages database,
* internalizing/externalizing the plist dictionary. Every initialization
* must be followed by a finalization if its data is not necessary, because
* the functions are reference counted.
*/
static prop_dictionary_t regpkgs_dict; static prop_dictionary_t regpkgs_dict;
static size_t regpkgs_refcount; static size_t regpkgs_refcount;
static bool regpkgs_initialized; static bool regpkgs_initialized;
prop_dictionary_t SYMEXPORT prop_dictionary_t
xbps_regpkgs_dictionary_init(void) xbps_regpkgs_dictionary_init(void)
{ {
char *plist; char *plist;
@ -60,7 +71,7 @@ xbps_regpkgs_dictionary_init(void)
return regpkgs_dict; return regpkgs_dict;
} }
void SYMEXPORT void
xbps_regpkgs_dictionary_release(void) xbps_regpkgs_dictionary_release(void)
{ {
if (--regpkgs_refcount > 0) if (--regpkgs_refcount > 0)

View File

@ -32,7 +32,38 @@
#include <xbps_api.h> #include <xbps_api.h>
int SYMEXPORT /**
* @file lib/remove.c
* @brief Package removal routines
* @defgroup pkg_remove Package removal functions
*
* These functions will remove a package or only a subset of its
* files. Package removal steps:
*
* 1) Its <b>pre-remove</b> target specified in the REMOVE script
* will be executed.
*
* 2) Its files, dirs and links will be removed. Modified files (not
* matching its sha256 hash) will always be preserved.
*
* 3) Its <b>post-remove</b> target specified in the REMOVE script
* will be executed.
*
* 4) Its requiredby objects will be removed from the installed packages
* database.
*
* 5) Its state will be changed to <b>config-files</b>.
*
* If a package is going to be updated and it's an essential package,
* only steps <b>1</b> and <b>4</b> will be executed.
*
* If a package is going to be updated and it's <b>NOT</b> an essential
* package, only steps <b>1</b>, <b>2</b> and <b>4</b> will be executed.
*
* If a package is going to be removed, all steps will be executed.
*/
int
xbps_remove_pkg_files(prop_dictionary_t dict, const char *key) xbps_remove_pkg_files(prop_dictionary_t dict, const char *key)
{ {
prop_array_t array; prop_array_t array;
@ -135,14 +166,14 @@ xbps_remove_pkg_files(prop_dictionary_t dict, const char *key)
return rv; return rv;
} }
int SYMEXPORT int
xbps_remove_pkg(const char *pkgname, const char *version, bool update) xbps_remove_pkg(const char *pkgname, const char *version, bool update)
{ {
prop_dictionary_t dict; prop_dictionary_t dict, pkgd;
const char *rootdir = xbps_get_rootdir(); const char *rootdir = xbps_get_rootdir();
char *path, *buf; char *path, *buf;
int rv = 0; int rv = 0;
bool prepostf = false; bool essential = false, prepostf = false;
assert(pkgname != NULL); assert(pkgname != NULL);
assert(version != NULL); assert(version != NULL);
@ -150,9 +181,12 @@ xbps_remove_pkg(const char *pkgname, const char *version, bool update)
/* /*
* Check if pkg is installed before anything else. * Check if pkg is installed before anything else.
*/ */
if (xbps_check_is_installed_pkgname(pkgname) == false) if ((pkgd = xbps_find_pkg_dict_installed(pkgname, false)) == NULL)
return ENOENT; return ENOENT;
prop_dictionary_get_bool(pkgd, "essential", &essential);
prop_object_release(pkgd);
if (strcmp(rootdir, "") == 0) if (strcmp(rootdir, "") == 0)
rootdir = "/"; rootdir = "/";
@ -183,6 +217,15 @@ xbps_remove_pkg(const char *pkgname, const char *version, bool update)
} }
} }
/*
* If updating an essential package, we just need to execute
* the current pre-remove action target, unregister its requiredby
* entries and continue. Its files will be overwritten later in
* the unpack phase.
*/
if (essential && update)
return xbps_requiredby_pkg_remove(pkgname);
/* /*
* Remove links, files and dirs. * Remove links, files and dirs.
*/ */

View File

@ -31,7 +31,7 @@
#include <xbps_api.h> #include <xbps_api.h>
int int HIDDEN
xbps_remove_obsoletes(prop_dictionary_t oldd, prop_dictionary_t newd) xbps_remove_obsoletes(prop_dictionary_t oldd, prop_dictionary_t newd)
{ {
prop_object_iterator_t iter, iter2; prop_object_iterator_t iter, iter2;

View File

@ -30,7 +30,13 @@
#include <xbps_api.h> #include <xbps_api.h>
int SYMEXPORT /**
* @file lib/repository.c
* @brief Repository (un)registration routines
* @defgroup repo_register Repository (un)registration functions
*/
int
xbps_repository_register(const char *uri) xbps_repository_register(const char *uri)
{ {
prop_dictionary_t dict; prop_dictionary_t dict;
@ -106,7 +112,7 @@ out:
return rv; return rv;
} }
int SYMEXPORT int
xbps_repository_unregister(const char *uri) xbps_repository_unregister(const char *uri)
{ {
prop_dictionary_t dict; prop_dictionary_t dict;

View File

@ -30,11 +30,6 @@
#include <xbps_api.h> #include <xbps_api.h>
static int add_missing_reqdep(prop_dictionary_t, const char *);
static int remove_missing_reqdep(prop_dictionary_t, const char *);
static int find_repo_deps(prop_dictionary_t, prop_dictionary_t,
const char *, prop_array_t);
static int static int
store_dependency(prop_dictionary_t master, prop_dictionary_t depd, store_dependency(prop_dictionary_t master, prop_dictionary_t depd,
const char *repoloc) const char *repoloc)
@ -135,14 +130,14 @@ add_missing_reqdep(prop_dictionary_t master, const char *reqpkg)
assert(prop_object_type(obj) == PROP_TYPE_STRING); assert(prop_object_type(obj) == PROP_TYPE_STRING);
curdep = prop_string_cstring_nocopy(obj); curdep = prop_string_cstring_nocopy(obj);
curver = xbps_get_pkgdep_version(curdep); curver = xbps_get_pkgpattern_version(curdep);
pkgver = xbps_get_pkgdep_version(reqpkg); pkgver = xbps_get_pkgpattern_version(reqpkg);
if (curver == NULL || pkgver == NULL) if (curver == NULL || pkgver == NULL)
goto out; goto out;
curpkgnamedep = xbps_get_pkgdep_name(curdep); curpkgnamedep = xbps_get_pkgpattern_name(curdep);
if (curpkgnamedep == NULL) if (curpkgnamedep == NULL)
goto out; goto out;
pkgnamedep = xbps_get_pkgdep_name(reqpkg); pkgnamedep = xbps_get_pkgpattern_name(reqpkg);
if (pkgnamedep == NULL) { if (pkgnamedep == NULL) {
free(curpkgnamedep); free(curpkgnamedep);
goto out; goto out;
@ -207,12 +202,12 @@ remove_missing_reqdep(prop_dictionary_t master, const char *reqpkg)
char *curpkgnamedep, *reqpkgname; char *curpkgnamedep, *reqpkgname;
curdep = prop_string_cstring_nocopy(obj); curdep = prop_string_cstring_nocopy(obj);
curpkgnamedep = xbps_get_pkgdep_name(curdep); curpkgnamedep = xbps_get_pkgpattern_name(curdep);
if (curpkgnamedep == NULL) { if (curpkgnamedep == NULL) {
rv = errno; rv = errno;
goto out; goto out;
} }
reqpkgname = xbps_get_pkgdep_name(reqpkg); reqpkgname = xbps_get_pkgpattern_name(reqpkg);
if (reqpkgname == NULL) { if (reqpkgname == NULL) {
free(curpkgnamedep); free(curpkgnamedep);
rv = errno; rv = errno;
@ -239,72 +234,6 @@ out:
return rv; return rv;
} }
int SYMEXPORT
xbps_repository_find_pkg_deps(prop_dictionary_t master, prop_dictionary_t pkg)
{
prop_array_t pkg_rdeps, missing_rdeps;
struct repository_pool *rpool;
const char *pkgname;
int rv = 0;
assert(master != NULL);
assert(pkg != NULL);
pkg_rdeps = prop_dictionary_get(pkg, "run_depends");
if (pkg_rdeps == NULL)
return 0;
if (!prop_dictionary_get_cstring_nocopy(pkg, "pkgname", &pkgname))
return errno;
if ((rv = xbps_repository_pool_init()) != 0)
return rv;
DPRINTF(("Checking rundeps for %s.\n", pkgname));
/*
* Iterate over the repository pool and find out if we have
* all available binary packages.
*/
SIMPLEQ_FOREACH(rpool, &repopool_queue, chain) {
/*
* This will find direct and indirect deps,
* if any of them is not there it will be added
* into the missing_deps array.
*/
if ((rv = find_repo_deps(master, rpool->rp_repod,
rpool->rp_uri, pkg_rdeps)) != 0) {
DPRINTF(("Error '%s' while checking rundeps!\n",
strerror(rv)));
goto out;
}
}
/*
* If there are no missing deps, there's nothing to do.
*/
missing_rdeps = prop_dictionary_get(master, "missing_deps");
if (prop_array_count(missing_rdeps) == 0)
goto out;
/*
* Iterate one more time, but this time with missing deps
* that were found in previous pass.
*/
DPRINTF(("Checking for missing deps in %s.\n", pkgname));
SIMPLEQ_FOREACH(rpool, &repopool_queue, chain) {
if ((rv = find_repo_deps(master, rpool->rp_repod,
rpool->rp_uri, missing_rdeps)) != 0) {
DPRINTF(("Error '%s' while checking for "
"missing rundeps!\n", strerror(rv)));
goto out;
}
}
out:
xbps_repository_pool_release();
return rv;
}
static int static int
find_repo_deps(prop_dictionary_t master, prop_dictionary_t repo, find_repo_deps(prop_dictionary_t master, prop_dictionary_t repo,
const char *repoloc, prop_array_t array) const char *repoloc, prop_array_t array)
@ -347,12 +276,12 @@ find_repo_deps(prop_dictionary_t master, prop_dictionary_t repo,
continue; continue;
} }
DPRINTF(("Dependency %s not installed.\n", reqpkg)); DPRINTF(("Dependency %s not installed.\n", reqpkg));
pkgname = xbps_get_pkgdep_name(reqpkg); pkgname = xbps_get_pkgpattern_name(reqpkg);
if (pkgname == NULL) { if (pkgname == NULL) {
rv = EINVAL; rv = EINVAL;
break; break;
} }
reqvers = xbps_get_pkgdep_version(reqpkg); reqvers = xbps_get_pkgpattern_version(reqpkg);
if (reqvers == NULL) { if (reqvers == NULL) {
free(pkgname); free(pkgname);
rv = EINVAL; rv = EINVAL;
@ -379,7 +308,8 @@ find_repo_deps(prop_dictionary_t master, prop_dictionary_t repo,
rv = errno; rv = errno;
break; break;
} }
if (xbps_pkgdep_match(pkg_queued, __UNCONST(reqpkg))) { if (xbps_pkgpattern_match(pkg_queued,
__UNCONST(reqpkg))) {
DPRINTF(("Dependency %s already queued.\n", DPRINTF(("Dependency %s already queued.\n",
pkgname)); pkgname));
free(pkgname); free(pkgname);
@ -429,7 +359,7 @@ find_repo_deps(prop_dictionary_t master, prop_dictionary_t repo,
rv = errno; rv = errno;
break; break;
} }
if (xbps_pkgdep_match(repo_pkgver, __UNCONST(reqpkg)) < 1) { if (xbps_pkgpattern_match(repo_pkgver, __UNCONST(reqpkg)) < 1) {
free(pkgname); free(pkgname);
continue; continue;
} }
@ -440,7 +370,7 @@ find_repo_deps(prop_dictionary_t master, prop_dictionary_t repo,
* an install. Packages that were unpacked previously * an install. Packages that were unpacked previously
* will be marked as pending to be configured. * will be marked as pending to be configured.
*/ */
tmpd = xbps_find_pkg_installed_from_plist(pkgname); tmpd = xbps_find_pkg_dict_installed(pkgname, false);
if (tmpd == NULL) { if (tmpd == NULL) {
if (errno && errno != ENOENT) { if (errno && errno != ENOENT) {
free(pkgname); free(pkgname);
@ -512,3 +442,69 @@ find_repo_deps(prop_dictionary_t master, prop_dictionary_t repo,
return rv; return rv;
} }
int HIDDEN
xbps_repository_find_pkg_deps(prop_dictionary_t master, prop_dictionary_t pkg)
{
prop_array_t pkg_rdeps, missing_rdeps;
struct repository_pool *rpool;
const char *pkgname;
int rv = 0;
assert(master != NULL);
assert(pkg != NULL);
pkg_rdeps = prop_dictionary_get(pkg, "run_depends");
if (pkg_rdeps == NULL)
return 0;
if (!prop_dictionary_get_cstring_nocopy(pkg, "pkgname", &pkgname))
return errno;
if ((rv = xbps_repository_pool_init()) != 0)
return rv;
DPRINTF(("Checking rundeps for %s.\n", pkgname));
/*
* Iterate over the repository pool and find out if we have
* all available binary packages.
*/
SIMPLEQ_FOREACH(rpool, &rp_queue, rp_entries) {
/*
* This will find direct and indirect deps,
* if any of them is not there it will be added
* into the missing_deps array.
*/
if ((rv = find_repo_deps(master, rpool->rp_repod,
rpool->rp_uri, pkg_rdeps)) != 0) {
DPRINTF(("Error '%s' while checking rundeps!\n",
strerror(rv)));
goto out;
}
}
/*
* If there are no missing deps, there's nothing to do.
*/
missing_rdeps = prop_dictionary_get(master, "missing_deps");
if (prop_array_count(missing_rdeps) == 0)
goto out;
/*
* Iterate one more time, but this time with missing deps
* that were found in previous pass.
*/
DPRINTF(("Checking for missing deps in %s.\n", pkgname));
SIMPLEQ_FOREACH(rpool, &rp_queue, rp_entries) {
if ((rv = find_repo_deps(master, rpool->rp_repod,
rpool->rp_uri, missing_rdeps)) != 0) {
DPRINTF(("Error '%s' while checking for "
"missing rundeps!\n", strerror(rv)));
goto out;
}
}
out:
xbps_repository_pool_release();
return rv;
}

View File

@ -31,11 +31,15 @@
#include <xbps_api.h> #include <xbps_api.h>
/**
* @file lib/repository_findpkg.c
* @brief Repository packages transaction handling routines
* @defgroup repo_pkgs Repository packages transaction handling functions
*/
static prop_dictionary_t trans_dict; static prop_dictionary_t trans_dict;
static bool trans_dict_initialized; static bool trans_dict_initialized;
static int set_pkg_state(prop_dictionary_t, const char *);
static int static int
create_transaction_dictionary(void) create_transaction_dictionary(void)
{ {
@ -84,16 +88,123 @@ fail:
return rv; return rv;
} }
prop_dictionary_t SYMEXPORT static int
compute_transaction_sizes(void)
{
prop_object_iterator_t iter;
prop_object_t obj;
uint64_t tsize = 0, dlsize = 0, instsize = 0;
int rv = 0;
const char *tract;
iter = xbps_get_array_iter_from_dict(trans_dict, "packages");
if (iter == NULL)
return -1;
while ((obj = prop_object_iterator_next(iter)) != NULL) {
if (!prop_dictionary_get_cstring_nocopy(obj,
"trans-action", &tract)) {
rv = -1;
goto out;
}
/*
* Skip pkgs that need to be configured.
*/
if (strcmp(tract, "configure") == 0)
continue;
if (!prop_dictionary_get_uint64(obj,
"filename-size", &tsize)) {
rv = -1;
goto out;
}
dlsize += tsize;
tsize = 0;
if (!prop_dictionary_get_uint64(obj,
"installed_size", &tsize)) {
rv = -1;
goto out;
}
instsize += tsize;
tsize = 0;
}
/*
* Add object in transaction dictionary with total installed
* size that it will take.
*/
if (!prop_dictionary_set_uint64(trans_dict,
"total-installed-size", instsize)) {
rv = -1;
goto out;
}
/*
* Add object in transaction dictionary with total download
* size that needs to be sucked in.
*/
if (!prop_dictionary_set_uint64(trans_dict,
"total-download-size", dlsize)) {
rv = -1;
goto out;
}
out:
prop_object_iterator_release(iter);
return rv;
}
static int
set_pkg_state(prop_dictionary_t pkgd, const char *pkgname)
{
pkg_state_t state = 0;
int rv = 0;
rv = xbps_set_pkg_state_dictionary(pkgd, XBPS_PKG_STATE_NOT_INSTALLED);
if (rv != 0)
return rv;
/*
* Overwrite package state in dictionary if it was unpacked
* previously.
*/
rv = xbps_get_pkg_state_installed(pkgname, &state);
if (rv == 0) {
if ((rv = xbps_set_pkg_state_dictionary(pkgd, state)) != 0)
return rv;
} else if (rv == ENOENT)
rv = 0;
return rv;
}
prop_dictionary_t
xbps_repository_get_transaction_dict(void) xbps_repository_get_transaction_dict(void)
{ {
if (trans_dict_initialized == false) int rv = 0;
if (trans_dict_initialized == false) {
errno = ENOENT;
return NULL;
}
/*
* Sort package list if necessary.
*/
if ((rv = xbps_sort_pkg_deps(trans_dict)) != 0) {
errno = rv;
return NULL;
}
/*
* Add total transaction installed/download sizes
* to the transaction dictionary.
*/
if (compute_transaction_sizes() != 0)
return NULL; return NULL;
return trans_dict; return trans_dict;
} }
int SYMEXPORT int
xbps_repository_update_allpkgs(void) xbps_repository_update_allpkgs(void)
{ {
prop_dictionary_t dict; prop_dictionary_t dict;
@ -110,9 +221,6 @@ xbps_repository_update_allpkgs(void)
if (dict == NULL) if (dict == NULL)
return ENOENT; return ENOENT;
/*
* Prepare simpleq with all registered repositories.
*/
if ((rv = xbps_repository_pool_init()) != 0) if ((rv = xbps_repository_pool_init()) != 0)
goto out; goto out;
@ -154,7 +262,7 @@ out:
return rv; return rv;
} }
int SYMEXPORT int
xbps_repository_update_pkg(const char *pkgname, prop_dictionary_t instpkg) xbps_repository_update_pkg(const char *pkgname, prop_dictionary_t instpkg)
{ {
prop_dictionary_t pkgrd = NULL; prop_dictionary_t pkgrd = NULL;
@ -173,7 +281,7 @@ xbps_repository_update_pkg(const char *pkgname, prop_dictionary_t instpkg)
if ((rv = xbps_repository_pool_init()) != 0) if ((rv = xbps_repository_pool_init()) != 0)
return rv; return rv;
SIMPLEQ_FOREACH(rpool, &repopool_queue, chain) { SIMPLEQ_FOREACH(rpool, &rp_queue, rp_entries) {
/* /*
* Get the package dictionary from current repository. * Get the package dictionary from current repository.
* If it's not there, pass to the next repository. * If it's not there, pass to the next repository.
@ -274,31 +382,8 @@ out:
return rv; return rv;
} }
static int int
set_pkg_state(prop_dictionary_t pkgd, const char *pkgname) xbps_repository_install_pkg(const char *pkg, bool bypattern)
{
pkg_state_t state = 0;
int rv = 0;
rv = xbps_set_pkg_state_dictionary(pkgd, XBPS_PKG_STATE_NOT_INSTALLED);
if (rv != 0)
return rv;
/*
* Overwrite package state in dictionary if it was unpacked
* previously.
*/
rv = xbps_get_pkg_state_installed(pkgname, &state);
if (rv == 0) {
if ((rv = xbps_set_pkg_state_dictionary(pkgd, state)) != 0)
return rv;
} else if (rv == ENOENT)
rv = 0;
return rv;
}
int SYMEXPORT
xbps_repository_install_pkg(const char *pkg, bool by_pkgmatch)
{ {
prop_dictionary_t origin_pkgrd = NULL, pkgrd = NULL; prop_dictionary_t origin_pkgrd = NULL, pkgrd = NULL;
prop_array_t unsorted; prop_array_t unsorted;
@ -311,13 +396,13 @@ xbps_repository_install_pkg(const char *pkg, bool by_pkgmatch)
if ((rv = xbps_repository_pool_init()) != 0) if ((rv = xbps_repository_pool_init()) != 0)
return rv; return rv;
SIMPLEQ_FOREACH(rpool, &repopool_queue, chain) { SIMPLEQ_FOREACH(rpool, &rp_queue, rp_entries) {
/* /*
* Get the package dictionary from current repository. * Get the package dictionary from current repository.
* If it's not there, pass to the next repository. * If it's not there, pass to the next repository.
*/ */
if (by_pkgmatch) if (bypattern)
pkgrd = xbps_find_pkg_in_dict_by_pkgmatch( pkgrd = xbps_find_pkg_in_dict_by_pattern(
rpool->rp_repod, "packages", pkg); rpool->rp_repod, "packages", pkg);
else else
pkgrd = xbps_find_pkg_in_dict_by_name( pkgrd = xbps_find_pkg_in_dict_by_name(
@ -346,8 +431,8 @@ xbps_repository_install_pkg(const char *pkg, bool by_pkgmatch)
* Check that this pkg hasn't been added previously into * Check that this pkg hasn't been added previously into
* the transaction. * the transaction.
*/ */
if (by_pkgmatch) { if (bypattern) {
if (xbps_find_pkg_in_dict_by_pkgmatch(trans_dict, if (xbps_find_pkg_in_dict_by_pattern(trans_dict,
"unsorted_deps", pkg)) "unsorted_deps", pkg))
goto out; goto out;
} else { } else {

View File

@ -34,6 +34,12 @@
#include <xbps_api.h> #include <xbps_api.h>
#include "fetch.h" #include "fetch.h"
/**
* @file lib/repository_plist.c
* @brief Repository plist file handling routines
* @defgroup repo_plist Repository plist file handling functions
*/
struct fetch_archive { struct fetch_archive {
struct url *url; struct url *url;
struct fetchIO *fetch; struct fetchIO *fetch;
@ -151,7 +157,7 @@ binpkg_in_cachedir(prop_dictionary_t d, const char *uri)
return NULL; return NULL;
} }
char SYMEXPORT * char *
xbps_repository_get_path_from_pkg_dict(prop_dictionary_t d, const char *uri) xbps_repository_get_path_from_pkg_dict(prop_dictionary_t d, const char *uri)
{ {
const char *arch, *filen; const char *arch, *filen;
@ -169,7 +175,7 @@ xbps_repository_get_path_from_pkg_dict(prop_dictionary_t d, const char *uri)
return xbps_xasprintf("%s/%s/%s", uri, arch, filen); return xbps_xasprintf("%s/%s/%s", uri, arch, filen);
} }
prop_dictionary_t SYMEXPORT prop_dictionary_t
xbps_repository_get_pkg_plist_dict_from_url(const char *url, const char *plistf) xbps_repository_get_pkg_plist_dict_from_url(const char *url, const char *plistf)
{ {
prop_dictionary_t plistd = NULL; prop_dictionary_t plistd = NULL;
@ -216,7 +222,7 @@ xbps_repository_get_pkg_plist_dict_from_url(const char *url, const char *plistf)
return plistd; return plistd;
} }
prop_dictionary_t SYMEXPORT prop_dictionary_t
xbps_repository_get_pkg_plist_dict(const char *pkgname, const char *plistf) xbps_repository_get_pkg_plist_dict(const char *pkgname, const char *plistf)
{ {
prop_dictionary_t plistd = NULL, pkgd; prop_dictionary_t plistd = NULL, pkgd;
@ -238,7 +244,7 @@ xbps_repository_get_pkg_plist_dict(const char *pkgname, const char *plistf)
* This will work locally and remotely, thanks to libarchive and * This will work locally and remotely, thanks to libarchive and
* libfetch! * libfetch!
*/ */
SIMPLEQ_FOREACH(rpool, &repopool_queue, chain) { SIMPLEQ_FOREACH(rpool, &rp_queue, rp_entries) {
pkgd = xbps_find_pkg_in_dict_by_name(rpool->rp_repod, pkgd = xbps_find_pkg_in_dict_by_name(rpool->rp_repod,
"packages", pkgname); "packages", pkgname);
if (pkgd == NULL) { if (pkgd == NULL) {

View File

@ -31,10 +31,16 @@
#include <xbps_api.h> #include <xbps_api.h>
/**
* @file lib/repository_pool.c
* @brief Repository pool init/fini routines
* @defgroup repopool Repository pool init/fini functions
*/
static size_t repolist_refcnt; static size_t repolist_refcnt;
static bool repolist_initialized; static bool repolist_initialized;
int SYMEXPORT int
xbps_repository_pool_init(void) xbps_repository_pool_init(void)
{ {
prop_dictionary_t dict = NULL; prop_dictionary_t dict = NULL;
@ -51,7 +57,7 @@ xbps_repository_pool_init(void)
return 0; return 0;
} }
SIMPLEQ_INIT(&repopool_queue); SIMPLEQ_INIT(&rp_queue);
plist = xbps_xasprintf("%s/%s/%s", xbps_get_rootdir(), plist = xbps_xasprintf("%s/%s/%s", xbps_get_rootdir(),
XBPS_META_PATH, XBPS_REPOLIST); XBPS_META_PATH, XBPS_REPOLIST);
@ -120,7 +126,7 @@ xbps_repository_pool_init(void)
goto out; goto out;
} }
free(plist); free(plist);
SIMPLEQ_INSERT_TAIL(&repopool_queue, rpool, chain); SIMPLEQ_INSERT_TAIL(&rp_queue, rpool, rp_entries);
} }
if (ntotal - nmissing == 0) if (ntotal - nmissing == 0)
@ -141,7 +147,7 @@ out:
} }
void SYMEXPORT void
xbps_repository_pool_release(void) xbps_repository_pool_release(void)
{ {
struct repository_pool *rpool; struct repository_pool *rpool;
@ -149,8 +155,8 @@ xbps_repository_pool_release(void)
if (--repolist_refcnt > 0) if (--repolist_refcnt > 0)
return; return;
while ((rpool = SIMPLEQ_FIRST(&repopool_queue)) != NULL) { while ((rpool = SIMPLEQ_FIRST(&rp_queue)) != NULL) {
SIMPLEQ_REMOVE(&repopool_queue, rpool, repository_pool, chain); SIMPLEQ_REMOVE(&rp_queue, rpool, repository_pool, rp_entries);
prop_object_release(rpool->rp_repod); prop_object_release(rpool->rp_repod);
free(rpool->rp_uri); free(rpool->rp_uri);
free(rpool); free(rpool);

View File

@ -33,7 +33,13 @@
#include <xbps_api.h> #include <xbps_api.h>
#include "fetch.h" #include "fetch.h"
char SYMEXPORT * /**
* @file lib/repository_sync_index.c
* @brief Repository package index synchronization routines
* @defgroup reposync Repository package index synchronization functions
*/
char *
xbps_get_remote_repo_string(const char *uri) xbps_get_remote_repo_string(const char *uri)
{ {
struct url *url; struct url *url;
@ -71,7 +77,7 @@ xbps_get_remote_repo_string(const char *uri)
* Returns -1 on error, 0 if transfer was not necessary (local/remote * Returns -1 on error, 0 if transfer was not necessary (local/remote
* size and/or mtime match) and 1 if downloaded successfully. * size and/or mtime match) and 1 if downloaded successfully.
*/ */
int SYMEXPORT int
xbps_repository_sync_pkg_index(const char *uri) xbps_repository_sync_pkg_index(const char *uri)
{ {
struct url *url = NULL; struct url *url = NULL;

View File

@ -121,7 +121,7 @@ remove_pkg_from_reqby(prop_object_t obj, void *arg, bool *loop_done)
return 0; return 0;
} }
int SYMEXPORT int HIDDEN
xbps_requiredby_pkg_remove(const char *pkgname) xbps_requiredby_pkg_remove(const char *pkgname)
{ {
prop_dictionary_t dict; prop_dictionary_t dict;
@ -151,7 +151,7 @@ xbps_requiredby_pkg_remove(const char *pkgname)
return rv; return rv;
} }
int SYMEXPORT int HIDDEN
xbps_requiredby_pkg_add(prop_array_t regar, prop_dictionary_t pkg) xbps_requiredby_pkg_add(prop_array_t regar, prop_dictionary_t pkg)
{ {
prop_array_t rdeps; prop_array_t rdeps;
@ -178,7 +178,7 @@ xbps_requiredby_pkg_add(prop_array_t regar, prop_dictionary_t pkg)
rv = errno; rv = errno;
goto out; goto out;
} }
rdepname = xbps_get_pkgdep_name(str); rdepname = xbps_get_pkgpattern_name(str);
if (rdepname == NULL) { if (rdepname == NULL) {
rv = EINVAL; rv = EINVAL;
goto out; goto out;

View File

@ -87,6 +87,11 @@
static void SHA256_Transform(SHA256_CTX *, const uint32_t*); static void SHA256_Transform(SHA256_CTX *, const uint32_t*);
static int SHA256_Final(uint8_t *, SHA256_CTX *); static int SHA256_Final(uint8_t *, SHA256_CTX *);
/*
* Constant used by SHA256/384/512_End() functions for converting the
* digest to a readable hexadecimal character string:
*/
static const char sha2_hex_digits[] = "0123456789abcdef";
/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
/* Hash constant words K for SHA-256: */ /* Hash constant words K for SHA-256: */
@ -122,7 +127,7 @@ static const uint32_t sha256_initial_hash_value[8] = {
}; };
/*** SHA-256: *********************************************************/ /*** SHA-256: *********************************************************/
int int HIDDEN
XBPS_SHA256_Init(SHA256_CTX *context) XBPS_SHA256_Init(SHA256_CTX *context)
{ {
if (context == NULL) if (context == NULL)
@ -297,7 +302,7 @@ SHA256_Transform(SHA256_CTX *context, const uint32_t *data)
#endif /* SHA2_UNROLL_TRANSFORM */ #endif /* SHA2_UNROLL_TRANSFORM */
int int HIDDEN
XBPS_SHA256_Update(SHA256_CTX *context, const uint8_t *data, size_t len) XBPS_SHA256_Update(SHA256_CTX *context, const uint8_t *data, size_t len)
{ {
unsigned int freespace, usedspace; unsigned int freespace, usedspace;
@ -434,13 +439,7 @@ SHA256_Final(uint8_t digest[], SHA256_CTX *context)
return SHA224_256_Final(digest, context, SHA256_DIGEST_LENGTH); return SHA224_256_Final(digest, context, SHA256_DIGEST_LENGTH);
} }
/* char HIDDEN *
* Constant used by SHA256/384/512_End() functions for converting the
* digest to a readable hexadecimal character string:
*/
static const char sha2_hex_digits[] = "0123456789abcdef";
char *
XBPS_SHA256_End(SHA256_CTX *ctx, uint8_t *buffer) XBPS_SHA256_End(SHA256_CTX *ctx, uint8_t *buffer)
{ {
uint8_t digest[SHA256_DIGEST_LENGTH], *d = digest; uint8_t digest[SHA256_DIGEST_LENGTH], *d = digest;

View File

@ -59,7 +59,7 @@ find_sorteddep_by_name(const char *pkgname)
return sdep; return sdep;
} }
int SYMEXPORT int HIDDEN
xbps_sort_pkg_deps(prop_dictionary_t chaindeps) xbps_sort_pkg_deps(prop_dictionary_t chaindeps)
{ {
prop_array_t sorted, unsorted, rundeps; prop_array_t sorted, unsorted, rundeps;
@ -149,7 +149,7 @@ again:
rv = EINVAL; rv = EINVAL;
goto out; goto out;
} }
pkgnamedep = xbps_get_pkgdep_name(str); pkgnamedep = xbps_get_pkgpattern_name(str);
if (pkgnamedep == NULL) { if (pkgnamedep == NULL) {
free(sdep); free(sdep);
rv = errno; rv = errno;

View File

@ -31,6 +31,12 @@
#include <xbps_api.h> #include <xbps_api.h>
/**
* @file lib/state.c
* @brief Package state handling routines
* @defgroup pkgstates Package state handling functions
*/
static int static int
set_new_state(prop_dictionary_t dict, pkg_state_t state) set_new_state(prop_dictionary_t dict, pkg_state_t state)
{ {
@ -96,14 +102,14 @@ get_state(prop_dictionary_t dict)
return state; return state;
} }
int SYMEXPORT int
xbps_get_pkg_state_installed(const char *pkgname, pkg_state_t *state) xbps_get_pkg_state_installed(const char *pkgname, pkg_state_t *state)
{ {
prop_dictionary_t pkgd; prop_dictionary_t pkgd;
assert(pkgname != NULL); assert(pkgname != NULL);
pkgd = xbps_find_pkg_installed_from_plist(pkgname); pkgd = xbps_find_pkg_dict_installed(pkgname, false);
if (pkgd == NULL) if (pkgd == NULL)
return errno; return errno;
@ -114,7 +120,7 @@ xbps_get_pkg_state_installed(const char *pkgname, pkg_state_t *state)
return 0; return 0;
} }
int SYMEXPORT int
xbps_get_pkg_state_dictionary(prop_dictionary_t dict, pkg_state_t *state) xbps_get_pkg_state_dictionary(prop_dictionary_t dict, pkg_state_t *state)
{ {
assert(dict != NULL); assert(dict != NULL);
@ -125,7 +131,7 @@ xbps_get_pkg_state_dictionary(prop_dictionary_t dict, pkg_state_t *state)
return 0; return 0;
} }
int SYMEXPORT int
xbps_set_pkg_state_dictionary(prop_dictionary_t dict, pkg_state_t state) xbps_set_pkg_state_dictionary(prop_dictionary_t dict, pkg_state_t state)
{ {
assert(dict != NULL); assert(dict != NULL);
@ -133,7 +139,7 @@ xbps_set_pkg_state_dictionary(prop_dictionary_t dict, pkg_state_t state)
return set_new_state(dict, state); return set_new_state(dict, state);
} }
int SYMEXPORT int
xbps_set_pkg_state_installed(const char *pkgname, pkg_state_t state) xbps_set_pkg_state_installed(const char *pkgname, pkg_state_t state)
{ {
prop_dictionary_t dict = NULL, pkgd; prop_dictionary_t dict = NULL, pkgd;

View File

@ -32,74 +32,11 @@
#include <xbps_api.h> #include <xbps_api.h>
static int unpack_archive_fini(struct archive *, prop_dictionary_t); /**
static void set_extract_flags(int *); * @file lib/unpack.c
* @brief Binary package file unpacking routines
int SYMEXPORT * @defgroup unpack Binary package file unpacking functions
xbps_unpack_binary_pkg(prop_dictionary_t pkg)
{
const char *pkgname, *repoloc;
struct archive *ar = NULL;
char *binfile = NULL;
int pkg_fd, rv = 0;
assert(pkg != NULL);
if (!prop_dictionary_get_cstring_nocopy(pkg, "pkgname", &pkgname))
return errno;
if (!prop_dictionary_get_cstring_nocopy(pkg, "repository", &repoloc))
return errno;
binfile = xbps_get_binpkg_local_path(pkg, repoloc);
if (binfile == NULL)
return EINVAL;
if ((pkg_fd = open(binfile, O_RDONLY)) == -1) {
rv = errno;
goto out;
}
ar = archive_read_new();
if (ar == NULL) {
rv = errno;
goto out;
}
/*
* Enable support for tar format and all compression methods.
*/ */
archive_read_support_compression_all(ar);
archive_read_support_format_tar(ar);
if ((rv = archive_read_open_fd(ar, pkg_fd,
ARCHIVE_READ_BLOCKSIZE)) != 0)
goto out;
if ((rv = unpack_archive_fini(ar, pkg)) == 0) {
/*
* If installation of package was successful, make sure
* its files are written in storage (if possible).
*/
if (fsync(pkg_fd) == -1) {
rv = errno;
goto out;
}
/*
* Set package state to unpacked.
*/
rv = xbps_set_pkg_state_installed(pkgname,
XBPS_PKG_STATE_UNPACKED);
}
out:
if (ar)
archive_read_finish(ar);
if (pkg_fd != -1)
(void)close(pkg_fd);
if (binfile)
free(binfile);
return rv;
}
static void static void
set_extract_flags(int *flags) set_extract_flags(int *flags)
@ -154,30 +91,6 @@ unpack_archive_fini(struct archive *ar, prop_dictionary_t pkg)
if (xbps_check_is_installed_pkgname(pkgname)) if (xbps_check_is_installed_pkgname(pkgname))
update = true; update = true;
/*
* If we are updating an essential package, we have to run the
* pre-remove stage by the current package, because later some
* files could be removed.
*/
if (update && essential) {
buf = xbps_xasprintf(".%s/metadata/%s/REMOVE",
XBPS_META_PATH, pkgname);
if (buf == NULL)
return errno;
if (access(buf, R_OK|X_OK) == 0) {
if ((rv = xbps_file_chdir_exec(rootdir, buf, "pre",
pkgname, version, "yes", NULL)) != 0) {
fprintf(stderr, "%s: prerm action target error"
"(%s) while updating!\n",
pkgname, strerror(errno));
free(buf);
return rv;
}
}
free(buf);
buf = NULL;
}
/* /*
* Process the archive files. * Process the archive files.
*/ */
@ -401,3 +314,69 @@ unpack_archive_fini(struct archive *ar, prop_dictionary_t pkg)
return rv; return rv;
} }
int
xbps_unpack_binary_pkg(prop_dictionary_t pkg)
{
const char *pkgname, *repoloc;
struct archive *ar = NULL;
char *binfile = NULL;
int pkg_fd, rv = 0;
assert(pkg != NULL);
if (!prop_dictionary_get_cstring_nocopy(pkg, "pkgname", &pkgname))
return errno;
if (!prop_dictionary_get_cstring_nocopy(pkg, "repository", &repoloc))
return errno;
binfile = xbps_get_binpkg_local_path(pkg, repoloc);
if (binfile == NULL)
return EINVAL;
if ((pkg_fd = open(binfile, O_RDONLY)) == -1) {
rv = errno;
goto out;
}
ar = archive_read_new();
if (ar == NULL) {
rv = errno;
goto out;
}
/*
* Enable support for tar format and all compression methods.
*/
archive_read_support_compression_all(ar);
archive_read_support_format_tar(ar);
if ((rv = archive_read_open_fd(ar, pkg_fd,
ARCHIVE_READ_BLOCKSIZE)) != 0)
goto out;
if ((rv = unpack_archive_fini(ar, pkg)) == 0) {
/*
* If installation of package was successful, make sure
* its files are written in storage (if possible).
*/
if (fsync(pkg_fd) == -1) {
rv = errno;
goto out;
}
/*
* Set package state to unpacked.
*/
rv = xbps_set_pkg_state_installed(pkgname,
XBPS_PKG_STATE_UNPACKED);
}
out:
if (ar)
archive_read_finish(ar);
if (pkg_fd != -1)
(void)close(pkg_fd);
if (binfile)
free(binfile);
return rv;
}

View File

@ -38,13 +38,17 @@
#include <xbps_api.h> #include <xbps_api.h>
#include "sha256.h" #include "sha256.h"
static bool question(bool, const char *, va_list); /**
* @file lib/util.c
* @brief Utility routines
* @defgroup util Utility functions
*/
static const char *rootdir; static const char *rootdir;
static const char *cachedir; static const char *cachedir;
static int flags; static int flags;
char SYMEXPORT * char *
xbps_get_file_hash(const char *file) xbps_get_file_hash(const char *file)
{ {
SHA256_CTX ctx; SHA256_CTX ctx;
@ -65,12 +69,12 @@ xbps_get_file_hash(const char *file)
return hash; return hash;
} }
int SYMEXPORT int
xbps_check_file_hash(const char *path, const char *sha256) xbps_check_file_hash(const char *file, const char *sha256)
{ {
char *res; char *res;
res = xbps_get_file_hash(path); res = xbps_get_file_hash(file);
if (res == NULL) if (res == NULL)
return errno; return errno;
@ -83,7 +87,7 @@ xbps_check_file_hash(const char *path, const char *sha256)
return 0; return 0;
} }
bool SYMEXPORT bool
xbps_check_is_repo_string_remote(const char *uri) xbps_check_is_repo_string_remote(const char *uri)
{ {
assert(uri != NULL); assert(uri != NULL);
@ -96,7 +100,20 @@ xbps_check_is_repo_string_remote(const char *uri)
return false; return false;
} }
int SYMEXPORT static const char *
xbps_get_pkgver_from_dict(prop_dictionary_t d)
{
const char *pkgver;
assert(d != NULL);
if (!prop_dictionary_get_cstring_nocopy(d, "pkgver", &pkgver))
return NULL;
return pkgver;
}
int
xbps_check_is_installed_pkg(const char *pkg) xbps_check_is_installed_pkg(const char *pkg)
{ {
prop_dictionary_t dict; prop_dictionary_t dict;
@ -107,11 +124,11 @@ xbps_check_is_installed_pkg(const char *pkg)
assert(pkg != NULL); assert(pkg != NULL);
pkgname = xbps_get_pkgdep_name(pkg); pkgname = xbps_get_pkgpattern_name(pkg);
if (pkgname == NULL) if (pkgname == NULL)
return -1; return -1;
dict = xbps_find_pkg_installed_from_plist(pkgname); dict = xbps_find_pkg_dict_installed(pkgname, false);
if (dict == NULL) { if (dict == NULL) {
free(pkgname); free(pkgname);
if (errno == ENOENT) { if (errno == ENOENT) {
@ -144,20 +161,20 @@ xbps_check_is_installed_pkg(const char *pkg)
return -1; return -1;
} }
rv = xbps_pkgdep_match(instpkgver, __UNCONST(pkg)); rv = xbps_pkgpattern_match(instpkgver, __UNCONST(pkg));
prop_object_release(dict); prop_object_release(dict);
return rv; return rv;
} }
bool SYMEXPORT bool
xbps_check_is_installed_pkgname(const char *pkgname) xbps_check_is_installed_pkgname(const char *pkgname)
{ {
prop_dictionary_t pkgd; prop_dictionary_t pkgd;
assert(pkgname != NULL); assert(pkgname != NULL);
pkgd = xbps_find_pkg_installed_from_plist(pkgname); pkgd = xbps_find_pkg_dict_installed(pkgname, false);
if (pkgd) { if (pkgd) {
prop_object_release(pkgd); prop_object_release(pkgd);
return true; return true;
@ -166,7 +183,7 @@ xbps_check_is_installed_pkgname(const char *pkgname)
return false; return false;
} }
const char SYMEXPORT * const char *
xbps_get_pkg_version(const char *pkg) xbps_get_pkg_version(const char *pkg)
{ {
const char *tmp; const char *tmp;
@ -181,7 +198,7 @@ xbps_get_pkg_version(const char *pkg)
return tmp + 1; /* skip first '-' */ return tmp + 1; /* skip first '-' */
} }
const char SYMEXPORT * const char *
xbps_get_pkg_revision(const char *pkg) xbps_get_pkg_revision(const char *pkg)
{ {
const char *tmp; const char *tmp;
@ -196,7 +213,7 @@ xbps_get_pkg_revision(const char *pkg)
return tmp + 1; /* skip first '_' */ return tmp + 1; /* skip first '_' */
} }
char SYMEXPORT * char *
xbps_get_pkg_name(const char *pkg) xbps_get_pkg_name(const char *pkg)
{ {
const char *tmp; const char *tmp;
@ -219,8 +236,8 @@ xbps_get_pkg_name(const char *pkg)
return pkgname; return pkgname;
} }
char SYMEXPORT * char *
xbps_get_pkgdep_name(const char *pkg) xbps_get_pkgpattern_name(const char *pkg)
{ {
char *res, *pkgname; char *res, *pkgname;
size_t len; size_t len;
@ -242,8 +259,8 @@ xbps_get_pkgdep_name(const char *pkg)
return pkgname; return pkgname;
} }
const char SYMEXPORT * const char *
xbps_get_pkgdep_version(const char *pkg) xbps_get_pkgpattern_version(const char *pkg)
{ {
char *res; char *res;
@ -256,19 +273,6 @@ xbps_get_pkgdep_version(const char *pkg)
return res; return res;
} }
const char SYMEXPORT *
xbps_get_pkgver_from_dict(prop_dictionary_t d)
{
const char *pkgver;
assert(d != NULL);
if (!prop_dictionary_get_cstring_nocopy(d, "pkgver", &pkgver))
return NULL;
return pkgver;
}
static char * static char *
get_pkg_index_remote_plist(const char *uri) get_pkg_index_remote_plist(const char *uri)
{ {
@ -288,7 +292,7 @@ get_pkg_index_remote_plist(const char *uri)
return repodir; return repodir;
} }
char SYMEXPORT * char *
xbps_get_pkg_index_plist(const char *uri) xbps_get_pkg_index_plist(const char *uri)
{ {
struct utsname un; struct utsname un;
@ -304,14 +308,14 @@ xbps_get_pkg_index_plist(const char *uri)
return xbps_xasprintf("%s/%s/%s", uri, un.machine, XBPS_PKGINDEX); return xbps_xasprintf("%s/%s/%s", uri, un.machine, XBPS_PKGINDEX);
} }
char SYMEXPORT * char *
xbps_get_binpkg_local_path(prop_dictionary_t pkg, const char *repoloc) xbps_get_binpkg_local_path(prop_dictionary_t pkgd, const char *repoloc)
{ {
const char *filen, *arch, *cdir; const char *filen, *arch, *cdir;
if (!prop_dictionary_get_cstring_nocopy(pkg, "filename", &filen)) if (!prop_dictionary_get_cstring_nocopy(pkgd, "filename", &filen))
return NULL; return NULL;
if (!prop_dictionary_get_cstring_nocopy(pkg, "architecture", &arch)) if (!prop_dictionary_get_cstring_nocopy(pkgd, "architecture", &arch))
return NULL; return NULL;
cdir = xbps_get_cachedir(); cdir = xbps_get_cachedir();
if (cdir == NULL) if (cdir == NULL)
@ -325,7 +329,7 @@ xbps_get_binpkg_local_path(prop_dictionary_t pkg, const char *repoloc)
return xbps_xasprintf("%s/%s", cdir, filen); return xbps_xasprintf("%s/%s", cdir, filen);
} }
bool SYMEXPORT bool
xbps_pkg_has_rundeps(prop_dictionary_t pkg) xbps_pkg_has_rundeps(prop_dictionary_t pkg)
{ {
prop_array_t array; prop_array_t array;
@ -338,14 +342,14 @@ xbps_pkg_has_rundeps(prop_dictionary_t pkg)
return false; return false;
} }
void SYMEXPORT void
xbps_set_rootdir(const char *dir) xbps_set_rootdir(const char *dir)
{ {
assert(dir != NULL); assert(dir != NULL);
rootdir = dir; rootdir = dir;
} }
const char SYMEXPORT * const char *
xbps_get_rootdir(void) xbps_get_rootdir(void)
{ {
if (rootdir == NULL) if (rootdir == NULL)
@ -354,7 +358,7 @@ xbps_get_rootdir(void)
return rootdir; return rootdir;
} }
void SYMEXPORT void
xbps_set_cachedir(const char *dir) xbps_set_cachedir(const char *dir)
{ {
static char res[PATH_MAX]; static char res[PATH_MAX];
@ -371,7 +375,7 @@ xbps_set_cachedir(const char *dir)
cachedir = res; cachedir = res;
} }
const char SYMEXPORT * const char *
xbps_get_cachedir(void) xbps_get_cachedir(void)
{ {
static char res[PATH_MAX]; static char res[PATH_MAX];
@ -388,19 +392,19 @@ xbps_get_cachedir(void)
return cachedir; return cachedir;
} }
void SYMEXPORT void
xbps_set_flags(int lflags) xbps_set_flags(int lflags)
{ {
flags = lflags; flags = lflags;
} }
int SYMEXPORT int
xbps_get_flags(void) xbps_get_flags(void)
{ {
return flags; return flags;
} }
char SYMEXPORT * char *
xbps_xasprintf(const char *fmt, ...) xbps_xasprintf(const char *fmt, ...)
{ {
va_list ap; va_list ap;
@ -414,32 +418,6 @@ xbps_xasprintf(const char *fmt, ...)
return buf; return buf;
} }
bool SYMEXPORT
xbps_yesno(const char *fmt, ...)
{
va_list ap;
bool res;
va_start(ap, fmt);
res = question(1, fmt, ap);
va_end(ap);
return res;
}
bool SYMEXPORT
xbps_noyes(const char *fmt, ...)
{
va_list ap;
bool res;
va_start(ap, fmt);
res = question(0, fmt, ap);
va_end(ap);
return res;
}
static char * static char *
strtrim(char *str) strtrim(char *str)
{ {
@ -489,3 +467,29 @@ question(bool preset, const char *fmt, va_list ap)
} }
return false; return false;
} }
bool
xbps_yesno(const char *fmt, ...)
{
va_list ap;
bool res;
va_start(ap, fmt);
res = question(1, fmt, ap);
va_end(ap);
return res;
}
bool
xbps_noyes(const char *fmt, ...)
{
va_list ap;
bool res;
va_start(ap, fmt);
res = question(0, fmt, ap);
va_end(ap);
return res;
}

View File

@ -22,7 +22,7 @@ WARNFLAGS = -pedantic -std=c99 -Wall -Wextra -Werror -Wshadow -Wformat=2
WARNFLAGS += -Wmissing-declarations -Wcomment -Wunused-macros -Wendif-labels WARNFLAGS += -Wmissing-declarations -Wcomment -Wunused-macros -Wendif-labels
WARNFLAGS += -Wcast-qual -Wcast-align -Wstack-protector WARNFLAGS += -Wcast-qual -Wcast-align -Wstack-protector
CFLAGS = $(DEBUG_FLAGS) $(WARNFLAGS) -fPIC -DPIC -fstack-protector-all CFLAGS = $(DEBUG_FLAGS) $(WARNFLAGS) -fPIC -DPIC -fstack-protector-all
SHAREDLIB_CFLAGS = -fvisibility=hidden SHAREDLIB_CFLAGS = -fvisibility=default
# Grr, hate the static libs! # Grr, hate the static libs!
STATIC_LIBS = -lprop -lpthread -larchive -lssl -lcrypto -ldl -lacl STATIC_LIBS = -lprop -lpthread -larchive -lssl -lcrypto -ldl -lacl