X-Git-Url: https://git.librecmc.org/?p=oweals%2Fopkg-lede.git;a=blobdiff_plain;f=libopkg%2Fopkg_cmd.c;h=42bfd16ade1a47d14fd58a491c3ed909cdab7db3;hp=a7f9b1afdfdcdbee4e2dd5fb9f017c97fb75724a;hb=9020bb63c0005f68973b6d21290e7808c63ed487;hpb=b6ceb5e11ae20ede9b30979d4b54c56f84e89eaf diff --git a/libopkg/opkg_cmd.c b/libopkg/opkg_cmd.c index a7f9b1a..42bfd16 100644 --- a/libopkg/opkg_cmd.c +++ b/libopkg/opkg_cmd.c @@ -19,6 +19,7 @@ #include "includes.h" #include #include +#include #include "opkg_conf.h" #include "opkg_cmd.h" @@ -33,19 +34,14 @@ #include "libbb/libbb.h" #include "opkg_utils.h" #include "opkg_defines.h" - -#include - - #include "opkg_download.h" #include "opkg_install.h" #include "opkg_upgrade.h" #include "opkg_remove.h" #include "opkg_configure.h" #include "opkg_message.h" - #include "libopkg.h" -static void *p_userdata = NULL; +#include "xsystem.h" static int opkg_update_cmd(opkg_conf_t *conf, int argc, char **argv); static int opkg_upgrade_cmd(opkg_conf_t *conf, int argc, char **argv); @@ -55,6 +51,7 @@ static int opkg_status_cmd(opkg_conf_t *conf, int argc, char **argv); static int opkg_install_pending_cmd(opkg_conf_t *conf, int argc, char **argv); static int opkg_install_cmd(opkg_conf_t *conf, int argc, char **argv); static int opkg_list_installed_cmd(opkg_conf_t *conf, int argc, char **argv); +static int opkg_list_upgradable_cmd(opkg_conf_t *conf, int argc, char **argv); static int opkg_remove_cmd(opkg_conf_t *conf, int argc, char **argv); static int opkg_purge_cmd(opkg_conf_t *conf, int argc, char **argv); static int opkg_flag_cmd(opkg_conf_t *conf, int argc, char **argv); @@ -72,6 +69,7 @@ static int opkg_whatreplaces_cmd(opkg_conf_t *conf, int argc, char **argv); static int opkg_compare_versions_cmd(opkg_conf_t *conf, int argc, char **argv); static int opkg_print_architecture_cmd(opkg_conf_t *conf, int argc, char **argv); static int opkg_configure_cmd(opkg_conf_t *conf, int argc, char **argv); +static int pkg_mark_provides(pkg_t *pkg); /* XXX: CLEANUP: The usage strings should be incorporated into this array for easier maintenance */ @@ -80,6 +78,7 @@ static opkg_cmd_t cmds[] = { {"upgrade", 0, (opkg_cmd_fun_t)opkg_upgrade_cmd}, {"list", 0, (opkg_cmd_fun_t)opkg_list_cmd}, {"list_installed", 0, (opkg_cmd_fun_t)opkg_list_installed_cmd}, + {"list_upgradable", 0, (opkg_cmd_fun_t)opkg_list_upgradable_cmd}, {"info", 0, (opkg_cmd_fun_t)opkg_info_cmd}, {"flag", 1, (opkg_cmd_fun_t)opkg_flag_cmd}, {"status", 0, (opkg_cmd_fun_t)opkg_status_cmd}, @@ -107,6 +106,16 @@ static opkg_cmd_t cmds[] = { {"whatconflicts", 1, (opkg_cmd_fun_t)opkg_whatconflicts_cmd}, }; +static void print_pkg(pkg_t *pkg) +{ + char *version = pkg_version_str_alloc(pkg); + if (pkg->description) + printf("%s - %s - %s\n", pkg->name, version, pkg->description); + else + printf("%s - %s\n", pkg->name, version); + free(version); +} + int opkg_state_changed; static void write_status_files_if_changed(opkg_conf_t *conf) { @@ -116,7 +125,7 @@ static void write_status_files_if_changed(opkg_conf_t *conf) opkg_conf_write_status_files(conf); pkg_write_changed_filelists(conf); } else { - opkg_message(conf, OPKG_NOTICE, "Nothing to be done\n"); + opkg_message(conf, OPKG_DEBUG, "Nothing to be done\n"); } } @@ -141,30 +150,12 @@ opkg_cmd_t *opkg_cmd_find(const char *name) int opkg_cmd_exec(opkg_cmd_t *cmd, opkg_conf_t *conf, int argc, const char **argv, void *userdata) { int result; - p_userdata = userdata; - result = (cmd->fun)(conf, argc, argv); - if ( result != 0 ) { - opkg_message(conf, OPKG_NOTICE, "An error ocurred, return value: %d.\n", result); - } - - if ( error_list ) { - reverse_error_list(&error_list); - - opkg_message(conf, OPKG_NOTICE, "Collected errors:\n"); - /* Here we print the errors collected and free the list */ - while (error_list != NULL) { - opkg_message(conf, OPKG_NOTICE, "%s",error_list->errmsg); - error_list = error_list->next; - - } - free_error_list(&error_list); + print_error_list(); + free_error_list(); - } - - p_userdata = NULL; return result; } @@ -186,7 +177,7 @@ static int opkg_update_cmd(opkg_conf_t *conf, int argc, char **argv) "%s: ERROR: %s exists, but is not a directory\n", __FUNCTION__, lists_dir); free(lists_dir); - return EINVAL; + return -1; } err = file_mkdir_hier(lists_dir, 0755); if (err) { @@ -194,25 +185,23 @@ static int opkg_update_cmd(opkg_conf_t *conf, int argc, char **argv) "%s: ERROR: failed to make directory %s: %s\n", __FUNCTION__, lists_dir, strerror(errno)); free(lists_dir); - return EINVAL; + return -1; } } failures = 0; - - tmp = strdup ("/tmp/opkg.XXXXXX"); - + sprintf_alloc(&tmp, "%s/update-XXXXXX", conf->tmp_dir); if (mkdtemp (tmp) == NULL) { perror ("mkdtemp"); - failures++; + return -1; } - for (iter = conf->pkg_src_list.head; iter; iter = iter->next) { + for (iter = void_list_first(&conf->pkg_src_list); iter; iter = void_list_next(&conf->pkg_src_list, iter)) { char *url, *list_file_name; - src = iter->data; + src = (pkg_src_t *)iter->data; if (src->extra_data) /* debian style? */ sprintf_alloc(&url, "%s/%s/%s", src->value, src->extra_data, @@ -241,6 +230,7 @@ static int opkg_update_cmd(opkg_conf_t *conf, int argc, char **argv) fclose (out); unlink (tmp_file_name); } + free(tmp_file_name); } else err = opkg_download(conf, url, list_file_name, NULL, NULL); if (err) { @@ -251,39 +241,41 @@ static int opkg_update_cmd(opkg_conf_t *conf, int argc, char **argv) list_file_name); } 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(&url, "%s/%s/%s", src->value, src->extra_data, - "Packages.sig"); - else - sprintf_alloc(&url, "%s/%s", src->value, "Packages.sig"); - - /* create temporary file for it */ - char *tmp_file_name; - - sprintf_alloc (&tmp_file_name, "%s/%s", tmp, "Packages.sig"); - - 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 (conf, list_file_name, tmp_file_name); - if (err == 0) - opkg_message (conf, OPKG_NOTICE, "Signature check passed\n"); - else - opkg_message (conf, OPKG_NOTICE, "Signature check failed\n"); - } - unlink (tmp_file_name); - free (tmp_file_name); - free (url); +#if defined(HAVE_GPGME) || defined(HAVE_OPENSSL) + if (conf->check_signature) { + /* download detached signitures to verify the package lists */ + /* get the url for the sig file */ + if (src->extra_data) /* debian style? */ + sprintf_alloc(&url, "%s/%s/%s", src->value, src->extra_data, + "Packages.sig"); + else + sprintf_alloc(&url, "%s/%s", src->value, "Packages.sig"); + + /* create temporary file for it */ + char *tmp_file_name; + + /* Put the signature in the right place */ + sprintf_alloc (&tmp_file_name, "%s/%s.sig", lists_dir, src->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 (conf, list_file_name, tmp_file_name); + if (err == 0) + opkg_message (conf, OPKG_NOTICE, "Signature check passed\n"); + else + opkg_message (conf, OPKG_NOTICE, "Signature check failed\n"); + } + /* We shouldn't unlink the signature ! */ + // 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); + // Do nothing #endif free(list_file_name); } @@ -295,36 +287,6 @@ static int opkg_update_cmd(opkg_conf_t *conf, int argc, char **argv) } -/* scan the args passed and cache the local filenames of the packages */ -int opkg_multiple_files_scan(opkg_conf_t *conf, int argc, char **argv) -{ - int i; - int err; - - /* - * First scan through package names/urls - * For any urls, download the packages and install in database. - * For any files, install package info in database. - */ - for (i = 0; i < argc; i ++) { - char *filename = argv [i]; - //char *tmp = basename (tmp); - //int tmplen = strlen (tmp); - - //if (strcmp (tmp + (tmplen - strlen (OPKG_PKG_EXTENSION)), OPKG_PKG_EXTENSION) != 0) - // continue; - //if (strcmp (tmp + (tmplen - strlen (DPKG_PKG_EXTENSION)), DPKG_PKG_EXTENSION) != 0) - // continue; - - opkg_message(conf, OPKG_DEBUG2, "Debug mfs: %s \n",filename ); - - err = opkg_prepare_url_for_install(conf, filename, &argv[i]); - if (err) - return err; - } - return 0; -} - struct opkg_intercept { char *oldpath; @@ -333,38 +295,34 @@ struct opkg_intercept typedef struct opkg_intercept *opkg_intercept_t; -opkg_intercept_t opkg_prep_intercepts(opkg_conf_t *conf) +static opkg_intercept_t opkg_prep_intercepts(opkg_conf_t *conf) { opkg_intercept_t ctx; char *newpath; - int gen; - - ctx = malloc (sizeof (*ctx)); - ctx->oldpath = strdup (getenv ("PATH")); - sprintf_alloc (&newpath, "%s/opkg/intercept:%s", DATADIR, ctx->oldpath); - setenv ("PATH", newpath, 1); - free (newpath); - - gen = 0; - retry: - sprintf_alloc (&ctx->statedir, "/tmp/opkg-intercept-%d-%d", getpid (), gen); - if (mkdir (ctx->statedir, 0770) < 0) { - if (errno == EEXIST) { - free (ctx->statedir); - gen++; - goto retry; - } - perror (ctx->statedir); + ctx = xcalloc(1, sizeof (*ctx)); + ctx->oldpath = xstrdup(getenv("PATH")); + sprintf_alloc(&newpath, "%s/opkg/intercept:%s", DATADIR, ctx->oldpath); + sprintf_alloc(&ctx->statedir, "%s/opkg-intercept-XXXXXX", conf->tmp_dir); + + if (mkdtemp(ctx->statedir) == NULL) { + fprintf(stderr, "%s: mkdtemp: %s\n", __FUNCTION__, strerror(errno)); + free(ctx->oldpath); + free(ctx->statedir); + free(newpath); + free(ctx); return NULL; } - setenv ("OPKG_INTERCEPT_DIR", ctx->statedir, 1); + + setenv("OPKG_INTERCEPT_DIR", ctx->statedir, 1); + setenv("PATH", newpath, 1); + free(newpath); + return ctx; } -int opkg_finalize_intercepts(opkg_intercept_t ctx) +static int opkg_finalize_intercepts(opkg_intercept_t ctx) { - char *cmd; DIR *dir; int err = 0; @@ -376,35 +334,121 @@ int opkg_finalize_intercepts(opkg_intercept_t ctx) struct dirent *de; while (de = readdir (dir), de != NULL) { char *path; - + if (de->d_name[0] == '.') continue; sprintf_alloc (&path, "%s/%s", ctx->statedir, de->d_name); if (access (path, X_OK) == 0) { - if (system (path)) { - err = errno; - perror (de->d_name); - } + const char *argv[] = {"sh", "-c", path, NULL}; + xsystem (argv); } free (path); } + closedir(dir); } else perror (ctx->statedir); - sprintf_alloc (&cmd, "rm -rf %s", ctx->statedir); - system (cmd); - free (cmd); - + rm_r(ctx->statedir); free (ctx->statedir); free (ctx); return err; } -int opkg_configure_packages(opkg_conf_t *conf, char *pkg_name) +/* 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. +*/ +static 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 (l < abpkg->provided_by->len && dependents[l] != NULL) { + 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; + +} + +static 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; @@ -415,9 +459,25 @@ int opkg_configure_packages(opkg_conf_t *conf, char *pkg_name) 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); + if (ic == NULL) { + err = -1; + goto error; + } for(i = 0; i < all->len; i++) { pkg = all->pkgs[i]; @@ -445,7 +505,11 @@ int opkg_configure_packages(opkg_conf_t *conf, char *pkg_name) if (r && !err) err = r; +error: pkg_vec_free(all); + pkg_vec_free(ordered); + pkg_vec_free(visited); + return err; } @@ -484,22 +548,14 @@ static int opkg_install_cmd(opkg_conf_t *conf, int argc, char **argv) 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" - "Check the spelling or perhaps run 'opkg update'\n", + "Cannot find package %s.\n", arg); } } - /* recheck to verify that all dependences are satisfied */ - if (0) opkg_satisfy_all_dependences(conf); - opkg_configure_packages(conf, NULL); write_status_files_if_changed(conf); @@ -561,9 +617,6 @@ static int opkg_upgrade_cmd(opkg_conf_t *conf, int argc, char **argv) pkg_vec_free(installed); } - /* recheck to verify that all dependences are satisfied */ - if (0) opkg_satisfy_all_dependences(conf); - opkg_configure_packages(conf, NULL); write_status_files_if_changed(conf); @@ -581,7 +634,7 @@ static int opkg_download_cmd(opkg_conf_t *conf, int argc, char **argv) for (i = 0; i < argc; i++) { arg = argv[i]; - pkg = pkg_hash_fetch_best_installation_candidate_by_name(conf, arg); + pkg = pkg_hash_fetch_best_installation_candidate_by_name(conf, arg, &err); if (pkg == NULL) { opkg_message(conf, OPKG_ERROR, "Cannot find package %s.\n" @@ -608,42 +661,23 @@ static int opkg_download_cmd(opkg_conf_t *conf, int argc, char **argv) static int opkg_list_cmd(opkg_conf_t *conf, int argc, char **argv) { - int i ; + int i; pkg_vec_t *available; pkg_t *pkg; - char desc_short[OPKG_LIST_DESCRIPTION_LENGTH]; - char *newline; char *pkg_name = NULL; - char *version_str; if (argc > 0) { pkg_name = argv[0]; } available = pkg_vec_alloc(); pkg_hash_fetch_available(&conf->pkg_hash, available); + pkg_vec_sort(available, pkg_compare_names); for (i=0; i < available->len; i++) { pkg = available->pkgs[i]; /* if we have package name or pattern and pkg does not match, then skip it */ if (pkg_name && fnmatch(pkg_name, pkg->name, 0)) continue; - if (pkg->description) { - strncpy(desc_short, pkg->description, OPKG_LIST_DESCRIPTION_LENGTH); - } else { - desc_short[0] = '\0'; - } - desc_short[OPKG_LIST_DESCRIPTION_LENGTH - 1] = '\0'; - newline = strchr(desc_short, '\n'); - if (newline) { - *newline = '\0'; - } - if (opkg_cb_list) { - version_str = pkg_version_str_alloc(pkg); - opkg_cb_list(pkg->name,desc_short, - version_str, - pkg->state_status, - p_userdata); - free(version_str); - } + print_pkg(pkg); } pkg_vec_free(available); @@ -656,91 +690,79 @@ static int opkg_list_installed_cmd(opkg_conf_t *conf, int argc, char **argv) int i ; pkg_vec_t *available; pkg_t *pkg; - char desc_short[OPKG_LIST_DESCRIPTION_LENGTH]; - char *newline; char *pkg_name = NULL; - char *version_str; if (argc > 0) { pkg_name = argv[0]; } available = pkg_vec_alloc(); pkg_hash_fetch_all_installed(&conf->pkg_hash, available); + pkg_vec_sort(available, pkg_compare_names); for (i=0; i < available->len; i++) { pkg = available->pkgs[i]; /* if we have package name or pattern and pkg does not match, then skip it */ if (pkg_name && fnmatch(pkg_name, pkg->name, 0)) continue; - if (pkg->description) { - strncpy(desc_short, pkg->description, OPKG_LIST_DESCRIPTION_LENGTH); - } else { - desc_short[0] = '\0'; - } - desc_short[OPKG_LIST_DESCRIPTION_LENGTH - 1] = '\0'; - newline = strchr(desc_short, '\n'); - if (newline) { - *newline = '\0'; - } - if (opkg_cb_list) { - version_str = pkg_version_str_alloc(pkg); - opkg_cb_list(pkg->name,desc_short, - version_str, - pkg->state_status, - p_userdata); - free(version_str); - } + print_pkg(pkg); } + pkg_vec_free(available); + return 0; } +static int opkg_list_upgradable_cmd(opkg_conf_t *conf, int argc, char **argv) +{ + struct active_list *head = prepare_upgrade_list(conf); + struct active_list *node=NULL; + pkg_t *_old_pkg, *_new_pkg; + char *old_v, *new_v; + for (node = active_list_next(head, head); node;node = active_list_next(head,node)) { + _old_pkg = list_entry(node, pkg_t, list); + _new_pkg = pkg_hash_fetch_best_installation_candidate_by_name(conf, _old_pkg->name, NULL); + old_v = pkg_version_str_alloc(_old_pkg); + new_v = pkg_version_str_alloc(_new_pkg); + printf("%s - %s - %s\n", _old_pkg->name, old_v, new_v); + free(old_v); + free(new_v); + } + active_list_head_delete(head); + return 0; +} + static int opkg_info_status_cmd(opkg_conf_t *conf, int argc, char **argv, int installed_only) { int i; pkg_vec_t *available; pkg_t *pkg; char *pkg_name = NULL; - char **pkg_fields = NULL; - int n_fields = 0; - char *buff ; // = (char *)malloc(1); if (argc > 0) { pkg_name = argv[0]; } - if (argc > 1) { - pkg_fields = &argv[1]; - n_fields = argc - 1; - } available = pkg_vec_alloc(); if (installed_only) pkg_hash_fetch_all_installed(&conf->pkg_hash, available); else pkg_hash_fetch_available(&conf->pkg_hash, available); + for (i=0; i < available->len; i++) { pkg = available->pkgs[i]; if (pkg_name && fnmatch(pkg_name, pkg->name, 0)) { continue; } - buff = pkg_formatted_info(pkg); - if ( buff ) { - if (opkg_cb_status) opkg_cb_status(pkg->name, - pkg->state_status, - buff, - p_userdata); -/* - We should not forget that actually the pointer is allocated. - We need to free it :) ( Thanks florian for seeing the error ) -*/ - free(buff); - } - if (conf->verbosity > 1) { + pkg_formatted_info(stdout, pkg); + + if (conf->verbosity >= OPKG_NOTICE) { conffile_list_elt_t *iter; - for (iter = pkg->conffiles.head; iter; iter = iter->next) { - conffile_t *cf = iter->data; + for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) { + conffile_t *cf = (conffile_t *)iter->data; int modified = conffile_has_been_modified(conf, cf); - opkg_message(conf, OPKG_NOTICE, "conffile=%s md5sum=%s modified=%d\n", + if (cf->value) + opkg_message(conf, OPKG_NOTICE, + "conffile=%s md5sum=%s modified=%d\n", cf->name, cf->value, modified); } } @@ -832,12 +854,12 @@ static int opkg_remove_cmd(opkg_conf_t *conf, int argc, char **argv) done = 0; - available = pkg_vec_alloc(); pkg_info_preinstall_check(conf); if ( argc > 0 ) { + available = pkg_vec_alloc(); pkg_hash_fetch_all_installed(&conf->pkg_hash, available); for (i=0; i < argc; i++) { - pkg_name = malloc(strlen(argv[i])+2); + pkg_name = xcalloc(1, strlen(argv[i])+2); strcpy(pkg_name,argv[i]); for (a=0; a < available->len; a++) { pkg = available->pkgs[a]; @@ -852,7 +874,7 @@ static int opkg_remove_cmd(opkg_conf_t *conf, int argc, char **argv) pkg_to_remove = pkg_hash_fetch_installed_by_name(&conf->pkg_hash, pkg->name ); } - if (pkg == NULL) { + if (pkg_to_remove == NULL) { opkg_message(conf, OPKG_ERROR, "Package %s is not installed.\n", pkg->name); continue; } @@ -991,19 +1013,10 @@ static int opkg_flag_cmd(opkg_conf_t *conf, int argc, char **argv) static int opkg_files_cmd(opkg_conf_t *conf, int argc, char **argv) { pkg_t *pkg; - str_list_t *installed_files; + str_list_t *files; str_list_elt_t *iter; char *pkg_version; - size_t buff_len = 8192; - size_t used_len; - char *buff ; - - buff = (char *)malloc(buff_len); - if ( buff == NULL ) { - fprintf( stderr,"%s: Unable to allocate memory \n",__FUNCTION__); - return ENOMEM; - } - + if (argc < 1) { return EINVAL; } @@ -1016,34 +1029,14 @@ static int opkg_files_cmd(opkg_conf_t *conf, int argc, char **argv) return 0; } - installed_files = pkg_get_installed_files(pkg); + files = pkg_get_installed_files(conf, pkg); pkg_version = pkg_version_str_alloc(pkg); - if (buff) { - try_again: - used_len = snprintf(buff, buff_len, "Package %s (%s) is installed on %s and has the following files:\n", - pkg->name, pkg_version, pkg->dest->name) + 1; - if (used_len > buff_len) { - buff_len *= 2; - buff = realloc (buff, buff_len); - goto try_again; - } - for (iter = installed_files->head; iter; iter = iter->next) { - used_len += strlen (iter->data) + 1; - while (buff_len <= used_len) { - buff_len *= 2; - buff = realloc (buff, buff_len); - } - strncat(buff, iter->data, buff_len); - strncat(buff, "\n", buff_len); - } - if (opkg_cb_list) opkg_cb_list(pkg->name, - buff, - pkg_version_str_alloc(pkg), - pkg->state_status, - p_userdata); - free(buff); - } + printf("Package %s (%s) is installed on %s and has the following files:\n", + pkg->name, pkg_version, pkg->dest->name); + + for (iter=str_list_first(files); iter; iter=str_list_next(files, iter)) + printf("%s\n", (char *)iter->data); free(pkg_version); pkg_free_installed_files(pkg); @@ -1069,26 +1062,25 @@ static int opkg_depends_cmd(opkg_conf_t *conf, int argc, char **argv) const char *target = argv[i]; int j; - opkg_message(conf, OPKG_ERROR, "target=%s\n", target); + opkg_message(conf, OPKG_NOTICE, "target=%s\n", target); for (j = 0; j < available_pkgs->len; j++) { pkg_t *pkg = available_pkgs->pkgs[j]; if (fnmatch(target, pkg->name, 0) == 0) { int k; int count = pkg->depends_count + pkg->pre_depends_count; - opkg_message(conf, OPKG_ERROR, "What %s (arch=%s) %s\n", + opkg_message(conf, OPKG_NOTICE, "What %s (arch=%s) %s\n", target, pkg->architecture, rel_str); for (k = 0; k < count; k++) { compound_depend_t *cdepend = &pkg->depends[k]; int l; for (l = 0; l < cdepend->possibility_count; l++) { depend_t *possibility = cdepend->possibilities[l]; - opkg_message(conf, OPKG_ERROR, " %s", possibility->pkg->name); - if (conf->verbosity > 0) { - // char *ver = abstract_pkg_version_str_alloc(possibility->pkg); - opkg_message(conf, OPKG_NOTICE, " %s", possibility->version); + opkg_message(conf, OPKG_NOTICE, " %s", possibility->pkg->name); + if (conf->verbosity >= OPKG_NOTICE) { if (possibility->version) { char *typestr = NULL; + opkg_message(conf, OPKG_NOTICE, " %s", possibility->version); switch (possibility->constraint) { case NONE: typestr = "none"; break; case EARLIER: typestr = "<"; break; @@ -1099,9 +1091,8 @@ static int opkg_depends_cmd(opkg_conf_t *conf, int argc, char **argv) } opkg_message(conf, OPKG_NOTICE, " (%s %s)", typestr, possibility->version); } - // free(ver); } - opkg_message(conf, OPKG_ERROR, "\n"); + opkg_message(conf, OPKG_NOTICE, "\n"); } } } @@ -1121,7 +1112,7 @@ enum what_field_type { WHATSUGGESTS }; -static int opkg_what_depends_conflicts_cmd(opkg_conf_t *conf, enum what_field_type what_field_type, int recursive, int argc, char **argv) +static int opkg_what_depends_conflicts_cmd(opkg_conf_t *conf, enum depend_type what_field_type, int recursive, int argc, char **argv) { if (argc > 0) { @@ -1131,12 +1122,11 @@ static int opkg_what_depends_conflicts_cmd(opkg_conf_t *conf, enum what_field_ty int changed; switch (what_field_type) { - case WHATDEPENDS: rel_str = "depends on"; break; - case WHATCONFLICTS: rel_str = "conflicts with"; break; - case WHATSUGGESTS: rel_str = "suggests"; break; - case WHATRECOMMENDS: rel_str = "recommends"; break; - case WHATPROVIDES: rel_str = "provides"; break; - case WHATREPLACES: rel_str = "replaces"; break; + case DEPEND: rel_str = "depends on"; break; + case CONFLICTS: rel_str = "conflicts with"; break; + case SUGGEST: rel_str = "suggests"; break; + case RECOMMEND: rel_str = "recommends"; break; + default: return -1; } if (conf->query_all) @@ -1168,7 +1158,7 @@ static int opkg_what_depends_conflicts_cmd(opkg_conf_t *conf, enum what_field_ty for (j = 0; j < available_pkgs->len; j++) { pkg_t *pkg = available_pkgs->pkgs[j]; int k; - int count = ((what_field_type == WHATCONFLICTS) + int count = ((what_field_type == CONFLICTS) ? pkg->conflicts_count : pkg->pre_depends_count + pkg->depends_count + pkg->recommends_count + pkg->suggests_count); /* skip this package if it is already marked */ @@ -1177,8 +1167,10 @@ static int opkg_what_depends_conflicts_cmd(opkg_conf_t *conf, enum what_field_ty } for (k = 0; k < count; k++) { compound_depend_t *cdepend = - (what_field_type == WHATCONFLICTS) ? &pkg->conflicts[k] : &pkg->depends[k]; + (what_field_type == CONFLICTS) ? &pkg->conflicts[k] : &pkg->depends[k]; int l; + if (what_field_type != cdepend->type) + continue; for (l = 0; l < cdepend->possibility_count; l++) { depend_t *possibility = cdepend->possibilities[l]; if (possibility->pkg->state_flag & SF_MARKED) { @@ -1187,9 +1179,9 @@ static int opkg_what_depends_conflicts_cmd(opkg_conf_t *conf, enum what_field_ty pkg_mark_provides(pkg); changed++; - opkg_message(conf, OPKG_NOTICE, " %s", pkg->name); - if (conf->verbosity > 0) { + if (conf->verbosity >= OPKG_NOTICE) { char *ver = pkg_version_str_alloc(pkg); + opkg_message(conf, OPKG_NOTICE, " %s", pkg->name); opkg_message(conf, OPKG_NOTICE, " %s", ver); opkg_message(conf, OPKG_NOTICE, "\t%s %s", rel_str, possibility->pkg->name); if (possibility->version) { @@ -1223,7 +1215,7 @@ static int opkg_what_depends_conflicts_cmd(opkg_conf_t *conf, enum what_field_ty return 0; } -int pkg_mark_provides(pkg_t *pkg) +static int pkg_mark_provides(pkg_t *pkg) { int provides_count = pkg->provides_count; abstract_pkg_t **provides = pkg->provides; @@ -1237,26 +1229,26 @@ int pkg_mark_provides(pkg_t *pkg) static int opkg_whatdepends_recursively_cmd(opkg_conf_t *conf, int argc, char **argv) { - return opkg_what_depends_conflicts_cmd(conf, WHATDEPENDS, 1, argc, argv); + return opkg_what_depends_conflicts_cmd(conf, DEPEND, 1, argc, argv); } static int opkg_whatdepends_cmd(opkg_conf_t *conf, int argc, char **argv) { - return opkg_what_depends_conflicts_cmd(conf, WHATDEPENDS, 0, argc, argv); + return opkg_what_depends_conflicts_cmd(conf, DEPEND, 0, argc, argv); } static int opkg_whatsuggests_cmd(opkg_conf_t *conf, int argc, char **argv) { - return opkg_what_depends_conflicts_cmd(conf, WHATSUGGESTS, 0, argc, argv); + return opkg_what_depends_conflicts_cmd(conf, SUGGEST, 0, argc, argv); } static int opkg_whatrecommends_cmd(opkg_conf_t *conf, int argc, char **argv) { - return opkg_what_depends_conflicts_cmd(conf, WHATRECOMMENDS, 0, argc, argv); + return opkg_what_depends_conflicts_cmd(conf, RECOMMEND, 0, argc, argv); } static int opkg_whatconflicts_cmd(opkg_conf_t *conf, int argc, char **argv) { - return opkg_what_depends_conflicts_cmd(conf, WHATCONFLICTS, 0, argc, argv); + return opkg_what_depends_conflicts_cmd(conf, CONFLICTS, 0, argc, argv); } static int opkg_what_provides_replaces_cmd(opkg_conf_t *conf, enum what_field_type what_field_type, int argc, char **argv) @@ -1328,28 +1320,22 @@ static int opkg_search_cmd(opkg_conf_t *conf, int argc, char **argv) installed = pkg_vec_alloc(); pkg_hash_fetch_all_installed(&conf->pkg_hash, installed); + pkg_vec_sort(installed, pkg_compare_names); for (i=0; i < installed->len; i++) { pkg = installed->pkgs[i]; - installed_files = pkg_get_installed_files(pkg); + installed_files = pkg_get_installed_files(conf, pkg); - for (iter = installed_files->head; iter; iter = iter->next) { - installed_file = iter->data; - if (fnmatch(argv[0], installed_file, 0)==0) { - if (opkg_cb_list) opkg_cb_list(pkg->name, - installed_file, - pkg_version_str_alloc(pkg), - pkg->state_status, p_userdata); - } + for (iter = str_list_first(installed_files); iter; iter = str_list_next(installed_files, iter)) { + installed_file = (char *)iter->data; + if (fnmatch(argv[0], installed_file, 0)==0) + print_pkg(pkg); } pkg_free_installed_files(pkg); } - /* XXX: CLEANUP: It's not obvious from the name of - pkg_hash_fetch_all_installed that we need to call - pkg_vec_free to avoid a memory leak. */ pkg_vec_free(installed); return 0; @@ -1360,8 +1346,8 @@ static int opkg_compare_versions_cmd(opkg_conf_t *conf, int argc, char **argv) if (argc == 3) { /* this is a bit gross */ struct pkg p1, p2; - parseVersion(&p1, argv[0]); - parseVersion(&p2, argv[2]); + parse_version(&p1, argv[0]); + parse_version(&p2, argv[2]); return pkg_version_satisfied(&p1, &p2, argv[1]); } else { opkg_message(conf, OPKG_ERROR, @@ -1371,23 +1357,13 @@ static int opkg_compare_versions_cmd(opkg_conf_t *conf, int argc, char **argv) } } -#ifndef HOST_CPU_STR -#define HOST_CPU_STR__(X) #X -#define HOST_CPU_STR_(X) HOST_CPU_STR__(X) -#define HOST_CPU_STR HOST_CPU_STR_(HOST_CPU_FOO) -#endif - static int opkg_print_architecture_cmd(opkg_conf_t *conf, int argc, char **argv) { nv_pair_list_elt_t *l; - l = conf->arch_list.head; - while (l) { - nv_pair_t *nv = l->data; + list_for_each_entry(l, &conf->arch_list.head, node) { + nv_pair_t *nv = (nv_pair_t *)l->data; printf("arch %s %s\n", nv->name, nv->value); - l = l->next; } return 0; } - -