-/* opkg_cmd.c - the itsy package management system
+/* opkg_cmd.c - the opkg package management system
Carl D. Worth
General Public License for more details.
*/
-#include <string.h>
-#include "opkg.h"
-#include <libgen.h>
-#include <glob.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <signal.h>
-#include <stdio.h>
+#include "includes.h"
#include <dirent.h>
+#include <glob.h>
#include "opkg_conf.h"
#include "opkg_cmd.h"
#include "file_util.h"
#include "str_util.h"
#include "libbb/libbb.h"
+#include "opkg_utils.h"
+#include "opkg_defines.h"
#include <fnmatch.h>
FILE *in, *out;
sprintf_alloc (&tmp_file_name, "%s/%s.gz", tmp, src->name);
- err = opkg_download(conf, url, tmp_file_name);
+ err = opkg_download(conf, url, tmp_file_name, NULL, NULL);
if (err == 0) {
opkg_message (conf, OPKG_NOTICE, "Inflating %s\n", url);
in = fopen (tmp_file_name, "r");
unlink (tmp_file_name);
}
} else
- err = opkg_download(conf, url, list_file_name);
+ err = opkg_download(conf, url, list_file_name, NULL, NULL);
if (err) {
failures++;
} else {
}
free(url);
+#ifdef HAVE_GPGME
/* download detached signitures to verify the package lists */
/* get the url for the sig file */
if (src->extra_data) /* debian style? */
sprintf_alloc (&tmp_file_name, "%s/%s", tmp, "Packages.sig");
- err = opkg_download(conf, url, tmp_file_name);
+ err = opkg_download(conf, url, tmp_file_name, NULL, NULL);
if (err) {
failures++;
opkg_message (conf, OPKG_NOTICE, "Signature check failed\n");
} else {
int err;
- err = opkg_verify_file (list_file_name, tmp_file_name);
+ err = opkg_verify_file (conf, list_file_name, tmp_file_name);
if (err == 0)
opkg_message (conf, OPKG_NOTICE, "Signature check passed\n");
else
}
unlink (tmp_file_name);
free (tmp_file_name);
-
free (url);
+#else
+ opkg_message (conf, OPKG_NOTICE, "Signiture check for %s skipped "
+ "because GPG support was not enabled in this build\n", src->name);
+#endif
free(list_file_name);
}
rmdir (tmp);
return err;
}
+/* For package pkg do the following: If it is already visited, return. If not,
+ add it in visited list and recurse to its deps. Finally, add it to ordered
+ list.
+ pkg_vec all contains all available packages in repos.
+ pkg_vec visited contains packages already visited by this function, and is
+ used to end recursion and avoid an infinite loop on graph cycles.
+ pkg_vec ordered will finally contain the ordered set of packages.
+*/
+int opkg_recurse_pkgs_in_order(opkg_conf_t *conf, pkg_t *pkg, pkg_vec_t *all,
+ pkg_vec_t *visited, pkg_vec_t *ordered)
+{
+ int j,k,l,m;
+ int count;
+ pkg_t *dep;
+ compound_depend_t * compound_depend;
+ depend_t ** possible_satisfiers;
+ abstract_pkg_t *abpkg;
+ abstract_pkg_t **dependents;
+
+ /* If it's just an available package, that is, not installed and not even
+ unpacked, skip it */
+ /* XXX: This is probably an overkill, since a state_status != SS_UNPACKED
+ would do here. However, if there is an intermediate node (pkg) that is
+ configured and installed between two unpacked packages, the latter
+ won't be properly reordered, unless all installed/unpacked pkgs are
+ checked */
+ if (pkg->state_status == SS_NOT_INSTALLED)
+ return 0;
+
+ /* If the package has already been visited (by this function), skip it */
+ for(j = 0; j < visited->len; j++)
+ if ( ! strcmp(visited->pkgs[j]->name, pkg->name)) {
+ opkg_message(conf, OPKG_INFO,
+ " pkg: %s already visited\n", pkg->name);
+ return 0;
+ }
+
+ pkg_vec_insert(visited, pkg);
+
+ count = pkg->pre_depends_count + pkg->depends_count + \
+ pkg->recommends_count + pkg->suggests_count;
+
+ opkg_message(conf, OPKG_INFO,
+ " pkg: %s\n", pkg->name);
+
+ /* Iterate over all the dependencies of pkg. For each one, find a package
+ that is either installed or unpacked and satisfies this dependency.
+ (there should only be one such package per dependency installed or
+ unpacked). Then recurse to the dependency package */
+ for (j=0; j < count ; j++) {
+ compound_depend = &pkg->depends[j];
+ possible_satisfiers = compound_depend->possibilities;
+ for (k=0; k < compound_depend->possibility_count ; k++) {
+ abpkg = possible_satisfiers[k]->pkg;
+ dependents = abpkg->provided_by->pkgs;
+ l = 0;
+ if (dependents != NULL)
+ while (dependents [l] != NULL && l < abpkg->provided_by->len) {
+ opkg_message(conf, OPKG_INFO,
+ " Descending on pkg: %s\n",
+ dependents [l]->name);
+
+ /* find whether dependent l is installed or unpacked,
+ * and then find which package in the list satisfies it */
+ for(m = 0; m < all->len; m++) {
+ dep = all->pkgs[m];
+ if ( dep->state_status != SS_NOT_INSTALLED)
+ if ( ! strcmp(dep->name, dependents[l]->name)) {
+ opkg_recurse_pkgs_in_order(conf, dep, all,
+ visited, ordered);
+ /* Stop the outer loop */
+ l = abpkg->provided_by->len;
+ /* break from the inner loop */
+ break;
+ }
+ }
+ l++;
+ }
+ }
+ }
+
+ /* When all recursions from this node down, are over, and all
+ dependencies have been added in proper order in the ordered array, add
+ also the package pkg to ordered array */
+ pkg_vec_insert(ordered, pkg);
+
+ return 0;
+
+}
+
int opkg_configure_packages(opkg_conf_t *conf, char *pkg_name)
{
- pkg_vec_t *all;
+ pkg_vec_t *all, *ordered, *visited;
int i;
pkg_t *pkg;
opkg_intercept_t ic;
fflush( stdout );
all = pkg_vec_alloc();
+
pkg_hash_fetch_available(&conf->pkg_hash, all);
+ /* Reorder pkgs in order to be configured according to the Depends: tag
+ order */
+ opkg_message(conf, OPKG_INFO,
+ "Reordering packages before configuring them...\n");
+ ordered = pkg_vec_alloc();
+ visited = pkg_vec_alloc();
+ for(i = 0; i < all->len; i++) {
+ pkg = all->pkgs[i];
+ opkg_recurse_pkgs_in_order(conf, pkg, all, visited, ordered);
+ }
+
+
ic = opkg_prep_intercepts (conf);
for(i = 0; i < all->len; i++) {
err = r;
pkg_vec_free(all);
+ pkg_vec_free(ordered);
+ pkg_vec_free(visited);
+
return err;
}
for (i=0; i < argc; i++) {
arg = argv[i];
- if (conf->multiple_providers)
- err = opkg_install_multi_by_name(conf, arg);
- else{
- err = opkg_install_by_name(conf, arg);
- }
+ err = opkg_install_by_name(conf, arg);
if (err == OPKG_PKG_HAS_NO_CANDIDATE) {
opkg_message(conf, OPKG_ERROR,
"Cannot find package %s.\n"