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_changed_conffiles_cmd(int argc, char **argv)
623 pkg_vec_t *available;
625 char *pkg_name = NULL;
626 conffile_list_elt_t *iter;
632 available = pkg_vec_alloc();
633 pkg_hash_fetch_all_installed(available);
634 pkg_vec_sort(available, pkg_compare_names);
635 for (i=0; i < available->len; i++) {
636 pkg = available->pkgs[i];
637 /* if we have package name or pattern and pkg does not match, then skip it */
638 if (pkg_name && fnmatch(pkg_name, pkg->name, 0))
640 if (nv_pair_list_empty(&pkg->conffiles))
642 for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
643 cf = (conffile_t *)iter->data;
644 if (cf->name && cf->value && conffile_has_been_modified(cf))
645 printf("%s\n", cf->name);
648 pkg_vec_free(available);
653 opkg_list_upgradable_cmd(int argc, char **argv)
655 struct active_list *head = prepare_upgrade_list();
656 struct active_list *node=NULL;
657 pkg_t *_old_pkg, *_new_pkg;
659 for (node = active_list_next(head, head); node;node = active_list_next(head,node)) {
660 _old_pkg = list_entry(node, pkg_t, list);
661 _new_pkg = pkg_hash_fetch_best_installation_candidate_by_name(_old_pkg->name);
662 if (_new_pkg == NULL)
664 old_v = pkg_version_str_alloc(_old_pkg);
665 new_v = pkg_version_str_alloc(_new_pkg);
666 printf("%s - %s - %s\n", _old_pkg->name, old_v, new_v);
670 active_list_head_delete(head);
675 opkg_info_status_cmd(int argc, char **argv, int installed_only)
678 pkg_vec_t *available;
680 char *pkg_name = NULL;
686 available = pkg_vec_alloc();
688 pkg_hash_fetch_all_installed(available);
690 pkg_hash_fetch_available(available);
692 for (i=0; i < available->len; i++) {
693 pkg = available->pkgs[i];
694 if (pkg_name && fnmatch(pkg_name, pkg->name, 0)) {
698 pkg_formatted_info(stdout, pkg);
700 if (conf->verbosity >= NOTICE) {
701 conffile_list_elt_t *iter;
702 for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
703 conffile_t *cf = (conffile_t *)iter->data;
704 int modified = conffile_has_been_modified(cf);
706 opkg_msg(INFO, "conffile=%s md5sum=%s modified=%d.\n",
707 cf->name, cf->value, modified);
711 pkg_vec_free(available);
717 opkg_info_cmd(int argc, char **argv)
719 return opkg_info_status_cmd(argc, argv, 0);
723 opkg_status_cmd(int argc, char **argv)
725 return opkg_info_status_cmd(argc, argv, 1);
729 opkg_configure_cmd(int argc, char **argv)
732 char *pkg_name = NULL;
737 err = opkg_configure_packages(pkg_name);
739 write_status_files_if_changed();
745 opkg_remove_cmd(int argc, char **argv)
747 int i, a, done, err = 0;
749 pkg_t *pkg_to_remove;
750 pkg_vec_t *available;
754 signal(SIGINT, sigint_handler);
756 pkg_info_preinstall_check();
758 available = pkg_vec_alloc();
759 pkg_hash_fetch_all_installed(available);
761 for (i=0; i<argc; i++) {
762 for (a=0; a<available->len; a++) {
763 pkg = available->pkgs[a];
764 if (fnmatch(argv[i], pkg->name, 0)) {
767 if (conf->restrict_to_default_dest) {
768 pkg_to_remove = pkg_hash_fetch_installed_by_name_dest(
772 pkg_to_remove = pkg_hash_fetch_installed_by_name(pkg->name);
775 if (pkg_to_remove == NULL) {
776 opkg_msg(ERROR, "Package %s is not installed.\n", pkg->name);
779 if (pkg->state_status == SS_NOT_INSTALLED) {
780 opkg_msg(ERROR, "Package %s not installed.\n", pkg->name);
784 if (opkg_remove_pkg(pkg_to_remove, 0))
791 pkg_vec_free(available);
794 opkg_msg(NOTICE, "No packages removed.\n");
796 write_status_files_if_changed();
801 opkg_flag_cmd(int argc, char **argv)
805 const char *flags = argv[0];
807 signal(SIGINT, sigint_handler);
809 for (i=1; i < argc; i++) {
810 if (conf->restrict_to_default_dest) {
811 pkg = pkg_hash_fetch_installed_by_name_dest(argv[i],
814 pkg = pkg_hash_fetch_installed_by_name(argv[i]);
818 opkg_msg(ERROR, "Package %s is not installed.\n", argv[i]);
821 if (( strcmp(flags,"hold")==0)||( strcmp(flags,"noprune")==0)||
822 ( strcmp(flags,"user")==0)||( strcmp(flags,"ok")==0)) {
823 pkg->state_flag = pkg_state_flag_from_str(flags);
827 * Useful if a package is installed in an offline_root, and
828 * should be configured by opkg-cl configure at a later date.
830 if (( strcmp(flags,"installed")==0)||( strcmp(flags,"unpacked")==0)){
831 pkg->state_status = pkg_state_status_from_str(flags);
834 opkg_state_changed++;
835 opkg_msg(NOTICE, "Setting flags for package %s to %s.\n",
839 write_status_files_if_changed();
844 opkg_files_cmd(int argc, char **argv)
848 str_list_elt_t *iter;
855 pkg = pkg_hash_fetch_installed_by_name(argv[0]);
857 opkg_msg(ERROR, "Package %s not installed.\n", argv[0]);
861 files = pkg_get_installed_files(pkg);
862 pkg_version = pkg_version_str_alloc(pkg);
864 printf("Package %s (%s) is installed on %s and has the following files:\n",
865 pkg->name, pkg_version, pkg->dest->name);
867 for (iter=str_list_first(files); iter; iter=str_list_next(files, iter))
868 printf("%s\n", (char *)iter->data);
871 pkg_free_installed_files(pkg);
877 opkg_depends_cmd(int argc, char **argv)
881 pkg_vec_t *available_pkgs;
882 compound_depend_t *cdep;
886 pkg_info_preinstall_check();
888 available_pkgs = pkg_vec_alloc();
890 pkg_hash_fetch_available(available_pkgs);
892 pkg_hash_fetch_all_installed(available_pkgs);
894 for (i=0; i<argc; i++) {
895 for (j=0; j<available_pkgs->len; j++) {
896 pkg = available_pkgs->pkgs[j];
898 if (fnmatch(argv[i], pkg->name, 0) != 0)
901 depends_count = pkg->depends_count +
902 pkg->pre_depends_count +
903 pkg->recommends_count +
906 opkg_msg(NOTICE, "%s depends on:\n", pkg->name);
908 for (k=0; k<depends_count; k++) {
909 cdep = &pkg->depends[k];
911 if (cdep->type != DEPEND)
914 str = pkg_depend_str(pkg, k);
915 opkg_msg(NOTICE, "\t%s\n", str);
922 pkg_vec_free(available_pkgs);
927 pkg_mark_provides(pkg_t *pkg)
929 int provides_count = pkg->provides_count;
930 abstract_pkg_t **provides = pkg->provides;
932 pkg->parent->state_flag |= SF_MARKED;
933 for (i = 0; i < provides_count; i++) {
934 provides[i]->state_flag |= SF_MARKED;
939 enum what_field_type {
949 opkg_what_depends_conflicts_cmd(enum depend_type what_field_type, int recursive, int argc, char **argv)
951 depend_t *possibility;
952 compound_depend_t *cdep;
953 pkg_vec_t *available_pkgs;
957 const char *rel_str = NULL;
960 switch (what_field_type) {
961 case DEPEND: rel_str = "depends on"; break;
962 case CONFLICTS: rel_str = "conflicts with"; break;
963 case SUGGEST: rel_str = "suggests"; break;
964 case RECOMMEND: rel_str = "recommends"; break;
968 available_pkgs = pkg_vec_alloc();
971 pkg_hash_fetch_available(available_pkgs);
973 pkg_hash_fetch_all_installed(available_pkgs);
975 /* mark the root set */
976 pkg_vec_clear_marks(available_pkgs);
977 opkg_msg(NOTICE, "Root set:\n");
978 for (i = 0; i < argc; i++)
979 pkg_vec_mark_if_matches(available_pkgs, argv[i]);
981 for (i = 0; i < available_pkgs->len; i++) {
982 pkg = available_pkgs->pkgs[i];
983 if (pkg->state_flag & SF_MARKED) {
984 /* mark the parent (abstract) package */
985 pkg_mark_provides(pkg);
986 opkg_msg(NOTICE, " %s\n", pkg->name);
990 opkg_msg(NOTICE, "What %s root set\n", rel_str);
994 for (j=0; j<available_pkgs->len; j++) {
996 pkg = available_pkgs->pkgs[j];
997 count = ((what_field_type == CONFLICTS)
998 ? pkg->conflicts_count
999 : pkg->pre_depends_count +
1000 pkg->depends_count +
1001 pkg->recommends_count +
1002 pkg->suggests_count);
1004 /* skip this package if it is already marked */
1005 if (pkg->parent->state_flag & SF_MARKED)
1008 for (k=0; k<count; k++) {
1009 cdep = (what_field_type == CONFLICTS)
1010 ? &pkg->conflicts[k]
1013 if (what_field_type != cdep->type)
1016 for (l=0; l<cdep->possibility_count; l++) {
1017 possibility = cdep->possibilities[l];
1019 if ((possibility->pkg->state_flag
1024 /* mark the depending package so we
1025 * won't visit it again */
1026 pkg->state_flag |= SF_MARKED;
1027 pkg_mark_provides(pkg);
1030 ver = pkg_version_str_alloc(pkg);
1031 opkg_msg(NOTICE, "\t%s %s\t%s %s",
1035 possibility->pkg->name);
1037 if (possibility->version) {
1038 opkg_msg(NOTICE, " (%s%s)",
1039 constraint_to_str(possibility->constraint),
1040 possibility->version);
1042 if (!pkg_dependence_satisfiable(possibility))
1045 opkg_message(NOTICE, "\n");
1052 } while (changed && recursive);
1054 pkg_vec_free(available_pkgs);
1060 opkg_whatdepends_recursively_cmd(int argc, char **argv)
1062 return opkg_what_depends_conflicts_cmd(DEPEND, 1, argc, argv);
1066 opkg_whatdepends_cmd(int argc, char **argv)
1068 return opkg_what_depends_conflicts_cmd(DEPEND, 0, argc, argv);
1072 opkg_whatsuggests_cmd(int argc, char **argv)
1074 return opkg_what_depends_conflicts_cmd(SUGGEST, 0, argc, argv);
1078 opkg_whatrecommends_cmd(int argc, char **argv)
1080 return opkg_what_depends_conflicts_cmd(RECOMMEND, 0, argc, argv);
1084 opkg_whatconflicts_cmd(int argc, char **argv)
1086 return opkg_what_depends_conflicts_cmd(CONFLICTS, 0, argc, argv);
1090 opkg_what_provides_replaces_cmd(enum what_field_type what_field_type, int argc, char **argv)
1094 pkg_vec_t *available_pkgs = pkg_vec_alloc();
1095 const char *rel_str = (what_field_type == WHATPROVIDES ? "provides" : "replaces");
1098 pkg_info_preinstall_check();
1100 if (conf->query_all)
1101 pkg_hash_fetch_available(available_pkgs);
1103 pkg_hash_fetch_all_installed(available_pkgs);
1104 for (i = 0; i < argc; i++) {
1105 const char *target = argv[i];
1108 opkg_msg(NOTICE, "What %s %s\n",
1110 for (j = 0; j < available_pkgs->len; j++) {
1111 pkg_t *pkg = available_pkgs->pkgs[j];
1113 int count = (what_field_type == WHATPROVIDES) ? pkg->provides_count : pkg->replaces_count;
1114 for (k = 0; k < count; k++) {
1115 abstract_pkg_t *apkg =
1116 ((what_field_type == WHATPROVIDES)
1118 : pkg->replaces[k]);
1119 if (fnmatch(target, apkg->name, 0) == 0) {
1120 opkg_msg(NOTICE, " %s", pkg->name);
1121 if (strcmp(target, apkg->name) != 0)
1122 opkg_msg(NOTICE, "\t%s %s\n",
1123 rel_str, apkg->name);
1124 opkg_message(NOTICE, "\n");
1129 pkg_vec_free(available_pkgs);
1135 opkg_whatprovides_cmd(int argc, char **argv)
1137 return opkg_what_provides_replaces_cmd(WHATPROVIDES, argc, argv);
1141 opkg_whatreplaces_cmd(int argc, char **argv)
1143 return opkg_what_provides_replaces_cmd(WHATREPLACES, argc, argv);
1147 opkg_search_cmd(int argc, char **argv)
1151 pkg_vec_t *installed;
1153 str_list_t *installed_files;
1154 str_list_elt_t *iter;
1155 char *installed_file;
1161 installed = pkg_vec_alloc();
1162 pkg_hash_fetch_all_installed(installed);
1163 pkg_vec_sort(installed, pkg_compare_names);
1165 for (i=0; i < installed->len; i++) {
1166 pkg = installed->pkgs[i];
1168 installed_files = pkg_get_installed_files(pkg);
1170 for (iter = str_list_first(installed_files); iter; iter = str_list_next(installed_files, iter)) {
1171 installed_file = (char *)iter->data;
1172 if (fnmatch(argv[0], installed_file, 0)==0)
1176 pkg_free_installed_files(pkg);
1179 pkg_vec_free(installed);
1185 opkg_compare_versions_cmd(int argc, char **argv)
1188 /* this is a bit gross */
1190 parse_version(&p1, argv[0]);
1191 parse_version(&p2, argv[2]);
1192 return pkg_version_satisfied(&p1, &p2, argv[1]);
1195 "opkg compare_versions <v1> <op> <v2>\n"
1196 "<op> is one of <= >= << >> =\n");
1202 opkg_print_architecture_cmd(int argc, char **argv)
1204 nv_pair_list_elt_t *l;
1206 list_for_each_entry(l, &conf->arch_list.head, node) {
1207 nv_pair_t *nv = (nv_pair_t *)l->data;
1208 printf("arch %s %s\n", nv->name, nv->value);
1214 /* XXX: CLEANUP: The usage strings should be incorporated into this
1215 array for easier maintenance */
1216 static opkg_cmd_t cmds[] = {
1217 {"update", 0, (opkg_cmd_fun_t)opkg_update_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1218 {"upgrade", 0, (opkg_cmd_fun_t)opkg_upgrade_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1219 {"list", 0, (opkg_cmd_fun_t)opkg_list_cmd, PFM_SOURCE},
1220 {"list_installed", 0, (opkg_cmd_fun_t)opkg_list_installed_cmd, PFM_SOURCE},
1221 {"list-installed", 0, (opkg_cmd_fun_t)opkg_list_installed_cmd, PFM_SOURCE},
1222 {"list_upgradable", 0, (opkg_cmd_fun_t)opkg_list_upgradable_cmd, PFM_SOURCE},
1223 {"list-upgradable", 0, (opkg_cmd_fun_t)opkg_list_upgradable_cmd, PFM_SOURCE},
1224 {"list_changed_conffiles", 0, (opkg_cmd_fun_t)opkg_list_changed_conffiles_cmd, PFM_SOURCE},
1225 {"list-changed-conffiles", 0, (opkg_cmd_fun_t)opkg_list_changed_conffiles_cmd, PFM_SOURCE},
1226 {"info", 0, (opkg_cmd_fun_t)opkg_info_cmd, 0},
1227 {"flag", 1, (opkg_cmd_fun_t)opkg_flag_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1228 {"status", 0, (opkg_cmd_fun_t)opkg_status_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1229 {"install", 1, (opkg_cmd_fun_t)opkg_install_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1230 {"remove", 1, (opkg_cmd_fun_t)opkg_remove_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1231 {"configure", 0, (opkg_cmd_fun_t)opkg_configure_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1232 {"files", 1, (opkg_cmd_fun_t)opkg_files_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1233 {"search", 1, (opkg_cmd_fun_t)opkg_search_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1234 {"download", 1, (opkg_cmd_fun_t)opkg_download_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1235 {"compare_versions", 1, (opkg_cmd_fun_t)opkg_compare_versions_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1236 {"compare-versions", 1, (opkg_cmd_fun_t)opkg_compare_versions_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1237 {"print-architecture", 0, (opkg_cmd_fun_t)opkg_print_architecture_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1238 {"print_architecture", 0, (opkg_cmd_fun_t)opkg_print_architecture_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1239 {"print-installation-architecture", 0, (opkg_cmd_fun_t)opkg_print_architecture_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1240 {"print_installation_architecture", 0, (opkg_cmd_fun_t)opkg_print_architecture_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1241 {"depends", 1, (opkg_cmd_fun_t)opkg_depends_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1242 {"whatdepends", 1, (opkg_cmd_fun_t)opkg_whatdepends_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1243 {"whatdependsrec", 1, (opkg_cmd_fun_t)opkg_whatdepends_recursively_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1244 {"whatrecommends", 1, (opkg_cmd_fun_t)opkg_whatrecommends_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1245 {"whatsuggests", 1, (opkg_cmd_fun_t)opkg_whatsuggests_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1246 {"whatprovides", 1, (opkg_cmd_fun_t)opkg_whatprovides_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1247 {"whatreplaces", 1, (opkg_cmd_fun_t)opkg_whatreplaces_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1248 {"whatconflicts", 1, (opkg_cmd_fun_t)opkg_whatconflicts_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1252 opkg_cmd_find(const char *name)
1256 int num_cmds = sizeof(cmds) / sizeof(opkg_cmd_t);
1258 for (i=0; i < num_cmds; i++) {
1260 if (strcmp(name, cmd->name) == 0)
1268 opkg_cmd_exec(opkg_cmd_t *cmd, int argc, const char **argv)
1270 return (cmd->fun)(argc, argv);