This was missing from last check-in
[metze/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 "capture-pcap-util.h"
75
76 #include "svnversion.h"
77
78 #ifdef SVNVERSION
79         const char *svnversion = " (" SVNVERSION ")";
80 #else
81         const char *svnversion = "";
82 #endif
83
84 /*
85  * See whether the last line in the string goes past column 80; if so,
86  * replace the blank at the specified point with a newline.
87  */
88 static void
89 do_word_wrap(GString *str, gint point)
90 {
91         char *line_begin;
92
93         line_begin = strrchr(str->str, '\n');
94         if (line_begin == NULL)
95                 line_begin = str->str;
96         else
97                 line_begin++;
98         if (strlen(line_begin) > 80) {
99                 g_assert(str->str[point] == ' ');
100                 str->str[point] = '\n';
101         }
102 }       
103
104 /*
105  * If the string doesn't end with a newline, append one.
106  */
107 static void
108 end_string(GString *str)
109 {
110         size_t point;
111
112         point = strlen(str->str);
113         if (point == 0 || str->str[point - 1] != '\n')
114                 g_string_append(str, "\n");
115 }       
116
117 /*
118  * Get various library compile-time versions and append them to
119  * the specified GString.
120  */
121 void
122 get_compiled_version_info(GString *str)
123 {
124         gint break_point;
125
126         g_string_append(str, "with ");
127         g_string_sprintfa(str,
128 #ifdef GLIB_MAJOR_VERSION
129             "GLib %d.%d.%d,", GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION,
130             GLIB_MICRO_VERSION);
131 #else
132             "GLib (version unknown),");
133 #endif
134
135         g_string_append(str, " ");
136         break_point = str->len - 1;
137         get_compiled_pcap_version(str);
138         g_string_append(str, ",");
139         do_word_wrap(str, break_point);
140
141         g_string_append(str, " ");
142         break_point = str->len - 1;
143 #ifdef HAVE_LIBZ
144         g_string_append(str, "with libz ");
145 #ifdef ZLIB_VERSION
146         g_string_append(str, ZLIB_VERSION);
147 #else /* ZLIB_VERSION */
148         g_string_append(str, "(version unknown)");
149 #endif /* ZLIB_VERSION */
150 #else /* HAVE_LIBZ */
151         g_string_append(str, "without libz");
152 #endif /* HAVE_LIBZ */
153         g_string_append(str, ",");
154         do_word_wrap(str, break_point);
155
156         g_string_append(str, " ");
157         break_point = str->len - 1;
158 #ifdef HAVE_LIBPCRE
159         g_string_append(str, "with libpcre ");
160 #ifdef PCRE_MAJOR
161 #ifdef PCRE_MINOR
162         g_string_sprintfa(str, "%u.%u", PCRE_MAJOR, PCRE_MINOR);
163 #else                   /* PCRE_MINOR */
164         g_string_sprintfa(str, "%u", PCRE_MAJOR);
165 #endif                  /* PCRE_MINOR */
166 #else           /* PCRE_MAJOR */
167         g_string_append(str, "(version unknown)");
168 #endif          /* PCRE_MAJOR */
169 #else   /* HAVE_LIBPCRE */
170         g_string_append(str, "without libpcre");
171 #endif  /* HAVE_LIBPCRE */
172
173         g_string_append(str, ",");
174         do_word_wrap(str, break_point);
175
176 /* Oh, this is pretty. */
177 /* Oh, ha.  you think that was pretty.  Try this:! --Wes */
178         g_string_append(str, " ");
179         break_point = str->len - 1;
180 #ifdef HAVE_SOME_SNMP
181
182 #ifdef HAVE_UCD_SNMP
183         g_string_append(str, "with UCD-SNMP ");
184         g_string_append(str, VersionInfo);
185 #endif /* HAVE_UCD_SNMP */
186
187 #ifdef HAVE_NET_SNMP
188         g_string_append(str, "with Net-SNMP ");
189         g_string_append(str, netsnmp_get_version());
190 #endif /* HAVE_NET_SNMP */
191
192 #else /* no SNMP library */
193         g_string_append(str, "without UCD-SNMP or Net-SNMP");
194 #endif /* HAVE_SOME_SNMP */
195         g_string_append(str, ",");
196         do_word_wrap(str, break_point);
197
198         g_string_append(str, " ");
199         break_point = str->len - 1;
200 #ifdef HAVE_GNU_ADNS
201         g_string_append(str, "with ADNS");
202 #else
203         g_string_append(str, "without ADNS");
204 #endif /* HAVE_GNU_ADNS */
205
206         g_string_append(str, ".");
207         do_word_wrap(str, break_point);
208
209 #ifndef HAVE_LIBPCRE
210         break_point = str->len - 1;
211         g_string_append(str,
212                         "\nNOTE: this build doesn't support the \"matches\" operator for Ethereal filter"
213                         "\nsyntax.");
214         do_word_wrap(str, break_point);
215 #endif  /* HAVE_LIBPCRE */
216
217         end_string(str);
218 }
219
220 /*
221  * Get various library run-time versions, and the OS version, and append
222  * them to the specified GString.
223  */
224 void
225 get_runtime_version_info(GString *str)
226 {
227 #if defined(_WIN32)
228         OSVERSIONINFO info;
229 #elif defined(HAVE_SYS_UTSNAME_H)
230         struct utsname name;
231 #endif
232
233         get_runtime_pcap_version(str);
234
235         g_string_append(str, "on ");
236 #if defined(_WIN32)
237         /*
238          * See
239          *
240          *      http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/getting_the_system_version.asp
241          *
242          * for more than you ever wanted to know about determining the
243          * flavor of Windows on which you're running.  Implementing more
244          * of that is left as an exercise to the reader - who should
245          * check any copyright information about code samples on MSDN
246          * before cutting and pasting into Ethereal.
247          *
248          * They should also note that you need an OSVERSIONINFOEX structure
249          * to get some of that information, and that not only is that
250          * structure not supported on older versions of Windows, you might
251          * not even be able to compile code that *uses* that structure with
252          * older versions of the SDK.
253          */
254         info.dwOSVersionInfoSize = sizeof info;
255         if (!GetVersionEx(&info)) {
256                 /*
257                  * XXX - get the failure reason.
258                  */
259                 g_string_append(str, "unknown Windows version");
260                 return;
261         }
262         switch (info.dwPlatformId) {
263
264         case VER_PLATFORM_WIN32s:
265                 /* Shyeah, right. */
266                 g_string_sprintfa(str, "Windows 3.1 with Win32s");
267                 break;
268
269         case VER_PLATFORM_WIN32_WINDOWS:
270                 /* Windows OT */
271                 switch (info.dwMajorVersion) {
272
273                 case 4:
274                         /* 3 cheers for Microsoft marketing! */
275                         switch (info.dwMinorVersion) {
276
277                         case 0:
278                                 g_string_sprintfa(str, "Windows 95");
279                                 break;
280
281                         case 10:
282                                 g_string_sprintfa(str, "Windows 98");
283                                 break;
284
285                         case 90:
286                                 g_string_sprintfa(str, "Windows Me");
287                                 break;
288
289                         default:
290                                 g_string_sprintfa(str, "Windows OT, unknown version %lu.%lu",
291                                     info.dwMajorVersion, info.dwMinorVersion);
292                                 break;
293                         }
294                         break;
295
296                 default:
297                         g_string_sprintfa(str, "Windows OT, unknown version %lu.%lu",
298                             info.dwMajorVersion, info.dwMinorVersion);
299                         break;
300                 }
301                 break;
302
303         case VER_PLATFORM_WIN32_NT:
304                 /* Windows NT */
305                 switch (info.dwMajorVersion) {
306
307                 case 3:
308                 case 4:
309                         g_string_sprintfa(str, "Windows NT %lu.%lu",
310                             info.dwMajorVersion, info.dwMinorVersion);
311                         break;
312
313                 case 5:
314                         /* 3 cheers for Microsoft marketing! */
315                         switch (info.dwMinorVersion) {
316
317                         case 0:
318                                 g_string_sprintfa(str, "Windows 2000");
319                                 break;
320
321                         case 1:
322                                 g_string_sprintfa(str, "Windows XP");
323                                 break;
324
325                         case 2:
326                                 g_string_sprintfa(str, "Windows Server 2003");
327                                 break;
328
329                         default:
330                                 g_string_sprintfa(str, "Windows NT, unknown version %lu.%lu",
331                                     info.dwMajorVersion, info.dwMinorVersion);
332                                 break;
333                         }
334                         break;
335
336                 case 6:
337                         g_string_sprintfa(str, "Windows Vista");
338                         break;
339
340                 default:
341                         g_string_sprintfa(str, "Windows NT, unknown version %lu.%lu",
342                             info.dwMajorVersion, info.dwMinorVersion);
343                         break;
344                 }
345                 break;
346
347         default:
348                 g_string_sprintfa(str, "Unknown Windows platform %lu version %lu.%lu",
349                     info.dwPlatformId, info.dwMajorVersion, info.dwMinorVersion);
350                 break;
351         }
352         if (info.szCSDVersion[0] != '\0')
353                 g_string_sprintfa(str, " %s", info.szCSDVersion);
354         g_string_sprintfa(str, ", build %lu", info.dwBuildNumber);
355 #elif defined(HAVE_SYS_UTSNAME_H)
356         /*
357          * We have <sys/utsname.h>, so we assume we have "uname()".
358          */
359         if (uname(&name) < 0) {
360                 g_string_sprintfa(str, "unknown OS version (uname failed - %s)",
361                     strerror(errno));
362                 return;
363         }
364
365         if (strcmp(name.sysname, "AIX") == 0) {
366                 /*
367                  * Yay, IBM!  Thanks for doing something different
368                  * from most of the other UNIXes out there, and
369                  * making "name.version" apparently be the major
370                  * version number and "name.release" be the minor
371                  * version number.
372                  */
373                 g_string_sprintfa(str, "%s %s.%s", name.sysname, name.version,
374                     name.release);
375         } else {
376                 /*
377                  * XXX - get "version" on any other platforms?
378                  *
379                  * On Digital/Tru65 UNIX, it's something unknown.
380                  * On Solaris, it's some kind of build information.
381                  * On HP-UX, it appears to be some sort of subrevision
382                  * thing.
383                  */
384                 g_string_sprintfa(str, "%s %s", name.sysname, name.release);
385         }
386 #else
387         g_string_append(str, "an unknown OS");
388 #endif
389         g_string_append(str, ".");
390
391         end_string(str);
392 }
393
394 /*
395  * Get copyright information.
396  */
397 const char *
398 get_copyright_info(void)
399 {
400         return
401 "Copyright 1998-2006 Gerald Combs <gerald@ethereal.com> and contributors.\n"
402 "This is free software; see the source for copying conditions. There is NO\n"
403 "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n";
404 }