first steps towards a separated capture tool, working title "dumpcap"
[obnox/wireshark/wip.git] / dumpcap.c
1 /* dumpcap.c
2  *
3  * $Id$
4  *
5  * Ethereal - Network traffic analyzer
6  * By Gerald Combs <gerald@ethereal.com>
7  * Copyright 1998 Gerald Combs
8  *
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include <glib.h>
30
31 #include <string.h>
32 #include <ctype.h>
33
34 #ifdef HAVE_UNISTD_H
35 #include <unistd.h>
36 #endif
37
38 #ifdef NEED_STRERROR_H
39 #include "strerror.h"
40 #endif
41
42 #ifdef NEED_GETOPT_H
43 #include "getopt.h"
44 #endif
45
46 #ifdef _WIN32 /* Needed for console I/O */
47 #include <fcntl.h>
48 #include <conio.h>
49 #endif
50
51 #include <epan/packet.h>
52 #include <epan/strutil.h>
53
54 #include "file.h"
55 #include "summary.h"
56 #include "filters.h"
57 #include "color.h"
58 #include "simple_dialog.h"
59 #include "ringbuffer.h"
60 #include "../ui_util.h"
61 #include "util.h"
62 #include "clopts_common.h"
63 #include "cmdarg_err.h"
64 #include "version_info.h"
65
66 #include <pcap.h>
67 #include "pcap-util.h"
68
69 #ifdef _WIN32
70 #include "capture-wpcap.h"
71 #include "capture_wpcap_packet.h"
72 #endif
73
74 #include "log.h"
75 #include "file_util.h"
76
77
78
79 capture_file cfile;
80 GString *comp_info_str, *runtime_info_str;
81 gchar       *ethereal_path = NULL;
82
83 #ifdef _WIN32
84 static gboolean has_console = TRUE;     /* TRUE if app has console */
85 static void create_console(void);
86 static void destroy_console(void);
87 #endif
88 static void
89 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
90                     const char *message, gpointer user_data _U_);
91
92 capture_options global_capture_opts;
93 capture_options *capture_opts = &global_capture_opts;
94
95
96
97 static void
98 print_usage(gboolean print_ver) {
99
100   FILE *output;
101
102 #ifdef _WIN32
103   create_console();
104 #endif
105
106   if (print_ver) {
107     output = stdout;
108     fprintf(output, "This is "PACKAGE " " VERSION "%s"
109         "\n (C) 1998-2005 Gerald Combs <gerald@ethereal.com>"
110         "\n\n%s\n\n%s\n",
111         svnversion, comp_info_str->str, runtime_info_str->str);
112   } else {
113     output = stderr;
114   }
115   fprintf(output, "\n%s [ -vh ] [ -klLnpQS ] [ -a <capture autostop condition> ] ...\n", PACKAGE);        
116   fprintf(output, "\t[ -b <capture ring buffer option> ] ...\n");
117 #ifdef _WIN32
118   fprintf(output, "\t[ -B <capture buffer size> ]\n");
119 #endif
120   fprintf(output, "\t[ -c <capture packet count> ] [ -f <capture filter> ]\n");
121   fprintf(output, "\t[ -g <packet number> ] [ -i <capture interface> ] [ -m <font> ]\n");
122   fprintf(output, "\t[ -N <name resolving flags> ] [ -o <preference/recent setting> ] ...\n");
123   fprintf(output, "\t[ -r <infile> ] [ -R <read (display) filter> ] [ -s <capture snaplen> ]\n");
124   fprintf(output, "\t[ -t <time stamp format> ] [ -w <savefile> ] [ -y <capture link type> ]\n");
125   fprintf(output, "\t[ -z <statistics> ] [ <infile> ]\n");
126 }
127
128 static void
129 show_version(void)
130 {
131   printf(PACKAGE " " VERSION "%s\n\n%s\n\n%s\n",
132       svnversion, comp_info_str->str, runtime_info_str->str);
133 }
134
135 /*
136  * Report an error in command-line arguments.
137  * Creates a console on Windows.
138  * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
139  * terminal isn't the standard error?
140  */
141 void
142 cmdarg_err(const char *fmt, ...)
143 {
144   va_list ap;
145
146 #ifdef _WIN32
147   create_console();
148 #endif
149   va_start(ap, fmt);
150   fprintf(stderr, "dumpcap: ");
151   vfprintf(stderr, fmt, ap);
152   fprintf(stderr, "\n");
153   va_end(ap);
154 }
155
156 /*
157  * Report additional information for an error in command-line arguments.
158  * Creates a console on Windows.
159  * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
160  * terminal isn't the standard error?
161  */
162 void
163 cmdarg_err_cont(const char *fmt, ...)
164 {
165   va_list ap;
166
167 #ifdef _WIN32
168   create_console();
169 #endif
170   va_start(ap, fmt);
171   vfprintf(stderr, fmt, ap);
172   fprintf(stderr, "\n");
173   va_end(ap);
174 }
175
176
177 #ifdef _WIN32
178 BOOL WINAPI ConsoleCtrlHandlerRoutine(DWORD dwCtrlType)
179 {
180     //printf("Event: %u", dwCtrlType);
181     capture_loop_stop();
182
183     return TRUE;
184 }
185 #endif
186
187 /* And now our feature presentation... [ fade to music ] */
188 int
189 main(int argc, char *argv[])
190 {
191   int                  opt;
192   extern char         *optarg;
193   gboolean             arg_error = FALSE;
194
195 #ifdef _WIN32
196   WSADATA              wsaData;
197 #endif  /* _WIN32 */
198
199   int                  err;
200   gboolean             start_capture = TRUE;
201   GList               *if_list;
202   if_info_t           *if_info;
203   GList               *lt_list, *lt_entry;
204   data_link_info_t    *data_link_info;
205   gchar                err_str[PCAP_ERRBUF_SIZE];
206   gchar               *cant_get_if_list_errstr;
207   gboolean             stats_known;
208   struct pcap_stat     stats;
209   GLogLevelFlags       log_flags;
210   gboolean             list_link_layer_types = FALSE;
211
212 #define OPTSTRING_INIT "a:b:c:f:Hhi:kLpQSs:W:w:vy:"
213
214 #ifdef _WIN32
215 #define OPTSTRING_WIN32 "B:Z:"
216 #else
217 #define OPTSTRING_WIN32 ""
218 #endif  /* _WIN32 */
219
220   char optstring[sizeof(OPTSTRING_INIT) + sizeof(OPTSTRING_WIN32) - 1] =
221     OPTSTRING_INIT OPTSTRING_WIN32;
222
223   /*** create the compile and runtime version strings ***/
224 #ifdef _WIN32
225   /* Load wpcap if possible. Do this before collecting the run-time version information */
226   load_wpcap();
227
228   /* ... and also load the packet.dll from wpcap */
229   wpcap_packet_load();
230
231   /* Start windows sockets */
232   WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
233
234
235   
236   SetConsoleCtrlHandler(&ConsoleCtrlHandlerRoutine, TRUE);
237 #endif  /* _WIN32 */
238
239   /* Assemble the compile-time version information string */
240   comp_info_str = g_string_new("Compiled ");
241   g_string_append(comp_info_str, "with ");
242   get_compiled_version_info(comp_info_str);
243
244   /* Assemble the run-time version information string */
245   runtime_info_str = g_string_new("Running ");
246   get_runtime_version_info(runtime_info_str);
247
248   ethereal_path = argv[0];
249
250   /* Arrange that if we have no console window, and a GLib message logging
251      routine is called to log a message, we pop up a console window.
252
253      We do that by inserting our own handler for all messages logged
254      to the default domain; that handler pops up a console if necessary,
255      and then calls the default handler. */
256
257   /* We might want to have component specific log levels later ... */
258
259   /* the default_log_handler will use stdout, which makes trouble with the */
260   /* capture child, as it uses stdout for it's sync_pipe */
261   /* so do the filtering in the console_log_handler and not here */
262   log_flags = 
263                     G_LOG_LEVEL_ERROR|
264                     G_LOG_LEVEL_CRITICAL|
265                     G_LOG_LEVEL_WARNING|
266                     G_LOG_LEVEL_MESSAGE|
267                     G_LOG_LEVEL_INFO|
268                     G_LOG_LEVEL_DEBUG|
269                     G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
270
271   g_log_set_handler(NULL,
272                     log_flags,
273                     console_log_handler, NULL /* user_data */);
274   g_log_set_handler(LOG_DOMAIN_MAIN,
275                     log_flags,
276                     console_log_handler, NULL /* user_data */);
277   g_log_set_handler(LOG_DOMAIN_CAPTURE,
278                     log_flags,
279             console_log_handler, NULL /* user_data */);
280   g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
281                     log_flags,
282             console_log_handler, NULL /* user_data */);
283
284   /* Set the initial values in the capture_opts. This might be overwritten 
285      by preference settings and then again by the command line parameters. */
286   capture_opts_init(capture_opts, &cfile);
287
288   capture_opts->snaplen             = MIN_PACKET_SIZE;
289   capture_opts->has_ring_num_files  = TRUE;
290
291   init_cap_file(&cfile);
292
293   /* Now get our args */
294   while ((opt = getopt(argc, argv, optstring)) != -1) {
295     switch (opt) {
296       case 'h':        /* Print help and exit */
297         print_usage(TRUE);
298         exit(0);
299         break;
300       case 'v':        /* Show version and exit */
301         show_version();
302         exit(0);
303         break;
304       /*** capture option specific ***/
305       case 'a':        /* autostop criteria */
306       case 'b':        /* Ringbuffer option */
307       case 'c':        /* Capture xxx packets */
308       case 'f':        /* capture filter */
309       case 'k':        /* Start capture immediately */
310       case 'H':        /* Hide capture info dialog box */
311       case 'i':        /* Use interface xxx */
312       case 'p':        /* Don't capture in promiscuous mode */
313       case 'Q':        /* Quit after capture (just capture to file) */
314       case 's':        /* Set the snapshot (capture) length */
315       case 'S':        /* "Sync" mode: used for following file ala tail -f */
316       case 'w':        /* Write to capture file xxx */
317       case 'y':        /* Set the pcap data link type */
318 #ifdef _WIN32
319       case 'B':        /* Buffer size */
320       /* Hidden option supporting Sync mode */
321       case 'Z':        /* Write to pipe FD XXX */
322 #endif /* _WIN32 */
323         capture_opts_add_opt(capture_opts, opt, optarg, &start_capture);
324         break;
325       /* This is a hidden option supporting Sync mode, so we don't set
326        * the error flags for the user in the non-libpcap case.
327        */
328       case 'W':        /* Write to capture file FD xxx */
329         capture_opts_add_opt(capture_opts, opt, optarg, &start_capture);
330         break;
331
332       /*** all non capture option specific ***/
333       case 'L':        /* Print list of link-layer types and exit */
334         list_link_layer_types = TRUE;
335         break;
336       default:
337       case '?':        /* Bad flag - print usage message */
338         arg_error = TRUE;
339         break;
340     }
341   }
342   argc -= optind;
343   argv += optind;
344   if (argc >= 1) {
345       /* user speficied file name as regular command-line argument */
346       /* XXX - use it as the capture file name (or somthing else)? */
347     argc--;
348     argv++;
349   }
350
351
352
353   if (argc != 0) {
354     /*
355      * Extra command line arguments were specified; complain.
356      */
357     cmdarg_err("Invalid argument: %s", argv[0]);
358     arg_error = TRUE;
359   }
360
361   if (arg_error) {
362     print_usage(FALSE);
363     exit(1);
364   }
365
366   if (list_link_layer_types) {
367     /* We're supposed to list the link-layer types for an interface;
368        did the user also specify a capture file to be read? */
369     /* No - did they specify a ring buffer option? */
370     if (capture_opts->multi_files_on) {
371       cmdarg_err("Ring buffer requested, but a capture isn't being done.");
372       exit(1);
373     }
374   } else {
375     /* No - was the ring buffer option specified and, if so, does it make
376        sense? */
377     if (capture_opts->multi_files_on) {
378       /* Ring buffer works only under certain conditions:
379          a) ring buffer does not work with temporary files;
380          b) real_time_mode and multi_files_on are mutually exclusive -
381             real_time_mode takes precedence;
382          c) it makes no sense to enable the ring buffer if the maximum
383             file size is set to "infinite". */
384       if (capture_opts->save_file == NULL) {
385         cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
386         capture_opts->multi_files_on = FALSE;
387       }
388       if (!capture_opts->has_autostop_filesize && !capture_opts->has_file_duration) {
389         cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
390 /* XXX - this must be redesigned as the conditions changed */
391 /*      capture_opts->multi_files_on = FALSE;*/
392       }
393     }
394   }
395
396 /* Did the user specify an interface to use? */
397 if (capture_opts->iface == NULL) {
398     /* No - pick the first one from the list of interfaces. */
399     if_list = get_interface_list(&err, err_str);
400     if (if_list == NULL) {
401       switch (err) {
402
403       case CANT_GET_INTERFACE_LIST:
404           cant_get_if_list_errstr = cant_get_if_list_error_message(err_str);
405           cmdarg_err("%s", cant_get_if_list_errstr);
406           g_free(cant_get_if_list_errstr);
407           break;
408
409       case NO_INTERFACES_FOUND:
410           cmdarg_err("There are no interfaces on which a capture can be done");
411           break;
412       }
413       exit(2);
414     }
415     if_info = if_list->data;    /* first interface */
416     capture_opts->iface = g_strdup(if_info->name);
417     free_interface_list(if_list);
418   }
419
420   if (list_link_layer_types) {
421     /* Get the list of link-layer types for the capture device. */
422     lt_list = get_pcap_linktype_list(capture_opts->iface, err_str);
423     if (lt_list == NULL) {
424       if (err_str[0] != '\0') {
425         cmdarg_err("The list of data link types for the capture device could not be obtained (%s)."
426           "Please check to make sure you have sufficient permissions, and that\n"
427           "you have the proper interface or pipe specified.\n", err_str);
428       } else
429         cmdarg_err("The capture device has no data link types.");
430       exit(2);
431     }
432     g_warning("Data link types (use option -y to set):");
433     for (lt_entry = lt_list; lt_entry != NULL;
434          lt_entry = g_list_next(lt_entry)) {
435       data_link_info = lt_entry->data;
436       g_warning("  %s", data_link_info->name);
437       if (data_link_info->description != NULL)
438         g_warning(" (%s)", data_link_info->description);
439       else
440         g_warning(" (not supported)");
441       putchar('\n');
442     }
443     free_pcap_linktype_list(lt_list);
444     exit(0);
445   }
446
447   if (capture_opts->has_snaplen) {
448     if (capture_opts->snaplen < 1)
449       capture_opts->snaplen = WTAP_MAX_PACKET_SIZE;
450     else if (capture_opts->snaplen < MIN_PACKET_SIZE)
451       capture_opts->snaplen = MIN_PACKET_SIZE;
452   }
453
454   /* Check the value range of the ringbuffer_num_files parameter */
455   if (capture_opts->ring_num_files > RINGBUFFER_MAX_NUM_FILES)
456     capture_opts->ring_num_files = RINGBUFFER_MAX_NUM_FILES;
457 #if RINGBUFFER_MIN_NUM_FILES > 0
458   else if (capture_opts->num_files < RINGBUFFER_MIN_NUM_FILES)
459     capture_opts->ring_num_files = RINGBUFFER_MIN_NUM_FILES;
460 #endif
461
462   /* Now start the capture. 
463      After the capture is done; there's nothing more for us to do. */
464
465   /* XXX - hand these stats to the parent process */
466   if(capture_loop_start(capture_opts, &stats_known, &stats) == TRUE) {
467       /* capture ok */
468       err = 0;
469   } else {
470       /* capture failed */
471       err = 1;
472   }
473
474 #ifdef _WIN32
475   /* Shutdown windows sockets */
476   WSACleanup();
477 #endif
478
479   destroy_console();
480
481   return err;
482 }
483
484 #ifdef _WIN32
485
486 /* We build this as a GUI subsystem application on Win32, so
487    "WinMain()", not "main()", gets called.
488
489    Hack shamelessly stolen from the Win32 port of the GIMP. */
490 #ifdef __GNUC__
491 #define _stdcall  __attribute__((stdcall))
492 #endif
493
494 int _stdcall
495 WinMain (struct HINSTANCE__ *hInstance,
496          struct HINSTANCE__ *hPrevInstance,
497          char               *lpszCmdLine,
498          int                 nCmdShow)
499 {
500   has_console = FALSE;
501   return main (__argc, __argv);
502 }
503
504 /*
505  * If this application has no console window to which its standard output
506  * would go, create one.
507  */
508 void
509 create_console(void)
510 {
511   if (!has_console) {
512     /* We have no console to which to print the version string, so
513        create one and make it the standard input, output, and error. */
514     if (!AllocConsole())
515       return;   /* couldn't create console */
516     eth_freopen("CONIN$", "r", stdin);
517     eth_freopen("CONOUT$", "w", stdout);
518     eth_freopen("CONOUT$", "w", stderr);
519
520     /* Well, we have a console now. */
521     has_console = TRUE;
522
523     /* Now register "destroy_console()" as a routine to be called just
524        before the application exits, so that we can destroy the console
525        after the user has typed a key (so that the console doesn't just
526        disappear out from under them, giving the user no chance to see
527        the message(s) we put in there). */
528     atexit(destroy_console);
529
530     SetConsoleTitle("Ethereal Capture Child Debug Console");
531   }
532 }
533
534 static void
535 destroy_console(void)
536 {
537   if (has_console) {
538     printf("\n\nPress any key to exit\n");
539     _getch();
540     FreeConsole();
541   }
542 }
543 #endif /* _WIN32 */
544
545
546 /* This routine should not be necessary, at least as I read the GLib
547    source code, as it looks as if GLib is, on Win32, *supposed* to
548    create a console window into which to display its output.
549
550    That doesn't happen, however.  I suspect there's something completely
551    broken about that code in GLib-for-Win32, and that it may be related
552    to the breakage that forces us to just call "printf()" on the message
553    rather than passing the message on to "g_log_default_handler()"
554    (which is the routine that does the aforementioned non-functional
555    console window creation). */
556 static void
557 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
558                     const char *message, gpointer user_data _U_)
559 {
560   time_t curr;
561   struct tm *today;
562   const char *level;
563
564
565   /* ignore log message, if log_level isn't interesting */
566   if( !(log_level & G_LOG_LEVEL_MASK & ~G_LOG_LEVEL_DEBUG /*prefs.console_log_level*/)) {
567     return;
568   }
569
570   /* create a "timestamp" */
571   time(&curr);
572   today = localtime(&curr);    
573
574 #ifdef _WIN32
575 //  if (prefs.gui_console_open != console_open_never) {
576     create_console();
577 //  }
578   if (has_console) {
579     /* For some unknown reason, the above doesn't appear to actually cause
580        anything to be sent to the standard output, so we'll just splat the
581        message out directly, just to make sure it gets out. */
582 #endif
583     switch(log_level & G_LOG_LEVEL_MASK) {
584     case G_LOG_LEVEL_ERROR:
585         level = "Err ";
586         break;
587     case G_LOG_LEVEL_CRITICAL:
588         level = "Crit";
589         break;
590     case G_LOG_LEVEL_WARNING:
591         level = "Warn";
592         break;
593     case G_LOG_LEVEL_MESSAGE:
594         level = "Msg ";
595         break;
596     case G_LOG_LEVEL_INFO:
597         level = "Info";
598         break;
599     case G_LOG_LEVEL_DEBUG:
600         level = "Dbg ";
601         break;
602     default:
603         fprintf(stderr, "unknown log_level %u\n", log_level);
604         level = NULL;
605         g_assert_not_reached();
606     }
607
608     /* don't use printf (stdout), as the capture child uses stdout for it's sync_pipe */
609     fprintf(stderr, "%02u:%02u:%02u %8s %s %s\n",
610             today->tm_hour, today->tm_min, today->tm_sec,
611             log_domain != NULL ? log_domain : "",
612             level, message);
613 #ifdef _WIN32
614   } else {
615     g_log_default_handler(log_domain, log_level, message, user_data);
616   }
617 #endif
618 }
619
620
621 /* Size of buffer to hold decimal representation of
622    signed/unsigned 64-bit int */
623 #define SP_DECISIZE 20
624
625 /*
626  * Indications sent out on the sync pipe.
627  */
628 #define SP_FILE         'F'     /* the name of the recently opened file */
629 #define SP_ERROR_MSG    'E'     /* error message */
630 #define SP_PACKET_COUNT 'P'     /* count of packets captured since last message */
631 #define SP_DROPS        'D'     /* count of packets dropped in capture */
632 #define SP_QUIT         'Q'     /* capture quit message (from parent to child) */
633
634 static void
635 pipe_write_block(int pipe, char indicator, int len, const char *msg)
636 {
637 }
638
639 void
640 sync_pipe_packet_count_to_parent(int packet_count)
641 {
642     char tmp[SP_DECISIZE+1+1];
643
644     g_snprintf(tmp, sizeof(tmp), "%d", packet_count);
645
646     //g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "sync_pipe_packet_count_to_parent: %s", tmp);
647
648     pipe_write_block(1, SP_PACKET_COUNT, strlen(tmp)+1, tmp);
649 }
650
651 void
652 sync_pipe_filename_to_parent(const char *filename)
653 {
654     g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO, "File: %s", filename);
655
656     pipe_write_block(1, SP_FILE, strlen(filename)+1, filename);
657 }
658
659 void
660 sync_pipe_errmsg_to_parent(const char *errmsg)
661 {
662     g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "sync_pipe_errmsg_to_parent: %s", errmsg);
663
664     pipe_write_block(1, SP_ERROR_MSG, strlen(errmsg)+1, errmsg);
665 }
666
667 void
668 sync_pipe_drops_to_parent(int drops)
669 {
670     char tmp[SP_DECISIZE+1+1];
671
672
673     g_snprintf(tmp, sizeof(tmp), "%d", drops);
674
675     g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "sync_pipe_drops_to_parent: %s", tmp);
676
677     pipe_write_block(1, SP_DROPS, strlen(tmp)+1, tmp);
678 }
679
680
681
682 /****************************************************************************************************************/
683 /* link dummies */
684
685 void main_window_update(void) {}
686
687 /* exit the main window */
688 void main_window_exit(void)
689 {
690 //  gtk_exit(0);
691 }
692
693 /* quit a nested main window */
694 void main_window_nested_quit(void)
695 {
696 //  if (gtk_main_level() > 0)
697   //  gtk_main_quit();
698 }
699
700 /* quit the main window */
701 void main_window_quit(void)
702 {
703   //gtk_main_quit();
704 }
705
706 void pipe_input_set_handler(gint source, gpointer user_data, int *child_process, pipe_input_cb_t input_cb)
707 {
708     /* we don't use a pipe input for */
709 assert(0);
710 }
711
712 void capture_info_create(capture_info    *cinfo, gchar           *iface) {}
713
714 void capture_info_update(capture_info    *cinfo) {
715     printf("Packets: %u\r", cinfo->counts->total);
716 }
717
718 void capture_info_destroy(capture_info    *cinfo) {}
719
720
721 static gpointer *
722 display_simple_dialog(gint type, gint btn_mask, char *message)
723 {
724     printf("%s", message);
725
726     return NULL;
727 }
728
729 char *simple_dialog_primary_start(void)
730 {
731     return "";
732 }
733
734 char *simple_dialog_primary_end(void)
735 {
736     return "";
737 }
738
739 /* Simple dialog function - Displays a dialog box with the supplied message
740  * text.
741  *
742  * Args:
743  * type       : One of ESD_TYPE_*.
744  * btn_mask   : The value passed in determines which buttons are displayed.
745  * msg_format : Sprintf-style format of the text displayed in the dialog.
746  * ...        : Argument list for msg_format
747  */
748
749 gpointer
750 vsimple_dialog(ESD_TYPE_E type, gint btn_mask, const gchar *msg_format, va_list ap)
751 {
752   gchar             *vmessage;
753   gchar             *message;
754   gpointer          *win;
755 #if GTK_MAJOR_VERSION >= 2
756   GdkWindowState state = 0;
757 #endif
758
759   /* Format the message. */
760   vmessage = g_strdup_vprintf(msg_format, ap);
761
762 #if GTK_MAJOR_VERSION >= 2
763   /* convert character encoding from locale to UTF8 (using iconv) */
764   message = g_locale_to_utf8(vmessage, -1, NULL, NULL, NULL);
765   g_free(vmessage);
766 #else
767   message = vmessage;
768 #endif
769
770   win = display_simple_dialog(type, btn_mask, message);
771
772   g_free(message);
773
774   return win;
775 }
776
777 gpointer
778 simple_dialog(ESD_TYPE_E type, gint btn_mask, const gchar *msg_format, ...)
779 {
780   va_list ap;
781   gpointer ret;
782
783   va_start(ap, msg_format);
784   ret = vsimple_dialog(type, btn_mask, msg_format, ap);
785   va_end(ap);
786   return ret;
787 }
788
789 char *
790 simple_dialog_format_message(const char *msg)
791 {
792     char *str;
793
794     if (msg) {
795 #if GTK_MAJOR_VERSION < 2
796         str = g_strdup(msg);
797 #else
798         str = xml_escape(msg);
799 #endif
800     } else {
801         str = NULL;
802     }
803     return str;
804 }
805
806
807
808 #include "fileset.h"
809
810 void fileset_file_opened(const char *fname) {}
811 void fileset_file_closed(void) {}
812 void fileset_dlg_add_file(fileset_entry *entry) {}
813
814 void packet_list_thaw(void) {}
815 void packet_list_clear(void) {}
816 void packet_list_freeze(void) {}
817 void packet_list_select_row(gint row) {}
818 void packet_list_moveto_end(void) {}
819 gint packet_list_find_row_from_data(gpointer data) { return 1; }
820 void packet_list_set_text(gint row, gint column, const gchar *text) {}
821 void packet_list_set_cls_time_width(gint column) {}
822 void packet_list_set_selected_row(gint row) {}
823 gint packet_list_append(const gchar *text[], gpointer data) { return 1; }
824 gint packet_list_get_sort_column(void) { return 1; }
825 gpointer packet_list_get_row_data(gint row) { return NULL; }
826 void packet_list_set_colors(gint row, color_t *fg, color_t *bg) {}
827
828
829 #include "progress_dlg.h"
830
831 void destroy_progress_dlg(progdlg_t *dlg) {}
832 void update_progress_dlg(progdlg_t *dlg, gfloat percentage, const gchar *status) {}
833 progdlg_t *
834 delayed_create_progress_dlg(const gchar *task_title, const gchar *item_title,
835     gboolean terminate_is_stop, gboolean *stop_flag,
836     const GTimeVal *start_time, gfloat progress) { return NULL; }
837
838 void tap_dfilter_dlg_update (void) {}
839
840
841 #include "color_filters.h"
842
843 color_filter_t * color_filters_colorize_packet(gint row, epan_dissect_t *edt) { return NULL; }
844 void color_filters_prime_edt(epan_dissect_t *edt) {}
845 gboolean color_filters_used(void) { return FALSE; }
846