Put the tmp file under conf->tmp_dir.
[oweals/opkg-lede.git] / libopkg / pkg.c
index b1f45dd274eea3bcc5658f36d3034d88bccf2573..5d705c7bb147c0d436ff611a61c4deb57821b434 100644 (file)
@@ -315,26 +315,48 @@ void pkg_deinit(pkg_t *pkg)
        pkg->tags = NULL;
 }
 
-int pkg_init_from_file(pkg_t *pkg, const char *filename)
+int
+pkg_init_from_file(pkg_t *pkg, const char *filename)
 {
-     int err;
-     FILE *control_file;
+       int fd, err = 0;
+       FILE *control_file;
+       char *control_path;
 
-     err = pkg_init(pkg);
-     if (err) { return err; }
+       pkg_init(pkg);
 
-     pkg->local_filename = xstrdup(filename);
-    
-     control_file = tmpfile();
-     err = pkg_extract_control_file_to_stream(pkg, control_file);
-     if (err) { return err; }
+       pkg->local_filename = xstrdup(filename);
+
+       sprintf_alloc(&control_path, "%s.control.XXXXXX", filename);
+       fd = mkstemp(control_path);
+       if (fd == -1) {
+               perror_msg("%s: mkstemp(%s)", __FUNCTION__, control_path);
+               err = -1;
+               goto err0;
+       }
 
-     rewind(control_file);
-     pkg_parse_from_stream(pkg, control_file, PFM_ALL);
+       control_file = fdopen(fd, "rw");
+       if (control_file == NULL) {
+               perror_msg("%s: fdopen", __FUNCTION__, control_path);
+               close(fd);
+               err = -1;
+               goto err1;
+       }
 
-     fclose(control_file);
+       err = pkg_extract_control_file_to_stream(pkg, control_file);
+       if (err)
+               goto err2;
 
-     return 0;
+       rewind(control_file);
+       pkg_parse_from_stream(pkg, control_file, PFM_ALL);
+
+err2:
+       fclose(control_file);
+err1:
+       unlink(control_path);
+err0:
+       free(control_path);
+
+       return err;
 }
 
 /* Merge any new information in newpkg into oldpkg */
@@ -509,6 +531,7 @@ void set_flags_from_control(opkg_conf_t *conf, pkg_t *pkg){
      if (fp == NULL) {
             opkg_message(conf, OPKG_ERROR, "fopen(%s): %s\n",
                             file_name, strerror(errno));
+            free(file_name);
             return;
      }
 
@@ -557,7 +580,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);
                    }
@@ -945,42 +968,40 @@ 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 = xstrdup("");
-     }
-
-     if (pkg->revision && strlen(pkg->revision)) {
-         sprintf_alloc(&revision_str, "-%s", pkg->revision);
-     } else {
-         revision_str = xstrdup("");
-     }
-
-
-     sprintf_alloc(&complete_version, "%s%s%s",
-                  epoch_str, pkg->version, revision_str);
-
-     free(epoch_str);
-     free(revision_str);
+       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 complete_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++;
 
@@ -1001,34 +1022,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, "rw");
+         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;
        
@@ -1039,22 +1077,24 @@ str_list_t *pkg_get_installed_files(pkg_t *pkg)
          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);
@@ -1063,6 +1103,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;
 }
 
@@ -1195,8 +1240,10 @@ int pkg_run_script(opkg_conf_t *conf, pkg_t *pkg,
 
      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) {
@@ -1398,7 +1445,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);