aboutsummaryrefslogtreecommitdiffstats
path: root/capture_sync.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2006-03-05 03:14:16 +0000
committerGuy Harris <guy@alum.mit.edu>2006-03-05 03:14:16 +0000
commitcbe69401ccddfe65c2320f06592e868f980b101a (patch)
tree96501d3ec05c28eb6978a72e86c1e480b2293ab1 /capture_sync.c
parentfd39d0ebed46f2c127653e98940a6f9bb529effa (diff)
Pass two strings in capture child messages, so the child can send
primary and secondary error messages and let the parent worry about how to display them. This means dumpcap doesn't need stub routines for generating the formatting tags for the primary and secondary messages. Have a separate message for capture filter errors, so that the parent can check whether the capture filter looks like a display filter and report the appropriate message. This means that dumpcap doesn't need a stub routine for compiling display filters (a stub routine also means that Ethereal won't do the check for capture filters that look like display filters!). svn path=/trunk/; revision=17465
Diffstat (limited to 'capture_sync.c')
-rw-r--r--capture_sync.c89
1 files changed, 59 insertions, 30 deletions
diff --git a/capture_sync.c b/capture_sync.c
index 2a34f79375..45dc5ff7d4 100644
--- a/capture_sync.c
+++ b/capture_sync.c
@@ -120,25 +120,42 @@ static void sync_pipe_wait_for_child(capture_options *capture_opts);
#define SP_MAX_MSG_LEN 4096
- /* write a message to the recipient pipe in the standard format
+/* write a message to the recipient pipe in the standard format
(3 digit message length (excluding length and indicator field),
- 1 byte message indicator and the rest is the message) */
+ 1 byte message indicator and the rest is the message).
+ If msg is NULL, the message has only a length and indicator.
+ Otherwise, if secondary_msg isn't NULL, send both msg and
+ secondary_msg as null-terminated strings, otherwise just send
+ msg as a null-terminated string and follow it with an empty string. */
static void
-pipe_write_block(int pipe, char indicator, int len, const char *msg)
+pipe_write_block(int pipe, char indicator, const char *msg,
+ const char *secondary_msg)
{
guchar header[3+1]; /* indicator + 3-byte len */
int ret;
+ size_t len, secondary_len, total_len;
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "write %d enter", pipe);
+ len = 0;
+ secondary_len = 0;
+ total_len = 0;
+ if(msg != NULL) {
+ len = strlen(msg) + 1; /* include the terminating '\0' */
+ total_len = len;
+ if(secondary_msg == NULL)
+ secondary_msg = ""; /* default to an empty string */
+ secondary_len = strlen(secondary_msg) + 1;
+ total_len += secondary_len;
+ }
g_assert(indicator < '0' || indicator > '9');
- g_assert(len <= SP_MAX_MSG_LEN);
+ g_assert(total_len <= SP_MAX_MSG_LEN);
/* write header (indicator + 3-byte len) */
header[0] = indicator;
- header[1] = (len >> 16) & 0xFF;
- header[2] = (len >> 8) & 0xFF;
- header[3] = (len >> 0) & 0xFF;
+ header[1] = (total_len >> 16) & 0xFF;
+ header[2] = (total_len >> 8) & 0xFF;
+ header[3] = (total_len >> 0) & 0xFF;
ret = write(pipe, header, sizeof header);
if(ret == -1) {
@@ -150,14 +167,21 @@ pipe_write_block(int pipe, char indicator, int len, const char *msg)
/* write value (if we have one) */
if(len) {
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG,
- "write %d indicator: %c value len: %u msg: %s", pipe, indicator,
- len, msg);
+ "write %d indicator: %c value len: %lu msg: \"%s\" secondary len: %lu secondary msg: \"%s\"", pipe, indicator,
+ (unsigned long)len, msg, (unsigned long)secondary_len,
+ secondary_msg);
ret = write(pipe, msg, len);
if(ret == -1) {
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
"write %d value: error %s", pipe, strerror(errno));
return;
}
+ ret = write(pipe, msg, secondary_len);
+ if(ret == -1) {
+ g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
+ "write %d value: error %s", pipe, strerror(errno));
+ return;
+ }
} else {
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG,
"write %d indicator: %c no value", pipe, indicator);
@@ -169,11 +193,12 @@ pipe_write_block(int pipe, char indicator, int len, const char *msg)
#ifndef _WIN32
void
-sync_pipe_errmsg_to_parent(const char *errmsg)
+sync_pipe_errmsg_to_parent(const char *error_msg,
+ const char *secondary_error_msg)
{
- g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "sync_pipe_errmsg_to_parent: %s", errmsg);
+ g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "sync_pipe_errmsg_to_parent: %s", error_msg);
- pipe_write_block(1, SP_ERROR_MSG, strlen(errmsg)+1, errmsg);
+ pipe_write_block(1, SP_ERROR_MSG, error_msg, secondary_error_msg);
}
#endif
@@ -185,7 +210,7 @@ signal_pipe_capquit_to_child(capture_options *capture_opts)
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
- pipe_write_block(capture_opts->signal_pipe_write_fd, SP_QUIT, 0, NULL);
+ pipe_write_block(capture_opts->signal_pipe_write_fd, SP_QUIT, NULL, NULL);
}
#endif
@@ -602,7 +627,7 @@ sync_pipe_start(capture_options *capture_opts) {
execv(exename, argv);
g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
exename, strerror(errno));
- sync_pipe_errmsg_to_parent(errmsg);
+ sync_pipe_errmsg_to_parent(errmsg, NULL);
/* Exit with "_exit()", so that we don't close the connection
to the X server (and cause stuff buffered up by our parent but
@@ -694,21 +719,21 @@ sync_pipe_input_cb(gint source, gpointer user_data)
switch(indicator) {
case SP_FILE:
- if(!capture_input_new_file(capture_opts, buffer)) {
- g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
-
- /* We weren't able to open the new capture file; user has been
- alerted. Close the sync pipe. */
- eth_close(source);
-
- /* the child has send us a filename which we couldn't open.
- this probably means, the child is creating files faster than we can handle it.
- this should only be the case for very fast file switches
- we can't do much more than telling the child to stop
- (this is the "emergency brake" if user e.g. wants to switch files every second) */
- sync_pipe_stop(capture_opts);
- }
- break;
+ if(!capture_input_new_file(capture_opts, buffer)) {
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
+
+ /* We weren't able to open the new capture file; user has been
+ alerted. Close the sync pipe. */
+ eth_close(source);
+
+ /* the child has send us a filename which we couldn't open.
+ this probably means, the child is creating files faster than we can handle it.
+ this should only be the case for very fast file switches
+ we can't do much more than telling the child to stop
+ (this is the "emergency brake" if user e.g. wants to switch files every second) */
+ sync_pipe_stop(capture_opts);
+ }
+ break;
case SP_PACKET_COUNT:
nread = atoi(buffer);
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", nread);
@@ -718,11 +743,15 @@ sync_pipe_input_cb(gint source, gpointer user_data)
capture_input_error_message(capture_opts, buffer);
/* the capture child will close the sync_pipe, nothing to do for now */
break;
+ case SP_BAD_FILTER:
+ capture_input_cfilter_error_message(capture_opts, buffer);
+ /* the capture child will close the sync_pipe, nothing to do for now */
+ break;
case SP_DROPS:
capture_input_drops(capture_opts, atoi(buffer));
break;
default:
- g_assert_not_reached();
+ g_assert_not_reached();
}
return TRUE;