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 && strcmp(src->extra_data, "__dummy__ "))
124 if (src->extra_data) /* debian style? */
125 sprintf_alloc(&url, "%s/%s/%s", src->value, src->extra_data,
126 src->gzip ? "Packages.gz" : "Packages");
128 sprintf_alloc(&url, "%s/%s", src->value, src->gzip ? "Packages.gz" : "Packages");
130 sprintf_alloc(&list_file_name, "%s/%s", lists_dir, src->name);
131 if (opkg_download(url, list_file_name, NULL, NULL, 0)) {
134 opkg_msg(NOTICE, "Updated list of available packages in %s.\n",
138 #if defined(HAVE_GPGME) || defined(HAVE_OPENSSL) || defined(HAVE_USIGN)
139 if (conf->check_signature) {
140 /* download detached signitures to verify the package lists */
141 /* get the url for the sig file */
142 if (src->extra_data) /* debian style? */
143 sprintf_alloc(&url, "%s/%s/%s", src->value, src->extra_data,
146 sprintf_alloc(&url, "%s/%s", src->value, "Packages.sig");
148 /* create temporary file for it */
151 /* Put the signature in the right place */
152 sprintf_alloc (&tmp_file_name, "%s/%s.sig", lists_dir, src->name);
154 err = opkg_download(url, tmp_file_name, NULL, NULL, 0);
157 opkg_msg(NOTICE, "Signature check failed.\n");
159 err = opkg_verify_file (list_file_name, tmp_file_name);
161 opkg_msg(NOTICE, "Signature check passed.\n");
163 opkg_msg(NOTICE, "Signature check failed.\n");
165 if (err && !conf->force_signature) {
166 /* The signature was wrong so delete it */
167 opkg_msg(NOTICE, "Remove wrong Signature file.\n");
168 unlink (tmp_file_name);
169 unlink (list_file_name);
171 /* We shouldn't unlink the signature ! */
172 // unlink (tmp_file_name);
173 free (tmp_file_name);
179 free(list_file_name);
189 struct opkg_intercept
195 typedef struct opkg_intercept *opkg_intercept_t;
197 static opkg_intercept_t
198 opkg_prep_intercepts(void)
200 opkg_intercept_t ctx;
203 ctx = xcalloc(1, sizeof (*ctx));
204 ctx->oldpath = xstrdup(getenv("PATH"));
205 sprintf_alloc(&newpath, "%s/opkg/intercept:%s", DATADIR, ctx->oldpath);
206 sprintf_alloc(&ctx->statedir, "%s/opkg-intercept-XXXXXX", conf->tmp_dir);
208 if (mkdtemp(ctx->statedir) == NULL) {
209 opkg_perror(ERROR,"Failed to make temp dir %s", ctx->statedir);
217 setenv("OPKG_INTERCEPT_DIR", ctx->statedir, 1);
218 setenv("PATH", newpath, 1);
225 opkg_finalize_intercepts(opkg_intercept_t ctx)
230 setenv ("PATH", ctx->oldpath, 1);
233 dir = opendir (ctx->statedir);
236 while (de = readdir (dir), de != NULL) {
239 if (de->d_name[0] == '.')
242 sprintf_alloc (&path, "%s/%s", ctx->statedir, de->d_name);
243 if (access (path, X_OK) == 0) {
244 const char *argv[] = {"sh", "-c", path, NULL};
251 opkg_perror(ERROR, "Failed to open dir %s", ctx->statedir);
254 free (ctx->statedir);
260 /* For package pkg do the following: If it is already visited, return. If not,
261 add it in visited list and recurse to its deps. Finally, add it to ordered
263 pkg_vec all contains all available packages in repos.
264 pkg_vec visited contains packages already visited by this function, and is
265 used to end recursion and avoid an infinite loop on graph cycles.
266 pkg_vec ordered will finally contain the ordered set of packages.
269 opkg_recurse_pkgs_in_order(pkg_t *pkg, pkg_vec_t *all,
270 pkg_vec_t *visited, pkg_vec_t *ordered)
275 compound_depend_t * compound_depend;
276 depend_t ** possible_satisfiers;
277 abstract_pkg_t *abpkg;
278 abstract_pkg_t **dependents;
280 /* If it's just an available package, that is, not installed and not even
282 /* XXX: This is probably an overkill, since a state_status != SS_UNPACKED
283 would do here. However, if there is an intermediate node (pkg) that is
284 configured and installed between two unpacked packages, the latter
285 won't be properly reordered, unless all installed/unpacked pkgs are
287 if (pkg->state_status == SS_NOT_INSTALLED)
290 /* If the package has already been visited (by this function), skip it */
291 for(j = 0; j < visited->len; j++)
292 if ( ! strcmp(visited->pkgs[j]->name, pkg->name)) {
293 opkg_msg(DEBUG, "pkg %s already visited, skipping.\n", pkg->name);
297 pkg_vec_insert(visited, pkg);
299 count = pkg->pre_depends_count + pkg->depends_count + \
300 pkg->recommends_count + pkg->suggests_count;
302 opkg_msg(DEBUG, "pkg %s.\n", pkg->name);
304 /* Iterate over all the dependencies of pkg. For each one, find a package
305 that is either installed or unpacked and satisfies this dependency.
306 (there should only be one such package per dependency installed or
307 unpacked). Then recurse to the dependency package */
308 for (j=0; j < count ; j++) {
309 compound_depend = &pkg->depends[j];
310 possible_satisfiers = compound_depend->possibilities;
311 for (k=0; k < compound_depend->possibility_count ; k++) {
312 abpkg = possible_satisfiers[k]->pkg;
313 dependents = abpkg->provided_by->pkgs;
315 if (dependents != NULL)
316 while (l < abpkg->provided_by->len && dependents[l] != NULL) {
317 opkg_msg(DEBUG, "Descending on pkg %s.\n",
318 dependents [l]->name);
320 /* find whether dependent l is installed or unpacked,
321 * and then find which package in the list satisfies it */
322 for(m = 0; m < all->len; m++) {
324 if ( dep->state_status != SS_NOT_INSTALLED)
325 if ( ! strcmp(dep->name, dependents[l]->name)) {
326 opkg_recurse_pkgs_in_order(dep, all,
328 /* Stop the outer loop */
329 l = abpkg->provided_by->len;
330 /* break from the inner loop */
339 /* When all recursions from this node down, are over, and all
340 dependencies have been added in proper order in the ordered array, add
341 also the package pkg to ordered array */
342 pkg_vec_insert(ordered, pkg);
349 opkg_configure_packages(char *pkg_name)
351 pkg_vec_t *all, *ordered, *visited;
357 opkg_msg(INFO, "Configuring unpacked packages.\n");
359 all = pkg_vec_alloc();
361 pkg_hash_fetch_available(all);
363 /* Reorder pkgs in order to be configured according to the Depends: tag
365 opkg_msg(INFO, "Reordering packages before configuring them...\n");
366 ordered = pkg_vec_alloc();
367 visited = pkg_vec_alloc();
368 for(i = 0; i < all->len; i++) {
370 opkg_recurse_pkgs_in_order(pkg, all, visited, ordered);
373 ic = opkg_prep_intercepts();
379 for(i = 0; i < ordered->len; i++) {
380 pkg = ordered->pkgs[i];
382 if (pkg_name && fnmatch(pkg_name, pkg->name, conf->nocase))
385 if (pkg->state_status == SS_UNPACKED) {
386 opkg_msg(NOTICE, "Configuring %s.\n", pkg->name);
387 r = opkg_configure(pkg);
389 pkg->state_status = SS_INSTALLED;
390 pkg->parent->state_status = SS_INSTALLED;
391 pkg->state_flag &= ~SF_PREFER;
392 opkg_state_changed++;
399 if (opkg_finalize_intercepts (ic))
404 pkg_vec_free(ordered);
405 pkg_vec_free(visited);
411 opkg_remove_cmd(int argc, char **argv);
414 opkg_install_cmd(int argc, char **argv)
420 if (conf->force_reinstall) {
421 int saved_force_depends = conf->force_depends;
422 conf->force_depends = 1;
423 (void)opkg_remove_cmd(argc, argv);
424 conf->force_depends = saved_force_depends;
425 conf->force_reinstall = 0;
428 signal(SIGINT, sigint_handler);
431 * Now scan through package names and install
433 for (i=0; i < argc; i++) {
436 opkg_msg(DEBUG2, "%s\n", arg);
437 if (opkg_prepare_url_for_install(arg, &argv[i]))
440 pkg_info_preinstall_check();
442 for (i=0; i < argc; i++) {
444 if (opkg_install_by_name(arg)) {
445 opkg_msg(ERROR, "Cannot install package %s.\n", arg);
450 if (opkg_configure_packages(NULL))
453 write_status_files_if_changed();
459 opkg_upgrade_cmd(int argc, char **argv)
465 signal(SIGINT, sigint_handler);
468 for (i=0; i < argc; i++) {
471 if (opkg_prepare_url_for_install(arg, &arg))
474 pkg_info_preinstall_check();
476 for (i=0; i < argc; i++) {
478 if (conf->restrict_to_default_dest) {
479 pkg = pkg_hash_fetch_installed_by_name_dest(argv[i],
482 opkg_msg(NOTICE, "Package %s not installed in %s.\n",
483 argv[i], conf->default_dest->name);
487 pkg = pkg_hash_fetch_installed_by_name(argv[i]);
490 if (opkg_upgrade_pkg(pkg))
493 if (opkg_install_by_name(arg))
499 if (opkg_configure_packages(NULL))
502 write_status_files_if_changed();
508 opkg_download_cmd(int argc, char **argv)
514 pkg_info_preinstall_check();
515 for (i = 0; i < argc; i++) {
518 pkg = pkg_hash_fetch_best_installation_candidate_by_name(arg);
520 opkg_msg(ERROR, "Cannot find package %s.\n", arg);
524 if (opkg_download_pkg(pkg, "."))
528 opkg_msg(ERROR, "Failed to download %s.\n", pkg->name);
530 opkg_msg(NOTICE, "Downloaded %s as %s.\n",
531 pkg->name, pkg->local_filename);
540 opkg_list_find_cmd(int argc, char **argv, int use_desc)
543 pkg_vec_t *available;
545 char *pkg_name = NULL;
550 available = pkg_vec_alloc();
551 pkg_hash_fetch_available(available);
552 pkg_vec_sort(available, pkg_compare_names);
553 for (i=0; i < available->len; i++) {
554 pkg = available->pkgs[i];
555 /* if we have package name or pattern and pkg does not match, then skip it */
556 if (pkg_name && fnmatch(pkg_name, pkg->name, conf->nocase) &&
557 (!use_desc || !pkg->description || fnmatch(pkg_name, pkg->description, conf->nocase)))
561 pkg_vec_free(available);
567 opkg_list_cmd(int argc, char **argv)
569 return opkg_list_find_cmd(argc, argv, 0);
573 opkg_find_cmd(int argc, char **argv)
575 return opkg_list_find_cmd(argc, argv, 1);
580 opkg_list_installed_cmd(int argc, char **argv)
583 pkg_vec_t *available;
585 char *pkg_name = NULL;
590 available = pkg_vec_alloc();
591 pkg_hash_fetch_all_installed(available);
592 pkg_vec_sort(available, pkg_compare_names);
593 for (i=0; i < available->len; i++) {
594 pkg = available->pkgs[i];
595 /* if we have package name or pattern and pkg does not match, then skip it */
596 if (pkg_name && fnmatch(pkg_name, pkg->name, conf->nocase))
601 pkg_vec_free(available);
607 opkg_list_changed_conffiles_cmd(int argc, char **argv)
610 pkg_vec_t *available;
612 char *pkg_name = NULL;
613 conffile_list_elt_t *iter;
619 available = pkg_vec_alloc();
620 pkg_hash_fetch_all_installed(available);
621 pkg_vec_sort(available, pkg_compare_names);
622 for (i=0; i < available->len; i++) {
623 pkg = available->pkgs[i];
624 /* if we have package name or pattern and pkg does not match, then skip it */
625 if (pkg_name && fnmatch(pkg_name, pkg->name, conf->nocase))
627 if (nv_pair_list_empty(&pkg->conffiles))
629 for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
630 cf = (conffile_t *)iter->data;
631 if (cf->name && cf->value && conffile_has_been_modified(cf))
632 printf("%s\n", cf->name);
635 pkg_vec_free(available);
640 opkg_list_upgradable_cmd(int argc, char **argv)
642 struct active_list *head = prepare_upgrade_list();
643 struct active_list *node=NULL;
644 pkg_t *_old_pkg, *_new_pkg;
646 for (node = active_list_next(head, head); node;node = active_list_next(head,node)) {
647 _old_pkg = list_entry(node, pkg_t, list);
648 _new_pkg = pkg_hash_fetch_best_installation_candidate_by_name(_old_pkg->name);
649 if (_new_pkg == NULL)
651 old_v = pkg_version_str_alloc(_old_pkg);
652 new_v = pkg_version_str_alloc(_new_pkg);
653 printf("%s - %s - %s\n", _old_pkg->name, old_v, new_v);
657 active_list_head_delete(head);
662 opkg_info_status_cmd(int argc, char **argv, int installed_only)
665 pkg_vec_t *available;
667 char *pkg_name = NULL;
673 available = pkg_vec_alloc();
675 pkg_hash_fetch_all_installed(available);
677 pkg_hash_fetch_available(available);
679 for (i=0; i < available->len; i++) {
680 pkg = available->pkgs[i];
681 if (pkg_name && fnmatch(pkg_name, pkg->name, conf->nocase)) {
685 pkg_formatted_info(stdout, pkg);
687 if (conf->verbosity >= NOTICE) {
688 conffile_list_elt_t *iter;
689 for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
690 conffile_t *cf = (conffile_t *)iter->data;
691 int modified = conffile_has_been_modified(cf);
693 opkg_msg(INFO, "conffile=%s md5sum=%s modified=%d.\n",
694 cf->name, cf->value, modified);
698 pkg_vec_free(available);
704 opkg_info_cmd(int argc, char **argv)
706 return opkg_info_status_cmd(argc, argv, 0);
710 opkg_status_cmd(int argc, char **argv)
712 return opkg_info_status_cmd(argc, argv, 1);
716 opkg_configure_cmd(int argc, char **argv)
719 char *pkg_name = NULL;
724 err = opkg_configure_packages(pkg_name);
726 write_status_files_if_changed();
732 opkg_remove_cmd(int argc, char **argv)
734 int i, a, done, err = 0;
736 pkg_t *pkg_to_remove;
737 pkg_vec_t *available;
741 signal(SIGINT, sigint_handler);
743 pkg_info_preinstall_check();
745 available = pkg_vec_alloc();
746 pkg_hash_fetch_all_installed(available);
748 for (i=0; i<argc; i++) {
749 for (a=0; a<available->len; a++) {
750 pkg = available->pkgs[a];
751 if (fnmatch(argv[i], pkg->name, conf->nocase)) {
754 if (conf->restrict_to_default_dest) {
755 pkg_to_remove = pkg_hash_fetch_installed_by_name_dest(
759 pkg_to_remove = pkg_hash_fetch_installed_by_name(pkg->name);
762 if (pkg_to_remove == NULL) {
763 opkg_msg(ERROR, "Package %s is not installed.\n", pkg->name);
766 if (pkg->state_status == SS_NOT_INSTALLED) {
767 opkg_msg(ERROR, "Package %s not installed.\n", pkg->name);
771 if (opkg_remove_pkg(pkg_to_remove, 0))
778 pkg_vec_free(available);
781 opkg_msg(NOTICE, "No packages removed.\n");
783 write_status_files_if_changed();
788 opkg_flag_cmd(int argc, char **argv)
792 const char *flags = argv[0];
794 signal(SIGINT, sigint_handler);
796 for (i=1; i < argc; i++) {
797 if (conf->restrict_to_default_dest) {
798 pkg = pkg_hash_fetch_installed_by_name_dest(argv[i],
801 pkg = pkg_hash_fetch_installed_by_name(argv[i]);
805 opkg_msg(ERROR, "Package %s is not installed.\n", argv[i]);
808 if (( strcmp(flags,"hold")==0)||( strcmp(flags,"noprune")==0)||
809 ( strcmp(flags,"user")==0)||( strcmp(flags,"ok")==0)) {
810 pkg->state_flag = pkg_state_flag_from_str(flags);
814 * Useful if a package is installed in an offline_root, and
815 * should be configured by opkg-cl configure at a later date.
817 if (( strcmp(flags,"installed")==0)||( strcmp(flags,"unpacked")==0)){
818 pkg->state_status = pkg_state_status_from_str(flags);
821 opkg_state_changed++;
822 opkg_msg(NOTICE, "Setting flags for package %s to %s.\n",
826 write_status_files_if_changed();
831 opkg_files_cmd(int argc, char **argv)
835 str_list_elt_t *iter;
842 pkg = pkg_hash_fetch_installed_by_name(argv[0]);
844 opkg_msg(ERROR, "Package %s not installed.\n", argv[0]);
848 files = pkg_get_installed_files(pkg);
849 pkg_version = pkg_version_str_alloc(pkg);
851 printf("Package %s (%s) is installed on %s and has the following files:\n",
852 pkg->name, pkg_version, pkg->dest->name);
854 for (iter=str_list_first(files); iter; iter=str_list_next(files, iter))
855 printf("%s\n", (char *)iter->data);
858 pkg_free_installed_files(pkg);
864 opkg_depends_cmd(int argc, char **argv)
868 pkg_vec_t *available_pkgs;
869 compound_depend_t *cdep;
873 pkg_info_preinstall_check();
875 available_pkgs = pkg_vec_alloc();
877 pkg_hash_fetch_available(available_pkgs);
879 pkg_hash_fetch_all_installed(available_pkgs);
881 for (i=0; i<argc; i++) {
882 for (j=0; j<available_pkgs->len; j++) {
883 pkg = available_pkgs->pkgs[j];
885 if (fnmatch(argv[i], pkg->name, conf->nocase) != 0)
888 depends_count = pkg->depends_count +
889 pkg->pre_depends_count +
890 pkg->recommends_count +
893 opkg_msg(NOTICE, "%s depends on:\n", pkg->name);
895 for (k=0; k<depends_count; k++) {
896 cdep = &pkg->depends[k];
898 if (cdep->type != DEPEND)
901 str = pkg_depend_str(pkg, k);
902 opkg_msg(NOTICE, "\t%s\n", str);
909 pkg_vec_free(available_pkgs);
914 pkg_mark_provides(pkg_t *pkg)
916 int provides_count = pkg->provides_count;
917 abstract_pkg_t **provides = pkg->provides;
919 pkg->parent->state_flag |= SF_MARKED;
920 for (i = 0; i < provides_count; i++) {
921 provides[i]->state_flag |= SF_MARKED;
926 enum what_field_type {
936 opkg_what_depends_conflicts_cmd(enum depend_type what_field_type, int recursive, int argc, char **argv)
938 depend_t *possibility;
939 compound_depend_t *cdep;
940 pkg_vec_t *available_pkgs;
944 const char *rel_str = NULL;
947 switch (what_field_type) {
948 case DEPEND: rel_str = "depends on"; break;
949 case CONFLICTS: rel_str = "conflicts with"; break;
950 case SUGGEST: rel_str = "suggests"; break;
951 case RECOMMEND: rel_str = "recommends"; break;
955 available_pkgs = pkg_vec_alloc();
958 pkg_hash_fetch_available(available_pkgs);
960 pkg_hash_fetch_all_installed(available_pkgs);
962 /* mark the root set */
963 pkg_vec_clear_marks(available_pkgs);
964 opkg_msg(NOTICE, "Root set:\n");
965 for (i = 0; i < argc; i++)
966 pkg_vec_mark_if_matches(available_pkgs, argv[i]);
968 for (i = 0; i < available_pkgs->len; i++) {
969 pkg = available_pkgs->pkgs[i];
970 if (pkg->state_flag & SF_MARKED) {
971 /* mark the parent (abstract) package */
972 pkg_mark_provides(pkg);
973 opkg_msg(NOTICE, " %s\n", pkg->name);
977 opkg_msg(NOTICE, "What %s root set\n", rel_str);
981 for (j=0; j<available_pkgs->len; j++) {
983 pkg = available_pkgs->pkgs[j];
984 count = ((what_field_type == CONFLICTS)
985 ? pkg->conflicts_count
986 : pkg->pre_depends_count +
988 pkg->recommends_count +
989 pkg->suggests_count);
991 /* skip this package if it is already marked */
992 if (pkg->parent->state_flag & SF_MARKED)
995 for (k=0; k<count; k++) {
996 cdep = (what_field_type == CONFLICTS)
1000 if (what_field_type != cdep->type)
1003 for (l=0; l<cdep->possibility_count; l++) {
1004 possibility = cdep->possibilities[l];
1006 if ((possibility->pkg->state_flag
1011 /* mark the depending package so we
1012 * won't visit it again */
1013 pkg->state_flag |= SF_MARKED;
1014 pkg_mark_provides(pkg);
1017 ver = pkg_version_str_alloc(pkg);
1018 opkg_msg(NOTICE, "\t%s %s\t%s %s",
1022 possibility->pkg->name);
1024 if (possibility->version) {
1025 opkg_msg(NOTICE, " (%s%s)",
1026 constraint_to_str(possibility->constraint),
1027 possibility->version);
1029 if (!pkg_dependence_satisfiable(possibility))
1032 opkg_message(NOTICE, "\n");
1039 } while (changed && recursive);
1041 pkg_vec_free(available_pkgs);
1047 opkg_whatdepends_recursively_cmd(int argc, char **argv)
1049 return opkg_what_depends_conflicts_cmd(DEPEND, 1, argc, argv);
1053 opkg_whatdepends_cmd(int argc, char **argv)
1055 return opkg_what_depends_conflicts_cmd(DEPEND, 0, argc, argv);
1059 opkg_whatsuggests_cmd(int argc, char **argv)
1061 return opkg_what_depends_conflicts_cmd(SUGGEST, 0, argc, argv);
1065 opkg_whatrecommends_cmd(int argc, char **argv)
1067 return opkg_what_depends_conflicts_cmd(RECOMMEND, 0, argc, argv);
1071 opkg_whatconflicts_cmd(int argc, char **argv)
1073 return opkg_what_depends_conflicts_cmd(CONFLICTS, 0, argc, argv);
1077 opkg_what_provides_replaces_cmd(enum what_field_type what_field_type, int argc, char **argv)
1081 pkg_vec_t *available_pkgs = pkg_vec_alloc();
1082 const char *rel_str = (what_field_type == WHATPROVIDES ? "provides" : "replaces");
1085 pkg_info_preinstall_check();
1087 if (conf->query_all)
1088 pkg_hash_fetch_available(available_pkgs);
1090 pkg_hash_fetch_all_installed(available_pkgs);
1091 for (i = 0; i < argc; i++) {
1092 const char *target = argv[i];
1095 opkg_msg(NOTICE, "What %s %s\n",
1097 for (j = 0; j < available_pkgs->len; j++) {
1098 pkg_t *pkg = available_pkgs->pkgs[j];
1100 int count = (what_field_type == WHATPROVIDES) ? pkg->provides_count : pkg->replaces_count;
1101 for (k = 0; k < count; k++) {
1102 abstract_pkg_t *apkg =
1103 ((what_field_type == WHATPROVIDES)
1105 : pkg->replaces[k]);
1106 if (fnmatch(target, apkg->name, conf->nocase) == 0) {
1107 opkg_msg(NOTICE, " %s", pkg->name);
1108 if ((conf->nocase ? strcasecmp(target, apkg->name) : strcmp(target, apkg->name)) != 0)
1109 opkg_msg(NOTICE, "\t%s %s\n",
1110 rel_str, apkg->name);
1111 opkg_message(NOTICE, "\n");
1116 pkg_vec_free(available_pkgs);
1122 opkg_whatprovides_cmd(int argc, char **argv)
1124 return opkg_what_provides_replaces_cmd(WHATPROVIDES, argc, argv);
1128 opkg_whatreplaces_cmd(int argc, char **argv)
1130 return opkg_what_provides_replaces_cmd(WHATREPLACES, argc, argv);
1134 opkg_search_cmd(int argc, char **argv)
1138 pkg_vec_t *installed;
1140 str_list_t *installed_files;
1141 str_list_elt_t *iter;
1142 char *installed_file;
1148 installed = pkg_vec_alloc();
1149 pkg_hash_fetch_all_installed(installed);
1150 pkg_vec_sort(installed, pkg_compare_names);
1152 for (i=0; i < installed->len; i++) {
1153 pkg = installed->pkgs[i];
1155 installed_files = pkg_get_installed_files(pkg);
1157 for (iter = str_list_first(installed_files); iter; iter = str_list_next(installed_files, iter)) {
1158 installed_file = (char *)iter->data;
1159 if (fnmatch(argv[0], installed_file, conf->nocase)==0)
1163 pkg_free_installed_files(pkg);
1166 pkg_vec_free(installed);
1172 opkg_compare_versions_cmd(int argc, char **argv)
1175 /* this is a bit gross */
1177 parse_version(&p1, argv[0]);
1178 parse_version(&p2, argv[2]);
1179 return pkg_version_satisfied(&p1, &p2, argv[1]);
1182 "opkg compare_versions <v1> <op> <v2>\n"
1183 "<op> is one of <= >= << >> =\n");
1189 opkg_print_architecture_cmd(int argc, char **argv)
1191 nv_pair_list_elt_t *l;
1193 list_for_each_entry(l, &conf->arch_list.head, node) {
1194 nv_pair_t *nv = (nv_pair_t *)l->data;
1195 printf("arch %s %s\n", nv->name, nv->value);
1201 /* XXX: CLEANUP: The usage strings should be incorporated into this
1202 array for easier maintenance */
1203 static opkg_cmd_t cmds[] = {
1204 {"update", 0, (opkg_cmd_fun_t)opkg_update_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1205 {"upgrade", 1, (opkg_cmd_fun_t)opkg_upgrade_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1206 {"list", 0, (opkg_cmd_fun_t)opkg_list_cmd, PFM_SOURCE},
1207 {"list_installed", 0, (opkg_cmd_fun_t)opkg_list_installed_cmd, PFM_SOURCE},
1208 {"list-installed", 0, (opkg_cmd_fun_t)opkg_list_installed_cmd, PFM_SOURCE},
1209 {"list_upgradable", 0, (opkg_cmd_fun_t)opkg_list_upgradable_cmd, PFM_SOURCE},
1210 {"list-upgradable", 0, (opkg_cmd_fun_t)opkg_list_upgradable_cmd, PFM_SOURCE},
1211 {"list_changed_conffiles", 0, (opkg_cmd_fun_t)opkg_list_changed_conffiles_cmd, PFM_SOURCE},
1212 {"list-changed-conffiles", 0, (opkg_cmd_fun_t)opkg_list_changed_conffiles_cmd, PFM_SOURCE},
1213 {"info", 0, (opkg_cmd_fun_t)opkg_info_cmd, 0},
1214 {"flag", 1, (opkg_cmd_fun_t)opkg_flag_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1215 {"status", 0, (opkg_cmd_fun_t)opkg_status_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1216 {"install", 1, (opkg_cmd_fun_t)opkg_install_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1217 {"remove", 1, (opkg_cmd_fun_t)opkg_remove_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1218 {"configure", 0, (opkg_cmd_fun_t)opkg_configure_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1219 {"files", 1, (opkg_cmd_fun_t)opkg_files_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1220 {"search", 1, (opkg_cmd_fun_t)opkg_search_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1221 {"find", 1, (opkg_cmd_fun_t)opkg_find_cmd, PFM_SOURCE},
1222 {"download", 1, (opkg_cmd_fun_t)opkg_download_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1223 {"compare_versions", 1, (opkg_cmd_fun_t)opkg_compare_versions_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1224 {"compare-versions", 1, (opkg_cmd_fun_t)opkg_compare_versions_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1225 {"print-architecture", 0, (opkg_cmd_fun_t)opkg_print_architecture_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1226 {"print_architecture", 0, (opkg_cmd_fun_t)opkg_print_architecture_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1227 {"print-installation-architecture", 0, (opkg_cmd_fun_t)opkg_print_architecture_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1228 {"print_installation_architecture", 0, (opkg_cmd_fun_t)opkg_print_architecture_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1229 {"depends", 1, (opkg_cmd_fun_t)opkg_depends_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1230 {"whatdepends", 1, (opkg_cmd_fun_t)opkg_whatdepends_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1231 {"whatdependsrec", 1, (opkg_cmd_fun_t)opkg_whatdepends_recursively_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1232 {"whatrecommends", 1, (opkg_cmd_fun_t)opkg_whatrecommends_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1233 {"whatsuggests", 1, (opkg_cmd_fun_t)opkg_whatsuggests_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1234 {"whatprovides", 1, (opkg_cmd_fun_t)opkg_whatprovides_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1235 {"whatreplaces", 1, (opkg_cmd_fun_t)opkg_whatreplaces_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1236 {"whatconflicts", 1, (opkg_cmd_fun_t)opkg_whatconflicts_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1240 opkg_cmd_find(const char *name)
1244 int num_cmds = sizeof(cmds) / sizeof(opkg_cmd_t);
1246 for (i=0; i < num_cmds; i++) {
1248 if (strcmp(name, cmd->name) == 0)
1256 opkg_cmd_exec(opkg_cmd_t *cmd, int argc, const char **argv)
1258 return (cmd->fun)(argc, argv);