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.
25 #include "opkg_conf.h"
27 #include "opkg_message.h"
30 #include "pkg_parse.h"
31 #include "sprintf_alloc.h"
33 #include "file_util.h"
34 #include "libbb/libbb.h"
35 #include "opkg_utils.h"
36 #include "opkg_defines.h"
37 #include "opkg_download.h"
38 #include "opkg_install.h"
39 #include "opkg_upgrade.h"
40 #include "opkg_remove.h"
41 #include "opkg_configure.h"
47 char *version = pkg_version_str_alloc(pkg);
49 printf("%s - %s - %s\n", pkg->name, version, pkg->description);
51 printf("%s - %s\n", pkg->name, version);
55 int opkg_state_changed;
58 write_status_files_if_changed(void)
60 if (opkg_state_changed && !conf->noaction) {
61 opkg_msg(INFO, "Writing status file.\n");
62 opkg_conf_write_status_files();
63 pkg_write_changed_filelists();
65 opkg_msg(DEBUG, "Nothing to be done.\n");
70 sigint_handler(int sig)
73 opkg_msg(NOTICE, "Interrupted. Writing out status database.\n");
74 write_status_files_if_changed();
79 opkg_update_cmd(int argc, char **argv)
85 pkg_src_list_elt_t *iter;
89 sprintf_alloc(&lists_dir, "%s", conf->restrict_to_default_dest ? conf->default_dest->lists_dir : conf->lists_dir);
91 if (! file_is_dir(lists_dir)) {
92 if (file_exists(lists_dir)) {
93 opkg_msg(ERROR, "%s exists, but is not a directory.\n",
98 err = file_mkdir_hier(lists_dir, 0755);
107 sprintf_alloc(&tmp, "%s/update-XXXXXX", conf->tmp_dir);
108 if (mkdtemp (tmp) == NULL) {
109 opkg_perror(ERROR, "Failed to make temp dir %s", conf->tmp_dir);
114 for (iter = void_list_first(&conf->pkg_src_list); iter; iter = void_list_next(&conf->pkg_src_list, iter)) {
115 char *url, *list_file_name;
117 src = (pkg_src_t *)iter->data;
119 if (src->extra_data) /* debian style? */
120 sprintf_alloc(&url, "%s/%s/%s", src->value, src->extra_data,
121 src->gzip ? "Packages.gz" : "Packages");
123 sprintf_alloc(&url, "%s/%s", src->value, src->gzip ? "Packages.gz" : "Packages");
125 sprintf_alloc(&list_file_name, "%s/%s", lists_dir, src->name);
130 sprintf_alloc (&tmp_file_name, "%s/%s.gz", tmp, src->name);
131 err = opkg_download(url, tmp_file_name, NULL, NULL);
133 opkg_msg(NOTICE, "Inflating %s.\n", url);
134 in = fopen (tmp_file_name, "r");
135 out = fopen (list_file_name, "w");
144 unlink (tmp_file_name);
148 err = opkg_download(url, list_file_name, NULL, NULL);
152 opkg_msg(NOTICE, "Updated list of available packages in %s.\n",
156 #if defined(HAVE_GPGME) || defined(HAVE_OPENSSL)
157 if (conf->check_signature) {
158 /* download detached signitures to verify the package lists */
159 /* get the url for the sig file */
160 if (src->extra_data) /* debian style? */
161 sprintf_alloc(&url, "%s/%s/%s", src->value, src->extra_data,
164 sprintf_alloc(&url, "%s/%s", src->value, "Packages.sig");
166 /* create temporary file for it */
169 /* Put the signature in the right place */
170 sprintf_alloc (&tmp_file_name, "%s/%s.sig", lists_dir, src->name);
172 err = opkg_download(url, tmp_file_name, NULL, NULL);
175 opkg_msg(NOTICE, "Signature check failed.\n");
177 err = opkg_verify_file (list_file_name, tmp_file_name);
179 opkg_msg(NOTICE, "Signature check passed.\n");
181 opkg_msg(NOTICE, "Signature check failed.\n");
183 /* We shouldn't unlink the signature ! */
184 // unlink (tmp_file_name);
185 free (tmp_file_name);
191 free(list_file_name);
201 struct opkg_intercept
207 typedef struct opkg_intercept *opkg_intercept_t;
209 static opkg_intercept_t
210 opkg_prep_intercepts(void)
212 opkg_intercept_t ctx;
215 ctx = xcalloc(1, sizeof (*ctx));
216 ctx->oldpath = xstrdup(getenv("PATH"));
217 sprintf_alloc(&newpath, "%s/opkg/intercept:%s", DATADIR, ctx->oldpath);
218 sprintf_alloc(&ctx->statedir, "%s/opkg-intercept-XXXXXX", conf->tmp_dir);
220 if (mkdtemp(ctx->statedir) == NULL) {
221 opkg_perror(ERROR,"Failed to make temp dir %s", ctx->statedir);
229 setenv("OPKG_INTERCEPT_DIR", ctx->statedir, 1);
230 setenv("PATH", newpath, 1);
237 opkg_finalize_intercepts(opkg_intercept_t ctx)
242 setenv ("PATH", ctx->oldpath, 1);
245 dir = opendir (ctx->statedir);
248 while (de = readdir (dir), de != NULL) {
251 if (de->d_name[0] == '.')
254 sprintf_alloc (&path, "%s/%s", ctx->statedir, de->d_name);
255 if (access (path, X_OK) == 0) {
256 const char *argv[] = {"sh", "-c", path, NULL};
263 opkg_perror(ERROR, "Failed to open dir %s", ctx->statedir);
266 free (ctx->statedir);
272 /* For package pkg do the following: If it is already visited, return. If not,
273 add it in visited list and recurse to its deps. Finally, add it to ordered
275 pkg_vec all contains all available packages in repos.
276 pkg_vec visited contains packages already visited by this function, and is
277 used to end recursion and avoid an infinite loop on graph cycles.
278 pkg_vec ordered will finally contain the ordered set of packages.
281 opkg_recurse_pkgs_in_order(pkg_t *pkg, pkg_vec_t *all,
282 pkg_vec_t *visited, pkg_vec_t *ordered)
287 compound_depend_t * compound_depend;
288 depend_t ** possible_satisfiers;
289 abstract_pkg_t *abpkg;
290 abstract_pkg_t **dependents;
292 /* If it's just an available package, that is, not installed and not even
294 /* XXX: This is probably an overkill, since a state_status != SS_UNPACKED
295 would do here. However, if there is an intermediate node (pkg) that is
296 configured and installed between two unpacked packages, the latter
297 won't be properly reordered, unless all installed/unpacked pkgs are
299 if (pkg->state_status == SS_NOT_INSTALLED)
302 /* If the package has already been visited (by this function), skip it */
303 for(j = 0; j < visited->len; j++)
304 if ( ! strcmp(visited->pkgs[j]->name, pkg->name)) {
305 opkg_msg(DEBUG, "pkg %s already visited, skipping.\n", pkg->name);
309 pkg_vec_insert(visited, pkg);
311 count = pkg->pre_depends_count + pkg->depends_count + \
312 pkg->recommends_count + pkg->suggests_count;
314 opkg_msg(DEBUG, "pkg %s.\n", pkg->name);
316 /* Iterate over all the dependencies of pkg. For each one, find a package
317 that is either installed or unpacked and satisfies this dependency.
318 (there should only be one such package per dependency installed or
319 unpacked). Then recurse to the dependency package */
320 for (j=0; j < count ; j++) {
321 compound_depend = &pkg->depends[j];
322 possible_satisfiers = compound_depend->possibilities;
323 for (k=0; k < compound_depend->possibility_count ; k++) {
324 abpkg = possible_satisfiers[k]->pkg;
325 dependents = abpkg->provided_by->pkgs;
327 if (dependents != NULL)
328 while (l < abpkg->provided_by->len && dependents[l] != NULL) {
329 opkg_msg(DEBUG, "Descending on pkg %s.\n",
330 dependents [l]->name);
332 /* find whether dependent l is installed or unpacked,
333 * and then find which package in the list satisfies it */
334 for(m = 0; m < all->len; m++) {
336 if ( dep->state_status != SS_NOT_INSTALLED)
337 if ( ! strcmp(dep->name, dependents[l]->name)) {
338 opkg_recurse_pkgs_in_order(dep, all,
340 /* Stop the outer loop */
341 l = abpkg->provided_by->len;
342 /* break from the inner loop */
351 /* When all recursions from this node down, are over, and all
352 dependencies have been added in proper order in the ordered array, add
353 also the package pkg to ordered array */
354 pkg_vec_insert(ordered, pkg);
361 opkg_configure_packages(char *pkg_name)
363 pkg_vec_t *all, *ordered, *visited;
369 opkg_msg(INFO, "Configuring unpacked packages.\n");
371 all = pkg_vec_alloc();
373 pkg_hash_fetch_available(all);
375 /* Reorder pkgs in order to be configured according to the Depends: tag
377 opkg_msg(INFO, "Reordering packages before configuring them...\n");
378 ordered = pkg_vec_alloc();
379 visited = pkg_vec_alloc();
380 for(i = 0; i < all->len; i++) {
382 opkg_recurse_pkgs_in_order(pkg, all, visited, ordered);
385 ic = opkg_prep_intercepts();
391 for(i = 0; i < all->len; i++) {
394 if (pkg_name && fnmatch(pkg_name, pkg->name, 0))
397 if (pkg->state_status == SS_UNPACKED) {
398 opkg_msg(NOTICE, "Configuring %s.\n", pkg->name);
399 r = opkg_configure(pkg);
401 pkg->state_status = SS_INSTALLED;
402 pkg->parent->state_status = SS_INSTALLED;
403 pkg->state_flag &= ~SF_PREFER;
404 opkg_state_changed++;
412 r = opkg_finalize_intercepts (ic);
418 pkg_vec_free(ordered);
419 pkg_vec_free(visited);
425 opkg_install_cmd(int argc, char **argv)
431 signal(SIGINT, sigint_handler);
434 * Now scan through package names and install
436 for (i=0; i < argc; i++) {
439 opkg_msg(DEBUG2, "%s\n", arg);
440 err = opkg_prepare_url_for_install(arg, &argv[i]);
444 pkg_info_preinstall_check();
446 for (i=0; i < argc; i++) {
448 err = opkg_install_by_name(arg);
450 opkg_msg(ERROR, "Cannot install package %s.\n", arg);
454 opkg_configure_packages(NULL);
456 write_status_files_if_changed();
462 opkg_upgrade_cmd(int argc, char **argv)
468 signal(SIGINT, sigint_handler);
471 for (i=0; i < argc; i++) {
474 err = opkg_prepare_url_for_install(arg, &arg);
478 pkg_info_preinstall_check();
480 for (i=0; i < argc; i++) {
482 if (conf->restrict_to_default_dest) {
483 pkg = pkg_hash_fetch_installed_by_name_dest(argv[i],
486 opkg_msg(NOTICE, "Package %s not installed in %s.\n",
487 argv[i], conf->default_dest->name);
491 pkg = pkg_hash_fetch_installed_by_name(argv[i]);
494 opkg_upgrade_pkg(pkg);
496 opkg_install_by_name(arg);
500 pkg_vec_t *installed = pkg_vec_alloc();
502 pkg_info_preinstall_check();
504 pkg_hash_fetch_all_installed(installed);
505 for (i = 0; i < installed->len; i++) {
506 pkg = installed->pkgs[i];
507 opkg_upgrade_pkg(pkg);
509 pkg_vec_free(installed);
512 opkg_configure_packages(NULL);
514 write_status_files_if_changed();
520 opkg_download_cmd(int argc, char **argv)
526 pkg_info_preinstall_check();
527 for (i = 0; i < argc; i++) {
530 pkg = pkg_hash_fetch_best_installation_candidate_by_name(arg);
532 opkg_msg(ERROR, "Cannot find package %s.\n", arg);
536 err = opkg_download_pkg(pkg, ".");
539 opkg_msg(ERROR, "Failed to download %s.\n", pkg->name);
541 opkg_msg(NOTICE, "Downloaded %s as %s.\n",
542 pkg->name, pkg->local_filename);
551 opkg_list_cmd(int argc, char **argv)
554 pkg_vec_t *available;
556 char *pkg_name = NULL;
561 available = pkg_vec_alloc();
562 pkg_hash_fetch_available(available);
563 pkg_vec_sort(available, pkg_compare_names);
564 for (i=0; i < available->len; i++) {
565 pkg = available->pkgs[i];
566 /* if we have package name or pattern and pkg does not match, then skip it */
567 if (pkg_name && fnmatch(pkg_name, pkg->name, 0))
571 pkg_vec_free(available);
578 opkg_list_installed_cmd(int argc, char **argv)
581 pkg_vec_t *available;
583 char *pkg_name = NULL;
588 available = pkg_vec_alloc();
589 pkg_hash_fetch_all_installed(available);
590 pkg_vec_sort(available, pkg_compare_names);
591 for (i=0; i < available->len; i++) {
592 pkg = available->pkgs[i];
593 /* if we have package name or pattern and pkg does not match, then skip it */
594 if (pkg_name && fnmatch(pkg_name, pkg->name, 0))
599 pkg_vec_free(available);
605 opkg_list_upgradable_cmd(int argc, char **argv)
607 struct active_list *head = prepare_upgrade_list();
608 struct active_list *node=NULL;
609 pkg_t *_old_pkg, *_new_pkg;
611 for (node = active_list_next(head, head); node;node = active_list_next(head,node)) {
612 _old_pkg = list_entry(node, pkg_t, list);
613 _new_pkg = pkg_hash_fetch_best_installation_candidate_by_name(_old_pkg->name);
614 if (_new_pkg == NULL)
616 old_v = pkg_version_str_alloc(_old_pkg);
617 new_v = pkg_version_str_alloc(_new_pkg);
618 printf("%s - %s - %s\n", _old_pkg->name, old_v, new_v);
622 active_list_head_delete(head);
627 opkg_info_status_cmd(int argc, char **argv, int installed_only)
630 pkg_vec_t *available;
632 char *pkg_name = NULL;
638 available = pkg_vec_alloc();
640 pkg_hash_fetch_all_installed(available);
642 pkg_hash_fetch_available(available);
644 for (i=0; i < available->len; i++) {
645 pkg = available->pkgs[i];
646 if (pkg_name && fnmatch(pkg_name, pkg->name, 0)) {
650 pkg_formatted_info(stdout, pkg);
652 if (conf->verbosity >= NOTICE) {
653 conffile_list_elt_t *iter;
654 for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
655 conffile_t *cf = (conffile_t *)iter->data;
656 int modified = conffile_has_been_modified(cf);
658 opkg_msg(INFO, "conffile=%s md5sum=%s modified=%d.\n",
659 cf->name, cf->value, modified);
663 pkg_vec_free(available);
669 opkg_info_cmd(int argc, char **argv)
671 return opkg_info_status_cmd(argc, argv, 0);
675 opkg_status_cmd(int argc, char **argv)
677 return opkg_info_status_cmd(argc, argv, 1);
681 opkg_configure_cmd(int argc, char **argv)
684 char *pkg_name = NULL;
689 err = opkg_configure_packages(pkg_name);
691 write_status_files_if_changed();
697 opkg_remove_cmd(int argc, char **argv)
701 pkg_t *pkg_to_remove;
702 pkg_vec_t *available;
706 signal(SIGINT, sigint_handler);
708 pkg_info_preinstall_check();
710 available = pkg_vec_alloc();
711 pkg_hash_fetch_all_installed(available);
713 for (i=0; i<argc; i++) {
714 for (a=0; a<available->len; a++) {
715 pkg = available->pkgs[a];
716 if (fnmatch(argv[i], pkg->name, 0)) {
719 if (conf->restrict_to_default_dest) {
720 pkg_to_remove = pkg_hash_fetch_installed_by_name_dest(
724 pkg_to_remove = pkg_hash_fetch_installed_by_name(pkg->name);
727 if (pkg_to_remove == NULL) {
728 opkg_msg(ERROR, "Package %s is not installed.\n", pkg->name);
731 if (pkg->state_status == SS_NOT_INSTALLED) { // Added the control, so every already removed package could be skipped
732 opkg_msg(ERROR, "Package %s not installed.\n", pkg->name);
735 opkg_remove_pkg(pkg_to_remove, 0);
740 pkg_vec_free(available);
743 opkg_msg(NOTICE, "No packages removed.\n");
745 write_status_files_if_changed();
750 opkg_flag_cmd(int argc, char **argv)
754 const char *flags = argv[0];
756 signal(SIGINT, sigint_handler);
758 for (i=1; i < argc; i++) {
759 if (conf->restrict_to_default_dest) {
760 pkg = pkg_hash_fetch_installed_by_name_dest(argv[i],
763 pkg = pkg_hash_fetch_installed_by_name(argv[i]);
767 opkg_msg(ERROR, "Package %s is not installed.\n", argv[i]);
770 if (( strcmp(flags,"hold")==0)||( strcmp(flags,"noprune")==0)||
771 ( strcmp(flags,"user")==0)||( strcmp(flags,"ok")==0)) {
772 pkg->state_flag = pkg_state_flag_from_str(flags);
776 * Useful if a package is installed in an offline_root, and
777 * should be configured by opkg-cl configure at a later date.
779 if (( strcmp(flags,"installed")==0)||( strcmp(flags,"unpacked")==0)){
780 pkg->state_status = pkg_state_status_from_str(flags);
783 opkg_state_changed++;
784 opkg_msg(NOTICE, "Setting flags for package %s to %s.\n",
788 write_status_files_if_changed();
793 opkg_files_cmd(int argc, char **argv)
797 str_list_elt_t *iter;
804 pkg = pkg_hash_fetch_installed_by_name(argv[0]);
806 opkg_msg(ERROR, "Package %s not installed.\n", argv[0]);
810 files = pkg_get_installed_files(pkg);
811 pkg_version = pkg_version_str_alloc(pkg);
813 printf("Package %s (%s) is installed on %s and has the following files:\n",
814 pkg->name, pkg_version, pkg->dest->name);
816 for (iter=str_list_first(files); iter; iter=str_list_next(files, iter))
817 printf("%s\n", (char *)iter->data);
820 pkg_free_installed_files(pkg);
826 opkg_depends_cmd(int argc, char **argv)
830 pkg_vec_t *available_pkgs;
831 compound_depend_t *cdep;
835 pkg_info_preinstall_check();
837 available_pkgs = pkg_vec_alloc();
839 pkg_hash_fetch_available(available_pkgs);
841 pkg_hash_fetch_all_installed(available_pkgs);
843 for (i=0; i<argc; i++) {
844 for (j=0; j<available_pkgs->len; j++) {
845 pkg = available_pkgs->pkgs[j];
847 if (fnmatch(argv[i], pkg->name, 0) != 0)
850 depends_count = pkg->depends_count +
851 pkg->pre_depends_count +
852 pkg->recommends_count +
855 opkg_msg(NOTICE, "%s depends on:\n", pkg->name);
857 for (k=0; k<depends_count; k++) {
858 cdep = &pkg->depends[k];
860 if (cdep->type != DEPEND)
863 str = pkg_depend_str(pkg, k);
864 opkg_msg(NOTICE, "\t%s\n", str);
871 pkg_vec_free(available_pkgs);
876 pkg_mark_provides(pkg_t *pkg)
878 int provides_count = pkg->provides_count;
879 abstract_pkg_t **provides = pkg->provides;
881 pkg->parent->state_flag |= SF_MARKED;
882 for (i = 0; i < provides_count; i++) {
883 provides[i]->state_flag |= SF_MARKED;
888 enum what_field_type {
898 opkg_what_depends_conflicts_cmd(enum depend_type what_field_type, int recursive, int argc, char **argv)
900 depend_t *possibility;
901 compound_depend_t *cdep;
902 pkg_vec_t *available_pkgs;
906 const char *rel_str = NULL;
909 switch (what_field_type) {
910 case DEPEND: rel_str = "depends on"; break;
911 case CONFLICTS: rel_str = "conflicts with"; break;
912 case SUGGEST: rel_str = "suggests"; break;
913 case RECOMMEND: rel_str = "recommends"; break;
917 available_pkgs = pkg_vec_alloc();
920 pkg_hash_fetch_available(available_pkgs);
922 pkg_hash_fetch_all_installed(available_pkgs);
924 /* mark the root set */
925 pkg_vec_clear_marks(available_pkgs);
926 opkg_msg(NOTICE, "Root set:\n");
927 for (i = 0; i < argc; i++)
928 pkg_vec_mark_if_matches(available_pkgs, argv[i]);
930 for (i = 0; i < available_pkgs->len; i++) {
931 pkg = available_pkgs->pkgs[i];
932 if (pkg->state_flag & SF_MARKED) {
933 /* mark the parent (abstract) package */
934 pkg_mark_provides(pkg);
935 opkg_msg(NOTICE, " %s\n", pkg->name);
939 opkg_msg(NOTICE, "What %s root set\n", rel_str);
943 for (j=0; j<available_pkgs->len; j++) {
945 pkg = available_pkgs->pkgs[j];
946 count = ((what_field_type == CONFLICTS)
947 ? pkg->conflicts_count
948 : pkg->pre_depends_count +
950 pkg->recommends_count +
951 pkg->suggests_count);
953 /* skip this package if it is already marked */
954 if (pkg->parent->state_flag & SF_MARKED)
957 for (k=0; k<count; k++) {
958 cdep = (what_field_type == CONFLICTS)
962 if (what_field_type != cdep->type)
965 for (l=0; l<cdep->possibility_count; l++) {
966 possibility = cdep->possibilities[l];
968 if ((possibility->pkg->state_flag
973 /* mark the depending package so we
974 * won't visit it again */
975 pkg->state_flag |= SF_MARKED;
976 pkg_mark_provides(pkg);
979 ver = pkg_version_str_alloc(pkg);
980 opkg_msg(NOTICE, "\t%s %s\t%s %s",
984 possibility->pkg->name);
986 if (possibility->version) {
987 opkg_msg(NOTICE, " (%s%s)",
988 constraint_to_str(possibility->constraint),
989 possibility->version);
991 if (!pkg_dependence_satisfiable(possibility))
994 opkg_msg(NOTICE, "\n");
1001 } while (changed && recursive);
1003 pkg_vec_free(available_pkgs);
1009 opkg_whatdepends_recursively_cmd(int argc, char **argv)
1011 return opkg_what_depends_conflicts_cmd(DEPEND, 1, argc, argv);
1015 opkg_whatdepends_cmd(int argc, char **argv)
1017 return opkg_what_depends_conflicts_cmd(DEPEND, 0, argc, argv);
1021 opkg_whatsuggests_cmd(int argc, char **argv)
1023 return opkg_what_depends_conflicts_cmd(SUGGEST, 0, argc, argv);
1027 opkg_whatrecommends_cmd(int argc, char **argv)
1029 return opkg_what_depends_conflicts_cmd(RECOMMEND, 0, argc, argv);
1033 opkg_whatconflicts_cmd(int argc, char **argv)
1035 return opkg_what_depends_conflicts_cmd(CONFLICTS, 0, argc, argv);
1039 opkg_what_provides_replaces_cmd(enum what_field_type what_field_type, int argc, char **argv)
1043 pkg_vec_t *available_pkgs = pkg_vec_alloc();
1044 const char *rel_str = (what_field_type == WHATPROVIDES ? "provides" : "replaces");
1047 pkg_info_preinstall_check();
1049 if (conf->query_all)
1050 pkg_hash_fetch_available(available_pkgs);
1052 pkg_hash_fetch_all_installed(available_pkgs);
1053 for (i = 0; i < argc; i++) {
1054 const char *target = argv[i];
1057 opkg_msg(NOTICE, "What %s %s\n",
1059 for (j = 0; j < available_pkgs->len; j++) {
1060 pkg_t *pkg = available_pkgs->pkgs[j];
1062 int count = (what_field_type == WHATPROVIDES) ? pkg->provides_count : pkg->replaces_count;
1063 for (k = 0; k < count; k++) {
1064 abstract_pkg_t *apkg =
1065 ((what_field_type == WHATPROVIDES)
1067 : pkg->replaces[k]);
1068 if (fnmatch(target, apkg->name, 0) == 0) {
1069 opkg_msg(NOTICE, " %s", pkg->name);
1070 if (strcmp(target, apkg->name) != 0)
1071 opkg_msg(NOTICE, "\t%s %s\n",
1072 rel_str, apkg->name);
1073 opkg_msg(NOTICE, "\n");
1078 pkg_vec_free(available_pkgs);
1084 opkg_whatprovides_cmd(int argc, char **argv)
1086 return opkg_what_provides_replaces_cmd(WHATPROVIDES, argc, argv);
1090 opkg_whatreplaces_cmd(int argc, char **argv)
1092 return opkg_what_provides_replaces_cmd(WHATREPLACES, argc, argv);
1096 opkg_search_cmd(int argc, char **argv)
1100 pkg_vec_t *installed;
1102 str_list_t *installed_files;
1103 str_list_elt_t *iter;
1104 char *installed_file;
1110 installed = pkg_vec_alloc();
1111 pkg_hash_fetch_all_installed(installed);
1112 pkg_vec_sort(installed, pkg_compare_names);
1114 for (i=0; i < installed->len; i++) {
1115 pkg = installed->pkgs[i];
1117 installed_files = pkg_get_installed_files(pkg);
1119 for (iter = str_list_first(installed_files); iter; iter = str_list_next(installed_files, iter)) {
1120 installed_file = (char *)iter->data;
1121 if (fnmatch(argv[0], installed_file, 0)==0)
1125 pkg_free_installed_files(pkg);
1128 pkg_vec_free(installed);
1134 opkg_compare_versions_cmd(int argc, char **argv)
1137 /* this is a bit gross */
1139 parse_version(&p1, argv[0]);
1140 parse_version(&p2, argv[2]);
1141 return pkg_version_satisfied(&p1, &p2, argv[1]);
1144 "opkg compare_versions <v1> <op> <v2>\n"
1145 "<op> is one of <= >= << >> =\n");
1151 opkg_print_architecture_cmd(int argc, char **argv)
1153 nv_pair_list_elt_t *l;
1155 list_for_each_entry(l, &conf->arch_list.head, node) {
1156 nv_pair_t *nv = (nv_pair_t *)l->data;
1157 printf("arch %s %s\n", nv->name, nv->value);
1163 /* XXX: CLEANUP: The usage strings should be incorporated into this
1164 array for easier maintenance */
1165 static opkg_cmd_t cmds[] = {
1166 {"update", 0, (opkg_cmd_fun_t)opkg_update_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1167 {"upgrade", 0, (opkg_cmd_fun_t)opkg_upgrade_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1168 {"list", 0, (opkg_cmd_fun_t)opkg_list_cmd, PFM_SOURCE},
1169 {"list_installed", 0, (opkg_cmd_fun_t)opkg_list_installed_cmd, PFM_SOURCE},
1170 {"list-installed", 0, (opkg_cmd_fun_t)opkg_list_installed_cmd, PFM_SOURCE},
1171 {"list_upgradable", 0, (opkg_cmd_fun_t)opkg_list_upgradable_cmd, PFM_SOURCE},
1172 {"list-upgradable", 0, (opkg_cmd_fun_t)opkg_list_upgradable_cmd, PFM_SOURCE},
1173 {"info", 0, (opkg_cmd_fun_t)opkg_info_cmd, 0},
1174 {"flag", 1, (opkg_cmd_fun_t)opkg_flag_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1175 {"status", 0, (opkg_cmd_fun_t)opkg_status_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1176 {"install", 1, (opkg_cmd_fun_t)opkg_install_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1177 {"remove", 1, (opkg_cmd_fun_t)opkg_remove_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1178 {"configure", 0, (opkg_cmd_fun_t)opkg_configure_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1179 {"files", 1, (opkg_cmd_fun_t)opkg_files_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1180 {"search", 1, (opkg_cmd_fun_t)opkg_search_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1181 {"download", 1, (opkg_cmd_fun_t)opkg_download_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1182 {"compare_versions", 1, (opkg_cmd_fun_t)opkg_compare_versions_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1183 {"compare-versions", 1, (opkg_cmd_fun_t)opkg_compare_versions_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1184 {"print-architecture", 0, (opkg_cmd_fun_t)opkg_print_architecture_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1185 {"print_architecture", 0, (opkg_cmd_fun_t)opkg_print_architecture_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1186 {"print-installation-architecture", 0, (opkg_cmd_fun_t)opkg_print_architecture_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1187 {"print_installation_architecture", 0, (opkg_cmd_fun_t)opkg_print_architecture_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1188 {"depends", 1, (opkg_cmd_fun_t)opkg_depends_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1189 {"whatdepends", 1, (opkg_cmd_fun_t)opkg_whatdepends_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1190 {"whatdependsrec", 1, (opkg_cmd_fun_t)opkg_whatdepends_recursively_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1191 {"whatrecommends", 1, (opkg_cmd_fun_t)opkg_whatrecommends_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1192 {"whatsuggests", 1, (opkg_cmd_fun_t)opkg_whatsuggests_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1193 {"whatprovides", 1, (opkg_cmd_fun_t)opkg_whatprovides_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1194 {"whatreplaces", 1, (opkg_cmd_fun_t)opkg_whatreplaces_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1195 {"whatconflicts", 1, (opkg_cmd_fun_t)opkg_whatconflicts_cmd, PFM_DESCRIPTION|PFM_SOURCE},
1199 opkg_cmd_find(const char *name)
1203 int num_cmds = sizeof(cmds) / sizeof(opkg_cmd_t);
1205 for (i=0; i < num_cmds; i++) {
1207 if (strcmp(name, cmd->name) == 0)
1215 opkg_cmd_exec(opkg_cmd_t *cmd, int argc, const char **argv)
1217 return (cmd->fun)(argc, argv);