Remove str_util.{c,h}
[oweals/opkg-lede.git] / libopkg / pkg.c
index e3e6c049b58ab46bb0772fabda58466648f1109d..be25c5c15c70c9dbbb0dbd210d43d00d700d190c 100644 (file)
@@ -32,7 +32,6 @@
 #include "libbb/libbb.h"
 #include "sprintf_alloc.h"
 #include "file_util.h"
-#include "str_util.h"
 #include "xsystem.h"
 #include "opkg_conf.h"
 
@@ -72,25 +71,8 @@ static const enum_map_t pkg_state_status_map[] = {
      { SS_REMOVAL_FAILED, "removal-failed" }
 };
 
-static int verrevcmp(const char *val, const char *ref);
-
-
-pkg_t *pkg_new(void)
-{
-     pkg_t *pkg;
-
-     pkg = calloc(1, sizeof(pkg_t));
-     if (pkg == NULL) {
-         fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
-         return NULL;
-     }
-
-     pkg_init(pkg);
-
-     return pkg;
-}
-
-int pkg_init(pkg_t *pkg)
+static void
+pkg_init(pkg_t *pkg)
 {
      pkg->name = NULL;
      pkg->epoch = 0;
@@ -144,11 +126,21 @@ int pkg_init(pkg_t *pkg)
      pkg->installed_files_ref_cnt = 0;
      pkg->essential = 0;
      pkg->provided_by_hand = 0;
+}
 
-     return 0;
+pkg_t *
+pkg_new(void)
+{
+     pkg_t *pkg;
+
+     pkg = xcalloc(1, sizeof(pkg_t));
+     pkg_init(pkg);
+
+     return pkg;
 }
 
-void compound_depend_deinit (compound_depend_t *depends)
+static void
+compound_depend_deinit(compound_depend_t *depends)
 {
     int i;
     for (i = 0; i < depends->possibility_count; i++)
@@ -161,155 +153,178 @@ void compound_depend_deinit (compound_depend_t *depends)
     free (depends->possibilities);
 }
 
-void pkg_deinit(pkg_t *pkg)
+void
+pkg_deinit(pkg_t *pkg)
 {
-     int i;
+       int i;
 
-     free(pkg->name);
-     pkg->name = NULL;
-     pkg->epoch = 0;
-     free(pkg->version);
-     pkg->version = NULL;
-     /* revision shares storage with version, so
-       don't free */
-     pkg->revision = NULL;
-     /* owned by opkg_conf_t */
-     pkg->dest = NULL;
-     /* owned by opkg_conf_t */
-     pkg->src = NULL;
-     free(pkg->architecture);
-     pkg->architecture = NULL;
-     free(pkg->maintainer);
-     pkg->maintainer = NULL;
-     free(pkg->section);
-     pkg->section = NULL;
-     free(pkg->description);
-     pkg->description = NULL;
-     pkg->state_want = SW_UNKNOWN;
-     pkg->state_flag = SF_OK;
-     pkg->state_status = SS_NOT_INSTALLED;
+       if (pkg->name)
+               free(pkg->name);
+       pkg->name = NULL;
 
-     active_list_clear(&pkg->list);
+       pkg->epoch = 0;
 
-     free (pkg->replaces);
-     pkg->replaces = NULL;
+       if (pkg->version)
+               free(pkg->version);
+       pkg->version = NULL;
+       /* revision shares storage with version, so don't free */
+       pkg->revision = NULL;
 
-     for (i = 0; i < pkg->depends_count; i++)
-       free (pkg->depends_str[i]);
-     free(pkg->depends_str);
-     pkg->depends_str = NULL;
+       /* owned by opkg_conf_t */
+       pkg->dest = NULL;
+       /* owned by opkg_conf_t */
+       pkg->src = NULL;
 
-     for (i = 0; i < pkg->provides_count; i++)
-       free (pkg->provides_str[i]);
-     free(pkg->provides_str);
-     pkg->provides_str = NULL;
+       if (pkg->architecture)
+               free(pkg->architecture);
+       pkg->architecture = NULL;
 
-     for (i = 0; i < pkg->conflicts_count; i++)
-       free (pkg->conflicts_str[i]);
-     free(pkg->conflicts_str);
-     pkg->conflicts_str = NULL;
+       if (pkg->maintainer)
+               free(pkg->maintainer);
+       pkg->maintainer = NULL;
 
-     for (i = 0; i < pkg->replaces_count; i++)
-       free (pkg->replaces_str[i]);
-     free(pkg->replaces_str);
-     pkg->replaces_str = NULL;
+       if (pkg->section)
+               free(pkg->section);
+       pkg->section = 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);
+       if (pkg->description)
+               free(pkg->description);
+       pkg->description = NULL;
+       
+       pkg->state_want = SW_UNKNOWN;
+       pkg->state_flag = SF_OK;
+       pkg->state_status = SS_NOT_INSTALLED;
+
+       active_list_clear(&pkg->list);
+
+       if (pkg->replaces)
+               free (pkg->replaces);
+       pkg->replaces = NULL;
+
+       if (pkg->depends) {
+               int count = pkg->pre_depends_count
+                               + pkg->depends_count
+                               + pkg->recommends_count
+                               + pkg->suggests_count;
+
+               for (i=0; i<count; i++)
+                       compound_depend_deinit (&pkg->depends[i]);
+               free (pkg->depends);
+       }
+
+       if (pkg->conflicts) {
+               for (i=0; i<pkg->conflicts_count; i++)
+                       compound_depend_deinit (&pkg->conflicts[i]);
+               free (pkg->conflicts);
+       }
+
+       if (pkg->provides)
+               free (pkg->provides);
+
+       pkg->pre_depends_count = 0;
+       pkg->provides_count = 0;
+       
+       if (pkg->filename)
+               free(pkg->filename);
+       pkg->filename = NULL;
+       
+       if (pkg->local_filename)
+               free(pkg->local_filename);
+       pkg->local_filename = NULL;
 
-     pkg->pre_depends_count = 0;
-     free(pkg->pre_depends_str);
-     pkg->pre_depends_str = NULL;
-     pkg->provides_count = 0;
-     free(pkg->filename);
-     pkg->filename = NULL;
-     free(pkg->local_filename);
-     pkg->local_filename = NULL;
      /* CLEANUP: It'd be nice to pullin the cleanup function from
        opkg_install.c here. See comment in
        opkg_install.c:cleanup_temporary_files */
-     free(pkg->tmp_unpack_dir);
-     pkg->tmp_unpack_dir = NULL;
-     free(pkg->md5sum);
-     pkg->md5sum = NULL;
+       if (pkg->tmp_unpack_dir)
+               free(pkg->tmp_unpack_dir);
+       pkg->tmp_unpack_dir = NULL;
+
+       if (pkg->md5sum)
+               free(pkg->md5sum);
+       pkg->md5sum = NULL;
+
 #if defined HAVE_SHA256
-     free(pkg->sha256sum);
-     pkg->sha256sum = NULL;
+       if (pkg->sha256sum)
+               free(pkg->sha256sum);
+       pkg->sha256sum = NULL;
 #endif
-     free(pkg->size);
-     pkg->size = NULL;
-     free(pkg->installed_size);
-     pkg->installed_size = NULL;
-     free(pkg->priority);
-     pkg->priority = NULL;
-     free(pkg->source);
-     pkg->source = NULL;
-     conffile_list_deinit(&pkg->conffiles);
-     /* XXX: QUESTION: Is forcing this to 1 correct? I suppose so,
-       since if they are calling deinit, they should know. Maybe do an
-       assertion here instead? */
-     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)
-{
-     int err;
-     char **raw, **raw_start;
-     FILE *control_file;
+       if (pkg->size)
+               free(pkg->size);
+       pkg->size = NULL;
 
-     err = pkg_init(pkg);
-     if (err) { return err; }
+       if (pkg->installed_size)
+               free(pkg->installed_size);
+       pkg->installed_size = NULL;
 
-     pkg->local_filename = strdup(filename);
-    
-     control_file = tmpfile();
-     err = pkg_extract_control_file_to_stream(pkg, control_file);
-     if (err) { return err; }
+       if (pkg->priority)
+               free(pkg->priority);
+       pkg->priority = NULL;
 
-     rewind(control_file);
-     raw = raw_start = read_raw_pkgs_from_stream(control_file);
-     pkg_parse_raw(pkg, &raw, NULL, NULL);
+       if (pkg->source)
+               free(pkg->source);
+       pkg->source = NULL;
 
-     fclose(control_file);
+       conffile_list_deinit(&pkg->conffiles);
 
-     raw = raw_start;
-     while (*raw) {
-         free(*raw++);
-     }
-     free(raw_start);
+       /* XXX: QUESTION: Is forcing this to 1 correct? I suppose so,
+       since if they are calling deinit, they should know. Maybe do an
+       assertion here instead? */
+       pkg->installed_files_ref_cnt = 1;
+       pkg_free_installed_files(pkg);
+       pkg->essential = 0;
 
-     return 0;
+       if (pkg->tags)
+               free (pkg->tags);
+       pkg->tags = NULL;
+}
+
+int
+pkg_init_from_file(opkg_conf_t *conf, pkg_t *pkg, const char *filename)
+{
+       int fd, err = 0;
+       FILE *control_file;
+       char *control_path;
+
+       pkg_init(pkg);
+
+       pkg->local_filename = xstrdup(filename);
+
+       sprintf_alloc(&control_path, "%s/%s.control.XXXXXX", 
+                        conf->tmp_dir,
+                        basename(filename));
+       fd = mkstemp(control_path);
+       if (fd == -1) {
+               perror_msg("%s: mkstemp(%s)", __FUNCTION__, control_path);
+               err = -1;
+               goto err0;
+       }
+
+       control_file = fdopen(fd, "r+");
+       if (control_file == NULL) {
+               perror_msg("%s: fdopen", __FUNCTION__, control_path);
+               close(fd);
+               err = -1;
+               goto err1;
+       }
+
+       err = pkg_extract_control_file_to_stream(pkg, control_file);
+       if (err)
+               goto err2;
+
+       rewind(control_file);
+
+       if (pkg_parse_from_stream(pkg, control_file, PFM_ALL))
+               err = -1;
+
+err2:
+       fclose(control_file);
+err1:
+       unlink(control_path);
+err0:
+       free(control_path);
+
+       return err;
 }
 
 /* Merge any new information in newpkg into oldpkg */
@@ -320,12 +335,16 @@ int pkg_init_from_file(pkg_t *pkg, const char *filename)
  * uh, i thought that i had originally written this so that it took 
  * two pkgs and returned a new one?  we can do that again... -sma
  */
-int pkg_merge(pkg_t *oldpkg, pkg_t *newpkg, int set_status)
+int
+pkg_merge(pkg_t *oldpkg, pkg_t *newpkg, int set_status)
 {
      if (oldpkg == newpkg) {
          return 0;
      }
 
+     if (!oldpkg->auto_installed)
+         oldpkg->auto_installed = newpkg->auto_installed;
+
      if (!oldpkg->src)
          oldpkg->src = newpkg->src;
      if (!oldpkg->dest)
@@ -353,44 +372,34 @@ int pkg_merge(pkg_t *oldpkg, pkg_t *newpkg, int set_status)
          oldpkg->state_flag |= newpkg->state_flag;
      }
 
-     if (!oldpkg->depends_str && !oldpkg->pre_depends_str && !oldpkg->recommends_str && !oldpkg->suggests_str) {
-         oldpkg->depends_str = newpkg->depends_str;
-         newpkg->depends_str = NULL;
+     if (!oldpkg->depends_count && !oldpkg->pre_depends_count && !oldpkg->recommends_count && !oldpkg->suggests_count) {
          oldpkg->depends_count = newpkg->depends_count;
          newpkg->depends_count = 0;
 
          oldpkg->depends = newpkg->depends;
          newpkg->depends = NULL;
 
-         oldpkg->pre_depends_str = newpkg->pre_depends_str;
-         newpkg->pre_depends_str = NULL;
          oldpkg->pre_depends_count = newpkg->pre_depends_count;
          newpkg->pre_depends_count = 0;
 
-         oldpkg->recommends_str = newpkg->recommends_str;
-         newpkg->recommends_str = NULL;
          oldpkg->recommends_count = newpkg->recommends_count;
          newpkg->recommends_count = 0;
 
-         oldpkg->suggests_str = newpkg->suggests_str;
-         newpkg->suggests_str = NULL;
          oldpkg->suggests_count = newpkg->suggests_count;
          newpkg->suggests_count = 0;
      }
 
-     if (!oldpkg->provides_str) {
-         oldpkg->provides_str = newpkg->provides_str;
-         newpkg->provides_str = NULL;
+     if (oldpkg->provides_count <= 1) {
          oldpkg->provides_count = newpkg->provides_count;
          newpkg->provides_count = 0;
 
-         oldpkg->provides = newpkg->provides;
-         newpkg->provides = NULL;
+         if (!oldpkg->provides) {
+               oldpkg->provides = newpkg->provides;
+               newpkg->provides = NULL;
+         }
      }
 
-     if (!oldpkg->conflicts_str) {
-         oldpkg->conflicts_str = newpkg->conflicts_str;
-         newpkg->conflicts_str = NULL;
+     if (!oldpkg->conflicts_count) {
          oldpkg->conflicts_count = newpkg->conflicts_count;
          newpkg->conflicts_count = 0;
 
@@ -398,9 +407,7 @@ int pkg_merge(pkg_t *oldpkg, pkg_t *newpkg, int set_status)
          newpkg->conflicts = NULL;
      }
 
-     if (!oldpkg->replaces_str) {
-         oldpkg->replaces_str = newpkg->replaces_str;
-         newpkg->replaces_str = NULL;
+     if (!oldpkg->replaces_count) {
          oldpkg->replaces_count = newpkg->replaces_count;
          newpkg->replaces_count = 0;
 
@@ -410,9 +417,6 @@ int pkg_merge(pkg_t *oldpkg, pkg_t *newpkg, int set_status)
 
      if (!oldpkg->filename)
          oldpkg->filename = xstrdup(newpkg->filename);
-     if (0)
-     fprintf(stdout, "pkg=%s old local_filename=%s new local_filename=%s\n", 
-            oldpkg->name, oldpkg->local_filename, newpkg->local_filename);
      if (!oldpkg->local_filename)
          oldpkg->local_filename = xstrdup(newpkg->local_filename);
      if (!oldpkg->tmp_unpack_dir)
@@ -446,77 +450,185 @@ int pkg_merge(pkg_t *oldpkg, pkg_t *newpkg, int set_status)
      return 0;
 }
 
-abstract_pkg_t *abstract_pkg_new(void)
+static void
+abstract_pkg_init(abstract_pkg_t *ab_pkg)
+{
+     ab_pkg->provided_by = abstract_pkg_vec_alloc();
+     ab_pkg->dependencies_checked = 0;
+     ab_pkg->state_status = SS_NOT_INSTALLED;
+}
+
+abstract_pkg_t *
+abstract_pkg_new(void)
 {
      abstract_pkg_t * ab_pkg;
 
-     ab_pkg = calloc(1, sizeof(abstract_pkg_t));
+     ab_pkg = xcalloc(1, sizeof(abstract_pkg_t));
+     abstract_pkg_init(ab_pkg);
 
-     if (ab_pkg == NULL) {
-         fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
-         return NULL;
+     return ab_pkg;
+}
+
+void
+set_flags_from_control(opkg_conf_t *conf, pkg_t *pkg){
+     char *file_name;
+     FILE *fp;
+
+     sprintf_alloc(&file_name,"%s/%s.control", pkg->dest->info_dir, pkg->name);
+
+     fp = fopen(file_name, "r");
+     if (fp == NULL) {
+            opkg_message(conf, OPKG_ERROR, "fopen(%s): %s\n",
+                            file_name, strerror(errno));
+            free(file_name);
+            return;
      }
 
-     if ( abstract_pkg_init(ab_pkg) < 0 ) 
-        return NULL;
+     free(file_name);
 
-     return ab_pkg;
+     if (pkg_parse_from_stream(pkg, fp, PFM_ESSENTIAL)) {
+        opkg_message(conf, OPKG_DEBUG, "unable to read control file for %s. May be empty\n", pkg->name);
+     }
+
+     fclose(fp);
+
+     return;
 }
 
-int abstract_pkg_init(abstract_pkg_t *ab_pkg)
+static char *
+pkg_state_want_to_str(pkg_state_want_t sw)
 {
-     ab_pkg->provided_by = abstract_pkg_vec_alloc();
-     if (ab_pkg->provided_by==NULL){
-        return -1;
+     int i;
+
+     for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
+         if (pkg_state_want_map[i].value == sw) {
+              return pkg_state_want_map[i].str;
+         }
      }
-     ab_pkg->dependencies_checked = 0;
-     ab_pkg->state_status = SS_NOT_INSTALLED;
 
-     return 0;
+     fprintf(stderr, "%s: ERROR: Illegal value for state_want: %d\n",
+            __FUNCTION__, sw);
+     return "<STATE_WANT_UNKNOWN>";
 }
 
-void set_flags_from_control(opkg_conf_t *conf, pkg_t *pkg){
-     char * temp_str;
-     char **raw =NULL;
-     char **raw_start=NULL; 
+pkg_state_want_t
+pkg_state_want_from_str(char *str)
+{
+     int i;
 
-     size_t str_size = strlen(pkg->dest->info_dir)+strlen(pkg->name)+12;
-     temp_str = (char *) alloca (str_size);
-     memset(temp_str, 0 , str_size);
-     
-     if (temp_str == NULL ){
-        opkg_message(conf, OPKG_INFO, "Out of memory in  %s\n", __FUNCTION__);
-        return;
-     }
-     sprintf( temp_str,"%s/%s.control",pkg->dest->info_dir,pkg->name);
-   
-     raw = raw_start = read_raw_pkgs_from_file(temp_str);
-     if (raw == NULL ){
-        opkg_message(conf, OPKG_ERROR, "Unable to open the control file in  %s\n", __FUNCTION__);
-        return;
+     for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
+         if (strcmp(str, pkg_state_want_map[i].str) == 0) {
+              return pkg_state_want_map[i].value;
+         }
      }
 
-     while(*raw){
-        if (!pkg_valorize_other_field(pkg, &raw ) == 0) {
-            opkg_message(conf, OPKG_DEBUG, "unable to read control file for %s. May be empty\n", pkg->name);
-        }
+     fprintf(stderr, "%s: ERROR: Illegal value for state_want string: %s\n",
+            __FUNCTION__, str);
+     return SW_UNKNOWN;
+}
+
+static char *
+pkg_state_flag_to_str(pkg_state_flag_t sf)
+{
+       int i;
+       int len;
+       char *str;
+
+       /* clear the temporary flags before converting to string */
+       sf &= SF_NONVOLATILE_FLAGS;
+
+       if (sf == 0)
+               return xstrdup("ok");
+
+       len = 0;
+       for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
+               if (sf & pkg_state_flag_map[i].value)
+                       len += strlen(pkg_state_flag_map[i].str) + 1;
+       }
+
+       str = xmalloc(len+1);
+       str[0] = '\0';
+
+       for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
+               if (sf & pkg_state_flag_map[i].value) {
+                       strncat(str, pkg_state_flag_map[i].str, len);
+                       strncat(str, ",", len);
+               }
+       }
+
+       len = strlen(str);
+       str[len-1] = '\0'; /* squash last comma */
+
+       return str;
+}
+
+pkg_state_flag_t
+pkg_state_flag_from_str(const char *str)
+{
+     int i;
+     int sf = SF_OK;
+
+     if (strcmp(str, "ok") == 0) {
+         return SF_OK;
      }
-     raw = raw_start;
-     while (*raw) {
-        if (raw!=NULL)
-          free(*raw++);
+     for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
+         const char *sfname = pkg_state_flag_map[i].str;
+         int sfname_len = strlen(sfname);
+         if (strncmp(str, sfname, sfname_len) == 0) {
+              sf |= pkg_state_flag_map[i].value;
+              str += sfname_len;
+              if (str[0] == ',') {
+                   str++;
+              } else {
+                   break;
+              }
+         }
      }
 
-     free(raw_start); 
+     return sf;
+}
 
-     return ;
+static char *
+pkg_state_status_to_str(pkg_state_status_t ss)
+{
+     int i;
 
+     for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
+         if (pkg_state_status_map[i].value == ss) {
+              return pkg_state_status_map[i].str;
+         }
+     }
+
+     fprintf(stderr, "%s: ERROR: Illegal value for state_status: %d\n",
+            __FUNCTION__, ss);
+     return "<STATE_STATUS_UNKNOWN>";
 }
 
-void pkg_formatted_field(FILE *fp, pkg_t *pkg, const char *field)
+pkg_state_status_t
+pkg_state_status_from_str(const char *str)
 {
      int i;
-     int flag_provide_false = 0;
+
+     for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
+         if (strcmp(str, pkg_state_status_map[i].str) == 0) {
+              return pkg_state_status_map[i].value;
+         }
+     }
+
+     fprintf(stderr, "%s: ERROR: Illegal value for state_status string: %s\n",
+            __FUNCTION__, str);
+     return SS_NOT_INSTALLED;
+}
+
+void
+pkg_formatted_field(FILE *fp, pkg_t *pkg, const char *field)
+{
+     int i, j;
+     char *str;
+     int depends_count = pkg->pre_depends_count +
+                        pkg->depends_count +
+                        pkg->recommends_count +
+                        pkg->suggests_count;
 
      if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) {
          goto UNKNOWN_FMT_FIELD;
@@ -548,16 +660,24 @@ void pkg_formatted_field(FILE *fp, pkg_t *pkg, const char *field)
                fprintf(fp, "Conffiles:\n");
               for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) {
                    if (((conffile_t *)iter->data)->name && ((conffile_t *)iter->data)->value) {
-                         fprintf(fp, "%s %s\n", 
+                         fprintf(fp, " %s %s\n", 
                                  ((conffile_t *)iter->data)->name, 
                                  ((conffile_t *)iter->data)->value);
                    }
               }
          } else if (strcasecmp(field, "Conflicts") == 0) {
+              struct depend *cdep;
               if (pkg->conflicts_count) {
                     fprintf(fp, "Conflicts:");
                    for(i = 0; i < pkg->conflicts_count; i++) {
-                        fprintf(fp, "%s %s", i == 0 ? "" : ",", pkg->conflicts_str[i]);
+                       cdep = pkg->conflicts[i].possibilities[0];
+                        fprintf(fp, "%s %s", i == 0 ? "" : ",",
+                               cdep->pkg->name);
+                       if (cdep->version) {
+                               fprintf(fp, " (%s%s)",
+                                       constraint_to_str(cdep->constraint),
+                                       cdep->version);
+                       }
                     }
                     fprintf(fp, "\n");
               }
@@ -570,8 +690,13 @@ void pkg_formatted_field(FILE *fp, pkg_t *pkg, const char *field)
          if (strcasecmp(field, "Depends") == 0) {
               if (pkg->depends_count) {
                     fprintf(fp, "Depends:");
-                   for(i = 0; i < pkg->depends_count; i++) {
-                        fprintf(fp, "%s %s", i == 0 ? "" : ",", pkg->depends_str[i]);
+                   for (j=0, i=0; i<depends_count; i++) {
+                       if (pkg->depends[i].type != DEPEND)
+                               continue;
+                       str = pkg_depend_str(pkg, i);
+                       fprintf(fp, "%s %s", j == 0 ? "" : ",", str);
+                       free(str);
+                       j++;
                     }
                    fprintf(fp, "\n");
               }
@@ -625,23 +750,12 @@ void pkg_formatted_field(FILE *fp, pkg_t *pkg, const char *field)
                fprintf(fp, "Priority: %s\n", pkg->priority);
          } else if (strcasecmp(field, "Provides") == 0) {
               if (pkg->provides_count) {
-               /* Here we check if the opkg_internal_use_only is used, and we discard it.*/
-                  for ( i=0; i < pkg->provides_count; i++ ){
-                     if (strstr(pkg->provides_str[i],"opkg_internal_use_only")!=NULL) {
-                         memset (pkg->provides_str[i],'\x0',strlen(pkg->provides_str[i])); /* Pigi clear my trick flag, just in case */
-                         flag_provide_false = 1;
-                      }
-                  }
-                  if ( !flag_provide_false ||                                             /* Pigi there is not my trick flag */
-                     ((flag_provide_false) &&  (pkg->provides_count > 1))){             /* Pigi There is, but we also have others Provides */
-                     fprintf(fp, "Provides:");
-                    for(i = 0; i < pkg->provides_count; i++) {
-                         if (strlen(pkg->provides_str[i])>0) {
-                            fprintf(fp, "%s %s", i == 1 ? "" : ",", pkg->provides_str[i]);
-                         }
-                     }
-                     fprintf(fp, "\n");
+                  fprintf(fp, "Provides:");
+                 for(i = 1; i < pkg->provides_count; i++) {
+                      fprintf(fp, "%s %s", i == 1 ? "" : ",",
+                                     pkg->provides[i]->name);
                   }
+                  fprintf(fp, "\n");
                }
          } else {
               goto UNKNOWN_FMT_FIELD;
@@ -653,15 +767,21 @@ void pkg_formatted_field(FILE *fp, pkg_t *pkg, const char *field)
               if (pkg->replaces_count) {
                     fprintf(fp, "Replaces:");
                    for (i = 0; i < pkg->replaces_count; i++) {
-                        fprintf(fp, "%s %s", i == 0 ? "" : ",", pkg->replaces_str[i]);
+                        fprintf(fp, "%s %s", i == 0 ? "" : ",",
+                                       pkg->replaces[i]->name);
                     }
                     fprintf(fp, "\n");
               }
          } else if (strcasecmp (field, "Recommends") == 0) {
               if (pkg->recommends_count) {
                     fprintf(fp, "Recommends:");
-                   for(i = 0; i < pkg->recommends_count; i++) {
-                        fprintf(fp, "%s %s", i == 0 ? "" : ",", pkg->recommends_str[i]);
+                   for (j=0, i=0; i<depends_count; i++) {
+                       if (pkg->depends[i].type != RECOMMEND)
+                               continue;
+                       str = pkg_depend_str(pkg, i);
+                       fprintf(fp, "%s %s", j == 0 ? "" : ",", str);
+                       free(str);
+                       j++;
                     }
                     fprintf(fp, "\n");
               }
@@ -691,22 +811,21 @@ void pkg_formatted_field(FILE *fp, pkg_t *pkg, const char *field)
                }
          } else if (strcasecmp(field, "Status") == 0) {
                char *pflag = pkg_state_flag_to_str(pkg->state_flag);
-               char *pstat = pkg_state_status_to_str(pkg->state_status);
-               char *pwant = pkg_state_want_to_str(pkg->state_want);
-
-              if (pflag == NULL || pstat == NULL || pwant == NULL)
-                      return;
-
-               fprintf(fp, "Status: %s %s %s\n", pwant, pflag, pstat);
-
+               fprintf(fp, "Status: %s %s %s\n",
+                                      pkg_state_want_to_str(pkg->state_want),
+                              pflag,
+                               pkg_state_status_to_str(pkg->state_status));
                free(pflag);
-               free(pwant);
-               free(pstat);
          } else if (strcasecmp(field, "Suggests") == 0) {
               if (pkg->suggests_count) {
                     fprintf(fp, "Suggests:");
-                   for(i = 0; i < pkg->suggests_count; i++) {
-                        fprintf(fp, "%s %s", i == 0 ? "" : ",", pkg->suggests_str[i]);
+                   for (j=0, i=0; i<depends_count; i++) {
+                       if (pkg->depends[i].type != SUGGEST)
+                               continue;
+                       str = pkg_depend_str(pkg, i);
+                       fprintf(fp, "%s %s", j == 0 ? "" : ",", str);
+                       free(str);
+                       j++;
                     }
                     fprintf(fp, "\n");
               }
@@ -742,7 +861,8 @@ UNKNOWN_FMT_FIELD:
      fprintf(stderr, "%s: ERROR: Unknown field name: %s\n", __FUNCTION__, field);
 }
 
-void pkg_formatted_info(FILE *fp, pkg_t *pkg)
+void
+pkg_formatted_info(FILE *fp, pkg_t *pkg)
 {
        pkg_formatted_field(fp, pkg, "Package");
        pkg_formatted_field(fp, pkg, "Version");
@@ -768,7 +888,8 @@ void pkg_formatted_info(FILE *fp, pkg_t *pkg)
        fputs("\n", fp);
 }
 
-void pkg_print_status(pkg_t * pkg, FILE * file)
+void
+pkg_print_status(pkg_t * pkg, FILE * file)
 {
      if (pkg == NULL) {
          return;
@@ -817,30 +938,6 @@ void pkg_print_status(pkg_t * pkg, FILE * file)
  *
  * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
  */
-int pkg_compare_versions(const pkg_t *pkg, const pkg_t *ref_pkg)
-{
-     int r;
-
-     if (pkg->epoch > ref_pkg->epoch) {
-         return 1;
-     }
-
-     if (pkg->epoch < ref_pkg->epoch) {
-         return -1;
-     }
-
-     r = verrevcmp(pkg->version, ref_pkg->version);
-     if (r) {
-         return r;
-     }
-
-     r = verrevcmp(pkg->revision, ref_pkg->revision);
-     if (r) {
-         return r;
-     }
-
-     return r;
-}
 
 /* assume ascii; warning: evaluates x multiple times! */
 #define order(x) ((x) == '~' ? -1 \
@@ -849,7 +946,8 @@ int pkg_compare_versions(const pkg_t *pkg, const pkg_t *ref_pkg)
                : isalpha((x)) ? (x) \
                : (x) + 256)
 
-static int verrevcmp(const char *val, const char *ref) {
+static int
+verrevcmp(const char *val, const char *ref) {
   if (!val) val= "";
   if (!ref) ref= "";
 
@@ -875,7 +973,35 @@ static int verrevcmp(const char *val, const char *ref) {
   return 0;
 }
 
-int pkg_version_satisfied(pkg_t *it, pkg_t *ref, const char *op)
+int
+pkg_compare_versions(const pkg_t *pkg, const pkg_t *ref_pkg)
+{
+     int r;
+
+     if (pkg->epoch > ref_pkg->epoch) {
+         return 1;
+     }
+
+     if (pkg->epoch < ref_pkg->epoch) {
+         return -1;
+     }
+
+     r = verrevcmp(pkg->version, ref_pkg->version);
+     if (r) {
+         return r;
+     }
+
+     r = verrevcmp(pkg->revision, ref_pkg->revision);
+     if (r) {
+         return r;
+     }
+
+     return r;
+}
+
+
+int
+pkg_version_satisfied(pkg_t *it, pkg_t *ref, const char *op)
 {
      int r;
 
@@ -905,7 +1031,8 @@ int pkg_version_satisfied(pkg_t *it, pkg_t *ref, const char *op)
      return 0;
 }
 
-int pkg_name_version_and_architecture_compare(const void *p1, const 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;
@@ -935,7 +1062,8 @@ int pkg_name_version_and_architecture_compare(const void *p1, const void *p2)
      return 0;
 }
 
-int abstract_pkg_name_compare(const void *p1, const 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;
@@ -948,42 +1076,41 @@ int abstract_pkg_name_compare(const void *p1, const void *p2)
 }
 
 
-char *pkg_version_str_alloc(pkg_t *pkg)
+char *
+pkg_version_str_alloc(pkg_t *pkg)
 {
-     char *complete_version;
-     char *epoch_str;
-     char *revision_str;
-
-     if (pkg->epoch) {
-         sprintf_alloc(&epoch_str, "%d:", pkg->epoch);
-     } else {
-         epoch_str = strdup("");
-     }
-
-     if (pkg->revision && strlen(pkg->revision)) {
-         sprintf_alloc(&revision_str, "-%s", pkg->revision);
-     } else {
-         revision_str = strdup("");
-     }
-
-
-     sprintf_alloc(&complete_version, "%s%s%s",
-                  epoch_str, pkg->version, revision_str);
-
-     free(epoch_str);
-     free(revision_str);
-
-     return complete_version;
+       char *version;
+
+       if (pkg->epoch) {
+               if (pkg->revision)
+                       sprintf_alloc(&version, "%d:%s-%s",
+                               pkg->epoch, pkg->version, pkg->revision);
+               else
+                       sprintf_alloc(&version, "%d:%s",
+                               pkg->epoch, pkg->version);
+       } else {
+               if (pkg->revision)
+                       sprintf_alloc(&version, "%s-%s",
+                               pkg->version, pkg->revision);
+               else
+                       version = xstrdup(pkg->version);
+       }
+
+       return version;
 }
 
-str_list_t *pkg_get_installed_files(pkg_t *pkg)
+/*
+ * XXX: this should be broken into two functions
+ */
+str_list_t *
+pkg_get_installed_files(opkg_conf_t *conf, pkg_t *pkg)
 {
-     int err;
+     int err, fd;
      char *list_file_name = NULL;
      FILE *list_file = NULL;
      char *line;
      char *installed_file_name;
-     int rootdirlen;
+     int rootdirlen = 0;
 
      pkg->installed_files_ref_cnt++;
 
@@ -992,10 +1119,6 @@ str_list_t *pkg_get_installed_files(pkg_t *pkg)
      }
 
      pkg->installed_files = str_list_alloc();
-     if (pkg->installed_files == NULL) {
-         fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
-         return NULL;
-     }
 
      /* For uninstalled packages, get the file list directly from the package.
        For installed packages, look at the package.list file in the database.
@@ -1008,34 +1131,51 @@ str_list_t *pkg_get_installed_files(pkg_t *pkg)
             file. In other words, change deb_extract so that it can
             simply return the file list as a char *[] rather than
             insisting on writing in to a FILE * as it does now. */
-         list_file = tmpfile();
+         sprintf_alloc(&list_file_name, "%s/%s.list.XXXXXX",
+                                         conf->tmp_dir, pkg->name);
+         fd = mkstemp(list_file_name);
+         if (fd == -1) {
+              opkg_message(conf, OPKG_ERROR, "%s: mkstemp(%s): %s",
+                              __FUNCTION__, list_file_name, strerror(errno));
+              free(list_file_name);
+              return pkg->installed_files;
+         }
+         list_file = fdopen(fd, "r+");
+         if (list_file == NULL) {
+              opkg_message(conf, OPKG_ERROR, "%s: fdopen: %s",
+                              __FUNCTION__, strerror(errno));
+              close(fd);
+              unlink(list_file_name);
+              free(list_file_name);
+              return pkg->installed_files;
+         }
          err = pkg_extract_data_file_names_to_stream(pkg, list_file);
          if (err) {
+              opkg_message(conf, OPKG_ERROR, "%s: Error extracting file list "
+                              "from %s: %s\n", __FUNCTION__,
+                              pkg->local_filename, strerror(err));
               fclose(list_file);
-              fprintf(stderr, "%s: Error extracting file list from %s: %s\n",
-                      __FUNCTION__, pkg->local_filename, strerror(err));
+              unlink(list_file_name);
+              free(list_file_name);
               return pkg->installed_files;
          }
          rewind(list_file);
      } else {
          sprintf_alloc(&list_file_name, "%s/%s.list",
                        pkg->dest->info_dir, pkg->name);
-         if (! file_exists(list_file_name)) {
-              free(list_file_name);
-              return pkg->installed_files;
-         }
-
          list_file = fopen(list_file_name, "r");
          if (list_file == NULL) {
-              fprintf(stderr, "WARNING: Cannot open %s: %s\n",
-                      list_file_name, strerror(errno));
+              opkg_message(conf, OPKG_ERROR, "%s: fopen(%s): %s\n",
+                      __FUNCTION__, list_file_name, strerror(errno));
               free(list_file_name);
               return pkg->installed_files;
          }
          free(list_file_name);
      }
 
-     rootdirlen = strlen( pkg->dest->root_dir );
+     if (conf->offline_root)
+          rootdirlen = strlen(conf->offline_root);
+
      while (1) {
          char *file_name;
        
@@ -1043,25 +1183,26 @@ str_list_t *pkg_get_installed_files(pkg_t *pkg)
          if (line == NULL) {
               break;
          }
-         str_chomp(line);
          file_name = line;
 
-         /* Take pains to avoid uglies like "/./" in the middle of file_name. */
-         if( strncmp( pkg->dest->root_dir, 
-                      file_name, 
-                      rootdirlen ) ) {
+         if (pkg->state_status == SS_NOT_INSTALLED || pkg->dest == NULL) {
               if (*file_name == '.') {
                    file_name++;
               }
               if (*file_name == '/') {
                    file_name++;
               }
-
-              /* Freed in pkg_free_installed_files */
-              sprintf_alloc(&installed_file_name, "%s%s", pkg->dest->root_dir, file_name);
+              sprintf_alloc(&installed_file_name, "%s%s",
+                              pkg->dest->root_dir, file_name);
          } else {
-              // already contains root_dir as header -> ABSOLUTE
-              sprintf_alloc(&installed_file_name, "%s", file_name);
+              if (conf->offline_root &&
+                      strncmp(conf->offline_root, file_name, rootdirlen)) {
+                   sprintf_alloc(&installed_file_name, "%s%s",
+                                   conf->offline_root, file_name);
+              } else {
+                   // already contains root_dir as header -> ABSOLUTE
+                   sprintf_alloc(&installed_file_name, "%s", file_name);
+              }
          }
          str_list_append(pkg->installed_files, installed_file_name);
           free(installed_file_name);
@@ -1070,6 +1211,11 @@ str_list_t *pkg_get_installed_files(pkg_t *pkg)
 
      fclose(list_file);
 
+     if (pkg->state_status == SS_NOT_INSTALLED || pkg->dest == NULL) {
+         unlink(list_file_name);
+         free(list_file_name);
+     }
+
      return pkg->installed_files;
 }
 
@@ -1078,44 +1224,37 @@ str_list_t *pkg_get_installed_files(pkg_t *pkg)
    convention. Nor the alloc/free convention. But, then again, neither
    of these conventions currrently fit the way these two functions
    work. */
-int pkg_free_installed_files(pkg_t *pkg)
+void
+pkg_free_installed_files(pkg_t *pkg)
 {
      pkg->installed_files_ref_cnt--;
 
      if (pkg->installed_files_ref_cnt > 0)
-         return 0;
+         return;
 
      if (pkg->installed_files) {
          str_list_purge(pkg->installed_files);
      }
 
      pkg->installed_files = NULL;
-
-     return 0;
 }
 
-int pkg_remove_installed_files_list(opkg_conf_t *conf, pkg_t *pkg)
+void
+pkg_remove_installed_files_list(opkg_conf_t *conf, pkg_t *pkg)
 {
-     int err;
-     char *list_file_name;
+       char *list_file_name;
 
-     //I don't think pkg_free_installed_files should be called here. Jamey
-     //pkg_free_installed_files(pkg);
+       sprintf_alloc(&list_file_name, "%s/%s.list",
+               pkg->dest->info_dir, pkg->name);
 
-     sprintf_alloc(&list_file_name, "%s/%s.list",
-                  pkg->dest->info_dir, pkg->name);
-     if (!conf->noaction) {
-         err = unlink(list_file_name);
-         free(list_file_name);
+       if (!conf->noaction)
+               (void)unlink(list_file_name);
 
-         if (err) {
-              return errno;
-         }
-     }
-     return 0;
+       free(list_file_name);
 }
 
-conffile_t *pkg_get_conffile(pkg_t *pkg, const char *file_name)
+conffile_t *
+pkg_get_conffile(pkg_t *pkg, const char *file_name)
 {
      conffile_list_elt_t *iter;
      conffile_t *conffile;
@@ -1135,13 +1274,41 @@ conffile_t *pkg_get_conffile(pkg_t *pkg, const char *file_name)
      return NULL;
 }
 
-int pkg_run_script(opkg_conf_t *conf, pkg_t *pkg,
-                  const char *script, const char *args)
+int
+pkg_run_script(opkg_conf_t *conf, pkg_t *pkg,
+               const char *script, const char *args)
 {
      int err;
      char *path;
      char *cmd;
 
+     if (conf->noaction)
+            return 0;
+
+     /* XXX: CLEANUP: There must be a better way to handle maintainer
+       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)
+      */
+
+     if (conf->offline_root) {
+          if (conf->offline_root_path) {
+            setenv("PATH", conf->offline_root_path, 1);
+          } else {
+            opkg_message(conf, OPKG_NOTICE, 
+               "(offline root mode: not running %s.%s)\n", pkg->name, script);
+           return 0;
+          }
+         setenv("OPKG_OFFLINE_ROOT", conf->offline_root, 1);
+         setenv("D", conf->offline_root, 1);
+     }
+
      /* XXX: FEATURE: When conf->offline_root is set, we should run the
        maintainer script within a chroot environment. */
 
@@ -1164,31 +1331,6 @@ int pkg_run_script(opkg_conf_t *conf, pkg_t *pkg,
      }
 
      opkg_message(conf, OPKG_INFO, "Running script %s\n", path);
-     if (conf->noaction) return 0;
-
-     /* XXX: CLEANUP: There must be a better way to handle maintainer
-       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",
            pkg->dest ? pkg->dest->root_dir : conf->default_dest->root_dir, 1);
@@ -1198,16 +1340,12 @@ int pkg_run_script(opkg_conf_t *conf, pkg_t *pkg,
          return 0;
      }
 
-     if (conf->offline_root && !AllowOfflineMode) {
-         fprintf(stderr, "(offline root mode: not running %s.%s)\n", pkg->name, script);
-         free(path);
-         return 0;
-     }
-
      sprintf_alloc(&cmd, "%s %s", path, args);
      free(path);
-
-     err = xsystem(cmd);
+     {
+         const char *argv[] = {"sh", "-c", cmd, NULL};
+         err = xsystem(argv);
+     }
      free(cmd);
 
      if (err) {
@@ -1218,128 +1356,8 @@ int pkg_run_script(opkg_conf_t *conf, pkg_t *pkg,
      return 0;
 }
 
-char *pkg_state_want_to_str(pkg_state_want_t sw)
-{
-     int i;
-
-     for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
-         if (pkg_state_want_map[i].value == sw) {
-              return strdup(pkg_state_want_map[i].str);
-         }
-     }
-
-     fprintf(stderr, "%s: ERROR: Illegal value for state_want: %d\n",
-            __FUNCTION__, sw);
-     return strdup("<STATE_WANT_UNKNOWN>");
-}
-
-pkg_state_want_t pkg_state_want_from_str(char *str)
-{
-     int i;
-
-     for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
-         if (strcmp(str, pkg_state_want_map[i].str) == 0) {
-              return pkg_state_want_map[i].value;
-         }
-     }
-
-     fprintf(stderr, "%s: ERROR: Illegal value for state_want string: %s\n",
-            __FUNCTION__, str);
-     return SW_UNKNOWN;
-}
-
-char *pkg_state_flag_to_str(pkg_state_flag_t sf)
-{
-     int i;
-     int len = 3; /* ok\000 is minimum */
-     char *str = NULL;
-
-     /* clear the temporary flags before converting to string */
-     sf &= SF_NONVOLATILE_FLAGS;
-
-     if (sf == 0) {
-         return strdup("ok");
-     } else {
-
-         for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
-              if (sf & pkg_state_flag_map[i].value) {
-                   len += strlen(pkg_state_flag_map[i].str) + 1;
-              }
-         }
-         str = malloc(len);
-          if ( str == NULL ) {
-             fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
-              return NULL;
-          }
-         str[0] = 0;
-         for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
-              if (sf & pkg_state_flag_map[i].value) {
-                   strcat(str, pkg_state_flag_map[i].str);
-                   strcat(str, ",");
-              }
-         }
-         len = strlen(str);
-         str[len-1] = 0; /* squash last comma */
-         return str;
-     }
-}
-
-pkg_state_flag_t pkg_state_flag_from_str(const char *str)
-{
-     int i;
-     int sf = SF_OK;
-
-     if (strcmp(str, "ok") == 0) {
-         return SF_OK;
-     }
-     for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
-         const char *sfname = pkg_state_flag_map[i].str;
-         int sfname_len = strlen(sfname);
-         if (strncmp(str, sfname, sfname_len) == 0) {
-              sf |= pkg_state_flag_map[i].value;
-              str += sfname_len;
-              if (str[0] == ',') {
-                   str++;
-              } else {
-                   break;
-              }
-         }
-     }
-
-     return sf;
-}
-
-char *pkg_state_status_to_str(pkg_state_status_t ss)
-{
-     int i;
-
-     for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
-         if (pkg_state_status_map[i].value == ss) {
-              return strdup(pkg_state_status_map[i].str);
-         }
-     }
-
-     fprintf(stderr, "%s: ERROR: Illegal value for state_status: %d\n",
-            __FUNCTION__, ss);
-     return strdup("<STATE_STATUS_UNKNOWN>");
-}
-
-pkg_state_status_t pkg_state_status_from_str(const char *str)
-{
-     int i;
-
-     for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
-         if (strcmp(str, pkg_state_status_map[i].str) == 0) {
-              return pkg_state_status_map[i].value;
-         }
-     }
-
-     fprintf(stderr, "%s: ERROR: Illegal value for state_status string: %s\n",
-            __FUNCTION__, str);
-     return SS_NOT_INSTALLED;
-}
-
-int pkg_arch_supported(opkg_conf_t *conf, pkg_t *pkg)
+int
+pkg_arch_supported(opkg_conf_t *conf, pkg_t *pkg)
 {
      nv_pair_list_elt_t *l;
 
@@ -1358,7 +1376,8 @@ int pkg_arch_supported(opkg_conf_t *conf, pkg_t *pkg)
      return 0;
 }
 
-int pkg_get_arch_priority(opkg_conf_t *conf, const char *archname)
+int
+pkg_get_arch_priority(opkg_conf_t *conf, const char *archname)
 {
      nv_pair_list_elt_t *l;
 
@@ -1372,7 +1391,8 @@ int pkg_get_arch_priority(opkg_conf_t *conf, const char *archname)
      return 0;
 }
 
-int pkg_info_preinstall_check(opkg_conf_t *conf)
+void
+pkg_info_preinstall_check(opkg_conf_t *conf)
 {
      int i;
      hash_table_t *pkg_hash = &conf->pkg_hash;
@@ -1413,7 +1433,7 @@ int pkg_info_preinstall_check(opkg_conf_t *conf)
      pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
      for (i = 0; i < installed_pkgs->len; i++) {
          pkg_t *pkg = installed_pkgs->pkgs[i];
-         str_list_t *installed_files = pkg_get_installed_files(pkg); /* this causes installed_files to be cached */
+         str_list_t *installed_files = pkg_get_installed_files(conf, pkg); /* this causes installed_files to be cached */
          str_list_elt_t *iter, *niter;
          if (installed_files == NULL) {
               opkg_message(conf, OPKG_ERROR, "No installed files for pkg %s\n", pkg->name);
@@ -1429,8 +1449,6 @@ int pkg_info_preinstall_check(opkg_conf_t *conf)
          pkg_free_installed_files(pkg);
      }
      pkg_vec_free(installed_pkgs);
-
-     return 0;
 }
 
 struct pkg_write_filelist_data {
@@ -1439,7 +1457,8 @@ struct pkg_write_filelist_data {
      FILE *stream;
 };
 
-void pkg_write_filelist_helper(const char *key, void *entry_, void *data_)
+void
+pkg_write_filelist_helper(const char *key, void *entry_, void *data_)
 {
      struct pkg_write_filelist_data *data = data_;
      pkg_t *entry = entry_;
@@ -1448,62 +1467,61 @@ void pkg_write_filelist_helper(const char *key, void *entry_, void *data_)
      }
 }
 
-int pkg_write_filelist(opkg_conf_t *conf, pkg_t *pkg)
+int
+pkg_write_filelist(opkg_conf_t *conf, pkg_t *pkg)
 {
-     struct pkg_write_filelist_data data;
-     char *list_file_name = NULL;
-     int err = 0;
+       struct pkg_write_filelist_data data;
+       char *list_file_name;
 
-     if (!pkg) {
-         opkg_message(conf, OPKG_ERROR, "Null pkg\n");
-         return -EINVAL;
-     }
-     opkg_message(conf, OPKG_INFO,
-                 "    creating %s.list file\n", pkg->name);
-     sprintf_alloc(&list_file_name, "%s/%s.list", pkg->dest->info_dir, pkg->name);
-     if (!list_file_name) {
-         opkg_message(conf, OPKG_ERROR, "Failed to alloc list_file_name\n");
-         return -ENOMEM;
-     }
-     opkg_message(conf, OPKG_INFO,
-                 "    creating %s file for pkg %s\n", list_file_name, pkg->name);
-     data.stream = fopen(list_file_name, "w");
-     if (!data.stream) {
-         opkg_message(conf, OPKG_ERROR, "Could not open %s for writing: %s\n",
-                      list_file_name, strerror(errno));
-                      return errno;
-     }
-     data.pkg = pkg;
-     data.conf = conf;
-     hash_table_foreach(&conf->file_hash, pkg_write_filelist_helper, &data);
-     fclose(data.stream);
-     free(list_file_name);
+       sprintf_alloc(&list_file_name, "%s/%s.list",
+                       pkg->dest->info_dir, pkg->name);
+
+       opkg_message(conf, OPKG_INFO, "%s: creating %s file for pkg %s\n",
+                       __FUNCTION__, list_file_name, pkg->name);
+
+       data.stream = fopen(list_file_name, "w");
+       if (!data.stream) {
+               opkg_message(conf, OPKG_ERROR, "%s: fopen(%s, \"w\"): %s\n",
+                       __FUNCTION__, list_file_name, strerror(errno));
+               free(list_file_name);
+               return -1;
+       }
+
+       data.pkg = pkg;
+       data.conf = conf;
+       hash_table_foreach(&conf->file_hash, pkg_write_filelist_helper, &data);
+       fclose(data.stream);
+       free(list_file_name);
 
-     pkg->state_flag &= ~SF_FILELIST_CHANGED;
+       pkg->state_flag &= ~SF_FILELIST_CHANGED;
 
-     return err;
+       return 0;
 }
 
-int pkg_write_changed_filelists(opkg_conf_t *conf)
+int
+pkg_write_changed_filelists(opkg_conf_t *conf)
 {
-     pkg_vec_t *installed_pkgs = pkg_vec_alloc();
-     hash_table_t *pkg_hash = &conf->pkg_hash;
-     int i;
-     int err;
-     if (conf->noaction)
-         return 0;
+       pkg_vec_t *installed_pkgs = pkg_vec_alloc();
+       hash_table_t *pkg_hash = &conf->pkg_hash;
+       int i, err, ret = 0;
 
-     opkg_message(conf, OPKG_INFO, "%s: saving changed filelists\n", __FUNCTION__);
-     pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
-     for (i = 0; i < installed_pkgs->len; i++) {
-         pkg_t *pkg = installed_pkgs->pkgs[i];
-         if (pkg->state_flag & SF_FILELIST_CHANGED) {
-               opkg_message(conf, OPKG_DEBUG, "Calling pkg_write_filelist for pkg=%s from %s\n", pkg->name, __FUNCTION__);
-              err = pkg_write_filelist(conf, pkg);
-              if (err)
-                   opkg_message(conf, OPKG_NOTICE, "pkg_write_filelist pkg=%s returned %d\n", pkg->name, err);
-         }
-     }
-     pkg_vec_free (installed_pkgs);
-     return 0;
+       if (conf->noaction)
+               return 0;
+
+       opkg_message(conf, OPKG_INFO, "%s: saving changed filelists\n",
+                       __FUNCTION__);
+
+       pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
+       for (i = 0; i < installed_pkgs->len; i++) {
+               pkg_t *pkg = installed_pkgs->pkgs[i];
+               if (pkg->state_flag & SF_FILELIST_CHANGED) {
+                       err = pkg_write_filelist(conf, pkg);
+                       if (err)
+                               ret = -1;
+               }
+       }
+
+       pkg_vec_free (installed_pkgs);
+
+       return ret;
 }