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
;
403 opkg_state_changed
++;
411 r
= opkg_finalize_intercepts (ic
);
417 pkg_vec_free(ordered
);
418 pkg_vec_free(visited
);
424 opkg_install_cmd(int argc
, char **argv
)
430 signal(SIGINT
, sigint_handler
);
433 * Now scan through package names and install
435 for (i
=0; i
< argc
; i
++) {
438 opkg_msg(DEBUG2
, "%s\n", arg
);
439 err
= opkg_prepare_url_for_install(arg
, &argv
[i
]);
443 pkg_info_preinstall_check();
445 for (i
=0; i
< argc
; i
++) {
447 err
= opkg_install_by_name(arg
);
449 opkg_msg(ERROR
, "Cannot install package %s.\n", arg
);
453 opkg_configure_packages(NULL
);
455 write_status_files_if_changed();
461 opkg_upgrade_cmd(int argc
, char **argv
)
467 signal(SIGINT
, sigint_handler
);
470 for (i
=0; i
< argc
; i
++) {
473 err
= opkg_prepare_url_for_install(arg
, &arg
);
477 pkg_info_preinstall_check();
479 for (i
=0; i
< argc
; i
++) {
481 if (conf
->restrict_to_default_dest
) {
482 pkg
= pkg_hash_fetch_installed_by_name_dest(argv
[i
],
485 opkg_msg(NOTICE
, "Package %s not installed in %s.\n",
486 argv
[i
], conf
->default_dest
->name
);
490 pkg
= pkg_hash_fetch_installed_by_name(argv
[i
]);
493 opkg_upgrade_pkg(pkg
);
495 opkg_install_by_name(arg
);
499 pkg_vec_t
*installed
= pkg_vec_alloc();
501 pkg_info_preinstall_check();
503 pkg_hash_fetch_all_installed(installed
);
504 for (i
= 0; i
< installed
->len
; i
++) {
505 pkg
= installed
->pkgs
[i
];
506 opkg_upgrade_pkg(pkg
);
508 pkg_vec_free(installed
);
511 opkg_configure_packages(NULL
);
513 write_status_files_if_changed();
519 opkg_download_cmd(int argc
, char **argv
)
525 pkg_info_preinstall_check();
526 for (i
= 0; i
< argc
; i
++) {
529 pkg
= pkg_hash_fetch_best_installation_candidate_by_name(arg
);
531 opkg_msg(ERROR
, "Cannot find package %s.\n", arg
);
535 err
= opkg_download_pkg(pkg
, ".");
538 opkg_msg(ERROR
, "Failed to download %s.\n", pkg
->name
);
540 opkg_msg(NOTICE
, "Downloaded %s as %s.\n",
541 pkg
->name
, pkg
->local_filename
);
550 opkg_list_cmd(int argc
, char **argv
)
553 pkg_vec_t
*available
;
555 char *pkg_name
= NULL
;
560 available
= pkg_vec_alloc();
561 pkg_hash_fetch_available(available
);
562 pkg_vec_sort(available
, pkg_compare_names
);
563 for (i
=0; i
< available
->len
; i
++) {
564 pkg
= available
->pkgs
[i
];
565 /* if we have package name or pattern and pkg does not match, then skip it */
566 if (pkg_name
&& fnmatch(pkg_name
, pkg
->name
, 0))
570 pkg_vec_free(available
);
577 opkg_list_installed_cmd(int argc
, char **argv
)
580 pkg_vec_t
*available
;
582 char *pkg_name
= NULL
;
587 available
= pkg_vec_alloc();
588 pkg_hash_fetch_all_installed(available
);
589 pkg_vec_sort(available
, pkg_compare_names
);
590 for (i
=0; i
< available
->len
; i
++) {
591 pkg
= available
->pkgs
[i
];
592 /* if we have package name or pattern and pkg does not match, then skip it */
593 if (pkg_name
&& fnmatch(pkg_name
, pkg
->name
, 0))
598 pkg_vec_free(available
);
604 opkg_list_upgradable_cmd(int argc
, char **argv
)
606 struct active_list
*head
= prepare_upgrade_list();
607 struct active_list
*node
=NULL
;
608 pkg_t
*_old_pkg
, *_new_pkg
;
610 for (node
= active_list_next(head
, head
); node
;node
= active_list_next(head
,node
)) {
611 _old_pkg
= list_entry(node
, pkg_t
, list
);
612 _new_pkg
= pkg_hash_fetch_best_installation_candidate_by_name(_old_pkg
->name
);
613 if (_new_pkg
== NULL
)
615 old_v
= pkg_version_str_alloc(_old_pkg
);
616 new_v
= pkg_version_str_alloc(_new_pkg
);
617 printf("%s - %s - %s\n", _old_pkg
->name
, old_v
, new_v
);
621 active_list_head_delete(head
);
626 opkg_info_status_cmd(int argc
, char **argv
, int installed_only
)
629 pkg_vec_t
*available
;
631 char *pkg_name
= NULL
;
637 available
= pkg_vec_alloc();
639 pkg_hash_fetch_all_installed(available
);
641 pkg_hash_fetch_available(available
);
643 for (i
=0; i
< available
->len
; i
++) {
644 pkg
= available
->pkgs
[i
];
645 if (pkg_name
&& fnmatch(pkg_name
, pkg
->name
, 0)) {
649 pkg_formatted_info(stdout
, pkg
);
651 if (conf
->verbosity
>= NOTICE
) {
652 conffile_list_elt_t
*iter
;
653 for (iter
= nv_pair_list_first(&pkg
->conffiles
); iter
; iter
= nv_pair_list_next(&pkg
->conffiles
, iter
)) {
654 conffile_t
*cf
= (conffile_t
*)iter
->data
;
655 int modified
= conffile_has_been_modified(cf
);
657 opkg_msg(INFO
, "conffile=%s md5sum=%s modified=%d.\n",
658 cf
->name
, cf
->value
, modified
);
662 pkg_vec_free(available
);
668 opkg_info_cmd(int argc
, char **argv
)
670 return opkg_info_status_cmd(argc
, argv
, 0);
674 opkg_status_cmd(int argc
, char **argv
)
676 return opkg_info_status_cmd(argc
, argv
, 1);
680 opkg_configure_cmd(int argc
, char **argv
)
683 char *pkg_name
= NULL
;
688 err
= opkg_configure_packages(pkg_name
);
690 write_status_files_if_changed();
696 opkg_remove_cmd(int argc
, char **argv
)
700 pkg_t
*pkg_to_remove
;
701 pkg_vec_t
*available
;
705 signal(SIGINT
, sigint_handler
);
707 pkg_info_preinstall_check();
709 available
= pkg_vec_alloc();
710 pkg_hash_fetch_all_installed(available
);
712 for (i
=0; i
<argc
; i
++) {
713 for (a
=0; a
<available
->len
; a
++) {
714 pkg
= available
->pkgs
[a
];
715 if (fnmatch(argv
[i
], pkg
->name
, 0)) {
718 if (conf
->restrict_to_default_dest
) {
719 pkg_to_remove
= pkg_hash_fetch_installed_by_name_dest(
723 pkg_to_remove
= pkg_hash_fetch_installed_by_name(pkg
->name
);
726 if (pkg_to_remove
== NULL
) {
727 opkg_msg(ERROR
, "Package %s is not installed.\n", pkg
->name
);
730 if (pkg
->state_status
== SS_NOT_INSTALLED
) { // Added the control, so every already removed package could be skipped
731 opkg_msg(ERROR
, "Package %s not installed.\n", pkg
->name
);
734 opkg_remove_pkg(pkg_to_remove
, 0);
739 pkg_vec_free(available
);
742 opkg_msg(NOTICE
, "No packages removed.\n");
744 write_status_files_if_changed();
749 opkg_flag_cmd(int argc
, char **argv
)
753 const char *flags
= argv
[0];
755 signal(SIGINT
, sigint_handler
);
757 for (i
=1; i
< argc
; i
++) {
758 if (conf
->restrict_to_default_dest
) {
759 pkg
= pkg_hash_fetch_installed_by_name_dest(argv
[i
],
762 pkg
= pkg_hash_fetch_installed_by_name(argv
[i
]);
766 opkg_msg(ERROR
, "Package %s is not installed.\n", argv
[i
]);
769 if (( strcmp(flags
,"hold")==0)||( strcmp(flags
,"noprune")==0)||
770 ( strcmp(flags
,"user")==0)||( strcmp(flags
,"ok")==0)) {
771 pkg
->state_flag
= pkg_state_flag_from_str(flags
);
775 * Useful if a package is installed in an offline_root, and
776 * should be configured by opkg-cl configure at a later date.
778 if (( strcmp(flags
,"installed")==0)||( strcmp(flags
,"unpacked")==0)){
779 pkg
->state_status
= pkg_state_status_from_str(flags
);
782 opkg_state_changed
++;
783 opkg_msg(NOTICE
, "Setting flags for package %s to %s.\n",
787 write_status_files_if_changed();
792 opkg_files_cmd(int argc
, char **argv
)
796 str_list_elt_t
*iter
;
803 pkg
= pkg_hash_fetch_installed_by_name(argv
[0]);
805 opkg_msg(ERROR
, "Package %s not installed.\n", argv
[0]);
809 files
= pkg_get_installed_files(pkg
);
810 pkg_version
= pkg_version_str_alloc(pkg
);
812 printf("Package %s (%s) is installed on %s and has the following files:\n",
813 pkg
->name
, pkg_version
, pkg
->dest
->name
);
815 for (iter
=str_list_first(files
); iter
; iter
=str_list_next(files
, iter
))
816 printf("%s\n", (char *)iter
->data
);
819 pkg_free_installed_files(pkg
);
825 opkg_depends_cmd(int argc
, char **argv
)
829 pkg_vec_t
*available_pkgs
;
830 compound_depend_t
*cdep
;
834 pkg_info_preinstall_check();
836 available_pkgs
= pkg_vec_alloc();
838 pkg_hash_fetch_available(available_pkgs
);
840 pkg_hash_fetch_all_installed(available_pkgs
);
842 for (i
=0; i
<argc
; i
++) {
843 for (j
=0; j
<available_pkgs
->len
; j
++) {
844 pkg
= available_pkgs
->pkgs
[j
];
846 if (fnmatch(argv
[i
], pkg
->name
, 0) != 0)
849 depends_count
= pkg
->depends_count
+
850 pkg
->pre_depends_count
+
851 pkg
->recommends_count
+
854 opkg_msg(NOTICE
, "%s depends on:\n", pkg
->name
);
856 for (k
=0; k
<depends_count
; k
++) {
857 cdep
= &pkg
->depends
[k
];
859 if (cdep
->type
!= DEPEND
)
862 str
= pkg_depend_str(pkg
, k
);
863 opkg_msg(NOTICE
, "\t%s\n", str
);
870 pkg_vec_free(available_pkgs
);
875 pkg_mark_provides(pkg_t
*pkg
)
877 int provides_count
= pkg
->provides_count
;
878 abstract_pkg_t
**provides
= pkg
->provides
;
880 pkg
->parent
->state_flag
|= SF_MARKED
;
881 for (i
= 0; i
< provides_count
; i
++) {
882 provides
[i
]->state_flag
|= SF_MARKED
;
887 enum what_field_type
{
897 opkg_what_depends_conflicts_cmd(enum depend_type what_field_type
, int recursive
, int argc
, char **argv
)
899 depend_t
*possibility
;
900 compound_depend_t
*cdep
;
901 pkg_vec_t
*available_pkgs
;
905 const char *rel_str
= NULL
;
908 switch (what_field_type
) {
909 case DEPEND
: rel_str
= "depends on"; break;
910 case CONFLICTS
: rel_str
= "conflicts with"; break;
911 case SUGGEST
: rel_str
= "suggests"; break;
912 case RECOMMEND
: rel_str
= "recommends"; break;
916 available_pkgs
= pkg_vec_alloc();
919 pkg_hash_fetch_available(available_pkgs
);
921 pkg_hash_fetch_all_installed(available_pkgs
);
923 /* mark the root set */
924 pkg_vec_clear_marks(available_pkgs
);
925 opkg_msg(NOTICE
, "Root set:\n");
926 for (i
= 0; i
< argc
; i
++)
927 pkg_vec_mark_if_matches(available_pkgs
, argv
[i
]);
929 for (i
= 0; i
< available_pkgs
->len
; i
++) {
930 pkg
= available_pkgs
->pkgs
[i
];
931 if (pkg
->state_flag
& SF_MARKED
) {
932 /* mark the parent (abstract) package */
933 pkg_mark_provides(pkg
);
934 opkg_msg(NOTICE
, " %s\n", pkg
->name
);
938 opkg_msg(NOTICE
, "What %s root set\n", rel_str
);
942 for (j
=0; j
<available_pkgs
->len
; j
++) {
944 pkg
= available_pkgs
->pkgs
[j
];
945 count
= ((what_field_type
== CONFLICTS
)
946 ? pkg
->conflicts_count
947 : pkg
->pre_depends_count
+
949 pkg
->recommends_count
+
950 pkg
->suggests_count
);
952 /* skip this package if it is already marked */
953 if (pkg
->parent
->state_flag
& SF_MARKED
)
956 for (k
=0; k
<count
; k
++) {
957 cdep
= (what_field_type
== CONFLICTS
)
961 if (what_field_type
!= cdep
->type
)
964 for (l
=0; l
<cdep
->possibility_count
; l
++) {
965 possibility
= cdep
->possibilities
[l
];
967 if ((possibility
->pkg
->state_flag
972 /* mark the depending package so we
973 * won't visit it again */
974 pkg
->state_flag
|= SF_MARKED
;
975 pkg_mark_provides(pkg
);
978 ver
= pkg_version_str_alloc(pkg
);
979 opkg_msg(NOTICE
, "\t%s %s\t%s %s",
983 possibility
->pkg
->name
);
985 if (possibility
->version
) {
986 opkg_msg(NOTICE
, " (%s%s)",
987 constraint_to_str(possibility
->constraint
),
988 possibility
->version
);
990 if (!pkg_dependence_satisfiable(possibility
))
993 opkg_msg(NOTICE
, "\n");
1000 } while (changed
&& recursive
);
1002 pkg_vec_free(available_pkgs
);
1008 opkg_whatdepends_recursively_cmd(int argc
, char **argv
)
1010 return opkg_what_depends_conflicts_cmd(DEPEND
, 1, argc
, argv
);
1014 opkg_whatdepends_cmd(int argc
, char **argv
)
1016 return opkg_what_depends_conflicts_cmd(DEPEND
, 0, argc
, argv
);
1020 opkg_whatsuggests_cmd(int argc
, char **argv
)
1022 return opkg_what_depends_conflicts_cmd(SUGGEST
, 0, argc
, argv
);
1026 opkg_whatrecommends_cmd(int argc
, char **argv
)
1028 return opkg_what_depends_conflicts_cmd(RECOMMEND
, 0, argc
, argv
);
1032 opkg_whatconflicts_cmd(int argc
, char **argv
)
1034 return opkg_what_depends_conflicts_cmd(CONFLICTS
, 0, argc
, argv
);
1038 opkg_what_provides_replaces_cmd(enum what_field_type what_field_type
, int argc
, char **argv
)
1042 pkg_vec_t
*available_pkgs
= pkg_vec_alloc();
1043 const char *rel_str
= (what_field_type
== WHATPROVIDES
? "provides" : "replaces");
1046 pkg_info_preinstall_check();
1048 if (conf
->query_all
)
1049 pkg_hash_fetch_available(available_pkgs
);
1051 pkg_hash_fetch_all_installed(available_pkgs
);
1052 for (i
= 0; i
< argc
; i
++) {
1053 const char *target
= argv
[i
];
1056 opkg_msg(NOTICE
, "What %s %s\n",
1058 for (j
= 0; j
< available_pkgs
->len
; j
++) {
1059 pkg_t
*pkg
= available_pkgs
->pkgs
[j
];
1061 int count
= (what_field_type
== WHATPROVIDES
) ? pkg
->provides_count
: pkg
->replaces_count
;
1062 for (k
= 0; k
< count
; k
++) {
1063 abstract_pkg_t
*apkg
=
1064 ((what_field_type
== WHATPROVIDES
)
1066 : pkg
->replaces
[k
]);
1067 if (fnmatch(target
, apkg
->name
, 0) == 0) {
1068 opkg_msg(NOTICE
, " %s", pkg
->name
);
1069 if (strcmp(target
, apkg
->name
) != 0)
1070 opkg_msg(NOTICE
, "\t%s %s\n",
1071 rel_str
, apkg
->name
);
1072 opkg_msg(NOTICE
, "\n");
1077 pkg_vec_free(available_pkgs
);
1083 opkg_whatprovides_cmd(int argc
, char **argv
)
1085 return opkg_what_provides_replaces_cmd(WHATPROVIDES
, argc
, argv
);
1089 opkg_whatreplaces_cmd(int argc
, char **argv
)
1091 return opkg_what_provides_replaces_cmd(WHATREPLACES
, argc
, argv
);
1095 opkg_search_cmd(int argc
, char **argv
)
1099 pkg_vec_t
*installed
;
1101 str_list_t
*installed_files
;
1102 str_list_elt_t
*iter
;
1103 char *installed_file
;
1109 installed
= pkg_vec_alloc();
1110 pkg_hash_fetch_all_installed(installed
);
1111 pkg_vec_sort(installed
, pkg_compare_names
);
1113 for (i
=0; i
< installed
->len
; i
++) {
1114 pkg
= installed
->pkgs
[i
];
1116 installed_files
= pkg_get_installed_files(pkg
);
1118 for (iter
= str_list_first(installed_files
); iter
; iter
= str_list_next(installed_files
, iter
)) {
1119 installed_file
= (char *)iter
->data
;
1120 if (fnmatch(argv
[0], installed_file
, 0)==0)
1124 pkg_free_installed_files(pkg
);
1127 pkg_vec_free(installed
);
1133 opkg_compare_versions_cmd(int argc
, char **argv
)
1136 /* this is a bit gross */
1138 parse_version(&p1
, argv
[0]);
1139 parse_version(&p2
, argv
[2]);
1140 return pkg_version_satisfied(&p1
, &p2
, argv
[1]);
1143 "opkg compare_versions <v1> <op> <v2>\n"
1144 "<op> is one of <= >= << >> =\n");
1150 opkg_print_architecture_cmd(int argc
, char **argv
)
1152 nv_pair_list_elt_t
*l
;
1154 list_for_each_entry(l
, &conf
->arch_list
.head
, node
) {
1155 nv_pair_t
*nv
= (nv_pair_t
*)l
->data
;
1156 printf("arch %s %s\n", nv
->name
, nv
->value
);
1162 /* XXX: CLEANUP: The usage strings should be incorporated into this
1163 array for easier maintenance */
1164 static opkg_cmd_t cmds
[] = {
1165 {"update", 0, (opkg_cmd_fun_t
)opkg_update_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1166 {"upgrade", 0, (opkg_cmd_fun_t
)opkg_upgrade_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1167 {"list", 0, (opkg_cmd_fun_t
)opkg_list_cmd
, PFM_SOURCE
},
1168 {"list_installed", 0, (opkg_cmd_fun_t
)opkg_list_installed_cmd
, PFM_SOURCE
},
1169 {"list-installed", 0, (opkg_cmd_fun_t
)opkg_list_installed_cmd
, PFM_SOURCE
},
1170 {"list_upgradable", 0, (opkg_cmd_fun_t
)opkg_list_upgradable_cmd
, PFM_SOURCE
},
1171 {"list-upgradable", 0, (opkg_cmd_fun_t
)opkg_list_upgradable_cmd
, PFM_SOURCE
},
1172 {"info", 0, (opkg_cmd_fun_t
)opkg_info_cmd
, 0},
1173 {"flag", 1, (opkg_cmd_fun_t
)opkg_flag_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1174 {"status", 0, (opkg_cmd_fun_t
)opkg_status_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1175 {"install", 1, (opkg_cmd_fun_t
)opkg_install_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1176 {"remove", 1, (opkg_cmd_fun_t
)opkg_remove_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1177 {"configure", 0, (opkg_cmd_fun_t
)opkg_configure_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1178 {"files", 1, (opkg_cmd_fun_t
)opkg_files_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1179 {"search", 1, (opkg_cmd_fun_t
)opkg_search_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1180 {"download", 1, (opkg_cmd_fun_t
)opkg_download_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1181 {"compare_versions", 1, (opkg_cmd_fun_t
)opkg_compare_versions_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1182 {"compare-versions", 1, (opkg_cmd_fun_t
)opkg_compare_versions_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1183 {"print-architecture", 0, (opkg_cmd_fun_t
)opkg_print_architecture_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1184 {"print_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 {"print_installation_architecture", 0, (opkg_cmd_fun_t
)opkg_print_architecture_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1187 {"depends", 1, (opkg_cmd_fun_t
)opkg_depends_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1188 {"whatdepends", 1, (opkg_cmd_fun_t
)opkg_whatdepends_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1189 {"whatdependsrec", 1, (opkg_cmd_fun_t
)opkg_whatdepends_recursively_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1190 {"whatrecommends", 1, (opkg_cmd_fun_t
)opkg_whatrecommends_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1191 {"whatsuggests", 1, (opkg_cmd_fun_t
)opkg_whatsuggests_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1192 {"whatprovides", 1, (opkg_cmd_fun_t
)opkg_whatprovides_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1193 {"whatreplaces", 1, (opkg_cmd_fun_t
)opkg_whatreplaces_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1194 {"whatconflicts", 1, (opkg_cmd_fun_t
)opkg_whatconflicts_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1198 opkg_cmd_find(const char *name
)
1202 int num_cmds
= sizeof(cmds
) / sizeof(opkg_cmd_t
);
1204 for (i
=0; i
< num_cmds
; i
++) {
1206 if (strcmp(name
, cmd
->name
) == 0)
1214 opkg_cmd_exec(opkg_cmd_t
*cmd
, int argc
, const char **argv
)
1216 return (cmd
->fun
)(argc
, argv
);