From eb5543f02f1bde05692c3be3c34b156390725e8c Mon Sep 17 00:00:00 2001 From: Slava Zanko Date: Wed, 4 Jan 2012 11:44:35 +0300 Subject: [PATCH] Moved functions mc_mkstemp() and mc_tempdir() to VFS module. Signed-off-by: Slava Zanko --- lib/util.c | 84 +--------------------- lib/util.h | 4 -- lib/utilunix.c | 110 ----------------------------- lib/vfs/interface.c | 195 ++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/vfs/vfs.h | 4 ++ 5 files changed, 200 insertions(+), 197 deletions(-) diff --git a/lib/util.c b/lib/util.c index 45ffcb840..23b5a8527 100644 --- a/lib/util.c +++ b/lib/util.c @@ -181,7 +181,7 @@ resolve_symlinks (const char *path) else if (*(r - 1) == PATH_SEP && r != buf + 1) *(r - 1) = 0; - ret: + ret: g_free (buf2); vfs_path_free (vpath); return buf; @@ -1182,88 +1182,6 @@ list_append_unique (GList * list, char *text) } /* --------------------------------------------------------------------------------------------- */ -/* Following code heavily borrows from libiberty, mkstemps.c */ -/* - * Arguments: - * pname (output) - pointer to the name of the temp file (needs g_free). - * NULL if the function fails. - * prefix - part of the filename before the random part. - * Prepend $TMPDIR or /tmp if there are no path separators. - * suffix - if not NULL, part of the filename after the random part. - * - * Result: - * handle of the open file or -1 if couldn't open any. - */ - -int -mc_mkstemps (char **pname, const char *prefix, const char *suffix) -{ - static const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - static unsigned long value; - struct timeval tv; - char *tmpbase; - char *tmpname; - char *XXXXXX; - int count; - - if (strchr (prefix, PATH_SEP) == NULL) - { - /* Add prefix first to find the position of XXXXXX */ - tmpbase = concat_dir_and_file (mc_tmpdir (), prefix); - } - else - { - tmpbase = g_strdup (prefix); - } - - tmpname = g_strconcat (tmpbase, "XXXXXX", suffix, (char *) NULL); - *pname = tmpname; - XXXXXX = &tmpname[strlen (tmpbase)]; - g_free (tmpbase); - - /* Get some more or less random data. */ - gettimeofday (&tv, NULL); - value += (tv.tv_usec << 16) ^ tv.tv_sec ^ getpid (); - - for (count = 0; count < TMP_MAX; ++count) - { - unsigned long v = value; - int fd; - - /* Fill in the random bits. */ - XXXXXX[0] = letters[v % 62]; - v /= 62; - XXXXXX[1] = letters[v % 62]; - v /= 62; - XXXXXX[2] = letters[v % 62]; - v /= 62; - XXXXXX[3] = letters[v % 62]; - v /= 62; - XXXXXX[4] = letters[v % 62]; - v /= 62; - XXXXXX[5] = letters[v % 62]; - - fd = open (tmpname, O_RDWR | O_CREAT | O_TRUNC | O_EXCL, S_IRUSR | S_IWUSR); - if (fd >= 0) - { - /* Successfully created. */ - return fd; - } - - /* This is a random value. It is only necessary that the next - TMP_MAX values generated by adding 7777 to VALUE are different - with (module 2^32). */ - value += 7777; - } - - /* Unsuccessful. Free the filename. */ - g_free (tmpname); - *pname = NULL; - - return -1; -} - -/* --------------------------------------------------------------------------------------------- */ /** * Read and restore position for the given filename. * If there is no stored data, return line 1 and col 0. diff --git a/lib/util.h b/lib/util.h index 4fc1824b8..077c361ee 100644 --- a/lib/util.h +++ b/lib/util.h @@ -166,10 +166,6 @@ void canonicalize_pathname (char *); int my_mkdir (const char *s, mode_t mode); int my_rmdir (const char *s); -/* Creating temporary files safely */ -const char *mc_tmpdir (void); -int mc_mkstemps (char **pname, const char *prefix, const char *suffix); - #ifdef HAVE_REALPATH #define mc_realpath realpath #else diff --git a/lib/utilunix.c b/lib/utilunix.c index 5913c44d6..0ea2eb57f 100644 --- a/lib/utilunix.c +++ b/lib/utilunix.c @@ -328,116 +328,6 @@ tilde_expand (const char *directory) /* --------------------------------------------------------------------------------------------- */ /** - * Return the directory where mc should keep its temporary files. - * This directory is (in Bourne shell terms) "${TMPDIR=/tmp}/mc-$USER" - * 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. - */ - -const char * -mc_tmpdir (void) -{ - static char buffer[64]; - 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 && lstat (tmpdir, &st) == 0 && S_ISDIR (st.st_mode) && - st.st_uid == getuid () && (st.st_mode & 0777) == 0700) - return tmpdir; - - sys_tmp = getenv ("TMPDIR"); - if (!sys_tmp || sys_tmp[0] != '/') - { - sys_tmp = TMPDIR_DEFAULT; - } - - pwd = getpwuid (getuid ()); - - if (pwd) - g_snprintf (buffer, sizeof (buffer), "%s/mc-%s", sys_tmp, pwd->pw_name); - else - g_snprintf (buffer, sizeof (buffer), "%s/mc-%lu", sys_tmp, (unsigned long) getuid ()); - - canonicalize_pathname (buffer); - - if (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 - { - /* Need to create directory */ - if (mkdir (buffer, S_IRWXU) != 0) - { - fprintf (stderr, - _("Cannot create temporary directory %s: %s\n"), - buffer, unix_error_string (errno)); - error = ""; - } - } - - if (error != NULL) - { - int test_fd; - char *test_fn, *fallback_prefix; - int fallback_ok = 0; - - if (*error) - 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_fn, fallback_prefix, NULL); - g_free (fallback_prefix); - if (test_fd != -1) - { - close (test_fd); - test_fd = open (test_fn, O_RDONLY); - if (test_fd != -1) - { - close (test_fd); - unlink (test_fn); - fallback_ok = 1; - } - } - - 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/"); - } - - fprintf (stderr, "%s\n", _("Press any key to continue...")); - getc (stdin); - } - - tmpdir = buffer; - - if (!error) - g_setenv ("MC_TMPDIR", tmpdir, TRUE); - - return tmpdir; -} - -/* --------------------------------------------------------------------------------------------- */ -/** * Creates a pipe to hold standard error for a later analysis. * The pipe can hold 4096 bytes. Make sure no more is written * or a deadlock might occur. diff --git a/lib/vfs/interface.c b/lib/vfs/interface.c index bd50f282d..f3e634541 100644 --- a/lib/vfs/interface.c +++ b/lib/vfs/interface.c @@ -45,11 +45,14 @@ #include #include #include +#include +#include #include "lib/global.h" #include "lib/widget.h" /* message() */ #include "lib/strutil.h" /* str_crt_conv_from() */ +#include "lib/util.h" #include "vfs.h" #include "utilvfs.h" @@ -746,3 +749,195 @@ mc_lseek (int fd, off_t offset, int whence) } /* --------------------------------------------------------------------------------------------- */ +/* Following code heavily borrows from libiberty, mkstemps.c */ +/* + * Arguments: + * pname (output) - pointer to the name of the temp file (needs g_free). + * NULL if the function fails. + * prefix - part of the filename before the random part. + * Prepend $TMPDIR or /tmp if there are no path separators. + * suffix - if not NULL, part of the filename after the random part. + * + * Result: + * handle of the open file or -1 if couldn't open any. + */ + +int +mc_mkstemps (char **pname, const char *prefix, const char *suffix) +{ + static const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + static unsigned long value; + struct timeval tv; + char *tmpbase; + char *tmpname; + char *XXXXXX; + int count; + + if (strchr (prefix, PATH_SEP) == NULL) + { + /* Add prefix first to find the position of XXXXXX */ + tmpbase = g_build_filename (mc_tmpdir (), prefix, NULL); + } + else + { + tmpbase = g_strdup (prefix); + } + + tmpname = g_strconcat (tmpbase, "XXXXXX", suffix, (char *) NULL); + *pname = tmpname; + XXXXXX = &tmpname[strlen (tmpbase)]; + g_free (tmpbase); + + /* Get some more or less random data. */ + gettimeofday (&tv, NULL); + value += (tv.tv_usec << 16) ^ tv.tv_sec ^ getpid (); + + for (count = 0; count < TMP_MAX; ++count) + { + unsigned long v = value; + int fd; + + /* Fill in the random bits. */ + XXXXXX[0] = letters[v % 62]; + v /= 62; + XXXXXX[1] = letters[v % 62]; + v /= 62; + XXXXXX[2] = letters[v % 62]; + v /= 62; + XXXXXX[3] = letters[v % 62]; + v /= 62; + XXXXXX[4] = letters[v % 62]; + v /= 62; + XXXXXX[5] = letters[v % 62]; + + fd = open (tmpname, O_RDWR | O_CREAT | O_TRUNC | O_EXCL, S_IRUSR | S_IWUSR); + if (fd >= 0) + { + /* Successfully created. */ + return fd; + } + + /* This is a random value. It is only necessary that the next + TMP_MAX values generated by adding 7777 to VALUE are different + with (module 2^32). */ + value += 7777; + } + + /* Unsuccessful. Free the filename. */ + g_free (tmpname); + *pname = NULL; + + return -1; +} + +/* --------------------------------------------------------------------------------------------- */ +/** + * Return the directory where mc should keep its temporary files. + * This directory is (in Bourne shell terms) "${TMPDIR=/tmp}/mc-$USER" + * 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. + */ + +const char * +mc_tmpdir (void) +{ + static char buffer[64]; + 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 && lstat (tmpdir, &st) == 0 && S_ISDIR (st.st_mode) && + st.st_uid == getuid () && (st.st_mode & 0777) == 0700) + return tmpdir; + + sys_tmp = getenv ("TMPDIR"); + if (!sys_tmp || sys_tmp[0] != '/') + { + sys_tmp = TMPDIR_DEFAULT; + } + + pwd = getpwuid (getuid ()); + + if (pwd) + g_snprintf (buffer, sizeof (buffer), "%s/mc-%s", sys_tmp, pwd->pw_name); + else + g_snprintf (buffer, sizeof (buffer), "%s/mc-%lu", sys_tmp, (unsigned long) getuid ()); + + canonicalize_pathname (buffer); + + if (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 + { + /* Need to create directory */ + if (mkdir (buffer, S_IRWXU) != 0) + { + fprintf (stderr, + _("Cannot create temporary directory %s: %s\n"), + buffer, unix_error_string (errno)); + error = ""; + } + } + + if (error != NULL) + { + int test_fd; + char *test_fn, *fallback_prefix; + int fallback_ok = 0; + + if (*error) + 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_fn, fallback_prefix, NULL); + g_free (fallback_prefix); + if (test_fd != -1) + { + close (test_fd); + test_fd = open (test_fn, O_RDONLY); + if (test_fd != -1) + { + close (test_fd); + unlink (test_fn); + fallback_ok = 1; + } + } + + 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/"); + } + + fprintf (stderr, "%s\n", _("Press any key to continue...")); + getc (stdin); + } + + tmpdir = buffer; + + if (!error) + g_setenv ("MC_TMPDIR", tmpdir, TRUE); + + return tmpdir; +} + +/* --------------------------------------------------------------------------------------------- */ diff --git a/lib/vfs/vfs.h b/lib/vfs/vfs.h index a17313ba6..0b592b018 100644 --- a/lib/vfs/vfs.h +++ b/lib/vfs/vfs.h @@ -303,6 +303,10 @@ int mc_open (const vfs_path_t * vpath, int flags, ...); char *mc_get_current_wd (char *buffer, size_t bufsize); char *mc_getlocalcopy (const char *pathname); int mc_ungetlocalcopy (const char *pathname, const char *local, int has_changed); +int mc_mkstemps (char **pname, const char *prefix, const char *suffix); + +/* Creating temporary files safely */ +const char *mc_tmpdir (void); /*** inline functions ****************************************************************************/ -- 2.11.4.GIT