Replaced all uses of sprintf() with the safer snprintf(). It is just a
[platform/upstream/curl.git] / lib / version.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
10  * This software is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution. The terms
12  * are also available at http://curl.haxx.se/docs/copyright.html.
13  *
14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15  * copies of the Software, and permit persons to whom the Software is
16  * furnished to do so, under the terms of the COPYING file.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  * $Id$
22  ***************************************************************************/
23
24 #include "setup.h"
25
26 #include <string.h>
27 #include <stdio.h>
28
29 #include <curl/curl.h>
30 #include "urldata.h"
31
32 #define _MPRINTF_REPLACE /* use the internal *printf() functions */
33 #include <curl/mprintf.h>
34
35 #ifdef USE_ARES
36 #include <ares_version.h>
37 #endif
38
39 #ifdef USE_LIBIDN
40 #include <stringprep.h>
41 #endif
42
43 #ifdef USE_SSLEAY
44 static int getssl_version(char *ptr, size_t left, long *num)
45 {
46
47 #if (SSLEAY_VERSION_NUMBER >= 0x905000)
48   {
49     char sub[2];
50     unsigned long ssleay_value;
51     sub[1]='\0';
52     ssleay_value=SSLeay();
53     *num = (long)ssleay_value;
54     if(ssleay_value < 0x906000) {
55       ssleay_value=SSLEAY_VERSION_NUMBER;
56       sub[0]='\0';
57     }
58     else {
59       if(ssleay_value&0xff0) {
60         sub[0]=(char)((ssleay_value>>4)&0xff) + 'a' -1;
61       }
62       else
63         sub[0]='\0';
64     }
65
66     return snprintf(ptr, left, " OpenSSL/%lx.%lx.%lx%s",
67                     (ssleay_value>>28)&0xf,
68                     (ssleay_value>>20)&0xff,
69                     (ssleay_value>>12)&0xff,
70                     sub);
71   }
72
73 #else
74   *num = SSLEAY_VERSION_NUMBER;
75 #if (SSLEAY_VERSION_NUMBER >= 0x900000)
76   return snprintf(ptr, left, " OpenSSL/%lx.%lx.%lx",
77                   (SSLEAY_VERSION_NUMBER>>28)&0xff,
78                   (SSLEAY_VERSION_NUMBER>>20)&0xff,
79                   (SSLEAY_VERSION_NUMBER>>12)&0xf);
80 #else
81   {
82     char sub[2];
83     sub[1]='\0';
84     if(SSLEAY_VERSION_NUMBER&0x0f) {
85       sub[0]=(SSLEAY_VERSION_NUMBER&0x0f) + 'a' -1;
86     }
87     else
88       sub[0]='\0';
89
90     return snprintf(ptr, left, " SSL/%x.%x.%x%s",
91                     (SSLEAY_VERSION_NUMBER>>12)&0xff,
92                     (SSLEAY_VERSION_NUMBER>>8)&0xf,
93                     (SSLEAY_VERSION_NUMBER>>4)&0xf, sub);
94   }
95 #endif
96 #endif
97 }
98
99 #endif
100
101 char *curl_version(void)
102 {
103   static char version[200];
104   char *ptr=version;
105   int len;
106   size_t left = sizeof(version);
107   strcpy(ptr, LIBCURL_NAME "/" LIBCURL_VERSION );
108   ptr=strchr(ptr, '\0');
109   left -= strlen(ptr);
110
111 #ifdef USE_SSLEAY
112   {
113     long num;
114     len = getssl_version(ptr, left, &num);
115     left -= len;
116     ptr += len;
117   }
118 #endif
119
120 #ifdef HAVE_LIBZ
121   len = snprintf(ptr, left, " zlib/%s", zlibVersion());
122   left -= len;
123   ptr += len;
124 #endif
125 #ifdef USE_ARES
126   /* this function is only present in c-ares, not in the original ares */
127   len = snprintf(ptr, left, " c-ares/%s", ares_version(NULL));
128   left -= len;
129   ptr += len;
130 #endif
131 #ifdef USE_LIBIDN
132   if(stringprep_check_version(LIBIDN_REQUIRED_VERSION)) {
133     len = snprintf(ptr, left, " libidn/%s", stringprep_check_version(NULL));
134     left -= len;
135     ptr += len;
136   }
137 #endif
138
139   return version;
140 }
141
142 /* data for curl_version_info */
143
144 static const char *protocols[] = {
145 #ifndef CURL_DISABLE_FTP
146   "ftp",
147 #endif
148 #ifndef CURL_DISABLE_GOPHER
149   "gopher",
150 #endif
151 #ifndef CURL_DISABLE_TELNET
152   "telnet",
153 #endif
154 #ifndef CURL_DISABLE_DICT
155   "dict",
156 #endif
157 #ifndef CURL_DISABLE_LDAP
158   "ldap",
159 #endif
160 #ifndef CURL_DISABLE_HTTP
161   "http",
162 #endif
163 #ifndef CURL_DISABLE_FILE
164   "file",
165 #endif
166
167 #ifdef USE_SSLEAY
168 #ifndef CURL_DISABLE_HTTP
169   "https",
170 #endif
171 #ifndef CURL_DISABLE_FTP
172   "ftps",
173 #endif
174 #endif
175   NULL
176 };
177
178 static curl_version_info_data version_info = {
179   CURLVERSION_NOW,
180   LIBCURL_VERSION,
181   LIBCURL_VERSION_NUM,
182   OS, /* as found by configure or set by hand at build-time */
183   0 /* features is 0 by default */
184 #ifdef ENABLE_IPV6
185   | CURL_VERSION_IPV6
186 #endif
187 #ifdef HAVE_KRB4
188   | CURL_VERSION_KERBEROS4
189 #endif
190 #ifdef USE_SSLEAY
191   | CURL_VERSION_SSL
192   | CURL_VERSION_NTLM /* since this requires OpenSSL */
193 #endif
194 #ifdef HAVE_LIBZ
195   | CURL_VERSION_LIBZ
196 #endif
197 #ifdef HAVE_GSSAPI
198   | CURL_VERSION_GSSNEGOTIATE
199 #endif
200 #ifdef CURLDEBUG
201   | CURL_VERSION_DEBUG
202 #endif
203 #ifdef USE_ARES
204   | CURL_VERSION_ASYNCHDNS
205 #endif
206 #ifdef HAVE_SPNEGO
207   | CURL_VERSION_SPNEGO
208 #endif
209 #if defined(ENABLE_64BIT) && (SIZEOF_CURL_OFF_T > 4)
210   | CURL_VERSION_LARGEFILE
211 #endif
212   ,
213   NULL, /* ssl_version */
214   0,    /* ssl_version_num */
215   NULL, /* zlib_version */
216   protocols,
217   NULL, /* c-ares version */
218   0,    /* c-ares version numerical */
219   NULL, /* libidn version */
220 };
221
222 curl_version_info_data *curl_version_info(CURLversion stamp)
223 {
224 #ifdef USE_SSLEAY
225   static char ssl_buffer[80];
226   long num;
227   getssl_version(ssl_buffer, sizeof(ssl_buffer), &num);
228
229   version_info.ssl_version = ssl_buffer;
230   version_info.ssl_version_num = num;
231   /* SSL stuff is left zero if undefined */
232 #endif
233
234 #ifdef HAVE_LIBZ
235   version_info.libz_version = zlibVersion();
236   /* libz left NULL if non-existing */
237 #endif
238 #ifdef USE_ARES
239   {
240     int aresnum;
241     version_info.ares = ares_version(&aresnum);
242     version_info.ares_num = aresnum;
243   }
244 #endif
245 #ifdef USE_LIBIDN
246   /* This returns a version string if we use the given version or later,
247      otherwise it returns NULL */
248   version_info.libidn = stringprep_check_version(LIBIDN_REQUIRED_VERSION);
249   if(version_info.libidn)
250     version_info.features |= CURL_VERSION_IDN;
251 #endif
252   (void)stamp; /* avoid compiler warnings, we don't use this */
253
254   return &version_info;
255 }