summaryrefslogtreecommitdiff
path: root/capture.c
diff options
context:
space:
mode:
Diffstat (limited to 'capture.c')
-rw-r--r--capture.c596
1 files changed, 372 insertions, 224 deletions
diff --git a/capture.c b/capture.c
index 9ad3996107..79e8282c7f 100644
--- a/capture.c
+++ b/capture.c
@@ -1,7 +1,7 @@
/* capture.c
* Routines for packet capture windows
*
- * $Id: capture.c,v 1.67 1999/09/11 06:23:22 guy Exp $
+ * $Id: capture.c,v 1.68 1999/09/23 06:27:19 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -41,6 +41,7 @@
#include <gtk/gtk.h>
#include <stdlib.h>
#include <stdio.h>
+#include <ctype.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
@@ -97,7 +98,141 @@ typedef struct _loop_data {
} loop_data;
void
-capture(void) {
+do_capture(void)
+{
+ char tmpname[128+1];
+ char c;
+ int i;
+ guint byte_count;
+ char *msg;
+
+ /* Choose a random name for the capture buffer */
+ if (cf.save_file && !cf.user_saved) {
+ unlink(cf.save_file); /* silently ignore error */
+ g_free(cf.save_file);
+ }
+ cf.save_file_fd = create_tempfile(tmpname, sizeof tmpname, "ether");
+ if (cf.save_file_fd == -1) {
+ simple_dialog(ESD_TYPE_WARN, NULL,
+ "The file to which the capture would be saved (\"%s\")"
+ "could not be opened: %s.", tmpname, strerror(errno));
+ return;
+ }
+ cf.save_file = g_strdup(tmpname);
+ cf.user_saved = 0;
+
+ if( fork_mode ){ /* use fork() for capture */
+ int fork_child;
+ char ssnap[24];
+ char scount[24]; /* need a constant for len of numbers */
+ char save_file_fd[24];
+ int err;
+
+ sprintf(ssnap,"%d",cf.snap); /* in lieu of itoa */
+ sprintf(scount,"%d",cf.count);
+ sprintf(save_file_fd,"%d",cf.save_file_fd);
+ signal(SIGCHLD, SIG_IGN);
+ if (sync_mode) pipe(sync_pipe);
+ if((fork_child = fork()) == 0){
+ /* args: -k -- capture
+ * -i interface specification
+ * -w file to write
+ * -W file descriptor to write
+ * -c count to capture
+ * -Q quit after capture (forces -k)
+ * -s snaplen
+ * -S sync mode
+ * -m / -b fonts
+ * -f "filter expression"
+ */
+ if (sync_mode) {
+ close(1);
+ dup(sync_pipe[1]);
+ close(sync_pipe[0]);
+ execlp(ethereal_path, "ethereal", "-k", "-Q", "-i", cf.iface,
+ "-w", cf.save_file, "-W", save_file_fd,
+ "-c", scount, "-s", ssnap, "-S",
+ "-m", medium_font, "-b", bold_font,
+ (cf.cfilter == NULL)? 0 : "-f",
+ (cf.cfilter == NULL)? 0 : cf.cfilter,
+ (const char *)NULL);
+ }
+ else {
+ execlp(ethereal_path, "ethereal", "-k", "-Q", "-i", cf.iface,
+ "-w", cf.save_file, "-W", save_file_fd,
+ "-c", scount, "-s", ssnap,
+ "-m", medium_font, "-b", bold_font,
+ (cf.cfilter == NULL)? 0 : "-f",
+ (cf.cfilter == NULL)? 0 : cf.cfilter,
+ (const char *)NULL);
+ }
+ }
+ else {
+ cf.filename = cf.save_file;
+ if (sync_mode) {
+ close(sync_pipe[1]);
+
+ /* Read a byte count from "sync_pipe[0]", terminated with a
+ colon; if the count is 0, the child process created the
+ capture file and we should start reading from it, otherwise
+ the capture couldn't start and the count is a count of bytes
+ of error message, and we should display the message. */
+ byte_count = 0;
+ for (;;) {
+ i = read(sync_pipe[0], &c, 1);
+ if (i == 0) {
+ /* EOF - the child process died.
+ XXX - reap it and report the status. */
+ simple_dialog(ESD_TYPE_WARN, NULL, "Capture child process died");
+ return;
+ }
+ if (c == ';')
+ break;
+ if (!isdigit(c)) {
+ /* Child process handed us crap. */
+ simple_dialog(ESD_TYPE_WARN, NULL,
+ "Capture child process sent us a bad message");
+ return;
+ }
+ byte_count = byte_count*10 + c - '0';
+ }
+ if (byte_count == 0) {
+ /* Success. */
+ err = tail_cap_file(cf.save_file, &cf);
+ if (err != 0) {
+ simple_dialog(ESD_TYPE_WARN, NULL,
+ file_open_error_message(err, FALSE), cf.save_file);
+ }
+ } else {
+ /* Failure. */
+ msg = g_malloc(byte_count + 1);
+ if (msg == NULL) {
+ simple_dialog(ESD_TYPE_WARN, NULL,
+ "Capture child process failed, but its error message was too big.");
+ } else {
+ i = read(sync_pipe[0], msg, byte_count);
+ if (i < 0) {
+ simple_dialog(ESD_TYPE_WARN, NULL,
+ "Capture child process failed: Error %s reading its error message.",
+ strerror(errno));
+ } else if (i == 0) {
+ simple_dialog(ESD_TYPE_WARN, NULL,
+ "Capture child process failed: EOF reading its error message.");
+ } else
+ simple_dialog(ESD_TYPE_WARN, NULL, msg);
+ g_free(msg);
+ }
+ }
+ }
+ }
+ }
+ else
+ capture();
+}
+
+void
+capture(void)
+{
GtkWidget *cap_w, *main_vb, *count_lb, *tcp_lb, *udp_lb, *icmp_lb,
*ospf_lb, *gre_lb, *netbios_lb, *other_lb, *stop_bt;
pcap_t *pch;
@@ -106,8 +241,7 @@ capture(void) {
bpf_u_int32 netnum, netmask;
time_t upd_time, cur_time;
int err, inpkts;
- char *errmsg;
- char errmsg_errno[1024+1];
+ char errmsg[1024+1];
ld.go = TRUE;
ld.counts.total = 0;
@@ -127,250 +261,264 @@ capture(void) {
pch = pcap_open_live(cf.iface, cf.snap, 1, 250, err_str);
- if (pch) {
- ld.linktype = wtap_pcap_encap_to_wtap_encap(pcap_datalink(pch));
- if (ld.linktype == WTAP_ENCAP_UNKNOWN) {
- errmsg = "The network you're capturing from is of a type"
- " that Ethereal doesn't support.";
- goto fail;
+ if (pch == NULL) {
+ /* Well, we couldn't start the capture. */
+ if (!fork_mode) {
+ /* In fork mode, we shouldn't do any UI stuff until we pop up the
+ capture-progress window, and, since we couldn't start the
+ capture, we haven't popped it up. */
+ while (gtk_events_pending()) gtk_main_iteration();
+ }
+ snprintf(errmsg, sizeof errmsg,
+ "The capture session could not be initiated (%s).\n"
+ "Please check to make sure you have sufficient permissions, and that\n"
+ "you have the proper interface specified.", err_str);
+ goto fatal_error;
+ }
+
+ if (cf.cfilter) {
+ if (pcap_lookupnet (cf.iface, &netnum, &netmask, err_str) < 0) {
+ snprintf(errmsg, sizeof errmsg,
+ "Can't use filter: Couldn't obtain netmask info (%s).", err_str);
+ goto fatal_error;
+ }
+ if (pcap_compile(pch, &cf.fcode, cf.cfilter, 1, netmask) < 0) {
+ snprintf(errmsg, sizeof errmsg, "Unable to parse filter string (%s).",
+ pcap_geterr(pch));
+ goto fatal_error;
}
- ld.pdh = wtap_dump_fdopen(cf.save_file_fd, WTAP_FILE_PCAP,
+ if (pcap_setfilter(pch, &cf.fcode) < 0) {
+ snprintf(errmsg, sizeof errmsg, "Can't install filter (%s).",
+ pcap_geterr(pch));
+ goto fatal_error;
+ }
+ }
+
+ ld.linktype = wtap_pcap_encap_to_wtap_encap(pcap_datalink(pch));
+ if (ld.linktype == WTAP_ENCAP_UNKNOWN) {
+ strcpy(errmsg, "The network you're capturing from is of a type"
+ " that Ethereal doesn't support.");
+ goto fatal_error;
+ }
+ ld.pdh = wtap_dump_fdopen(cf.save_file_fd, WTAP_FILE_PCAP,
ld.linktype, pcap_snapshot(pch), &err);
- if (ld.pdh == NULL) { /* We have an error */
+ if (ld.pdh == NULL) { /* We have an error */
+ switch (err) {
+
+ case WTAP_ERR_CANT_OPEN:
+ strcpy(errmsg, "The file to which the capture would be saved"
+ " couldn't be created for some unknown reason.");
+ break;
+
+ case WTAP_ERR_SHORT_WRITE:
+ strcpy(errmsg, "A full header couldn't be written to the file"
+ " to which the capture would be saved.");
+ break;
+
+ default:
+ if (err < 0) {
+ sprintf(errmsg, "The file to which the capture would be"
+ " saved (\"%s\") could not be opened: Error %d.",
+ cf.save_file, err);
+ } else {
+ sprintf(errmsg, "The file to which the capture would be"
+ " saved (\"%s\") could not be opened: %s.",
+ cf.save_file, strerror(err));
+ }
+ break;
+ }
+ goto fatal_error;
+ }
+
+ if (sync_mode) {
+ /* Sync out the capture file, so the header makes it to the file
+ system, and send a "capture started successfully and capture
+ file created" message to our parent so that they'll open the
+ capture file and update its windows to indicate that we have
+ a live capture in progress. */
+ fflush(wtap_dump_file(ld.pdh));
+ write(1, "0;", 2);
+ }
+
+ cap_w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title(GTK_WINDOW(cap_w), "Ethereal: Capture / Playback");
+
+ /* Container for capture display widgets */
+ main_vb = gtk_vbox_new(FALSE, 1);
+ gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
+ gtk_container_add(GTK_CONTAINER(cap_w), main_vb);
+ gtk_widget_show(main_vb);
+
+ count_lb = gtk_label_new("Count: 0");
+ gtk_box_pack_start(GTK_BOX(main_vb), count_lb, FALSE, FALSE, 3);
+ gtk_widget_show(count_lb);
+
+ tcp_lb = gtk_label_new("TCP: 0 (0.0%)");
+ gtk_box_pack_start(GTK_BOX(main_vb), tcp_lb, FALSE, FALSE, 3);
+ gtk_widget_show(tcp_lb);
+
+ udp_lb = gtk_label_new("UDP: 0 (0.0%)");
+ gtk_box_pack_start(GTK_BOX(main_vb), udp_lb, FALSE, FALSE, 3);
+ gtk_widget_show(udp_lb);
+
+ icmp_lb = gtk_label_new("ICMP: 0 (0.0%)");
+ gtk_box_pack_start(GTK_BOX(main_vb), icmp_lb, FALSE, FALSE, 3);
+ gtk_widget_show(icmp_lb);
+
+ ospf_lb = gtk_label_new("OSPF: 0 (0.0%)");
+ gtk_box_pack_start(GTK_BOX(main_vb), ospf_lb, FALSE, FALSE, 3);
+ gtk_widget_show(ospf_lb);
+
+ gre_lb = gtk_label_new("GRE: 0 (0.0%)");
+ gtk_box_pack_start(GTK_BOX(main_vb), gre_lb, FALSE, FALSE, 3);
+ gtk_widget_show(gre_lb);
+
+ netbios_lb = gtk_label_new("NetBIOS: 0 (0.0%)");
+ gtk_box_pack_start(GTK_BOX(main_vb), netbios_lb, FALSE, FALSE, 3);
+ gtk_widget_show(netbios_lb);
+
+ other_lb = gtk_label_new("Other: 0 (0.0%)");
+ gtk_box_pack_start(GTK_BOX(main_vb), other_lb, FALSE, FALSE, 3);
+ gtk_widget_show(other_lb);
+
+ stop_bt = gtk_button_new_with_label ("Stop");
+ gtk_signal_connect(GTK_OBJECT(stop_bt), "clicked",
+ GTK_SIGNAL_FUNC(capture_stop_cb), (gpointer) &ld);
+ gtk_box_pack_end(GTK_BOX(main_vb), stop_bt, FALSE, FALSE, 3);
+ GTK_WIDGET_SET_FLAGS(stop_bt, GTK_CAN_DEFAULT);
+ gtk_widget_grab_default(stop_bt);
+ GTK_WIDGET_SET_FLAGS(stop_bt, GTK_CAN_DEFAULT);
+ gtk_widget_grab_default(stop_bt);
+ gtk_widget_show(stop_bt);
+
+ gtk_widget_show(cap_w);
+ gtk_grab_add(cap_w);
+
+ upd_time = time(NULL);
+ while (ld.go) {
+ while (gtk_events_pending()) gtk_main_iteration();
+ inpkts = pcap_dispatch(pch, 1, capture_pcap_cb, (u_char *) &ld);
+ if (inpkts > 0)
+ ld.sync_packets += inpkts;
+ /* Only update once a second so as not to overload slow displays */
+ cur_time = time(NULL);
+ if (cur_time > upd_time) {
+ upd_time = cur_time;
+
+ sprintf(label_str, "Count: %d", ld.counts.total);
+ gtk_label_set(GTK_LABEL(count_lb), label_str);
+
+ sprintf(label_str, "TCP: %d (%.1f%%)", ld.counts.tcp,
+ pct(ld.counts.tcp, ld.counts.total));
+ gtk_label_set(GTK_LABEL(tcp_lb), label_str);
+
+ sprintf(label_str, "UDP: %d (%.1f%%)", ld.counts.udp,
+ pct(ld.counts.udp, ld.counts.total));
+ gtk_label_set(GTK_LABEL(udp_lb), label_str);
+
+ sprintf(label_str, "ICMP: %d (%.1f%%)", ld.counts.icmp,
+ pct(ld.counts.icmp, ld.counts.total));
+ gtk_label_set(GTK_LABEL(icmp_lb), label_str);
+
+ sprintf(label_str, "OSPF: %d (%.1f%%)", ld.counts.ospf,
+ pct(ld.counts.ospf, ld.counts.total));
+ gtk_label_set(GTK_LABEL(ospf_lb), label_str);
+
+ sprintf(label_str, "GRE: %d (%.1f%%)", ld.counts.gre,
+ pct(ld.counts.gre, ld.counts.total));
+ gtk_label_set(GTK_LABEL(gre_lb), label_str);
+
+ sprintf(label_str, "NetBIOS: %d (%.1f%%)", ld.counts.netbios,
+ pct(ld.counts.netbios, ld.counts.total));
+ gtk_label_set(GTK_LABEL(netbios_lb), label_str);
+
+ sprintf(label_str, "Other: %d (%.1f%%)", ld.counts.other,
+ pct(ld.counts.other, ld.counts.total));
+ gtk_label_set(GTK_LABEL(other_lb), label_str);
+
+ /* do sync here, too */
+ fflush(wtap_dump_file(ld.pdh));
+ if (sync_mode && ld.sync_packets) {
+ char tmp[20];
+ sprintf(tmp, "%d*", ld.sync_packets);
+ write(1, tmp, strlen(tmp));
+ ld.sync_packets = 0;
+ }
+ }
+ }
+
+ if (ld.pdh) {
+ if (!wtap_dump_close(ld.pdh, &err)) {
switch (err) {
- case WTAP_ERR_CANT_OPEN:
- errmsg = "The file to which the capture would be saved"
- " couldn't be created for some unknown reason.";
+ case WTAP_ERR_CANT_CLOSE:
+ strcpy(errmsg, "The file to which the capture was being saved"
+ " couldn't be closed for some unknown reason.");
break;
case WTAP_ERR_SHORT_WRITE:
- errmsg = "A full header couldn't be written to the file"
- " to which the capture would be saved.";
+ strcpy(errmsg, "Not all the data could be written to the file"
+ " to which the capture was being saved.");
break;
default:
if (err < 0) {
- sprintf(errmsg_errno, "The file to which the capture would be"
- " saved (\"%%s\") could not be opened: Error %d.",
- err);
+ sprintf(errmsg, "The file to which the capture was being"
+ " saved (\"%s\") could not be closed: Error %d.",
+ cf.save_file, err);
} else {
- sprintf(errmsg_errno, "The file to which the capture would be"
- " saved (\"%%s\") could not be opened: %s.",
- strerror(err));
+ sprintf(errmsg, "The file to which the capture was being"
+ " saved (\"%s\") could not be closed: %s.",
+ cf.save_file, strerror(err));
}
- errmsg = errmsg_errno;
break;
}
-fail:
- snprintf(err_str, PCAP_ERRBUF_SIZE, errmsg, cf.save_file);
- simple_dialog(ESD_TYPE_WARN, NULL, err_str);
- pcap_close(pch);
- return;
- }
-
- if (cf.cfilter) {
- if (pcap_lookupnet (cf.iface, &netnum, &netmask, err_str) < 0) {
- simple_dialog(ESD_TYPE_WARN, NULL,
- "Can't use filter: Couldn't obtain netmask info (%s).", err_str);
- wtap_dump_close(ld.pdh, NULL);
- unlink(cf.save_file); /* silently ignore error */
- pcap_close(pch);
- return;
- } else if (pcap_compile(pch, &cf.fcode, cf.cfilter, 1, netmask) < 0) {
- simple_dialog(ESD_TYPE_WARN, NULL, "Unable to parse filter string (%s).",
- pcap_geterr(pch));
- wtap_dump_close(ld.pdh, NULL);
- unlink(cf.save_file); /* silently ignore error */
- pcap_close(pch);
- return;
- } else if (pcap_setfilter(pch, &cf.fcode) < 0) {
- simple_dialog(ESD_TYPE_WARN, NULL, "Can't install filter (%s).",
- pcap_geterr(pch));
- wtap_dump_close(ld.pdh, NULL);
- unlink(cf.save_file); /* silently ignore error */
- pcap_close(pch);
- return;
- }
- }
-
- if (sync_mode) {
- /* Sync out the capture file, so the header makes it to the file
- system, and signal our parent so that they'll open the capture
- file and update its windows to indicate that we have a live
- capture in progress. */
- fflush(wtap_dump_file(ld.pdh));
- kill(getppid(), SIGUSR2);
- }
-
- cap_w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title(GTK_WINDOW(cap_w), "Ethereal: Capture / Playback");
-
- /* Container for capture display widgets */
- main_vb = gtk_vbox_new(FALSE, 1);
- gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
- gtk_container_add(GTK_CONTAINER(cap_w), main_vb);
- gtk_widget_show(main_vb);
-
- count_lb = gtk_label_new("Count: 0");
- gtk_box_pack_start(GTK_BOX(main_vb), count_lb, FALSE, FALSE, 3);
- gtk_widget_show(count_lb);
-
- tcp_lb = gtk_label_new("TCP: 0 (0.0%)");
- gtk_box_pack_start(GTK_BOX(main_vb), tcp_lb, FALSE, FALSE, 3);
- gtk_widget_show(tcp_lb);
-
- udp_lb = gtk_label_new("UDP: 0 (0.0%)");
- gtk_box_pack_start(GTK_BOX(main_vb), udp_lb, FALSE, FALSE, 3);
- gtk_widget_show(udp_lb);
-
- icmp_lb = gtk_label_new("ICMP: 0 (0.0%)");
- gtk_box_pack_start(GTK_BOX(main_vb), icmp_lb, FALSE, FALSE, 3);
- gtk_widget_show(icmp_lb);
-
- ospf_lb = gtk_label_new("OSPF: 0 (0.0%)");
- gtk_box_pack_start(GTK_BOX(main_vb), ospf_lb, FALSE, FALSE, 3);
- gtk_widget_show(ospf_lb);
-
- gre_lb = gtk_label_new("GRE: 0 (0.0%)");
- gtk_box_pack_start(GTK_BOX(main_vb), gre_lb, FALSE, FALSE, 3);
- gtk_widget_show(gre_lb);
-
- netbios_lb = gtk_label_new("NetBIOS: 0 (0.0%)");
- gtk_box_pack_start(GTK_BOX(main_vb), netbios_lb, FALSE, FALSE, 3);
- gtk_widget_show(netbios_lb);
-
- other_lb = gtk_label_new("Other: 0 (0.0%)");
- gtk_box_pack_start(GTK_BOX(main_vb), other_lb, FALSE, FALSE, 3);
- gtk_widget_show(other_lb);
-
- stop_bt = gtk_button_new_with_label ("Stop");
- gtk_signal_connect(GTK_OBJECT(stop_bt), "clicked",
- GTK_SIGNAL_FUNC(capture_stop_cb), (gpointer) &ld);
- gtk_box_pack_end(GTK_BOX(main_vb), stop_bt, FALSE, FALSE, 3);
- GTK_WIDGET_SET_FLAGS(stop_bt, GTK_CAN_DEFAULT);
- gtk_widget_grab_default(stop_bt);
- GTK_WIDGET_SET_FLAGS(stop_bt, GTK_CAN_DEFAULT);
- gtk_widget_grab_default(stop_bt);
- gtk_widget_show(stop_bt);
-
- gtk_widget_show(cap_w);
- gtk_grab_add(cap_w);
-
- upd_time = time(NULL);
- while (ld.go) {
- while (gtk_events_pending()) gtk_main_iteration();
- inpkts = pcap_dispatch(pch, 1, capture_pcap_cb, (u_char *) &ld);
- if (inpkts > 0)
- ld.sync_packets += inpkts;
- /* Only update once a second so as not to overload slow displays */
- cur_time = time(NULL);
- if (cur_time > upd_time) {
-
- upd_time = cur_time;
-
- sprintf(label_str, "Count: %d", ld.counts.total);
- gtk_label_set(GTK_LABEL(count_lb), label_str);
-
- sprintf(label_str, "TCP: %d (%.1f%%)", ld.counts.tcp,
- pct(ld.counts.tcp, ld.counts.total));
- gtk_label_set(GTK_LABEL(tcp_lb), label_str);
-
- sprintf(label_str, "UDP: %d (%.1f%%)", ld.counts.udp,
- pct(ld.counts.udp, ld.counts.total));
- gtk_label_set(GTK_LABEL(udp_lb), label_str);
-
- sprintf(label_str, "ICMP: %d (%.1f%%)", ld.counts.icmp,
- pct(ld.counts.icmp, ld.counts.total));
- gtk_label_set(GTK_LABEL(icmp_lb), label_str);
-
- sprintf(label_str, "OSPF: %d (%.1f%%)", ld.counts.ospf,
- pct(ld.counts.ospf, ld.counts.total));
- gtk_label_set(GTK_LABEL(ospf_lb), label_str);
-
- sprintf(label_str, "GRE: %d (%.1f%%)", ld.counts.gre,
- pct(ld.counts.gre, ld.counts.total));
- gtk_label_set(GTK_LABEL(gre_lb), label_str);
-
- sprintf(label_str, "NetBIOS: %d (%.1f%%)", ld.counts.netbios,
- pct(ld.counts.netbios, ld.counts.total));
- gtk_label_set(GTK_LABEL(netbios_lb), label_str);
-
- sprintf(label_str, "Other: %d (%.1f%%)", ld.counts.other,
- pct(ld.counts.other, ld.counts.total));
- gtk_label_set(GTK_LABEL(other_lb), label_str);
-
- /* do sync here, too */
- fflush(wtap_dump_file(ld.pdh));
- if (sync_mode && ld.sync_packets) {
- char tmp[20];
- sprintf(tmp, "%d*", ld.sync_packets);
- write(1, tmp, strlen(tmp));
- ld.sync_packets = 0;
- }
- }
- }
-
- if (ld.pdh) {
- if (!wtap_dump_close(ld.pdh, &err)) {
- switch (err) {
-
- case WTAP_ERR_CANT_CLOSE:
- errmsg = "The file to which the capture was being saved"
- " couldn't be closed for some unknown reason.";
- break;
-
- case WTAP_ERR_SHORT_WRITE:
- errmsg = "Not all the data could be written to the file"
- " to which the capture was being saved.";
- break;
-
- default:
- if (err < 0) {
- sprintf(errmsg_errno, "The file to which the capture was being"
- " saved (\"%%s\") could not be closed: Error %d.",
- err);
- } else {
- sprintf(errmsg_errno, "The file to which the capture was being"
- " saved (\"%%s\") could not be closed: %s.",
- strerror(err));
- }
- errmsg = errmsg_errno;
- break;
- }
- snprintf(err_str, PCAP_ERRBUF_SIZE, errmsg, cf.save_file);
- simple_dialog(ESD_TYPE_WARN, NULL, err_str);
- }
+ goto error;
}
- pcap_close(pch);
-
- gtk_grab_remove(GTK_WIDGET(cap_w));
- gtk_widget_destroy(GTK_WIDGET(cap_w));
- } else {
- while (gtk_events_pending()) gtk_main_iteration();
- simple_dialog(ESD_TYPE_WARN, NULL,
- "The capture session could not be initiated (%s).\n"
- "Please check to make sure you have sufficient permissions, and that\n"
- "you have the proper interface specified.", err_str);
}
+ pcap_close(pch);
+
+ gtk_grab_remove(GTK_WIDGET(cap_w));
+ gtk_widget_destroy(GTK_WIDGET(cap_w));
- if( quit_after_cap ){
+ if (quit_after_cap) {
/* DON'T unlink the save file. Presumably someone wants it. */
gtk_exit(0);
}
- if (pch) {
- /* "pch" is non-NULL only if we successfully started a capture.
- If we haven't, there's no capture file to load. */
- if ((err = open_cap_file(cf.save_file, &cf)) == 0) {
- /* Set the read filter to NULL. */
- cf.rfcode = NULL;
- err = read_cap_file(&cf);
- set_menu_sensitivity("/File/Save", TRUE);
- set_menu_sensitivity("/File/Save As...", FALSE);
- }
+ if ((err = open_cap_file(cf.save_file, &cf)) == 0) {
+ /* Set the read filter to NULL. */
+ cf.rfcode = NULL;
+ err = read_cap_file(&cf);
+ set_menu_sensitivity("/File/Save", TRUE);
+ set_menu_sensitivity("/File/Save As...", FALSE);
+ }
+ return;
+
+fatal_error:
+ /* We couldn't even start the capture, so get rid of the capture
+ file. */
+ unlink(cf.save_file); /* silently ignore error */
+
+error:
+ if (sync_mode) {
+ /* Send the error message to our parent, so they can display a
+ dialog box containing it. */
+ int msglen = strlen(errmsg);
+ char lenbuf[10+1+1];
+ sprintf(lenbuf, "%u;", msglen);
+ write(1, lenbuf, strlen(lenbuf));
+ write(1, errmsg, msglen);
+ } else {
+ /* Display the dialog box ourselves; there's no parent. */
+ simple_dialog(ESD_TYPE_WARN, NULL, errmsg);
}
+ if (pch != NULL)
+ pcap_close(pch);
+
+ if (quit_after_cap)
+ gtk_exit(0);
}
static float