aboutsummaryrefslogtreecommitdiffstats
path: root/wsutil
diff options
context:
space:
mode:
authorDavid Perry <boolean263@protonmail.com>2022-02-09 14:32:28 +0000
committerA Wireshark GitLab Utility <6629907-ws-gitlab-utility@users.noreply.gitlab.com>2022-02-09 14:32:28 +0000
commit1e0d117eb7ab1ce7f4ff8a4fd6dc2529634d7baa (patch)
treee7670b02e6c4d49e4f321864e730e0e48433b151 /wsutil
parentf72787e86ff78790559fd5550e98865e225bfb68 (diff)
Specify directory for temporary captures
Diffstat (limited to 'wsutil')
-rw-r--r--wsutil/tempfile.c64
-rw-r--r--wsutil/tempfile.h3
2 files changed, 61 insertions, 6 deletions
diff --git a/wsutil/tempfile.c b/wsutil/tempfile.c
index a4d1ad5181..f93f96d538 100644
--- a/wsutil/tempfile.c
+++ b/wsutil/tempfile.c
@@ -9,12 +9,17 @@
*/
#include "config.h"
+
+#include <errno.h>
+
#include "tempfile.h"
+#include "file_util.h"
/**
* Create a tempfile with the given prefix (e.g. "wireshark"). The path
* is created using g_file_open_tmp.
*
+ * @param tempdir [in] If not NULL, the directory in which to create the file.
* @param namebuf [in,out] If not NULL, receives the full path of the temp file.
* Must be freed.
* @param pfx [in] A prefix for the temporary file.
@@ -24,7 +29,7 @@
* @return The file descriptor of the new tempfile, from mkstemps().
*/
int
-create_tempfile(gchar **namebuf, const char *pfx, const char *sfx, GError **err)
+create_tempfile(const char *tempdir, gchar **namebuf, const char *pfx, const char *sfx, GError **err)
{
int fd;
gchar *safe_pfx = NULL;
@@ -44,12 +49,61 @@ create_tempfile(gchar **namebuf, const char *pfx, const char *sfx, GError **err)
safe_pfx = g_strdelimit(safe_pfx, delimiters, '-');
}
- gchar* filetmpl = ws_strdup_printf("%sXXXXXX%s", safe_pfx ? safe_pfx : "", sfx ? sfx : "");
- g_free(safe_pfx);
+ if (tempdir == NULL || tempdir[0] == '\0') {
+ /* Use OS default tempdir behaviour */
+ gchar* filetmpl = ws_strdup_printf("%sXXXXXX%s", safe_pfx ? safe_pfx : "", sfx ? sfx : "");
+ g_free(safe_pfx);
+
+ fd = g_file_open_tmp(filetmpl, namebuf, err);
+ g_free(filetmpl);
+ }
+ else {
+ /* User-specified tempdir.
+ * We don't get libc's help generating a random name here.
+ */
+ const gchar alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
+ const gint32 a_len = 64;
+ gchar* filetmpl = NULL;
+
+ while(1) {
+ g_free(filetmpl);
+ filetmpl = ws_strdup_printf("%s%c%s%c%c%c%c%c%c%s",
+ tempdir,
+ G_DIR_SEPARATOR,
+ safe_pfx ? safe_pfx : "",
+ alphabet[g_random_int_range(0, a_len)],
+ alphabet[g_random_int_range(0, a_len)],
+ alphabet[g_random_int_range(0, a_len)],
+ alphabet[g_random_int_range(0, a_len)],
+ alphabet[g_random_int_range(0, a_len)],
+ alphabet[g_random_int_range(0, a_len)],
+ sfx ? sfx : "");
- fd = g_file_open_tmp(filetmpl, namebuf, err);
+ fd = ws_open(filetmpl, O_CREAT|O_EXCL|O_BINARY|O_WRONLY, 0600);
+ if (fd >= 0) {
+ break;
+ }
+ if (errno != EEXIST) {
+ g_set_error_literal(err, G_FILE_ERROR,
+ g_file_error_from_errno(errno), g_strerror(errno));
+ g_free(filetmpl);
+ filetmpl = NULL;
+ break;
+ }
+ /* Loop continues if error was EEXIST, meaning the file we tried
+ * to make already existed at the destination
+ */
+ }
+
+ if (namebuf == NULL) {
+ g_free(filetmpl);
+ }
+ else {
+ *namebuf = filetmpl;
+ }
+ g_free(safe_pfx);
+ }
- g_free(filetmpl);
return fd;
}
diff --git a/wsutil/tempfile.h b/wsutil/tempfile.h
index 49e344840a..70031b5419 100644
--- a/wsutil/tempfile.h
+++ b/wsutil/tempfile.h
@@ -25,6 +25,7 @@ extern "C" {
* Create a tempfile with the given prefix (e.g. "wireshark"). The path
* is created using g_file_open_tmp.
*
+ * @param tempdir [in] If not NULL, the directory in which to create the file.
* @param namebuf [in,out] If not NULL, receives the full path of the temp file.
* Must be freed.
* @param pfx [in] A prefix for the temporary file.
@@ -33,7 +34,7 @@ extern "C" {
* @param err [out] Any error returned by g_file_open_tmp. May be NULL.
* @return The file descriptor of the new tempfile, from mkstemps().
*/
-WS_DLL_PUBLIC int create_tempfile(gchar **namebuf, const char *pfx, const char *sfx, GError **err);
+WS_DLL_PUBLIC int create_tempfile(const gchar *tempdir, gchar **namebuf, const char *pfx, const char *sfx, GError **err);
#ifdef __cplusplus
}