diff --git a/bin/xbps-repo/Makefile b/bin/xbps-repo/Makefile index 0ccfbf35..de93b3dd 100644 --- a/bin/xbps-repo/Makefile +++ b/bin/xbps-repo/Makefile @@ -2,7 +2,7 @@ TOPDIR = ../.. include $(TOPDIR)/vars.mk BIN = xbps-repo -OBJS = main.o util.o index.o +OBJS = main.o util.o index.o repository.o MAN = $(BIN).8 include $(TOPDIR)/prog.mk diff --git a/bin/xbps-repo/defs.h b/bin/xbps-repo/defs.h index 062674c0..70e61480 100644 --- a/bin/xbps-repo/defs.h +++ b/bin/xbps-repo/defs.h @@ -28,11 +28,20 @@ /* From index.c */ int xbps_repo_genindex(const char *); +/* From repository.c */ +int pkgindex_verify(const char *, const char *, bool); +bool sanitize_url(char *, const char *); +int register_repository(const char *); +int unregister_repository(const char *); +int show_pkg_info_from_repolist(const char *); +int show_pkg_deps_from_repolist(const char *); +int repository_sync(void); /* From util.c */ int show_pkg_files(prop_dictionary_t); -void show_pkg_info(prop_dictionary_t); -int show_pkg_namedesc(prop_object_t, void *, bool *); -int list_strings_in_array(prop_object_t, void *, bool *); -int list_strings_sep_in_array(prop_object_t, void *, bool *); +void show_pkg_info(prop_dictionary_t); +void show_pkg_info_only_repo(prop_dictionary_t); +int show_pkg_namedesc(prop_object_t, void *, bool *); +int list_strings_in_array(prop_object_t, void *, bool *); +int list_strings_sep_in_array(prop_object_t, void *, bool *); #endif /* !_XBPS_REPO_DEFS_H_ */ diff --git a/bin/xbps-repo/index.c b/bin/xbps-repo/index.c index 6c60cff4..d9413178 100644 --- a/bin/xbps-repo/index.c +++ b/bin/xbps-repo/index.c @@ -85,12 +85,10 @@ xbps_repo_addpkg_index(prop_dictionary_t idxdict, const char *filedir, { prop_dictionary_t newpkgd, curpkgd; prop_array_t pkgar; - struct archive *ar = NULL; - struct archive_entry *entry; struct stat st; const char *pkgname, *version, *regver, *oldfilen; char *sha256, *filen, *tmpfilen, *tmpstr, *oldfilepath; - int i = 0, rv = 0; + int rv = 0; if (idxdict == NULL || file == NULL) return EINVAL; @@ -108,187 +106,148 @@ xbps_repo_addpkg_index(prop_dictionary_t idxdict, const char *filedir, goto out; } - ar = archive_read_new(); - if (ar == NULL) { + newpkgd = xbps_get_pkg_plist_dict_from_url(file, XBPS_PKGPROPS); + if (newpkgd == NULL) { + printf("%s: can't read %s metadata file, skipping!\n", + file, XBPS_PKGPROPS); + goto out; + } + if (!prop_dictionary_get_cstring_nocopy(newpkgd, "pkgname", &pkgname)) { + prop_object_release(newpkgd); 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 (!prop_dictionary_get_cstring_nocopy(newpkgd, "version", &version)) { + prop_object_release(newpkgd); + rv = errno; + goto out; + } + /* + * Check if this package exists already in the index, but first + * checking the version. If current package version is greater + * than current registered package, update the index; otherwise + * pass to the next one. + */ + curpkgd = xbps_find_pkg_in_dict(idxdict, "packages", pkgname); + if (curpkgd) { + if (!prop_dictionary_get_cstring_nocopy(curpkgd, + "version", ®ver)) { + prop_object_release(newpkgd); + rv = errno; + goto out; + } + if (xbps_cmpver(version, regver) <= 0) { + printf("W: skipping %s. %s-%s already " + "registered.\n", filen, pkgname, regver); + prop_object_release(newpkgd); + rv = EEXIST; + goto out; + } + /* + * Current binpkg is newer than the one registered + * in package index, remove outdated binpkg file + * and its dictionary from the pkg index. + */ + if (!prop_dictionary_get_cstring_nocopy(curpkgd, + "filename", &oldfilen)) { + prop_object_release(newpkgd); + rv = errno; + goto out; + } + oldfilepath = xbps_xasprintf("%s/%s", filedir, oldfilen); + if (oldfilepath == NULL) { + prop_object_release(newpkgd); + rv = errno; + goto out; + } + if (remove(oldfilepath) == -1) { + printf("E: Couldn't remove old package file " + "'%s'!\n", oldfilen); + free(oldfilepath); + prop_object_release(newpkgd); + rv = errno; + goto out; + } + free(oldfilepath); + tmpstr = strdup(oldfilen); + if (tmpstr == NULL) { + prop_object_release(newpkgd); + rv = errno; + goto out; + } + if ((rv = xbps_remove_pkg_from_dict(idxdict, + "packages", pkgname)) != 0) { + prop_object_release(newpkgd); + free(tmpstr); + goto out; + } + printf("W: removed outdated binpkg file for '%s'.\n", tmpstr); + free(tmpstr); + } - if ((rv = archive_read_open_filename(ar, file, - ARCHIVE_READ_BLOCKSIZE)) == -1) { + /* + * We have the dictionary now, add the required + * objects for the index. + */ + if (!prop_dictionary_set_cstring(newpkgd, "filename", filen)) { + prop_object_release(newpkgd); + rv = errno; + goto out; + } + sha256 = xbps_get_file_hash(file); + if (sha256 == NULL) { + prop_object_release(newpkgd); + rv = errno; + goto out; + } + if (!prop_dictionary_set_cstring(newpkgd, "filename-sha256", sha256)) { + prop_object_release(newpkgd); + free(sha256); + rv = errno; + goto out; + } + free(sha256); + if (stat(file, &st) == -1) { + prop_object_release(newpkgd); + rv = errno; + goto out; + } + if (!prop_dictionary_set_uint64(newpkgd, "filename-size", + (uint64_t)st.st_size)) { + prop_object_release(newpkgd); + rv = errno; + goto out; + } + /* Get package array in repo index file */ + pkgar = prop_dictionary_get(idxdict, "packages"); + if (pkgar == NULL) { + prop_object_release(newpkgd); rv = errno; goto out; } /* - * Open the binary package and read the props.plist - * into a buffer. + * Remote some unneeded and large objects. */ - while (archive_read_next_header(ar, &entry) == ARCHIVE_OK) { - if (i >= 5) { - /* - * Unlikely that archive contains XBPS_PKGPROPS, - * discard it completely. - */ - archive_read_data_skip(ar); - printf("W: archive %s does not contain required " - "props.plist file!\n", file); - break; - } - if (strstr(archive_entry_pathname(entry), XBPS_PKGPROPS) == 0) { - archive_read_data_skip(ar); - i++; - continue; - } - newpkgd = xbps_read_dict_from_archive_entry(ar, entry); - if (newpkgd == NULL) { - printf("%s: can't read %s metadata file, skipping!\n", - file, XBPS_PKGPROPS); - break; - } - if (!prop_dictionary_get_cstring_nocopy(newpkgd, "pkgname", - &pkgname)) { - prop_object_release(newpkgd); - rv = errno; - break; - } - if (!prop_dictionary_get_cstring_nocopy(newpkgd, "version", - &version)) { - prop_object_release(newpkgd); - rv = errno; - break; - } - /* - * Check if this package exists already in the index, but first - * checking the version. If current package version is greater - * than current registered package, update the index; otherwise - * pass to the next one. - */ - curpkgd = xbps_find_pkg_in_dict(idxdict, "packages", pkgname); - if (curpkgd) { - if (!prop_dictionary_get_cstring_nocopy(curpkgd, - "version", ®ver)) { - prop_object_release(newpkgd); - rv = errno; - break; - } - if (xbps_cmpver(version, regver) <= 0) { - printf("W: skipping %s. %s-%s already " - "registered.\n", filen, pkgname, regver); - prop_object_release(newpkgd); - archive_read_data_skip(ar); - rv = EEXIST; - break; - } - /* - * Current binpkg is newer than the one registered - * in package index, remove outdated binpkg file - * and its dictionary from the pkg index. - */ - if (!prop_dictionary_get_cstring_nocopy(curpkgd, - "filename", &oldfilen)) { - prop_object_release(newpkgd); - rv = errno; - break; - } - oldfilepath = xbps_xasprintf("%s/%s", filedir, - oldfilen); - if (oldfilepath == NULL) { - prop_object_release(newpkgd); - rv = errno; - break; - } - if (remove(oldfilepath) == -1) { - printf("E: Couldn't remove old package file " - "'%s'!\n", oldfilen); - free(oldfilepath); - prop_object_release(newpkgd); - rv = errno; - break; - } - free(oldfilepath); - tmpstr = strdup(oldfilen); - if (tmpstr == NULL) { - prop_object_release(newpkgd); - rv = errno; - break; - } - if ((rv = xbps_remove_pkg_from_dict(idxdict, - "packages", pkgname)) != 0) { - prop_object_release(newpkgd); - free(tmpstr); - break; - } - printf("W: removed outdated binpkg file " - "for '%s'.\n", tmpstr); - free(tmpstr); - } + prop_dictionary_remove(newpkgd, "long_desc"); + prop_dictionary_remove(newpkgd, "maintainer"); - /* - * We have the dictionary now, add the required - * objects for the index. - */ - if (!prop_dictionary_set_cstring(newpkgd, "filename", filen)) { - prop_object_release(newpkgd); - rv = errno; - break; - } - sha256 = xbps_get_file_hash(file); - if (sha256 == NULL) { - prop_object_release(newpkgd); - rv = errno; - break; - } - if (!prop_dictionary_set_cstring(newpkgd, - "filename-sha256", sha256)) { - prop_object_release(newpkgd); - free(sha256); - rv = errno; - break; - } - free(sha256); - if (stat(file, &st) == -1) { - prop_object_release(newpkgd); - rv = errno; - break; - } - if (!prop_dictionary_set_uint64(newpkgd, "filename-size", - (uint64_t)st.st_size)) { - prop_object_release(newpkgd); - rv = errno; - break; - } - /* Get package array in repo index file */ - pkgar = prop_dictionary_get(idxdict, "packages"); - if (pkgar == NULL) { - prop_object_release(newpkgd); - rv = errno; - break; - } - /* - * Add dictionary into the index and update package count. - */ - if (!xbps_add_obj_to_array(pkgar, newpkgd)) { - prop_object_release(newpkgd); - rv = EINVAL; - break; - } - printf("Registered %s-%s (%s) in package index.\n", - pkgname, version, filen); - - if (!prop_dictionary_set_uint64(idxdict, "total-pkgs", - prop_array_count(pkgar))) - rv = errno; - - break; + /* + * Add dictionary into the index and update package count. + */ + if (!xbps_add_obj_to_array(pkgar, newpkgd)) { + prop_object_release(newpkgd); + rv = EINVAL; + goto out; } + printf("Registered %s-%s (%s) in package index.\n", + pkgname, version, filen); + + if (!prop_dictionary_set_uint64(idxdict, "total-pkgs", + prop_array_count(pkgar))) + rv = errno; out: - if (ar) - archive_read_finish(ar); if (tmpfilen) free(tmpfilen); diff --git a/bin/xbps-repo/main.c b/bin/xbps-repo/main.c index 85fb3623..a37ebd0d 100644 --- a/bin/xbps-repo/main.c +++ b/bin/xbps-repo/main.c @@ -34,8 +34,6 @@ #include #include "defs.h" -static bool sanitize_localpath(char *, const char *); -static int pkgindex_verify(const char *, const char *, bool); static void usage(void); static void @@ -68,153 +66,12 @@ usage(void) exit(EXIT_FAILURE); } -static int -pkgindex_verify(const char *plist, const char *uri, bool only_sync) -{ - prop_dictionary_t d; - const char *pkgidx_version; - uint64_t total_pkgs; - int rv = 0; - - assert(plist != NULL); - - d = prop_dictionary_internalize_from_file(plist); - if (d == NULL) { - printf("E: repository %s does not contain any " - "xbps pkgindex file.\n", uri); - return errno; - } - - if (!prop_dictionary_get_cstring_nocopy(d, - "pkgindex-version", &pkgidx_version)) { - printf("E: missing 'pkgindex-version' object!\n"); - rv = errno; - goto out; - } - - if (!prop_dictionary_get_uint64(d, "total-pkgs", &total_pkgs)) { - printf("E: missing 'total-pkgs' object!\n"); - rv = errno; - goto out; - } - - /* Reject empty repositories, how could this happen? :-) */ - if (total_pkgs == 0) { - printf("E: empty package list!\n"); - rv = EINVAL; - goto out; - } - - printf("%s package index at %s (v%s) with %ju packages.\n", - only_sync ? "Updated" : "Added", uri, pkgidx_version, total_pkgs); - -out: - prop_object_release(d); - if (rv != 0) { - printf("W: removing incorrect pkg index file: '%s' ...\n", - plist); - rv = remove(plist); - } - return rv; -} - -static bool -sanitize_localpath(char *buf, const char *path) -{ - char *dirnp, *basenp, *dir, *base, *tmp; - bool rv = false; - - dir = strdup(path); - if (dir == NULL) - return false; - - base = strdup(path); - if (base == NULL) { - free(dir); - return false; - } - - dirnp = dirname(dir); - if (strcmp(dirnp, ".") == 0) - goto out; - - basenp = basename(base); - if (strcmp(basenp, base) == 0) - goto out; - - tmp = strncpy(buf, dirnp, PATH_MAX - 1); - if (sizeof(*tmp) >= PATH_MAX) - goto out; - - buf[strlen(buf) + 1] = '\0'; - if (strcmp(dirnp, "/")) - strncat(buf, "/", 1); - strncat(buf, basenp, PATH_MAX - strlen(buf) - 1); - rv = true; - -out: - free(dir); - free(base); - - return rv; -} - -static int -add_repository(const char *uri) -{ - char *plist, idxstr[PATH_MAX]; - int rv = 0; - - if (xbps_check_is_repo_string_remote(uri)) { - if (!sanitize_localpath(idxstr, uri)) - return errno; - - printf("Fetching remote package index at %s...\n", uri); - rv = xbps_sync_repository_pkg_index(idxstr); - if (rv == -1) { - printf("Error: could not fetch pkg index file: %s.\n", - xbps_fetch_error_string()); - return rv; - } else if (rv == 0) { - printf("Package index file is already " - "up to date.\n"); - return 0; - } - - plist = xbps_get_pkg_index_plist(idxstr); - } else { - if (!sanitize_localpath(idxstr, uri)) - return errno; - - plist = xbps_get_pkg_index_plist(idxstr); - } - - if (plist == NULL) - return errno; - - if ((rv = pkgindex_verify(plist, idxstr, false)) != 0) - goto out; - - if ((rv = xbps_register_repository(idxstr)) != 0) { - printf("ERROR: couldn't register repository (%s)\n", - strerror(rv)); - goto out; - } - -out: - if (plist != NULL) - free(plist); - - return rv; -} - int main(int argc, char **argv) { prop_dictionary_t pkgd; struct repository_data *rdata; - const char *pkgver; - char dpkgidx[PATH_MAX], *plist, *root; + char *root; int c, rv = 0; while ((c = getopt(argc, argv, "Vr:")) != -1) { @@ -252,7 +109,7 @@ main(int argc, char **argv) if (argc != 2) usage(); - rv = add_repository(argv[1]); + rv = register_repository(argv[1]); } else if (strcasecmp(argv[0], "list") == 0) { /* Lists all repositories registered in pool. */ @@ -268,19 +125,7 @@ main(int argc, char **argv) if (argc != 2) usage(); - if (!sanitize_localpath(dpkgidx, argv[1])) { - rv = EINVAL; - goto out; - } - - if ((rv = xbps_unregister_repository(dpkgidx)) != 0) { - if (rv == ENOENT) - printf("Repository '%s' not actually " - "registered.\n", dpkgidx); - else - printf("ERROR: couldn't unregister " - "repository (%s)\n", strerror(rv)); - } + rv = unregister_repository(argv[1]); } else if (strcasecmp(argv[0], "search") == 0) { /* @@ -301,17 +146,7 @@ main(int argc, char **argv) if (argc != 2) usage(); - SIMPLEQ_FOREACH(rdata, &repodata_queue, chain) { - pkgd = xbps_find_pkg_in_dict(rdata->rd_repod, - "packages", argv[1]); - if (pkgd == NULL) { - errno = ENOENT; - continue; - } - printf("Repository: %s\n", rdata->rd_uri); - show_pkg_info(pkgd); - break; - } + rv = show_pkg_info_from_repolist(argv[1]); if (rv == 0 && errno == ENOENT) { printf("Unable to locate package '%s' from " "repository pool.\n", argv[1]); @@ -324,23 +159,7 @@ main(int argc, char **argv) if (argc != 2) usage(); - SIMPLEQ_FOREACH(rdata, &repodata_queue, chain) { - pkgd = xbps_find_pkg_in_dict(rdata->rd_repod, - "packages", argv[1]); - if (pkgd == NULL) { - errno = ENOENT; - continue; - } - if (!prop_dictionary_get_cstring_nocopy(pkgd, - "version", &pkgver)) { - rv = errno; - goto out; - } - printf("Repository %s [pkgver: %s]\n", - rdata->rd_uri, pkgver); - (void)xbps_callback_array_iter_in_dict(pkgd, - "run_depends", list_strings_sep_in_array, NULL); - } + rv = show_pkg_deps_from_repolist(argv[1]); if (rv == 0 && errno == ENOENT) { printf("Unable to locate package '%s' from " "repository pool.\n", argv[1]); @@ -354,9 +173,9 @@ main(int argc, char **argv) usage(); pkgd = xbps_get_pkg_plist_dict_from_repo(argv[1], - "./files.plist"); + XBPS_PKGFILES); if (pkgd == NULL) { - printf("E: couldn't read files.plist: %s.\n", + printf("E: couldn't read %s: %s.\n", XBPS_PKGFILES, strerror(errno)); rv = errno; goto out; @@ -376,32 +195,7 @@ main(int argc, char **argv) if (argc != 1) usage(); - /* - * Iterate over repository pool. - */ - SIMPLEQ_FOREACH(rdata, &repodata_queue, chain) { - const char *uri = rdata->rd_uri; - if (xbps_check_is_repo_string_remote(uri)) { - printf("Syncing package index from: %s\n", uri); - rv = xbps_sync_repository_pkg_index(uri); - if (rv == -1) { - printf("Failed! returned: %s\n", - xbps_fetch_error_string()); - goto out; - } else if (rv == 0) { - printf("Package index file is already " - "up to date.\n"); - continue; - } - plist = xbps_get_pkg_index_plist(uri); - if (plist == NULL) { - rv = EINVAL; - goto out; - } - (void)pkgindex_verify(plist, uri, true); - free(plist); - } - } + rv = repository_sync(); } else { usage(); diff --git a/bin/xbps-repo/repository.c b/bin/xbps-repo/repository.c new file mode 100644 index 00000000..a516acb0 --- /dev/null +++ b/bin/xbps-repo/repository.c @@ -0,0 +1,292 @@ +/*- + * Copyright (c) 2008-2009 Juan Romero Pardines. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "defs.h" + +int +pkgindex_verify(const char *plist, const char *uri, bool only_sync) +{ + prop_dictionary_t d; + const char *pkgidx_version; + uint64_t total_pkgs; + int rv = 0; + + assert(plist != NULL); + + d = prop_dictionary_internalize_from_file(plist); + if (d == NULL) { + printf("E: repository %s does not contain any " + "xbps pkgindex file.\n", uri); + return errno; + } + + if (!prop_dictionary_get_cstring_nocopy(d, + "pkgindex-version", &pkgidx_version)) { + printf("E: missing 'pkgindex-version' object!\n"); + rv = errno; + goto out; + } + + if (!prop_dictionary_get_uint64(d, "total-pkgs", &total_pkgs)) { + printf("E: missing 'total-pkgs' object!\n"); + rv = errno; + goto out; + } + + /* Reject empty repositories, how could this happen? :-) */ + if (total_pkgs == 0) { + printf("E: empty package list!\n"); + rv = EINVAL; + goto out; + } + + printf("%s package index at %s (v%s) with %ju packages.\n", + only_sync ? "Updated" : "Added", uri, pkgidx_version, total_pkgs); + +out: + prop_object_release(d); + if (rv != 0) { + printf("W: removing incorrect pkg index file: '%s' ...\n", + plist); + rv = remove(plist); + } + return rv; +} + +bool +sanitize_url(char *buf, const char *path) +{ + char *dirnp, *basenp, *dir, *base, *tmp; + bool rv = false; + + dir = strdup(path); + if (dir == NULL) + return false; + + base = strdup(path); + if (base == NULL) { + free(dir); + return false; + } + + dirnp = dirname(dir); + if (strcmp(dirnp, ".") == 0) + goto out; + + basenp = basename(base); + if (strcmp(basenp, base) == 0) + goto out; + + tmp = strncpy(buf, dirnp, PATH_MAX - 1); + if (sizeof(*tmp) >= PATH_MAX) + goto out; + + buf[strlen(buf) + 1] = '\0'; + if (strcmp(dirnp, "/")) + strncat(buf, "/", 1); + strncat(buf, basenp, PATH_MAX - strlen(buf) - 1); + rv = true; + +out: + free(dir); + free(base); + + return rv; +} + +int +unregister_repository(const char *uri) +{ + char idxstr[PATH_MAX]; + int rv = 0; + + if (!sanitize_url(idxstr, uri)) + return errno; + + if ((rv = xbps_unregister_repository(idxstr)) != 0) { + if (rv == ENOENT) + printf("Repository '%s' not actually " + "registered.\n", idxstr); + else + printf("E: couldn't unregister " + "repository (%s)\n", strerror(rv)); + } + + return rv; +} + +int +register_repository(const char *uri) +{ + char *plist, idxstr[PATH_MAX]; + int rv = 0; + + if (xbps_check_is_repo_string_remote(uri)) { + if (!sanitize_url(idxstr, uri)) + return errno; + + printf("Fetching remote package index at %s...\n", uri); + rv = xbps_sync_repository_pkg_index(idxstr); + if (rv == -1) { + printf("Error: could not fetch pkg index file: %s.\n", + xbps_fetch_error_string()); + return rv; + } else if (rv == 0) { + printf("Package index file is already " + "up to date.\n"); + return 0; + } + + plist = xbps_get_pkg_index_plist(idxstr); + } else { + if (!sanitize_url(idxstr, uri)) + return errno; + + plist = xbps_get_pkg_index_plist(idxstr); + } + + if (plist == NULL) + return errno; + + if ((rv = pkgindex_verify(plist, idxstr, false)) != 0) + goto out; + + if ((rv = xbps_register_repository(idxstr)) != 0) { + printf("ERROR: couldn't register repository (%s)\n", + strerror(rv)); + goto out; + } + +out: + if (plist != NULL) + free(plist); + + return rv; +} + +int +show_pkg_info_from_repolist(const char *pkgname) +{ + struct repository_data *rd; + prop_dictionary_t repo_pkgd, pkg_propsd; + int rv = 0; + + SIMPLEQ_FOREACH(rd, &repodata_queue, chain) { + char *url = NULL; + repo_pkgd = xbps_find_pkg_in_dict(rd->rd_repod, + "packages", pkgname); + if (repo_pkgd == NULL) { + errno = ENOENT; + continue; + } + url = xbps_get_path_from_pkg_dict_repo(repo_pkgd, rd->rd_uri); + if (url == NULL) { + rv = errno; + break; + } + printf("Fetching info from: %s\n", rd->rd_uri); + pkg_propsd = xbps_get_pkg_plist_dict_from_url(url, + XBPS_PKGPROPS); + if (pkg_propsd == NULL) { + free(url); + rv = errno; + break; + } + show_pkg_info_only_repo(repo_pkgd); + show_pkg_info(pkg_propsd); + prop_object_release(pkg_propsd); + break; + } + + return rv; +} + +int +show_pkg_deps_from_repolist(const char *pkgname) +{ + struct repository_data *rd; + prop_dictionary_t pkgd; + const char *ver; + int rv = 0; + + SIMPLEQ_FOREACH(rd, &repodata_queue, chain) { + pkgd = xbps_find_pkg_in_dict(rd->rd_repod, "packages", pkgname); + if (pkgd == NULL) { + errno = ENOENT; + continue; + } + if (!prop_dictionary_get_cstring_nocopy(pkgd, + "version", &ver)) { + rv = errno; + break; + } + printf("Repository %s [pkgver: %s]\n", rd->rd_uri, ver); + (void)xbps_callback_array_iter_in_dict(pkgd, + "run_depends", list_strings_sep_in_array, NULL); + } + + return rv; +} + +int +repository_sync(void) +{ + struct repository_data *rd; + char *plist; + int rv = 0; + + SIMPLEQ_FOREACH(rd, &repodata_queue, chain) { + if (!xbps_check_is_repo_string_remote(rd->rd_uri)) + continue; + + printf("Syncing package index from: %s\n", rd->rd_uri); + rv = xbps_sync_repository_pkg_index(rd->rd_uri); + if (rv == -1) { + printf("Failed! returned: %s\n", + xbps_fetch_error_string()); + break; + } else if (rv == 0) { + printf("Package index file is already up to date.\n"); + continue; + } + if ((plist = xbps_get_pkg_index_plist(rd->rd_uri)) == NULL) { + rv = EINVAL; + break; + } + (void)pkgindex_verify(plist, rd->rd_uri, true); + free(plist); + } + + return rv; +} diff --git a/bin/xbps-repo/util.c b/bin/xbps-repo/util.c index 7c240fcb..c5bc34cb 100644 --- a/bin/xbps-repo/util.c +++ b/bin/xbps-repo/util.c @@ -33,6 +33,35 @@ #include #include "defs.h" +void +show_pkg_info_only_repo(prop_dictionary_t dict) +{ + prop_object_t obj; + char size[64]; + int rv = 0; + + obj = prop_dictionary_get(dict, "filename"); + if (obj && prop_object_type(obj) == PROP_TYPE_STRING) { + printf("Filename: %s", prop_string_cstring_nocopy(obj)); + obj = prop_dictionary_get(dict, "filename-size"); + if (obj && prop_object_type(obj) == PROP_TYPE_NUMBER) { + rv = xbps_humanize_number(size, 5, + (int64_t)prop_number_unsigned_integer_value(obj), + "", HN_AUTOSCALE, HN_B|HN_DECIMAL|HN_NOSPACE); + if (rv == -1) + printf(" (size: %ju)\n", + prop_number_unsigned_integer_value(obj)); + else + printf(" (size: %s)\n", size); + } else + printf("\n"); + } + + obj = prop_dictionary_get(dict, "filename-sha256"); + if (obj && prop_object_type(obj) == PROP_TYPE_STRING) + printf("SHA256: %s\n", prop_string_cstring_nocopy(obj)); +} + void show_pkg_info(prop_dictionary_t dict) { @@ -73,27 +102,6 @@ show_pkg_info(prop_dictionary_t dict) if (obj && prop_object_type(obj) == PROP_TYPE_STRING) printf("Version: %s\n", prop_string_cstring_nocopy(obj)); - obj = prop_dictionary_get(dict, "filename"); - if (obj && prop_object_type(obj) == PROP_TYPE_STRING) { - printf("Filename: %s", prop_string_cstring_nocopy(obj)); - obj = prop_dictionary_get(dict, "filename-size"); - if (obj && prop_object_type(obj) == PROP_TYPE_NUMBER) { - rv = xbps_humanize_number(size, 5, - (int64_t)prop_number_unsigned_integer_value(obj), - "", HN_AUTOSCALE, HN_B|HN_DECIMAL|HN_NOSPACE); - if (rv == -1) - printf(" (size: %ju)\n", - prop_number_unsigned_integer_value(obj)); - else - printf(" (size: %s)\n", size); - } else - printf("\n"); - } - - obj = prop_dictionary_get(dict, "filename-sha256"); - if (obj && prop_object_type(obj) == PROP_TYPE_STRING) - printf("SHA256: %s\n", prop_string_cstring_nocopy(obj)); - obj = prop_dictionary_get(dict, "conf_files"); if (obj && prop_object_type(obj) == PROP_TYPE_ARRAY) { printf("Configuration files:\n"); @@ -105,7 +113,7 @@ show_pkg_info(prop_dictionary_t dict) obj = prop_dictionary_get(dict, "short_desc"); if (obj && prop_object_type(obj) == PROP_TYPE_STRING) - printf("Description: %s", prop_string_cstring_nocopy(obj)); + printf("Description: %s\n", prop_string_cstring_nocopy(obj)); obj = prop_dictionary_get(dict, "long_desc"); if (obj && prop_object_type(obj) == PROP_TYPE_STRING)