From e0ebc32195232e1b5d96aec5f34b64932ba69bca Mon Sep 17 00:00:00 2001 From: Gerald Combs Date: Wed, 1 Jul 2009 23:36:51 +0000 Subject: [PATCH] Updates to create_tempfile: - Use g_get_tmp_dir, just like get_tempfile_path. - Don't make the caller worry about the path buffer length. svn path=/trunk/; revision=28915 --- dumpcap.c | 4 +- file.c | 4 +- gtk/follow_stream.c | 7 +-- gtk/follow_stream.h | 6 +-- gtk/follow_tcp.c | 9 +++- gtk/hostlist_table.c | 4 +- gtk/iax2_analysis.c | 17 +++--- gtk/print_dlg.c | 6 +-- gtk/rtp_analysis.c | 17 +++--- tempfile.c | 124 ++++++++++++++----------------------------- tempfile.h | 19 +++++-- 11 files changed, 95 insertions(+), 122 deletions(-) diff --git a/dumpcap.c b/dumpcap.c index 59f1f4c6e3..92e4c99d18 100644 --- a/dumpcap.c +++ b/dumpcap.c @@ -1702,7 +1702,7 @@ static gboolean capture_loop_open_output(capture_options *capture_opts, int *save_file_fd, char *errmsg, int errmsg_len) { - char tmpname[128+1]; + char *tmpname; gchar *capfile_name; gboolean is_tempfile; #ifndef _WIN32 @@ -1757,7 +1757,7 @@ capture_loop_open_output(capture_options *capture_opts, int *save_file_fd, is_tempfile = FALSE; } else { /* Choose a random name for the temporary capture buffer */ - *save_file_fd = create_tempfile(tmpname, sizeof tmpname, "wireshark"); + *save_file_fd = create_tempfile(&tmpname, "wireshark"); capfile_name = g_strdup(tmpname); is_tempfile = TRUE; } diff --git a/file.c b/file.c index e618628d64..8e6a52ac22 100644 --- a/file.c +++ b/file.c @@ -1253,7 +1253,7 @@ cf_merge_files(char **out_filenamep, int in_file_count, merge_in_file_t *in_files; wtap *wth; char *out_filename; - char tmpname[128+1]; + char *tmpname; int out_fd; wtap_dumper *pdh; int open_err, read_err, write_err, close_err; @@ -1288,7 +1288,7 @@ cf_merge_files(char **out_filenamep, int in_file_count, if (out_fd == -1) open_err = errno; } else { - out_fd = create_tempfile(tmpname, sizeof tmpname, "wireshark"); + out_fd = create_tempfile(&tmpname, "wireshark"); if (out_fd == -1) open_err = errno; out_filename = g_strdup(tmpname); diff --git a/gtk/follow_stream.c b/gtk/follow_stream.c index bdb433ff56..2414093368 100644 --- a/gtk/follow_stream.c +++ b/gtk/follow_stream.c @@ -395,7 +395,7 @@ follow_print_stream(GtkWidget * w _U_, gpointer data) #ifdef _WIN32 gboolean win_printer = FALSE; int tmp_fd; - char tmp_namebuf[128+1]; /* see create_tmpfile which says [128+1]; why ? */ + char *tmp_namebuf; #endif switch (prefs.pr_dest) { @@ -410,10 +410,10 @@ follow_print_stream(GtkWidget * w _U_, gpointer data) /* Don't use tmpnam() or such, as this will fail under some ACL */ /* circumstances: http://bugs.wireshark.org/bugzilla/show_bug.cgi?id=358 */ /* Also: tmpnam is "insecure" and should not be used. */ - tmp_fd = create_tempfile(tmp_namebuf, sizeof(tmp_namebuf), "wshprint"); + tmp_fd = create_tempfile(tmp_namebuf, "wshprint"); if(tmp_fd == -1) { simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "Couldn't create a temporary file for printing."); + "Couldn't create temporary file for printing:\n%s", tmp_namebuf); return; } ws_close(tmp_fd); @@ -967,6 +967,7 @@ follow_destroy_cb(GtkWidget *w, gpointer data _U_) break; } + g_free(follow_info->data_out_filename); g_free(follow_info->filter_out_filter); g_free((gpointer)follow_info->client_ip.data); forget_follow_info(follow_info); diff --git a/gtk/follow_stream.h b/gtk/follow_stream.h index 02078e9e3d..3f9471f933 100644 --- a/gtk/follow_stream.h +++ b/gtk/follow_stream.h @@ -68,7 +68,7 @@ typedef struct { follow_type_t follow_type; show_stream_t show_stream; show_type_t show_type; - char data_out_filename[128 + 1]; + char *data_out_filename; GtkWidget *text; GtkWidget *ascii_bt; GtkWidget *ebcdic_bt; @@ -99,12 +99,12 @@ void follow_stream(gchar *title, follow_info_t *follow_info, gchar *both_directions_string, gchar *server_to_client_string, gchar *client_to_server_string); -frs_return_t follow_show(follow_info_t *follow_info, +frs_return_t follow_show(follow_info_t *follow_info, gboolean (*print_line)(char *, size_t, gboolean, void *), char *buffer, size_t nchars, gboolean is_server, void *arg, guint32 *global_pos, - guint32 *server_packet_count, + guint32 *server_packet_count, guint32 *client_packet_count); frs_return_t follow_read_tcp_stream(follow_info_t *follow_info, gboolean (*print_line)(char *, size_t, gboolean, void *), void *arg); diff --git a/gtk/follow_tcp.c b/gtk/follow_tcp.c index df1854c8d5..6ea8cfbcba 100644 --- a/gtk/follow_tcp.c +++ b/gtk/follow_tcp.c @@ -106,6 +106,7 @@ follow_tcp_stream_cb(GtkWidget * w, gpointer data _U_) follow_info_t *follow_info; tcp_stream_chunk sc; size_t nchars; + gchar *data_out_filename; /* we got tcp so we can follow */ if (cfile.edt->pi.ipproto != IP_PROTO_TCP) { @@ -138,13 +139,14 @@ follow_tcp_stream_cb(GtkWidget * w, gpointer data _U_) append stuff to the text widget for the TCP stream window, if we can arrange that said window not pop up until we're done. */ - tmp_fd = create_tempfile(follow_info->data_out_filename, - sizeof follow_info->data_out_filename, "follow"); + tmp_fd = create_tempfile(&data_out_filename, "follow"); + follow_info->data_out_filename = g_strdup(data_out_filename); if (tmp_fd == -1) { simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not create temporary file %s: %s", follow_info->data_out_filename, strerror(errno)); + g_free(follow_info->data_out_filename); g_free(follow_info); g_free(follow_filter); return; @@ -157,6 +159,7 @@ follow_tcp_stream_cb(GtkWidget * w, gpointer data _U_) follow_info->data_out_filename, strerror(errno)); ws_close(tmp_fd); ws_unlink(follow_info->data_out_filename); + g_free(follow_info->data_out_filename); g_free(follow_info); g_free(follow_filter); return; @@ -201,6 +204,7 @@ follow_tcp_stream_cb(GtkWidget * w, gpointer data _U_) "The packets in the capture file for that stream have no data."); ws_close(tmp_fd); ws_unlink(follow_info->data_out_filename); + g_free(follow_info->data_out_filename); g_free(follow_info->filter_out_filter); g_free(follow_info); return; @@ -232,6 +236,7 @@ follow_tcp_stream_cb(GtkWidget * w, gpointer data _U_) } ws_close(tmp_fd); ws_unlink(follow_info->data_out_filename); + g_free(follow_info->data_out_filename); g_free(follow_info->filter_out_filter); g_free(follow_info); return; diff --git a/gtk/hostlist_table.c b/gtk/hostlist_table.c index 5e0b2db34e..aac4237b95 100644 --- a/gtk/hostlist_table.c +++ b/gtk/hostlist_table.c @@ -595,7 +595,7 @@ open_as_map_cb(GtkWindow *copy_bt, gpointer data _U_) FILE *out_file; gchar *file_uri; gboolean uri_open; - char map_data_filename[128+1]; + char *map_data_filename; int temp_fd; char *src_file_path; char *temp_path; @@ -644,7 +644,7 @@ open_as_map_cb(GtkWindow *copy_bt, gpointer data _U_) /* open the TSV output file */ /* XXX - add error handling */ - temp_fd = create_tempfile(map_data_filename, sizeof map_data_filename, "ipmap_"); + temp_fd = create_tempfile(&map_data_filename, "ipmap_"); if(temp_fd == -1) { simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not create temporary file %s: %s", diff --git a/gtk/iax2_analysis.c b/gtk/iax2_analysis.c index 7094c87094..449a06225e 100644 --- a/gtk/iax2_analysis.c +++ b/gtk/iax2_analysis.c @@ -209,8 +209,6 @@ struct _info_direction { tap_iax2_save_info_t saveinfo; }; -#define TMPNAMSIZE 100 - #define SILENCE_PCMU (guint8)0xFF #define SILENCE_PCMA (guint8)0x55 @@ -230,8 +228,8 @@ typedef struct _user_data_t { struct _info_direction forward; struct _info_direction reversed; - char f_tempname[TMPNAMSIZE]; - char r_tempname[TMPNAMSIZE]; + char *f_tempname; + char *r_tempname; /* dialog associated data */ dialog_data_t dlg; @@ -781,6 +779,8 @@ static void on_destroy(GtkWidget *win _U_, user_data_t *user_data) /* XXX: Is this still true for GTK2 ??? */ g_signal_handler_disconnect(user_data->dlg.notebook, user_data->dlg.notebook_signal_id); + g_free(user_data->f_tempname); + g_free(user_data->r_tempname); g_free(user_data); } @@ -3438,6 +3438,7 @@ void iax2_analysis( {0, 0x0000, 0xffff, 0x0000}, {0, 0x0000, 0x0000, 0xffff} }; + char *tempname; /* init */ user_data = g_malloc(sizeof(user_data_t)); @@ -3454,11 +3455,11 @@ void iax2_analysis( /* file names for storing sound data */ /*XXX: check for errors*/ - fd = create_tempfile(user_data->f_tempname, sizeof(user_data->f_tempname), - "ether_iax2_f"); + fd = create_tempfile(&tempname, "wireshark_iax2_f"); + user_data->f_tempname = g_strdup(tempname); ws_close(fd); - fd = create_tempfile(user_data->r_tempname, sizeof(user_data->r_tempname), - "ether_iax2_r"); + fd = create_tempfile(&tempname, "wireshark_iax2_r"); + user_data->r_tempname = g_strdup(tempname); ws_close(fd); user_data->forward.saveinfo.fp = NULL; user_data->reversed.saveinfo.fp = NULL; diff --git a/gtk/print_dlg.c b/gtk/print_dlg.c index 0a6f5b0224..55a2ffd343 100644 --- a/gtk/print_dlg.c +++ b/gtk/print_dlg.c @@ -908,7 +908,7 @@ print_ok_cb(GtkWidget *ok_bt, gpointer parent_w) #ifdef _WIN32 gboolean win_printer = FALSE; int tmp_fd; - char tmp_namebuf[128+1]; /* XX: see create_tmpfile which says [128+1]; why ? */ + char *tmp_namebuf; char *tmp_oldfile; #endif cf_print_status_t status; @@ -951,10 +951,10 @@ print_ok_cb(GtkWidget *ok_bt, gpointer parent_w) /* Don't use tmpnam() or such, as this will fail under some ACL */ /* circumstances: http://bugs.wireshark.org/bugzilla/show_bug.cgi?id=358 */ /* Also: tmpnam is "insecure" and should not be used. */ - tmp_fd = create_tempfile(tmp_namebuf, sizeof(tmp_namebuf), "wshprint"); + tmp_fd = create_tempfile(&tmp_namebuf, "wshprint"); if(tmp_fd == -1) { simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "Couldn't create a temporary file for printing."); + "Couldn't create a temporary file for printing:\n%s", tmp_namebuf); return; } /* remember to restore these values later! */ diff --git a/gtk/rtp_analysis.c b/gtk/rtp_analysis.c index a1d193eced..b27aa244ee 100644 --- a/gtk/rtp_analysis.c +++ b/gtk/rtp_analysis.c @@ -203,8 +203,6 @@ struct _info_direction { tap_rtp_save_info_t saveinfo; }; -#define TMPNAMSIZE 100 - #define SILENCE_PCMU (guint8)0xFF #define SILENCE_PCMA (guint8)0x55 @@ -226,8 +224,8 @@ typedef struct _user_data_t { struct _info_direction forward; struct _info_direction reversed; - char f_tempname[TMPNAMSIZE]; - char r_tempname[TMPNAMSIZE]; + char *f_tempname; + char *r_tempname; /* dialog associated data */ dialog_data_t dlg; @@ -777,6 +775,8 @@ static void on_destroy(GtkWidget *win _U_, user_data_t *user_data) /* disable the "switch_page" signal in the dlg, otherwise will be called when the windows is destroy and cause an exception using GTK1*/ g_signal_handler_disconnect(user_data->dlg.notebook, user_data->dlg.notebook_signal_id); + g_free(user_data->f_tempname); + g_free(user_data->r_tempname); g_free(user_data); } @@ -3580,6 +3580,7 @@ void rtp_analysis( {0, 0x0000, 0xffff, 0x0000}, {0, 0x0000, 0x0000, 0xffff} }; + char *tempname; /* init */ user_data = g_malloc(sizeof(user_data_t)); @@ -3598,11 +3599,11 @@ void rtp_analysis( /* file names for storing sound data */ /*XXX: check for errors*/ - fd = create_tempfile(user_data->f_tempname, sizeof(user_data->f_tempname), - "ether_rtp_f"); + fd = create_tempfile(&tempname, "wireshark_rtp_f"); + user_data->f_tempname = g_strdup(tempname); ws_close(fd); - fd = create_tempfile(user_data->r_tempname, sizeof(user_data->r_tempname), - "ether_rtp_r"); + fd = create_tempfile(&tempname, "wireshark_rtp_r"); + user_data->r_tempname = g_strdup(tempname); ws_close(fd); user_data->forward.saveinfo.fp = NULL; user_data->reversed.saveinfo.fp = NULL; diff --git a/tempfile.c b/tempfile.c index 84e66f321c..7b3ede6917 100644 --- a/tempfile.c +++ b/tempfile.c @@ -45,39 +45,50 @@ #include "mkstemp.h" #include -static const char * -setup_tmpdir(const char *dir) -{ - size_t len = strlen(dir); - char *newdir; +#define INITIAL_PATH_SIZE 128 +#define TMP_FILE_SUFFIX "XXXXXXXXXX" - /* Append path separator if necessary */ - if (len != 0 && dir[len - 1] == G_DIR_SEPARATOR) { - return dir; - } - else { - newdir = g_strdup_printf("%s%s", dir, G_DIR_SEPARATOR_S); - return newdir; - } -} - -static int -try_tempfile(char *namebuf, int namebuflen, const char *dir, const char *pfx) +/** + * Create a tempfile with the given prefix (e.g. "wireshark"). + * + * @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. + * @return The file descriptor of the new tempfile, from mkstemp(). + */ +int +create_tempfile(char **namebuf, const char *pfx) { - static const char suffix[] = "XXXXXXXXXX"; - int namelen = (int) (strlen(dir) + strlen(pfx) + sizeof(suffix)); + static char *tf_path[3]; + static int tf_path_len[3]; + static int idx; + const char *tmp_dir; int old_umask; - int tmp_fd; + int fd; - g_snprintf(namebuf, namebuflen, "%s%s%s", dir, pfx, suffix); - if (namebuflen < namelen) { - /* Stick with the truncated name, so that if this error is - reported with the file name, you at least get - something. */ - errno = ENAMETOOLONG; - return -1; + idx = (idx + 1) % 3; + + /* + * Allocate the buffer if it's not already allocated. + */ + if (tf_path[idx] == NULL) { + tf_path_len[idx] = INITIAL_PATH_SIZE; + tf_path[idx] = g_malloc(tf_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(tf_path[idx], tf_path_len[idx], "%s%c%s" TMP_FILE_SUFFIX, tmp_dir, G_DIR_SEPARATOR, pfx) > tf_path_len[idx]) { + tf_path_len[idx] *= 2; + tf_path[idx] = g_realloc(tf_path[idx], tf_path_len[idx]); + } + + if (namebuf) { + *namebuf = tf_path[idx]; + } /* The Single UNIX Specification doesn't say that "mkstemp()" creates the temporary file with mode rw-------, so we won't assume that all UNIXes will do so; instead, we set @@ -85,62 +96,7 @@ try_tempfile(char *namebuf, int namebuflen, const char *dir, const char *pfx) permissions, attempt to create the file, and then put the umask back. */ old_umask = umask(0077); - tmp_fd = mkstemp(namebuf); + fd = mkstemp(tf_path[idx]); umask(old_umask); - return tmp_fd; -} - -static const char *tmpdir = NULL; -#ifdef _WIN32 -static const char *temp = NULL; -#endif -static const char *E_tmpdir; - -#ifndef P_tmpdir -#define P_tmpdir "/var/tmp" -#endif - -/* create a tempfile with the given prefix (e.g. "wireshark") - * namebuf (and namebuflen) should be 128+1 bytes long (BTW: why?) - * returns the file descriptor of the new tempfile and - * the name of the new file in namebuf - */ -int -create_tempfile(char *namebuf, int namebuflen, const char *pfx) -{ - char *dir; - int fd; - static gboolean initialized; - - if (!initialized) { - if ((dir = getenv("TMPDIR")) != NULL) - tmpdir = setup_tmpdir(dir); -#ifdef _WIN32 - if ((dir = getenv("TEMP")) != NULL) - temp = setup_tmpdir(dir); -#endif - - E_tmpdir = setup_tmpdir(P_tmpdir); - initialized = TRUE; - } - - if (tmpdir != NULL) { - fd = try_tempfile(namebuf, namebuflen, tmpdir, pfx); - if (fd != -1) - return fd; - } - -#ifdef _WIN32 - if (temp != NULL) { - fd = try_tempfile(namebuf, namebuflen, temp, pfx); - if (fd != -1) - return fd; - } -#endif - - fd = try_tempfile(namebuf, namebuflen, E_tmpdir, pfx); - if (fd != -1) - return fd; - - return try_tempfile(namebuf, namebuflen, G_DIR_SEPARATOR_S "tmp", pfx); + return fd; } diff --git a/tempfile.h b/tempfile.h index 1c073e5e2b..95a03794a6 100644 --- a/tempfile.h +++ b/tempfile.h @@ -29,12 +29,21 @@ extern "C" { #endif /* __cplusplus */ -/* create a tempfile with the given prefix (e.g. "ether") - * namebuf (and namebuflen) should be 128+1 bytes long (BTW: why?) - * returns the file descriptor of the new tempfile and - * the name of the new file in namebuf +/** @file + * Convenience function for temporary file creation. */ -int create_tempfile(char *namebuf, int namebuflen, const char *pfx); + + +/** + * Create a tempfile with the given prefix (e.g. "wireshark"). The path + * is created using g_get_tmp_dir and mkstemp. + * + * @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. + * @return The file descriptor of the new tempfile, from mkstemp(). + */ +int create_tempfile(char **namebuf, const char *pfx); #ifdef __cplusplus }