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"
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(INFO
, "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(INFO
, "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(INFO
, "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
;
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
)
1218 result
= (cmd
->fun
)(argc
, argv
);