libopkg: support https_proxy
[project/opkg-lede.git] / libopkg / opkg_cmd.c
index ee5902175a983c79b46657976f19cb1badddbcac..6547775d1a57c762e582675ab12be671792a4147 100644 (file)
 #include "opkg_configure.h"
 #include "xsystem.h"
 
+int opkg_cli_argc = 0;
+const char **opkg_cli_argv = NULL;
+
 static void print_pkg(pkg_t * pkg)
 {
        char *version = pkg_version_str_alloc(pkg);
        char *description = pkg_get_string(pkg, PKG_DESCRIPTION);
-       printf("%s - %s", pkg->name, version);
+       const char *abiver;
+       char *tmp, *tmpname = NULL;
+
+       if (conf->strip_abi &&
+           (abiver = pkg_get_string(pkg, PKG_ABIVERSION)) &&
+           (strlen(pkg->name) > strlen(abiver))) {
+               tmpname = strdup(pkg->name);
+               tmp = &tmpname[strlen(tmpname) - strlen(abiver)];
+               if (!strncmp(abiver, tmp, strlen(abiver)))
+                       *tmp = '\0';
+       };
+
+       printf("%s - %s", tmpname?tmpname:pkg->name, version);
+
+       if (tmpname)
+               free(tmpname);
+
        if (conf->size)
                printf(" - %lu", (unsigned long) pkg_get_int(pkg, PKG_SIZE));
        if (description)
@@ -117,16 +136,8 @@ static int opkg_update_cmd(int argc, char **argv)
 
                src = (pkg_src_t *) iter->data;
 
-               if (src->extra_data && strcmp(src->extra_data, "__dummy__ "))
-                       continue;
-
-               if (src->extra_data)    /* debian style? */
-                       sprintf_alloc(&url, "%s/%s/%s", src->value,
-                                     src->extra_data,
-                                     src->gzip ? "Packages.gz" : "Packages");
-               else
-                       sprintf_alloc(&url, "%s/%s", src->value,
-                                     src->gzip ? "Packages.gz" : "Packages");
+               sprintf_alloc(&url, "%s/%s", src->value,
+                             src->gzip ? "Packages.gz" : "Packages");
 
                sprintf_alloc(&list_file_name, "%s/%s", lists_dir, src->name);
                pkglist_dl_error = 0;
@@ -146,12 +157,8 @@ static int opkg_update_cmd(int argc, char **argv)
                if (pkglist_dl_error == 0 && 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");
+                       sprintf_alloc(&url, "%s/%s", src->value,
+                                     "Packages.sig");
 
                        /* create temporary file for it */
                        char *tmp_file_name;
@@ -458,7 +465,7 @@ static int opkg_install_cmd(int argc, char **argv)
        }
 
        pkg_hash_load_package_details();
-       pkg_hash_load_status_files();
+       pkg_hash_load_status_files(NULL, NULL);
 
        if (conf->force_reinstall) {
                int saved_force_depends = conf->force_depends;
@@ -569,31 +576,118 @@ static int opkg_download_cmd(int argc, char **argv)
        return err;
 }
 
+struct opkg_list_find_cmd_item {
+       int size;
+       char *name;
+       char *version;
+       char *description;
+};
+
+struct opkg_list_find_cmd_args {
+       int use_desc;
+       int set_status;
+       char *pkg_name;
+       struct opkg_list_find_cmd_item **items;
+       size_t n_items;
+};
+
+static void opkg_list_find_cmd_cb(pkg_t *pkg, void *priv)
+{
+       struct opkg_list_find_cmd_args *args = priv;
+       char *description = pkg_get_string(pkg, PKG_DESCRIPTION);
+       char *version = pkg_version_str_alloc(pkg);
+       struct opkg_list_find_cmd_item *item;
+       char *nameptr, *versionptr, *descriptionptr, *tmp;
+       const char *abiver;
+       int i, found = 0;
+
+       /* if we have package name or pattern and pkg does not match, then skip it */
+       if (args->pkg_name && fnmatch(args->pkg_name, pkg->name, conf->nocase) &&
+           (!args->use_desc || !description
+            || fnmatch(args->pkg_name, description, conf->nocase)))
+               goto out;
+
+       if (args->set_status) {
+               for (i = 0; i < args->n_items; i++) {
+                       if (!strcmp(args->items[i]->name, pkg->name)) {
+                               found = 1;
+                               break;
+                       }
+               }
+       }
+
+       if (!found) {
+               item = calloc_a(sizeof(*item),
+                               &nameptr, strlen(pkg->name) + 1,
+                               &versionptr, strlen(version) + 1,
+                               &descriptionptr, description ? strlen(description) + 1 : 0);
+
+               item->name = strcpy(nameptr, pkg->name);
+
+               if (conf->strip_abi &&
+                   (abiver = pkg_get_string(pkg, PKG_ABIVERSION)) &&
+                   (strlen(item->name) > strlen(abiver))) {
+                       tmp = &item->name[strlen(item->name) - strlen(abiver)];
+                       if (!strncmp(abiver, tmp, strlen(abiver)))
+                               *tmp = '\0';
+               };
+
+               item->size = pkg_get_int(pkg, PKG_SIZE);
+               item->version = strcpy(versionptr, version);
+               item->description = description ? strcpy(descriptionptr, description) : NULL;
+
+               args->items = xrealloc(args->items, sizeof(item) * (args->n_items + 1));
+               args->items[args->n_items++] = item;
+       }
+
+out:
+       pkg_deinit(pkg);
+       free(pkg);
+       free(version);
+}
+
+static int opkg_list_find_cmd_sort(const void *a, const void *b)
+{
+       const struct opkg_list_find_cmd_item *pkg_a = *(const struct opkg_list_find_cmd_item **)a;
+       const struct opkg_list_find_cmd_item *pkg_b = *(const struct opkg_list_find_cmd_item **)b;
+       return strcmp(pkg_a->name, pkg_b->name);
+}
+
 static int opkg_list_find_cmd(int argc, char **argv, int use_desc)
 {
        int i;
-       pkg_vec_t *available;
-       pkg_t *pkg;
-       char *pkg_name = NULL;
-       char *description;
+       struct opkg_list_find_cmd_args args = {
+               .use_desc = use_desc,
+               .pkg_name = (argc > 0) ? argv[0] : NULL
+       };
 
-       if (argc > 0) {
-               pkg_name = argv[0];
-       }
-       available = pkg_vec_alloc();
-       pkg_hash_fetch_available(available);
-       pkg_vec_sort(available, pkg_compare_names);
-       for (i = 0; i < available->len; i++) {
-               pkg = available->pkgs[i];
-               description = use_desc ? pkg_get_string(pkg, PKG_DESCRIPTION) : NULL;
-               /* if we have package name or pattern and pkg does not match, then skip it */
-               if (pkg_name && fnmatch(pkg_name, pkg->name, conf->nocase) &&
-                   (!use_desc || !description
-                    || fnmatch(pkg_name, description, conf->nocase)))
-                       continue;
-               print_pkg(pkg);
+       args.set_status = 0;
+       pkg_hash_load_feeds(SF_NEED_DETAIL, opkg_list_find_cmd_cb, &args);
+
+       args.set_status = 1;
+       pkg_hash_load_status_files(opkg_list_find_cmd_cb, &args);
+
+       if (args.n_items > 1)
+               qsort(args.items, args.n_items, sizeof(args.items[0]),
+                     opkg_list_find_cmd_sort);
+
+       for (i = 0; i < args.n_items; i++) {
+               printf("%s - %s",
+                      args.items[i]->name,
+                      args.items[i]->version);
+
+               if (conf->size)
+                       printf(" - %lu", (unsigned long) args.items[i]->size);
+
+               if (args.items[i]->description)
+                       printf(" - %s", args.items[i]->description);
+
+               printf("\n");
+
+               free(args.items[i]);
        }
-       pkg_vec_free(available);
+
+       free(args.items);
 
        return 0;
 }
@@ -1217,12 +1311,21 @@ static int opkg_search_cmd(int argc, char **argv)
 
 static int opkg_compare_versions_cmd(int argc, char **argv)
 {
+       int rc;
+       pkg_t *p1, *p2;
+
        if (argc == 3) {
                /* this is a bit gross */
-               struct pkg p1, p2;
-               parse_version(&p1, argv[0]);
-               parse_version(&p2, argv[2]);
-               return pkg_version_satisfied(&p1, &p2, argv[1]) ? 0 : 1;
+               p1 = pkg_new();
+               p2 = pkg_new();
+               parse_version(p1, argv[0]);
+               parse_version(p2, argv[2]);
+               rc = pkg_version_satisfied(p1, p2, argv[1]);
+               pkg_deinit(p1);
+               pkg_deinit(p2);
+               free(p1);
+               free(p2);
+               return rc ? 0 : 1;
        } else {
                opkg_msg(ERROR,
                         "opkg compare_versions <v1> <op> <v2>\n"
@@ -1280,10 +1383,8 @@ static opkg_cmd_t cmds[] = {
        {"find", 1, (opkg_cmd_fun_t) opkg_find_cmd, PFM_SOURCE},
        {"download", 1, (opkg_cmd_fun_t) opkg_download_cmd,
         PFM_DESCRIPTION | PFM_SOURCE},
-       {"compare_versions", 1, (opkg_cmd_fun_t) opkg_compare_versions_cmd,
-        PFM_DESCRIPTION | PFM_SOURCE},
-       {"compare-versions", 1, (opkg_cmd_fun_t) opkg_compare_versions_cmd,
-        PFM_DESCRIPTION | PFM_SOURCE},
+       {"compare_versions", 1, (opkg_cmd_fun_t) opkg_compare_versions_cmd, 0},
+       {"compare-versions", 1, (opkg_cmd_fun_t) opkg_compare_versions_cmd, 0},
        {"print-architecture", 0, (opkg_cmd_fun_t) opkg_print_architecture_cmd,
         PFM_DESCRIPTION | PFM_SOURCE},
        {"print_architecture", 0, (opkg_cmd_fun_t) opkg_print_architecture_cmd,
@@ -1329,5 +1430,7 @@ opkg_cmd_t *opkg_cmd_find(const char *name)
 
 int opkg_cmd_exec(opkg_cmd_t * cmd, int argc, const char **argv)
 {
+       opkg_cli_argc = argc;
+       opkg_cli_argv = argv;
        return (cmd->fun) (argc, argv);
 }