From Olivier Jacques: Add #defines to disable XML validation.
[obnox/wireshark/wip.git] / version_info.c
1 /* version_info.c
2  * Routines to report version information for stuff used by Ethereal
3  *
4  * $Id$
5  *
6  * Ethereal - Network traffic analyzer
7  * By Gerald Combs <gerald@ethereal.com>
8  * Copyright 1998 Gerald Combs
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 #ifdef HAVE_LIBPCAP
30 #include <pcap.h>
31 #endif /* HAVE_LIBPCAP */
32
33 #include <glib.h>
34
35 #include <stdlib.h>
36 #include <string.h>
37 #include <errno.h>
38
39 #ifdef HAVE_LIBZ
40 #include <zlib.h>       /* to get the libz version number */
41 #endif
42
43 #ifdef HAVE_LIBPCRE
44 #include <pcre.h>       /* to get the libpcre version number */
45 #endif /* HAVE_LIBPCRE */
46
47 /*
48  * This has to come after the include of <pcap.h>, as the include of
49  * <pcap.h> might cause <winsock2.h> to be included, and if we've
50  * already included <winsock.h> as a result of including <windows.h>,
51  * we get a bunch of redefinitions.
52  */
53 #ifdef HAVE_WINDOWS_H
54 #include <windows.h>
55 #endif
56
57 #ifdef HAVE_SOME_SNMP
58
59 #ifdef HAVE_NET_SNMP
60 #include <net-snmp/version.h>
61 #endif /* HAVE_NET_SNMP */
62
63 #ifdef HAVE_UCD_SNMP
64 #include <ucd-snmp/version.h>
65 #endif /* HAVE_UCD_SNMP */
66
67 #endif /* HAVE_SOME_SNMP */
68
69 #ifdef HAVE_SYS_UTSNAME_H
70 #include <sys/utsname.h>
71 #endif
72
73 #include "version_info.h"
74 #include "pcap-util.h"
75
76 /*
77  * See whether the last line in the string goes past column 80; if so,
78  * replace the blank at the specified point with a newline.
79  */
80 static void
81 do_word_wrap(GString *str, gint point)
82 {
83         char *line_begin;
84
85         line_begin = strrchr(str->str, '\n');
86         if (line_begin == NULL)
87                 line_begin = str->str;
88         else
89                 line_begin++;
90         if (strlen(line_begin) > 80) {
91                 g_assert(str->str[point] == ' ');
92                 str->str[point] = '\n';
93         }
94 }       
95
96 /*
97  * Get various library compile-time versions and append them to
98  * the specified GString.
99  */
100 void
101 get_compiled_version_info(GString *str)
102 {
103         gint break_point;
104
105         g_string_append(str, "with ");
106         g_string_sprintfa(str,
107 #ifdef GLIB_MAJOR_VERSION
108             "GLib %d.%d.%d,", GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION,
109             GLIB_MICRO_VERSION);
110 #else
111             "GLib (version unknown),");
112 #endif
113
114         g_string_append(str, " ");
115         break_point = str->len - 1;
116         get_compiled_pcap_version(str);
117         g_string_append(str, ",");
118         do_word_wrap(str, break_point);
119
120         g_string_append(str, " ");
121         break_point = str->len - 1;
122 #ifdef HAVE_LIBZ
123         g_string_append(str, "with libz ");
124 #ifdef ZLIB_VERSION
125         g_string_append(str, ZLIB_VERSION);
126 #else /* ZLIB_VERSION */
127         g_string_append(str, "(version unknown)");
128 #endif /* ZLIB_VERSION */
129 #else /* HAVE_LIBZ */
130         g_string_append(str, "without libz");
131 #endif /* HAVE_LIBZ */
132         g_string_append(str, ",");
133         do_word_wrap(str, break_point);
134
135         g_string_append(str, " ");
136         break_point = str->len - 1;
137 #ifdef HAVE_LIBPCRE
138         g_string_append(str, "with libpcre ");
139 #ifdef PCRE_MAJOR
140 #ifdef PCRE_MINOR
141         g_string_sprintfa(str, "%u.%u", PCRE_MAJOR, PCRE_MINOR);
142 #else                   /* PCRE_MINOR */
143         g_string_sprintfa(str, "%u", PCRE_MAJOR);
144 #endif                  /* PCRE_MINOR */
145 #else           /* PCRE_MAJOR */
146         g_string_append(str, "(version unknown)");
147 #endif          /* PCRE_MAJOR */
148 #else   /* HAVE_LIBPCRE */
149         g_string_append(str, "without libpcre");
150 #endif  /* HAVE_LIBPCRE */
151
152         g_string_append(str, ",");
153         do_word_wrap(str, break_point);
154
155 /* Oh, this is pretty. */
156 /* Oh, ha.  you think that was pretty.  Try this:! --Wes */
157         g_string_append(str, " ");
158         break_point = str->len - 1;
159 #ifdef HAVE_SOME_SNMP
160
161 #ifdef HAVE_UCD_SNMP
162         g_string_append(str, "with UCD-SNMP ");
163         g_string_append(str, VersionInfo);
164 #endif /* HAVE_UCD_SNMP */
165
166 #ifdef HAVE_NET_SNMP
167         g_string_append(str, "with Net-SNMP ");
168         g_string_append(str, netsnmp_get_version());
169 #endif /* HAVE_NET_SNMP */
170
171 #else /* no SNMP library */
172         g_string_append(str, "without UCD-SNMP or Net-SNMP");
173 #endif /* HAVE_SOME_SNMP */
174         g_string_append(str, ",");
175         do_word_wrap(str, break_point);
176
177         g_string_append(str, " ");
178         break_point = str->len - 1;
179 #ifdef HAVE_GNU_ADNS
180         g_string_append(str, "with ADNS");
181 #else
182         g_string_append(str, "without ADNS");
183 #endif /* HAVE_GNU_ADNS */
184
185         g_string_append(str, ".");
186         do_word_wrap(str, break_point);
187
188 #ifndef HAVE_LIBPCRE
189         break_point = str->len - 1;
190         g_string_append(str,
191                         "\nNOTE: this build does not support the \"matches\" operator for Ethereal filter"
192                         "\nsyntax.");
193         do_word_wrap(str, break_point);
194 #endif  /* HAVE_LIBPCRE */
195 }
196
197 /*
198  * Get various library run-time versions, and the OS version, and append
199  * them to the specified GString.
200  */
201 void
202 get_runtime_version_info(GString *str)
203 {
204 #if defined(_WIN32)
205         OSVERSIONINFO info;
206 #elif defined(HAVE_SYS_UTSNAME_H)
207         struct utsname name;
208 #endif
209
210         get_runtime_pcap_version(str);
211
212         g_string_append(str, "on ");
213 #if defined(_WIN32)
214         info.dwOSVersionInfoSize = sizeof info;
215         if (!GetVersionEx(&info)) {
216                 /*
217                  * XXX - get the failure reason.
218                  */
219                 g_string_append(str, "unknown Windows version");
220                 return;
221         }
222         switch (info.dwPlatformId) {
223
224         case VER_PLATFORM_WIN32s:
225                 /* Shyeah, right. */
226                 g_string_sprintfa(str, "Windows 3.1 with Win32s");
227                 break;
228
229         case VER_PLATFORM_WIN32_WINDOWS:
230                 /* Windows OT */
231                 switch (info.dwMajorVersion) {
232
233                 case 4:
234                         /* 3 cheers for Microsoft marketing! */
235                         switch (info.dwMinorVersion) {
236
237                         case 0:
238                                 g_string_sprintfa(str, "Windows 95");
239                                 break;
240
241                         case 10:
242                                 g_string_sprintfa(str, "Windows 98");
243                                 break;
244
245                         case 90:
246                                 g_string_sprintfa(str, "Windows Me");
247                                 break;
248
249                         default:
250                                 g_string_sprintfa(str, "Windows OT, unknown version %lu.%lu",
251                                     info.dwMajorVersion, info.dwMinorVersion);
252                                 break;
253                         }
254                         break;
255
256                 default:
257                         g_string_sprintfa(str, "Windows OT, unknown version %lu.%lu",
258                             info.dwMajorVersion, info.dwMinorVersion);
259                         break;
260                 }
261                 break;
262
263         case VER_PLATFORM_WIN32_NT:
264                 /* Windows NT */
265                 switch (info.dwMajorVersion) {
266
267                 case 3:
268                 case 4:
269                         g_string_sprintfa(str, "Windows NT %lu.%lu",
270                             info.dwMajorVersion, info.dwMinorVersion);
271                         break;
272
273                 case 5:
274                         /* 3 cheers for Microsoft marketing! */
275                         switch (info.dwMinorVersion) {
276
277                         case 0:
278                                 g_string_sprintfa(str, "Windows 2000");
279                                 break;
280
281                         case 1:
282                                 g_string_sprintfa(str, "Windows XP");
283                                 break;
284
285                         case 2:
286                                 g_string_sprintfa(str, "Windows Server 2003");
287                                 break;
288
289                         default:
290                                 g_string_sprintfa(str, "Windows NT, unknown version %lu.%lu",
291                                     info.dwMajorVersion, info.dwMinorVersion);
292                                 break;
293                         }
294                         break;
295
296                 default:
297                         g_string_sprintfa(str, "Windows NT, unknown version %lu.%lu",
298                             info.dwMajorVersion, info.dwMinorVersion);
299                         break;
300                 }
301                 break;
302
303         default:
304                 g_string_sprintfa(str, "Unknown Windows platform %lu version %lu.%lu",
305                     info.dwPlatformId, info.dwMajorVersion, info.dwMinorVersion);
306                 break;
307         }
308         if (info.szCSDVersion[0] != '\0')
309                 g_string_sprintfa(str, " %s", info.szCSDVersion);
310         g_string_sprintfa(str, ", build %lu", info.dwBuildNumber);
311 #elif defined(HAVE_SYS_UTSNAME_H)
312         /*
313          * We have <sys/utsname.h>, so we assume we have "uname()".
314          */
315         if (uname(&name) < 0) {
316                 g_string_sprintfa(str, "unknown OS version (uname failed - %s)",
317                     strerror(errno));
318                 return;
319         }
320
321         if (strcmp(name.sysname, "AIX") == 0) {
322                 /*
323                  * Yay, IBM!  Thanks for doing something different
324                  * from most of the other UNIXes out there, and
325                  * making "name.version" apparently be the major
326                  * version number and "name.release" be the minor
327                  * version number.
328                  */
329                 g_string_sprintfa(str, "%s %s.%s", name.sysname, name.version,
330                     name.release);
331         } else {
332                 /*
333                  * XXX - get "version" on any other platforms?
334                  *
335                  * On Digital/Tru65 UNIX, it's something unknown.
336                  * On Solaris, it's some kind of build information.
337                  * On HP-UX, it appears to be some sort of subrevision
338                  * thing.
339                  */
340                 g_string_sprintfa(str, "%s %s", name.sysname, name.release);
341         }
342 #else
343         g_string_append(str, "an unknown OS");
344 #endif
345         g_string_append(str, ".");
346 }