1 /*
2  * Tux Racer
3  * Copyright (C) 1999-2001 Jasmin F. Patry
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18  */
19 
20 #include "tuxracer.h"
21 
22 #if defined( COMPILER_IS_UNIX_COMPATIBLE )
23 #   include <sys/utsname.h>
24 #endif
25 
26 #ifdef _MSC_VER
27 #  define snprintf _snprintf
28 #endif
29 
30 
31 /* This function only used in Win32; ifdef'd to eliminate "unused" warnings */
32 #if defined( WIN32 )
33 
append_to_buff(char ** buff,int * size,char * string)34 static bool_t append_to_buff( char **buff, int *size, char *string )
35 {
36     int len;
37 
38     if ( *size < 0 ) {
39 	return False;
40     }
41 
42     len = snprintf( *buff, *size, "%s", string );
43 
44     check_assertion( len >= 0, "buff too small" );
45     if ( len < 0 ) {
46 	return False;
47     }
48 
49     *buff += len;
50     *size -= len;
51 
52 	return True;
53 }
54 
55 #endif /* WIN32 */
56 
57 
58 /*---------------------------------------------------------------------------*/
59 /*!
60   Fills \c buff with a string describing the current OS (including version)
61   \return  0 on success, 1 if buffer too small, -1 if failed to determine
62            OS version
63   \author  jfpatry
64   \date    Created:  2000-10-30
65   \date    Modified: 2000-10-30
66 */
get_os_version(char * buff,int size)67 int get_os_version( char *buff, int size )
68 {
69 
70 #ifdef WIN32
71     /* Win32 Version */
72 
73     /* See http://www.mvps.org/vb/index2.html?tips/getversionex.htm for
74        a table mapping OSVERSIONINFOEX entries to Windows version */
75 
76     char tmp_buff[BUFF_LEN];
77     int tmp_buff_size = BUFF_LEN;
78     char *ptr = tmp_buff;
79     int len;
80 
81     OSVERSIONINFO osvi;
82 
83     ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
84     osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
85 
86     if ( !GetVersionEx( (OSVERSIONINFO *) &osvi) ) {
87 	return -1;
88     }
89 
90     switch (osvi.dwPlatformId)
91     {
92     case VER_PLATFORM_WIN32_NT:
93 
94 	/* Check for NT versus 2000 */
95 	if ( osvi.dwMajorVersion <= 4 ) {
96 	    if ( !append_to_buff( &ptr, &tmp_buff_size,
97 				  "Microsoft Windows NT" ) )
98 	    {
99 		return -1;
100 	    }
101 	}
102 
103 	if ( osvi.dwMajorVersion == 5 ) {
104 	    if ( !append_to_buff( &ptr, &tmp_buff_size,
105 				  "Microsoft Windows 2000" ) )
106 	    {
107 		return -1;
108 	    }
109 	}
110 
111 
112 	/* Display version, service pack (if any), and build number. */
113 	len = snprintf(ptr, tmp_buff_size, " version %d.%d %s (Build %d)",
114 		       osvi.dwMajorVersion,
115 		       osvi.dwMinorVersion,
116 		       osvi.szCSDVersion,
117 		       osvi.dwBuildNumber & 0xFFFF);
118 
119 	check_assertion( len >= 0, "tmp_buff too small" );
120 	if ( len < 0 ) {
121 	    return -1;
122 	}
123 
124 	ptr += len;
125 	tmp_buff_size -= len;
126 
127 	break;
128 
129     case VER_PLATFORM_WIN32_WINDOWS:
130 
131 	if ((osvi.dwMajorVersion > 4) ||
132             ((osvi.dwMajorVersion == 4) && (osvi.dwMinorVersion > 0)))
133 	{
134 	    if ( osvi.dwMinorVersion <= 10 ) {
135 		if ( strcmp( osvi.szCSDVersion, "A" ) == 0 ) {
136 		    if ( !append_to_buff( &ptr, &tmp_buff_size,
137 					  "Microsoft Windows 98 SE") )
138 		    {
139 			return -1;
140 		    }
141 		} else {
142 		    if ( !append_to_buff( &ptr, &tmp_buff_size,
143 					  "Microsoft Windows 98") )
144 		    {
145 			return -1;
146 		    }
147 		}
148 	    } else {
149 		if ( !append_to_buff( &ptr, &tmp_buff_size,
150 				      "Microsoft Windows ME") )
151 		{
152 		    return -1;
153 		}
154 	    }
155 	} else {
156 	    if ( strcmp( osvi.szCSDVersion, "B" ) == 0 ) {
157 		if ( !append_to_buff( &ptr, &tmp_buff_size,
158 				      "Microsoft Windows 95 OSR2") )
159 		{
160 		    return -1;
161 		}
162 	    } else {
163 		if ( !append_to_buff( &ptr, &tmp_buff_size,
164 				      "Microsoft Windows 95") )
165 		{
166 		    return -1;
167 		}
168 	    }
169 	}
170 
171 	/* Append Build */
172 	len = snprintf(ptr, tmp_buff_size, " (Build %d)",
173 		       osvi.dwBuildNumber & 0xFFFF);
174 
175 	check_assertion( len >= 0, "tmp_buff too small" );
176 	if ( len < 0 ) {
177 	    return -1;
178 	}
179 
180 	ptr += len;
181 	tmp_buff_size -= len;
182 
183 	break;
184 
185     case VER_PLATFORM_WIN32s:
186 	if ( !append_to_buff( &ptr, &tmp_buff_size, "Microsoft Win32s") ) {
187 	    return -1;
188 	}
189 
190 	break;
191     }
192 
193     len = snprintf( buff, size, "%s", tmp_buff );
194     if ( len < 0 ) {
195 	/* buffer too small */
196 	buff[size-1] = (char)0;
197 	return 1;
198     }
199 
200     return 0;
201 
202 #else
203     /* Unix/Linux version */
204 
205     struct utsname utsname;
206 
207     if ( uname( &utsname ) >= 0 ) {
208 	if ( strlen( utsname.sysname ) + strlen( utsname.release ) +
209 	     strlen( utsname.version ) + 3 > size )
210 	{
211 	    if ( size > 0 ) {
212 		buff[0] = (char)0;
213 	    }
214 	    return 1;
215 	}
216 
217 	sprintf( buff, "%s %s %s",
218 		 utsname.sysname, utsname.release, utsname.version );
219 
220 	return 0;
221 
222     } else {
223 	/* uname failed */
224 	return -1;
225     }
226 #endif /* WIN32 */
227 }
228 
229 
230 /* EOF */
231