Browse Source

Ticket #4535: change name of temporary drirectory.

  * (mc_tmpdir): use g_mkdtemp() to create temporary directory.
  Make it name unique to avoid conflicts with other software such as
  Distrobox container.
  * (main): temporary directory has unique name from now. Remove it at exit.
Andrew Borodin 10 months ago
parent
commit
2fda4c6670
2 changed files with 22 additions and 76 deletions
  1. 9 75
      lib/vfs/interface.c
  2. 13 1
      src/main.c

+ 9 - 75
lib/vfs/interface.c

@@ -762,7 +762,7 @@ mc_mkstemps (vfs_path_t ** pname_vpath, const char *prefix, const char *suffix)
 /* --------------------------------------------------------------------------------------------- */
 /**
  * Return the directory where mc should keep its temporary files.
- * This directory is (in Bourne shell terms) "${TMPDIR=/tmp}/mc-$USER"
+ * This directory is (in Bourne shell terms) "${TMPDIR=/tmp}/mc-XXXXXX"
  * When called the first time, the directory is created if needed.
  * The first call should be done early, since we are using fprintf()
  * and not message() to report possible problems.
@@ -774,9 +774,7 @@ mc_tmpdir (void)
     static char buffer[PATH_MAX];
     static const char *tmpdir = NULL;
     const char *sys_tmp;
-    struct passwd *pwd;
     struct stat st;
-    const char *error = NULL;
 
     /* Check if already correctly initialized */
     if (tmpdir != NULL && lstat (tmpdir, &st) == 0 && S_ISDIR (st.st_mode) &&
@@ -791,84 +789,20 @@ mc_tmpdir (void)
             sys_tmp = TMPDIR_DEFAULT;
     }
 
-    pwd = getpwuid (getuid ());
-    if (pwd != NULL)
-        g_snprintf (buffer, sizeof (buffer), "%s/mc-%s", sys_tmp, pwd->pw_name);
+    g_snprintf (buffer, sizeof (buffer), "%s/mc-XXXXXX", sys_tmp);
+    tmpdir = g_mkdtemp (buffer);
+    if (tmpdir != NULL)
+        g_setenv ("MC_TMPDIR", tmpdir, TRUE);
     else
-        g_snprintf (buffer, sizeof (buffer), "%s/mc-%lu", sys_tmp, (unsigned long) getuid ());
-
-    canonicalize_pathname (buffer);
-
-    /* Try to create directory */
-    if (mkdir (buffer, S_IRWXU) != 0)
     {
-        if (errno == EEXIST && lstat (buffer, &st) == 0)
-        {
-            /* Sanity check for existing directory */
-            if (!S_ISDIR (st.st_mode))
-                error = _("%s is not a directory\n");
-            else if (st.st_uid != getuid ())
-                error = _("Directory %s is not owned by you\n");
-            else if (((st.st_mode & 0777) != 0700) && (chmod (buffer, 0700) != 0))
-                error = _("Cannot set correct permissions for directory %s\n");
-        }
-        else
-        {
-            fprintf (stderr,
-                     _("Cannot create temporary directory %s: %s\n"),
-                     buffer, unix_error_string (errno));
-            error = "";
-        }
-    }
-
-    if (error != NULL)
-    {
-        int test_fd;
-        char *fallback_prefix;
-        gboolean fallback_ok = FALSE;
-        vfs_path_t *test_vpath;
-
-        if (*error != '\0')
-            fprintf (stderr, error, buffer);
-
-        /* Test if sys_tmp is suitable for temporary files */
-        fallback_prefix = g_strdup_printf ("%s/mctest", sys_tmp);
-        test_fd = mc_mkstemps (&test_vpath, fallback_prefix, NULL);
-        g_free (fallback_prefix);
-        if (test_fd != -1)
-        {
-            close (test_fd);
-            test_fd = open (vfs_path_as_str (test_vpath), O_RDONLY);
-            if (test_fd != -1)
-            {
-                close (test_fd);
-                unlink (vfs_path_as_str (test_vpath));
-                fallback_ok = TRUE;
-            }
-        }
-
-        if (fallback_ok)
-        {
-            fprintf (stderr, _("Temporary files will be created in %s\n"), sys_tmp);
-            g_snprintf (buffer, sizeof (buffer), "%s", sys_tmp);
-            error = NULL;
-        }
-        else
-        {
-            fprintf (stderr, _("Temporary files will not be created\n"));
-            g_snprintf (buffer, sizeof (buffer), "%s", "/dev/null/");
-        }
-
-        vfs_path_free (test_vpath, TRUE);
+        fprintf (stderr, _("Cannot create temporary directory %s: %s.\n"
+                           "Temporary files will not be created\n"), buffer,
+                 unix_error_string (errno));
+        g_snprintf (buffer, sizeof (buffer), "%s", "/dev/null/");
         fprintf (stderr, "%s\n", _("Press any key to continue..."));
         getc (stdin);
     }
 
-    tmpdir = buffer;
-
-    if (error == NULL)
-        g_setenv ("MC_TMPDIR", tmpdir, TRUE);
-
     return tmpdir;
 }
 

+ 13 - 1
src/main.c

@@ -62,6 +62,7 @@
 #include "filemanager/ext.h"    /* flush_extension_file() */
 #include "filemanager/command.h"        /* cmdline */
 #include "filemanager/panel.h"  /* panalized_panel */
+#include "filemanager/filenot.h"        /* my_rmdir() */
 
 #ifdef USE_INTERNAL_EDIT
 #include "editor/edit.h"        /* edit_arg_free() */
@@ -257,6 +258,7 @@ main (int argc, char *argv[])
 {
     GError *mcerror = NULL;
     int exit_code = EXIT_FAILURE;
+    const char *tmpdir = NULL;
 
     mc_global.run_from_parent_mc = !check_sid ();
 
@@ -326,12 +328,17 @@ main (int argc, char *argv[])
     vfs_setup_work_dir ();
 
     /* Set up temporary directory after VFS initialization */
-    mc_tmpdir ();
+    tmpdir = mc_tmpdir ();
 
     /* do this after vfs initialization and vfs working directory setup
        due to mc_setctl() and mcedit_arg_vpath_new() calls in mc_setup_by_args() */
     if (!mc_setup_by_args (argc, argv, &mcerror))
     {
+        /* At exit, do this before vfs_shut():
+           normally, temporary directory should be empty */
+        vfs_expire (TRUE);
+        (void) my_rmdir (tmpdir);
+
         vfs_shut ();
         done_setup ();
         g_free (saved_other_dir);
@@ -470,6 +477,11 @@ main (int argc, char *argv[])
 
     keymap_free ();
 
+    /* At exit, do this before vfs_shut():
+       normally, temporary directory should be empty */
+    vfs_expire (TRUE);
+    (void) my_rmdir (tmpdir);
+
     /* Virtual File System shutdown */
     vfs_shut ();