Use g_file_open_tmp within create_tempfile

Much better to use a known library than create it ourselves.

Also remove get_tempfile_path as it's not used.

Bug: 15992
Change-Id: I17b9bd879e8bdb540f79db83c6c138f8ee724764
Reviewed-on: https://code.wireshark.org/review/34420
Reviewed-by: Tomasz Moń <desowin@gmail.com>
Petri-Dish: Tomasz Moń <desowin@gmail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Roland Knall <rknall@gmail.com>
This commit is contained in:
Michael Mann 2019-09-01 14:37:38 -04:00 committed by Roland Knall
parent c247a8351f
commit 2925fb0850
10 changed files with 61 additions and 201 deletions

View File

@ -94,7 +94,6 @@ libwsutil.so.0 libwsutil0 #MINVER#
get_progfile_dir@Base 1.12.0~rc1
get_resource_usage@Base 2.3.0
get_systemfile_dir@Base 1.12.0~rc1
get_tempfile_path@Base 1.12.0~rc1
has_global_profiles@Base 1.12.0~rc1
hkdf_expand@Base 2.5.1
ieee80211_chan_to_mhz@Base 1.99.7

View File

@ -3428,10 +3428,10 @@ static gboolean
capture_loop_open_output(capture_options *capture_opts, int *save_file_fd,
char *errmsg, int errmsg_len)
{
char *tmpname;
gchar *capfile_name;
gchar *prefix, *suffix;
gboolean is_tempfile;
GError *err_tempfile = NULL;
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "capture_loop_open_output: %s",
(capture_opts->save_file) ? capture_opts->save_file : "(not specified)");
@ -3556,9 +3556,8 @@ capture_loop_open_output(capture_options *capture_opts, int *save_file_fd,
} else {
suffix = ".pcap";
}
*save_file_fd = create_tempfile(&tmpname, prefix, suffix);
*save_file_fd = create_tempfile(&capfile_name, prefix, suffix, &err_tempfile);
g_free(prefix);
capfile_name = g_strdup(tmpname);
is_tempfile = TRUE;
}
@ -3567,7 +3566,8 @@ capture_loop_open_output(capture_options *capture_opts, int *save_file_fd,
if (is_tempfile) {
g_snprintf(errmsg, errmsg_len,
"The temporary file to which the capture would be saved (\"%s\") "
"could not be opened: %s.", capfile_name, g_strerror(errno));
"could not be opened: %s.", capfile_name, err_tempfile->message);
g_error_free(err_tempfile);
} else {
if (capture_opts->multi_files_on) {
/* Ensures that the ringbuffer is not used. This ensures that

View File

@ -1541,7 +1541,7 @@ static gboolean extcap_create_pipe(const gchar *ifname, gchar **fifo, const gcha
int fd = 0;
gchar *pfx = g_strconcat(pipe_prefix, "_", ifname, NULL);
if ((fd = create_tempfile(&temp_name, pfx, NULL)) < 0)
if ((fd = create_tempfile(&temp_name, pfx, NULL, NULL)) < 0)
{
g_free(pfx);
return FALSE;
@ -1560,9 +1560,12 @@ static gboolean extcap_create_pipe(const gchar *ifname, gchar **fifo, const gcha
if (mkfifo(temp_name, 0600) == 0)
{
*fifo = g_strdup(temp_name);
*fifo = temp_name;
}
else
{
g_free(temp_name);
}
return TRUE;
}
#endif

1
file.c
View File

@ -18,7 +18,6 @@
#include <ctype.h>
#include <errno.h>
#include <wsutil/tempfile.h>
#include <wsutil/file_util.h>
#include <wsutil/filesystem.h>
#include <wsutil/json_dumper.h>

View File

@ -34,12 +34,17 @@ static void
exp_pdu_file_open(exp_pdu_t *exp_pdu_tap_data)
{
int import_file_fd;
char *tmpname, *capfile_name, *comment;
char *capfile_name, *comment;
int err;
/* Choose a random name for the temporary import buffer */
import_file_fd = create_tempfile(&tmpname, "Wireshark_PDU_", NULL);
capfile_name = g_strdup(tmpname);
GError *err_tempfile = NULL;
import_file_fd = create_tempfile(&capfile_name, "Wireshark_PDU_", NULL, &err_tempfile);
if (import_file_fd < 0) {
failure_alert_box("Temporary file could not be created: %s", err_tempfile->message);
g_error_free(err_tempfile);
goto end;
}
comment = g_strdup_printf("Dump of PDUs from %s", cfile.filename);
err = exp_pdu_open(exp_pdu_tap_data, import_file_fd, comment);

View File

@ -19,7 +19,6 @@
#include "wsutil/file_util.h"
#include "wsutil/pint.h"
#include "wsutil/str_util.h"
#include "wsutil/tempfile.h"
#include <wsutil/utf8_entities.h>
#include <ui/qt/utils/qt_ui_utils.h>
@ -33,6 +32,7 @@
#include <QMessageBox>
#include <QPushButton>
#include <QUrl>
#include <QTemporaryFile>
static const QString table_name_ = QObject::tr("Endpoint");
EndpointDialog::EndpointDialog(QWidget &parent, CaptureFile &cf, int cli_proto_id, const char *filter) :
@ -200,22 +200,21 @@ QUrl EndpointDialog::createMap(bool json_only)
g_ptr_array_add(hosts_arr, NULL);
hostlist_talker_t **hosts = (hostlist_talker_t **)g_ptr_array_free(hosts_arr, FALSE);
char *map_path = NULL;
int fd = create_tempfile(&map_path, "ipmap", ".html");
FILE *fp = NULL;
if (fd != -1) {
fp = ws_fdopen(fd, "wb");
if (!fp) {
ws_close(fd);
fd = -1;
}
}
if (fd == -1) {
QTemporaryFile tf("ipmapXXXXXX.html");
tf.setAutoRemove(false);
if (!tf.open()) {
QMessageBox::warning(this, tr("Map file error"), tr("Unable to create temporary file"));
g_free(hosts);
return QUrl();
}
QString map_path_str(map_path);
int fd = tf.handle();
FILE* fp = ws_fdopen(fd, "wb");
if (fd == -1) {
QMessageBox::warning(this, tr("Map file error"), tr("Unable to create temporary file"));
g_free(hosts);
tf.remove();
return QUrl();
}
gchar *err_str;
if (!write_endpoint_geoip_map(fp, json_only, hosts, &err_str)) {
@ -223,17 +222,17 @@ QUrl EndpointDialog::createMap(bool json_only)
g_free(err_str);
g_free(hosts);
fclose(fp);
ws_unlink(qPrintable(map_path_str));
tf.remove();
return QUrl();
}
g_free(hosts);
if (fclose(fp) == EOF) {
QMessageBox::warning(this, tr("Map file error"), g_strerror(errno));
ws_unlink(qPrintable(map_path_str));
tf.remove();
return QUrl();
}
return QUrl::fromLocalFile(map_path_str);
return QUrl::fromLocalFile(tf.fileName());
}
void EndpointDialog::openMap()
@ -241,6 +240,9 @@ void EndpointDialog::openMap()
QUrl map_file = createMap(false);
if (!map_file.isEmpty()) {
QDesktopServices::openUrl(map_file);
QString source_file = map_file.toLocalFile();
if (!source_file.isEmpty())
QFile::remove(source_file);
}
}

View File

@ -2422,7 +2422,6 @@ wtap_dump_open_tempfile(char **filenamep, const char *pfx,
int fd;
const char *ext;
char sfx[16];
char *tmpname;
wtap_dumper *wdh;
WFILE_T fh;
@ -2444,13 +2443,12 @@ wtap_dump_open_tempfile(char **filenamep, const char *pfx,
g_strlcat(sfx, ext, 16);
/* Choose a random name for the file */
fd = create_tempfile(&tmpname, pfx, sfx);
fd = create_tempfile(filenamep, pfx, sfx, NULL);
if (fd == -1) {
*err = errno;
*err = WTAP_ERR_CANT_OPEN;
g_free(wdh);
return NULL; /* can't create file */
}
*filenamep = g_strdup(tmpname);
/* In case "fopen()" fails but doesn't set "errno", set "errno"
to a generic "the open failed" error. */
@ -2468,7 +2466,7 @@ wtap_dump_open_tempfile(char **filenamep, const char *pfx,
/* Get rid of the file we created; we couldn't finish
opening it. */
wtap_dump_file_close(wdh);
ws_unlink(tmpname);
ws_unlink(*filenamep);
g_free(wdh);
return NULL;
}

View File

@ -176,7 +176,7 @@ nettrace_close(wtap *wth)
/* delete the temp file */
ws_unlink(file_info->tmpname);
g_free(file_info->tmpname);
}
/* This attribute specification contains a timestamp that refers to the start of the
@ -813,7 +813,7 @@ create_temp_pcapng_file(wtap *wth, int *err, gchar **err_info, nettrace_3gpp_32_
wtap_open_return_val result = WTAP_OPEN_MINE;
/* pcapng defs */
GArray *shb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));
GArray *shb_hdrs;
wtap_block_t shb_hdr;
wtapng_iface_descriptions_t *idb_inf = NULL;
wtap_block_t int_data;
@ -839,10 +839,13 @@ create_temp_pcapng_file(wtap *wth, int *err, gchar **err_info, nettrace_3gpp_32_
memset(&exported_pdu_info, 0x0, sizeof(exported_pdu_info_t));
import_file_fd = create_tempfile(&(file_info->tmpname), "Wireshark_PDU_", NULL);
import_file_fd = create_tempfile(&(file_info->tmpname), "Wireshark_PDU_", NULL, NULL);
if (import_file_fd < 0)
return WTAP_OPEN_ERROR;
/* Now open a file and dump to it */
/* Create data for SHB */
shb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));
os_info_str = g_string_new("");
get_os_version_info(os_info_str);

View File

@ -10,171 +10,31 @@
#include "config.h"
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#ifdef _WIN32
#include <windows.h>
#include <process.h> /* For getpid() */
#endif
#include <glib.h>
#include "tempfile.h"
#include <wsutil/file_util.h>
#ifndef __set_errno
#define __set_errno(x) errno=(x)
#endif
#define INITIAL_PATH_SIZE 128
#define TMP_FILE_SUFFIX "XXXXXX"
#ifndef HAVE_MKSTEMPS
/* Generate a unique temporary file name from TEMPLATE.
The last six characters before the suffix length of TEMPLATE
must be TMP_FILE_SUFFIX; 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
mkstemps(char *path_template, int suffixlen)
{
static const char letters[]
= "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
char uniqueness[6];
size_t len;
size_t i;
len = strlen (path_template);
if (len < 6 || strncmp (&path_template[len - 6 - suffixlen], TMP_FILE_SUFFIX, 6))
{
__set_errno (EINVAL);
return -1;
}
if (g_snprintf (uniqueness, 6, "%.5u",
(unsigned int) ws_getpid () % 100000) != 5)
/* Inconceivable lossage. */
return -1;
memcpy(&path_template[len - 5 - suffixlen], uniqueness, 5);
for (i = 0; i < sizeof (letters); ++i)
{
int fd;
path_template[len - 6 - suffixlen] = letters[i];
fd = ws_open (path_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. */
path_template[0] = '\0';
return -1;
}
#endif /* HAVE_MKSTEMPS */
/*
* Construct and return the path name of a file in the
* appropriate temporary file directory.
*/
char *get_tempfile_path(const char *filename)
{
return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", g_get_tmp_dir(), filename);
}
#define MAX_TEMPFILES 3
/**
* Create a tempfile with the given prefix (e.g. "wireshark").
/**
* Create a tempfile with the given prefix (e.g. "wireshark"). The path
* is created using g_file_open_tmp.
*
* @param namebuf If not NULL, receives the full path of the temp file.
* Should NOT be freed.
* @param pfx A prefix for the temporary 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.
* @param sfx [in] A file extension for the temporary file. NULL can be passed
* if no file extension is needed
* @param sfx [out] Any error returned by g_file_open_tmp. May be NULL.
* @return The file descriptor of the new tempfile, from mkstemps().
*/
int
create_tempfile(char **namebuf, const char *pfx, const char *sfx)
create_tempfile(gchar **namebuf, const char *pfx, const char *sfx, GError **err)
{
static struct _tf {
char *path;
size_t len;
} tf[MAX_TEMPFILES];
static int idx;
const char *tmp_dir;
int old_umask;
int fd;
time_t current_time;
struct tm *tm;
char timestr[14 + 1];
gchar *tmp_file;
size_t tmp_file_strsize;
gchar *safe_pfx;
gchar sep[2] = {0, 0};
/* The characters in "delimiters" come from:
* https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions.
* Add to the list as necessary for other OS's.
*/
const gchar *delimiters = "<>:\"/\\|?*"
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a"
"\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
"\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f";
gchar* filetmpl = g_strdup_printf("%sXXXXXX%s", pfx ? pfx : "", sfx ? sfx : "");
/* Sanitize the pfx to resolve bug 7877 */
safe_pfx = g_strdup(pfx);
safe_pfx = g_strdelimit(safe_pfx, delimiters, '-');
fd = g_file_open_tmp(filetmpl, namebuf, err);
idx = (idx + 1) % MAX_TEMPFILES;
/*
* Allocate the buffer if it's not already allocated.
*/
if (tf[idx].path == NULL) {
tf[idx].len = INITIAL_PATH_SIZE;
tf[idx].path = (char *)g_malloc(tf[idx].len);
}
tmp_dir = g_get_tmp_dir();
#ifdef _WIN32
_tzset();
#endif
current_time = time(NULL);
tm = localtime(&current_time);
if (tm != NULL)
strftime(timestr, sizeof(timestr), "%Y%m%d%H%M%S", tm);
else
g_strlcpy(timestr, "196912312359", sizeof(timestr)); /* second before the Epoch */
sep[0] = G_DIR_SEPARATOR;
tmp_file = g_strconcat(tmp_dir, sep, safe_pfx, "_", timestr, "_", TMP_FILE_SUFFIX, sfx, NULL);
g_free(safe_pfx);
tmp_file_strsize = strlen(tmp_file) + 1;
if (tmp_file_strsize > tf[idx].len) {
tf[idx].len = tmp_file_strsize;
tf[idx].path = (char *)g_realloc(tf[idx].path, tf[idx].len);
}
g_strlcpy(tf[idx].path, tmp_file, tf[idx].len);
g_free(tmp_file);
if (namebuf) {
*namebuf = tf[idx].path;
}
/* The Single UNIX Specification doesn't say that "mkstemps()"
creates the temporary file with mode rw-------, so we
won't assume that all UNIXes will do so; instead, we set
the umask to 0077 to take away all group and other
permissions, attempt to create the file, and then put
the umask back. */
old_umask = ws_umask(0077);
fd = mkstemps(tf[idx].path, sfx ? (int) strlen(sfx) : 0);
ws_umask(old_umask);
g_free(filetmpl);
return fd;
}

View File

@ -21,28 +21,19 @@ extern "C" {
* Convenience function for temporary file creation.
*/
/**
* Construct the path name of a file in the appropriate temporary
* file directory.
*
* @param filename the file name to be given to the file.
* @return the pathname of the file, g_malloced so the caller
* should g_free it.
*/
WS_DLL_PUBLIC char *get_tempfile_path(const char *filename);
/**
* Create a tempfile with the given prefix (e.g. "wireshark"). The path
* is created using g_get_tmp_dir and mkstemp.
* is created using g_file_open_tmp.
*
* @param namebuf [in,out] If not NULL, receives the full path of the temp file.
* Must NOT be freed.
* Must be freed.
* @param pfx [in] A prefix for the temporary file.
* @param sfx [in] A file extension for the temporary file. NULL can be passed
* if no file extension is needed
* @param sfx [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(char **namebuf, const char *pfx, const char *sfx);
WS_DLL_PUBLIC int create_tempfile(gchar **namebuf, const char *pfx, const char *sfx, GError **err);
#ifdef __cplusplus
}