Add routines to Wiretap to allow a client of Wiretap to get:
a pointer to the "wtap_pkthdr" structure for an open capture file; a pointer to the "wtap_pseudo_header" union for an open capture file; a pointer to the packet buffer for an open capture file; so that a program using "wtap_read()" in a loop can get at those items. Keep, in a "capture_file" structure, an indicator of whether: no file is open; a file is open, and being read; a file is open, and is being read, but the user tried to quit out of reading the file (e.g., by doing "File/Quit"); a file is open, and has been completely read. Abort if we try to close a capture that's being read if the user hasn't tried to quit out of the read. Have "File/Quit" check if a file is being read; if so, just set the state indicator to "user tried to quit out of it", so that the code reading the file can do what's appropriate to clean up, rather than closing the file out from under that code and causing crashes. Have "read_cap_file()" read the capture file with a loop using "wtap_read()", rather than by using "wtap_loop()"; have it check after reading each packet whether the user tried to abort the read and, if so, close the capture and return an indication that the read was aborted by the user. Otherwise, return an indication of whether the read completely succeeded or failed in the middle (and, if it failed, return the error code through a pointer). Have "continue_tail_cap_file()" read the capture file with a loop using "wtap_read()", rather than by using "wtap_loop()"; have it check after reading each packet whether the user tried to abort the read and, if so, quit the loop, and after the loop finishes (even if it read no packets), return an indication that the read was aborted by the user if that happened. Otherwise, return an indication of whether the read completely succeeded or failed in the middle (and, if it failed, return the error code through a pointer). Have "finish_tail_cap_file()" read the capture file with a loop using "wtap_read()", rather than by using "wtap_loop()"; have it check after reading each packet whether the user tried to abort the read and, if so, quit the loop, and after the loop finishes (even if it read no packets), close the capture and return an indication that the read was aborted by the user if that happened. Otherwise, return an indication of whether the read completely succeeded or failed in the middle (and, if it failed, return the error code through a pointer). Have their callers check whether the read was aborted or not and, if it was, bail out in the appropriate fashion (exit if it's reading a file specified by "-r" on the command line; exit the main loop if it's reading a file specified with File->Open; kill the capture child if it's "continue_tail_cap_file()"; exit the main loop if it's "finish_tail_cap_file()". svn path=/trunk/; revision=2095
This commit is contained in:
parent
5af6a8d416
commit
7843ac6d0e
64
capture.c
64
capture.c
|
@ -1,7 +1,7 @@
|
|||
/* capture.c
|
||||
* Routines for packet capture windows
|
||||
*
|
||||
* $Id: capture.c,v 1.109 2000/06/27 04:35:42 guy Exp $
|
||||
* $Id: capture.c,v 1.110 2000/06/27 07:13:12 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
|
@ -113,6 +113,7 @@ static int sync_pipe[2]; /* used to sync father */
|
|||
enum PIPES { READ, WRITE }; /* Constants 0 and 1 for READ and WRITE */
|
||||
int quit_after_cap; /* Makes a "capture only mode". Implies -k */
|
||||
gboolean capture_child; /* if this is the child for "-S" */
|
||||
static int fork_child; /* In parent, process ID of child */
|
||||
static guint cap_input_id;
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -182,7 +183,6 @@ do_capture(char *capfile_name)
|
|||
cfile.save_file = capfile_name;
|
||||
|
||||
if (sync_mode) { /* do the capture in a child process */
|
||||
int fork_child;
|
||||
char ssnap[24];
|
||||
char scount[24]; /* need a constant for len of numbers */
|
||||
char save_file_fd[24];
|
||||
|
@ -415,7 +415,21 @@ do_capture(char *capfile_name)
|
|||
if ((err = open_cap_file(cfile.save_file, is_tempfile, &cfile)) == 0) {
|
||||
/* Set the read filter to NULL. */
|
||||
cfile.rfcode = NULL;
|
||||
err = read_cap_file(&cfile);
|
||||
switch (read_cap_file(&cfile, &err)) {
|
||||
|
||||
case READ_SUCCESS:
|
||||
case READ_ERROR:
|
||||
/* Just because we got an error, that doesn't mean we were unable
|
||||
to read any of the file; we handle what we could get from the
|
||||
file. */
|
||||
break;
|
||||
|
||||
case READ_ABORTED:
|
||||
/* Exit by leaving the main loop, so that any quit functions
|
||||
we registered get called. */
|
||||
gtk_main_quit();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* We're not doing a capture any more, so we don't have a save
|
||||
|
@ -601,7 +615,21 @@ cap_file_input_cb(gpointer data, gint source, GdkInputCondition condition)
|
|||
|
||||
/* Read what remains of the capture file, and finish the capture.
|
||||
XXX - do something if this fails? */
|
||||
err = finish_tail_cap_file(cf);
|
||||
switch (finish_tail_cap_file(cf, &err)) {
|
||||
|
||||
case READ_SUCCESS:
|
||||
case READ_ERROR:
|
||||
/* Just because we got an error, that doesn't mean we were unable
|
||||
to read any of the file; we handle what we could get from the
|
||||
file. */
|
||||
break;
|
||||
|
||||
case READ_ABORTED:
|
||||
/* Exit by leaving the main loop, so that any quit functions
|
||||
we registered get called. */
|
||||
gtk_main_quit();
|
||||
return;
|
||||
}
|
||||
|
||||
/* We're not doing a capture any more, so we don't have a save
|
||||
file. */
|
||||
|
@ -634,7 +662,27 @@ cap_file_input_cb(gpointer data, gint source, GdkInputCondition condition)
|
|||
/* Read from the capture file the number of records the child told us
|
||||
it added.
|
||||
XXX - do something if this fails? */
|
||||
err = continue_tail_cap_file(cf, to_read);
|
||||
switch (continue_tail_cap_file(cf, to_read, &err)) {
|
||||
|
||||
case READ_SUCCESS:
|
||||
case READ_ERROR:
|
||||
/* Just because we got an error, that doesn't mean we were unable
|
||||
to read any of the file; we handle what we could get from the
|
||||
file.
|
||||
|
||||
XXX - abort on a read error? */
|
||||
break;
|
||||
|
||||
case READ_ABORTED:
|
||||
/* Kill the child capture process; the user wants to exit, and we
|
||||
shouldn't just leave it running. */
|
||||
#ifdef _WIN32
|
||||
/* XXX - kill it. */
|
||||
#else
|
||||
kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
/* restore pipe handler */
|
||||
#ifdef _WIN32
|
||||
|
@ -785,6 +833,12 @@ capture(void)
|
|||
goto error;
|
||||
}
|
||||
|
||||
/* XXX - capture SIGTERM and close the capture, in case we're on a
|
||||
Linux 2.0[.x] system and you have to explicitly close the capture
|
||||
stream in order to turn promiscuous mode off? We need to do that
|
||||
in other places as well - and I don't think that works all the
|
||||
time in any case, due to libpcap bugs. */
|
||||
|
||||
if (capture_child) {
|
||||
/* Well, we should be able to start capturing.
|
||||
|
||||
|
|
146
file.c
146
file.c
|
@ -1,7 +1,7 @@
|
|||
/* file.c
|
||||
* File I/O routines
|
||||
*
|
||||
* $Id: file.c,v 1.190 2000/06/27 04:35:44 guy Exp $
|
||||
* $Id: file.c,v 1.191 2000/06/27 07:13:13 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
|
@ -93,8 +93,7 @@ gboolean auto_scroll_live = FALSE;
|
|||
static guint32 firstsec, firstusec;
|
||||
static guint32 prevsec, prevusec;
|
||||
|
||||
static void wtap_dispatch_cb(u_char *, const struct wtap_pkthdr *, int,
|
||||
union wtap_pseudo_header *, const u_char *);
|
||||
static void read_packet(capture_file *cf, int offset, const u_char *buf);
|
||||
|
||||
static void set_selected_row(int row);
|
||||
|
||||
|
@ -143,6 +142,9 @@ open_cap_file(char *fname, gboolean is_tempfile, capture_file *cf)
|
|||
/* Initialize protocol-specific variables */
|
||||
init_all_protocols();
|
||||
|
||||
/* We're about to start reading the file. */
|
||||
cf->state = FILE_READ_IN_PROGRESS;
|
||||
|
||||
cf->wth = wth;
|
||||
cf->filed = fd;
|
||||
cf->f_len = cf_stat.st_size;
|
||||
|
@ -188,6 +190,9 @@ fail:
|
|||
void
|
||||
close_cap_file(capture_file *cf, void *w)
|
||||
{
|
||||
/* Die if we're in the middle of reading a file. */
|
||||
g_assert(cf->state != FILE_READ_IN_PROGRESS);
|
||||
|
||||
/* Destroy all popup packet windows, as they refer to packets in the
|
||||
capture file we're closing. */
|
||||
destroy_packet_wins();
|
||||
|
@ -240,6 +245,9 @@ close_cap_file(capture_file *cf, void *w)
|
|||
set_menus_for_captured_packets(FALSE);
|
||||
set_menus_for_selected_packet(FALSE);
|
||||
set_menus_for_capture_in_progress(FALSE);
|
||||
|
||||
/* We have no file open. */
|
||||
cf->state = FILE_CLOSED;
|
||||
}
|
||||
|
||||
/* Set the file name in the status line, in the name for the main window,
|
||||
|
@ -277,16 +285,15 @@ set_display_filename(capture_file *cf)
|
|||
g_free(win_name);
|
||||
}
|
||||
|
||||
int
|
||||
read_cap_file(capture_file *cf)
|
||||
read_status_t
|
||||
read_cap_file(capture_file *cf, int *err)
|
||||
{
|
||||
gchar *name_ptr, *load_msg, *load_fmt = " Loading: %s...";
|
||||
int success;
|
||||
int err;
|
||||
size_t msg_len;
|
||||
char *errmsg;
|
||||
char errmsg_errno[1024+1];
|
||||
gchar err_str[2048+1];
|
||||
int data_offset;
|
||||
|
||||
name_ptr = get_basename(cf->filename);
|
||||
|
||||
|
@ -308,17 +315,30 @@ read_cap_file(capture_file *cf)
|
|||
#endif
|
||||
|
||||
freeze_clist(cf);
|
||||
success = wtap_loop(cf->wth, 0, wtap_dispatch_cb, (u_char *) cf, &err);
|
||||
|
||||
while ((data_offset = wtap_read(cf->wth, err)) > 0) {
|
||||
if (cf->state == FILE_READ_ABORTED) {
|
||||
/* Well, the user decided to abort the read. Close the capture
|
||||
file, and return READ_ABORTED so our caller can do whatever is
|
||||
appropriate when that happens. */
|
||||
close_cap_file(cf, info_bar);
|
||||
return (READ_ABORTED);
|
||||
}
|
||||
read_packet(cf, data_offset, wtap_buf_ptr(cf->wth));
|
||||
}
|
||||
|
||||
/* We're done reading sequentially through the file. */
|
||||
cf->state = FILE_READ_DONE;
|
||||
|
||||
/* Close the sequential I/O side, to free up memory it requires. */
|
||||
wtap_sequential_close(cf->wth);
|
||||
|
||||
/* Set the file encapsulation type now; we don't know what it is until
|
||||
we've looked at all the packets, as we don't know until then whether
|
||||
there's more than one type (and thus whether it's
|
||||
WTAP_ENCAP_PER_PACKET). */
|
||||
|
||||
/* We're done reading sequentially through the file; close the
|
||||
sequential I/O side, to free up memory it requires. */
|
||||
wtap_sequential_close(cf->wth);
|
||||
|
||||
cf->lnk_t = wtap_file_encap(cf->wth);
|
||||
|
||||
cf->current_frame = cf->first_displayed;
|
||||
thaw_clist(cf);
|
||||
|
||||
|
@ -341,11 +361,11 @@ read_cap_file(capture_file *cf)
|
|||
if (cf->first_displayed != NULL)
|
||||
gtk_signal_emit_by_name(GTK_OBJECT(packet_list), "select_row", 0);
|
||||
|
||||
if (!success) {
|
||||
if (data_offset < 0) {
|
||||
/* Put up a message box noting that the read failed somewhere along
|
||||
the line. Don't throw out the stuff we managed to read, though,
|
||||
if any. */
|
||||
switch (err) {
|
||||
switch (*err) {
|
||||
|
||||
case WTAP_ERR_UNSUPPORTED_ENCAP:
|
||||
errmsg = "The capture file is for a network type that Ethereal doesn't support.";
|
||||
|
@ -367,15 +387,15 @@ read_cap_file(capture_file *cf)
|
|||
|
||||
default:
|
||||
sprintf(errmsg_errno, "An error occurred while reading the"
|
||||
" capture file: %s.", wtap_strerror(err));
|
||||
" capture file: %s.", wtap_strerror(*err));
|
||||
errmsg = errmsg_errno;
|
||||
break;
|
||||
}
|
||||
snprintf(err_str, sizeof err_str, errmsg);
|
||||
simple_dialog(ESD_TYPE_WARN, NULL, err_str);
|
||||
return (err);
|
||||
return (READ_ERROR);
|
||||
} else
|
||||
return (0);
|
||||
return (READ_SUCCESS);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBPCAP
|
||||
|
@ -412,14 +432,23 @@ start_tail_cap_file(char *fname, gboolean is_tempfile, capture_file *cf)
|
|||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
continue_tail_cap_file(capture_file *cf, int to_read)
|
||||
read_status_t
|
||||
continue_tail_cap_file(capture_file *cf, int to_read, int *err)
|
||||
{
|
||||
int err;
|
||||
int data_offset = 0;
|
||||
|
||||
gtk_clist_freeze(GTK_CLIST(packet_list));
|
||||
|
||||
wtap_loop(cf->wth, to_read, wtap_dispatch_cb, (u_char *) cf, &err);
|
||||
while (to_read != 0 && (data_offset = wtap_read(cf->wth, err)) > 0) {
|
||||
if (cf->state == FILE_READ_ABORTED) {
|
||||
/* Well, the user decided to exit Ethereal. Break out of the
|
||||
loop, and let the code below (which is called even if there
|
||||
aren't any packets left to read) exit. */
|
||||
break;
|
||||
}
|
||||
read_packet(cf, data_offset, wtap_buf_ptr(cf->wth));
|
||||
to_read--;
|
||||
}
|
||||
|
||||
gtk_clist_thaw(GTK_CLIST(packet_list));
|
||||
|
||||
|
@ -428,17 +457,48 @@ continue_tail_cap_file(capture_file *cf, int to_read)
|
|||
if (auto_scroll_live && cf->plist_end != NULL)
|
||||
gtk_clist_moveto(GTK_CLIST(packet_list),
|
||||
GTK_CLIST(packet_list)->rows - 1, -1, 1.0, 1.0);
|
||||
return err;
|
||||
|
||||
if (cf->state == FILE_READ_ABORTED) {
|
||||
/* Well, the user decided to exit Ethereal. Return READ_ABORTED
|
||||
so that our caller can kill off the capture child process;
|
||||
this will cause an EOF on the pipe from the child, so
|
||||
"finish_tail_cap_file()" will be called, and it will clean up
|
||||
and exit. */
|
||||
return READ_ABORTED;
|
||||
} else if (data_offset < 0) {
|
||||
/* We got an error reading the capture file.
|
||||
XXX - pop up a dialog box? */
|
||||
return (READ_ERROR);
|
||||
} else
|
||||
return (READ_SUCCESS);
|
||||
}
|
||||
|
||||
int
|
||||
finish_tail_cap_file(capture_file *cf)
|
||||
read_status_t
|
||||
finish_tail_cap_file(capture_file *cf, int *err)
|
||||
{
|
||||
int err;
|
||||
int data_offset;
|
||||
|
||||
gtk_clist_freeze(GTK_CLIST(packet_list));
|
||||
|
||||
wtap_loop(cf->wth, 0, wtap_dispatch_cb, (u_char *) cf, &err);
|
||||
while ((data_offset = wtap_read(cf->wth, err)) > 0) {
|
||||
if (cf->state == FILE_READ_ABORTED) {
|
||||
/* Well, the user decided to abort the read. Break out of the
|
||||
loop, and let the code below (which is called even if there
|
||||
aren't any packets left to read) exit. */
|
||||
break;
|
||||
}
|
||||
read_packet(cf, data_offset, wtap_buf_ptr(cf->wth));
|
||||
}
|
||||
|
||||
if (cf->state == FILE_READ_ABORTED) {
|
||||
/* Well, the user decided to abort the read. We're only called
|
||||
when the child capture process closes the pipe to us (meaning
|
||||
it's probably exited), so we can just close the capture
|
||||
file; we return READ_ABORTED so our caller can do whatever
|
||||
is appropriate when that happens. */
|
||||
close_cap_file(cf, info_bar);
|
||||
return READ_ABORTED;
|
||||
}
|
||||
|
||||
thaw_clist(cf);
|
||||
if (auto_scroll_live && cf->plist_end != NULL)
|
||||
|
@ -447,6 +507,9 @@ finish_tail_cap_file(capture_file *cf)
|
|||
gtk_clist_moveto(GTK_CLIST(packet_list),
|
||||
GTK_CLIST(packet_list)->rows - 1, -1, 1.0, 1.0);
|
||||
|
||||
/* We're done reading sequentially through the file. */
|
||||
cf->state = FILE_READ_DONE;
|
||||
|
||||
/* We're done reading sequentially through the file; close the
|
||||
sequential I/O side, to free up memory it requires. */
|
||||
wtap_sequential_close(cf->wth);
|
||||
|
@ -471,7 +534,12 @@ finish_tail_cap_file(capture_file *cf)
|
|||
set_menus_for_capture_file(TRUE);
|
||||
set_menus_for_unsaved_capture_file(!cf->user_saved);
|
||||
|
||||
return err;
|
||||
if (data_offset < 0) {
|
||||
/* We got an error reading the capture file.
|
||||
XXX - pop up a dialog box? */
|
||||
return (READ_ERROR);
|
||||
} else
|
||||
return (READ_SUCCESS);
|
||||
}
|
||||
#endif /* HAVE_LIBPCAP */
|
||||
|
||||
|
@ -634,11 +702,11 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
|
|||
}
|
||||
|
||||
static void
|
||||
wtap_dispatch_cb(u_char *user, const struct wtap_pkthdr *phdr, int offset,
|
||||
union wtap_pseudo_header *pseudo_header, const u_char *buf)
|
||||
read_packet(capture_file *cf, int offset, const u_char *buf)
|
||||
{
|
||||
const struct wtap_pkthdr *phdr = wtap_phdr(cf->wth);
|
||||
union wtap_pseudo_header *pseudo_header = wtap_pseudoheader(cf->wth);
|
||||
frame_data *fdata;
|
||||
capture_file *cf = (capture_file *) user;
|
||||
int passed;
|
||||
proto_tree *protocol_tree;
|
||||
frame_data *plist_end;
|
||||
|
@ -1600,7 +1668,21 @@ done:
|
|||
|
||||
if ((err = open_cap_file(fname, FALSE, cf)) == 0) {
|
||||
/* XXX - report errors if this fails? */
|
||||
err = read_cap_file(cf);
|
||||
switch (read_cap_file(cf, &err)) {
|
||||
|
||||
case READ_SUCCESS:
|
||||
case READ_ERROR:
|
||||
/* Just because we got an error, that doesn't mean we were unable
|
||||
to read any of the file; we handle what we could get from the
|
||||
file. */
|
||||
break;
|
||||
|
||||
case READ_ABORTED:
|
||||
/* Exit by leaving the main loop, so that any quit functions
|
||||
we registered get called. */
|
||||
gtk_main_quit();
|
||||
return 0;
|
||||
}
|
||||
set_menus_for_unsaved_capture_file(FALSE);
|
||||
}
|
||||
}
|
||||
|
|
25
file.h
25
file.h
|
@ -1,7 +1,7 @@
|
|||
/* file.h
|
||||
* Definitions for file structures and routines
|
||||
*
|
||||
* $Id: file.h,v 1.68 2000/05/19 23:06:07 gram Exp $
|
||||
* $Id: file.h,v 1.69 2000/06/27 07:13:14 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
|
@ -69,7 +69,16 @@
|
|||
|
||||
typedef struct bpf_program bpf_prog;
|
||||
|
||||
/* Current state of file. */
|
||||
typedef enum {
|
||||
FILE_CLOSED, /* No file open */
|
||||
FILE_READ_IN_PROGRESS, /* Reading a file we've opened */
|
||||
FILE_READ_ABORTED, /* Read aborted by user */
|
||||
FILE_READ_DONE /* Read completed */
|
||||
} file_state;
|
||||
|
||||
typedef struct _capture_file {
|
||||
file_state state; /* Current state of capture file */
|
||||
int filed; /* File descriptor of capture file */
|
||||
gchar *filename; /* Name of capture file */
|
||||
gboolean is_tempfile; /* Is capture file a temporary file? */
|
||||
|
@ -113,12 +122,20 @@ typedef struct _capture_file {
|
|||
FILE *print_fh; /* File we're printing to */
|
||||
} capture_file;
|
||||
|
||||
/* Return values from "read_cap_file()", "continue_tail_cap_file()",
|
||||
and "finish_tail_cap_file()". */
|
||||
typedef enum {
|
||||
READ_SUCCESS, /* read succeeded */
|
||||
READ_ERROR, /* read got an error */
|
||||
READ_ABORTED /* read aborted by user */
|
||||
} read_status_t;
|
||||
|
||||
int open_cap_file(char *, gboolean, capture_file *);
|
||||
void close_cap_file(capture_file *, void *);
|
||||
int read_cap_file(capture_file *);
|
||||
read_status_t read_cap_file(capture_file *, int *);
|
||||
int start_tail_cap_file(char *, gboolean, capture_file *);
|
||||
int continue_tail_cap_file(capture_file *, int);
|
||||
int finish_tail_cap_file(capture_file *);
|
||||
read_status_t continue_tail_cap_file(capture_file *, int, int *);
|
||||
read_status_t finish_tail_cap_file(capture_file *, int *);
|
||||
/* size_t read_frame_header(capture_file *); */
|
||||
int save_cap_file(char *, capture_file *, gboolean, guint);
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* file_dlg.c
|
||||
* Dialog boxes for handling files
|
||||
*
|
||||
* $Id: file_dlg.c,v 1.25 2000/06/27 04:36:00 guy Exp $
|
||||
* $Id: file_dlg.c,v 1.26 2000/06/27 07:13:25 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
|
@ -221,7 +221,22 @@ file_open_ok_cb(GtkWidget *w, GtkFileSelection *fs) {
|
|||
gtk_widget_hide(GTK_WIDGET (fs));
|
||||
gtk_widget_destroy(GTK_WIDGET (fs));
|
||||
|
||||
err = read_cap_file(&cfile);
|
||||
switch (read_cap_file(&cfile, &err)) {
|
||||
|
||||
case READ_SUCCESS:
|
||||
case READ_ERROR:
|
||||
/* Just because we got an error, that doesn't mean we were unable
|
||||
to read any of the file; we handle what we could get from the
|
||||
file. */
|
||||
break;
|
||||
|
||||
case READ_ABORTED:
|
||||
/* Exit by leaving the main loop, so that any quit functions
|
||||
we registered get called. */
|
||||
gtk_main_quit();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Save the name of the containing directory specified in the path name,
|
||||
if any; we can write over cf_name, which is a good thing, given that
|
||||
"get_dirname()" does write over its argument. */
|
||||
|
@ -484,6 +499,7 @@ file_reload_cmd_cb(GtkWidget *w, gpointer data) {
|
|||
GtkWidget *filter_te;
|
||||
gchar *filename;
|
||||
gboolean is_tempfile;
|
||||
int err;
|
||||
|
||||
filter_te = gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_TE_KEY);
|
||||
|
||||
|
@ -504,9 +520,23 @@ file_reload_cmd_cb(GtkWidget *w, gpointer data) {
|
|||
filename = strdup(cfile.filename);
|
||||
is_tempfile = cfile.is_tempfile;
|
||||
cfile.is_tempfile = FALSE;
|
||||
if (open_cap_file(filename, is_tempfile, &cfile) == 0)
|
||||
read_cap_file(&cfile);
|
||||
else {
|
||||
if (open_cap_file(filename, is_tempfile, &cfile) == 0) {
|
||||
switch (read_cap_file(&cfile, &err)) {
|
||||
|
||||
case READ_SUCCESS:
|
||||
case READ_ERROR:
|
||||
/* Just because we got an error, that doesn't mean we were unable
|
||||
to read any of the file; we handle what we could get from the
|
||||
file. */
|
||||
break;
|
||||
|
||||
case READ_ABORTED:
|
||||
/* Exit by leaving the main loop, so that any quit functions
|
||||
we registered get called. */
|
||||
gtk_main_quit();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
/* The open failed, so "cfile.is_tempfile" wasn't set to "is_tempfile".
|
||||
Instead, the file was left open, so we should restore "cfile.is_tempfile"
|
||||
ourselves.
|
||||
|
|
71
gtk/main.c
71
gtk/main.c
|
@ -1,6 +1,6 @@
|
|||
/* main.c
|
||||
*
|
||||
* $Id: main.c,v 1.124 2000/06/27 04:40:15 guy Exp $
|
||||
* $Id: main.c,v 1.125 2000/06/27 07:13:25 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
|
@ -1097,30 +1097,42 @@ file_quit_cmd_cb (GtkWidget *widget, gpointer data)
|
|||
"main_window_delete_event_cb()" should return its
|
||||
return value. */
|
||||
|
||||
/* Close any capture file we have open; on some OSes, you can't
|
||||
unlink a temporary capture file if you have it open.
|
||||
"close_cap_file()" will unlink it after closing it if
|
||||
it's a temporary file.
|
||||
/* Are we in the middle of reading a capture? */
|
||||
if (cfile.state == FILE_READ_IN_PROGRESS) {
|
||||
/* Yes, so we can't just close the file and quit, as
|
||||
that may yank the rug out from under the read in
|
||||
progress; instead, just set the state to
|
||||
"FILE_READ_ABORTED" and return - the code doing the read
|
||||
will check for that and, if it sees that, will clean
|
||||
up and quit. */
|
||||
cfile.state = FILE_READ_ABORTED;
|
||||
} else {
|
||||
/* Close any capture file we have open; on some OSes, you
|
||||
can't unlink a temporary capture file if you have it
|
||||
open.
|
||||
"close_cap_file()" will unlink it after closing it if
|
||||
it's a temporary file.
|
||||
|
||||
We do this here, rather than after the main loop returns,
|
||||
as, after the main loop returns, the main window may have
|
||||
been destroyed (if this is called due to a "destroy"
|
||||
even on the main window rather than due to the user
|
||||
selecting a menu item), and there may be a crash
|
||||
or other problem when "close_cap_file()" tries to
|
||||
clean up stuff in the main window.
|
||||
We do this here, rather than after the main loop returns,
|
||||
as, after the main loop returns, the main window may have
|
||||
been destroyed (if this is called due to a "destroy"
|
||||
even on the main window rather than due to the user
|
||||
selecting a menu item), and there may be a crash
|
||||
or other problem when "close_cap_file()" tries to
|
||||
clean up stuff in the main window.
|
||||
|
||||
XXX - is there a better place to put this?
|
||||
Or should we have a routine that *just* closes the
|
||||
capture file, and doesn't do anything with the UI,
|
||||
which we'd call here, and another routine that
|
||||
calls that routine and also cleans up the UI, which
|
||||
we'd call elsewhere? */
|
||||
close_cap_file(&cfile, info_bar);
|
||||
XXX - is there a better place to put this?
|
||||
Or should we have a routine that *just* closes the
|
||||
capture file, and doesn't do anything with the UI,
|
||||
which we'd call here, and another routine that
|
||||
calls that routine and also cleans up the UI, which
|
||||
we'd call elsewhere? */
|
||||
close_cap_file(&cfile, info_bar);
|
||||
|
||||
/* Exit by leaving the main loop, so that any quit functions
|
||||
we registered get called. */
|
||||
gtk_main_quit();
|
||||
/* Exit by leaving the main loop, so that any quit functions
|
||||
we registered get called. */
|
||||
gtk_main_quit();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1567,7 +1579,20 @@ main(int argc, char *argv[])
|
|||
capture file, and thus destroyed any previous read filter
|
||||
attached to "cf". */
|
||||
cfile.rfcode = rfcode;
|
||||
err = read_cap_file(&cfile);
|
||||
switch (read_cap_file(&cfile, &err)) {
|
||||
|
||||
case READ_SUCCESS:
|
||||
case READ_ERROR:
|
||||
/* Just because we got an error, that doesn't mean we were unable
|
||||
to read any of the file; we handle what we could get from the
|
||||
file. */
|
||||
break;
|
||||
|
||||
case READ_ABORTED:
|
||||
/* Exit now. */
|
||||
gtk_exit(0);
|
||||
break;
|
||||
}
|
||||
/* Save the name of the containing directory specified in the
|
||||
path name, if any; we can write over cf_name, which is a
|
||||
good thing, given that "get_dirname()" does write over its
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* wtap.c
|
||||
*
|
||||
* $Id: wtap.c,v 1.44 2000/05/25 09:00:23 guy Exp $
|
||||
* $Id: wtap.c,v 1.45 2000/06/27 07:13:42 guy Exp $
|
||||
*
|
||||
* Wiretap Library
|
||||
* Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org>
|
||||
|
@ -228,7 +228,22 @@ void wtap_close(wtap *wth)
|
|||
|
||||
int wtap_read(wtap *wth, int *err)
|
||||
{
|
||||
return wth -> subtype_read(wth, err);
|
||||
return wth->subtype_read(wth, err);
|
||||
}
|
||||
|
||||
struct wtap_pkthdr *wtap_phdr(wtap *wth)
|
||||
{
|
||||
return &wth->phdr;
|
||||
}
|
||||
|
||||
union wtap_pseudo_header *wtap_pseudoheader(wtap *wth)
|
||||
{
|
||||
return &wth->pseudo_header;
|
||||
}
|
||||
|
||||
guint8 *wtap_buf_ptr(wtap *wth)
|
||||
{
|
||||
return buffer_start_ptr(wth->frame_buffer);
|
||||
}
|
||||
|
||||
int wtap_loop(wtap *wth, int count, wtap_handler callback, u_char* user,
|
||||
|
@ -239,7 +254,7 @@ int wtap_loop(wtap *wth, int count, wtap_handler callback, u_char* user,
|
|||
/* Start be clearing error flag */
|
||||
*err = 0;
|
||||
|
||||
while ((data_offset = wth->subtype_read(wth, err)) > 0) {
|
||||
while ((data_offset = wtap_read(wth, err)) > 0) {
|
||||
callback(user, &wth->phdr, data_offset,
|
||||
&wth->pseudo_header, buffer_start_ptr(wth->frame_buffer));
|
||||
if (count > 0 && ++loop >= count)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* wtap.h
|
||||
*
|
||||
* $Id: wtap.h,v 1.73 2000/06/24 05:32:48 guy Exp $
|
||||
* $Id: wtap.h,v 1.74 2000/06/27 07:13:42 guy Exp $
|
||||
*
|
||||
* Wiretap Library
|
||||
* Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org>
|
||||
|
@ -271,6 +271,9 @@ typedef struct wtap_dumper wtap_dumper;
|
|||
struct wtap* wtap_open_offline(const char *filename, int *err, gboolean do_random);
|
||||
int wtap_loop(wtap *wth, int, wtap_handler, u_char*, int*);
|
||||
int wtap_read(wtap *wth, int *err);
|
||||
struct wtap_pkthdr *wtap_phdr(wtap *wth);
|
||||
union wtap_pseudo_header *wtap_pseudoheader(wtap *wth);
|
||||
guint8 *wtap_buf_ptr(wtap *wth);
|
||||
|
||||
FILE* wtap_file(wtap *wth);
|
||||
int wtap_fd(wtap *wth);
|
||||
|
|
Loading…
Reference in New Issue