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++;
413 if (opkg_finalize_intercepts (ic))
418 pkg_vec_free(ordered);
419 pkg_vec_free(visited);
425 opkg_remove_cmd(int argc, char **argv);
428 opkg_install_cmd(int argc, char **argv)
434 if (conf->force_reinstall) {
435 int saved_force_depends = conf->force_depends;
436 conf->force_depends = 1;
437 (void)opkg_remove_cmd(argc, argv);
438 conf->force_depends = saved_force_depends;
439 conf->force_reinstall = 0;
442 signal(SIGINT, sigint_handler);
445 * Now scan through package names and install
447 for (i=0; i < argc; i++) {
450 opkg_msg(DEBUG2, "%s\n", arg);
451 if (opkg_prepare_url_for_install(arg, &argv[i]))
454 pkg_info_preinstall_check();
456 for (i=0; i < argc; i++) {
458 if (opkg_install_by_name(arg)) {
459 opkg_msg(ERROR, "Cannot install package %s.\n", arg);
464 if (opkg_configure_packages(NULL))
467 write_status_files_if_changed();
473 opkg_upgrade_cmd(int argc, char **argv)
479 signal(SIGINT, sigint_handler);
482 for (i=0; i < argc; i++) {
485 if (opkg_prepare_url_for_install(arg, &arg))
488 pkg_info_preinstall_check();
490 for (i=0; i < argc; i++) {
492 if (conf->restrict_to_default_dest) {
493 pkg = pkg_hash_fetch_installed_by_name_dest(argv[i],
496 opkg_msg(NOTICE, "Package %s not installed in %s.\n",
497 argv[i], conf->default_dest->name);
501 pkg = pkg_hash_fetch_installed_by_name(argv[i]);
504 if (opkg_upgrade_pkg(pkg))
507 if (opkg_install_by_name(arg))
512 pkg_vec_t *installed = pkg_vec_alloc();
514 pkg_info_preinstall_check();
516 pkg_hash_fetch_all_installed(installed);
517 for (i = 0; i < installed->len; i++) {
518 pkg = installed->pkgs[i];
519 if (opkg_upgrade_pkg(pkg))
522 pkg_vec_free(installed);
525 if (opkg_configure_packages(NULL))
528 write_status_files_if_changed();
534 opkg_download_cmd(int argc, char **argv)
540 pkg_info_preinstall_check();
541 for (i = 0; i < argc; i++) {
544 pkg = pkg_hash_fetch_best_installation_candidate_by_name(arg);
546 opkg_msg(ERROR, "Cannot find package %s.\n", arg);
550 if (opkg_download_pkg(pkg, "."))
554 opkg_msg(ERROR, "Failed to download %s.\n", pkg->name);
556 opkg_msg(NOTICE, "Downloaded %s as %s.\n",
557 pkg->name, pkg->local_filename);
566 opkg_list_cmd(int argc, char **argv)
569 pkg_vec_t *available;
571 char *pkg_name = NULL;
576 available = pkg_vec_alloc();
577 pkg_hash_fetch_available(available);
578 pkg_vec_sort(available, pkg_compare_names);
579 for (i=0; i < available->len; i++) {
580 pkg = available->pkgs[i];
581 /* if we have package name or pattern and pkg does not match, then skip it */
582 if (pkg_name && fnmatch(pkg_name, pkg->name, 0))
586 pkg_vec_free(available);
593 opkg_list_installed_cmd(int argc, char **argv)
596 pkg_vec_t *available;
598 char *pkg_name = NULL;
603 available = pkg_vec_alloc();
604 pkg_hash_fetch_all_installed(available);
605 pkg_vec_sort(available, pkg_compare_names);
606 for (i=0; i < available->len; i++) {
607 pkg = available->pkgs[i];
608 /* if we have package name or pattern and pkg does not match, then skip it */
609 if (pkg_name && fnmatch(pkg_name, pkg->name, 0))
614 pkg_vec_free(available);
620 opkg_list_upgradable_cmd(int argc, char **argv)
622 struct active_list *head = prepare_upgrade_list();
623 struct active_list *node=NULL;
624 pkg_t *_old_pkg, *_new_pkg;
626 for (node = active_list_next(head, head); node;node = active_list_next(head,node)) {
627 _old_pkg = list_entry(node, pkg_t, list);
628 _new_pkg = pkg_hash_fetch_best_installation_candidate_by_name(_old_pkg->name);
629 if (_new_pkg == NULL)
631 old_v = pkg_version_str_alloc(_old_pkg);
632 new_v = pkg_version_str_alloc(_new_pkg);
633 printf("%s - %s - %s\n", _old_pkg->name, old_v, new_v);
637 active_list_head_delete(head);
642 opkg_info_status_cmd(int argc, char **argv, int installed_only)
645 pkg_vec_t *available;
647 char *pkg_name = NULL;
653 available = pkg_vec_alloc();
655 pkg_hash_fetch_all_installed(available);
657 pkg_hash_fetch_available(available);
659 for (i=0; i < available->len; i++) {
660 pkg = available->pkgs[i];
661 if (pkg_name && fnmatch(pkg_name, pkg->name, 0)) {
665 pkg_formatted_info(stdout, pkg);
667 if (conf->verbosity >= NOTICE) {
668 conffile_list_elt_t *iter;
669 for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
670 conffile_t *cf = (conffile_t *)iter->data;
671 int modified = conffile_has_been_modified(cf);
673 opkg_msg(INFO, "conffile=%s md5sum=%s modified=%d.\n",
674 cf->name, cf->value, modified);
678 pkg_vec_free(available);
684 opkg_info_cmd(int argc, char **argv)
686 return opkg_info_status_cmd(argc, argv, 0);
690 opkg_status_cmd(int argc, char **argv)
692 return opkg_info_status_cmd(argc, argv, 1);
696 opkg_configure_cmd(int argc, char **argv)
699 char *pkg_name = NULL;
704 err = opkg_configure_packages(pkg_name);
706 write_status_files_if_changed();
712 opkg_remove_cmd(int argc, char **argv)
714 int i, a, done, err = 0;
716 pkg_t *pkg_to_remove;
717 pkg_vec_t *available;
721 signal(SIGINT, sigint_handler);
723 pkg_info_preinstall_check();
725 available = pkg_vec_alloc();
726 pkg_hash_fetch_all_installed(available);
728 for (i=0; i<argc; i++) {
729 for (a=0; a<available->len; a++) {
730 pkg = available->pkgs[a];
731 if (fnmatch(argv[i], pkg->name, 0)) {
734 if (conf->restrict_to_default_dest) {
735 pkg_to_remove = pkg_hash_fetch_installed_by_name_dest(
739 pkg_to_remove = pkg_hash_fetch_installed_by_name(pkg->name);
742 if (pkg_to_remove == NULL) {
743 opkg_msg(ERROR, "Package %s is not installed.\n", pkg->name);
746 if (pkg->state_status == SS_NOT_INSTALLED) {
747 opkg_msg(ERROR, "Package %s not installed.\n", pkg->name);
751 if (opkg_remove_pkg(pkg_to_remove, 0))
758 pkg_vec_free(available);
761 opkg_msg(NOTICE, "No packages removed.\n");
763 write_status_files_if_changed();
768 opkg_flag_cmd(int argc, char **argv)
772 const char *flags = argv[0];
774 signal(SIGINT, sigint_handler);
776 for (i=1; i < argc; i++) {
777 if (conf->restrict_to_default_dest) {
778 pkg = pkg_hash_fetch_installed_by_name_dest(argv[i],
781 pkg = pkg_hash_fetch_installed_by_name(argv[i]);
785 opkg_msg(ERROR, "Package %s is not installed.\n", argv[i]);
788 if (( strcmp(flags,"hold")==0)||( strcmp(flags,"noprune")==0)||
789 ( strcmp(flags,"user")==0)||( strcmp(flags,"ok")==0)) {
790 pkg->state_flag = pkg_state_flag_from_str(flags);
794 * Useful if a package is installed in an offline_root, and
795 * should be configured by opkg-cl configure at a later date.
797 if (( strcmp(flags,"installed")==0)||( strcmp(flags,"unpacked")==0)){
798 pkg->state_status = pkg_state_status_from_str(flags);
801 opkg_state_changed++;
802 opkg_msg(NOTICE, "Setting flags for package %s to %s.\n",
806 write_status_files_if_changed();
811 opkg_files_cmd(int argc, char **argv)
815 str_list_elt_t *iter;
822 pkg = pkg_hash_fetch_installed_by_name(argv[0]);
824 opkg_msg(ERROR, "Package %s not installed.\n", argv[0]);
828 files = pkg_get_installed_files(pkg);
829 pkg_version = pkg_version_str_alloc(pkg);
831 printf("Package %s (%s) is installed on %s and has the following files:\n",
832 pkg->name, pkg_version, pkg->dest->name);
834 for (iter=str_list_first(files); iter; iter=str_list_next(files, iter))
835 printf("%s\n", (char *)iter->data);
838 pkg_free_installed_files(pkg);
844 opkg_depends_cmd(int argc, char **argv)
848 pkg_vec_t *available_pkgs;
849 compound_depend_t *cdep;
853 pkg_info_preinstall_check();
855 available_pkgs = pkg_vec_alloc();
857 pkg_hash_fetch_available(available_pkgs);
859 pkg_hash_fetch_all_installed(available_pkgs);
861 for (i=0; i<argc; i++) {
862 for (j=0; j<available_pkgs->len; j++) {
863 pkg = available_pkgs->pkgs[j];
865 if (fnmatch(argv[i], pkg->name, 0) != 0)
868 depends_count = pkg->depends_count +
869 pkg->pre_depends_count +
870 pkg->recommends_count +
873 opkg_msg(NOTICE, "%s depends on:\n", pkg->name);
875 for (k=0; k<depends_count; k++) {
876 cdep = &pkg->depends[k];
878 if (cdep->type != DEPEND)
881 str = pkg_depend_str(pkg, k);
882 opkg_msg(NOTICE, "\t%s\n", str);
889 pkg_vec_free(available_pkgs);
894 pkg_mark_provides(pkg_t *pkg)
896 int provides_count = pkg->provides_count;
897 abstract_pkg_t **provides = pkg->provides;
899 pkg->parent->state_flag |= SF_MARKED;
900 for (i = 0; i < provides_count; i++) {
901 provides[i]->state_flag |= SF_MARKED;
906 enum what_field_type {
916 opkg_what_depends_conflicts_cmd(enum depend_type what_field_type, int recursive, int argc, char **argv)
918 depend_t *possibility;
919 compound_depend_t *cdep;
920 pkg_vec_t *available_pkgs;
924 const char *rel_str = NULL;
927 switch (what_field_type) {
928 case DEPEND: rel_str = "depends on"; break;
929 case CONFLICTS: rel_str = "conflicts with"; break;
930 case SUGGEST: rel_str = "suggests"; break;
931 case RECOMMEND: rel_str = "recommends"; break;
935 available_pkgs = pkg_vec_alloc();
938 pkg_hash_fetch_available(available_pkgs);
940 pkg_hash_fetch_all_installed(available_pkgs);
942 /* mark the root set */
943 pkg_vec_clear_marks(available_pkgs);
944 opkg_msg(NOTICE, "Root set:\n");
945 for (i = 0; i < argc; i++)
946 pkg_vec_mark_if_matches(available_pkgs, argv[i]);
948 for (i = 0; i < available_pkgs->len; i++) {
949 pkg = available_pkgs->pkgs[i];
950 if (pkg->state_flag & SF_MARKED) {
951 /* mark the parent (abstract) package */
952 pkg_mark_provides(pkg);
953 opkg_msg(NOTICE, " %s\n", pkg->name);
957 opkg_msg(NOTICE, "What %s root set\n", rel_str);
961 for (j=0; j<available_pkgs->len; j++) {
963 pkg = available_pkgs->pkgs[j];
964 count = ((what_field_type == CONFLICTS)
965 ? pkg->conflicts_count
966 : pkg->pre_depends_count +
968 pkg->recommends_count +
969 pkg->suggests_count);
971 /* skip this package if it is already marked */
972 if (pkg->parent->state_flag & SF_MARKED)
975 for (k=0; k<count; k++) {
976 cdep = (what_field_type == CONFLICTS)
980 if (what_field_type != cdep->type)
983 for (l=0; l<cdep->possibility_count; l++) {
984 possibility = cdep->possibilities[l];
986 if ((possibility->pkg->state_flag
991 /* mark the depending package so we
992 * won't visit it again */
993 pkg->state_flag |= SF_MARKED;
994 pkg_mark_provides(pkg);
997 ver = pkg_version_str_alloc(pkg);
998 opkg_msg(NOTICE, "\t%s %s\t%s %s",
1002 possibility->pkg->name);
1004 if (possibility->version) {
1005 opkg_msg(NOTICE, " (%s%s)",
1006 constraint_to_str(possibility->constraint),
1007 possibility->version);
1009 if (!pkg_dependence_satisfiable(possibility))
1012 opkg_msg(NOTICE, "\n");
1019 } while (changed && recursive);
1021 pkg_vec_free(available_pkgs);
1027 opkg_whatdepends_recursively_cmd(int argc, char **argv)
1029 return opkg_what_depends_conflicts_cmd(DEPEND, 1, argc, argv);
1033 opkg_whatdepends_cmd(int argc, char **argv)
1035 return opkg_what_depends_conflicts_cmd(DEPEND, 0, argc, argv);
1039 opkg_whatsuggests_cmd(int argc, char **argv)
1041 return opkg_what_depends_conflicts_cmd(SUGGEST, 0, argc, argv);
1045 opkg_whatrecommends_cmd(int argc, char **argv)
1047 return opkg_what_depends_conflicts_cmd(RECOMMEND, 0, argc, argv);
1051 opkg_whatconflicts_cmd(int argc, char **argv)
1053 return opkg_what_depends_conflicts_cmd(CONFLICTS, 0, argc, argv);
1057 opkg_what_provides_replaces_cmd(enum what_field_type what_field_type, int argc, char **argv)
1061 pkg_vec_t *available_pkgs = pkg_vec_alloc();
1062 const char *rel_str = (what_field_type == WHATPROVIDES ? "provides" : "replaces");
1065 pkg_info_preinstall_check();
1067 if (conf->query_all)
1068 pkg_hash_fetch_available(available_pkgs);
1070 pkg_hash_fetch_all_installed(available_pkgs);
1071 for (i = 0; i < argc; i++) {
1072 const char *target = argv[i];
1075 opkg_msg(NOTICE, "What %s %s\n",
1077 for (j = 0; j < available_pkgs->len; j++) {
1078 pkg_t *pkg = available_pkgs->pkgs[j];
1080 int count = (what_field_type == WHATPROVIDES) ? pkg->provides_count : pkg->replaces_count;
1081 for (k = 0; k < count; k++) {
1082 abstract_pkg_t *apkg =
1083 ((what_field_type == WHATPROVIDES)
1085 : pkg->replaces[k]);
1086 if (fnmatch(target, apkg->name, 0) == 0) {
1087 opkg_msg(NOTICE, " %s", pkg->name);
1088 if (strcmp(target, apkg->name) != 0)
1089 opkg_msg(NOTICE, "\t%s %s\n",
1090 rel_str, apkg->name);
1091 opkg_msg(NOTICE, "\n");
1096 pkg_vec_free(available_pkgs);
1102 opkg_whatprovides_cmd(int argc, char **argv)
1104 return opkg_what_provides_replaces_cmd(WHATPROVIDES, argc, argv);
1108 opkg_whatreplaces_cmd(int argc, char **argv)
1110 return opkg_what_provides_replaces_cmd(WHATREPLACES, argc, argv);
1114 opkg_search_cmd(int argc, char **argv)
1118 pkg_vec_t *installed;
1120 str_list_t *installed_files;
1121 str_list_elt_t *iter;
1122 char *installed_file;
1128 installed = pkg_vec_alloc();
1129 pkg_hash_fetch_all_installed(installed);
1130 pkg_vec_sort(installed, pkg_compare_names);
1132 for (i=0; i < installed->len; i++) {
1133 pkg = installed->pkgs[i];
1135 installed_files = pkg_get_installed_files(pkg);
1137 for (iter = str_list_first(installed_files); iter; iter = str_list_next(installed_files, iter)) {
1138 installed_file = (char *)iter->data;
1139 if (fnmatch(argv[0], installed_file, 0)==0)
1143 pkg_free_installed_files(pkg);
1146 pkg_vec_free(installed);
1152 opkg_compare_versions_cmd(int argc, char **argv)
1155 /* this is a bit gross */
1157 parse_version(&p1, argv[0]);
1158 parse_version(&p2, argv[2]);
1159 return pkg_version_satisfied(&p1, &p2, argv[1]);
1162 "opkg compare_versions <v1> <op> <v2>\n"
1163 "<op> is one of <= >= << >> =\n");
1169 opkg_print_architecture_cmd(int argc, char **argv)
1171 nv_pair_list_elt_t *l;
1173 list_for_each_entry(l, &conf->arch_list.head, node) {
1174 nv_pair_t *nv = (nv_pair_t *)l->data;
1175 printf("arch %s %s\n", nv->name, nv->value);
1181 /* XXX: CLEANUP: The usage strings should be incorporated into this
1182 array for easier maintenance */
1183 static opkg_cmd_t cmds[] = {
1184 {"update", 0, (opkg_cmd_fun_t)opkg_update_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1185 {"upgrade", 0, (opkg_cmd_fun_t)opkg_upgrade_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1186 {"list", 0, (opkg_cmd_fun_t)opkg_list_cmd, PFM_SOURCE},
1187 {"list_installed", 0, (opkg_cmd_fun_t)opkg_list_installed_cmd, PFM_SOURCE},
1188 {"list-installed", 0, (opkg_cmd_fun_t)opkg_list_installed_cmd, PFM_SOURCE},
1189 {"list_upgradable", 0, (opkg_cmd_fun_t)opkg_list_upgradable_cmd, PFM_SOURCE},
1190 {"list-upgradable", 0, (opkg_cmd_fun_t)opkg_list_upgradable_cmd, PFM_SOURCE},
1191 {"info", 0, (opkg_cmd_fun_t)opkg_info_cmd, 0},
1192 {"flag", 1, (opkg_cmd_fun_t)opkg_flag_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1193 {"status", 0, (opkg_cmd_fun_t)opkg_status_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1194 {"install", 1, (opkg_cmd_fun_t)opkg_install_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1195 {"remove", 1, (opkg_cmd_fun_t)opkg_remove_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1196 {"configure", 0, (opkg_cmd_fun_t)opkg_configure_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1197 {"files", 1, (opkg_cmd_fun_t)opkg_files_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1198 {"search", 1, (opkg_cmd_fun_t)opkg_search_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1199 {"download", 1, (opkg_cmd_fun_t)opkg_download_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1200 {"compare_versions", 1, (opkg_cmd_fun_t)opkg_compare_versions_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1201 {"compare-versions", 1, (opkg_cmd_fun_t)opkg_compare_versions_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1202 {"print-architecture", 0, (opkg_cmd_fun_t)opkg_print_architecture_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1203 {"print_architecture", 0, (opkg_cmd_fun_t)opkg_print_architecture_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1204 {"print-installation-architecture", 0, (opkg_cmd_fun_t)opkg_print_architecture_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1205 {"print_installation_architecture", 0, (opkg_cmd_fun_t)opkg_print_architecture_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1206 {"depends", 1, (opkg_cmd_fun_t)opkg_depends_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1207 {"whatdepends", 1, (opkg_cmd_fun_t)opkg_whatdepends_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1208 {"whatdependsrec", 1, (opkg_cmd_fun_t)opkg_whatdepends_recursively_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1209 {"whatrecommends", 1, (opkg_cmd_fun_t)opkg_whatrecommends_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1210 {"whatsuggests", 1, (opkg_cmd_fun_t)opkg_whatsuggests_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1211 {"whatprovides", 1, (opkg_cmd_fun_t)opkg_whatprovides_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1212 {"whatreplaces", 1, (opkg_cmd_fun_t)opkg_whatreplaces_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1213 {"whatconflicts", 1, (opkg_cmd_fun_t)opkg_whatconflicts_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1217 opkg_cmd_find(const char *name)
1221 int num_cmds = sizeof(cmds) / sizeof(opkg_cmd_t);
1223 for (i=0; i < num_cmds; i++) {
1225 if (strcmp(name, cmd->name) == 0)
1233 opkg_cmd_exec(opkg_cmd_t *cmd, int argc, const char **argv)
1235 return (cmd->fun)(argc, argv);