diff --git a/utils/plist.c b/utils/plist.c index 0f78ea8baae..bc7d490b03e 100644 --- a/utils/plist.c +++ b/utils/plist.c @@ -155,6 +155,26 @@ xbps_get_array_iter_from_dict(prop_dictionary_t dict, const char *key) return prop_array_iterator(array); } +const char * +xbps_get_pkgidx_string(const char *repofile) +{ + const char *res; + char plist[PATH_MAX], *len; + + assert(repofile != NULL); + + /* Add full path to pkg-index.plist file */ + len = strncpy(plist, repofile, sizeof(plist) - 1); + if (sizeof(*len) >= sizeof(plist)) + return NULL; + + plist[sizeof(plist) - 1] = '\0'; + strncat(plist, "/", sizeof(plist) - strlen(plist) - 1); + strncat(plist, XBPS_PKGINDEX, sizeof(plist) - strlen(plist) - 1); + res = plist; + + return res; +} bool xbps_remove_string_from_array(prop_object_t obj, void *arg, bool *loop_done) @@ -350,26 +370,74 @@ xbps_show_pkg_info(prop_dictionary_t dict) prop_object_iterator_release(iter); } +bool +xbps_show_pkg_namedesc(prop_object_t obj, void *arg, bool *loop_done) +{ + const char *pkgname, *desc, *ver, *string = arg; + + assert(prop_object_type(obj) == PROP_TYPE_DICTIONARY); + assert(string != NULL); + + prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); + prop_dictionary_get_cstring_nocopy(obj, "short_desc", &desc); + prop_dictionary_get_cstring_nocopy(obj, "version", &ver); + assert(ver != NULL); + + if ((strstr(pkgname, string) || strstr(desc, string))) + printf("\t%s-%s - %s\n", pkgname, ver, desc); + + return true; +} + +bool +xbps_search_string_in_pkgs(prop_object_t obj, void *arg, bool *loop_done) +{ + prop_dictionary_t dict; + const char *repofile, *plist, *pkgstring = arg; + + assert(prop_object_type(obj) == PROP_TYPE_STRING); + assert(pkgstring != NULL); + + /* Get the location of pkgindex file. */ + repofile = prop_string_cstring_nocopy(obj); + assert(repofile != NULL); + + /* Get string for pkg-index.plist with full path. */ + plist = xbps_get_pkgidx_string(repofile); + if (plist == NULL) + return false; + + dict = prop_dictionary_internalize_from_file(plist); + if (dict == NULL || prop_dictionary_count(dict) == 0) + return false; + + printf("From %s repository ...\n", repofile); + xbps_callback_array_iter_in_dict(dict, "packages", + xbps_show_pkg_namedesc, (void *)pkgstring); + + return true; +} + bool xbps_show_pkg_info_from_repolist(prop_object_t obj, void *arg, bool *loop_done) { prop_dictionary_t dict, pkgdict; prop_string_t oloc; - const char *repofile, *repoloc; - char plist[PATH_MAX]; + const char *repofile, *repoloc, *plist; assert(prop_object_type(obj) == PROP_TYPE_STRING); /* Get the location */ repofile = prop_string_cstring_nocopy(obj); - /* Add full path to pkg-index.plist file */ - strncpy(plist, repofile, sizeof(plist) - 1); - plist[sizeof(plist) - 1] = '\0'; - strncat(plist, "/", sizeof(plist) - strlen(plist) - 1); - strncat(plist, XBPS_PKGINDEX, sizeof(plist) - strlen(plist) - 1); + /* Get string for pkg-index.plist with full path. */ + plist = xbps_get_pkgidx_string(repofile); + if (plist == NULL) + return false; dict = prop_dictionary_internalize_from_file(plist); + if (dict == NULL || prop_dictionary_count(dict) == 0) + return false; pkgdict = xbps_find_pkg_in_dict(dict, arg); if (pkgdict == NULL) return false; diff --git a/utils/plist.h b/utils/plist.h index 0281e6bffc1..4bc4f38c04b 100644 --- a/utils/plist.h +++ b/utils/plist.h @@ -132,5 +132,8 @@ bool xbps_list_strings_in_array(prop_object_t, void *, bool *); bool xbps_list_strings_in_array2(prop_object_t, void *, bool *); bool xbps_remove_string_from_array(prop_object_t, void *, bool *); bool xbps_show_pkg_info_from_repolist(prop_object_t obj, void *, bool *); +bool xbps_show_pkg_namedesc(prop_object_t, void *, bool *); +bool xbps_search_string_in_pkgs(prop_object_t, void *, bool *); +const char *xbps_get_pkgidx_string(const char *); #endif /* !_XBPS_PLIST_H_ */ diff --git a/utils/xbps-bin.c b/utils/xbps-bin.c index 26697e98754..f455a98e4fa 100644 --- a/utils/xbps-bin.c +++ b/utils/xbps-bin.c @@ -50,11 +50,12 @@ usage(void) { printf("Usage: xbps-bin [action] [arguments]\n\n" " Available actions:\n" - " repo-add, repo-list, repo-rm, show\n" + " repo-add, repo-list, repo-rm, search, show\n" " Action arguments:\n" " repo-add\t[]\n" " repo-list\t[none]\n" " repo-rm\t[]\n" + " search\t[]\n" " show\t[]\n" "\n" " Examples:\n" @@ -62,6 +63,7 @@ usage(void) " $ xbps-bin repo-add http://www.location.org/xbps-repo\n" " $ xbps-bin repo-list\n" " $ xbps-bin repo-rm /path/to/directory\n" + " $ xbps-bin search klibc\n" " $ xbps-bin show klibc\n"); exit(1); } @@ -154,8 +156,7 @@ main(int argc, char **argv) { prop_dictionary_t dict; repo_info_t *rinfo = NULL; - const char *dpkgidx; - char plist[PATH_MAX]; + const char *dpkgidx, *repolist; if (argc < 2) usage(); @@ -170,13 +171,11 @@ main(int argc, char **argv) exit(EINVAL); /* Temp buffer to verify pkgindex file. */ - strncpy(plist, dpkgidx, sizeof(plist) - 1); - plist[sizeof(plist) - 1] = '\0'; - strncat(plist, "/", sizeof(plist) - strlen(plist) - 1); - strncat(plist, XBPS_PKGINDEX, - sizeof(plist) - strlen(plist) - 1); + repolist = xbps_get_pkgidx_string(dpkgidx); + if (repolist == NULL) + exit(EINVAL); - dict = prop_dictionary_internalize_from_file(plist); + dict = prop_dictionary_internalize_from_file(repolist); if (dict == NULL) { printf("Directory %s does not contain any " "xbps pkgindex file.\n", dpkgidx); @@ -188,7 +187,7 @@ main(int argc, char **argv) exit(ENOMEM); if (!pkgindex_getinfo(dict, rinfo)) { - printf("'%s' is incomplete.\n", plist); + printf("'%s' is incomplete.\n", repolist); free(rinfo); exit(EINVAL); } @@ -232,6 +231,14 @@ main(int argc, char **argv) exit(EINVAL); } + } else if (strcasecmp(argv[1], "search") == 0) { + /* Search for a package by looking at short_desc. */ + if (argc != 3) + usage(); + + xbps_callback_array_iter_in_dict(getrepolist_dict(), + "repository-list", xbps_search_string_in_pkgs, argv[2]); + } else if (strcasecmp(argv[1], "show") == 0) { /* Shows info about a binary package. */ if (argc != 3) @@ -245,6 +252,11 @@ main(int argc, char **argv) exit(EINVAL); } + } else if (strcasecmp(argv[1], "install") == 0) { + /* Installs a binary package and required deps. */ + if (argc != 3) + usage(); + } else { usage(); }