1 /* opkg_cmd.c - the opkg package management system
5 Copyright (C) 2001 University of Southern California
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2, or (at
10 your option) any later version.
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
27 #include "opkg_conf.h"
29 #include "opkg_message.h"
32 #include "pkg_parse.h"
33 #include "sprintf_alloc.h"
35 #include "file_util.h"
36 #include "libbb/libbb.h"
37 #include "opkg_utils.h"
38 #include "opkg_defines.h"
39 #include "opkg_download.h"
40 #include "opkg_install.h"
41 #include "opkg_upgrade.h"
42 #include "opkg_remove.h"
43 #include "opkg_configure.h"
49 char *version = pkg_version_str_alloc(pkg);
51 printf("%s - %s - %s\n", pkg->name, version, pkg->description);
53 printf("%s - %s\n", pkg->name, version);
57 int opkg_state_changed;
60 write_status_files_if_changed(void)
62 if (opkg_state_changed && !conf->noaction) {
63 opkg_msg(INFO, "Writing status file.\n");
64 opkg_conf_write_status_files();
65 pkg_write_changed_filelists();
67 opkg_msg(DEBUG, "Nothing to be done.\n");
72 sigint_handler(int sig)
75 opkg_msg(NOTICE, "Interrupted. Writing out status database.\n");
76 write_status_files_if_changed();
81 opkg_update_cmd(int argc, char **argv)
87 pkg_src_list_elt_t *iter;
91 sprintf_alloc(&lists_dir, "%s", conf->restrict_to_default_dest ? conf->default_dest->lists_dir : conf->lists_dir);
93 if (! file_is_dir(lists_dir)) {
94 if (file_exists(lists_dir)) {
95 opkg_msg(ERROR, "%s exists, but is not a directory.\n",
100 err = file_mkdir_hier(lists_dir, 0755);
109 sprintf_alloc(&tmp, "%s/update-XXXXXX", conf->tmp_dir);
110 if (mkdtemp (tmp) == NULL) {
111 opkg_perror(ERROR, "Failed to make temp dir %s", conf->tmp_dir);
116 for (iter = void_list_first(&conf->pkg_src_list); iter; iter = void_list_next(&conf->pkg_src_list, iter)) {
117 char *url, *list_file_name;
119 src = (pkg_src_t *)iter->data;
121 if (src->extra_data) /* debian style? */
122 sprintf_alloc(&url, "%s/%s/%s", src->value, src->extra_data,
123 src->gzip ? "Packages.gz" : "Packages");
125 sprintf_alloc(&url, "%s/%s", src->value, src->gzip ? "Packages.gz" : "Packages");
127 sprintf_alloc(&list_file_name, "%s/%s", lists_dir, src->name);
132 sprintf_alloc (&tmp_file_name, "%s/%s.gz", tmp, src->name);
133 err = opkg_download(url, tmp_file_name, NULL, NULL);
135 opkg_msg(NOTICE, "Inflating %s.\n", url);
136 in = fopen (tmp_file_name, "r");
137 out = fopen (list_file_name, "w");
146 unlink (tmp_file_name);
150 err = opkg_download(url, list_file_name, NULL, NULL);
154 opkg_msg(NOTICE, "Updated list of available packages in %s.\n",
158 #if defined(HAVE_GPGME) || defined(HAVE_OPENSSL)
159 if (conf->check_signature) {
160 /* download detached signitures to verify the package lists */
161 /* get the url for the sig file */
162 if (src->extra_data) /* debian style? */
163 sprintf_alloc(&url, "%s/%s/%s", src->value, src->extra_data,
166 sprintf_alloc(&url, "%s/%s", src->value, "Packages.sig");
168 /* create temporary file for it */
171 /* Put the signature in the right place */
172 sprintf_alloc (&tmp_file_name, "%s/%s.sig", lists_dir, src->name);
174 err = opkg_download(url, tmp_file_name, NULL, NULL);
177 opkg_msg(NOTICE, "Signature check failed.\n");
179 err = opkg_verify_file (list_file_name, tmp_file_name);
181 opkg_msg(NOTICE, "Signature check passed.\n");
183 opkg_msg(NOTICE, "Signature check failed.\n");
185 /* We shouldn't unlink the signature ! */
186 // unlink (tmp_file_name);
187 free (tmp_file_name);
193 free(list_file_name);
203 struct opkg_intercept
209 typedef struct opkg_intercept *opkg_intercept_t;
211 static opkg_intercept_t
212 opkg_prep_intercepts(void)
214 opkg_intercept_t ctx;
217 ctx = xcalloc(1, sizeof (*ctx));
218 ctx->oldpath = xstrdup(getenv("PATH"));
219 sprintf_alloc(&newpath, "%s/opkg/intercept:%s", DATADIR, ctx->oldpath);
220 sprintf_alloc(&ctx->statedir, "%s/opkg-intercept-XXXXXX", conf->tmp_dir);
222 if (mkdtemp(ctx->statedir) == NULL) {
223 opkg_perror(ERROR,"Failed to make temp dir %s", ctx->statedir);
231 setenv("OPKG_INTERCEPT_DIR", ctx->statedir, 1);
232 setenv("PATH", newpath, 1);
239 opkg_finalize_intercepts(opkg_intercept_t ctx)
244 setenv ("PATH", ctx->oldpath, 1);
247 dir = opendir (ctx->statedir);
250 while (de = readdir (dir), de != NULL) {
253 if (de->d_name[0] == '.')
256 sprintf_alloc (&path, "%s/%s", ctx->statedir, de->d_name);
257 if (access (path, X_OK) == 0) {
258 const char *argv[] = {"sh", "-c", path, NULL};
265 opkg_perror(ERROR, "Failed to open dir %s", ctx->statedir);
268 free (ctx->statedir);
274 /* For package pkg do the following: If it is already visited, return. If not,
275 add it in visited list and recurse to its deps. Finally, add it to ordered
277 pkg_vec all contains all available packages in repos.
278 pkg_vec visited contains packages already visited by this function, and is
279 used to end recursion and avoid an infinite loop on graph cycles.
280 pkg_vec ordered will finally contain the ordered set of packages.
283 opkg_recurse_pkgs_in_order(pkg_t *pkg, pkg_vec_t *all,
284 pkg_vec_t *visited, pkg_vec_t *ordered)
289 compound_depend_t * compound_depend;
290 depend_t ** possible_satisfiers;
291 abstract_pkg_t *abpkg;
292 abstract_pkg_t **dependents;
294 /* If it's just an available package, that is, not installed and not even
296 /* XXX: This is probably an overkill, since a state_status != SS_UNPACKED
297 would do here. However, if there is an intermediate node (pkg) that is
298 configured and installed between two unpacked packages, the latter
299 won't be properly reordered, unless all installed/unpacked pkgs are
301 if (pkg->state_status == SS_NOT_INSTALLED)
304 /* If the package has already been visited (by this function), skip it */
305 for(j = 0; j < visited->len; j++)
306 if ( ! strcmp(visited->pkgs[j]->name, pkg->name)) {
307 opkg_msg(DEBUG, "pkg %s already visited, skipping.\n", pkg->name);
311 pkg_vec_insert(visited, pkg);
313 count = pkg->pre_depends_count + pkg->depends_count + \
314 pkg->recommends_count + pkg->suggests_count;
316 opkg_msg(DEBUG, "pkg %s.\n", pkg->name);
318 /* Iterate over all the dependencies of pkg. For each one, find a package
319 that is either installed or unpacked and satisfies this dependency.
320 (there should only be one such package per dependency installed or
321 unpacked). Then recurse to the dependency package */
322 for (j=0; j < count ; j++) {
323 compound_depend = &pkg->depends[j];
324 possible_satisfiers = compound_depend->possibilities;
325 for (k=0; k < compound_depend->possibility_count ; k++) {
326 abpkg = possible_satisfiers[k]->pkg;
327 dependents = abpkg->provided_by->pkgs;
329 if (dependents != NULL)
330 while (l < abpkg->provided_by->len && dependents[l] != NULL) {
331 opkg_msg(DEBUG, "Descending on pkg %s.\n",
332 dependents [l]->name);
334 /* find whether dependent l is installed or unpacked,
335 * and then find which package in the list satisfies it */
336 for(m = 0; m < all->len; m++) {
338 if ( dep->state_status != SS_NOT_INSTALLED)
339 if ( ! strcmp(dep->name, dependents[l]->name)) {
340 opkg_recurse_pkgs_in_order(dep, all,
342 /* Stop the outer loop */
343 l = abpkg->provided_by->len;
344 /* break from the inner loop */
353 /* When all recursions from this node down, are over, and all
354 dependencies have been added in proper order in the ordered array, add
355 also the package pkg to ordered array */
356 pkg_vec_insert(ordered, pkg);
363 opkg_configure_packages(char *pkg_name)
365 pkg_vec_t *all, *ordered, *visited;
371 opkg_msg(INFO, "Configuring unpacked packages.\n");
373 all = pkg_vec_alloc();
375 pkg_hash_fetch_available(all);
377 /* Reorder pkgs in order to be configured according to the Depends: tag
379 opkg_msg(INFO, "Reordering packages before configuring them...\n");
380 ordered = pkg_vec_alloc();
381 visited = pkg_vec_alloc();
382 for(i = 0; i < all->len; i++) {
384 opkg_recurse_pkgs_in_order(pkg, all, visited, ordered);
387 ic = opkg_prep_intercepts();
393 for(i = 0; i < ordered->len; i++) {
394 pkg = ordered->pkgs[i];
396 if (pkg_name && fnmatch(pkg_name, pkg->name, 0))
399 if (pkg->state_status == SS_UNPACKED) {
400 opkg_msg(NOTICE, "Configuring %s.\n", pkg->name);
401 r = opkg_configure(pkg);
403 pkg->state_status = SS_INSTALLED;
404 pkg->parent->state_status = SS_INSTALLED;
405 pkg->state_flag &= ~SF_PREFER;
406 opkg_state_changed++;
414 r = opkg_finalize_intercepts (ic);
420 pkg_vec_free(ordered);
421 pkg_vec_free(visited);
427 opkg_remove_cmd(int argc, char **argv);
430 opkg_install_cmd(int argc, char **argv)
436 if (conf->force_reinstall) {
437 int saved_force_depends = conf->force_depends;
438 conf->force_depends = 1;
439 (void)opkg_remove_cmd(argc, argv);
440 conf->force_depends = saved_force_depends;
441 conf->force_reinstall = 0;
444 signal(SIGINT, sigint_handler);
447 * Now scan through package names and install
449 for (i=0; i < argc; i++) {
452 opkg_msg(DEBUG2, "%s\n", arg);
453 err = opkg_prepare_url_for_install(arg, &argv[i]);
457 pkg_info_preinstall_check();
459 for (i=0; i < argc; i++) {
461 err = opkg_install_by_name(arg);
463 opkg_msg(ERROR, "Cannot install package %s.\n", arg);
467 r = opkg_configure_packages(NULL);
471 write_status_files_if_changed();
477 opkg_upgrade_cmd(int argc, char **argv)
483 signal(SIGINT, sigint_handler);
486 for (i=0; i < argc; i++) {
489 err = opkg_prepare_url_for_install(arg, &arg);
493 pkg_info_preinstall_check();
495 for (i=0; i < argc; i++) {
497 if (conf->restrict_to_default_dest) {
498 pkg = pkg_hash_fetch_installed_by_name_dest(argv[i],
501 opkg_msg(NOTICE, "Package %s not installed in %s.\n",
502 argv[i], conf->default_dest->name);
506 pkg = pkg_hash_fetch_installed_by_name(argv[i]);
509 opkg_upgrade_pkg(pkg);
511 opkg_install_by_name(arg);
515 pkg_vec_t *installed = pkg_vec_alloc();
517 pkg_info_preinstall_check();
519 pkg_hash_fetch_all_installed(installed);
520 for (i = 0; i < installed->len; i++) {
521 pkg = installed->pkgs[i];
522 opkg_upgrade_pkg(pkg);
524 pkg_vec_free(installed);
527 r = opkg_configure_packages(NULL);
531 write_status_files_if_changed();
537 opkg_download_cmd(int argc, char **argv)
543 pkg_info_preinstall_check();
544 for (i = 0; i < argc; i++) {
547 pkg = pkg_hash_fetch_best_installation_candidate_by_name(arg);
549 opkg_msg(ERROR, "Cannot find package %s.\n", arg);
553 err = opkg_download_pkg(pkg, ".");
556 opkg_msg(ERROR, "Failed to download %s.\n", pkg->name);
558 opkg_msg(NOTICE, "Downloaded %s as %s.\n",
559 pkg->name, pkg->local_filename);
568 opkg_list_cmd(int argc, char **argv)
571 pkg_vec_t *available;
573 char *pkg_name = NULL;
578 available = pkg_vec_alloc();
579 pkg_hash_fetch_available(available);
580 pkg_vec_sort(available, pkg_compare_names);
581 for (i=0; i < available->len; i++) {
582 pkg = available->pkgs[i];
583 /* if we have package name or pattern and pkg does not match, then skip it */
584 if (pkg_name && fnmatch(pkg_name, pkg->name, 0))
588 pkg_vec_free(available);
595 opkg_list_installed_cmd(int argc, char **argv)
598 pkg_vec_t *available;
600 char *pkg_name = NULL;
605 available = pkg_vec_alloc();
606 pkg_hash_fetch_all_installed(available);
607 pkg_vec_sort(available, pkg_compare_names);
608 for (i=0; i < available->len; i++) {
609 pkg = available->pkgs[i];
610 /* if we have package name or pattern and pkg does not match, then skip it */
611 if (pkg_name && fnmatch(pkg_name, pkg->name, 0))
616 pkg_vec_free(available);
622 opkg_list_upgradable_cmd(int argc, char **argv)
624 struct active_list *head = prepare_upgrade_list();
625 struct active_list *node=NULL;
626 pkg_t *_old_pkg, *_new_pkg;
628 for (node = active_list_next(head, head); node;node = active_list_next(head,node)) {
629 _old_pkg = list_entry(node, pkg_t, list);
630 _new_pkg = pkg_hash_fetch_best_installation_candidate_by_name(_old_pkg->name);
631 if (_new_pkg == NULL)
633 old_v = pkg_version_str_alloc(_old_pkg);
634 new_v = pkg_version_str_alloc(_new_pkg);
635 printf("%s - %s - %s\n", _old_pkg->name, old_v, new_v);
639 active_list_head_delete(head);
644 opkg_info_status_cmd(int argc, char **argv, int installed_only)
647 pkg_vec_t *available;
649 char *pkg_name = NULL;
655 available = pkg_vec_alloc();
657 pkg_hash_fetch_all_installed(available);
659 pkg_hash_fetch_available(available);
661 for (i=0; i < available->len; i++) {
662 pkg = available->pkgs[i];
663 if (pkg_name && fnmatch(pkg_name, pkg->name, 0)) {
667 pkg_formatted_info(stdout, pkg);
669 if (conf->verbosity >= NOTICE) {
670 conffile_list_elt_t *iter;
671 for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
672 conffile_t *cf = (conffile_t *)iter->data;
673 int modified = conffile_has_been_modified(cf);
675 opkg_msg(INFO, "conffile=%s md5sum=%s modified=%d.\n",
676 cf->name, cf->value, modified);
680 pkg_vec_free(available);
686 opkg_info_cmd(int argc, char **argv)
688 return opkg_info_status_cmd(argc, argv, 0);
692 opkg_status_cmd(int argc, char **argv)
694 return opkg_info_status_cmd(argc, argv, 1);
698 opkg_configure_cmd(int argc, char **argv)
701 char *pkg_name = NULL;
706 err = opkg_configure_packages(pkg_name);
708 write_status_files_if_changed();
714 opkg_remove_cmd(int argc, char **argv)
716 int i, a, done, r, err = 0;
718 pkg_t *pkg_to_remove;
719 pkg_vec_t *available;
723 signal(SIGINT, sigint_handler);
725 pkg_info_preinstall_check();
727 available = pkg_vec_alloc();
728 pkg_hash_fetch_all_installed(available);
730 for (i=0; i<argc; i++) {
731 for (a=0; a<available->len; a++) {
732 pkg = available->pkgs[a];
733 if (fnmatch(argv[i], pkg->name, 0)) {
736 if (conf->restrict_to_default_dest) {
737 pkg_to_remove = pkg_hash_fetch_installed_by_name_dest(
741 pkg_to_remove = pkg_hash_fetch_installed_by_name(pkg->name);
744 if (pkg_to_remove == NULL) {
745 opkg_msg(ERROR, "Package %s is not installed.\n", pkg->name);
748 if (pkg->state_status == SS_NOT_INSTALLED) { // Added the control, so every already removed package could be skipped
749 opkg_msg(ERROR, "Package %s not installed.\n", pkg->name);
752 r = opkg_remove_pkg(pkg_to_remove, 0);
760 pkg_vec_free(available);
763 opkg_msg(NOTICE, "No packages removed.\n");
765 write_status_files_if_changed();
770 opkg_flag_cmd(int argc, char **argv)
774 const char *flags = argv[0];
776 signal(SIGINT, sigint_handler);
778 for (i=1; i < argc; i++) {
779 if (conf->restrict_to_default_dest) {
780 pkg = pkg_hash_fetch_installed_by_name_dest(argv[i],
783 pkg = pkg_hash_fetch_installed_by_name(argv[i]);
787 opkg_msg(ERROR, "Package %s is not installed.\n", argv[i]);
790 if (( strcmp(flags,"hold")==0)||( strcmp(flags,"noprune")==0)||
791 ( strcmp(flags,"user")==0)||( strcmp(flags,"ok")==0)) {
792 pkg->state_flag = pkg_state_flag_from_str(flags);
796 * Useful if a package is installed in an offline_root, and
797 * should be configured by opkg-cl configure at a later date.
799 if (( strcmp(flags,"installed")==0)||( strcmp(flags,"unpacked")==0)){
800 pkg->state_status = pkg_state_status_from_str(flags);
803 opkg_state_changed++;
804 opkg_msg(NOTICE, "Setting flags for package %s to %s.\n",
808 write_status_files_if_changed();
813 opkg_files_cmd(int argc, char **argv)
817 str_list_elt_t *iter;
824 pkg = pkg_hash_fetch_installed_by_name(argv[0]);
826 opkg_msg(ERROR, "Package %s not installed.\n", argv[0]);
830 files = pkg_get_installed_files(pkg);
831 pkg_version = pkg_version_str_alloc(pkg);
833 printf("Package %s (%s) is installed on %s and has the following files:\n",
834 pkg->name, pkg_version, pkg->dest->name);
836 for (iter=str_list_first(files); iter; iter=str_list_next(files, iter))
837 printf("%s\n", (char *)iter->data);
840 pkg_free_installed_files(pkg);
846 opkg_depends_cmd(int argc, char **argv)
850 pkg_vec_t *available_pkgs;
851 compound_depend_t *cdep;
855 pkg_info_preinstall_check();
857 available_pkgs = pkg_vec_alloc();
859 pkg_hash_fetch_available(available_pkgs);
861 pkg_hash_fetch_all_installed(available_pkgs);
863 for (i=0; i<argc; i++) {
864 for (j=0; j<available_pkgs->len; j++) {
865 pkg = available_pkgs->pkgs[j];
867 if (fnmatch(argv[i], pkg->name, 0) != 0)
870 depends_count = pkg->depends_count +
871 pkg->pre_depends_count +
872 pkg->recommends_count +
875 opkg_msg(NOTICE, "%s depends on:\n", pkg->name);
877 for (k=0; k<depends_count; k++) {
878 cdep = &pkg->depends[k];
880 if (cdep->type != DEPEND)
883 str = pkg_depend_str(pkg, k);
884 opkg_msg(NOTICE, "\t%s\n", str);
891 pkg_vec_free(available_pkgs);
896 pkg_mark_provides(pkg_t *pkg)
898 int provides_count = pkg->provides_count;
899 abstract_pkg_t **provides = pkg->provides;
901 pkg->parent->state_flag |= SF_MARKED;
902 for (i = 0; i < provides_count; i++) {
903 provides[i]->state_flag |= SF_MARKED;
908 enum what_field_type {
918 opkg_what_depends_conflicts_cmd(enum depend_type what_field_type, int recursive, int argc, char **argv)
920 depend_t *possibility;
921 compound_depend_t *cdep;
922 pkg_vec_t *available_pkgs;
926 const char *rel_str = NULL;
929 switch (what_field_type) {
930 case DEPEND: rel_str = "depends on"; break;
931 case CONFLICTS: rel_str = "conflicts with"; break;
932 case SUGGEST: rel_str = "suggests"; break;
933 case RECOMMEND: rel_str = "recommends"; break;
937 available_pkgs = pkg_vec_alloc();
940 pkg_hash_fetch_available(available_pkgs);
942 pkg_hash_fetch_all_installed(available_pkgs);
944 /* mark the root set */
945 pkg_vec_clear_marks(available_pkgs);
946 opkg_msg(NOTICE, "Root set:\n");
947 for (i = 0; i < argc; i++)
948 pkg_vec_mark_if_matches(available_pkgs, argv[i]);
950 for (i = 0; i < available_pkgs->len; i++) {
951 pkg = available_pkgs->pkgs[i];
952 if (pkg->state_flag & SF_MARKED) {
953 /* mark the parent (abstract) package */
954 pkg_mark_provides(pkg);
955 opkg_msg(NOTICE, " %s\n", pkg->name);
959 opkg_msg(NOTICE, "What %s root set\n", rel_str);
963 for (j=0; j<available_pkgs->len; j++) {
965 pkg = available_pkgs->pkgs[j];
966 count = ((what_field_type == CONFLICTS)
967 ? pkg->conflicts_count
968 : pkg->pre_depends_count +
970 pkg->recommends_count +
971 pkg->suggests_count);
973 /* skip this package if it is already marked */
974 if (pkg->parent->state_flag & SF_MARKED)
977 for (k=0; k<count; k++) {
978 cdep = (what_field_type == CONFLICTS)
982 if (what_field_type != cdep->type)
985 for (l=0; l<cdep->possibility_count; l++) {
986 possibility = cdep->possibilities[l];
988 if ((possibility->pkg->state_flag
993 /* mark the depending package so we
994 * won't visit it again */
995 pkg->state_flag |= SF_MARKED;
996 pkg_mark_provides(pkg);
999 ver = pkg_version_str_alloc(pkg);
1000 opkg_msg(NOTICE, "\t%s %s\t%s %s",
1004 possibility->pkg->name);
1006 if (possibility->version) {
1007 opkg_msg(NOTICE, " (%s%s)",
1008 constraint_to_str(possibility->constraint),
1009 possibility->version);
1011 if (!pkg_dependence_satisfiable(possibility))
1014 opkg_msg(NOTICE, "\n");
1021 } while (changed && recursive);
1023 pkg_vec_free(available_pkgs);
1029 opkg_whatdepends_recursively_cmd(int argc, char **argv)
1031 return opkg_what_depends_conflicts_cmd(DEPEND, 1, argc, argv);
1035 opkg_whatdepends_cmd(int argc, char **argv)
1037 return opkg_what_depends_conflicts_cmd(DEPEND, 0, argc, argv);
1041 opkg_whatsuggests_cmd(int argc, char **argv)
1043 return opkg_what_depends_conflicts_cmd(SUGGEST, 0, argc, argv);
1047 opkg_whatrecommends_cmd(int argc, char **argv)
1049 return opkg_what_depends_conflicts_cmd(RECOMMEND, 0, argc, argv);
1053 opkg_whatconflicts_cmd(int argc, char **argv)
1055 return opkg_what_depends_conflicts_cmd(CONFLICTS, 0, argc, argv);
1059 opkg_what_provides_replaces_cmd(enum what_field_type what_field_type, int argc, char **argv)
1063 pkg_vec_t *available_pkgs = pkg_vec_alloc();
1064 const char *rel_str = (what_field_type == WHATPROVIDES ? "provides" : "replaces");
1067 pkg_info_preinstall_check();
1069 if (conf->query_all)
1070 pkg_hash_fetch_available(available_pkgs);
1072 pkg_hash_fetch_all_installed(available_pkgs);
1073 for (i = 0; i < argc; i++) {
1074 const char *target = argv[i];
1077 opkg_msg(NOTICE, "What %s %s\n",
1079 for (j = 0; j < available_pkgs->len; j++) {
1080 pkg_t *pkg = available_pkgs->pkgs[j];
1082 int count = (what_field_type == WHATPROVIDES) ? pkg->provides_count : pkg->replaces_count;
1083 for (k = 0; k < count; k++) {
1084 abstract_pkg_t *apkg =
1085 ((what_field_type == WHATPROVIDES)
1087 : pkg->replaces[k]);
1088 if (fnmatch(target, apkg->name, 0) == 0) {
1089 opkg_msg(NOTICE, " %s", pkg->name);
1090 if (strcmp(target, apkg->name) != 0)
1091 opkg_msg(NOTICE, "\t%s %s\n",
1092 rel_str, apkg->name);
1093 opkg_msg(NOTICE, "\n");
1098 pkg_vec_free(available_pkgs);
1104 opkg_whatprovides_cmd(int argc, char **argv)
1106 return opkg_what_provides_replaces_cmd(WHATPROVIDES, argc, argv);
1110 opkg_whatreplaces_cmd(int argc, char **argv)
1112 return opkg_what_provides_replaces_cmd(WHATREPLACES, argc, argv);
1116 opkg_search_cmd(int argc, char **argv)
1120 pkg_vec_t *installed;
1122 str_list_t *installed_files;
1123 str_list_elt_t *iter;
1124 char *installed_file;
1130 installed = pkg_vec_alloc();
1131 pkg_hash_fetch_all_installed(installed);
1132 pkg_vec_sort(installed, pkg_compare_names);
1134 for (i=0; i < installed->len; i++) {
1135 pkg = installed->pkgs[i];
1137 installed_files = pkg_get_installed_files(pkg);
1139 for (iter = str_list_first(installed_files); iter; iter = str_list_next(installed_files, iter)) {
1140 installed_file = (char *)iter->data;
1141 if (fnmatch(argv[0], installed_file, 0)==0)
1145 pkg_free_installed_files(pkg);
1148 pkg_vec_free(installed);
1154 opkg_compare_versions_cmd(int argc, char **argv)
1157 /* this is a bit gross */
1159 parse_version(&p1, argv[0]);
1160 parse_version(&p2, argv[2]);
1161 return pkg_version_satisfied(&p1, &p2, argv[1]);
1164 "opkg compare_versions <v1> <op> <v2>\n"
1165 "<op> is one of <= >= << >> =\n");
1171 opkg_print_architecture_cmd(int argc, char **argv)
1173 nv_pair_list_elt_t *l;
1175 list_for_each_entry(l, &conf->arch_list.head, node) {
1176 nv_pair_t *nv = (nv_pair_t *)l->data;
1177 printf("arch %s %s\n", nv->name, nv->value);
1183 /* XXX: CLEANUP: The usage strings should be incorporated into this
1184 array for easier maintenance */
1185 static opkg_cmd_t cmds[] = {
1186 {"update", 0, (opkg_cmd_fun_t)opkg_update_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1187 {"upgrade", 0, (opkg_cmd_fun_t)opkg_upgrade_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1188 {"list", 0, (opkg_cmd_fun_t)opkg_list_cmd, PFM_SOURCE},
1189 {"list_installed", 0, (opkg_cmd_fun_t)opkg_list_installed_cmd, PFM_SOURCE},
1190 {"list-installed", 0, (opkg_cmd_fun_t)opkg_list_installed_cmd, PFM_SOURCE},
1191 {"list_upgradable", 0, (opkg_cmd_fun_t)opkg_list_upgradable_cmd, PFM_SOURCE},
1192 {"list-upgradable", 0, (opkg_cmd_fun_t)opkg_list_upgradable_cmd, PFM_SOURCE},
1193 {"info", 0, (opkg_cmd_fun_t)opkg_info_cmd, 0},
1194 {"flag", 1, (opkg_cmd_fun_t)opkg_flag_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1195 {"status", 0, (opkg_cmd_fun_t)opkg_status_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1196 {"install", 1, (opkg_cmd_fun_t)opkg_install_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1197 {"remove", 1, (opkg_cmd_fun_t)opkg_remove_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1198 {"configure", 0, (opkg_cmd_fun_t)opkg_configure_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1199 {"files", 1, (opkg_cmd_fun_t)opkg_files_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1200 {"search", 1, (opkg_cmd_fun_t)opkg_search_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1201 {"download", 1, (opkg_cmd_fun_t)opkg_download_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1202 {"compare_versions", 1, (opkg_cmd_fun_t)opkg_compare_versions_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1203 {"compare-versions", 1, (opkg_cmd_fun_t)opkg_compare_versions_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1204 {"print-architecture", 0, (opkg_cmd_fun_t)opkg_print_architecture_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1205 {"print_architecture", 0, (opkg_cmd_fun_t)opkg_print_architecture_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1206 {"print-installation-architecture", 0, (opkg_cmd_fun_t)opkg_print_architecture_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1207 {"print_installation_architecture", 0, (opkg_cmd_fun_t)opkg_print_architecture_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1208 {"depends", 1, (opkg_cmd_fun_t)opkg_depends_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1209 {"whatdepends", 1, (opkg_cmd_fun_t)opkg_whatdepends_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1210 {"whatdependsrec", 1, (opkg_cmd_fun_t)opkg_whatdepends_recursively_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1211 {"whatrecommends", 1, (opkg_cmd_fun_t)opkg_whatrecommends_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1212 {"whatsuggests", 1, (opkg_cmd_fun_t)opkg_whatsuggests_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1213 {"whatprovides", 1, (opkg_cmd_fun_t)opkg_whatprovides_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1214 {"whatreplaces", 1, (opkg_cmd_fun_t)opkg_whatreplaces_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1215 {"whatconflicts", 1, (opkg_cmd_fun_t)opkg_whatconflicts_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1219 opkg_cmd_find(const char *name)
1223 int num_cmds = sizeof(cmds) / sizeof(opkg_cmd_t);
1225 for (i=0; i < num_cmds; i++) {
1227 if (strcmp(name, cmd->name) == 0)
1235 opkg_cmd_exec(opkg_cmd_t *cmd, int argc, const char **argv)
1237 return (cmd->fun)(argc, argv);