opkg: trivial, clean up obsolete code, and some typo
[oweals/opkg-lede.git] / libopkg / pkg.c
index 93fd20aa9842bca54a88c3bea351c57b5c9d4e8c..6c07b840b8c978e194e49abdb42f89d37868b084 100644 (file)
@@ -1,4 +1,4 @@
-/* pkg.c - the itsy package management system
+/* pkg.c - the opkg package management system
 
    Carl D. Worth
 
    General Public License for more details.
 */
 
-#include "opkg.h"
+#include "includes.h"
 #include <ctype.h>
 #include <string.h>
+#include <stdbool.h>
 #include <errno.h>
 
 #include "pkg.h"
@@ -94,7 +95,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 +142,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 +182,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 +267,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 +585,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 +1004,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 */
@@ -971,6 +1053,7 @@ char * pkg_formatted_field(pkg_t *pkg, const char *field )
 
 void pkg_print_info(pkg_t *pkg, FILE *file)
 {
+  int t=0;
      char * buff;
      if (pkg == NULL) {
        return;
@@ -980,7 +1063,7 @@ void pkg_print_info(pkg_t *pkg, FILE *file)
      if ( buff == NULL ) 
          return;
      if (strlen(buff)>2){
-         fwrite(buff, 1, strlen(buff), file);
+       t = fwrite(buff, 1, strlen(buff), file); //#~rzr:TODO
      } 
      free(buff);
 }
@@ -998,7 +1081,7 @@ void pkg_print_status(pkg_t * pkg, FILE * file)
        can be found in th available file.
 
        But, someone proposed the idea to make it possible to
-       reconstruct a .ipk from an installed package, (ie. for beaming
+       reconstruct a .opk from an installed package, (ie. for beaming
        from one handheld to another). So, maybe we actually want a few
        more fields here, (depends, suggests, etc.), so that that would
        be guaranteed to work even in the absence of more information
@@ -1138,10 +1221,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) {
@@ -1168,7 +1251,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;
@@ -1230,7 +1313,7 @@ str_list_t *pkg_get_installed_files(pkg_t *pkg)
          return NULL;
      }
 
-     /* For uninstalled packages, get the file list firectly from the package.
+     /* For uninstalled packages, get the file list directly from the package.
        For installed packages, look at the package.list file in the database.
      */
      if (pkg->state_status == SS_NOT_INSTALLED || pkg->dest == NULL) {
@@ -1328,6 +1411,7 @@ int pkg_free_installed_files(pkg_t *pkg)
          }
 
          str_list_deinit(pkg->installed_files);
+         free (pkg->installed_files);
      }
 
      pkg->installed_files = NULL;
@@ -1411,8 +1495,24 @@ int pkg_run_script(opkg_conf_t *conf, pkg_t *pkg,
        scripts when running with offline_root mode and/or a dest other
        than '/'. I've been playing around with some clever chroot
        tricks and I might come up with something workable. */
+     /*
+      * Attempt to provide a restricted environment for offline operation
+      * Need the following set as a minimum:
+      * OPKG_OFFLINE_ROOT = absolute path to root dir
+      * D                 = absolute path to root dir (for OE generated postinst)
+      * PATH              = something safe (a restricted set of utilities)
+      */
+
+     bool AllowOfflineMode = false;
      if (conf->offline_root) {
          setenv("OPKG_OFFLINE_ROOT", conf->offline_root, 1);
+         setenv("D", conf->offline_root, 1);
+          if (NULL == conf->offline_root_path || '\0' == conf->offline_root_path[0]) {
+            setenv("PATH", "/dev/null", 1);
+          } else {
+            setenv("PATH", conf->offline_root_path, 1);
+            AllowOfflineMode = true;
+          }
      }
 
      setenv("PKG_ROOT",
@@ -1423,7 +1523,7 @@ int pkg_run_script(opkg_conf_t *conf, pkg_t *pkg,
          return 0;
      }
 
-     if (conf->offline_root) {
+     if (conf->offline_root && !AllowOfflineMode) {
          fprintf(stderr, "(offline root mode: not running %s.%s)\n", pkg->name, script);
          free(path);
          return 0;
@@ -1631,7 +1731,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;
@@ -1655,6 +1755,7 @@ int pkg_info_preinstall_check(opkg_conf_t *conf)
               // opkg_message(conf, OPKG_DEBUG2, "pkg %s: file=%s\n", pkg->name, installed_file);
               file_hash_set_file_owner(conf, installed_file, pkg);
          }
+         pkg_free_installed_files(pkg);
      }
      pkg_vec_free(installed_pkgs);
 
@@ -1730,5 +1831,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;
 }