diff options
Diffstat (limited to 'tempfile.c')
-rw-r--r-- | tempfile.c | 146 |
1 files changed, 145 insertions, 1 deletions
diff --git a/tempfile.c b/tempfile.c index 7b3ede6917..1a292b5fc7 100644 --- a/tempfile.c +++ b/tempfile.c @@ -33,6 +33,10 @@ #include <stdio.h> #include <errno.h> +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif + #ifdef HAVE_UNISTD_H #include <unistd.h> #endif @@ -41,10 +45,108 @@ #include <windows.h> #endif +#ifdef _WIN32 +#include <process.h> /* For getpid() */ +#endif + #include "tempfile.h" -#include "mkstemp.h" #include <wsutil/file_util.h> +#ifndef __set_errno +#define __set_errno(x) errno=(x) +#endif + +#ifndef HAVE_MKSTEMP +/* Generate a unique temporary file name from TEMPLATE. + The last six characters of TEMPLATE must be "XXXXXX"; + they are replaced with a string that makes the filename unique. + Returns a file descriptor open on the file for reading and writing. */ +static int +mkstemp (template) + char *template; +{ + static const char letters[] + = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + size_t len; + size_t i; + + len = strlen (template); + if (len < 6 || strcmp (&template[len - 6], "XXXXXX")) + { + __set_errno (EINVAL); + return -1; + } + + if (g_snprintf (&template[len - 5], 6, "%.5u", + (unsigned int) getpid () % 100000) != 5) + /* Inconceivable lossage. */ + return -1; + + for (i = 0; i < sizeof (letters); ++i) + { + int fd; + + template[len - 6] = letters[i]; + + fd = ws_open (template, O_RDWR|O_BINARY|O_CREAT|O_EXCL, 0600); + if (fd >= 0) + return fd; + } + + /* We return the null string if we can't find a unique file name. */ + + template[0] = '\0'; + return -1; +} + +#endif /* HAVE_MKSTEMP */ + +#ifndef HAVE_MKDTEMP +/* Generate a unique temporary directory name from TEMPLATE. + The last six characters of TEMPLATE must be "XXXXXX"; + they are replaced with a string that makes the filename unique. + Returns 0 on success or -1 on error (from mkdir(2)). */ +char * +mkdtemp (template) + char *template; +{ + static const char letters[] + = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + size_t len; + size_t i; + + len = strlen (template); + if (len < 6 || strcmp (&template[len - 6], "XXXXXX")) + { + __set_errno (EINVAL); + return NULL; + } + + if (g_snprintf (&template[len - 5], 6, "%.5u", + (unsigned int) getpid () % 100000) != 5) + /* Inconceivable lossage. */ + return NULL; + + for (i = 0; i < sizeof (letters); ++i) + { + int ret; + + template[len - 6] = letters[i]; + + ret = ws_mkdir(template, 0700); + if (ret >= 0) + return template; + } + + /* We return the null string if we can't find a unique file name. */ + + template[0] = '\0'; + return NULL; +} + +#endif /* HAVE_MKDTEMP */ + + #define INITIAL_PATH_SIZE 128 #define TMP_FILE_SUFFIX "XXXXXXXXXX" @@ -100,3 +202,45 @@ create_tempfile(char **namebuf, const char *pfx) umask(old_umask); return fd; } + +/** + * Create a directory with the given prefix (e.g. "wireshark"). The path + * is created using g_get_tmp_dir and mkdtemp. + * + * @param pfx A prefix for the temporary directory. + * @return The temporary directory path on success, or NULL on failure. + * Must NOT be freed. + */ +const char * +create_tempdir(char **namebuf, const char *pfx) +{ + static char *td_path[3]; + static int td_path_len[3]; + static int idx; + const char *tmp_dir; + + idx = (idx + 1) % 3; + + /* + * Allocate the buffer if it's not already allocated. + */ + if (td_path[idx] == NULL) { + td_path_len[idx] = INITIAL_PATH_SIZE; + td_path[idx] = g_malloc(td_path_len[idx]); + } + + /* + * We can't use get_tempfile_path here because we're called from dumpcap.c. + */ + tmp_dir = g_get_tmp_dir(); + + while (g_snprintf(td_path[idx], td_path_len[idx], "%s%c%s" TMP_FILE_SUFFIX, tmp_dir, G_DIR_SEPARATOR, pfx) > td_path_len[idx]) { + td_path_len[idx] *= 2; + td_path[idx] = g_realloc(td_path[idx], td_path_len[idx]); + } + + if (namebuf) { + *namebuf = td_path[idx]; + } + return mkdtemp(td_path[idx]); +} |