(some) redesign of capture data structures.
don't use global cfile at all but only an untpyed handle to call the cf_... functions in file.c move the save_file member from capture_file to capture_opts, as it's only used while capturing and while preparing it svn path=/trunk/; revision=13276
This commit is contained in:
parent
02f8788b4e
commit
dd71ad695f
30
capture.c
30
capture.c
|
@ -129,8 +129,8 @@ capture_open_output(capture_options *capture_opts, const char *save_file, gboole
|
|||
|
||||
/* close the old file */
|
||||
cf_close(&cfile);
|
||||
g_assert(cfile.save_file == NULL);
|
||||
cfile.save_file = capfile_name;
|
||||
g_assert(capture_opts->save_file == NULL);
|
||||
capture_opts->save_file = capfile_name;
|
||||
/* cfile.save_file is "g_free"ed later, which is equivalent to
|
||||
"g_free(capfile_name)". */
|
||||
|
||||
|
@ -193,21 +193,21 @@ normal_do_capture(capture_options *capture_opts, gboolean is_tempfile)
|
|||
if (capture_opts->multi_files_on) {
|
||||
ringbuf_free();
|
||||
} else {
|
||||
g_free(cfile.save_file);
|
||||
g_free(capture_opts->save_file);
|
||||
}
|
||||
cfile.save_file = NULL;
|
||||
capture_opts->save_file = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
/* Capture succeeded; attempt to read in the capture file. */
|
||||
if ((err = cf_open(cfile.save_file, is_tempfile, &cfile)) != 0) {
|
||||
if ((err = cf_open(capture_opts->save_file, is_tempfile, &cfile)) != 0) {
|
||||
/* We're not doing a capture any more, so we don't have a save
|
||||
file. */
|
||||
if (capture_opts->multi_files_on) {
|
||||
ringbuf_free();
|
||||
} else {
|
||||
g_free(cfile.save_file);
|
||||
g_free(capture_opts->save_file);
|
||||
}
|
||||
cfile.save_file = NULL;
|
||||
capture_opts->save_file = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -266,9 +266,9 @@ normal_do_capture(capture_options *capture_opts, gboolean is_tempfile)
|
|||
if (capture_opts->multi_files_on) {
|
||||
ringbuf_free();
|
||||
} else {
|
||||
g_free(cfile.save_file);
|
||||
g_free(capture_opts->save_file);
|
||||
}
|
||||
cfile.save_file = NULL;
|
||||
capture_opts->save_file = NULL;
|
||||
|
||||
/* if we didn't captured even a single packet, close the file again */
|
||||
if(cfile.count == 0) {
|
||||
|
@ -306,21 +306,21 @@ capture_start(capture_options *capture_opts, gboolean *stats_known, struct pcap_
|
|||
}
|
||||
|
||||
void
|
||||
capture_stop(gboolean sync_mode)
|
||||
capture_stop(capture_options *capture_opts)
|
||||
{
|
||||
|
||||
if (sync_mode) {
|
||||
sync_pipe_stop();
|
||||
if (capture_opts->sync_mode) {
|
||||
sync_pipe_stop(capture_opts);
|
||||
}
|
||||
|
||||
capture_loop_stop();
|
||||
}
|
||||
|
||||
void
|
||||
kill_capture_child(gboolean sync_mode)
|
||||
kill_capture_child(capture_options *capture_opts)
|
||||
{
|
||||
if (sync_mode) {
|
||||
sync_pipe_kill();
|
||||
if (capture_opts->sync_mode) {
|
||||
sync_pipe_kill(capture_opts);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
/** Capture options coming from user interface */
|
||||
typedef struct capture_options_tag {
|
||||
/* general */
|
||||
void *cf; /**< handle to cfile (note: untyped handle) */
|
||||
#ifdef _WIN32
|
||||
int buffer_size; /**< the capture buffer size (MB) */
|
||||
#endif
|
||||
|
@ -47,6 +48,7 @@ typedef struct capture_options_tag {
|
|||
int linktype; /**< Data link type to use, or -1 for
|
||||
"use default" */
|
||||
gboolean capture_child; /**< True if this is the child for "-S" */
|
||||
gchar *save_file; /**< File that user saved capture to */
|
||||
int save_file_fd; /**< File descriptor for saved file */
|
||||
|
||||
/* GUI related */
|
||||
|
@ -77,6 +79,9 @@ typedef struct capture_options_tag {
|
|||
gboolean has_autostop_duration; /**< TRUE if maximum capture duration
|
||||
is specified */
|
||||
gint32 autostop_duration; /**< Maximum capture duration */
|
||||
|
||||
/* internally used (don't touch from outside) */
|
||||
int fork_child; /**< If not -1, in parent, process ID of child */
|
||||
} capture_options;
|
||||
|
||||
|
||||
|
@ -90,10 +95,10 @@ extern gboolean do_capture(capture_options *capture_opts, const char *save_file)
|
|||
extern int capture_start(capture_options *capture_opts, gboolean *stats_known, struct pcap_stat *stats);
|
||||
|
||||
/** Stop a capture from a menu item. */
|
||||
extern void capture_stop(gboolean sync_mode);
|
||||
extern void capture_stop(capture_options *capture_opts);
|
||||
|
||||
/** Terminate the capture child cleanly when exiting. */
|
||||
extern void kill_capture_child(gboolean sync_mode);
|
||||
extern void kill_capture_child(capture_options *capture_opts);
|
||||
|
||||
/** Do the low-level work of a capture. */
|
||||
extern int capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct pcap_stat *stats);
|
||||
|
|
|
@ -822,12 +822,12 @@ static int capture_loop_open_wiretap_output(capture_options *capture_opts, loop_
|
|||
g_snprintf(errmsg, errmsg_len,
|
||||
"The file to which the capture would be"
|
||||
" saved (\"%s\") could not be opened: Error %d.",
|
||||
cfile.save_file, err);
|
||||
capture_opts->save_file, err);
|
||||
} else {
|
||||
g_snprintf(errmsg, errmsg_len,
|
||||
"The file to which the capture would be"
|
||||
" saved (\"%s\") could not be opened: %s.",
|
||||
cfile.save_file, strerror(err));
|
||||
capture_opts->save_file, strerror(err));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -840,7 +840,7 @@ static int capture_loop_open_wiretap_output(capture_options *capture_opts, loop_
|
|||
|
||||
static gboolean capture_loop_close_output(capture_options *capture_opts, loop_data *ld, int *err_close) {
|
||||
if (capture_opts->multi_files_on) {
|
||||
return ringbuf_wtap_dump_close(&cfile.save_file, err_close);
|
||||
return ringbuf_wtap_dump_close(&capture_opts->save_file, err_close);
|
||||
} else {
|
||||
return wtap_dump_close(ld->wtap_pdh, err_close);
|
||||
}
|
||||
|
@ -1106,7 +1106,7 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
|
|||
}
|
||||
|
||||
/* Switch to the next ringbuffer file */
|
||||
if (ringbuf_switch_file(&ld.wtap_pdh, &cfile.save_file, &capture_opts->save_file_fd, &ld.err)) {
|
||||
if (ringbuf_switch_file(&ld.wtap_pdh, &capture_opts->save_file, &capture_opts->save_file_fd, &ld.err)) {
|
||||
/* File switch succeeded: reset the conditions */
|
||||
cnd_reset(cnd_autostop_size);
|
||||
if (cnd_file_duration) {
|
||||
|
@ -1175,7 +1175,7 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
|
|||
}
|
||||
|
||||
/* Switch to the next ringbuffer file */
|
||||
if (ringbuf_switch_file(&ld.wtap_pdh, &cfile.save_file, &capture_opts->save_file_fd, &ld.err)) {
|
||||
if (ringbuf_switch_file(&ld.wtap_pdh, &capture_opts->save_file, &capture_opts->save_file_fd, &ld.err)) {
|
||||
/* file switch succeeded: reset the conditions */
|
||||
cnd_reset(cnd_file_duration);
|
||||
if(cnd_autostop_size)
|
||||
|
@ -1225,7 +1225,7 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
|
|||
if (ld.err == 0) {
|
||||
write_ok = TRUE;
|
||||
} else {
|
||||
capture_loop_get_errmsg(errmsg, sizeof(errmsg), cfile.save_file, ld.err,
|
||||
capture_loop_get_errmsg(errmsg, sizeof(errmsg), capture_opts->save_file, ld.err,
|
||||
FALSE);
|
||||
capture_loop_popup_errmsg(capture_opts, errmsg);
|
||||
write_ok = FALSE;
|
||||
|
@ -1237,7 +1237,7 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
|
|||
/* If we've displayed a message about a write error, there's no point
|
||||
in displaying another message about an error on close. */
|
||||
if (!close_ok && write_ok) {
|
||||
capture_loop_get_errmsg(errmsg, sizeof(errmsg), cfile.save_file, err_close,
|
||||
capture_loop_get_errmsg(errmsg, sizeof(errmsg), capture_opts->save_file, err_close,
|
||||
TRUE);
|
||||
capture_loop_popup_errmsg(capture_opts, errmsg);
|
||||
}
|
||||
|
@ -1287,10 +1287,10 @@ error:
|
|||
|
||||
/* We couldn't even start the capture, so get rid of the capture
|
||||
file. */
|
||||
unlink(cfile.save_file); /* silently ignore error */
|
||||
g_free(cfile.save_file);
|
||||
unlink(capture_opts->save_file); /* silently ignore error */
|
||||
g_free(capture_opts->save_file);
|
||||
}
|
||||
cfile.save_file = NULL;
|
||||
capture_opts->save_file = NULL;
|
||||
capture_loop_popup_errmsg(capture_opts, errmsg);
|
||||
|
||||
/* close the input file (pcap or cap_pipe) */
|
||||
|
|
|
@ -95,8 +95,6 @@
|
|||
# include <io.h>
|
||||
#endif
|
||||
|
||||
int fork_child = -1; /* If not -1, in parent, process ID of child */
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <process.h> /* For spawning child process */
|
||||
#endif
|
||||
|
@ -113,7 +111,7 @@ static char *sync_pipe_signame(int);
|
|||
|
||||
|
||||
static gboolean sync_pipe_input_cb(gint source, gpointer user_data);
|
||||
static void sync_pipe_wait_for_child(gboolean always_report);
|
||||
static void sync_pipe_wait_for_child(int fork_child, gboolean always_report);
|
||||
|
||||
/* Size of buffer to hold decimal representation of
|
||||
signed/unsigned 64-bit int */
|
||||
|
@ -233,7 +231,7 @@ sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile) {
|
|||
int sync_pipe[2]; /* pipes used to sync between instances */
|
||||
|
||||
|
||||
fork_child = -1;
|
||||
capture_opts->fork_child = -1;
|
||||
|
||||
/* Allocate the string pointer array with enough space for the
|
||||
terminating NULL pointer. */
|
||||
|
@ -248,7 +246,7 @@ sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile) {
|
|||
argv = sync_pipe_add_arg(argv, &argc, cfile.iface);
|
||||
|
||||
argv = sync_pipe_add_arg(argv, &argc, "-w");
|
||||
argv = sync_pipe_add_arg(argv, &argc, cfile.save_file);
|
||||
argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
|
||||
|
||||
argv = sync_pipe_add_arg(argv, &argc, "-W");
|
||||
sprintf(save_file_fd,"%d",capture_opts->save_file_fd); /* in lieu of itoa */
|
||||
|
@ -302,9 +300,9 @@ sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile) {
|
|||
if(_pipe(sync_pipe, 512, O_BINARY) < 0) {
|
||||
/* Couldn't create the pipe between parent and child. */
|
||||
error = errno;
|
||||
unlink(cfile.save_file);
|
||||
g_free(cfile.save_file);
|
||||
cfile.save_file = NULL;
|
||||
unlink(capture_opts->save_file);
|
||||
g_free(capture_opts->save_file);
|
||||
capture_opts->save_file = NULL;
|
||||
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create sync pipe: %s",
|
||||
strerror(error));
|
||||
return FALSE;
|
||||
|
@ -329,7 +327,7 @@ sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile) {
|
|||
}
|
||||
|
||||
/* Spawn process */
|
||||
fork_child = spawnvp(_P_NOWAIT, ethereal_path, argv);
|
||||
capture_opts->fork_child = spawnvp(_P_NOWAIT, ethereal_path, argv);
|
||||
g_free(fontstring);
|
||||
if (filterstring) {
|
||||
g_free(filterstring);
|
||||
|
@ -398,13 +396,13 @@ sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile) {
|
|||
it and reading the save file through Wiretap. */
|
||||
close(capture_opts->save_file_fd);
|
||||
|
||||
if (fork_child == -1) {
|
||||
if (capture_opts->fork_child == -1) {
|
||||
/* We couldn't even create the child process. */
|
||||
error = errno;
|
||||
close(sync_pipe[PIPE_READ]);
|
||||
unlink(cfile.save_file);
|
||||
g_free(cfile.save_file);
|
||||
cfile.save_file = NULL;
|
||||
unlink(capture_opts->save_file);
|
||||
g_free(capture_opts->save_file);
|
||||
capture_opts->save_file = NULL;
|
||||
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
|
||||
"Couldn't create child process: %s", strerror(error));
|
||||
return FALSE;
|
||||
|
@ -423,10 +421,10 @@ sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile) {
|
|||
Close the read side of the sync pipe, remove the capture file,
|
||||
and report the failure. */
|
||||
close(sync_pipe[PIPE_READ]);
|
||||
unlink(cfile.save_file);
|
||||
g_free(cfile.save_file);
|
||||
cfile.save_file = NULL;
|
||||
sync_pipe_wait_for_child(TRUE);
|
||||
unlink(capture_opts->save_file);
|
||||
g_free(capture_opts->save_file);
|
||||
capture_opts->save_file = NULL;
|
||||
sync_pipe_wait_for_child(capture_opts->fork_child, TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
if (c == SP_CAPSTART || c == SP_ERROR_MSG)
|
||||
|
@ -436,9 +434,9 @@ sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile) {
|
|||
Close the read side of the sync pipe, remove the capture file,
|
||||
and report the failure. */
|
||||
close(sync_pipe[PIPE_READ]);
|
||||
unlink(cfile.save_file);
|
||||
g_free(cfile.save_file);
|
||||
cfile.save_file = NULL;
|
||||
unlink(capture_opts->save_file);
|
||||
g_free(capture_opts->save_file);
|
||||
capture_opts->save_file = NULL;
|
||||
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
|
||||
"Capture child process sent us a bad message");
|
||||
return FALSE;
|
||||
|
@ -467,7 +465,7 @@ sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile) {
|
|||
} else if (i == 0) {
|
||||
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
|
||||
"Capture child process failed: EOF reading its error message.");
|
||||
sync_pipe_wait_for_child(FALSE);
|
||||
sync_pipe_wait_for_child(capture_opts->fork_child, FALSE);
|
||||
} else
|
||||
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, msg);
|
||||
g_free(msg);
|
||||
|
@ -477,16 +475,16 @@ sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile) {
|
|||
close(sync_pipe[PIPE_READ]);
|
||||
|
||||
/* Get rid of the save file - the capture never started. */
|
||||
unlink(cfile.save_file);
|
||||
g_free(cfile.save_file);
|
||||
cfile.save_file = NULL;
|
||||
unlink(capture_opts->save_file);
|
||||
g_free(capture_opts->save_file);
|
||||
capture_opts->save_file = NULL;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* The child process started a capture.
|
||||
Attempt to open the capture file and set up to read it. */
|
||||
err = cf_start_tail(cfile.save_file, is_tempfile, &cfile);
|
||||
err = cf_start_tail(capture_opts->save_file, is_tempfile, &cfile);
|
||||
if (err != 0) {
|
||||
/* We weren't able to open the capture file; user has been
|
||||
alerted. Close the sync pipe. */
|
||||
|
@ -495,15 +493,15 @@ sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile) {
|
|||
|
||||
/* Don't unlink the save file - leave it around, for debugging
|
||||
purposes. */
|
||||
g_free(cfile.save_file);
|
||||
cfile.save_file = NULL;
|
||||
g_free(capture_opts->save_file);
|
||||
capture_opts->save_file = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
/* We were able to open and set up to read the capture file;
|
||||
arrange that our callback be called whenever it's possible
|
||||
to read from the sync pipe, so that it's called when
|
||||
the child process wants to tell us something. */
|
||||
pipe_input_set_handler(sync_pipe[PIPE_READ], (gpointer) &cfile, &fork_child, sync_pipe_input_cb);
|
||||
pipe_input_set_handler(sync_pipe[PIPE_READ], (gpointer) capture_opts, &capture_opts->fork_child, sync_pipe_input_cb);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -515,7 +513,8 @@ sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile) {
|
|||
static gboolean
|
||||
sync_pipe_input_cb(gint source, gpointer user_data)
|
||||
{
|
||||
capture_file *cf = (capture_file *)user_data;
|
||||
capture_options *capture_opts = (capture_options *)user_data;
|
||||
gint fork_child = capture_opts->fork_child;
|
||||
#define BUFSIZE 4096
|
||||
char buffer[BUFSIZE+1], *p = buffer, *q = buffer, *msg, *r;
|
||||
int nread, msglen, chars_to_copy;
|
||||
|
@ -527,20 +526,20 @@ sync_pipe_input_cb(gint source, gpointer user_data)
|
|||
/* The child has closed the sync pipe, meaning it's not going to be
|
||||
capturing any more packets. Pick up its exit status, and
|
||||
complain if it did anything other than exit with status 0. */
|
||||
sync_pipe_wait_for_child(FALSE);
|
||||
sync_pipe_wait_for_child(fork_child, FALSE);
|
||||
|
||||
/* Read what remains of the capture file, and finish the capture.
|
||||
XXX - do something if this fails? */
|
||||
switch (cf_finish_tail(cf, &err)) {
|
||||
switch (cf_finish_tail(capture_opts->cf, &err)) {
|
||||
|
||||
case READ_SUCCESS:
|
||||
if(cf->count == 0) {
|
||||
if(cf_packet_count(capture_opts->cf) == 0) {
|
||||
simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
|
||||
"%sNo packets captured!%s\n\n"
|
||||
"As no data was captured, closing the %scapture file!",
|
||||
simple_dialog_primary_start(), simple_dialog_primary_end(),
|
||||
(cf->is_tempfile) ? "temporary " : "");
|
||||
cf_close(cf);
|
||||
cf_is_tempfile(capture_opts->cf) ? "temporary " : "");
|
||||
cf_close(capture_opts->cf);
|
||||
}
|
||||
break;
|
||||
case READ_ERROR:
|
||||
|
@ -558,8 +557,8 @@ sync_pipe_input_cb(gint source, gpointer user_data)
|
|||
|
||||
/* We're not doing a capture any more, so we don't have a save
|
||||
file. */
|
||||
g_free(cf->save_file);
|
||||
cf->save_file = NULL;
|
||||
g_free(capture_opts->save_file);
|
||||
capture_opts->save_file = NULL;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -576,8 +575,8 @@ sync_pipe_input_cb(gint source, gpointer user_data)
|
|||
nread--;
|
||||
break;
|
||||
case SP_DROPS :
|
||||
cf->drops_known = TRUE;
|
||||
cf->drops = atoi(p);
|
||||
cf_set_drops_known(capture_opts->cf, TRUE);
|
||||
cf_set_drops(capture_opts->cf, atoi(p));
|
||||
p = q + 1;
|
||||
q++;
|
||||
nread--;
|
||||
|
@ -622,7 +621,7 @@ sync_pipe_input_cb(gint source, gpointer user_data)
|
|||
/* Read from the capture file the number of records the child told us
|
||||
it added.
|
||||
XXX - do something if this fails? */
|
||||
switch (cf_continue_tail(cf, to_read, &err)) {
|
||||
switch (cf_continue_tail(capture_opts->cf, to_read, &err)) {
|
||||
|
||||
case READ_SUCCESS:
|
||||
case READ_ERROR:
|
||||
|
@ -636,7 +635,7 @@ sync_pipe_input_cb(gint source, gpointer user_data)
|
|||
case READ_ABORTED:
|
||||
/* Kill the child capture process; the user wants to exit, and we
|
||||
shouldn't just leave it running. */
|
||||
kill_capture_child(TRUE /* sync_mode */);
|
||||
kill_capture_child(capture_opts);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -646,7 +645,7 @@ sync_pipe_input_cb(gint source, gpointer user_data)
|
|||
|
||||
/* the child process is going down, wait until it's completely terminated */
|
||||
static void
|
||||
sync_pipe_wait_for_child(gboolean always_report)
|
||||
sync_pipe_wait_for_child(int fork_child, gboolean always_report)
|
||||
{
|
||||
int wstatus;
|
||||
|
||||
|
@ -789,11 +788,11 @@ sync_pipe_signame(int sig)
|
|||
|
||||
|
||||
void
|
||||
sync_pipe_stop(void)
|
||||
sync_pipe_stop(capture_options *capture_opts)
|
||||
{
|
||||
if (fork_child != -1) {
|
||||
if (capture_opts->fork_child != -1) {
|
||||
#ifndef _WIN32
|
||||
kill(fork_child, SIGUSR1);
|
||||
kill(capture_opts->fork_child, SIGUSR1);
|
||||
#else
|
||||
/* XXX: this is not the preferred method of closing a process!
|
||||
* the clean way would be getting the process id of the child process,
|
||||
|
@ -807,18 +806,18 @@ sync_pipe_stop(void)
|
|||
* running in the same console, I don't know if that is true for our case.
|
||||
* And this also will require to have the process id
|
||||
*/
|
||||
TerminateProcess((HANDLE) fork_child, 0);
|
||||
TerminateProcess((HANDLE) (capture_opts->fork_child), 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sync_pipe_kill(void)
|
||||
sync_pipe_kill(capture_options *capture_opts)
|
||||
{
|
||||
if (fork_child != -1)
|
||||
if (capture_opts->fork_child != -1)
|
||||
#ifndef _WIN32
|
||||
kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
|
||||
kill(capture_opts->fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
|
||||
#else
|
||||
/* XXX: this is not the preferred method of closing a process!
|
||||
* the clean way would be getting the process id of the child process,
|
||||
|
@ -832,7 +831,7 @@ sync_pipe_kill(void)
|
|||
* running in the same console, I don't know if that is true for our case.
|
||||
* And this also will require to have the process id
|
||||
*/
|
||||
TerminateProcess((HANDLE) fork_child, 0);
|
||||
TerminateProcess((HANDLE) (capture_opts->fork_child), 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -50,11 +50,11 @@ sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile);
|
|||
|
||||
/** User wants to stop capturing, gracefully close the capture child */
|
||||
extern void
|
||||
sync_pipe_stop(void);
|
||||
sync_pipe_stop(capture_options *capture_opts);
|
||||
|
||||
/** We want to stop the program, just kill the child as soon as possible */
|
||||
extern void
|
||||
sync_pipe_kill(void);
|
||||
sync_pipe_kill(capture_options *capture_opts);
|
||||
|
||||
|
||||
/** the child will immediately start capturing, notify the parent */
|
||||
|
|
1
cfile.c
1
cfile.c
|
@ -56,7 +56,6 @@ init_cap_file(capture_file *cf)
|
|||
cf->cfilter = g_strdup("");
|
||||
#endif
|
||||
cf->iface = NULL;
|
||||
cf->save_file = NULL;
|
||||
cf->has_snap = FALSE;
|
||||
cf->snap = WTAP_MAX_PACKET_SIZE;
|
||||
cf->count = 0;
|
||||
|
|
1
cfile.h
1
cfile.h
|
@ -61,7 +61,6 @@ typedef struct _capture_file {
|
|||
gboolean has_snap; /* TRUE if maximum capture packet length is known */
|
||||
int snap; /* Maximum captured packet length */
|
||||
gchar *iface; /* Interface */
|
||||
gchar *save_file; /* File that user saved capture to */
|
||||
wtap *wth; /* Wiretap session */
|
||||
dfilter_t *rfcode; /* Compiled read filter program */
|
||||
gchar *dfilter; /* Display filter string */
|
||||
|
|
26
file.c
26
file.c
|
@ -707,6 +707,32 @@ cf_get_display_name(capture_file *cf)
|
|||
return displayname;
|
||||
}
|
||||
|
||||
/* XXX - use a macro instead? */
|
||||
int
|
||||
cf_packet_count(capture_file *cf)
|
||||
{
|
||||
return cf->count;
|
||||
}
|
||||
|
||||
/* XXX - use a macro instead? */
|
||||
gboolean
|
||||
cf_is_tempfile(capture_file *cf)
|
||||
{
|
||||
return cf->is_tempfile;
|
||||
}
|
||||
|
||||
/* XXX - use a macro instead? */
|
||||
void cf_set_drops_known(capture_file *cf, gboolean drops_known)
|
||||
{
|
||||
cf->drops_known = drops_known;
|
||||
}
|
||||
|
||||
/* XXX - use a macro instead? */
|
||||
void cf_set_drops(capture_file *cf, guint32 drops)
|
||||
{
|
||||
cf->drops = drops;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
color_filter_t *colorf;
|
||||
epan_dissect_t *edt;
|
||||
|
|
4
file.h
4
file.h
|
@ -52,6 +52,10 @@ read_status_t cf_finish_tail(capture_file *, int *);
|
|||
/* size_t read_frame_header(capture_file *); */
|
||||
gboolean cf_save(char *fname, capture_file * cf, packet_range_t *range, guint save_format);
|
||||
const gchar *cf_get_display_name(capture_file *);
|
||||
int cf_packet_count(capture_file *cf);
|
||||
gboolean cf_is_tempfile(capture_file *cf);
|
||||
void cf_set_drops_known(capture_file *cf, gboolean drops_known);
|
||||
void cf_set_drops(capture_file *cf, guint32 drops);
|
||||
|
||||
gboolean
|
||||
cf_merge_files(const char *out_filename, int out_fd, int in_file_count,
|
||||
|
|
|
@ -123,7 +123,7 @@ capture_prep_interface_changed_cb(GtkWidget *entry, gpointer parent_w);
|
|||
void
|
||||
capture_stop_cb(GtkWidget *w _U_, gpointer d _U_)
|
||||
{
|
||||
capture_stop(capture_opts->sync_mode);
|
||||
capture_stop(capture_opts);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -75,7 +75,7 @@ pct(gint num, gint denom) {
|
|||
|
||||
static void
|
||||
capture_info_delete_cb(GtkWidget *w _U_, GdkEvent *event _U_, gpointer data _U_) {
|
||||
capture_stop(capture_opts->sync_mode);
|
||||
capture_stop(capture_opts);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -880,7 +880,7 @@ main_do_quit(void)
|
|||
|
||||
#ifdef HAVE_LIBPCAP
|
||||
/* Nuke any child capture in progress. */
|
||||
kill_capture_child(capture_opts->sync_mode);
|
||||
kill_capture_child(capture_opts);
|
||||
#endif
|
||||
|
||||
/* Are we in the middle of reading a capture? */
|
||||
|
@ -1847,6 +1847,7 @@ main(int argc, char *argv[])
|
|||
}
|
||||
#endif
|
||||
|
||||
capture_opts->cf = &cfile;
|
||||
#ifdef HAVE_LIBPCAP
|
||||
capture_opts->has_snaplen = FALSE;
|
||||
capture_opts->snaplen = MIN_PACKET_SIZE;
|
||||
|
|
153
tethereal.c
153
tethereal.c
|
@ -167,48 +167,9 @@ typedef struct _loop_data {
|
|||
|
||||
static loop_data ld;
|
||||
|
||||
static int capture(int);
|
||||
static void capture_pcap_cb(guchar *, const struct pcap_pkthdr *,
|
||||
const guchar *);
|
||||
static void report_counts(void);
|
||||
#ifdef _WIN32
|
||||
static BOOL WINAPI capture_cleanup(DWORD);
|
||||
#else /* _WIN32 */
|
||||
static void capture_cleanup(int);
|
||||
#ifdef SIGINFO
|
||||
static void report_counts_siginfo(int);
|
||||
#endif /* SIGINFO */
|
||||
#endif /* _WIN32 */
|
||||
#endif /* HAVE_LIBPCAP */
|
||||
|
||||
static int load_cap_file(capture_file *, int);
|
||||
static gboolean process_packet(capture_file *cf, wtap_dumper *pdh, long offset,
|
||||
const struct wtap_pkthdr *whdr, union wtap_pseudo_header *pseudo_header,
|
||||
const guchar *pd, int *err);
|
||||
static void show_capture_file_io_error(const char *, int, gboolean);
|
||||
static void show_print_file_io_error(int err);
|
||||
static gboolean write_preamble(capture_file *cf);
|
||||
static gboolean print_packet(capture_file *cf, epan_dissect_t *edt);
|
||||
static gboolean write_finale(void);
|
||||
static char *cf_open_error_message(int err, gchar *err_info,
|
||||
gboolean for_writing, int file_type);
|
||||
#ifdef HAVE_LIBPCAP
|
||||
#ifndef _WIN32
|
||||
static void adjust_header(loop_data *, struct pcap_hdr *, struct pcaprec_hdr *);
|
||||
static int pipe_open_live(char *, struct pcap_hdr *, loop_data *, char *, int);
|
||||
static int pipe_dispatch(int, loop_data *, struct pcap_hdr *, \
|
||||
struct pcaprec_modified_hdr *, guchar *, char *, int);
|
||||
#endif /* _WIN32 */
|
||||
#endif
|
||||
|
||||
static void open_failure_message(const char *filename, int err,
|
||||
gboolean for_writing);
|
||||
static void failure_message(const char *msg_format, va_list ap);
|
||||
static void read_failure_message(const char *filename, int err);
|
||||
|
||||
capture_file cfile;
|
||||
#ifdef HAVE_LIBPCAP
|
||||
typedef struct {
|
||||
gchar *save_file; /* File that user saved capture to */
|
||||
int snaplen; /* Maximum captured packet length */
|
||||
int promisc_mode; /* Capture in promiscuous mode */
|
||||
int autostop_count; /* Maximum packet count */
|
||||
|
@ -227,6 +188,7 @@ typedef struct {
|
|||
} capture_options;
|
||||
|
||||
static capture_options capture_opts = {
|
||||
"",
|
||||
WTAP_MAX_PACKET_SIZE, /* snapshot length - default is
|
||||
infinite, in effect */
|
||||
TRUE, /* promiscuous mode is the default */
|
||||
|
@ -254,6 +216,49 @@ static gboolean infoprint; /* if TRUE, print capture info after clearing infodel
|
|||
#endif /* SIGINFO */
|
||||
#endif /* HAVE_LIBPCAP */
|
||||
|
||||
|
||||
static int capture(int);
|
||||
static void capture_pcap_cb(guchar *, const struct pcap_pkthdr *,
|
||||
const guchar *);
|
||||
static void report_counts(void);
|
||||
#ifdef _WIN32
|
||||
static BOOL WINAPI capture_cleanup(DWORD);
|
||||
#else /* _WIN32 */
|
||||
static void capture_cleanup(int);
|
||||
#ifdef SIGINFO
|
||||
static void report_counts_siginfo(int);
|
||||
#endif /* SIGINFO */
|
||||
#endif /* _WIN32 */
|
||||
#endif /* HAVE_LIBPCAP */
|
||||
|
||||
static int load_cap_file(capture_file *, capture_options *capture_opts, int);
|
||||
static gboolean process_packet(capture_file *cf, wtap_dumper *pdh, long offset,
|
||||
const struct wtap_pkthdr *whdr, union wtap_pseudo_header *pseudo_header,
|
||||
const guchar *pd, int *err);
|
||||
static void show_capture_file_io_error(const char *, int, gboolean);
|
||||
static void show_print_file_io_error(int err);
|
||||
static gboolean write_preamble(capture_file *cf);
|
||||
static gboolean print_packet(capture_file *cf, epan_dissect_t *edt);
|
||||
static gboolean write_finale(void);
|
||||
static char *cf_open_error_message(int err, gchar *err_info,
|
||||
gboolean for_writing, int file_type);
|
||||
#ifdef HAVE_LIBPCAP
|
||||
#ifndef _WIN32
|
||||
static void adjust_header(loop_data *, struct pcap_hdr *, struct pcaprec_hdr *);
|
||||
static int pipe_open_live(char *, struct pcap_hdr *, loop_data *, char *, int);
|
||||
static int pipe_dispatch(int, loop_data *, struct pcap_hdr *, \
|
||||
struct pcaprec_modified_hdr *, guchar *, char *, int);
|
||||
#endif /* _WIN32 */
|
||||
#endif
|
||||
|
||||
static void open_failure_message(const char *filename, int err,
|
||||
gboolean for_writing);
|
||||
static void failure_message(const char *msg_format, va_list ap);
|
||||
static void read_failure_message(const char *filename, int err);
|
||||
|
||||
capture_file cfile;
|
||||
|
||||
|
||||
static void
|
||||
print_usage(gboolean print_ver)
|
||||
{
|
||||
|
@ -1238,7 +1243,7 @@ main(int argc, char *argv[])
|
|||
exit(0);
|
||||
break;
|
||||
case 'w': /* Write to capture file xxx */
|
||||
cfile.save_file = g_strdup(optarg);
|
||||
capture_opts.save_file = g_strdup(optarg);
|
||||
break;
|
||||
case 'V': /* Verbose */
|
||||
verbose = TRUE;
|
||||
|
@ -1317,12 +1322,12 @@ main(int argc, char *argv[])
|
|||
#ifdef HAVE_LIBPCAP
|
||||
ld.output_to_pipe = FALSE;
|
||||
#endif
|
||||
if (cfile.save_file != NULL) {
|
||||
if (capture_opts.save_file != NULL) {
|
||||
/* We're writing to a capture file. */
|
||||
if (strcmp(cfile.save_file, "-") == 0) {
|
||||
if (strcmp(capture_opts.save_file, "-") == 0) {
|
||||
/* Write to the standard output. */
|
||||
g_free(cfile.save_file);
|
||||
cfile.save_file = g_strdup("");
|
||||
g_free(capture_opts.save_file);
|
||||
capture_opts.save_file = g_strdup("");
|
||||
#ifdef HAVE_LIBPCAP
|
||||
/* XXX - should we check whether it's a pipe? It's arguably
|
||||
silly to do "-w - >output_file" rather than "-w output_file",
|
||||
|
@ -1333,7 +1338,7 @@ main(int argc, char *argv[])
|
|||
}
|
||||
#ifdef HAVE_LIBPCAP
|
||||
else {
|
||||
err = test_for_fifo(cfile.save_file);
|
||||
err = test_for_fifo(capture_opts.save_file);
|
||||
switch (err) {
|
||||
|
||||
case ENOENT: /* it doesn't exist, so we'll be creating it,
|
||||
|
@ -1406,7 +1411,7 @@ main(int argc, char *argv[])
|
|||
} else {
|
||||
/* If they didn't specify a "-w" flag, but specified a maximum capture
|
||||
file size, tell them that this doesn't work, and exit. */
|
||||
if (capture_opts.has_autostop_filesize && cfile.save_file == NULL) {
|
||||
if (capture_opts.has_autostop_filesize && capture_opts.save_file == NULL) {
|
||||
fprintf(stderr, "tethereal: Maximum capture file size specified, but "
|
||||
"capture isn't being saved to a file.\n");
|
||||
exit(1);
|
||||
|
@ -1420,7 +1425,7 @@ main(int argc, char *argv[])
|
|||
c) it makes no sense to enable the ring buffer if the maximum
|
||||
file size is set to "infinite";
|
||||
d) file must not be a pipe. */
|
||||
if (cfile.save_file == NULL) {
|
||||
if (capture_opts.save_file == NULL) {
|
||||
fprintf(stderr, "tethereal: Ring buffer requested, but "
|
||||
"capture isn't being saved to a file.\n");
|
||||
exit(1);
|
||||
|
@ -1578,7 +1583,7 @@ main(int argc, char *argv[])
|
|||
epan_cleanup();
|
||||
exit(2);
|
||||
}
|
||||
err = load_cap_file(&cfile, out_file_type);
|
||||
err = load_cap_file(&cfile, &capture_opts, out_file_type);
|
||||
if (err != 0) {
|
||||
epan_cleanup();
|
||||
exit(2);
|
||||
|
@ -1869,7 +1874,7 @@ capture(int out_file_type)
|
|||
file_snaplen = pcap_snapshot(ld.pch);
|
||||
}
|
||||
ld.linktype = wtap_pcap_encap_to_wtap_encap(pcap_encap);
|
||||
if (cfile.save_file != NULL) {
|
||||
if (capture_opts.save_file != NULL) {
|
||||
/* Set up to write to the capture file. */
|
||||
if (ld.linktype == WTAP_ENCAP_UNKNOWN) {
|
||||
strcpy(errmsg, "The network you're capturing from is of a type"
|
||||
|
@ -1877,7 +1882,7 @@ capture(int out_file_type)
|
|||
goto error;
|
||||
}
|
||||
if (capture_opts.ringbuffer_on) {
|
||||
save_file_fd = ringbuf_init(cfile.save_file,
|
||||
save_file_fd = ringbuf_init(capture_opts.save_file,
|
||||
capture_opts.ringbuffer_num_files);
|
||||
if (save_file_fd != -1) {
|
||||
ld.pdh = ringbuf_init_wtap_dump_fdopen(out_file_type, ld.linktype,
|
||||
|
@ -1887,14 +1892,14 @@ capture(int out_file_type)
|
|||
ld.pdh = NULL;
|
||||
}
|
||||
} else {
|
||||
ld.pdh = wtap_dump_open(cfile.save_file, out_file_type,
|
||||
ld.pdh = wtap_dump_open(capture_opts.save_file, out_file_type,
|
||||
ld.linktype, file_snaplen, &err);
|
||||
}
|
||||
|
||||
if (ld.pdh == NULL) {
|
||||
snprintf(errmsg, sizeof errmsg,
|
||||
cf_open_error_message(err, NULL, TRUE, out_file_type),
|
||||
*cfile.save_file == '\0' ? "stdout" : cfile.save_file);
|
||||
*capture_opts.save_file == '\0' ? "stdout" : capture_opts.save_file);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
@ -2035,7 +2040,7 @@ capture(int out_file_type)
|
|||
its maximum size. */
|
||||
if (capture_opts.ringbuffer_on) {
|
||||
/* Switch to the next ringbuffer file */
|
||||
if (ringbuf_switch_file(&ld.pdh, &cfile.save_file, &save_file_fd, &loop_err)) {
|
||||
if (ringbuf_switch_file(&ld.pdh, &capture_opts.save_file, &save_file_fd, &loop_err)) {
|
||||
/* File switch succeeded: reset the condition */
|
||||
cnd_reset(cnd_stop_capturesize);
|
||||
if (cnd_ring_timeout) {
|
||||
|
@ -2071,7 +2076,7 @@ capture(int out_file_type)
|
|||
if (cnd_ring_timeout != NULL)
|
||||
cnd_delete(cnd_ring_timeout);
|
||||
|
||||
if ((cfile.save_file != NULL) && !quiet) {
|
||||
if ((capture_opts.save_file != NULL) && !quiet) {
|
||||
/* We're saving to a file, which means we're printing packet counts
|
||||
to stderr if we are not running silent and deep.
|
||||
Send a newline so that we move to the line after the packet count. */
|
||||
|
@ -2097,21 +2102,21 @@ capture(int out_file_type)
|
|||
if (volatile_err == 0)
|
||||
write_err = FALSE;
|
||||
else {
|
||||
show_capture_file_io_error(cfile.save_file, volatile_err, FALSE);
|
||||
show_capture_file_io_error(capture_opts.save_file, volatile_err, FALSE);
|
||||
write_err = TRUE;
|
||||
}
|
||||
|
||||
if (cfile.save_file != NULL) {
|
||||
if (capture_opts.save_file != NULL) {
|
||||
/* We're saving to a file or files; close all files. */
|
||||
if (capture_opts.ringbuffer_on) {
|
||||
dump_ok = ringbuf_wtap_dump_close(&cfile.save_file, &err);
|
||||
dump_ok = ringbuf_wtap_dump_close(&capture_opts.save_file, &err);
|
||||
} else {
|
||||
dump_ok = wtap_dump_close(ld.pdh, &err);
|
||||
}
|
||||
/* If we've displayed a message about a write error, there's no point
|
||||
in displaying another message about an error on close. */
|
||||
if (!dump_ok && !write_err)
|
||||
show_capture_file_io_error(cfile.save_file, err, TRUE);
|
||||
show_capture_file_io_error(capture_opts.save_file, err, TRUE);
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
|
@ -2143,8 +2148,8 @@ error:
|
|||
if (capture_opts.ringbuffer_on) {
|
||||
ringbuf_error_cleanup();
|
||||
}
|
||||
g_free(cfile.save_file);
|
||||
cfile.save_file = NULL;
|
||||
g_free(capture_opts.save_file);
|
||||
capture_opts.save_file = NULL;
|
||||
fprintf(stderr, "tethereal: %s\n", errmsg);
|
||||
#ifndef _WIN32
|
||||
if (ld.from_pipe) {
|
||||
|
@ -2195,7 +2200,7 @@ capture_pcap_cb(guchar *user, const struct pcap_pkthdr *phdr,
|
|||
*/
|
||||
if (cnd_ring_timeout != NULL && cnd_eval(cnd_ring_timeout)) {
|
||||
/* time elapsed for this ring file, switch to the next */
|
||||
if (ringbuf_switch_file(&ldat->pdh, &cfile.save_file, &save_file_fd, &loop_err)) {
|
||||
if (ringbuf_switch_file(&ldat->pdh, &capture_opts.save_file, &save_file_fd, &loop_err)) {
|
||||
/* File switch succeeded: reset the condition */
|
||||
cnd_reset(cnd_ring_timeout);
|
||||
} else {
|
||||
|
@ -2212,7 +2217,7 @@ capture_pcap_cb(guchar *user, const struct pcap_pkthdr *phdr,
|
|||
a count of packets captured; move to the line after the count. */
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
show_capture_file_io_error(cfile.save_file, err, FALSE);
|
||||
show_capture_file_io_error(capture_opts.save_file, err, FALSE);
|
||||
pcap_close(ldat->pch);
|
||||
wtap_dump_close(ldat->pdh, &err);
|
||||
exit(2);
|
||||
|
@ -2311,7 +2316,7 @@ report_counts_siginfo(int signum _U_)
|
|||
#endif /* HAVE_LIBPCAP */
|
||||
|
||||
static int
|
||||
load_cap_file(capture_file *cf, int out_file_type)
|
||||
load_cap_file(capture_file *cf, capture_options *capture_opts, int out_file_type)
|
||||
{
|
||||
gint linktype;
|
||||
int snapshot_length;
|
||||
|
@ -2321,14 +2326,14 @@ load_cap_file(capture_file *cf, int out_file_type)
|
|||
long data_offset;
|
||||
|
||||
linktype = wtap_file_encap(cf->wth);
|
||||
if (cf->save_file != NULL) {
|
||||
if (capture_opts->save_file != NULL) {
|
||||
/* Set up to write to the capture file. */
|
||||
snapshot_length = wtap_snapshot_length(cf->wth);
|
||||
if (snapshot_length == 0) {
|
||||
/* Snapshot length of input file not known. */
|
||||
snapshot_length = WTAP_MAX_PACKET_SIZE;
|
||||
}
|
||||
pdh = wtap_dump_open(cf->save_file, out_file_type,
|
||||
pdh = wtap_dump_open(capture_opts->save_file, out_file_type,
|
||||
linktype, snapshot_length, &err);
|
||||
|
||||
if (pdh == NULL) {
|
||||
|
@ -2351,19 +2356,19 @@ load_cap_file(capture_file *cf, int out_file_type)
|
|||
fprintf(stderr,
|
||||
"tethereal: The file \"%s\" couldn't be created for some "
|
||||
"unknown reason.\n",
|
||||
*cf->save_file == '\0' ? "stdout" : cf->save_file);
|
||||
*capture_opts->save_file == '\0' ? "stdout" : capture_opts->save_file);
|
||||
break;
|
||||
|
||||
case WTAP_ERR_SHORT_WRITE:
|
||||
fprintf(stderr,
|
||||
"tethereal: A full header couldn't be written to the file \"%s\".\n",
|
||||
*cf->save_file == '\0' ? "stdout" : cf->save_file);
|
||||
*capture_opts->save_file == '\0' ? "stdout" : capture_opts->save_file);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr,
|
||||
"tethereal: The file \"%s\" could not be created: %s\n.",
|
||||
*cf->save_file == '\0' ? "stdout" : cf->save_file,
|
||||
*capture_opts->save_file == '\0' ? "stdout" : capture_opts->save_file,
|
||||
wtap_strerror(err));
|
||||
break;
|
||||
}
|
||||
|
@ -2384,7 +2389,7 @@ load_cap_file(capture_file *cf, int out_file_type)
|
|||
wtap_pseudoheader(cf->wth), wtap_buf_ptr(cf->wth),
|
||||
&err)) {
|
||||
/* Error writing to a capture file */
|
||||
show_capture_file_io_error(cf->save_file, err, FALSE);
|
||||
show_capture_file_io_error(capture_opts->save_file, err, FALSE);
|
||||
wtap_dump_close(pdh, &err);
|
||||
exit(2);
|
||||
}
|
||||
|
@ -2423,16 +2428,16 @@ load_cap_file(capture_file *cf, int out_file_type)
|
|||
cf->filename, wtap_strerror(err));
|
||||
break;
|
||||
}
|
||||
if (cf->save_file != NULL) {
|
||||
if (capture_opts->save_file != NULL) {
|
||||
/* Now close the capture file. */
|
||||
if (!wtap_dump_close(pdh, &err))
|
||||
show_capture_file_io_error(cfile.save_file, err, TRUE);
|
||||
show_capture_file_io_error(capture_opts->save_file, err, TRUE);
|
||||
}
|
||||
} else {
|
||||
if (cf->save_file != NULL) {
|
||||
if (capture_opts->save_file != NULL) {
|
||||
/* Now close the capture file. */
|
||||
if (!wtap_dump_close(pdh, &err))
|
||||
show_capture_file_io_error(cfile.save_file, err, TRUE);
|
||||
show_capture_file_io_error(capture_opts->save_file, err, TRUE);
|
||||
} else {
|
||||
if (print_packet_info) {
|
||||
if (!write_finale()) {
|
||||
|
|
Loading…
Reference in New Issue