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 < all->len; i++) {
396 if (pkg_name && fnmatch(pkg_name, pkg->name, 0))
399 if (pkg->state_status == SS_UNPACKED) {
400 opkg_msg(NOTICE, "Configuring %s.\n", pkg->name);
401 r = opkg_configure(pkg);
403 pkg->state_status = SS_INSTALLED;
404 pkg->parent->state_status = SS_INSTALLED;
405 pkg->state_flag &= ~SF_PREFER;
406 opkg_state_changed++;
414 r = opkg_finalize_intercepts (ic);
420 pkg_vec_free(ordered);
421 pkg_vec_free(visited);
427 opkg_install_cmd(int argc, char **argv)
433 signal(SIGINT, sigint_handler);
436 * Now scan through package names and install
438 for (i=0; i < argc; i++) {
441 opkg_msg(DEBUG2, "%s\n", arg);
442 err = opkg_prepare_url_for_install(arg, &argv[i]);
446 pkg_info_preinstall_check();
448 for (i=0; i < argc; i++) {
450 err = opkg_install_by_name(arg);
452 opkg_msg(ERROR, "Cannot install package %s.\n", arg);
456 opkg_configure_packages(NULL);
458 write_status_files_if_changed();
464 opkg_upgrade_cmd(int argc, char **argv)
470 signal(SIGINT, sigint_handler);
473 for (i=0; i < argc; i++) {
476 err = opkg_prepare_url_for_install(arg, &arg);
480 pkg_info_preinstall_check();
482 for (i=0; i < argc; i++) {
484 if (conf->restrict_to_default_dest) {
485 pkg = pkg_hash_fetch_installed_by_name_dest(argv[i],
488 opkg_msg(NOTICE, "Package %s not installed in %s.\n",
489 argv[i], conf->default_dest->name);
493 pkg = pkg_hash_fetch_installed_by_name(argv[i]);
496 opkg_upgrade_pkg(pkg);
498 opkg_install_by_name(arg);
502 pkg_vec_t *installed = pkg_vec_alloc();
504 pkg_info_preinstall_check();
506 pkg_hash_fetch_all_installed(installed);
507 for (i = 0; i < installed->len; i++) {
508 pkg = installed->pkgs[i];
509 opkg_upgrade_pkg(pkg);
511 pkg_vec_free(installed);
514 opkg_configure_packages(NULL);
516 write_status_files_if_changed();
522 opkg_download_cmd(int argc, char **argv)
528 pkg_info_preinstall_check();
529 for (i = 0; i < argc; i++) {
532 pkg = pkg_hash_fetch_best_installation_candidate_by_name(arg);
534 opkg_msg(ERROR, "Cannot find package %s.\n", arg);
538 err = opkg_download_pkg(pkg, ".");
541 opkg_msg(ERROR, "Failed to download %s.\n", pkg->name);
543 opkg_msg(NOTICE, "Downloaded %s as %s.\n",
544 pkg->name, pkg->local_filename);
553 opkg_list_cmd(int argc, char **argv)
556 pkg_vec_t *available;
558 char *pkg_name = NULL;
563 available = pkg_vec_alloc();
564 pkg_hash_fetch_available(available);
565 pkg_vec_sort(available, pkg_compare_names);
566 for (i=0; i < available->len; i++) {
567 pkg = available->pkgs[i];
568 /* if we have package name or pattern and pkg does not match, then skip it */
569 if (pkg_name && fnmatch(pkg_name, pkg->name, 0))
573 pkg_vec_free(available);
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, 0))
601 pkg_vec_free(available);
607 opkg_list_upgradable_cmd(int argc, char **argv)
609 struct active_list *head = prepare_upgrade_list();
610 struct active_list *node=NULL;
611 pkg_t *_old_pkg, *_new_pkg;
613 for (node = active_list_next(head, head); node;node = active_list_next(head,node)) {
614 _old_pkg = list_entry(node, pkg_t, list);
615 _new_pkg = pkg_hash_fetch_best_installation_candidate_by_name(_old_pkg->name);
616 if (_new_pkg == NULL)
618 old_v = pkg_version_str_alloc(_old_pkg);
619 new_v = pkg_version_str_alloc(_new_pkg);
620 printf("%s - %s - %s\n", _old_pkg->name, old_v, new_v);
624 active_list_head_delete(head);
629 opkg_info_status_cmd(int argc, char **argv, int installed_only)
632 pkg_vec_t *available;
634 char *pkg_name = NULL;
640 available = pkg_vec_alloc();
642 pkg_hash_fetch_all_installed(available);
644 pkg_hash_fetch_available(available);
646 for (i=0; i < available->len; i++) {
647 pkg = available->pkgs[i];
648 if (pkg_name && fnmatch(pkg_name, pkg->name, 0)) {
652 pkg_formatted_info(stdout, pkg);
654 if (conf->verbosity >= NOTICE) {
655 conffile_list_elt_t *iter;
656 for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
657 conffile_t *cf = (conffile_t *)iter->data;
658 int modified = conffile_has_been_modified(cf);
660 opkg_msg(INFO, "conffile=%s md5sum=%s modified=%d.\n",
661 cf->name, cf->value, modified);
665 pkg_vec_free(available);
671 opkg_info_cmd(int argc, char **argv)
673 return opkg_info_status_cmd(argc, argv, 0);
677 opkg_status_cmd(int argc, char **argv)
679 return opkg_info_status_cmd(argc, argv, 1);
683 opkg_configure_cmd(int argc, char **argv)
686 char *pkg_name = NULL;
691 err = opkg_configure_packages(pkg_name);
693 write_status_files_if_changed();
699 opkg_remove_cmd(int argc, char **argv)
703 pkg_t *pkg_to_remove;
704 pkg_vec_t *available;
708 signal(SIGINT, sigint_handler);
710 pkg_info_preinstall_check();
712 available = pkg_vec_alloc();
713 pkg_hash_fetch_all_installed(available);
715 for (i=0; i<argc; i++) {
716 for (a=0; a<available->len; a++) {
717 pkg = available->pkgs[a];
718 if (fnmatch(argv[i], pkg->name, 0)) {
721 if (conf->restrict_to_default_dest) {
722 pkg_to_remove = pkg_hash_fetch_installed_by_name_dest(
726 pkg_to_remove = pkg_hash_fetch_installed_by_name(pkg->name);
729 if (pkg_to_remove == NULL) {
730 opkg_msg(ERROR, "Package %s is not installed.\n", pkg->name);
733 if (pkg->state_status == SS_NOT_INSTALLED) { // Added the control, so every already removed package could be skipped
734 opkg_msg(ERROR, "Package %s not installed.\n", pkg->name);
737 opkg_remove_pkg(pkg_to_remove, 0);
742 pkg_vec_free(available);
745 opkg_msg(NOTICE, "No packages removed.\n");
747 write_status_files_if_changed();
752 opkg_flag_cmd(int argc, char **argv)
756 const char *flags = argv[0];
758 signal(SIGINT, sigint_handler);
760 for (i=1; i < argc; i++) {
761 if (conf->restrict_to_default_dest) {
762 pkg = pkg_hash_fetch_installed_by_name_dest(argv[i],
765 pkg = pkg_hash_fetch_installed_by_name(argv[i]);
769 opkg_msg(ERROR, "Package %s is not installed.\n", argv[i]);
772 if (( strcmp(flags,"hold")==0)||( strcmp(flags,"noprune")==0)||
773 ( strcmp(flags,"user")==0)||( strcmp(flags,"ok")==0)) {
774 pkg->state_flag = pkg_state_flag_from_str(flags);
778 * Useful if a package is installed in an offline_root, and
779 * should be configured by opkg-cl configure at a later date.
781 if (( strcmp(flags,"installed")==0)||( strcmp(flags,"unpacked")==0)){
782 pkg->state_status = pkg_state_status_from_str(flags);
785 opkg_state_changed++;
786 opkg_msg(NOTICE, "Setting flags for package %s to %s.\n",
790 write_status_files_if_changed();
795 opkg_files_cmd(int argc, char **argv)
799 str_list_elt_t *iter;
806 pkg = pkg_hash_fetch_installed_by_name(argv[0]);
808 opkg_msg(ERROR, "Package %s not installed.\n", argv[0]);
812 files = pkg_get_installed_files(pkg);
813 pkg_version = pkg_version_str_alloc(pkg);
815 printf("Package %s (%s) is installed on %s and has the following files:\n",
816 pkg->name, pkg_version, pkg->dest->name);
818 for (iter=str_list_first(files); iter; iter=str_list_next(files, iter))
819 printf("%s\n", (char *)iter->data);
822 pkg_free_installed_files(pkg);
828 opkg_depends_cmd(int argc, char **argv)
832 pkg_vec_t *available_pkgs;
833 compound_depend_t *cdep;
837 pkg_info_preinstall_check();
839 available_pkgs = pkg_vec_alloc();
841 pkg_hash_fetch_available(available_pkgs);
843 pkg_hash_fetch_all_installed(available_pkgs);
845 for (i=0; i<argc; i++) {
846 for (j=0; j<available_pkgs->len; j++) {
847 pkg = available_pkgs->pkgs[j];
849 if (fnmatch(argv[i], pkg->name, 0) != 0)
852 depends_count = pkg->depends_count +
853 pkg->pre_depends_count +
854 pkg->recommends_count +
857 opkg_msg(NOTICE, "%s depends on:\n", pkg->name);
859 for (k=0; k<depends_count; k++) {
860 cdep = &pkg->depends[k];
862 if (cdep->type != DEPEND)
865 str = pkg_depend_str(pkg, k);
866 opkg_msg(NOTICE, "\t%s\n", str);
873 pkg_vec_free(available_pkgs);
878 pkg_mark_provides(pkg_t *pkg)
880 int provides_count = pkg->provides_count;
881 abstract_pkg_t **provides = pkg->provides;
883 pkg->parent->state_flag |= SF_MARKED;
884 for (i = 0; i < provides_count; i++) {
885 provides[i]->state_flag |= SF_MARKED;
890 enum what_field_type {
900 opkg_what_depends_conflicts_cmd(enum depend_type what_field_type, int recursive, int argc, char **argv)
902 depend_t *possibility;
903 compound_depend_t *cdep;
904 pkg_vec_t *available_pkgs;
908 const char *rel_str = NULL;
911 switch (what_field_type) {
912 case DEPEND: rel_str = "depends on"; break;
913 case CONFLICTS: rel_str = "conflicts with"; break;
914 case SUGGEST: rel_str = "suggests"; break;
915 case RECOMMEND: rel_str = "recommends"; break;
919 available_pkgs = pkg_vec_alloc();
922 pkg_hash_fetch_available(available_pkgs);
924 pkg_hash_fetch_all_installed(available_pkgs);
926 /* mark the root set */
927 pkg_vec_clear_marks(available_pkgs);
928 opkg_msg(NOTICE, "Root set:\n");
929 for (i = 0; i < argc; i++)
930 pkg_vec_mark_if_matches(available_pkgs, argv[i]);
932 for (i = 0; i < available_pkgs->len; i++) {
933 pkg = available_pkgs->pkgs[i];
934 if (pkg->state_flag & SF_MARKED) {
935 /* mark the parent (abstract) package */
936 pkg_mark_provides(pkg);
937 opkg_msg(NOTICE, " %s\n", pkg->name);
941 opkg_msg(NOTICE, "What %s root set\n", rel_str);
945 for (j=0; j<available_pkgs->len; j++) {
947 pkg = available_pkgs->pkgs[j];
948 count = ((what_field_type == CONFLICTS)
949 ? pkg->conflicts_count
950 : pkg->pre_depends_count +
952 pkg->recommends_count +
953 pkg->suggests_count);
955 /* skip this package if it is already marked */
956 if (pkg->parent->state_flag & SF_MARKED)
959 for (k=0; k<count; k++) {
960 cdep = (what_field_type == CONFLICTS)
964 if (what_field_type != cdep->type)
967 for (l=0; l<cdep->possibility_count; l++) {
968 possibility = cdep->possibilities[l];
970 if ((possibility->pkg->state_flag
975 /* mark the depending package so we
976 * won't visit it again */
977 pkg->state_flag |= SF_MARKED;
978 pkg_mark_provides(pkg);
981 ver = pkg_version_str_alloc(pkg);
982 opkg_msg(NOTICE, "\t%s %s\t%s %s",
986 possibility->pkg->name);
988 if (possibility->version) {
989 opkg_msg(NOTICE, " (%s%s)",
990 constraint_to_str(possibility->constraint),
991 possibility->version);
993 if (!pkg_dependence_satisfiable(possibility))
996 opkg_msg(NOTICE, "\n");
1003 } while (changed && recursive);
1005 pkg_vec_free(available_pkgs);
1011 opkg_whatdepends_recursively_cmd(int argc, char **argv)
1013 return opkg_what_depends_conflicts_cmd(DEPEND, 1, argc, argv);
1017 opkg_whatdepends_cmd(int argc, char **argv)
1019 return opkg_what_depends_conflicts_cmd(DEPEND, 0, argc, argv);
1023 opkg_whatsuggests_cmd(int argc, char **argv)
1025 return opkg_what_depends_conflicts_cmd(SUGGEST, 0, argc, argv);
1029 opkg_whatrecommends_cmd(int argc, char **argv)
1031 return opkg_what_depends_conflicts_cmd(RECOMMEND, 0, argc, argv);
1035 opkg_whatconflicts_cmd(int argc, char **argv)
1037 return opkg_what_depends_conflicts_cmd(CONFLICTS, 0, argc, argv);
1041 opkg_what_provides_replaces_cmd(enum what_field_type what_field_type, int argc, char **argv)
1045 pkg_vec_t *available_pkgs = pkg_vec_alloc();
1046 const char *rel_str = (what_field_type == WHATPROVIDES ? "provides" : "replaces");
1049 pkg_info_preinstall_check();
1051 if (conf->query_all)
1052 pkg_hash_fetch_available(available_pkgs);
1054 pkg_hash_fetch_all_installed(available_pkgs);
1055 for (i = 0; i < argc; i++) {
1056 const char *target = argv[i];
1059 opkg_msg(NOTICE, "What %s %s\n",
1061 for (j = 0; j < available_pkgs->len; j++) {
1062 pkg_t *pkg = available_pkgs->pkgs[j];
1064 int count = (what_field_type == WHATPROVIDES) ? pkg->provides_count : pkg->replaces_count;
1065 for (k = 0; k < count; k++) {
1066 abstract_pkg_t *apkg =
1067 ((what_field_type == WHATPROVIDES)
1069 : pkg->replaces[k]);
1070 if (fnmatch(target, apkg->name, 0) == 0) {
1071 opkg_msg(NOTICE, " %s", pkg->name);
1072 if (strcmp(target, apkg->name) != 0)
1073 opkg_msg(NOTICE, "\t%s %s\n",
1074 rel_str, apkg->name);
1075 opkg_msg(NOTICE, "\n");
1080 pkg_vec_free(available_pkgs);
1086 opkg_whatprovides_cmd(int argc, char **argv)
1088 return opkg_what_provides_replaces_cmd(WHATPROVIDES, argc, argv);
1092 opkg_whatreplaces_cmd(int argc, char **argv)
1094 return opkg_what_provides_replaces_cmd(WHATREPLACES, argc, argv);
1098 opkg_search_cmd(int argc, char **argv)
1102 pkg_vec_t *installed;
1104 str_list_t *installed_files;
1105 str_list_elt_t *iter;
1106 char *installed_file;
1112 installed = pkg_vec_alloc();
1113 pkg_hash_fetch_all_installed(installed);
1114 pkg_vec_sort(installed, pkg_compare_names);
1116 for (i=0; i < installed->len; i++) {
1117 pkg = installed->pkgs[i];
1119 installed_files = pkg_get_installed_files(pkg);
1121 for (iter = str_list_first(installed_files); iter; iter = str_list_next(installed_files, iter)) {
1122 installed_file = (char *)iter->data;
1123 if (fnmatch(argv[0], installed_file, 0)==0)
1127 pkg_free_installed_files(pkg);
1130 pkg_vec_free(installed);
1136 opkg_compare_versions_cmd(int argc, char **argv)
1139 /* this is a bit gross */
1141 parse_version(&p1, argv[0]);
1142 parse_version(&p2, argv[2]);
1143 return pkg_version_satisfied(&p1, &p2, argv[1]);
1146 "opkg compare_versions <v1> <op> <v2>\n"
1147 "<op> is one of <= >= << >> =\n");
1153 opkg_print_architecture_cmd(int argc, char **argv)
1155 nv_pair_list_elt_t *l;
1157 list_for_each_entry(l, &conf->arch_list.head, node) {
1158 nv_pair_t *nv = (nv_pair_t *)l->data;
1159 printf("arch %s %s\n", nv->name, nv->value);
1165 /* XXX: CLEANUP: The usage strings should be incorporated into this
1166 array for easier maintenance */
1167 static opkg_cmd_t cmds[] = {
1168 {"update", 0, (opkg_cmd_fun_t)opkg_update_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1169 {"upgrade", 0, (opkg_cmd_fun_t)opkg_upgrade_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1170 {"list", 0, (opkg_cmd_fun_t)opkg_list_cmd, PFM_SOURCE},
1171 {"list_installed", 0, (opkg_cmd_fun_t)opkg_list_installed_cmd, PFM_SOURCE},
1172 {"list-installed", 0, (opkg_cmd_fun_t)opkg_list_installed_cmd, PFM_SOURCE},
1173 {"list_upgradable", 0, (opkg_cmd_fun_t)opkg_list_upgradable_cmd, PFM_SOURCE},
1174 {"list-upgradable", 0, (opkg_cmd_fun_t)opkg_list_upgradable_cmd, PFM_SOURCE},
1175 {"info", 0, (opkg_cmd_fun_t)opkg_info_cmd, 0},
1176 {"flag", 1, (opkg_cmd_fun_t)opkg_flag_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1177 {"status", 0, (opkg_cmd_fun_t)opkg_status_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1178 {"install", 1, (opkg_cmd_fun_t)opkg_install_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1179 {"remove", 1, (opkg_cmd_fun_t)opkg_remove_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1180 {"configure", 0, (opkg_cmd_fun_t)opkg_configure_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1181 {"files", 1, (opkg_cmd_fun_t)opkg_files_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1182 {"search", 1, (opkg_cmd_fun_t)opkg_search_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1183 {"download", 1, (opkg_cmd_fun_t)opkg_download_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1184 {"compare_versions", 1, (opkg_cmd_fun_t)opkg_compare_versions_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1185 {"compare-versions", 1, (opkg_cmd_fun_t)opkg_compare_versions_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1186 {"print-architecture", 0, (opkg_cmd_fun_t)opkg_print_architecture_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1187 {"print_architecture", 0, (opkg_cmd_fun_t)opkg_print_architecture_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1188 {"print-installation-architecture", 0, (opkg_cmd_fun_t)opkg_print_architecture_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1189 {"print_installation_architecture", 0, (opkg_cmd_fun_t)opkg_print_architecture_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1190 {"depends", 1, (opkg_cmd_fun_t)opkg_depends_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1191 {"whatdepends", 1, (opkg_cmd_fun_t)opkg_whatdepends_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1192 {"whatdependsrec", 1, (opkg_cmd_fun_t)opkg_whatdepends_recursively_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1193 {"whatrecommends", 1, (opkg_cmd_fun_t)opkg_whatrecommends_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1194 {"whatsuggests", 1, (opkg_cmd_fun_t)opkg_whatsuggests_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1195 {"whatprovides", 1, (opkg_cmd_fun_t)opkg_whatprovides_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1196 {"whatreplaces", 1, (opkg_cmd_fun_t)opkg_whatreplaces_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1197 {"whatconflicts", 1, (opkg_cmd_fun_t)opkg_whatconflicts_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1201 opkg_cmd_find(const char *name)
1205 int num_cmds = sizeof(cmds) / sizeof(opkg_cmd_t);
1207 for (i=0; i < num_cmds; i++) {
1209 if (strcmp(name, cmd->name) == 0)
1217 opkg_cmd_exec(opkg_cmd_t *cmd, int argc, const char **argv)
1219 return (cmd->fun)(argc, argv);