2 * Routines to create temporary files
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * SPDX-License-Identifier: GPL-2.0-or-later
16 #include "file_util.h"
19 sanitize_prefix(const char *prefix
)
25 /* The characters in "delimiters" come from:
26 * https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions.
27 * Add to the list as necessary for other OS's.
29 const char *delimiters
= "<>:\"/\\|?*"
30 "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a"
31 "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
32 "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f";
34 /* Sanitize the prefix to resolve bug 7877 */
35 char *safe_prefx
= g_strdup(prefix
);
36 safe_prefx
= g_strdelimit(safe_prefx
, delimiters
, '-');
41 * Create a tempfile with the given prefix (e.g. "wireshark"). The path
42 * is created using g_file_open_tmp.
44 * @param tempdir [in] If not NULL, the directory in which to create the file.
45 * @param namebuf [in,out] If not NULL, receives the full path of the temp file.
47 * @param pfx [in] A prefix for the temporary file.
48 * @param sfx [in] A file extension for the temporary file. NULL can be passed
49 * if no file extension is needed
50 * @param err [out] Any error returned by g_file_open_tmp. May be NULL
51 * @return The file descriptor of the new tempfile, from mkstemps().
54 create_tempfile(const char *tempdir
, char **namebuf
, const char *pfx
, const char *sfx
, GError
**err
)
57 char *safe_pfx
= sanitize_prefix(pfx
);
59 if (tempdir
== NULL
|| tempdir
[0] == '\0') {
60 /* Use OS default tempdir behaviour */
61 char* filetmpl
= ws_strdup_printf("%sXXXXXX%s", safe_pfx
? safe_pfx
: "", sfx
? sfx
: "");
64 fd
= g_file_open_tmp(filetmpl
, namebuf
, err
);
68 /* User-specified tempdir.
69 * We don't get libc's help generating a random name here.
71 const char alphabet
[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
72 const int32_t a_len
= 64;
73 char* filetmpl
= NULL
;
77 filetmpl
= ws_strdup_printf("%s%c%s%c%c%c%c%c%c%s",
80 safe_pfx
? safe_pfx
: "",
81 alphabet
[g_random_int_range(0, a_len
)],
82 alphabet
[g_random_int_range(0, a_len
)],
83 alphabet
[g_random_int_range(0, a_len
)],
84 alphabet
[g_random_int_range(0, a_len
)],
85 alphabet
[g_random_int_range(0, a_len
)],
86 alphabet
[g_random_int_range(0, a_len
)],
89 fd
= ws_open(filetmpl
, O_CREAT
|O_EXCL
|O_BINARY
|O_WRONLY
, 0600);
93 if (errno
!= EEXIST
) {
94 g_set_error_literal(err
, G_FILE_ERROR
,
95 g_file_error_from_errno(errno
), g_strerror(errno
));
100 /* Loop continues if error was EEXIST, meaning the file we tried
101 * to make already existed at the destination
105 if (namebuf
== NULL
) {
118 create_tempdir(const char *parent_dir
, const char *tmpl
, GError
**err
)
120 if (parent_dir
== NULL
|| parent_dir
[0] == '\0') {
121 parent_dir
= g_get_tmp_dir();
124 char *safe_pfx
= sanitize_prefix(tmpl
);
125 if (safe_pfx
== NULL
) {
126 safe_pfx
= g_strdup("wireshark_XXXXXX");
129 char *temp_subdir
= g_build_path(G_DIR_SEPARATOR_S
, parent_dir
, safe_pfx
, NULL
);
131 if (g_mkdtemp(temp_subdir
) == NULL
)
134 g_set_error_literal(err
, G_FILE_ERROR
,
135 g_file_error_from_errno(errno
), g_strerror(errno
));
143 * Editor modelines - https://www.wireshark.org/tools/modelines.html
148 * indent-tabs-mode: nil
151 * ex: set shiftwidth=2 tabstop=8 expandtab:
152 * :indentSize=2:tabSize=8:noTabs=true: