nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /* ws_version_info.c
2 * Routines to report version information for Wireshark programs
3 *
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22  
23 #include <config.h>
24  
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <locale.h>
29  
30 #ifdef _WIN32
31 #include <windows.h>
32 #endif
33  
34 #include <glib.h>
35  
36 #ifdef HAVE_ZLIB
37 #include <zlib.h>
38 #endif
39  
40 #include "version.h"
41  
42 #include "ws_version_info.h"
43  
44 #include <wsutil/ws_cpuid.h>
45 #include <wsutil/copyright_info.h>
46 #include <wsutil/os_version_info.h>
47  
48 /*
49 * If the string doesn't end with a newline, append one.
50 * Then word-wrap it to 80 columns.
51 */
52 static void
53 end_string(GString *str)
54 {
55 size_t point;
56 char *p, *q;
57  
58 point = str->len;
59 if (point == 0 || str->str[point - 1] != '\n')
60 g_string_append(str, "\n");
61 p = str->str;
62 while (*p != '\0') {
63 q = strchr(p, '\n');
64 if (q - p > 80) {
65 /*
66 * Break at or before this point.
67 */
68 q = p + 80;
69 while (q > p && *q != ' ')
70 q--;
71 if (q != p)
72 *q = '\n';
73 }
74 p = q + 1;
75 }
76 }
77  
78 static const gchar *
79 get_zlib_compiled_version_info(void)
80 {
81 #ifdef HAVE_ZLIB
82 #ifdef ZLIB_VERSION
83 return "with zlib "ZLIB_VERSION;
84 #else
85 return "with zlib (version unknown)";
86 #endif /* ZLIB_VERSION */
87 #else
88 return "without zlib";
89 #endif /* HAVE_ZLIB */
90 }
91  
92 /*
93 * Get various library compile-time versions, put them in a GString,
94 * and return the GString.
95 *
96 * "prepend_info" is called at the start to prepend any additional
97 * information before the standard library information.
98 *
99 * "append_info" is called at the end to append any additional
100 * information after the standard library information. This is
101 * required in order to, for example, put the Portaudio information
102 * at the end of the string, as we currently don't use Portaudio in
103 * TShark.
104 */
105 GString *
106 get_compiled_version_info(void (*prepend_info)(GString *),
107 void (*append_info)(GString *))
108 {
109 GString *str;
110  
111 str = g_string_new("Compiled ");
112  
113 if (sizeof(str) == 4)
114 g_string_append(str, "(32-bit) ");
115 else
116 g_string_append(str, "(64-bit) ");
117  
118 if (prepend_info) {
119 (*prepend_info)(str);
120 g_string_append(str, ", ");
121 }
122  
123 /* GLIB */
124 g_string_append(str, "with ");
125 g_string_append_printf(str,
126 #ifdef GLIB_MAJOR_VERSION
127 "GLib %d.%d.%d", GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION,
128 GLIB_MICRO_VERSION);
129 #else
130 "GLib (version unknown)");
131 #endif
132  
133 g_string_append_printf(str, ", %s", get_zlib_compiled_version_info());
134  
135 /* Additional application-dependent information */
136 if (append_info)
137 (*append_info)(str);
138 g_string_append(str, ".");
139  
140 end_string(str);
141  
142 return str;
143 }
144  
145 /*
146 * Get the CPU info, and append it to the GString
147 */
148 static void
149 get_cpu_info(GString *str)
150 {
151 guint32 CPUInfo[4];
152 char CPUBrandString[0x40];
153 unsigned nExIds;
154  
155 /* http://msdn.microsoft.com/en-us/library/hskdteyh(v=vs.100).aspx */
156  
157 /* Calling __cpuid with 0x80000000 as the InfoType argument*/
158 /* gets the number of valid extended IDs.*/
159 if (!ws_cpuid(CPUInfo, 0x80000000))
160 return;
161 nExIds = CPUInfo[0];
162  
163 if( nExIds<0x80000005)
164 return;
165 memset(CPUBrandString, 0, sizeof(CPUBrandString));
166  
167 /* Interpret CPU brand string.*/
168 ws_cpuid(CPUInfo, 0x80000002);
169 memcpy(CPUBrandString, CPUInfo, sizeof(CPUInfo));
170 ws_cpuid(CPUInfo, 0x80000003);
171 memcpy(CPUBrandString + 16, CPUInfo, sizeof(CPUInfo));
172 ws_cpuid(CPUInfo, 0x80000004);
173 memcpy(CPUBrandString + 32, CPUInfo, sizeof(CPUInfo));
174  
175 g_string_append_printf(str, "\n%s", CPUBrandString);
176  
177 if (ws_cpuid_sse42())
178 g_string_append(str, " (with SSE4.2)");
179 }
180  
181 static void
182 get_mem_info(GString *str _U_)
183 {
184 #ifdef _WIN32
185 MEMORYSTATUSEX statex;
186  
187 statex.dwLength = sizeof (statex);
188  
189 if (GlobalMemoryStatusEx(&statex))
190 g_string_append_printf(str, ", with ""%" G_GINT64_MODIFIER "d" "MB of physical memory.\n", statex.ullTotalPhys/(1024*1024));
191 #endif
192 }
193  
194 /*
195 * Get compiler information, and append it to the GString.
196 */
197 static void
198 get_compiler_info(GString *str)
199 {
200 /*
201 * See https://sourceforge.net/apps/mediawiki/predef/index.php?title=Compilers
202 * information on various defined strings.
203 *
204 * GCC's __VERSION__ is a nice text string for humans to
205 * read. The page at sourceforge.net largely describes
206 * numeric #defines that encode the version; if the compiler
207 * doesn't also offer a nice printable string, we try prettifying
208 * the number somehow.
209 */
210 #if defined(__GNUC__) && defined(__VERSION__)
211 /*
212 * Clang and llvm-gcc also define __GNUC__ and __VERSION__;
213 * distinguish between them.
214 */
215 #if defined(__clang__)
216 g_string_append_printf(str, "\n\nBuilt using clang %s.\n", __VERSION__);
217 #elif defined(__llvm__)
218 g_string_append_printf(str, "\n\nBuilt using llvm-gcc %s.\n", __VERSION__);
219 #else /* boring old GCC */
220 g_string_append_printf(str, "\n\nBuilt using gcc %s.\n", __VERSION__);
221 #endif /* llvm */
222 #elif defined(__HP_aCC)
223 g_string_append_printf(str, "\n\nBuilt using HP aCC %d.\n", __HP_aCC);
224 #elif defined(__xlC__)
225 g_string_append_printf(str, "\n\nBuilt using IBM XL C %d.%d\n",
226 (__xlC__ >> 8) & 0xFF, __xlC__ & 0xFF);
227 #ifdef __IBMC__
228 if ((__IBMC__ % 10) != 0)
229 g_string_append_printf(str, " patch %d", __IBMC__ % 10);
230 #endif /* __IBMC__ */
231 g_string_append_printf(str, "\n");
232 #elif defined(__INTEL_COMPILER)
233 g_string_append_printf(str, "\n\nBuilt using Intel C %d.%d",
234 __INTEL_COMPILER / 100, (__INTEL_COMPILER / 10) % 10);
235 if ((__INTEL_COMPILER % 10) != 0)
236 g_string_append_printf(str, " patch %d", __INTEL_COMPILER % 10);
237 #ifdef __INTEL_COMPILER_BUILD_DATE
238 g_string_sprinta(str, ", compiler built %04d-%02d-%02d",
239 __INTEL_COMPILER_BUILD_DATE / 10000,
240 (__INTEL_COMPILER_BUILD_DATE / 100) % 100,
241 __INTEL_COMPILER_BUILD_DATE % 100);
242 #endif /* __INTEL_COMPILER_BUILD_DATE */
243 g_string_append_printf(str, "\n");
244 #elif defined(_MSC_FULL_VER)
245 # if _MSC_FULL_VER > 99999999
246 /* Quote from the web:
247 * Bakersfield: DevDiv's upper management determines the scheduling of new major versions.
248 * They also decided to increment the product version from 12 (for VS 2013) to 14 (for VS 2015).
249 * However, the C++ compiler's version incremented normally, from 18 to 19.
250 * (It's larger because the C++ compiler predates the "Visual" in Visual C++.)
251 * XXX? Should we just output the compiler version?
252 */
253 int compiler_major_version = (_MSC_FULL_VER / 10000000), visual_studio_ver;
254  
255 if (compiler_major_version < 19) {
256 visual_studio_ver = compiler_major_version - 6;
257 }else{
258 visual_studio_ver = compiler_major_version - 5;
259 }
260  
261 g_string_append_printf(str, "\n\nBuilt using Microsoft Visual C++ %d.%d",
262 visual_studio_ver,
263 (_MSC_FULL_VER / 100000) % 100);
264 # if (_MSC_FULL_VER % 100000) != 0
265 g_string_append_printf(str, " build %d",
266 _MSC_FULL_VER % 100000);
267 # endif
268 # else
269 g_string_append_printf(str, "\n\nBuilt using Microsoft Visual C++ %d.%d",
270 (_MSC_FULL_VER / 1000000) - 6,
271 (_MSC_FULL_VER / 10000) % 100);
272 # if (_MSC_FULL_VER % 10000) != 0
273 g_string_append_printf(str, " build %d",
274 _MSC_FULL_VER % 10000);
275 # endif
276 # endif
277 g_string_append_printf(str, "\n");
278 #elif defined(_MSC_VER)
279 /* _MSC_FULL_VER not defined, but _MSC_VER defined */
280 g_string_append_printf(str, "\n\nBuilt using Microsoft Visual C++ %d.%d\n",
281 (_MSC_VER / 100) - 6, _MSC_VER % 100);
282 #elif defined(__SUNPRO_C)
283 g_string_append_printf(str, "\n\nBuilt using Sun C %d.%d",
284 (__SUNPRO_C >> 8) & 0xF, (__SUNPRO_C >> 4) & 0xF);
285 if ((__SUNPRO_C & 0xF) != 0)
286 g_string_append_printf(str, " patch %d", __SUNPRO_C & 0xF);
287 g_string_append_printf(str, "\n");
288 #endif
289 }
290  
291 /* XXX - is the setlocale() return string opaque? For glibc the separator is ';' */
292 static gchar *
293 get_locale(void)
294 {
295 const gchar *lang;
296 gchar **locv, *loc;
297  
298 lang = setlocale(LC_ALL, NULL);
299 if (lang == NULL) {
300 return NULL;
301 }
302  
303 locv = g_strsplit(lang, ";", -1);
304 loc = g_strjoinv(", ", locv);
305 g_strfreev(locv);
306 return loc;
307 }
308  
309 /*
310 * Get various library run-time versions, and the OS version, and append
311 * them to the specified GString.
312 *
313 * "additional_info" is called at the end to append any additional
314 * information; this is required in order to, for example, put the
315 * Portaudio information at the end of the string, as we currently
316 * don't use Portaudio in TShark.
317 */
318 GString *
319 get_runtime_version_info(void (*additional_info)(GString *))
320 {
321 GString *str;
322 gchar *lang;
323  
324 str = g_string_new("Running on ");
325  
326 get_os_version_info(str);
327  
328 /*
329 * Locale.
330 *
331 * This returns the C language's locale information; this
332 * returns the locale that's actually in effect, even if
333 * it doesn't happen to match the settings of any of the
334 * locale environment variables.
335 *
336 * XXX - what happens on Windows? If nobody's explicitly
337 * overridden any of the environment variables, does this
338 * reflect the locale settings in the OS? If so, does
339 * that include the code page? (We're not using UTF-16
340 * for output to files or the console; using code page
341 * 65001, i.e. UTF-8, as your system code page probably
342 * works best with Wireshark.)
343 */
344 if ((lang = get_locale()) != NULL) {
345 g_string_append_printf(str, ", with locale %s", lang);
346 g_free(lang);
347 }
348 else {
349 g_string_append(str, ", with default locale");
350 }
351  
352  
353 /* Additional application-dependent information */
354 if (additional_info)
355 (*additional_info)(str);
356  
357 /* zlib */
358 #if defined(HAVE_ZLIB) && !defined(_WIN32)
359 g_string_append_printf(str, ", with zlib %s", zlibVersion());
360 #endif
361  
362 g_string_append(str, ".");
363  
364 /* CPU Info */
365 get_cpu_info(str);
366  
367 /* Get info about installed memory Windows only */
368 get_mem_info(str);
369  
370 /* Compiler info */
371 get_compiler_info(str);
372  
373 end_string(str);
374  
375 return str;
376 }
377  
378 void
379 show_version(const gchar *prog_name_str, GString *comp_info_str,
380 GString *runtime_info_str)
381 {
382 printf("%s %s\n"
383 "\n"
384 "%s"
385 "\n"
386 "%s"
387 "\n"
388 "%s",
389 prog_name_str, get_ws_vcs_version_info(), get_copyright_info(),
390 comp_info_str->str, runtime_info_str->str);
391 }
392  
393 /*
394 * Return a version number string for Wireshark, including, for builds
395 * from a tree checked out from Wireshark's version control system,
396 * something identifying what version was checked out.
397 */
398 const char *
399 get_ws_vcs_version_info(void)
400 {
401 #ifdef VCSVERSION
402 return VERSION " (" VCSVERSION ")";
403 #else
404 return VERSION;
405 #endif
406 }
407  
408 /*
409 * Editor modelines - http://www.wireshark.org/tools/modelines.html
410 *
411 * Local variables:
412 * c-basic-offset: 8
413 * tab-width: 8
414 * indent-tabs-mode: t
415 * End:
416 *
417 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
418 * :indentSize=8:tabSize=8:noTabs=false:
419 */