cli: default to /etc/opkg.conf
[oweals/opkg-lede.git] / libopkg / pkg_hash.c
index f72ed26e52fc3845e9f29f1c1911605d3dd37cd6..2a76be886bff273a12eafdce8cca2bb246174daa 100644 (file)
@@ -1,7 +1,7 @@
 /* opkg_hash.c - the opkg package management system
 
    Steven M. Ayer
-   
+
    Copyright (C) 2002 Compaq Computer Corporation
 
    This program is free software; you can redistribute it and/or
@@ -18,6 +18,7 @@
 #include <stdio.h>
 
 #include "hash_table.h"
+#include "release.h"
 #include "pkg.h"
 #include "opkg_message.h"
 #include "pkg_vec.h"
@@ -44,7 +45,7 @@ free_pkgs(const char *key, void *entry, void *data)
        /* Each entry in the hash table is an abstract package, which contains
         * a list of packages that provide the abstract package.
         */
-  
+
        ab_pkg = (abstract_pkg_t*) entry;
 
        if (ab_pkg->pkgs) {
@@ -69,6 +70,32 @@ pkg_hash_deinit(void)
        hash_table_deinit(&conf->pkg_hash);
 }
 
+int
+dist_hash_add_from_file(const char *lists_dir, pkg_src_t *dist)
+{
+       nv_pair_list_elt_t *l;
+       char *list_file, *subname;
+
+       list_for_each_entry(l , &conf->arch_list.head, node) {
+               nv_pair_t *nv = (nv_pair_t *)l->data;
+               sprintf_alloc(&subname, "%s-%s", dist->name, nv->name);
+               sprintf_alloc(&list_file, "%s/%s", lists_dir, subname);
+
+               if (file_exists(list_file)) {
+                       if (pkg_hash_add_from_file(list_file, dist, NULL, 0)) {
+                               free(list_file);
+                               return -1;
+                       }
+                       pkg_src_list_append (&conf->pkg_src_list, subname, dist->value, "__dummy__", 0);
+               }
+
+               free(list_file);
+       }
+
+       return 0;
+}
+
+
 int
 pkg_hash_add_from_file(const char *file_name,
                        pkg_src_t *src, pkg_dest_t *dest, int is_status_file)
@@ -131,7 +158,7 @@ int
 pkg_hash_load_feeds(void)
 {
        pkg_src_list_elt_t *iter;
-       pkg_src_t *src;
+       pkg_src_t *src, *subdist;
        char *list_file, *lists_dir;
 
        opkg_msg(INFO, "\n");
@@ -139,6 +166,40 @@ pkg_hash_load_feeds(void)
        lists_dir = conf->restrict_to_default_dest ?
                conf->default_dest->lists_dir : conf->lists_dir;
 
+       for (iter = void_list_first(&conf->dist_src_list); iter;
+                       iter = void_list_next(&conf->dist_src_list, iter)) {
+
+               src = (pkg_src_t *)iter->data;
+
+               sprintf_alloc(&list_file, "%s/%s", lists_dir, src->name);
+
+               if (file_exists(list_file)) {
+                       int i;
+                       release_t *release = release_new();
+                       if(release_init_from_file(release, list_file)) {
+                               free(list_file);
+                               return -1;
+                       }
+
+                       unsigned int ncomp;
+                       const char **comps = release_comps(release, &ncomp);
+                       subdist = (pkg_src_t *) xmalloc(sizeof(pkg_src_t));
+                       memcpy(subdist, src, sizeof(pkg_src_t));
+
+                       for(i = 0; i < ncomp; i++){
+                               subdist->name = NULL;
+                               sprintf_alloc(&subdist->name, "%s-%s", src->name, comps[i]);
+                               if (dist_hash_add_from_file(lists_dir, subdist)) {
+                                       free(subdist->name); free(subdist);
+                                       free(list_file);
+                                       return -1;
+                               }
+                       }
+                       free(subdist->name); free(subdist);
+               }
+               free(list_file);
+       }
+
        for (iter = void_list_first(&conf->pkg_src_list); iter;
                        iter = void_list_next(&conf->pkg_src_list, iter)) {
 
@@ -171,7 +232,7 @@ pkg_hash_load_status_files(void)
 
        for (iter = void_list_first(&conf->pkg_dest_list); iter;
                        iter = void_list_next(&conf->pkg_dest_list, iter)) {
-       
+
                dest = (pkg_dest_t *)iter->data;
 
                if (file_exists(dest->status_file_name)) {
@@ -247,7 +308,7 @@ pkg_hash_fetch_best_installation_candidate(abstract_pkg_t *apkg,
          }
 
          if (replacement_apkg)
-              opkg_msg(DEBUG, "replacement_apkg=%s for provider_apkg=%s.\n", 
+              opkg_msg(DEBUG, "replacement_apkg=%s for provider_apkg=%s.\n",
                            replacement_apkg->name, provider_apkg->name);
 
          if (replacement_apkg && (replacement_apkg != provider_apkg)) {
@@ -262,7 +323,7 @@ pkg_hash_fetch_best_installation_candidate(abstract_pkg_t *apkg,
                               provider_apkg->name);
               continue;
          }
-    
+
 
          /* now check for supported architecture */
          {
@@ -274,7 +335,7 @@ pkg_hash_fetch_best_installation_candidate(abstract_pkg_t *apkg,
                    opkg_msg(DEBUG, "%s arch=%s arch_priority=%d version=%s.\n",
                                 maybe->name, maybe->architecture,
                                 maybe->arch_priority, maybe->version);
-                    /* We make sure not to add the same package twice. Need to search for the reason why 
+                    /* We make sure not to add the same package twice. Need to search for the reason why
                        they show up twice sometimes. */
                    if ((maybe->arch_priority > 0) && (! pkg_vec_contains(matching_pkgs, maybe))) {
                         max_count++;
@@ -313,7 +374,7 @@ pkg_hash_fetch_best_installation_candidate(abstract_pkg_t *apkg,
              good_pkg_by_name = matching;
             /* It has been provided by hand, so it is what user want */
              if (matching->provided_by_hand == 1)
-                break;                                 
+                break;
           }
      }
 
@@ -344,7 +405,7 @@ pkg_hash_fetch_best_installation_candidate(abstract_pkg_t *apkg,
                                matching->name, prio);
                   }
               }
-          
+
           }
 
      if (conf->verbosity >= INFO && matching_apkgs->len > 1) {
@@ -364,7 +425,7 @@ pkg_hash_fetch_best_installation_candidate(abstract_pkg_t *apkg,
      abstract_pkg_vec_free(matching_apkgs);
      abstract_pkg_vec_free(providers);
 
-     if (good_pkg_by_name) {   /* We found a good candidate, we will install it */ 
+     if (good_pkg_by_name) {   /* We found a good candidate, we will install it */
          return good_pkg_by_name;
      }
      if (held_pkg) {
@@ -404,7 +465,7 @@ pkg_name_constraint_fcn(pkg_t *pkg, void *cdata)
        if (strcmp(pkg->name, name) == 0)
                return 1;
        else
-               return 0;   
+               return 0;
 }
 
 static pkg_vec_t *
@@ -449,10 +510,10 @@ pkg_hash_fetch_by_name_version(const char *pkg_name, const char * version)
        pkg_vec_t * vec;
        int i;
        char *version_str = NULL;
-    
+
        if(!(vec = pkg_vec_fetch_by_name(pkg_name)))
                return NULL;
-    
+
        for(i = 0; i < vec->len; i++) {
                version_str = pkg_version_str_alloc(vec->pkgs[i]);
                if(!strcmp(version_str, version)) {
@@ -464,7 +525,7 @@ pkg_hash_fetch_by_name_version(const char *pkg_name, const char * version)
 
        if(i == vec->len)
                return NULL;
-    
+
        return vec->pkgs[i];
 }
 
@@ -619,37 +680,47 @@ hash_insert_pkg(pkg_t *pkg, int set_status)
        pkg->parent = ab_pkg;
 }
 
-
-pkg_t *
-file_hash_get_file_owner(const char *file_name)
+static const char *
+strip_offline_root(const char *file_name)
 {
+       unsigned int len;
+
        if (conf->offline_root) {
-               unsigned int len = strlen(conf->offline_root);
-               if (strncmp(file_name, conf->offline_root, len) == 0) {
+               len = strlen(conf->offline_root);
+               if (strncmp(file_name, conf->offline_root, len) == 0)
                        file_name += len;
-               }
        }
 
+       return file_name;
+}
+
+void
+file_hash_remove(const char *file_name)
+{
+       file_name = strip_offline_root(file_name);
+       hash_table_remove(&conf->file_hash, file_name);
+}
+
+pkg_t *
+file_hash_get_file_owner(const char *file_name)
+{
+       file_name = strip_offline_root(file_name);
        return hash_table_get(&conf->file_hash, file_name);
 }
 
 void
 file_hash_set_file_owner(const char *file_name, pkg_t *owning_pkg)
 {
-       pkg_t *old_owning_pkg = hash_table_get(&conf->file_hash, file_name);
+       pkg_t *old_owning_pkg;
        int file_name_len = strlen(file_name);
 
        if (file_name[file_name_len -1] == '/')
                return;
 
-       if (conf->offline_root) {
-               unsigned int len = strlen(conf->offline_root);
-               if (strncmp(file_name, conf->offline_root, len) == 0) {
-                       file_name += len;
-               }
-       }
+       file_name = strip_offline_root(file_name);
 
-       hash_table_insert(&conf->file_hash, file_name, owning_pkg); 
+       old_owning_pkg = hash_table_get(&conf->file_hash, file_name);
+       hash_table_insert(&conf->file_hash, file_name, owning_pkg);
 
        if (old_owning_pkg) {
                pkg_get_installed_files(old_owning_pkg);