Fix parsing of Conffiles lines in status files.
[oweals/opkg-lede.git] / libopkg / pkg.c
index e36a38133c688165f71a2b19d9045637c46c24e6..9ba44e82eafa71493952f3132bae8ea2f844fe57 100644 (file)
@@ -29,6 +29,7 @@
 #include "opkg_message.h"
 #include "opkg_utils.h"
 
+#include "libbb/libbb.h"
 #include "sprintf_alloc.h"
 #include "file_util.h"
 #include "str_util.h"
@@ -78,12 +79,7 @@ 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 = xcalloc(1, sizeof(pkg_t));
      pkg_init(pkg);
 
      return pkg;
@@ -162,152 +158,182 @@ void compound_depend_deinit (compound_depend_t *depends)
 
 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;
-
-     active_list_clear(&pkg->list);
-
-     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;
-
-     for (i = 0; i < pkg->conflicts_count; i++)
-       free (pkg->conflicts_str[i]);
-     free(pkg->conflicts_str);
-     pkg->conflicts_str = NULL;
+       if (pkg->name)
+               free(pkg->name);
+       pkg->name = NULL;
 
-     for (i = 0; i < pkg->replaces_count; i++)
-       free (pkg->replaces_str[i]);
-     free(pkg->replaces_str);
-     pkg->replaces_str = NULL;
+       pkg->epoch = 0;
 
-     for (i = 0; i < pkg->recommends_count; i++)
-       free (pkg->recommends_str[i]);
-     free(pkg->recommends_str);
-     pkg->recommends_str = 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->suggests_count; i++)
-       free (pkg->suggests_str[i]);
-     free(pkg->suggests_str);
-     pkg->suggests_str = NULL;
+       /* owned by opkg_conf_t */
+       pkg->dest = NULL;
+       /* owned by opkg_conf_t */
+       pkg->src = NULL;
 
-     if (pkg->depends)
-     {
-       int count = pkg->pre_depends_count + pkg->depends_count + pkg->recommends_count + pkg->suggests_count;
-       int x;
+       if (pkg->architecture)
+               free(pkg->architecture);
+       pkg->architecture = NULL;
 
-       for (x = 0; x < count; x++)
-        compound_depend_deinit (&pkg->depends[x]);
-       free (pkg->depends);
-     }
+       if (pkg->maintainer)
+               free(pkg->maintainer);
+       pkg->maintainer = NULL;
 
-     if (pkg->conflicts)
-     {
-       int x;
-       for (x = 0; x < pkg->conflicts_count; x++)
-         compound_depend_deinit (&pkg->conflicts[x]);
-       free (pkg->conflicts);
-     }
+       if (pkg->section)
+               free(pkg->section);
+       pkg->section = NULL;
 
-     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;
+
+       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-1; i++)
+               free (pkg->provides_str[i]);
+       free(pkg->provides_str);
+       pkg->provides_str = NULL;
+
+       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;
+
+               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;
+       if (pkg->pre_depends_str)
+               free(pkg->pre_depends_str);
+       pkg->pre_depends_str = NULL;
+       
+       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,
+
+       if (pkg->size)
+               free(pkg->size);
+       pkg->size = NULL;
+
+       if (pkg->installed_size)
+               free(pkg->installed_size);
+       pkg->installed_size = NULL;
+
+       if (pkg->priority)
+               free(pkg->priority);
+       pkg->priority = NULL;
+
+       if (pkg->source)
+               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;
+       pkg->installed_files_ref_cnt = 1;
+       pkg_free_installed_files(pkg);
+       pkg->essential = 0;
+
+       if (pkg->tags)
+               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;
 
      err = pkg_init(pkg);
      if (err) { return err; }
 
-     pkg->local_filename = strdup(filename);
+     pkg->local_filename = xstrdup(filename);
     
      control_file = tmpfile();
      err = pkg_extract_control_file_to_stream(pkg, control_file);
      if (err) { return err; }
 
      rewind(control_file);
-     raw = raw_start = read_raw_pkgs_from_stream(control_file);
-     pkg_parse_raw(pkg, &raw, NULL, NULL);
+     pkg_parse_from_stream(pkg, control_file, PFM_ALL);
 
      fclose(control_file);
 
-     raw = raw_start;
-     while (*raw) {
-         free(*raw++);
-     }
-     free(raw_start);
-
      return 0;
 }
 
@@ -330,15 +356,15 @@ int pkg_merge(pkg_t *oldpkg, pkg_t *newpkg, int set_status)
      if (!oldpkg->dest)
          oldpkg->dest = newpkg->dest;
      if (!oldpkg->architecture)
-         oldpkg->architecture = str_dup_safe(newpkg->architecture);
+         oldpkg->architecture = xstrdup(newpkg->architecture);
      if (!oldpkg->arch_priority)
          oldpkg->arch_priority = newpkg->arch_priority;
      if (!oldpkg->section)
-         oldpkg->section = str_dup_safe(newpkg->section);
+         oldpkg->section = xstrdup(newpkg->section);
      if(!oldpkg->maintainer)
-         oldpkg->maintainer = str_dup_safe(newpkg->maintainer);
+         oldpkg->maintainer = xstrdup(newpkg->maintainer);
      if(!oldpkg->description)
-         oldpkg->description = str_dup_safe(newpkg->description);
+         oldpkg->description = xstrdup(newpkg->description);
      if (set_status) {
          /* merge the state_flags from the new package */
          oldpkg->state_want = newpkg->state_want;
@@ -383,8 +409,10 @@ int pkg_merge(pkg_t *oldpkg, pkg_t *newpkg, int set_status)
          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) {
@@ -408,28 +436,25 @@ int pkg_merge(pkg_t *oldpkg, pkg_t *newpkg, int set_status)
      }
 
      if (!oldpkg->filename)
-         oldpkg->filename = str_dup_safe(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);
+         oldpkg->filename = xstrdup(newpkg->filename);
      if (!oldpkg->local_filename)
-         oldpkg->local_filename = str_dup_safe(newpkg->local_filename);
+         oldpkg->local_filename = xstrdup(newpkg->local_filename);
      if (!oldpkg->tmp_unpack_dir)
-         oldpkg->tmp_unpack_dir = str_dup_safe(newpkg->tmp_unpack_dir);
+         oldpkg->tmp_unpack_dir = xstrdup(newpkg->tmp_unpack_dir);
      if (!oldpkg->md5sum)
-         oldpkg->md5sum = str_dup_safe(newpkg->md5sum);
+         oldpkg->md5sum = xstrdup(newpkg->md5sum);
 #if defined HAVE_SHA256
      if (!oldpkg->sha256sum)
-         oldpkg->sha256sum = str_dup_safe(newpkg->sha256sum);
+         oldpkg->sha256sum = xstrdup(newpkg->sha256sum);
 #endif
      if (!oldpkg->size)
-         oldpkg->size = str_dup_safe(newpkg->size);
+         oldpkg->size = xstrdup(newpkg->size);
      if (!oldpkg->installed_size)
-         oldpkg->installed_size = str_dup_safe(newpkg->installed_size);
+         oldpkg->installed_size = xstrdup(newpkg->installed_size);
      if (!oldpkg->priority)
-         oldpkg->priority = str_dup_safe(newpkg->priority);
+         oldpkg->priority = xstrdup(newpkg->priority);
      if (!oldpkg->source)
-         oldpkg->source = str_dup_safe(newpkg->source);
+         oldpkg->source = xstrdup(newpkg->source);
      if (nv_pair_list_empty(&oldpkg->conffiles)){
          list_splice_init(&newpkg->conffiles.head, &oldpkg->conffiles.head);
          conffile_list_init(&newpkg->conffiles);
@@ -449,7 +474,7 @@ 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));
 
      if (ab_pkg == NULL) {
          fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
@@ -475,47 +500,32 @@ int abstract_pkg_init(abstract_pkg_t *ab_pkg)
 }
 
 void set_flags_from_control(opkg_conf_t *conf, pkg_t *pkg){
-     char * temp_str;
-     char **raw =NULL;
-     char **raw_start=NULL; 
+     char *file_name;
+     FILE *fp;
 
-     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;
-     }
+     sprintf_alloc(&file_name,"%s/%s.control", pkg->dest->info_dir, pkg->name);
 
-     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);
-        }
-     }
-     raw = raw_start;
-     while (*raw) {
-        if (raw!=NULL)
-          free(*raw++);
+     fp = fopen(file_name, "r");
+     if (fp == NULL) {
+            opkg_message(conf, OPKG_ERROR, "fopen(%s): %s\n",
+                            file_name, strerror(errno));
+            return;
      }
 
-     free(raw_start); 
+     free(file_name);
+
+     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);
+     }
 
-     return ;
+     fclose(fp);
 
+     return;
 }
 
 void pkg_formatted_field(FILE *fp, pkg_t *pkg, const char *field)
 {
      int i;
-     int flag_provide_false = 0;
 
      if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) {
          goto UNKNOWN_FMT_FIELD;
@@ -547,7 +557,7 @@ 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);
                    }
@@ -624,23 +634,11 @@ 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 = 0; i < pkg->provides_count-1; i++) {
+                      fprintf(fp, "%s %s", i == 0 ? "" : ",", pkg->provides_str[i]);
                   }
+                  fprintf(fp, "\n");
                }
          } else {
               goto UNKNOWN_FMT_FIELD;
@@ -947,32 +945,27 @@ 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)
@@ -991,10 +984,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.
@@ -1141,6 +1130,33 @@ int pkg_run_script(opkg_conf_t *conf, pkg_t *pkg,
      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. */
 
@@ -1163,31 +1179,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);
@@ -1197,12 +1188,6 @@ 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);
 
@@ -1223,13 +1208,13 @@ char *pkg_state_want_to_str(pkg_state_want_t sw)
 
      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);
+              return xstrdup(pkg_state_want_map[i].str);
          }
      }
 
      fprintf(stderr, "%s: ERROR: Illegal value for state_want: %d\n",
             __FUNCTION__, sw);
-     return strdup("<STATE_WANT_UNKNOWN>");
+     return xstrdup("<STATE_WANT_UNKNOWN>");
 }
 
 pkg_state_want_t pkg_state_want_from_str(char *str)
@@ -1257,7 +1242,7 @@ char *pkg_state_flag_to_str(pkg_state_flag_t sf)
      sf &= SF_NONVOLATILE_FLAGS;
 
      if (sf == 0) {
-         return strdup("ok");
+         return xstrdup("ok");
      } else {
 
          for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
@@ -1265,11 +1250,7 @@ char *pkg_state_flag_to_str(pkg_state_flag_t sf)
                    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 = xmalloc(len);
          str[0] = 0;
          for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
               if (sf & pkg_state_flag_map[i].value) {
@@ -1314,13 +1295,13 @@ char *pkg_state_status_to_str(pkg_state_status_t ss)
 
      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);
+              return xstrdup(pkg_state_status_map[i].str);
          }
      }
 
      fprintf(stderr, "%s: ERROR: Illegal value for state_status: %d\n",
             __FUNCTION__, ss);
-     return strdup("<STATE_STATUS_UNKNOWN>");
+     return xstrdup("<STATE_STATUS_UNKNOWN>");
 }
 
 pkg_state_status_t pkg_state_status_from_str(const char *str)