1 /* opkg_cmd.c - the opkg package management system
5 Copyright (C) 2001 University of Southern California
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2, or (at
10 your option) any later version.
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
27 #include "opkg_conf.h"
29 #include "opkg_message.h"
32 #include "pkg_parse.h"
33 #include "sprintf_alloc.h"
35 #include "file_util.h"
36 #include "libbb/libbb.h"
37 #include "opkg_utils.h"
38 #include "opkg_defines.h"
39 #include "opkg_download.h"
40 #include "opkg_install.h"
41 #include "opkg_upgrade.h"
42 #include "opkg_remove.h"
43 #include "opkg_configure.h"
49 char *version
= pkg_version_str_alloc(pkg
);
51 printf("%s - %s - %s\n", pkg
->name
, version
, pkg
->description
);
53 printf("%s - %s\n", pkg
->name
, version
);
57 int opkg_state_changed
;
60 write_status_files_if_changed(void)
62 if (opkg_state_changed
&& !conf
->noaction
) {
63 opkg_msg(INFO
, "Writing status file.\n");
64 opkg_conf_write_status_files();
65 pkg_write_changed_filelists();
67 opkg_msg(DEBUG
, "Nothing to be done.\n");
72 sigint_handler(int sig
)
75 opkg_msg(NOTICE
, "Interrupted. Writing out status database.\n");
76 write_status_files_if_changed();
81 opkg_update_cmd(int argc
, char **argv
)
87 pkg_src_list_elt_t
*iter
;
91 sprintf_alloc(&lists_dir
, "%s", conf
->restrict_to_default_dest
? conf
->default_dest
->lists_dir
: conf
->lists_dir
);
93 if (! file_is_dir(lists_dir
)) {
94 if (file_exists(lists_dir
)) {
95 opkg_msg(ERROR
, "%s exists, but is not a directory.\n",
100 err
= file_mkdir_hier(lists_dir
, 0755);
109 sprintf_alloc(&tmp
, "%s/update-XXXXXX", conf
->tmp_dir
);
110 if (mkdtemp (tmp
) == NULL
) {
111 opkg_perror(ERROR
, "Failed to make temp dir %s", conf
->tmp_dir
);
116 for (iter
= void_list_first(&conf
->pkg_src_list
); iter
; iter
= void_list_next(&conf
->pkg_src_list
, iter
)) {
117 char *url
, *list_file_name
;
119 src
= (pkg_src_t
*)iter
->data
;
121 if (src
->extra_data
) /* debian style? */
122 sprintf_alloc(&url
, "%s/%s/%s", src
->value
, src
->extra_data
,
123 src
->gzip
? "Packages.gz" : "Packages");
125 sprintf_alloc(&url
, "%s/%s", src
->value
, src
->gzip
? "Packages.gz" : "Packages");
127 sprintf_alloc(&list_file_name
, "%s/%s", lists_dir
, src
->name
);
132 sprintf_alloc (&tmp_file_name
, "%s/%s.gz", tmp
, src
->name
);
133 err
= opkg_download(url
, tmp_file_name
, NULL
, NULL
);
135 opkg_msg(NOTICE
, "Inflating %s.\n", url
);
136 in
= fopen (tmp_file_name
, "r");
137 out
= fopen (list_file_name
, "w");
146 unlink (tmp_file_name
);
150 err
= opkg_download(url
, list_file_name
, NULL
, NULL
);
154 opkg_msg(NOTICE
, "Updated list of available packages in %s.\n",
158 #if defined(HAVE_GPGME) || defined(HAVE_OPENSSL)
159 if (conf
->check_signature
) {
160 /* download detached signitures to verify the package lists */
161 /* get the url for the sig file */
162 if (src
->extra_data
) /* debian style? */
163 sprintf_alloc(&url
, "%s/%s/%s", src
->value
, src
->extra_data
,
166 sprintf_alloc(&url
, "%s/%s", src
->value
, "Packages.sig");
168 /* create temporary file for it */
171 /* Put the signature in the right place */
172 sprintf_alloc (&tmp_file_name
, "%s/%s.sig", lists_dir
, src
->name
);
174 err
= opkg_download(url
, tmp_file_name
, NULL
, NULL
);
177 opkg_msg(NOTICE
, "Signature check failed.\n");
179 err
= opkg_verify_file (list_file_name
, tmp_file_name
);
181 opkg_msg(NOTICE
, "Signature check passed.\n");
183 opkg_msg(NOTICE
, "Signature check failed.\n");
185 /* We shouldn't unlink the signature ! */
186 // unlink (tmp_file_name);
187 free (tmp_file_name
);
193 free(list_file_name
);
203 struct opkg_intercept
209 typedef struct opkg_intercept
*opkg_intercept_t
;
211 static opkg_intercept_t
212 opkg_prep_intercepts(void)
214 opkg_intercept_t ctx
;
217 ctx
= xcalloc(1, sizeof (*ctx
));
218 ctx
->oldpath
= xstrdup(getenv("PATH"));
219 sprintf_alloc(&newpath
, "%s/opkg/intercept:%s", DATADIR
, ctx
->oldpath
);
220 sprintf_alloc(&ctx
->statedir
, "%s/opkg-intercept-XXXXXX", conf
->tmp_dir
);
222 if (mkdtemp(ctx
->statedir
) == NULL
) {
223 opkg_perror(ERROR
,"Failed to make temp dir %s", ctx
->statedir
);
231 setenv("OPKG_INTERCEPT_DIR", ctx
->statedir
, 1);
232 setenv("PATH", newpath
, 1);
239 opkg_finalize_intercepts(opkg_intercept_t ctx
)
244 setenv ("PATH", ctx
->oldpath
, 1);
247 dir
= opendir (ctx
->statedir
);
250 while (de
= readdir (dir
), de
!= NULL
) {
253 if (de
->d_name
[0] == '.')
256 sprintf_alloc (&path
, "%s/%s", ctx
->statedir
, de
->d_name
);
257 if (access (path
, X_OK
) == 0) {
258 const char *argv
[] = {"sh", "-c", path
, NULL
};
265 opkg_perror(ERROR
, "Failed to open dir %s", ctx
->statedir
);
268 free (ctx
->statedir
);
274 /* For package pkg do the following: If it is already visited, return. If not,
275 add it in visited list and recurse to its deps. Finally, add it to ordered
277 pkg_vec all contains all available packages in repos.
278 pkg_vec visited contains packages already visited by this function, and is
279 used to end recursion and avoid an infinite loop on graph cycles.
280 pkg_vec ordered will finally contain the ordered set of packages.
283 opkg_recurse_pkgs_in_order(pkg_t
*pkg
, pkg_vec_t
*all
,
284 pkg_vec_t
*visited
, pkg_vec_t
*ordered
)
289 compound_depend_t
* compound_depend
;
290 depend_t
** possible_satisfiers
;
291 abstract_pkg_t
*abpkg
;
292 abstract_pkg_t
**dependents
;
294 /* If it's just an available package, that is, not installed and not even
296 /* XXX: This is probably an overkill, since a state_status != SS_UNPACKED
297 would do here. However, if there is an intermediate node (pkg) that is
298 configured and installed between two unpacked packages, the latter
299 won't be properly reordered, unless all installed/unpacked pkgs are
301 if (pkg
->state_status
== SS_NOT_INSTALLED
)
304 /* If the package has already been visited (by this function), skip it */
305 for(j
= 0; j
< visited
->len
; j
++)
306 if ( ! strcmp(visited
->pkgs
[j
]->name
, pkg
->name
)) {
307 opkg_msg(DEBUG
, "pkg %s already visited, skipping.\n", pkg
->name
);
311 pkg_vec_insert(visited
, pkg
);
313 count
= pkg
->pre_depends_count
+ pkg
->depends_count
+ \
314 pkg
->recommends_count
+ pkg
->suggests_count
;
316 opkg_msg(DEBUG
, "pkg %s.\n", pkg
->name
);
318 /* Iterate over all the dependencies of pkg. For each one, find a package
319 that is either installed or unpacked and satisfies this dependency.
320 (there should only be one such package per dependency installed or
321 unpacked). Then recurse to the dependency package */
322 for (j
=0; j
< count
; j
++) {
323 compound_depend
= &pkg
->depends
[j
];
324 possible_satisfiers
= compound_depend
->possibilities
;
325 for (k
=0; k
< compound_depend
->possibility_count
; k
++) {
326 abpkg
= possible_satisfiers
[k
]->pkg
;
327 dependents
= abpkg
->provided_by
->pkgs
;
329 if (dependents
!= NULL
)
330 while (l
< abpkg
->provided_by
->len
&& dependents
[l
] != NULL
) {
331 opkg_msg(DEBUG
, "Descending on pkg %s.\n",
332 dependents
[l
]->name
);
334 /* find whether dependent l is installed or unpacked,
335 * and then find which package in the list satisfies it */
336 for(m
= 0; m
< all
->len
; m
++) {
338 if ( dep
->state_status
!= SS_NOT_INSTALLED
)
339 if ( ! strcmp(dep
->name
, dependents
[l
]->name
)) {
340 opkg_recurse_pkgs_in_order(dep
, all
,
342 /* Stop the outer loop */
343 l
= abpkg
->provided_by
->len
;
344 /* break from the inner loop */
353 /* When all recursions from this node down, are over, and all
354 dependencies have been added in proper order in the ordered array, add
355 also the package pkg to ordered array */
356 pkg_vec_insert(ordered
, pkg
);
363 opkg_configure_packages(char *pkg_name
)
365 pkg_vec_t
*all
, *ordered
, *visited
;
371 opkg_msg(INFO
, "Configuring unpacked packages.\n");
373 all
= pkg_vec_alloc();
375 pkg_hash_fetch_available(all
);
377 /* Reorder pkgs in order to be configured according to the Depends: tag
379 opkg_msg(INFO
, "Reordering packages before configuring them...\n");
380 ordered
= pkg_vec_alloc();
381 visited
= pkg_vec_alloc();
382 for(i
= 0; i
< all
->len
; i
++) {
384 opkg_recurse_pkgs_in_order(pkg
, all
, visited
, ordered
);
387 ic
= opkg_prep_intercepts();
393 for(i
= 0; i
< ordered
->len
; i
++) {
394 pkg
= ordered
->pkgs
[i
];
396 if (pkg_name
&& fnmatch(pkg_name
, pkg
->name
, 0))
399 if (pkg
->state_status
== SS_UNPACKED
) {
400 opkg_msg(NOTICE
, "Configuring %s.\n", pkg
->name
);
401 r
= opkg_configure(pkg
);
403 pkg
->state_status
= SS_INSTALLED
;
404 pkg
->parent
->state_status
= SS_INSTALLED
;
405 pkg
->state_flag
&= ~SF_PREFER
;
406 opkg_state_changed
++;
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 r
= opkg_configure_packages(NULL
);
460 write_status_files_if_changed();
466 opkg_upgrade_cmd(int argc
, char **argv
)
472 signal(SIGINT
, sigint_handler
);
475 for (i
=0; i
< argc
; i
++) {
478 err
= opkg_prepare_url_for_install(arg
, &arg
);
482 pkg_info_preinstall_check();
484 for (i
=0; i
< argc
; i
++) {
486 if (conf
->restrict_to_default_dest
) {
487 pkg
= pkg_hash_fetch_installed_by_name_dest(argv
[i
],
490 opkg_msg(NOTICE
, "Package %s not installed in %s.\n",
491 argv
[i
], conf
->default_dest
->name
);
495 pkg
= pkg_hash_fetch_installed_by_name(argv
[i
]);
498 opkg_upgrade_pkg(pkg
);
500 opkg_install_by_name(arg
);
504 pkg_vec_t
*installed
= pkg_vec_alloc();
506 pkg_info_preinstall_check();
508 pkg_hash_fetch_all_installed(installed
);
509 for (i
= 0; i
< installed
->len
; i
++) {
510 pkg
= installed
->pkgs
[i
];
511 opkg_upgrade_pkg(pkg
);
513 pkg_vec_free(installed
);
516 r
= opkg_configure_packages(NULL
);
520 write_status_files_if_changed();
526 opkg_download_cmd(int argc
, char **argv
)
532 pkg_info_preinstall_check();
533 for (i
= 0; i
< argc
; i
++) {
536 pkg
= pkg_hash_fetch_best_installation_candidate_by_name(arg
);
538 opkg_msg(ERROR
, "Cannot find package %s.\n", arg
);
542 err
= opkg_download_pkg(pkg
, ".");
545 opkg_msg(ERROR
, "Failed to download %s.\n", pkg
->name
);
547 opkg_msg(NOTICE
, "Downloaded %s as %s.\n",
548 pkg
->name
, pkg
->local_filename
);
557 opkg_list_cmd(int argc
, char **argv
)
560 pkg_vec_t
*available
;
562 char *pkg_name
= NULL
;
567 available
= pkg_vec_alloc();
568 pkg_hash_fetch_available(available
);
569 pkg_vec_sort(available
, pkg_compare_names
);
570 for (i
=0; i
< available
->len
; i
++) {
571 pkg
= available
->pkgs
[i
];
572 /* if we have package name or pattern and pkg does not match, then skip it */
573 if (pkg_name
&& fnmatch(pkg_name
, pkg
->name
, 0))
577 pkg_vec_free(available
);
584 opkg_list_installed_cmd(int argc
, char **argv
)
587 pkg_vec_t
*available
;
589 char *pkg_name
= NULL
;
594 available
= pkg_vec_alloc();
595 pkg_hash_fetch_all_installed(available
);
596 pkg_vec_sort(available
, pkg_compare_names
);
597 for (i
=0; i
< available
->len
; i
++) {
598 pkg
= available
->pkgs
[i
];
599 /* if we have package name or pattern and pkg does not match, then skip it */
600 if (pkg_name
&& fnmatch(pkg_name
, pkg
->name
, 0))
605 pkg_vec_free(available
);
611 opkg_list_upgradable_cmd(int argc
, char **argv
)
613 struct active_list
*head
= prepare_upgrade_list();
614 struct active_list
*node
=NULL
;
615 pkg_t
*_old_pkg
, *_new_pkg
;
617 for (node
= active_list_next(head
, head
); node
;node
= active_list_next(head
,node
)) {
618 _old_pkg
= list_entry(node
, pkg_t
, list
);
619 _new_pkg
= pkg_hash_fetch_best_installation_candidate_by_name(_old_pkg
->name
);
620 if (_new_pkg
== NULL
)
622 old_v
= pkg_version_str_alloc(_old_pkg
);
623 new_v
= pkg_version_str_alloc(_new_pkg
);
624 printf("%s - %s - %s\n", _old_pkg
->name
, old_v
, new_v
);
628 active_list_head_delete(head
);
633 opkg_info_status_cmd(int argc
, char **argv
, int installed_only
)
636 pkg_vec_t
*available
;
638 char *pkg_name
= NULL
;
644 available
= pkg_vec_alloc();
646 pkg_hash_fetch_all_installed(available
);
648 pkg_hash_fetch_available(available
);
650 for (i
=0; i
< available
->len
; i
++) {
651 pkg
= available
->pkgs
[i
];
652 if (pkg_name
&& fnmatch(pkg_name
, pkg
->name
, 0)) {
656 pkg_formatted_info(stdout
, pkg
);
658 if (conf
->verbosity
>= NOTICE
) {
659 conffile_list_elt_t
*iter
;
660 for (iter
= nv_pair_list_first(&pkg
->conffiles
); iter
; iter
= nv_pair_list_next(&pkg
->conffiles
, iter
)) {
661 conffile_t
*cf
= (conffile_t
*)iter
->data
;
662 int modified
= conffile_has_been_modified(cf
);
664 opkg_msg(INFO
, "conffile=%s md5sum=%s modified=%d.\n",
665 cf
->name
, cf
->value
, modified
);
669 pkg_vec_free(available
);
675 opkg_info_cmd(int argc
, char **argv
)
677 return opkg_info_status_cmd(argc
, argv
, 0);
681 opkg_status_cmd(int argc
, char **argv
)
683 return opkg_info_status_cmd(argc
, argv
, 1);
687 opkg_configure_cmd(int argc
, char **argv
)
690 char *pkg_name
= NULL
;
695 err
= opkg_configure_packages(pkg_name
);
697 write_status_files_if_changed();
703 opkg_remove_cmd(int argc
, char **argv
)
705 int i
, a
, done
, r
, err
= 0;
707 pkg_t
*pkg_to_remove
;
708 pkg_vec_t
*available
;
712 signal(SIGINT
, sigint_handler
);
714 pkg_info_preinstall_check();
716 available
= pkg_vec_alloc();
717 pkg_hash_fetch_all_installed(available
);
719 for (i
=0; i
<argc
; i
++) {
720 for (a
=0; a
<available
->len
; a
++) {
721 pkg
= available
->pkgs
[a
];
722 if (fnmatch(argv
[i
], pkg
->name
, 0)) {
725 if (conf
->restrict_to_default_dest
) {
726 pkg_to_remove
= pkg_hash_fetch_installed_by_name_dest(
730 pkg_to_remove
= pkg_hash_fetch_installed_by_name(pkg
->name
);
733 if (pkg_to_remove
== NULL
) {
734 opkg_msg(ERROR
, "Package %s is not installed.\n", pkg
->name
);
737 if (pkg
->state_status
== SS_NOT_INSTALLED
) { // Added the control, so every already removed package could be skipped
738 opkg_msg(ERROR
, "Package %s not installed.\n", pkg
->name
);
741 r
= opkg_remove_pkg(pkg_to_remove
, 0);
749 pkg_vec_free(available
);
752 opkg_msg(NOTICE
, "No packages removed.\n");
754 write_status_files_if_changed();
759 opkg_flag_cmd(int argc
, char **argv
)
763 const char *flags
= argv
[0];
765 signal(SIGINT
, sigint_handler
);
767 for (i
=1; i
< argc
; i
++) {
768 if (conf
->restrict_to_default_dest
) {
769 pkg
= pkg_hash_fetch_installed_by_name_dest(argv
[i
],
772 pkg
= pkg_hash_fetch_installed_by_name(argv
[i
]);
776 opkg_msg(ERROR
, "Package %s is not installed.\n", argv
[i
]);
779 if (( strcmp(flags
,"hold")==0)||( strcmp(flags
,"noprune")==0)||
780 ( strcmp(flags
,"user")==0)||( strcmp(flags
,"ok")==0)) {
781 pkg
->state_flag
= pkg_state_flag_from_str(flags
);
785 * Useful if a package is installed in an offline_root, and
786 * should be configured by opkg-cl configure at a later date.
788 if (( strcmp(flags
,"installed")==0)||( strcmp(flags
,"unpacked")==0)){
789 pkg
->state_status
= pkg_state_status_from_str(flags
);
792 opkg_state_changed
++;
793 opkg_msg(NOTICE
, "Setting flags for package %s to %s.\n",
797 write_status_files_if_changed();
802 opkg_files_cmd(int argc
, char **argv
)
806 str_list_elt_t
*iter
;
813 pkg
= pkg_hash_fetch_installed_by_name(argv
[0]);
815 opkg_msg(ERROR
, "Package %s not installed.\n", argv
[0]);
819 files
= pkg_get_installed_files(pkg
);
820 pkg_version
= pkg_version_str_alloc(pkg
);
822 printf("Package %s (%s) is installed on %s and has the following files:\n",
823 pkg
->name
, pkg_version
, pkg
->dest
->name
);
825 for (iter
=str_list_first(files
); iter
; iter
=str_list_next(files
, iter
))
826 printf("%s\n", (char *)iter
->data
);
829 pkg_free_installed_files(pkg
);
835 opkg_depends_cmd(int argc
, char **argv
)
839 pkg_vec_t
*available_pkgs
;
840 compound_depend_t
*cdep
;
844 pkg_info_preinstall_check();
846 available_pkgs
= pkg_vec_alloc();
848 pkg_hash_fetch_available(available_pkgs
);
850 pkg_hash_fetch_all_installed(available_pkgs
);
852 for (i
=0; i
<argc
; i
++) {
853 for (j
=0; j
<available_pkgs
->len
; j
++) {
854 pkg
= available_pkgs
->pkgs
[j
];
856 if (fnmatch(argv
[i
], pkg
->name
, 0) != 0)
859 depends_count
= pkg
->depends_count
+
860 pkg
->pre_depends_count
+
861 pkg
->recommends_count
+
864 opkg_msg(NOTICE
, "%s depends on:\n", pkg
->name
);
866 for (k
=0; k
<depends_count
; k
++) {
867 cdep
= &pkg
->depends
[k
];
869 if (cdep
->type
!= DEPEND
)
872 str
= pkg_depend_str(pkg
, k
);
873 opkg_msg(NOTICE
, "\t%s\n", str
);
880 pkg_vec_free(available_pkgs
);
885 pkg_mark_provides(pkg_t
*pkg
)
887 int provides_count
= pkg
->provides_count
;
888 abstract_pkg_t
**provides
= pkg
->provides
;
890 pkg
->parent
->state_flag
|= SF_MARKED
;
891 for (i
= 0; i
< provides_count
; i
++) {
892 provides
[i
]->state_flag
|= SF_MARKED
;
897 enum what_field_type
{
907 opkg_what_depends_conflicts_cmd(enum depend_type what_field_type
, int recursive
, int argc
, char **argv
)
909 depend_t
*possibility
;
910 compound_depend_t
*cdep
;
911 pkg_vec_t
*available_pkgs
;
915 const char *rel_str
= NULL
;
918 switch (what_field_type
) {
919 case DEPEND
: rel_str
= "depends on"; break;
920 case CONFLICTS
: rel_str
= "conflicts with"; break;
921 case SUGGEST
: rel_str
= "suggests"; break;
922 case RECOMMEND
: rel_str
= "recommends"; break;
926 available_pkgs
= pkg_vec_alloc();
929 pkg_hash_fetch_available(available_pkgs
);
931 pkg_hash_fetch_all_installed(available_pkgs
);
933 /* mark the root set */
934 pkg_vec_clear_marks(available_pkgs
);
935 opkg_msg(NOTICE
, "Root set:\n");
936 for (i
= 0; i
< argc
; i
++)
937 pkg_vec_mark_if_matches(available_pkgs
, argv
[i
]);
939 for (i
= 0; i
< available_pkgs
->len
; i
++) {
940 pkg
= available_pkgs
->pkgs
[i
];
941 if (pkg
->state_flag
& SF_MARKED
) {
942 /* mark the parent (abstract) package */
943 pkg_mark_provides(pkg
);
944 opkg_msg(NOTICE
, " %s\n", pkg
->name
);
948 opkg_msg(NOTICE
, "What %s root set\n", rel_str
);
952 for (j
=0; j
<available_pkgs
->len
; j
++) {
954 pkg
= available_pkgs
->pkgs
[j
];
955 count
= ((what_field_type
== CONFLICTS
)
956 ? pkg
->conflicts_count
957 : pkg
->pre_depends_count
+
959 pkg
->recommends_count
+
960 pkg
->suggests_count
);
962 /* skip this package if it is already marked */
963 if (pkg
->parent
->state_flag
& SF_MARKED
)
966 for (k
=0; k
<count
; k
++) {
967 cdep
= (what_field_type
== CONFLICTS
)
971 if (what_field_type
!= cdep
->type
)
974 for (l
=0; l
<cdep
->possibility_count
; l
++) {
975 possibility
= cdep
->possibilities
[l
];
977 if ((possibility
->pkg
->state_flag
982 /* mark the depending package so we
983 * won't visit it again */
984 pkg
->state_flag
|= SF_MARKED
;
985 pkg_mark_provides(pkg
);
988 ver
= pkg_version_str_alloc(pkg
);
989 opkg_msg(NOTICE
, "\t%s %s\t%s %s",
993 possibility
->pkg
->name
);
995 if (possibility
->version
) {
996 opkg_msg(NOTICE
, " (%s%s)",
997 constraint_to_str(possibility
->constraint
),
998 possibility
->version
);
1000 if (!pkg_dependence_satisfiable(possibility
))
1003 opkg_msg(NOTICE
, "\n");
1010 } while (changed
&& recursive
);
1012 pkg_vec_free(available_pkgs
);
1018 opkg_whatdepends_recursively_cmd(int argc
, char **argv
)
1020 return opkg_what_depends_conflicts_cmd(DEPEND
, 1, argc
, argv
);
1024 opkg_whatdepends_cmd(int argc
, char **argv
)
1026 return opkg_what_depends_conflicts_cmd(DEPEND
, 0, argc
, argv
);
1030 opkg_whatsuggests_cmd(int argc
, char **argv
)
1032 return opkg_what_depends_conflicts_cmd(SUGGEST
, 0, argc
, argv
);
1036 opkg_whatrecommends_cmd(int argc
, char **argv
)
1038 return opkg_what_depends_conflicts_cmd(RECOMMEND
, 0, argc
, argv
);
1042 opkg_whatconflicts_cmd(int argc
, char **argv
)
1044 return opkg_what_depends_conflicts_cmd(CONFLICTS
, 0, argc
, argv
);
1048 opkg_what_provides_replaces_cmd(enum what_field_type what_field_type
, int argc
, char **argv
)
1052 pkg_vec_t
*available_pkgs
= pkg_vec_alloc();
1053 const char *rel_str
= (what_field_type
== WHATPROVIDES
? "provides" : "replaces");
1056 pkg_info_preinstall_check();
1058 if (conf
->query_all
)
1059 pkg_hash_fetch_available(available_pkgs
);
1061 pkg_hash_fetch_all_installed(available_pkgs
);
1062 for (i
= 0; i
< argc
; i
++) {
1063 const char *target
= argv
[i
];
1066 opkg_msg(NOTICE
, "What %s %s\n",
1068 for (j
= 0; j
< available_pkgs
->len
; j
++) {
1069 pkg_t
*pkg
= available_pkgs
->pkgs
[j
];
1071 int count
= (what_field_type
== WHATPROVIDES
) ? pkg
->provides_count
: pkg
->replaces_count
;
1072 for (k
= 0; k
< count
; k
++) {
1073 abstract_pkg_t
*apkg
=
1074 ((what_field_type
== WHATPROVIDES
)
1076 : pkg
->replaces
[k
]);
1077 if (fnmatch(target
, apkg
->name
, 0) == 0) {
1078 opkg_msg(NOTICE
, " %s", pkg
->name
);
1079 if (strcmp(target
, apkg
->name
) != 0)
1080 opkg_msg(NOTICE
, "\t%s %s\n",
1081 rel_str
, apkg
->name
);
1082 opkg_msg(NOTICE
, "\n");
1087 pkg_vec_free(available_pkgs
);
1093 opkg_whatprovides_cmd(int argc
, char **argv
)
1095 return opkg_what_provides_replaces_cmd(WHATPROVIDES
, argc
, argv
);
1099 opkg_whatreplaces_cmd(int argc
, char **argv
)
1101 return opkg_what_provides_replaces_cmd(WHATREPLACES
, argc
, argv
);
1105 opkg_search_cmd(int argc
, char **argv
)
1109 pkg_vec_t
*installed
;
1111 str_list_t
*installed_files
;
1112 str_list_elt_t
*iter
;
1113 char *installed_file
;
1119 installed
= pkg_vec_alloc();
1120 pkg_hash_fetch_all_installed(installed
);
1121 pkg_vec_sort(installed
, pkg_compare_names
);
1123 for (i
=0; i
< installed
->len
; i
++) {
1124 pkg
= installed
->pkgs
[i
];
1126 installed_files
= pkg_get_installed_files(pkg
);
1128 for (iter
= str_list_first(installed_files
); iter
; iter
= str_list_next(installed_files
, iter
)) {
1129 installed_file
= (char *)iter
->data
;
1130 if (fnmatch(argv
[0], installed_file
, 0)==0)
1134 pkg_free_installed_files(pkg
);
1137 pkg_vec_free(installed
);
1143 opkg_compare_versions_cmd(int argc
, char **argv
)
1146 /* this is a bit gross */
1148 parse_version(&p1
, argv
[0]);
1149 parse_version(&p2
, argv
[2]);
1150 return pkg_version_satisfied(&p1
, &p2
, argv
[1]);
1153 "opkg compare_versions <v1> <op> <v2>\n"
1154 "<op> is one of <= >= << >> =\n");
1160 opkg_print_architecture_cmd(int argc
, char **argv
)
1162 nv_pair_list_elt_t
*l
;
1164 list_for_each_entry(l
, &conf
->arch_list
.head
, node
) {
1165 nv_pair_t
*nv
= (nv_pair_t
*)l
->data
;
1166 printf("arch %s %s\n", nv
->name
, nv
->value
);
1172 /* XXX: CLEANUP: The usage strings should be incorporated into this
1173 array for easier maintenance */
1174 static opkg_cmd_t cmds
[] = {
1175 {"update", 0, (opkg_cmd_fun_t
)opkg_update_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1176 {"upgrade", 0, (opkg_cmd_fun_t
)opkg_upgrade_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1177 {"list", 0, (opkg_cmd_fun_t
)opkg_list_cmd
, PFM_SOURCE
},
1178 {"list_installed", 0, (opkg_cmd_fun_t
)opkg_list_installed_cmd
, PFM_SOURCE
},
1179 {"list-installed", 0, (opkg_cmd_fun_t
)opkg_list_installed_cmd
, PFM_SOURCE
},
1180 {"list_upgradable", 0, (opkg_cmd_fun_t
)opkg_list_upgradable_cmd
, PFM_SOURCE
},
1181 {"list-upgradable", 0, (opkg_cmd_fun_t
)opkg_list_upgradable_cmd
, PFM_SOURCE
},
1182 {"info", 0, (opkg_cmd_fun_t
)opkg_info_cmd
, 0},
1183 {"flag", 1, (opkg_cmd_fun_t
)opkg_flag_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1184 {"status", 0, (opkg_cmd_fun_t
)opkg_status_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1185 {"install", 1, (opkg_cmd_fun_t
)opkg_install_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1186 {"remove", 1, (opkg_cmd_fun_t
)opkg_remove_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1187 {"configure", 0, (opkg_cmd_fun_t
)opkg_configure_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1188 {"files", 1, (opkg_cmd_fun_t
)opkg_files_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1189 {"search", 1, (opkg_cmd_fun_t
)opkg_search_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1190 {"download", 1, (opkg_cmd_fun_t
)opkg_download_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1191 {"compare_versions", 1, (opkg_cmd_fun_t
)opkg_compare_versions_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1192 {"compare-versions", 1, (opkg_cmd_fun_t
)opkg_compare_versions_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1193 {"print-architecture", 0, (opkg_cmd_fun_t
)opkg_print_architecture_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1194 {"print_architecture", 0, (opkg_cmd_fun_t
)opkg_print_architecture_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1195 {"print-installation-architecture", 0, (opkg_cmd_fun_t
)opkg_print_architecture_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1196 {"print_installation_architecture", 0, (opkg_cmd_fun_t
)opkg_print_architecture_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1197 {"depends", 1, (opkg_cmd_fun_t
)opkg_depends_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1198 {"whatdepends", 1, (opkg_cmd_fun_t
)opkg_whatdepends_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1199 {"whatdependsrec", 1, (opkg_cmd_fun_t
)opkg_whatdepends_recursively_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1200 {"whatrecommends", 1, (opkg_cmd_fun_t
)opkg_whatrecommends_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1201 {"whatsuggests", 1, (opkg_cmd_fun_t
)opkg_whatsuggests_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1202 {"whatprovides", 1, (opkg_cmd_fun_t
)opkg_whatprovides_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1203 {"whatreplaces", 1, (opkg_cmd_fun_t
)opkg_whatreplaces_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1204 {"whatconflicts", 1, (opkg_cmd_fun_t
)opkg_whatconflicts_cmd
, PFM_DESCRIPTION
|PFM_SOURCE
},
1208 opkg_cmd_find(const char *name
)
1212 int num_cmds
= sizeof(cmds
) / sizeof(opkg_cmd_t
);
1214 for (i
=0; i
< num_cmds
; i
++) {
1216 if (strcmp(name
, cmd
->name
) == 0)
1224 opkg_cmd_exec(opkg_cmd_t
*cmd
, int argc
, const char **argv
)
1226 return (cmd
->fun
)(argc
, argv
);