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.
24 #include "opkg_conf.h"
26 #include "opkg_message.h"
29 #include "pkg_parse.h"
30 #include "sprintf_alloc.h"
32 #include "file_util.h"
33 #include "libbb/libbb.h"
34 #include "opkg_utils.h"
35 #include "opkg_defines.h"
36 #include "opkg_download.h"
37 #include "opkg_install.h"
38 #include "opkg_upgrade.h"
39 #include "opkg_remove.h"
40 #include "opkg_configure.h"
46 char *version = pkg_version_str_alloc(pkg);
48 printf("%s - %s - %s\n", pkg->name, version, pkg->description);
50 printf("%s - %s\n", pkg->name, version);
54 int opkg_state_changed;
57 write_status_files_if_changed(void)
59 if (opkg_state_changed && !conf->noaction) {
60 opkg_msg(INFO, "Writing status file.\n");
61 opkg_conf_write_status_files();
62 pkg_write_changed_filelists();
64 opkg_msg(DEBUG, "Nothing to be done.\n");
69 sigint_handler(int sig)
72 opkg_msg(NOTICE, "Interrupted. Writing out status database.\n");
73 write_status_files_if_changed();
78 opkg_update_cmd(int argc, char **argv)
84 pkg_src_list_elt_t *iter;
88 sprintf_alloc(&lists_dir, "%s", conf->restrict_to_default_dest ? conf->default_dest->lists_dir : conf->lists_dir);
90 if (! file_is_dir(lists_dir)) {
91 if (file_exists(lists_dir)) {
92 opkg_msg(ERROR, "%s exists, but is not a directory.\n",
97 err = file_mkdir_hier(lists_dir, 0755);
106 sprintf_alloc(&tmp, "%s/update-XXXXXX", conf->tmp_dir);
107 if (mkdtemp (tmp) == NULL) {
108 opkg_perror(ERROR, "Failed to make temp dir %s", conf->tmp_dir);
113 for (iter = void_list_first(&conf->pkg_src_list); iter; iter = void_list_next(&conf->pkg_src_list, iter)) {
114 char *url, *list_file_name;
116 src = (pkg_src_t *)iter->data;
118 if (src->extra_data) /* debian style? */
119 sprintf_alloc(&url, "%s/%s/%s", src->value, src->extra_data,
120 src->gzip ? "Packages.gz" : "Packages");
122 sprintf_alloc(&url, "%s/%s", src->value, src->gzip ? "Packages.gz" : "Packages");
124 sprintf_alloc(&list_file_name, "%s/%s", lists_dir, src->name);
129 sprintf_alloc (&tmp_file_name, "%s/%s.gz", tmp, src->name);
130 err = opkg_download(url, tmp_file_name, NULL, NULL);
132 opkg_msg(NOTICE, "Inflating %s.\n", url);
133 in = fopen (tmp_file_name, "r");
134 out = fopen (list_file_name, "w");
143 unlink (tmp_file_name);
147 err = opkg_download(url, list_file_name, NULL, NULL);
151 opkg_msg(NOTICE, "Updated list of available packages in %s.\n",
155 #if defined(HAVE_GPGME) || defined(HAVE_OPENSSL)
156 if (conf->check_signature) {
157 /* download detached signitures to verify the package lists */
158 /* get the url for the sig file */
159 if (src->extra_data) /* debian style? */
160 sprintf_alloc(&url, "%s/%s/%s", src->value, src->extra_data,
163 sprintf_alloc(&url, "%s/%s", src->value, "Packages.sig");
165 /* create temporary file for it */
168 /* Put the signature in the right place */
169 sprintf_alloc (&tmp_file_name, "%s/%s.sig", lists_dir, src->name);
171 err = opkg_download(url, tmp_file_name, NULL, NULL);
174 opkg_msg(NOTICE, "Signature check failed.\n");
176 err = opkg_verify_file (list_file_name, tmp_file_name);
178 opkg_msg(NOTICE, "Signature check passed.\n");
180 opkg_msg(NOTICE, "Signature check failed.\n");
182 /* We shouldn't unlink the signature ! */
183 // unlink (tmp_file_name);
184 free (tmp_file_name);
190 free(list_file_name);
200 struct opkg_intercept
206 typedef struct opkg_intercept *opkg_intercept_t;
208 static opkg_intercept_t
209 opkg_prep_intercepts(void)
211 opkg_intercept_t ctx;
214 ctx = xcalloc(1, sizeof (*ctx));
215 ctx->oldpath = xstrdup(getenv("PATH"));
216 sprintf_alloc(&newpath, "%s/opkg/intercept:%s", DATADIR, ctx->oldpath);
217 sprintf_alloc(&ctx->statedir, "%s/opkg-intercept-XXXXXX", conf->tmp_dir);
219 if (mkdtemp(ctx->statedir) == NULL) {
220 opkg_perror(ERROR,"Failed to make temp dir %s", ctx->statedir);
228 setenv("OPKG_INTERCEPT_DIR", ctx->statedir, 1);
229 setenv("PATH", newpath, 1);
236 opkg_finalize_intercepts(opkg_intercept_t ctx)
241 setenv ("PATH", ctx->oldpath, 1);
244 dir = opendir (ctx->statedir);
247 while (de = readdir (dir), de != NULL) {
250 if (de->d_name[0] == '.')
253 sprintf_alloc (&path, "%s/%s", ctx->statedir, de->d_name);
254 if (access (path, X_OK) == 0) {
255 const char *argv[] = {"sh", "-c", path, NULL};
262 opkg_perror(ERROR, "Failed to open dir %s", ctx->statedir);
265 free (ctx->statedir);
271 /* For package pkg do the following: If it is already visited, return. If not,
272 add it in visited list and recurse to its deps. Finally, add it to ordered
274 pkg_vec all contains all available packages in repos.
275 pkg_vec visited contains packages already visited by this function, and is
276 used to end recursion and avoid an infinite loop on graph cycles.
277 pkg_vec ordered will finally contain the ordered set of packages.
280 opkg_recurse_pkgs_in_order(pkg_t *pkg, pkg_vec_t *all,
281 pkg_vec_t *visited, pkg_vec_t *ordered)
286 compound_depend_t * compound_depend;
287 depend_t ** possible_satisfiers;
288 abstract_pkg_t *abpkg;
289 abstract_pkg_t **dependents;
291 /* If it's just an available package, that is, not installed and not even
293 /* XXX: This is probably an overkill, since a state_status != SS_UNPACKED
294 would do here. However, if there is an intermediate node (pkg) that is
295 configured and installed between two unpacked packages, the latter
296 won't be properly reordered, unless all installed/unpacked pkgs are
298 if (pkg->state_status == SS_NOT_INSTALLED)
301 /* If the package has already been visited (by this function), skip it */
302 for(j = 0; j < visited->len; j++)
303 if ( ! strcmp(visited->pkgs[j]->name, pkg->name)) {
304 opkg_msg(DEBUG, "pkg %s already visited, skipping.\n", pkg->name);
308 pkg_vec_insert(visited, pkg);
310 count = pkg->pre_depends_count + pkg->depends_count + \
311 pkg->recommends_count + pkg->suggests_count;
313 opkg_msg(DEBUG, "pkg %s.\n", pkg->name);
315 /* Iterate over all the dependencies of pkg. For each one, find a package
316 that is either installed or unpacked and satisfies this dependency.
317 (there should only be one such package per dependency installed or
318 unpacked). Then recurse to the dependency package */
319 for (j=0; j < count ; j++) {
320 compound_depend = &pkg->depends[j];
321 possible_satisfiers = compound_depend->possibilities;
322 for (k=0; k < compound_depend->possibility_count ; k++) {
323 abpkg = possible_satisfiers[k]->pkg;
324 dependents = abpkg->provided_by->pkgs;
326 if (dependents != NULL)
327 while (l < abpkg->provided_by->len && dependents[l] != NULL) {
328 opkg_msg(DEBUG, "Descending on pkg %s.\n",
329 dependents [l]->name);
331 /* find whether dependent l is installed or unpacked,
332 * and then find which package in the list satisfies it */
333 for(m = 0; m < all->len; m++) {
335 if ( dep->state_status != SS_NOT_INSTALLED)
336 if ( ! strcmp(dep->name, dependents[l]->name)) {
337 opkg_recurse_pkgs_in_order(dep, all,
339 /* Stop the outer loop */
340 l = abpkg->provided_by->len;
341 /* break from the inner loop */
350 /* When all recursions from this node down, are over, and all
351 dependencies have been added in proper order in the ordered array, add
352 also the package pkg to ordered array */
353 pkg_vec_insert(ordered, pkg);
360 opkg_configure_packages(char *pkg_name)
362 pkg_vec_t *all, *ordered, *visited;
368 opkg_msg(INFO, "Configuring unpacked packages.\n");
370 all = pkg_vec_alloc();
372 pkg_hash_fetch_available(all);
374 /* Reorder pkgs in order to be configured according to the Depends: tag
376 opkg_msg(INFO, "Reordering packages before configuring them...\n");
377 ordered = pkg_vec_alloc();
378 visited = pkg_vec_alloc();
379 for(i = 0; i < all->len; i++) {
381 opkg_recurse_pkgs_in_order(pkg, all, visited, ordered);
384 ic = opkg_prep_intercepts();
390 for(i = 0; i < all->len; i++) {
393 if (pkg_name && fnmatch(pkg_name, pkg->name, 0))
396 if (pkg->state_status == SS_UNPACKED) {
397 opkg_msg(NOTICE, "Configuring %s.\n", pkg->name);
398 r = opkg_configure(pkg);
400 pkg->state_status = SS_INSTALLED;
401 pkg->parent->state_status = SS_INSTALLED;
402 pkg->state_flag &= ~SF_PREFER;
410 r = opkg_finalize_intercepts (ic);
416 pkg_vec_free(ordered);
417 pkg_vec_free(visited);
423 opkg_install_cmd(int argc, char **argv)
429 signal(SIGINT, sigint_handler);
432 * Now scan through package names and install
434 for (i=0; i < argc; i++) {
437 opkg_msg(DEBUG2, "%s\n", arg);
438 err = opkg_prepare_url_for_install(arg, &argv[i]);
442 pkg_info_preinstall_check();
444 for (i=0; i < argc; i++) {
446 err = opkg_install_by_name(arg);
448 opkg_msg(ERROR, "Cannot install package %s.\n", arg);
452 opkg_configure_packages(NULL);
454 write_status_files_if_changed();
460 opkg_upgrade_cmd(int argc, char **argv)
466 signal(SIGINT, sigint_handler);
469 for (i=0; i < argc; i++) {
472 err = opkg_prepare_url_for_install(arg, &arg);
476 pkg_info_preinstall_check();
478 for (i=0; i < argc; i++) {
480 if (conf->restrict_to_default_dest) {
481 pkg = pkg_hash_fetch_installed_by_name_dest(argv[i],
484 opkg_msg(NOTICE, "Package %s not installed in %s.\n",
485 argv[i], conf->default_dest->name);
489 pkg = pkg_hash_fetch_installed_by_name(argv[i]);
492 opkg_upgrade_pkg(pkg);
494 opkg_install_by_name(arg);
498 pkg_vec_t *installed = pkg_vec_alloc();
500 pkg_info_preinstall_check();
502 pkg_hash_fetch_all_installed(installed);
503 for (i = 0; i < installed->len; i++) {
504 pkg = installed->pkgs[i];
505 opkg_upgrade_pkg(pkg);
507 pkg_vec_free(installed);
510 opkg_configure_packages(NULL);
512 write_status_files_if_changed();
518 opkg_download_cmd(int argc, char **argv)
524 pkg_info_preinstall_check();
525 for (i = 0; i < argc; i++) {
528 pkg = pkg_hash_fetch_best_installation_candidate_by_name(arg);
530 opkg_msg(ERROR, "Cannot find package %s.\n", arg);
534 err = opkg_download_pkg(pkg, ".");
537 opkg_msg(ERROR, "Failed to download %s.\n", pkg->name);
539 opkg_msg(NOTICE, "Downloaded %s as %s.\n",
540 pkg->name, pkg->local_filename);
549 opkg_list_cmd(int argc, char **argv)
552 pkg_vec_t *available;
554 char *pkg_name = NULL;
559 available = pkg_vec_alloc();
560 pkg_hash_fetch_available(available);
561 pkg_vec_sort(available, pkg_compare_names);
562 for (i=0; i < available->len; i++) {
563 pkg = available->pkgs[i];
564 /* if we have package name or pattern and pkg does not match, then skip it */
565 if (pkg_name && fnmatch(pkg_name, pkg->name, 0))
569 pkg_vec_free(available);
576 opkg_list_installed_cmd(int argc, char **argv)
579 pkg_vec_t *available;
581 char *pkg_name = NULL;
586 available = pkg_vec_alloc();
587 pkg_hash_fetch_all_installed(available);
588 pkg_vec_sort(available, pkg_compare_names);
589 for (i=0; i < available->len; i++) {
590 pkg = available->pkgs[i];
591 /* if we have package name or pattern and pkg does not match, then skip it */
592 if (pkg_name && fnmatch(pkg_name, pkg->name, 0))
597 pkg_vec_free(available);
603 opkg_list_upgradable_cmd(int argc, char **argv)
605 struct active_list *head = prepare_upgrade_list();
606 struct active_list *node=NULL;
607 pkg_t *_old_pkg, *_new_pkg;
609 for (node = active_list_next(head, head); node;node = active_list_next(head,node)) {
610 _old_pkg = list_entry(node, pkg_t, list);
611 _new_pkg = pkg_hash_fetch_best_installation_candidate_by_name(_old_pkg->name);
612 if (_new_pkg == NULL)
614 old_v = pkg_version_str_alloc(_old_pkg);
615 new_v = pkg_version_str_alloc(_new_pkg);
616 printf("%s - %s - %s\n", _old_pkg->name, old_v, new_v);
620 active_list_head_delete(head);
625 opkg_info_status_cmd(int argc, char **argv, int installed_only)
628 pkg_vec_t *available;
630 char *pkg_name = NULL;
636 available = pkg_vec_alloc();
638 pkg_hash_fetch_all_installed(available);
640 pkg_hash_fetch_available(available);
642 for (i=0; i < available->len; i++) {
643 pkg = available->pkgs[i];
644 if (pkg_name && fnmatch(pkg_name, pkg->name, 0)) {
648 pkg_formatted_info(stdout, pkg);
650 if (conf->verbosity >= NOTICE) {
651 conffile_list_elt_t *iter;
652 for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
653 conffile_t *cf = (conffile_t *)iter->data;
654 int modified = conffile_has_been_modified(cf);
656 opkg_msg(INFO, "conffile=%s md5sum=%s modified=%d.\n",
657 cf->name, cf->value, modified);
661 pkg_vec_free(available);
667 opkg_info_cmd(int argc, char **argv)
669 return opkg_info_status_cmd(argc, argv, 0);
673 opkg_status_cmd(int argc, char **argv)
675 return opkg_info_status_cmd(argc, argv, 1);
679 opkg_configure_cmd(int argc, char **argv)
682 char *pkg_name = NULL;
687 err = opkg_configure_packages(pkg_name);
689 write_status_files_if_changed();
695 opkg_remove_cmd(int argc, char **argv)
699 pkg_t *pkg_to_remove;
700 pkg_vec_t *available;
704 signal(SIGINT, sigint_handler);
706 pkg_info_preinstall_check();
708 available = pkg_vec_alloc();
709 pkg_hash_fetch_all_installed(available);
711 for (i=0; i<argc; i++) {
712 for (a=0; a<available->len; a++) {
713 pkg = available->pkgs[a];
714 if (fnmatch(argv[i], pkg->name, 0)) {
717 if (conf->restrict_to_default_dest) {
718 pkg_to_remove = pkg_hash_fetch_installed_by_name_dest(
722 pkg_to_remove = pkg_hash_fetch_installed_by_name(pkg->name);
725 if (pkg_to_remove == NULL) {
726 opkg_msg(ERROR, "Package %s is not installed.\n", pkg->name);
729 if (pkg->state_status == SS_NOT_INSTALLED) { // Added the control, so every already removed package could be skipped
730 opkg_msg(ERROR, "Package %s not installed.\n", pkg->name);
733 opkg_remove_pkg(pkg_to_remove, 0);
738 pkg_vec_free(available);
741 opkg_msg(NOTICE, "No packages removed.\n");
743 write_status_files_if_changed();
748 opkg_flag_cmd(int argc, char **argv)
752 const char *flags = argv[0];
754 signal(SIGINT, sigint_handler);
756 for (i=1; i < argc; i++) {
757 if (conf->restrict_to_default_dest) {
758 pkg = pkg_hash_fetch_installed_by_name_dest(argv[i],
761 pkg = pkg_hash_fetch_installed_by_name(argv[i]);
765 opkg_msg(ERROR, "Package %s is not installed.\n", argv[i]);
768 if (( strcmp(flags,"hold")==0)||( strcmp(flags,"noprune")==0)||
769 ( strcmp(flags,"user")==0)||( strcmp(flags,"ok")==0)) {
770 pkg->state_flag = pkg_state_flag_from_str(flags);
774 * Useful if a package is installed in an offline_root, and
775 * should be configured by opkg-cl configure at a later date.
777 if (( strcmp(flags,"installed")==0)||( strcmp(flags,"unpacked")==0)){
778 pkg->state_status = pkg_state_status_from_str(flags);
781 opkg_state_changed++;
782 opkg_msg(NOTICE, "Setting flags for package %s to %s.\n",
786 write_status_files_if_changed();
791 opkg_files_cmd(int argc, char **argv)
795 str_list_elt_t *iter;
802 pkg = pkg_hash_fetch_installed_by_name(argv[0]);
804 opkg_msg(ERROR, "Package %s not installed.\n", argv[0]);
808 files = pkg_get_installed_files(pkg);
809 pkg_version = pkg_version_str_alloc(pkg);
811 printf("Package %s (%s) is installed on %s and has the following files:\n",
812 pkg->name, pkg_version, pkg->dest->name);
814 for (iter=str_list_first(files); iter; iter=str_list_next(files, iter))
815 printf("%s\n", (char *)iter->data);
818 pkg_free_installed_files(pkg);
824 opkg_depends_cmd(int argc, char **argv)
828 pkg_vec_t *available_pkgs;
829 compound_depend_t *cdep;
833 pkg_info_preinstall_check();
835 available_pkgs = pkg_vec_alloc();
837 pkg_hash_fetch_available(available_pkgs);
839 pkg_hash_fetch_all_installed(available_pkgs);
841 for (i=0; i<argc; i++) {
842 for (j=0; j<available_pkgs->len; j++) {
843 pkg = available_pkgs->pkgs[j];
845 if (fnmatch(argv[i], pkg->name, 0) != 0)
848 depends_count = pkg->depends_count +
849 pkg->pre_depends_count +
850 pkg->recommends_count +
853 opkg_msg(NOTICE, "%s depends on:\n", pkg->name);
855 for (k=0; k<depends_count; k++) {
856 cdep = &pkg->depends[k];
858 if (cdep->type != DEPEND)
861 str = pkg_depend_str(pkg, k);
862 opkg_msg(NOTICE, "\t%s\n", str);
869 pkg_vec_free(available_pkgs);
874 pkg_mark_provides(pkg_t *pkg)
876 int provides_count = pkg->provides_count;
877 abstract_pkg_t **provides = pkg->provides;
879 pkg->parent->state_flag |= SF_MARKED;
880 for (i = 0; i < provides_count; i++) {
881 provides[i]->state_flag |= SF_MARKED;
886 enum what_field_type {
896 opkg_what_depends_conflicts_cmd(enum depend_type what_field_type, int recursive, int argc, char **argv)
898 depend_t *possibility;
899 compound_depend_t *cdep;
900 pkg_vec_t *available_pkgs;
904 const char *rel_str = NULL;
907 switch (what_field_type) {
908 case DEPEND: rel_str = "depends on"; break;
909 case CONFLICTS: rel_str = "conflicts with"; break;
910 case SUGGEST: rel_str = "suggests"; break;
911 case RECOMMEND: rel_str = "recommends"; break;
915 available_pkgs = pkg_vec_alloc();
918 pkg_hash_fetch_available(available_pkgs);
920 pkg_hash_fetch_all_installed(available_pkgs);
922 /* mark the root set */
923 pkg_vec_clear_marks(available_pkgs);
924 opkg_msg(NOTICE, "Root set:\n");
925 for (i = 0; i < argc; i++)
926 pkg_vec_mark_if_matches(available_pkgs, argv[i]);
928 for (i = 0; i < available_pkgs->len; i++) {
929 pkg = available_pkgs->pkgs[i];
930 if (pkg->state_flag & SF_MARKED) {
931 /* mark the parent (abstract) package */
932 pkg_mark_provides(pkg);
933 opkg_msg(NOTICE, " %s\n", pkg->name);
937 opkg_msg(NOTICE, "What %s root set\n", rel_str);
941 for (j=0; j<available_pkgs->len; j++) {
943 pkg = available_pkgs->pkgs[j];
944 count = ((what_field_type == CONFLICTS)
945 ? pkg->conflicts_count
946 : pkg->pre_depends_count +
948 pkg->recommends_count +
949 pkg->suggests_count);
951 /* skip this package if it is already marked */
952 if (pkg->parent->state_flag & SF_MARKED)
955 for (k=0; k<count; k++) {
956 cdep = (what_field_type == CONFLICTS)
960 if (what_field_type != cdep->type)
963 for (l=0; l<cdep->possibility_count; l++) {
964 possibility = cdep->possibilities[l];
966 if ((possibility->pkg->state_flag
971 /* mark the depending package so we
972 * won't visit it again */
973 pkg->state_flag |= SF_MARKED;
974 pkg_mark_provides(pkg);
977 ver = pkg_version_str_alloc(pkg);
978 opkg_msg(NOTICE, "\t%s %s\t%s %s",
982 possibility->pkg->name);
984 if (possibility->version) {
985 opkg_msg(NOTICE, " (%s%s)",
986 constraint_to_str(possibility->constraint),
987 possibility->version);
989 if (!pkg_dependence_satisfiable(possibility))
992 opkg_msg(NOTICE, "\n");
999 } while (changed && recursive);
1001 pkg_vec_free(available_pkgs);
1007 opkg_whatdepends_recursively_cmd(int argc, char **argv)
1009 return opkg_what_depends_conflicts_cmd(DEPEND, 1, argc, argv);
1013 opkg_whatdepends_cmd(int argc, char **argv)
1015 return opkg_what_depends_conflicts_cmd(DEPEND, 0, argc, argv);
1019 opkg_whatsuggests_cmd(int argc, char **argv)
1021 return opkg_what_depends_conflicts_cmd(SUGGEST, 0, argc, argv);
1025 opkg_whatrecommends_cmd(int argc, char **argv)
1027 return opkg_what_depends_conflicts_cmd(RECOMMEND, 0, argc, argv);
1031 opkg_whatconflicts_cmd(int argc, char **argv)
1033 return opkg_what_depends_conflicts_cmd(CONFLICTS, 0, argc, argv);
1037 opkg_what_provides_replaces_cmd(enum what_field_type what_field_type, int argc, char **argv)
1041 pkg_vec_t *available_pkgs = pkg_vec_alloc();
1042 const char *rel_str = (what_field_type == WHATPROVIDES ? "provides" : "replaces");
1045 pkg_info_preinstall_check();
1047 if (conf->query_all)
1048 pkg_hash_fetch_available(available_pkgs);
1050 pkg_hash_fetch_all_installed(available_pkgs);
1051 for (i = 0; i < argc; i++) {
1052 const char *target = argv[i];
1055 opkg_msg(NOTICE, "What %s %s\n",
1057 for (j = 0; j < available_pkgs->len; j++) {
1058 pkg_t *pkg = available_pkgs->pkgs[j];
1060 int count = (what_field_type == WHATPROVIDES) ? pkg->provides_count : pkg->replaces_count;
1061 for (k = 0; k < count; k++) {
1062 abstract_pkg_t *apkg =
1063 ((what_field_type == WHATPROVIDES)
1065 : pkg->replaces[k]);
1066 if (fnmatch(target, apkg->name, 0) == 0) {
1067 opkg_msg(NOTICE, " %s", pkg->name);
1068 if (strcmp(target, apkg->name) != 0)
1069 opkg_msg(NOTICE, "\t%s %s\n",
1070 rel_str, apkg->name);
1071 opkg_msg(NOTICE, "\n");
1076 pkg_vec_free(available_pkgs);
1082 opkg_whatprovides_cmd(int argc, char **argv)
1084 return opkg_what_provides_replaces_cmd(WHATPROVIDES, argc, argv);
1088 opkg_whatreplaces_cmd(int argc, char **argv)
1090 return opkg_what_provides_replaces_cmd(WHATREPLACES, argc, argv);
1094 opkg_search_cmd(int argc, char **argv)
1098 pkg_vec_t *installed;
1100 str_list_t *installed_files;
1101 str_list_elt_t *iter;
1102 char *installed_file;
1108 installed = pkg_vec_alloc();
1109 pkg_hash_fetch_all_installed(installed);
1110 pkg_vec_sort(installed, pkg_compare_names);
1112 for (i=0; i < installed->len; i++) {
1113 pkg = installed->pkgs[i];
1115 installed_files = pkg_get_installed_files(pkg);
1117 for (iter = str_list_first(installed_files); iter; iter = str_list_next(installed_files, iter)) {
1118 installed_file = (char *)iter->data;
1119 if (fnmatch(argv[0], installed_file, 0)==0)
1123 pkg_free_installed_files(pkg);
1126 pkg_vec_free(installed);
1132 opkg_compare_versions_cmd(int argc, char **argv)
1135 /* this is a bit gross */
1137 parse_version(&p1, argv[0]);
1138 parse_version(&p2, argv[2]);
1139 return pkg_version_satisfied(&p1, &p2, argv[1]);
1142 "opkg compare_versions <v1> <op> <v2>\n"
1143 "<op> is one of <= >= << >> =\n");
1149 opkg_print_architecture_cmd(int argc, char **argv)
1151 nv_pair_list_elt_t *l;
1153 list_for_each_entry(l, &conf->arch_list.head, node) {
1154 nv_pair_t *nv = (nv_pair_t *)l->data;
1155 printf("arch %s %s\n", nv->name, nv->value);
1161 /* XXX: CLEANUP: The usage strings should be incorporated into this
1162 array for easier maintenance */
1163 static opkg_cmd_t cmds[] = {
1164 {"update", 0, (opkg_cmd_fun_t)opkg_update_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1165 {"upgrade", 0, (opkg_cmd_fun_t)opkg_upgrade_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1166 {"list", 0, (opkg_cmd_fun_t)opkg_list_cmd, PFM_SOURCE},
1167 {"list_installed", 0, (opkg_cmd_fun_t)opkg_list_installed_cmd, PFM_SOURCE},
1168 {"list-installed", 0, (opkg_cmd_fun_t)opkg_list_installed_cmd, PFM_SOURCE},
1169 {"list_upgradable", 0, (opkg_cmd_fun_t)opkg_list_upgradable_cmd, PFM_SOURCE},
1170 {"list-upgradable", 0, (opkg_cmd_fun_t)opkg_list_upgradable_cmd, PFM_SOURCE},
1171 {"info", 0, (opkg_cmd_fun_t)opkg_info_cmd, 0},
1172 {"flag", 1, (opkg_cmd_fun_t)opkg_flag_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1173 {"status", 0, (opkg_cmd_fun_t)opkg_status_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1174 {"install", 1, (opkg_cmd_fun_t)opkg_install_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1175 {"remove", 1, (opkg_cmd_fun_t)opkg_remove_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1176 {"configure", 0, (opkg_cmd_fun_t)opkg_configure_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1177 {"files", 1, (opkg_cmd_fun_t)opkg_files_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1178 {"search", 1, (opkg_cmd_fun_t)opkg_search_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1179 {"download", 1, (opkg_cmd_fun_t)opkg_download_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1180 {"compare_versions", 1, (opkg_cmd_fun_t)opkg_compare_versions_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1181 {"compare-versions", 1, (opkg_cmd_fun_t)opkg_compare_versions_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1182 {"print-architecture", 0, (opkg_cmd_fun_t)opkg_print_architecture_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1183 {"print_architecture", 0, (opkg_cmd_fun_t)opkg_print_architecture_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1184 {"print-installation-architecture", 0, (opkg_cmd_fun_t)opkg_print_architecture_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1185 {"print_installation_architecture", 0, (opkg_cmd_fun_t)opkg_print_architecture_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1186 {"depends", 1, (opkg_cmd_fun_t)opkg_depends_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1187 {"whatdepends", 1, (opkg_cmd_fun_t)opkg_whatdepends_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1188 {"whatdependsrec", 1, (opkg_cmd_fun_t)opkg_whatdepends_recursively_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1189 {"whatrecommends", 1, (opkg_cmd_fun_t)opkg_whatrecommends_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1190 {"whatsuggests", 1, (opkg_cmd_fun_t)opkg_whatsuggests_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1191 {"whatprovides", 1, (opkg_cmd_fun_t)opkg_whatprovides_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1192 {"whatreplaces", 1, (opkg_cmd_fun_t)opkg_whatreplaces_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1193 {"whatconflicts", 1, (opkg_cmd_fun_t)opkg_whatconflicts_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1197 opkg_cmd_find(const char *name)
1201 int num_cmds = sizeof(cmds) / sizeof(opkg_cmd_t);
1203 for (i=0; i < num_cmds; i++) {
1205 if (strcmp(name, cmd->name) == 0)
1213 opkg_cmd_exec(opkg_cmd_t *cmd, int argc, const char **argv)
1215 return (cmd->fun)(argc, argv);