Properly introduce packet-pn.c as a helper
[obnox/wireshark/wip.git] / capture_loop.c
index 2cdb3649034ca5b33e6fbe72b01af9c35865725a..dfcecaa600b97c17aa4705633fcb6e747215cdf1 100644 (file)
@@ -231,8 +231,10 @@ cap_pipe_open_live(char *pipename, struct pcap_hdr *hdr, loop_data *ld,
 #ifndef _WIN32
   struct stat pipe_stat;
 #else
+#if 1
   char *pncopy, *pos;
   wchar_t *err_str;
+#endif
   HANDLE hPipe = NULL;
 #endif
   int          sel_ret;
@@ -293,13 +295,13 @@ cap_pipe_open_live(char *pipename, struct pcap_hdr *hdr, loop_data *ld,
       return -1;
     }
 #else /* _WIN32 */
-#if 0 /* Enable/disable Windows named pipes */
+#if 1 /* Enable/disable Windows named pipes */
 #define PIPE_STR "\\pipe\\"
     /* Under Windows, named pipes _must_ have the form
      * "\\<server>\pipe\<pipename>".  <server> may be "." for localhost.
      */
     pncopy = g_strdup(pipename);
-    if (strstr(pncopy, "\\\\") == pncopy) {
+    if ( (pos=strstr(pncopy, "\\\\")) == pncopy) {
       pos = strchr(pncopy + 3, '\\');
       if (pos && g_strncasecmp(pos, PIPE_STR, strlen(PIPE_STR)) != 0)
         pos = NULL;
@@ -361,6 +363,7 @@ cap_pipe_open_live(char *pipename, struct pcap_hdr *hdr, loop_data *ld,
 
     g_snprintf(errmsg, errmsgl,
 "The capture session could not be initiated.  Unable to open interface.");
+    ld->cap_pipe_err = PIPNEXIST;
     return -1;
 #endif /* Enable/disable Windows named pipes */
 #endif /* _WIN32 */
@@ -475,7 +478,7 @@ error:
 
 /* We read one record from the pipe, take care of byte order in the record
  * header, write the record to the capture file, and update capture statistics. */
-int
+static int
 cap_pipe_dispatch(loop_data *ld, guchar *data, char *errmsg, int errmsgl)
 {
   struct pcap_pkthdr phdr;
@@ -726,7 +729,7 @@ capture_loop_open_input(capture_options *capture_opts, loop_data *ld,
          libpcap_warn = "";
        g_snprintf(errmsg, errmsg_len,
          "The capture session could not be initiated (%s).", open_err_str);
-#ifdef _WIN32
+#ifndef _WIN32
        g_snprintf(secondary_errmsg, secondary_errmsg_len,
 "Please check to make sure you have sufficient permissions, and that you have\n"
 "the proper interface or pipe specified.%s", libpcap_warn);
@@ -797,14 +800,19 @@ static void capture_loop_close_input(loop_data *ld) {
   if (ld->cap_pipe_fd >= 0) {
     g_assert(ld->from_cap_pipe);
     eth_close(ld->cap_pipe_fd);
+    ld->cap_pipe_fd = 0;
   }
 
   /* if open, close the pcap "input file" */
   if(ld->pcap_h != NULL) {
+    g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "capture_loop_close_input: closing %p", ld->pcap_h);
     g_assert(!ld->from_cap_pipe);
     pcap_close(ld->pcap_h);
+    ld->pcap_h = NULL;
   }
 
+  ld->go = FALSE;
+
 #ifdef _WIN32
   /* Shut down windows sockets */
   WSACleanup();
@@ -932,7 +940,7 @@ gboolean capture_loop_close_output(capture_options *capture_opts, loop_data *ld,
 }
 
 /* dispatch incoming packets (pcap or capture pipe) */
-static int
+int
 capture_loop_dispatch(capture_options *capture_opts _U_, loop_data *ld,
                      char *errmsg, int errmsg_len) {
   int       inpkts;
@@ -984,7 +992,7 @@ capture_loop_dispatch(capture_options *capture_opts _U_, loop_data *ld,
     g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "capture_loop_dispatch: from pcap_dispatch with select");
 #endif
     if (ld->pcap_fd != -1) {
-      sel_ret = cap_pipe_select(fd, TRUE);
+      sel_ret = cap_pipe_select(ld->pcap_fd, TRUE);
       if (sel_ret > 0) {
         /*
          * "select()" says we can read from it without blocking; go for
@@ -1103,18 +1111,26 @@ capture_loop_open_output(capture_options *capture_opts, int *save_file_fd,
      * case the caller destroys it after we return.
      */
     capfile_name = g_strdup(capture_opts->save_file);
-    if (strcmp(capfile_name, "-") == 0) {
-      /* Write to the standard output. */
+
+    if (capture_opts->output_to_pipe == TRUE) { /* either "-" or named pipe */
       if (capture_opts->multi_files_on) {
-        /* ringbuffer is enabled; that doesn't work with standard output */
+        /* ringbuffer is enabled; that doesn't work with standard output or a named pipe */
         g_snprintf(errmsg, errmsg_len,
-           "Ring buffer requested, but capture is being written to the standard output.");
+           "Ring buffer requested, but capture is being written to standard output or to a named pipe.");
         g_free(capfile_name);
         return FALSE;
-      } else {
+      }
+      if (strcmp(capfile_name, "-") == 0) {
+        /* write to stdout */
         *save_file_fd = 1;
+#ifdef _WIN32
+        /* set output pipe to binary mode to avoid Windows text-mode processing (eg: for CR/LF)  */
+        _setmode(1, O_BINARY);
+#endif
       }
-    } else {
+    } /* if (...output_to_pipe ... */
+
+    else {
       if (capture_opts->multi_files_on) {
         /* ringbuffer is enabled */
         *save_file_fd = ringbuf_init(capfile_name,
@@ -1204,10 +1220,13 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
   gboolean    write_ok;
   gboolean    close_ok;
   gboolean    cfilter_error = FALSE;
-  char        errmsg[4096+1];
-  char        secondary_errmsg[4096+1];
+#define MSG_MAX_LENGTH 4096
+  char        errmsg[MSG_MAX_LENGTH+1];
+  char        secondary_errmsg[MSG_MAX_LENGTH+1];
   int         save_file_fd = -1;
 
+  *errmsg           = '\0';
+  *secondary_errmsg = '\0';
 
   /* init the loop data */
   ld.go                 = TRUE;
@@ -1265,7 +1284,6 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
   case INITFILTER_BAD_FILTER:
     cfilter_error = TRUE;
     g_snprintf(errmsg, sizeof(errmsg), "%s", pcap_geterr(ld.pcap_h));
-    *secondary_errmsg = '\0';
     goto error;
 
   case INITFILTER_OTHER_ERROR:
@@ -1279,13 +1297,11 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
      (temporary/specified name/ringbuffer) */
   if (capture_opts->saving_to_file) {
     if (!capture_loop_open_output(capture_opts, &save_file_fd, errmsg, sizeof(errmsg))) {
-      *secondary_errmsg = '\0';
       goto error;
     }
 
     /* set up to write to the already-opened capture output file/files */
     if (!capture_loop_init_output(capture_opts, save_file_fd, &ld, errmsg, sizeof(errmsg))) {
-      *secondary_errmsg = '\0';
       goto error;
     }
 
@@ -1579,10 +1595,10 @@ error:
 void capture_loop_stop(void)
 {
 #ifdef HAVE_PCAP_BREAKLOOP
-  pcap_breakloop(ld.pcap_h);
-#else
-  ld.go = FALSE;
+  if(ld.pcap_h != NULL)
+    pcap_breakloop(ld.pcap_h);
 #endif
+  ld.go = FALSE;
 }