Specify directory for temporary captures

This commit is contained in:
David Perry 2022-02-09 14:32:28 +00:00 committed by A Wireshark GitLab Utility
parent f72787e86f
commit 1e0d117eb7
27 changed files with 237 additions and 33 deletions

View File

@ -266,6 +266,11 @@ sync_pipe_start(capture_options *capture_opts, GPtrArray *capture_comments,
}
}
if (capture_opts->temp_dir) {
argv = sync_pipe_add_arg(argv, &argc, "--temp-dir");
argv = sync_pipe_add_arg(argv, &argc, capture_opts->temp_dir);
}
if (capture_opts->multi_files_on) {
if (capture_opts->has_autostop_filesize) {
char sfilesize[ARGV_NUMBER_LEN];

View File

@ -13,6 +13,10 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#ifdef HAVE_LIBPCAP
#include <string.h>
@ -121,6 +125,7 @@ capture_opts_init(capture_options *capture_opts)
capture_opts->capture_child = FALSE;
capture_opts->print_file_names = FALSE;
capture_opts->print_name_to = NULL;
capture_opts->temp_dir = NULL;
capture_opts->compress_type = NULL;
}
@ -147,6 +152,7 @@ capture_opts_cleanup(capture_options *capture_opts)
capture_opts->all_ifaces = NULL;
}
g_free(capture_opts->save_file);
g_free(capture_opts->temp_dir);
}
/* log content of capture_opts */
@ -261,6 +267,7 @@ capture_opts_log(const char *log_domain, enum ws_log_level log_level, capture_op
ws_log(log_domain, log_level, "AutostopPackets (%u) : %u", capture_opts->has_autostop_packets, capture_opts->autostop_packets);
ws_log(log_domain, log_level, "AutostopFilesize(%u) : %u (KB)", capture_opts->has_autostop_filesize, capture_opts->autostop_filesize);
ws_log(log_domain, log_level, "AutostopDuration(%u) : %.3f", capture_opts->has_autostop_duration, capture_opts->autostop_duration);
ws_log(log_domain, log_level, "Temporary Directory : %s", capture_opts->temp_dir && capture_opts->temp_dir[0] ? capture_opts->temp_dir : g_get_tmp_dir());
}
/*
@ -801,6 +808,7 @@ int
capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_str_p)
{
int status, snaplen;
ws_statb64 fstat;
switch(opt) {
case 'a': /* autostop criteria */
@ -1002,6 +1010,30 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_
}
capture_opts->compress_type = g_strdup(optarg_str_p);
break;
case LONGOPT_CAPTURE_TMPDIR: /* capture temporary directory */
if (capture_opts->temp_dir) {
cmdarg_err("--temp-dir can be set only once");
return 1;
}
if (ws_stat64(optarg_str_p, &fstat) < 0) {
cmdarg_err("Can't set temporary directory %s: %s",
optarg_str_p, g_strerror(errno));
return 1;
}
if (!S_ISDIR(fstat.st_mode)) {
cmdarg_err("Can't set temporary directory %s: not a directory",
optarg_str_p);
return 1;
}
#ifdef S_IRWXU
if ((fstat.st_mode & S_IRWXU) != S_IRWXU) {
cmdarg_err("Can't set temporary directory %s: not a writable directory",
optarg_str_p);
return 1;
}
#endif /* S_IRWXU */
capture_opts->temp_dir = g_strdup(optarg_str_p);
break;
default:
/* the caller is responsible to send us only the right opt's */
ws_assert_not_reached();

View File

@ -47,6 +47,7 @@ extern "C" {
#define LONGOPT_LIST_TSTAMP_TYPES LONGOPT_BASE_CAPTURE+1
#define LONGOPT_SET_TSTAMP_TYPE LONGOPT_BASE_CAPTURE+2
#define LONGOPT_COMPRESS_TYPE LONGOPT_BASE_CAPTURE+3
#define LONGOPT_CAPTURE_TMPDIR LONGOPT_BASE_CAPTURE+4
/*
* Options for capturing common to all capturing programs.
@ -87,7 +88,8 @@ extern "C" {
{"linktype", ws_required_argument, NULL, 'y'}, \
{"list-time-stamp-types", ws_no_argument, NULL, LONGOPT_LIST_TSTAMP_TYPES}, \
{"time-stamp-type", ws_required_argument, NULL, LONGOPT_SET_TSTAMP_TYPE}, \
{"compress-type", ws_required_argument, NULL, LONGOPT_COMPRESS_TYPE},
{"compress-type", ws_required_argument, NULL, LONGOPT_COMPRESS_TYPE}, \
{"temp-dir", ws_required_argument, NULL, LONGOPT_CAPTURE_TMPDIR},
#define OPTSTRING_CAPTURE_COMMON \
@ -315,6 +317,7 @@ typedef struct capture_options_tag {
gboolean print_file_names; /**< TRUE if printing names of completed
files as we close them */
gchar *print_name_to; /**< output file name */
gchar *temp_dir; /**< temporary directory path */
/* internally used (don't touch from outside) */
gboolean output_to_pipe; /**< save_file is a pipe (named or stdout) */

View File

@ -38,6 +38,7 @@ dumpcap - Dump network traffic
[ *-s*|*--snapshot-length* <capture snaplen> ]
[ *-S* ]
[ *-t* ]
[ *--temp-dir* <directory> ]
[ *-v*|*--version* ]
[ *-w* <outfile> ]
[ *-y*|*--linktype* <capture link type> ]
@ -460,6 +461,14 @@ Print statistics for each interface once every second.
Use a separate thread per interface.
--
--temp-dir <directory>::
+
--
Specifies the directory into which temporary files (including capture files)
are to be written. The default behaviour is to use your system's temporary
directory (typically __/tmp__ on Linux, and __C:\\Temp__ on Windows).
--
-v|--version::
+
--

View File

@ -961,6 +961,14 @@ multi-line view of the details of each of the packets, depending on
whether the *-V* option was specified. This is the default.
--
--temp-dir <directory>::
+
--
Specifies the directory into which temporary files (including capture files)
are to be written. The default behaviour is to use your system's temporary
directory (typically __/tmp__ on Linux, and __C:\\Temp__ on Windows).
--
-u <seconds type>::
+
--

View File

@ -670,6 +670,14 @@ was captured
The default format is relative.
--
--temp-dir <directory>::
+
--
Specifies the directory into which temporary files (including capture files)
are to be written. The default behaviour is to use your system's temporary
directory (typically __/tmp__ on Linux, and __C:\\Temp__ on Windows).
--
--time-stamp-type <type>::
+
--

View File

@ -38,6 +38,7 @@
#include <wsutil/socket.h>
#include <wsutil/wslog.h>
#include <wsutil/file_util.h>
#ifdef HAVE_LIBCAP
# include <sys/prctl.h>
@ -434,6 +435,8 @@ print_usage(FILE *output)
fprintf(output, " --capture-comment <comment>\n");
fprintf(output, " add a capture comment to the output file\n");
fprintf(output, " (only for pcapng)\n");
fprintf(output, " --temp-dir <directory> write temporary files to this directory\n");
fprintf(output, " (default: %s)\n", g_get_tmp_dir());
fprintf(output, "\n");
ws_log_print_usage(output);
@ -3678,7 +3681,7 @@ capture_loop_open_output(capture_options *capture_opts, int *save_file_fd,
} else {
suffix = ".pcap";
}
*save_file_fd = create_tempfile(&capfile_name, prefix, suffix, &err_tempfile);
*save_file_fd = create_tempfile(capture_opts->temp_dir, &capfile_name, prefix, suffix, &err_tempfile);
g_free(prefix);
is_tempfile = TRUE;
}
@ -5163,6 +5166,7 @@ main(int argc, char *argv[])
case 'I': /* Monitor mode */
#endif
case LONGOPT_COMPRESS_TYPE: /* compress type */
case LONGOPT_CAPTURE_TMPDIR: /* capture temp directory */
status = capture_opts_add_opt(&global_capture_opts, opt, ws_optarg);
if (status != 0) {
exit_main(status);

View File

@ -1547,13 +1547,13 @@ static gboolean extcap_create_pipe(const gchar *ifname, gchar **fifo, HANDLE *ha
return TRUE;
}
#else
static gboolean extcap_create_pipe(const gchar *ifname, gchar **fifo, const gchar *pipe_prefix)
static gboolean extcap_create_pipe(const gchar *ifname, gchar **fifo, const gchar *temp_dir, const gchar *pipe_prefix)
{
gchar *temp_name = NULL;
int fd = 0;
gchar *pfx = g_strconcat(pipe_prefix, "_", ifname, NULL);
if ((fd = create_tempfile(&temp_name, pfx, NULL, NULL)) < 0)
if ((fd = create_tempfile(temp_dir, &temp_name, pfx, NULL, NULL)) < 0)
{
g_free(pfx);
return FALSE;
@ -1611,11 +1611,15 @@ extcap_init_interfaces(capture_options *capture_opts)
extcap_create_pipe(interface_opts->name, &interface_opts->extcap_control_in,
#ifdef _WIN32
&interface_opts->extcap_control_in_h,
#else
capture_opts->temp_dir,
#endif
EXTCAP_CONTROL_IN_PREFIX);
extcap_create_pipe(interface_opts->name, &interface_opts->extcap_control_out,
#ifdef _WIN32
&interface_opts->extcap_control_out_h,
#else
capture_opts->temp_dir,
#endif
EXTCAP_CONTROL_OUT_PREFIX);
}
@ -1624,6 +1628,8 @@ extcap_init_interfaces(capture_options *capture_opts)
if (!extcap_create_pipe(interface_opts->name, &interface_opts->extcap_fifo,
#ifdef _WIN32
&interface_opts->extcap_pipe_h,
#else
capture_opts->temp_dir,
#endif
EXTCAP_PIPE_PREFIX))
{

4
file.c
View File

@ -1400,7 +1400,7 @@ merge_callback(merge_event event, int num _U_,
cf_status_t
cf_merge_files_to_tempfile(gpointer pd_window, char **out_filenamep,
cf_merge_files_to_tempfile(gpointer pd_window, const char *temp_dir, char **out_filenamep,
int in_file_count, const char *const *in_filenames,
int file_type, gboolean do_append)
{
@ -1420,7 +1420,7 @@ cf_merge_files_to_tempfile(gpointer pd_window, char **out_filenamep,
cf_callback_invoke(cf_cb_file_merge_started, NULL);
/* merge the files */
status = merge_files_to_tempfile(out_filenamep, "wireshark", file_type,
status = merge_files_to_tempfile(temp_dir, out_filenamep, "wireshark", file_type,
in_filenames,
in_file_count, do_append,
IDB_MERGE_MODE_ALL_SAME, 0 /* snaplen */,

2
file.h
View File

@ -678,7 +678,7 @@ void cf_unignore_frame(capture_file *cf, frame_data *frame);
* @return one of cf_status_t
*/
cf_status_t
cf_merge_files_to_tempfile(gpointer pd_window, char **out_filenamep,
cf_merge_files_to_tempfile(gpointer pd_window, const char *temp_dir, char **out_filenamep,
int in_file_count, const char *const *in_filenames,
int file_type, gboolean do_append);

View File

@ -482,6 +482,8 @@ print_usage(FILE *output)
fprintf(output, " values\n");
fprintf(output, " --elastic-mapping-filter <protocols> If -G elastic-mapping is specified, put only the\n");
fprintf(output, " specified protocols within the mapping file\n");
fprintf(output, " --temp-dir <directory> write temporary files to this directory\n");
fprintf(output, " (default: %s)\n", g_get_tmp_dir());
fprintf(output, "\n");
ws_log_print_usage(output);
@ -616,7 +618,13 @@ about_folders(void)
*/
/* temp */
printf("%-21s\t%s\n", "Temp:", g_get_tmp_dir());
constpath = g_get_tmp_dir();
#ifdef HAVE_LIBPCAP
/* global_capture_opts only exists in this case */
if (global_capture_opts.temp_dir)
constpath = global_capture_opts.temp_dir;
#endif
printf("%-21s\t%s\n", "Temp:", constpath);
/* pers conf */
path = get_persconffile_path("", FALSE);
@ -1130,6 +1138,7 @@ main(int argc, char *argv[])
case 'B': /* Buffer size */
#endif
case LONGOPT_COMPRESS_TYPE: /* compress type */
case LONGOPT_CAPTURE_TMPDIR: /* capture temp directory */
/* These are options only for packet capture. */
#ifdef HAVE_LIBPCAP
exit_status = capture_opts_add_opt(&global_capture_opts, opt, ws_optarg);

View File

@ -166,6 +166,9 @@ commandline_print_usage(gboolean for_help_option) {
fprintf(output, " --capture-comment <comment>\n");
fprintf(output, " add a capture file comment, if supported\n");
#endif
fprintf(output, " --temp-dir <directory> write temporary files to this directory\n");
fprintf(output, " (default: %s)\n", g_get_tmp_dir());
fprintf(output, "\n");
ws_log_print_usage(output);
@ -411,6 +414,7 @@ void commandline_other_options(int argc, char *argv[], gboolean opt_reset)
case 'p': /* Don't capture in promiscuous mode */
case 'i': /* Use interface x */
case LONGOPT_SET_TSTAMP_TYPE: /* Set capture timestamp type */
case LONGOPT_CAPTURE_TMPDIR: /* capture temp directory */
#ifdef HAVE_PCAP_CREATE
case 'I': /* Capture in monitor mode, if available */
#endif

View File

@ -18,6 +18,7 @@
#include "ui/version_info.h"
#include <epan/tap.h>
#include <epan/prefs.h>
#include <epan/exported_pdu.h>
#include <epan/epan_dissect.h>
#include <wiretap/wtap.h>
@ -29,7 +30,7 @@
#include "export_pdu_ui_utils.h"
void
do_export_pdu(const char *filter, const gchar *tap_name)
do_export_pdu(const char *filter, const gchar *temp_dir, const gchar *tap_name)
{
exp_pdu_t exp_pdu_tap_data;
char *error;
@ -50,7 +51,7 @@ do_export_pdu(const char *filter, const gchar *tap_name)
/* Choose a random name for the temporary import buffer */
GError *err_tempfile = NULL;
import_file_fd = create_tempfile(&capfile_name, "Wireshark_PDU_", NULL, &err_tempfile);
import_file_fd = create_tempfile(temp_dir, &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);

View File

@ -21,7 +21,7 @@ extern "C" {
* Filters the current opened capture file into a temporary file. On success,
* the filtered file is opened into the UI.
*/
void do_export_pdu(const char *filter, const gchar *tap_name);
void do_export_pdu(const char *filter, const gchar *temp_dir, const gchar *tap_name);
#ifdef __cplusplus

View File

@ -23,6 +23,7 @@
#endif
#include <epan/maxmind_db.h>
#include <epan/prefs.h>
#ifdef HAVE_LUA
#include <epan/wslua/init_wslua.h>
@ -39,6 +40,7 @@
#include "wsutil/plugins.h"
#include "wsutil/copyright_info.h"
#include "ui/version_info.h"
#include "ui/capture_globals.h"
#include "extcap.h"
@ -197,7 +199,7 @@ FolderListModel::FolderListModel(QObject * parent):
appendRow(QStringList() << tr("\"File\" dialogs") << get_last_open_dir() << tr("capture files"));
/* temp */
appendRow(QStringList() << tr("Temp") << g_get_tmp_dir() << tr("untitled capture files"));
appendRow(QStringList() << tr("Temp") << (global_capture_opts.temp_dir && global_capture_opts.temp_dir[0] ? global_capture_opts.temp_dir : g_get_tmp_dir()) << tr("untitled capture files"));
/* pers conf */
appendRow(QStringList() << tr("Personal configuration")

View File

@ -213,6 +213,9 @@ CaptureOptionsDialog::CaptureOptionsDialog(QWidget *parent) :
ui->rbCompressionNone->setChecked(true);
ui->tempDirLineEdit->setPlaceholderText(g_get_tmp_dir());
ui->tempDirLineEdit->setText(global_capture_opts.temp_dir);
// Changes in interface selections or capture filters should be propagated
// to the main welcome screen where they will be applied to the global
// capture options.
@ -231,6 +234,7 @@ CaptureOptionsDialog::CaptureOptionsDialog(QWidget *parent) :
connect(ui->browseButton, SIGNAL(clicked()), this, SLOT(browseButtonClicked()));
connect(ui->interfaceTree, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(itemClicked(QTreeWidgetItem*,int)));
connect(ui->interfaceTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(itemDoubleClicked(QTreeWidgetItem*)));
connect(ui->tempDirBrowseButton, SIGNAL(clicked()), this, SLOT(tempDirBrowseButtonClicked()));
updateWidgets();
}
@ -381,6 +385,12 @@ void CaptureOptionsDialog::browseButtonClicked()
ui->filenameLineEdit->setText(file_name);
}
void CaptureOptionsDialog::tempDirBrowseButtonClicked()
{
QString specified_dir = WiresharkFileDialog::getExistingDirectory(this, tr("Specify temporary directory"));
ui->tempDirLineEdit->setText(specified_dir);
}
void CaptureOptionsDialog::interfaceItemChanged(QTreeWidgetItem *item, int column)
{
QWidget* editor = ui->interfaceTree->indexWidget(ui->interfaceTree->currentIndex());
@ -951,6 +961,14 @@ bool CaptureOptionsDialog::saveOptionsToPreferences()
global_capture_opts.orig_save_file = NULL;
}
QString tempdir = ui->tempDirLineEdit->text();
if (tempdir.length() > 0) {
global_capture_opts.temp_dir = qstring_strdup(tempdir);
}
else {
global_capture_opts.temp_dir = NULL;
}
global_capture_opts.has_ring_num_files = ui->RbCheckBox->isChecked();
if (global_capture_opts.has_ring_num_files) {

View File

@ -92,6 +92,7 @@ private slots:
void itemClicked(QTreeWidgetItem *item, int column);
void itemDoubleClicked(QTreeWidgetItem *item);
void changeEvent(QEvent* event);
void tempDirBrowseButtonClicked();
signals:
void startCapture();

View File

@ -902,6 +902,40 @@ For example, use 1 hour to have a new file created every hour on the hour.</stri
</widget>
</item>
<item row="2" column="0">
<widget class="QGroupBox" name="gbTempDir">
<property name="enabled">
<bool>true</bool>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Optionally specify a temporary directory for unnamed capture files.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="title">
<string>Directory for temporary files</string>
</property>
<property name="flat">
<bool>true</bool>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QLineEdit" name="tempDirLineEdit"/>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="tempDirBrowseButton">
<property name="text">
<string>Browse…</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="0">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>

View File

@ -17,6 +17,7 @@
#include <epan/exported_pdu.h>
#include "ui/export_pdu_ui_utils.h"
#include "ui/capture_globals.h"
ExportPDUDialog::ExportPDUDialog(QWidget *parent) :
QDialog(parent),
@ -35,7 +36,7 @@ void ExportPDUDialog::on_buttonBox_accepted()
const QByteArray& filter = ui->displayFilterLineEdit->text().toUtf8();
const QByteArray& tap_name = ui->comboBox->currentText().toUtf8();
do_export_pdu(filter.constData(), tap_name.constData());
do_export_pdu(filter.constData(), global_capture_opts.temp_dir, tap_name.constData());
}
ExportPDUDialog::~ExportPDUDialog()
{

View File

@ -20,6 +20,7 @@
#include "ui/last_open_dir.h"
#include "ui/alert_box.h"
#include "ui/help_url.h"
#include "ui/capture_globals.h"
#include "file.h"
#include "wsutil/file_util.h"
@ -510,7 +511,7 @@ int ImportTextDialog::exec() {
}
text_import_pre_open(&params, file_type_subtype, import_info_.import_text_filename, interface_name.toUtf8().constData());
/* Use a random name for the temporary import buffer */
import_info_.wdh = wtap_dump_open_tempfile(&tmp, "import", file_type_subtype, WTAP_UNCOMPRESSED, &params, &err, &err_info);
import_info_.wdh = wtap_dump_open_tempfile(global_capture_opts.temp_dir, &tmp, "import", file_type_subtype, WTAP_UNCOMPRESSED, &params, &err, &err_info);
capfile_name_.append(tmp ? tmp : "temporary file");
import_info_.output_filename = tmp;

View File

@ -1056,7 +1056,7 @@ void MainWindow::dropEvent(QDropEvent *event)
}
/* merge the files in chronological order */
if (cf_merge_files_to_tempfile(this, &tmpname, local_files.size(),
if (cf_merge_files_to_tempfile(this, global_capture_opts.temp_dir, &tmpname, local_files.size(),
in_filenames,
wtap_pcapng_file_type_subtype(),
FALSE) == CF_OK) {
@ -1253,17 +1253,17 @@ void MainWindow::mergeCaptureFile()
/* chronological order */
in_filenames[0] = g_strdup(capture_file_.capFile()->filename);
in_filenames[1] = qstring_strdup(file_name);
merge_status = cf_merge_files_to_tempfile(this, &tmpname, 2, in_filenames, file_type, FALSE);
merge_status = cf_merge_files_to_tempfile(this, global_capture_opts.temp_dir, &tmpname, 2, in_filenames, file_type, FALSE);
} else if (merge_dlg.mergeType() <= 0) {
/* prepend file */
in_filenames[0] = qstring_strdup(file_name);
in_filenames[1] = g_strdup(capture_file_.capFile()->filename);
merge_status = cf_merge_files_to_tempfile(this, &tmpname, 2, in_filenames, file_type, TRUE);
merge_status = cf_merge_files_to_tempfile(this, global_capture_opts.temp_dir, &tmpname, 2, in_filenames, file_type, TRUE);
} else {
/* append file */
in_filenames[0] = g_strdup(capture_file_.capFile()->filename);
in_filenames[1] = qstring_strdup(file_name);
merge_status = cf_merge_files_to_tempfile(this, &tmpname, 2, in_filenames, file_type, TRUE);
merge_status = cf_merge_files_to_tempfile(this, global_capture_opts.temp_dir, &tmpname, 2, in_filenames, file_type, TRUE);
}
g_free(in_filenames[0]);

View File

@ -2395,7 +2395,7 @@ wtap_dump_open(const char *filename, int file_type_subtype,
}
wtap_dumper *
wtap_dump_open_tempfile(char **filenamep, const char *pfx,
wtap_dump_open_tempfile(const char *tmpdir, char **filenamep, const char *pfx,
int file_type_subtype, wtap_compression_type compression_type,
const wtap_dump_params *params, int *err, gchar **err_info)
{
@ -2426,7 +2426,7 @@ wtap_dump_open_tempfile(char **filenamep, const char *pfx,
(void) g_strlcat(sfx, ext, 16);
/* Choose a random name for the file */
fd = create_tempfile(filenamep, pfx, sfx, NULL);
fd = create_tempfile(tmpdir, filenamep, pfx, sfx, NULL);
if (fd == -1) {
*err = WTAP_ERR_CANT_OPEN;
g_free(wdh);

View File

@ -1065,11 +1065,11 @@ merge_files_common(const gchar* out_filename, /* normal output mode */
dsb_combined = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));
params.dsbs_growing = dsb_combined;
}
if (out_filename) {
if (out_filename && !out_filenamep) {
pdh = wtap_dump_open(out_filename, file_type, WTAP_UNCOMPRESSED,
&params, err, err_info);
} else if (out_filenamep) {
pdh = wtap_dump_open_tempfile(out_filenamep, pfx, file_type,
} else if (out_filename && out_filenamep) {
pdh = wtap_dump_open_tempfile(out_filename, out_filenamep, pfx, file_type,
WTAP_UNCOMPRESSED, &params, err,
err_info);
} else {
@ -1132,7 +1132,7 @@ merge_files(const gchar* out_filename, const int file_type,
* on failure.
*/
merge_result
merge_files_to_tempfile(gchar **out_filenamep, const char *pfx,
merge_files_to_tempfile(const char *tmpdir, gchar **out_filenamep, const char *pfx,
const int file_type, const char *const *in_filenames,
const guint in_file_count, const gboolean do_append,
const idb_merge_mode mode, guint snaplen,
@ -1145,7 +1145,7 @@ merge_files_to_tempfile(gchar **out_filenamep, const char *pfx,
/* no temporary file name yet */
*out_filenamep = NULL;
return merge_files_common(NULL, out_filenamep, pfx,
return merge_files_common(tmpdir, out_filenamep, pfx,
file_type, in_filenames, in_file_count,
do_append, mode, snaplen, app_name, cb, err,
err_info, err_fileno, err_framenum);

View File

@ -144,6 +144,7 @@ merge_files(const gchar* out_filename, const int file_type,
/** Merge the given input files to a temporary file
*
* @param tmpdir Points to the directory in which to write the temporary file
* @param out_filenamep Points to a pointer that's set to point to the
* pathname of the temporary file; it's allocated with g_malloc()
* @param pfx A string to be used as the prefix for the temporary file name
@ -166,7 +167,7 @@ merge_files(const gchar* out_filename, const int file_type,
* @return the frame type
*/
WS_DLL_PUBLIC merge_result
merge_files_to_tempfile(gchar **out_filenamep, const char *pfx,
merge_files_to_tempfile(const char *tmpdir, gchar **out_filenamep, const char *pfx,
const int file_type, const char *const *in_filenames,
const guint in_file_count, const gboolean do_append,
const idb_merge_mode mode, guint snaplen,

View File

@ -2023,6 +2023,7 @@ wtap_dumper* wtap_dump_open(const char *filename, int file_type_subtype,
/**
* @brief Creates a dumper for a temporary file.
*
* @param tmpdir Directory in which to create the temporary file.
* @param filenamep Points to a pointer that's set to point to the
* pathname of the temporary file; it's allocated with g_malloc()
* @param pfx A string to be used as the prefix for the temporary file name
@ -2035,7 +2036,8 @@ wtap_dumper* wtap_dump_open(const char *filename, int file_type_subtype,
* @return The newly created dumper object, or NULL on failure.
*/
WS_DLL_PUBLIC
wtap_dumper* wtap_dump_open_tempfile(char **filenamep, const char *pfx,
wtap_dumper* wtap_dump_open_tempfile(const char *tmpdir, char **filenamep,
const char *pfx,
int file_type_subtype, wtap_compression_type compression_type,
const wtap_dump_params *params, int *err, gchar **err_info);

View File

@ -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);
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 = 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;
}

View File

@ -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
}