opkg: consolidate error enums and add an error for when no package matches
[project/opkg-lede.git] / libopkg / pkg.c
index 887b217d6f8d15c7b21f4454ca4583ce453c0180..e15fc2430479c8b7088773d6ae436aa89062f7d4 100644 (file)
@@ -1,4 +1,4 @@
-/* pkg.c - the itsy package management system
+/* pkg.c - the opkg package management system
 
    Carl D. Worth
 
@@ -15,7 +15,7 @@
    General Public License for more details.
 */
 
-#include "opkg.h"
+#include "includes.h"
 #include <ctype.h>
 #include <string.h>
 #include <errno.h>
@@ -94,7 +94,6 @@ int pkg_init(pkg_t *pkg)
      pkg->epoch = 0;
      pkg->version = NULL;
      pkg->revision = NULL;
-     pkg->familiar_revision = NULL;
      pkg->dest = NULL;
      pkg->src = NULL;
      pkg->architecture = NULL;
@@ -142,17 +141,31 @@ int pkg_init(pkg_t *pkg)
      return 0;
 }
 
+void compound_depend_deinit (compound_depend_t *depends)
+{
+    int i;
+    for (i = 0; i < depends->possibility_count; i++)
+    {
+        depend_t *d;
+        d = depends->possibilities[i];
+        free (d->version);
+        free (d);
+    }
+    free (depends->possibilities);
+}
+
 void pkg_deinit(pkg_t *pkg)
 {
+     int i;
+
      free(pkg->name);
      pkg->name = NULL;
      pkg->epoch = 0;
      free(pkg->version);
      pkg->version = NULL;
-     /* revision and familiar_revision share storage with version, so
+     /* revision shares storage with version, so
        don't free */
      pkg->revision = NULL;
-     pkg->familiar_revision = NULL;
      /* owned by opkg_conf_t */
      pkg->dest = NULL;
      /* owned by opkg_conf_t */
@@ -168,18 +181,65 @@ void pkg_deinit(pkg_t *pkg)
      pkg->state_want = SW_UNKNOWN;
      pkg->state_flag = SF_OK;
      pkg->state_status = SS_NOT_INSTALLED;
+
+     //for (i = 0; i < pkg->replaces_count; i++)
+     free (pkg->replaces);
+     pkg->replaces = NULL;
+
+     for (i = 0; i < pkg->depends_count; i++)
+       free (pkg->depends_str[i]);
      free(pkg->depends_str);
      pkg->depends_str = NULL;
+
+     for (i = 0; i < pkg->provides_count; i++)
+       free (pkg->provides_str[i]);
      free(pkg->provides_str);
      pkg->provides_str = NULL;
-     pkg->depends_count = 0;
-     /* XXX: CLEANUP: MEMORY_LEAK: how to free up pkg->depends ? */
+
+     for (i = 0; i < pkg->conflicts_count; i++)
+       free (pkg->conflicts_str[i]);
+     free(pkg->conflicts_str);
+     pkg->conflicts_str = NULL;
+
+     for (i = 0; i < pkg->replaces_count; i++)
+       free (pkg->replaces_str[i]);
+     free(pkg->replaces_str);
+     pkg->replaces_str = NULL;
+
+     for (i = 0; i < pkg->recommends_count; i++)
+       free (pkg->recommends_str[i]);
+     free(pkg->recommends_str);
+     pkg->recommends_str = NULL;
+
+     for (i = 0; i < pkg->suggests_count; i++)
+       free (pkg->suggests_str[i]);
+     free(pkg->suggests_str);
+     pkg->suggests_str = NULL;
+
+     if (pkg->depends)
+     {
+       int count = pkg->pre_depends_count + pkg->depends_count + pkg->recommends_count + pkg->suggests_count;
+       int x;
+
+       for (x = 0; x < count; x++)
+        compound_depend_deinit (&pkg->depends[x]);
+       free (pkg->depends);
+     }
+
+     if (pkg->conflicts)
+     {
+       int x;
+       for (x = 0; x < pkg->conflicts_count; x++)
+         compound_depend_deinit (&pkg->conflicts[x]);
+       free (pkg->conflicts);
+     }
+
+     free (pkg->provides);
+
      pkg->pre_depends_count = 0;
      free(pkg->pre_depends_str);
      pkg->pre_depends_str = NULL;
      pkg->provides_count = 0;
-     /* XXX: CLEANUP: MEMORY_LEAK: how to free up pkg->provides ? */
-     /* XXX: CLEANUP: MEMORY_LEAK: how to free up pkg->suggests ? */
      free(pkg->filename);
      pkg->filename = NULL;
      free(pkg->local_filename);
@@ -206,6 +266,8 @@ void pkg_deinit(pkg_t *pkg)
      pkg->installed_files_ref_cnt = 1;
      pkg_free_installed_files(pkg);
      pkg->essential = 0;
+     free (pkg->tags);
+     pkg->tags = NULL;
 }
 
 int pkg_init_from_file(pkg_t *pkg, const char *filename)
@@ -522,6 +584,10 @@ char * pkg_formatted_info(pkg_t *pkg )
      strncat(buff ,line, strlen(line));
      free(line);
 
+     line = pkg_formatted_field(pkg, "Tags");
+     strncat(buff ,line, strlen(line));
+     free(line);
+
      return buff;
 }
 
@@ -937,6 +1003,21 @@ char * pkg_formatted_field(pkg_t *pkg, const char *field )
          }
      }
          break;
+     case 't':
+     case 'T':
+         if (strcasecmp(field, "Tags") == 0) {
+              /* Tags */
+              if (pkg->tags) {
+                   temp = (char *)realloc(temp,strlen(pkg->tags)+8);
+                   if ( temp == NULL ){
+                     fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
+                     return NULL;
+                   }
+                   temp[0]='\0';
+                   snprintf(temp, (strlen(pkg->tags)+8), "Tags: %s\n", pkg->tags);
+              }
+         }
+         break;
      case 'v':
      case 'V': {
          /* Version */
@@ -1067,15 +1148,11 @@ int pkg_compare_versions(const pkg_t *pkg, const pkg_t *ref_pkg)
          return r;
      }
 
-#ifdef USE_DEBVERSION
      r = verrevcmp(pkg->revision, ref_pkg->revision);
      if (r) {
          return r;
      }
 
-     r = verrevcmp(pkg->familiar_revision, ref_pkg->familiar_revision);
-#endif
-
      return r;
 }
 
@@ -1142,10 +1219,10 @@ int pkg_version_satisfied(pkg_t *it, pkg_t *ref, const char *op)
      return 0;
 }
 
-int pkg_name_version_and_architecture_compare(void *p1, void *p2)
+int pkg_name_version_and_architecture_compare(const void *p1, const void *p2)
 {
-     const pkg_t *a = *(const pkg_t **)p1;
-     const pkg_t *b = *(const pkg_t **)p2;
+     const pkg_t *a = *(const pkg_t**) p1;
+     const pkg_t *b = *(const pkg_t**) p2;
      int namecmp;
      int vercmp;
      if (!a->name || !b->name) {
@@ -1172,7 +1249,7 @@ int pkg_name_version_and_architecture_compare(void *p1, void *p2)
      return 0;
 }
 
-int abstract_pkg_name_compare(void *p1, void *p2)
+int abstract_pkg_name_compare(const void *p1, const void *p2)
 {
      const abstract_pkg_t *a = *(const abstract_pkg_t **)p1;
      const abstract_pkg_t *b = *(const abstract_pkg_t **)p2;
@@ -1189,10 +1266,7 @@ char *pkg_version_str_alloc(pkg_t *pkg)
 {
      char *complete_version;
      char *epoch_str;
-#ifdef USE_DEBVERSION
      char *revision_str;
-     char *familiar_revision_str;
-#endif
 
      if (pkg->epoch) {
          sprintf_alloc(&epoch_str, "%d:", pkg->epoch);
@@ -1200,33 +1274,18 @@ char *pkg_version_str_alloc(pkg_t *pkg)
          epoch_str = strdup("");
      }
 
-#ifdef USE_DEBVERSION
      if (pkg->revision && strlen(pkg->revision)) {
          sprintf_alloc(&revision_str, "-%s", pkg->revision);
      } else {
          revision_str = strdup("");
      }
 
-     if (pkg->familiar_revision && strlen(pkg->familiar_revision)) {
-         sprintf_alloc(&familiar_revision_str, "-fam%s", pkg->familiar_revision);
-     } else {
-         familiar_revision_str = strdup("");
-     }
-#endif
 
-#ifdef USE_DEBVERSION
-     sprintf_alloc(&complete_version, "%s%s%s%s",
-                  epoch_str, pkg->version, revision_str, familiar_revision_str);
-#else
-     sprintf_alloc(&complete_version, "%s%s",
-                  epoch_str, pkg->version);
-#endif
+     sprintf_alloc(&complete_version, "%s%s%s",
+                  epoch_str, pkg->version, revision_str);
 
      free(epoch_str);
-#ifdef USE_DEBVERSION
      free(revision_str);
-     free(familiar_revision_str);
-#endif
 
      return complete_version;
 }
@@ -1350,6 +1409,7 @@ int pkg_free_installed_files(pkg_t *pkg)
          }
 
          str_list_deinit(pkg->installed_files);
+         free (pkg->installed_files);
      }
 
      pkg->installed_files = NULL;
@@ -1653,7 +1713,7 @@ int pkg_info_preinstall_check(opkg_conf_t *conf)
          pkg_t *pkg = available_pkgs->pkgs[i];
          if (!pkg->arch_priority && (pkg->state_flag || (pkg->state_want != SW_UNKNOWN))) {
               /* clear flags and want for any uninstallable package */
-              opkg_message(conf, OPKG_NOTICE, "Clearing state_want and state_flag for pkg=%s (arch_priority=%d flag=%d want=%d)\n", 
+              opkg_message(conf, OPKG_DEBUG, "Clearing state_want and state_flag for pkg=%s (arch_priority=%d flag=%d want=%d)\n", 
                            pkg->name, pkg->arch_priority, pkg->state_flag, pkg->state_want);
               pkg->state_want = SW_UNKNOWN;
               pkg->state_flag = 0;
@@ -1752,5 +1812,6 @@ int pkg_write_changed_filelists(opkg_conf_t *conf)
                    opkg_message(conf, OPKG_NOTICE, "pkg_write_filelist pkg=%s returned %d\n", pkg->name, err);
          }
      }
+     pkg_vec_free (installed_pkgs);
      return 0;
 }