Fix comment end after SPDX identifier
[metze/wireshark/wip.git] / ui / console.c
1 /* console.c
2  * Console log handler routines
3  *
4  * Wireshark - Network traffic analyzer
5  * By Gerald Combs <gerald@wireshark.org>
6  * Copyright 1998 Gerald Combs
7  *
8  * SPDX-License-Identifier: GPL-2.0-or-later
9  */
10
11 #include "config.h"
12
13 #include <stdio.h>
14
15
16 #include "epan/prefs.h"
17 #include "wsutil/time_util.h"
18
19 #include "console.h"
20
21 #include "log.h"
22
23 static void
24 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
25                     const char *message, gpointer user_data _U_)
26 {
27     time_t curr;
28     struct tm *today;
29     const char *level;
30
31
32     /* ignore log message, if log_level isn't interesting based
33        upon the console log preferences.
34        If the preferences haven't been loaded loaded yet, display the
35        message anyway.
36
37        The default console_log_level preference value is such that only
38          ERROR, CRITICAL and WARNING level messages are processed;
39          MESSAGE, INFO and DEBUG level messages are ignored.  */
40     if((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
41         prefs.console_log_level != 0) {
42         return;
43     }
44
45 #ifdef _WIN32
46     if (prefs.gui_console_open != console_open_never || log_level & G_LOG_LEVEL_ERROR) {
47         /* the user wants a console or the application will terminate immediately */
48         create_console();
49     }
50     if (get_has_console()) {
51         /* For some unknown reason, the above doesn't appear to actually cause
52            anything to be sent to the standard output, so we'll just splat the
53            message out directly, just to make sure it gets out. */
54 #endif
55         switch(log_level & G_LOG_LEVEL_MASK) {
56             case G_LOG_LEVEL_ERROR:
57                 level = "Err ";
58                 break;
59             case G_LOG_LEVEL_CRITICAL:
60                 level = "Crit";
61                 break;
62             case G_LOG_LEVEL_WARNING:
63                 level = "Warn";
64                 break;
65             case G_LOG_LEVEL_MESSAGE:
66                 level = "Msg ";
67                 break;
68             case G_LOG_LEVEL_INFO:
69                 level = "Info";
70                 break;
71             case G_LOG_LEVEL_DEBUG:
72                 level = "Dbg ";
73                 break;
74             default:
75                 fprintf(stderr, "unknown log_level %d\n", log_level);
76                 level = NULL;
77                 g_assert_not_reached();
78         }
79
80         /* create a "timestamp" */
81         time(&curr);
82         today = localtime(&curr);
83         guint64 microseconds = create_timestamp();
84         if (today != NULL) {
85                 fprintf(stderr, "%02d:%02d:%02d.%03" G_GUINT64_FORMAT " %8s %s %s\n",
86                         today->tm_hour, today->tm_min, today->tm_sec,
87                         microseconds % 1000000 / 1000,
88                         log_domain != NULL ? log_domain : "",
89                         level, message);
90         } else {
91                 fprintf(stderr, "Time not representable %8s %s %s\n",
92                         log_domain != NULL ? log_domain : "",
93                         level, message);
94         }
95 #ifdef _WIN32
96         if(log_level & G_LOG_LEVEL_ERROR) {
97             /* wait for a key press before the following error handler will terminate the program
98                this way the user at least can read the error message */
99             printf("\n\nPress any key to exit\n");
100             _getch();
101         }
102     } else {
103         /* XXX - on UN*X, should we just use g_log_default_handler()?
104            We want the error messages to go to the standard output;
105            on macOS, that will cause them to show up in various
106            per-user logs accessible through Console (details depend
107            on whether you're running 10.0 through 10.4 or running
108            10.5 and later), and, on other UN*X desktop environments,
109            if they don't show up in some form of console log, that's
110            a deficiency in that desktop environment.  (Too bad
111            Windows doesn't set the standard output and error for
112            GUI apps to something that shows up in such a log.) */
113         g_log_default_handler(log_domain, log_level, message, user_data);
114     }
115 #endif
116 }
117
118 void set_console_log_handler(void)
119 {
120     GLogLevelFlags log_flags;
121     /* Arrange that if we have no console window, and a GLib message logging
122        routine is called to log a message, we pop up a console window.
123
124        We do that by inserting our own handler for all messages logged
125        to the default domain; that handler pops up a console if necessary,
126        and then calls the default handler. */
127
128     /* We might want to have component specific log levels later ... */
129
130     log_flags = (GLogLevelFlags)
131                 (G_LOG_LEVEL_ERROR|
132                  G_LOG_LEVEL_CRITICAL|
133                  G_LOG_LEVEL_WARNING|
134                  G_LOG_LEVEL_MESSAGE|
135                  G_LOG_LEVEL_INFO|
136                  G_LOG_LEVEL_DEBUG|
137                  G_LOG_FLAG_FATAL|
138                  G_LOG_FLAG_RECURSION);
139
140     g_log_set_handler(NULL,
141                       log_flags,
142                       console_log_handler, NULL /* user_data */);
143     g_log_set_handler(LOG_DOMAIN_MAIN,
144                       log_flags,
145                       console_log_handler, NULL /* user_data */);
146
147 #ifdef HAVE_LIBPCAP
148     g_log_set_handler(LOG_DOMAIN_CAPTURE,
149                       log_flags,
150                       console_log_handler, NULL /* user_data */);
151     g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
152                     log_flags,
153                     console_log_handler, NULL /* user_data */);
154
155 #endif
156 }
157
158 /*
159  * Editor modelines
160  *
161  * Local Variables:
162  * c-basic-offset: 4
163  * tab-width: 8
164  * indent-tabs-mode: nil
165  * End:
166  *
167  * ex: set shiftwidth=4 tabstop=8 expandtab:
168  * :indentSize=4:tabSize=8:noTabs=true:
169  */