The compiler almost certainly knows better.
[project/opkg-lede.git] / libopkg / opkg_conf.c
index 8cda3216dace84a32269b68dc39555611cc4587d..1312c417165189b1841930fa80cd0276ad0c041e 100644 (file)
@@ -1,4 +1,4 @@
-/* opkg_conf.c - the itsy package management system
+/* opkg_conf.c - the opkg package management system
 
    Carl D. Worth
 
    General Public License for more details.
 */
 
-#include <glob.h>
-
-#include "opkg.h"
+#include "includes.h"
 #include "opkg_conf.h"
+#include "opkg_error.h"
 
 #include "xregex.h"
 #include "sprintf_alloc.h"
-#include "opkg_conf.h"
+#include "args.h"
 #include "opkg_message.h"
 #include "file_util.h"
 #include "str_util.h"
 #include "xsystem.h"
+#include <glob.h>
+#include "opkg_defines.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+extern char *conf_file_dir;
 
 static int opkg_conf_parse_file(opkg_conf_t *conf, const char *filename,
                                pkg_src_list_t *pkg_src_list,
                                nv_pair_list_t *tmp_dest_nv_pair_list,
                                char **tmp_lists_dir);
-static int opkg_init_options_array(const opkg_conf_t *conf, opkg_option_t **options);
 static int opkg_conf_set_option(const opkg_option_t *options,
                                const char *name, const char *value);
 static int opkg_conf_set_default_dest(opkg_conf_t *conf,
@@ -45,31 +52,35 @@ static int set_and_load_pkg_dest_list(opkg_conf_t *conf,
 int opkg_init_options_array(const opkg_conf_t *conf, opkg_option_t **options)
 {
      opkg_option_t tmp[] = {
+         { "cache", OPKG_OPT_TYPE_STRING, &conf->cache},
          { "force_defaults", OPKG_OPT_TYPE_BOOL, &conf->force_defaults },
+          { "force_maintainer", OPKG_OPT_TYPE_BOOL, &conf->force_maintainer }, 
          { "force_depends", OPKG_OPT_TYPE_BOOL, &conf->force_depends },
          { "force_overwrite", OPKG_OPT_TYPE_BOOL, &conf->force_overwrite },
          { "force_downgrade", OPKG_OPT_TYPE_BOOL, &conf->force_downgrade },
          { "force_reinstall", OPKG_OPT_TYPE_BOOL, &conf->force_reinstall },
          { "force_space", OPKG_OPT_TYPE_BOOL, &conf->force_space },
+          { "check_signature", OPKG_OPT_TYPE_INT, &conf->check_signature }, 
          { "ftp_proxy", OPKG_OPT_TYPE_STRING, &conf->ftp_proxy },
          { "http_proxy", OPKG_OPT_TYPE_STRING, &conf->http_proxy },
-         { "multiple_providers", OPKG_OPT_TYPE_BOOL, &conf->multiple_providers },
          { "no_proxy", OPKG_OPT_TYPE_STRING, &conf->no_proxy },
          { "test", OPKG_OPT_TYPE_INT, &conf->noaction },
          { "noaction", OPKG_OPT_TYPE_INT, &conf->noaction },
          { "nodeps", OPKG_OPT_TYPE_BOOL, &conf->nodeps },
          { "offline_root", OPKG_OPT_TYPE_STRING, &conf->offline_root },
+         { "offline_root_path", OPKG_OPT_TYPE_STRING, &conf->offline_root_path },
          { "offline_root_post_script_cmd", OPKG_OPT_TYPE_STRING, &conf->offline_root_post_script_cmd },
          { "offline_root_pre_script_cmd", OPKG_OPT_TYPE_STRING, &conf->offline_root_pre_script_cmd },
          { "proxy_passwd", OPKG_OPT_TYPE_STRING, &conf->proxy_passwd },
          { "proxy_user", OPKG_OPT_TYPE_STRING, &conf->proxy_user },
          { "query-all", OPKG_OPT_TYPE_BOOL, &conf->query_all },
-         { "verbose-wget", OPKG_OPT_TYPE_BOOL, &conf->verbose_wget },
          { "verbosity", OPKG_OPT_TYPE_BOOL, &conf->verbosity },
+         { "signature_ca_file", OPKG_OPT_TYPE_STRING, &conf->signature_ca_file },
+         { "signature_ca_path", OPKG_OPT_TYPE_STRING, &conf->signature_ca_path },
          { NULL }
      };
 
-     *options = (opkg_option_t *)malloc(sizeof(tmp));
+     *options = (opkg_option_t *)calloc(1, sizeof(tmp));
      if ( options == NULL ){
         fprintf(stderr,"%s: Unable to allocate memory\n",__FUNCTION__);
         return -1;
@@ -100,12 +111,13 @@ static void opkg_conf_free_string(char **conf_str)
 int opkg_conf_init(opkg_conf_t *conf, const args_t *args)
 {
      int err;
+     int errno_copy;
      char *tmp_dir_base;
      nv_pair_list_t tmp_dest_nv_pair_list;
-     char * lists_dir =NULL;
+     char *lists_dir = NULL, *lock_file = NULL;
      glob_t globbuf;
-     char *etc_opkg_conf_pattern = "/etc/opkg/*.conf";
-     char *pending_dir  =NULL;
+     char *etc_opkg_conf_pattern;
+     char *pending_dir NULL;
 
      memset(conf, 0, sizeof(opkg_conf_t));
 
@@ -119,6 +131,29 @@ int opkg_conf_init(opkg_conf_t *conf, const args_t *args)
      conf->restrict_to_default_dest = 0;
      conf->default_dest = NULL;
 
+     /* check for lock file */
+     if (args->offline_root)
+       sprintf_alloc (&lock_file, "%s/%s/lock", args->offline_root, OPKG_STATE_DIR_PREFIX);
+     else
+       sprintf_alloc (&lock_file, "%s/lock", OPKG_STATE_DIR_PREFIX);
+
+     conf->lock_fd = creat (lock_file, S_IRUSR | S_IWUSR | S_IRGRP);
+     err = lockf (conf->lock_fd, F_TLOCK, 0);
+     errno_copy = errno;
+
+     free (lock_file);
+
+     if (err)
+     {
+       if(args->offline_root) {
+         opkg_message (conf, OPKG_ERROR, "Could not obtain administrative lock for offline root (ERR: %s)  at %s/%s/lock\n",
+                 strerror(errno_copy), args->offline_root, OPKG_STATE_DIR_PREFIX);
+       } else {
+         opkg_message (conf, OPKG_ERROR, "Could not obtain administrative lock (ERR: %s) at %s/lock\n",
+                 strerror(errno_copy), OPKG_STATE_DIR_PREFIX);
+       }
+       return OPKG_CONF_ERR_LOCK;
+     }
 
      if (args->tmp_dir)
          tmp_dir_base = args->tmp_dir;
@@ -131,32 +166,9 @@ int opkg_conf_init(opkg_conf_t *conf, const args_t *args)
      if (conf->tmp_dir == NULL) {
          fprintf(stderr, "%s: Failed to create temporary directory `%s': %s\n",
                  __FUNCTION__, conf->tmp_dir, strerror(errno));
-         return errno;
+         return OPKG_CONF_ERR_TMP_DIR;
      }
 
-     conf->force_depends = 0;
-     conf->force_defaults = 0;
-     conf->force_overwrite = 0;
-     conf->force_downgrade = 0;
-     conf->force_reinstall = 0;
-     conf->force_space = 0;
-     conf->force_removal_of_essential_packages = 0;
-     conf->force_removal_of_dependent_packages = 0;
-     conf->nodeps = 0;
-     conf->verbose_wget = 0;
-     conf->offline_root = NULL;
-     conf->offline_root_pre_script_cmd = NULL;
-     conf->offline_root_post_script_cmd = NULL;
-     conf->multiple_providers = 0;
-     conf->verbosity = 1;
-     conf->noaction = 0;
-
-     conf->http_proxy = NULL;
-     conf->ftp_proxy = NULL;
-     conf->no_proxy = NULL;
-     conf->proxy_user = NULL;
-     conf->proxy_passwd = NULL;
-
      pkg_hash_init("pkg-hash", &conf->pkg_hash, OPKG_CONF_DEFAULT_HASH_LEN);
      hash_table_init("file-hash", &conf->file_hash, OPKG_CONF_DEFAULT_HASH_LEN);
      hash_table_init("obs-file-hash", &conf->obs_file_hash, OPKG_CONF_DEFAULT_HASH_LEN);
@@ -169,25 +181,23 @@ int opkg_conf_init(opkg_conf_t *conf, const args_t *args)
               if (opkg_conf_parse_file(conf, args->conf_file,
                                    &conf->pkg_src_list, &tmp_dest_nv_pair_list,&lists_dir)<0) {
                    /* Memory leakage from opkg_conf_parse-file */
-                   return -1;
+                   return OPKG_CONF_ERR_PARSE;
                }
-                   
      }
 
-     /* if (!lists_dir ){*/
      if (strlen(lists_dir)<=1 ){
         lists_dir = realloc(lists_dir,strlen(OPKG_CONF_LISTS_DIR)+2);
         sprintf (lists_dir,"%s",OPKG_CONF_LISTS_DIR);
      }
 
      if (args->offline_root) {
-            char *tmp = malloc(strlen(lists_dir) + strlen(args->offline_root) + 1);
+            char *tmp;
             sprintf_alloc(&tmp, "%s/%s",args->offline_root,lists_dir);
             free(lists_dir);
             lists_dir = tmp;
      }
 
-     pending_dir = malloc(strlen(lists_dir)+strlen("/pending")+5);
+     pending_dir = calloc(1, strlen(lists_dir)+strlen("/pending")+5);
      snprintf(pending_dir,strlen(lists_dir)+strlen("/pending") ,"%s%s",lists_dir,"/pending");
 
      conf->lists_dir = strdup(lists_dir);
@@ -195,8 +205,11 @@ int opkg_conf_init(opkg_conf_t *conf, const args_t *args)
 
      if (args->offline_root) 
          sprintf_alloc(&etc_opkg_conf_pattern, "%s/etc/opkg/*.conf", args->offline_root);
+     else
+         sprintf_alloc(&etc_opkg_conf_pattern, "%s/*.conf", conf_file_dir);
      memset(&globbuf, 0, sizeof(globbuf));
      err = glob(etc_opkg_conf_pattern, 0, NULL, &globbuf);
+     free (etc_opkg_conf_pattern);
      if (!err) {
          int i;
          for (i = 0; i < globbuf.gl_pathc; i++) {
@@ -204,7 +217,7 @@ int opkg_conf_init(opkg_conf_t *conf, const args_t *args)
                    if ( opkg_conf_parse_file(conf, globbuf.gl_pathv[i], 
                                         &conf->pkg_src_list, &tmp_dest_nv_pair_list,&lists_dir)<0) {
                         /* Memory leakage from opkg_conf_parse-file */
-                        return -1;
+                        return OPKG_CONF_ERR_PARSE;
                    }
          }
      }
@@ -218,7 +231,7 @@ int opkg_conf_init(opkg_conf_t *conf, const args_t *args)
      }
 
      /* Even if there is no conf file, we'll need at least one dest. */
-     if (tmp_dest_nv_pair_list.head == NULL) {
+     if (nv_pair_list_empty(&tmp_dest_nv_pair_list)) {
          nv_pair_list_append(&tmp_dest_nv_pair_list,
                              OPKG_CONF_DEFAULT_DEST_NAME,
                              OPKG_CONF_DEFAULT_DEST_ROOT_DIR);
@@ -240,6 +253,9 @@ int opkg_conf_init(opkg_conf_t *conf, const args_t *args)
      if (args->force_defaults) {
          conf->force_defaults = 1;
      }
+     if (args->force_maintainer) {
+          conf->force_maintainer = 1;
+     }
      if (args->force_overwrite) {
          conf->force_overwrite = 1;
      }
@@ -264,23 +280,21 @@ int opkg_conf_init(opkg_conf_t *conf, const args_t *args)
      if (args->query_all) {
          conf->query_all = 1;
      }
-     if (args->verbose_wget) {
-         conf->verbose_wget = 1;
-     }
-     if (args->multiple_providers) {
-         conf->multiple_providers = 1;
-     }
      if (args->verbosity != conf->verbosity) {
          conf->verbosity = args->verbosity;
      } 
 
      opkg_conf_override_string(&conf->offline_root, 
                               args->offline_root);
+     opkg_conf_override_string(&conf->offline_root_path, 
+                              args->offline_root_path);
      opkg_conf_override_string(&conf->offline_root_pre_script_cmd, 
                               args->offline_root_pre_script_cmd);
      opkg_conf_override_string(&conf->offline_root_post_script_cmd, 
                               args->offline_root_post_script_cmd);
 
+     opkg_conf_override_string(&conf->cache, args->cache);
+
 /* Pigi: added a flag to disable the checking of structures if the command does not need to 
          read anything from there.
 */
@@ -297,7 +311,7 @@ int opkg_conf_init(opkg_conf_t *conf, const args_t *args)
         if (args->dest) {
             err = opkg_conf_set_default_dest(conf, args->dest);
             if (err) {
-                 return err;
+                 return OPKG_CONF_ERR_DEFAULT_DEST;
             }
         }
      }
@@ -332,6 +346,8 @@ void opkg_conf_deinit(opkg_conf_t *conf)
 #endif /* OPKG_DEBUG_NO_TMP_CLEANUP */
 
      free(conf->tmp_dir); /*XXX*/
+     free(conf->lists_dir);
+     free(conf->pending_dir);
 
      pkg_src_list_deinit(&conf->pkg_src_list);
      pkg_dest_list_deinit(&conf->pkg_dest_list);
@@ -344,9 +360,12 @@ void opkg_conf_deinit(opkg_conf_t *conf)
                    hash_table_deinit(&conf->obs_file_hash);
 
      opkg_conf_free_string(&conf->offline_root);
+     opkg_conf_free_string(&conf->offline_root_path);
      opkg_conf_free_string(&conf->offline_root_pre_script_cmd);
      opkg_conf_free_string(&conf->offline_root_post_script_cmd);
 
+     opkg_conf_free_string(&conf->cache);
+
      if (conf->verbosity > 1) { 
          int i;
          hash_table_t *hashes[] = {
@@ -383,8 +402,8 @@ static int opkg_conf_set_default_dest(opkg_conf_t *conf,
      pkg_dest_list_elt_t *iter;
      pkg_dest_t *dest;
 
-     for (iter = conf->pkg_dest_list.head; iter; iter = iter->next) {
-         dest = iter->data;
+     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 (strcmp(dest->name, default_dest_name) == 0) {
               conf->default_dest = dest;
               conf->restrict_to_default_dest = 1;
@@ -403,8 +422,8 @@ static int set_and_load_pkg_src_list(opkg_conf_t *conf, pkg_src_list_t *pkg_src_
      pkg_src_t *src;
      char *list_file;
 
-     for (iter = pkg_src_list->head; iter; iter = iter->next) {
-          src = iter->data;
+     for (iter = void_list_first(pkg_src_list); iter; iter = void_list_next(pkg_src_list, iter)) {
+          src = (pkg_src_t *)iter->data;
          if (src == NULL) {
               continue;
          }
@@ -429,8 +448,8 @@ static int set_and_load_pkg_dest_list(opkg_conf_t *conf, nv_pair_list_t *nv_pair
      pkg_dest_t *dest;
      char *root_dir;
 
-     for (iter = nv_pair_list->head; iter; iter = iter->next) {
-         nv_pair = iter->data;
+     for (iter = nv_pair_list_first(nv_pair_list); iter; iter = nv_pair_list_next(nv_pair_list, iter)) {
+         nv_pair = (nv_pair_t *)iter->data;
 
          if (conf->offline_root) {
               sprintf_alloc(&root_dir, "%s%s", conf->offline_root, nv_pair->value);
@@ -580,7 +599,7 @@ static int opkg_conf_parse_file(opkg_conf_t *conf, const char *filename,
                    opkg_message(conf, OPKG_NOTICE, "defaulting architecture %s priority to 10\n", name);
                    value = strdup("10");
               }
-              nv_pair_list_append(&conf->arch_list, strdup(name), strdup(value));
+              nv_pair_list_append(&conf->arch_list, name, value);
          } else {
               fprintf(stderr, "WARNING: Ignoring unknown configuration "
                       "parameter: %s %s %s\n", type, name, value);
@@ -646,22 +665,21 @@ static int opkg_conf_set_option(const opkg_option_t *options,
 
 int opkg_conf_write_status_files(opkg_conf_t *conf)
 {
-     pkg_dest_list_elt_t *iter;
      pkg_dest_t *dest;
      pkg_vec_t *all;
      pkg_t *pkg;
-     register int i;
+     int i;
      int err;
+     FILE * status_file=NULL;
 
      if (conf->noaction)
          return 0;
-     for (iter = conf->pkg_dest_list.head; iter; iter = iter->next) {
-         dest = iter->data;
-         dest->status_file = fopen(dest->status_file_tmp_name, "w");
-         if (dest->status_file == NULL) {
-              fprintf(stderr, "%s: Can't open status file: %s for writing: %s\n",
-                      __FUNCTION__, dest->status_file_name, strerror(errno));
-         }
+
+     dest = (pkg_dest_t *)void_list_first(&conf->pkg_dest_list)->data;
+     status_file = fopen(dest->status_file_tmp_name, "w");
+     if (status_file == NULL) {
+         fprintf(stderr, "%s: Can't open status file: %s for writing: %s\n",
+                 __FUNCTION__, dest->status_file_tmp_name, strerror(errno));
      }
 
      all = pkg_vec_alloc();
@@ -685,29 +703,25 @@ int opkg_conf_write_status_files(opkg_conf_t *conf)
                       __FUNCTION__, pkg->name);
               continue;
          }
-         if (pkg->dest->status_file) {
-              pkg_print_status(pkg, pkg->dest->status_file);
+         if (status_file) {
+              pkg_print_status(pkg, status_file);
          }
      }
 
      pkg_vec_free(all);
 
-     for (iter = conf->pkg_dest_list.head; iter; iter = iter->next) {
-         dest = iter->data;
-         if (dest->status_file) {
-              err = ferror(dest->status_file);
-              fclose(dest->status_file);
-              dest->status_file = NULL;
-              if (!err) {
-                   file_move(dest->status_file_tmp_name, dest->status_file_name);
-              } else {
-                   fprintf(stderr, "%s: ERROR: An error has occurred writing %s, "
-                           "retaining old %s\n", __FUNCTION__, 
-                           dest->status_file_tmp_name, dest->status_file_name);
-              }
-         }
+     if (status_file) {
+         err = ferror(status_file);
+         fclose(status_file);
+         if (!err) {
+             file_move(dest->status_file_tmp_name, dest->status_file_name);
+         } else {
+             fprintf(stderr, "%s: ERROR: An error has occurred writing %s, "
+                     "retaining old %s\n", __FUNCTION__,
+                     dest->status_file_tmp_name, dest->status_file_name);
+         }
+         status_file = NULL;
      }
-
      return 0;
 }