opkg: improve opkg_install error reporting and include a check to verify repository...
authorticktock35 <ticktock35@e8e0d7a0-c8d9-11dd-a880-a1081c7ac358>
Mon, 15 Dec 2008 05:20:28 +0000 (05:20 +0000)
committerticktock35 <ticktock35@e8e0d7a0-c8d9-11dd-a880-a1081c7ac358>
Mon, 15 Dec 2008 05:20:28 +0000 (05:20 +0000)
git-svn-id: http://opkg.googlecode.com/svn/trunk@123 e8e0d7a0-c8d9-11dd-a880-a1081c7ac358

libopkg/opkg.c
libopkg/opkg.h
libopkg/opkg_install.c
libopkg/opkg_install.h
tests/libopkg_test.c

index ec524f9..6cd0423 100644 (file)
@@ -407,7 +407,7 @@ opkg_install_package (opkg_t *opkg, const char *package_name, opkg_progress_call
   {
     /* XXX: Error: Could not satisfy dependencies */
     pkg_vec_free (deps);
-    return OPKG_DEPENDANCIES_FAILED;
+    return OPKG_DEPENDENCIES_FAILED;
   }
 
   /* insert the package we are installing so that we download it */
@@ -487,7 +487,17 @@ opkg_install_package (opkg_t *opkg, const char *package_name, opkg_progress_call
   if (err)
   {
     opkg_package_free (pdata.package);
-    return OPKG_UNKNOWN_ERROR;
+    switch (err)
+    {
+      case PKG_INSTALL_ERR_NOT_TRUSTED: return OPKG_GPG_ERROR;
+      case PKG_INSTALL_ERR_DOWNLOAD: return OPKG_DOWNLOAD_FAILED;
+      case PKG_INSTALL_ERR_DEPENDENCIES:
+      case PKG_INSTALL_ERR_CONFLICTS: return OPKG_DEPENDENCIES_FAILED;
+      case PKG_INSTALL_ERR_ALREADY_INSTALLED: return OPKG_PACKAGE_ALREADY_INSTALLED;
+      case PKG_INSTALL_ERR_SIGNATURE: return OPKG_GPG_ERROR;
+      case PKG_INSTALL_ERR_MD5: return OPKG_MD5_ERROR;
+      default: return OPKG_UNKNOWN_ERROR;
+    }
   }
 
   progress (pdata, 75);
@@ -675,7 +685,6 @@ opkg_update_package_lists (opkg_t *opkg, opkg_progress_callback_t progress_callb
   pkg_src_t *src;
   int sources_list_count, sources_done;
   opkg_progress_data_t pdata;
-  char *tmp_file_name = NULL;
 
   opkg_assert (opkg != NULL);
 
@@ -716,7 +725,7 @@ opkg_update_package_lists (opkg_t *opkg, opkg_progress_callback_t progress_callb
     return 1;
   }
 
-  /* cout the number of sources so we can give some progress updates */
+  /* count the number of sources so we can give some progress updates */
   sources_list_count = 0;
   sources_done = 0;
   iter = opkg->conf->pkg_src_list.head;
@@ -728,7 +737,7 @@ opkg_update_package_lists (opkg_t *opkg, opkg_progress_callback_t progress_callb
 
   for (iter = opkg->conf->pkg_src_list.head; iter; iter = iter->next)
   {
-    char *url, *list_file_name;
+    char *url, *list_file_name = NULL, *sig_file_name = NULL;
 
     src = iter->data;
 
@@ -743,6 +752,7 @@ opkg_update_package_lists (opkg_t *opkg, opkg_progress_callback_t progress_callb
     {
       FILE *in, *out;
       struct _curl_cb_data cb_data;
+      char *tmp_file_name = NULL;
 
       sprintf_alloc (&tmp_file_name, "%s/%s.gz", tmp, src->name);
 
@@ -772,10 +782,10 @@ opkg_update_package_lists (opkg_t *opkg, opkg_progress_callback_t progress_callb
           fclose (out);
         unlink (tmp_file_name);
       }
+      free (tmp_file_name);
     }
     else
       err = opkg_download (opkg->conf, url, list_file_name, NULL, NULL);
-    free (tmp_file_name);
 
     if (err)
     {
@@ -793,10 +803,13 @@ opkg_update_package_lists (opkg_t *opkg, opkg_progress_callback_t progress_callb
     else
       sprintf_alloc (&url, "%s/%s", src->value, "Packages.sig");
 
-    /* create temporary file for it */
-    sprintf_alloc (&tmp_file_name, "%s/%s", tmp, "Packages.sig");
+    /* create filename for signature */
+    sprintf_alloc (&sig_file_name, "%s/%s.sig", lists_dir, src->name);
 
-    err = opkg_download (opkg->conf, url, tmp_file_name, NULL, NULL);
+    /* make sure there is no existing signature file */
+    unlink (sig_file_name);
+
+    err = opkg_download (opkg->conf, url, sig_file_name, NULL, NULL);
     if (err)
     {
       /* XXX: Warning: Download failed */
@@ -804,7 +817,7 @@ opkg_update_package_lists (opkg_t *opkg, opkg_progress_callback_t progress_callb
     else
     {
       int err;
-      err = opkg_verify_file (opkg->conf, list_file_name, tmp_file_name);
+      err = opkg_verify_file (opkg->conf, list_file_name, sig_file_name);
       if (err == 0)
       {
         /* XXX: Notice: Signature check passed */
@@ -814,15 +827,14 @@ opkg_update_package_lists (opkg_t *opkg, opkg_progress_callback_t progress_callb
         /* XXX: Warning: Signature check failed */
       }
     }
-    unlink (tmp_file_name);
-    free (tmp_file_name);
+    free (sig_file_name);
+    free (list_file_name);
     free (url);
 #else
     /* XXX: Note: Signiture check for %s skipped because GPG support was not
      * enabled in this build
      */
 #endif
-    free (list_file_name);
 
     sources_done++;
     progress (pdata, 100 * sources_done / sources_list_count);
index d2a5bd0..36da8cf 100644 (file)
@@ -37,11 +37,13 @@ enum _opkg_error_code_t
   OPKG_NO_ERROR,
   OPKG_UNKNOWN_ERROR,
   OPKG_DOWNLOAD_FAILED,
-  OPKG_DEPENDANCIES_FAILED,
+  OPKG_DEPENDENCIES_FAILED,
   OPKG_PACKAGE_ALREADY_INSTALLED,
   OPKG_PACKAGE_NOT_AVAILABLE,
   OPKG_PACKAGE_NOT_FOUND,
-  OPKG_PACKAGE_NOT_INSTALLED
+  OPKG_PACKAGE_NOT_INSTALLED,
+  OPKG_GPG_ERROR,
+  OPKG_MD5_ERROR
 };
 
 struct _opkg_package_t
index f6666b2..1c73b5c 100644 (file)
@@ -755,7 +755,6 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade)
      int old_state_flag;
      char* file_md5;
      char *pkgid;
-
     
      if ( from_upgrade ) 
         message = 1;            /* Coming from an upgrade, and should change the output message */
@@ -763,7 +762,7 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade)
      if (!pkg) {
          opkg_message(conf, OPKG_ERROR,
                       "INTERNAL ERROR: null pkg passed to opkg_install_pkg\n");
-         return -EINVAL;
+         return PKG_INSTALL_ERR_INTERNAL;
      }
 
      opkg_message(conf, OPKG_DEBUG2, "Function: %s calling pkg_arch_supported %s \n", __FUNCTION__, __FUNCTION__);
@@ -771,11 +770,11 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade)
      if (!pkg_arch_supported(conf, pkg)) {
          opkg_message(conf, OPKG_ERROR, "INTERNAL ERROR: architecture %s for pkg %s is unsupported.\n",
                       pkg->architecture, pkg->name);
-         return -EINVAL;
+         return PKG_INSTALL_ERR_INTERNAL;
      }
      if (pkg->state_status == SS_INSTALLED && conf->force_reinstall == 0 && conf->nodeps == 0) {
          err = satisfy_dependencies_for(conf, pkg);
-         if (err) { return err; }
+         if (err) { return PKG_INSTALL_ERR_DEPENDENCIES; }
 
          opkg_message(conf, OPKG_NOTICE,
                       "Package %s is already installed in %s.\n", 
@@ -790,7 +789,7 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade)
      old_pkg = pkg_hash_fetch_installed_by_name(&conf->pkg_hash, pkg->name);
 
      err = opkg_install_check_downgrade(conf, pkg, old_pkg, message);
-     if (err) { return err; }
+     if (err) { return PKG_INSTALL_ERR_NO_DOWNGRADE; }
 
      pkg->state_want = SW_INSTALL;
      if (old_pkg){                          
@@ -800,7 +799,7 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade)
 
      /* Abhaya: conflicts check */
      err = check_conflicts_for(conf, pkg);
-     if (err) { return err; }
+     if (err) { return PKG_INSTALL_ERR_CONFLICTS; }
     
      /* this setup is to remove the upgrade scenario in the end when
        installing pkg A, A deps B & B deps on A. So both B and A are
@@ -810,7 +809,7 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade)
         && conf->force_reinstall == 0) return 0;
     
      err = verify_pkg_installable(conf, pkg);
-     if (err) { return err; }
+     if (err) { return PKG_INSTALL_ERR_NO_SPACE; }
 
      if (pkg->local_filename == NULL) {
          err = opkg_download_pkg(conf, pkg, conf->tmp_dir);
@@ -818,11 +817,33 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade)
               opkg_message(conf, OPKG_ERROR,
                            "Failed to download %s. Perhaps you need to run 'opkg update'?\n",
                            pkg->name);
-              return err;
+              return PKG_INSTALL_ERR_DOWNLOAD;
          }
      }
 
-/* Check for md5 values */
+     /* check that the repository is valid */
+     #if HAVE_GPGME
+     char *list_file_name, *sig_file_name, *lists_dir;
+
+     sprintf_alloc (&lists_dir, "%s",
+                   (conf->restrict_to_default_dest)
+                    ? conf->default_dest->lists_dir
+                    : conf->lists_dir);
+     sprintf_alloc (&list_file_name, "%s/%s", lists_dir, pkg->src->name);
+     sprintf_alloc (&sig_file_name, "%s/%s.sig", lists_dir, pkg->src->name);
+
+     if (file_exists (sig_file_name))
+     {
+       if (opkg_verify_file (conf, list_file_name, sig_file_name))
+         return PKG_INSTALL_ERR_SIGNATURE;
+     }
+
+     free (lists_dir);
+     free (list_file_name);
+     free (sig_file_name);
+     #endif
+
+     /* Check for md5 values */
      if (pkg->md5sum)
      {
          file_md5 = file_md5sum_alloc(pkg->local_filename);
@@ -832,7 +853,7 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade)
                            "Package %s md5sum mismatch. Either the opkg or the package index are corrupt. Try 'opkg update'.\n",
                            pkg->name);
               free(file_md5);
-              return err;
+              return PKG_INSTALL_ERR_MD5;
          }
          free(file_md5);
      }
@@ -845,11 +866,11 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade)
 /* Pigi: check if it will pass from here when replacing. It seems to fail */
 /* That's rather strange that files don't change owner. Investigate !!!!!!*/
      err = update_file_ownership(conf, pkg, old_pkg);
-     if (err) { return err; }
+     if (err) { return PKG_INSTALL_ERR_UNKNOWN; }
 
      if (conf->nodeps == 0) {
          err = satisfy_dependencies_for(conf, pkg);
-         if (err) { return err; }
+         if (err) { return PKG_INSTALL_ERR_DEPENDENCIES; }
      }
 
      replacees = pkg_vec_alloc();
@@ -998,7 +1019,7 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade)
               sigprocmask(SIG_UNBLOCK, &newset, &oldset);
 
           pkg_vec_free (replacees);
-         return err;
+         return PKG_INSTALL_ERR_UNKNOWN;
      }
      opkg_set_current_state (conf, OPKG_STATE_NONE, NULL);
 }
index 4bed953..0c01cc0 100644 (file)
 #include "opkg_conf.h"
 #include "opkg_error.h"
 
+enum {
+  PKG_INSTALL_ERR_NONE,
+  PKG_INSTALL_ERR_NOT_TRUSTED,
+  PKG_INSTALL_ERR_DOWNLOAD,
+  PKG_INSTALL_ERR_CONFLICTS,
+  PKG_INSTALL_ERR_ALREADY_INSTALLED,
+  PKG_INSTALL_ERR_DEPENDENCIES,
+  PKG_INSTALL_ERR_NO_DOWNGRADE,
+  PKG_INSTALL_ERR_NO_SPACE,
+  PKG_INSTALL_ERR_SIGNATURE,
+  PKG_INSTALL_ERR_MD5,
+  PKG_INSTALL_ERR_INTERNAL,
+  PKG_INSTALL_ERR_UNKNOWN
+};
+
 opkg_error_t opkg_install_by_name(opkg_conf_t *conf, const char *pkg_name);
 opkg_error_t opkg_install_multi_by_name(opkg_conf_t *conf, const char *pkg_name);
 int opkg_install_from_file(opkg_conf_t *conf, const char *filename);
index 7033ced..d9bd0ef 100644 (file)
@@ -4,7 +4,7 @@
 
 opkg_package_t *find_pkg = NULL;
 
-char *errors[8] = {
+char *errors[10] = {
   "No Error",
   "Unknown Eror",
   "Download failed",
@@ -12,9 +12,14 @@ char *errors[8] = {
   "Package already installed",
   "Package not available",
   "Package not found",
-  "Package not installed"
+  "Package not installed",
+  "Signature check failed",
+  "MD5 sum failed"
 };
 
+
+#define TEST_PACKAGE "aspell"
+
 void
 progress_callback (opkg_t *opkg, const opkg_progress_data_t *progress, void *data)
 {
@@ -112,13 +117,13 @@ main (int argc, char **argv)
   else
     printf ("No package available to test find_package.\n");
 
-  err = opkg_install_package (opkg, "aspell", progress_callback, "Installing...");
+  err = opkg_install_package (opkg, TEST_PACKAGE, progress_callback, "Installing...");
   printf ("\nopkg_install_package returned %d (%s)\n", err, errors[err]);
 
-  err = opkg_upgrade_package (opkg, "aspell", progress_callback, "Upgrading...");
+  err = opkg_upgrade_package (opkg, TEST_PACKAGE, progress_callback, "Upgrading...");
   printf ("\nopkg_upgrade_package returned %d (%s)\n", err, errors[err]);
 
-  err = opkg_remove_package (opkg, "aspell", progress_callback, "Removing...");
+  err = opkg_remove_package (opkg, TEST_PACKAGE, progress_callback, "Removing...");
   printf ("\nopkg_remove_package returned %d (%s)\n", err, errors[err]);
 
   printf ("Listing upgradable packages...\n");