mirror of
https://github.com/MidnightCommander/mc
synced 2025-01-03 18:14:25 +03:00
Moved functions mc_mkstemp() and mc_tempdir() to VFS module.
Signed-off-by: Slava Zanko <slavazanko@gmail.com>
This commit is contained in:
parent
4945d0f9a6
commit
53c500f58c
84
lib/util.c
84
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;
|
||||
@ -1181,88 +1181,6 @@ list_append_unique (GList * list, char *text)
|
||||
return list;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* 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.
|
||||
|
@ -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
|
||||
|
110
lib/utilunix.c
110
lib/utilunix.c
@ -324,116 +324,6 @@ tilde_expand (const char *directory)
|
||||
return g_strconcat (passwd->pw_dir, PATH_SEP_STR, q, (char *) NULL);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* 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;
|
||||
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.
|
||||
|
@ -45,11 +45,14 @@
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
|
||||
#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;
|
||||
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;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -301,6 +301,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 ****************************************************************************/
|
||||
|
Loading…
Reference in New Issue
Block a user