1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel (at) 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 ***************************************************************************/ 22 23 #include "curl_setup.h" 24 25 #include <curl/curl.h> 26 #include "urldata.h" 27 #include "vtls/vtls.h" 28 #include "http2.h" 29 #include "curl_printf.h" 30 31 #ifdef USE_ARES 32 # if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \ 33 (defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__)) 34 # define CARES_STATICLIB 35 # endif 36 # include <ares.h> 37 #endif 38 39 #ifdef USE_LIBIDN 40 #include <stringprep.h> 41 #endif 42 43 #if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS) 44 #include <iconv.h> 45 #endif 46 47 #ifdef USE_LIBRTMP 48 #include <librtmp/rtmp.h> 49 #endif 50 51 #ifdef USE_LIBSSH2 52 #include <libssh2.h> 53 #endif 54 55 #ifdef HAVE_LIBSSH2_VERSION 56 /* get it run-time if possible */ 57 #define CURL_LIBSSH2_VERSION libssh2_version(0) 58 #else 59 /* use build-time if run-time not possible */ 60 #define CURL_LIBSSH2_VERSION LIBSSH2_VERSION 61 #endif 62 63 char *curl_version(void) 64 { 65 static char version[200]; 66 char *ptr = version; 67 size_t len; 68 size_t left = sizeof(version); 69 70 strcpy(ptr, LIBCURL_NAME "/" LIBCURL_VERSION); 71 len = strlen(ptr); 72 left -= len; 73 ptr += len; 74 75 if(left > 1) { 76 len = Curl_ssl_version(ptr + 1, left - 1); 77 78 if(len > 0) { 79 *ptr = ' '; 80 left -= ++len; 81 ptr += len; 82 } 83 } 84 85 #ifdef HAVE_LIBZ 86 len = snprintf(ptr, left, " zlib/%s", zlibVersion()); 87 left -= len; 88 ptr += len; 89 #endif 90 #ifdef USE_ARES 91 /* this function is only present in c-ares, not in the original ares */ 92 len = snprintf(ptr, left, " c-ares/%s", ares_version(NULL)); 93 left -= len; 94 ptr += len; 95 #endif 96 #ifdef USE_LIBIDN 97 if(stringprep_check_version(LIBIDN_REQUIRED_VERSION)) { 98 len = snprintf(ptr, left, " libidn/%s", stringprep_check_version(NULL)); 99 left -= len; 100 ptr += len; 101 } 102 #endif 103 #ifdef USE_WIN32_IDN 104 len = snprintf(ptr, left, " WinIDN"); 105 left -= len; 106 ptr += len; 107 #endif 108 #if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS) 109 #ifdef _LIBICONV_VERSION 110 len = snprintf(ptr, left, " iconv/%d.%d", 111 _LIBICONV_VERSION >> 8, _LIBICONV_VERSION & 255); 112 #else 113 /* version unknown */ 114 len = snprintf(ptr, left, " iconv"); 115 #endif /* _LIBICONV_VERSION */ 116 left -= len; 117 ptr += len; 118 #endif 119 #ifdef USE_LIBSSH2 120 len = snprintf(ptr, left, " libssh2/%s", CURL_LIBSSH2_VERSION); 121 left -= len; 122 ptr += len; 123 #endif 124 #ifdef USE_NGHTTP2 125 len = Curl_http2_ver(ptr, left); 126 left -= len; 127 ptr += len; 128 #endif 129 #ifdef USE_LIBRTMP 130 { 131 char suff[2]; 132 if(RTMP_LIB_VERSION & 0xff) { 133 suff[0] = (RTMP_LIB_VERSION & 0xff) + 'a' - 1; 134 suff[1] = '\0'; 135 } 136 else 137 suff[0] = '\0'; 138 139 snprintf(ptr, left, " librtmp/%d.%d%s", 140 RTMP_LIB_VERSION >> 16, (RTMP_LIB_VERSION >> 8) & 0xff, 141 suff); 142 /* 143 If another lib version is added below this one, this code would 144 also have to do: 145 146 len = what snprintf() returned 147 148 left -= len; 149 ptr += len; 150 */ 151 } 152 #endif 153 154 return version; 155 } 156 157 /* data for curl_version_info 158 159 Keep the list sorted alphabetically. It is also written so that each 160 protocol line has its own #if line to make things easier on the eye. 161 */ 162 163 static const char * const protocols[] = { 164 #ifndef CURL_DISABLE_DICT 165 "dict", 166 #endif 167 #ifndef CURL_DISABLE_FILE 168 "file", 169 #endif 170 #ifndef CURL_DISABLE_FTP 171 "ftp", 172 #endif 173 #if defined(USE_SSL) && !defined(CURL_DISABLE_FTP) 174 "ftps", 175 #endif 176 #ifndef CURL_DISABLE_GOPHER 177 "gopher", 178 #endif 179 #ifndef CURL_DISABLE_HTTP 180 "http", 181 #endif 182 #if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP) 183 "https", 184 #endif 185 #ifndef CURL_DISABLE_IMAP 186 "imap", 187 #endif 188 #if defined(USE_SSL) && !defined(CURL_DISABLE_IMAP) 189 "imaps", 190 #endif 191 #ifndef CURL_DISABLE_LDAP 192 "ldap", 193 #if !defined(CURL_DISABLE_LDAPS) && \ 194 ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \ 195 (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL))) 196 "ldaps", 197 #endif 198 #endif 199 #ifndef CURL_DISABLE_POP3 200 "pop3", 201 #endif 202 #if defined(USE_SSL) && !defined(CURL_DISABLE_POP3) 203 "pop3s", 204 #endif 205 #ifdef USE_LIBRTMP 206 "rtmp", 207 #endif 208 #ifndef CURL_DISABLE_RTSP 209 "rtsp", 210 #endif 211 #ifdef USE_LIBSSH2 212 "scp", 213 #endif 214 #ifdef USE_LIBSSH2 215 "sftp", 216 #endif 217 #if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \ 218 (CURL_SIZEOF_CURL_OFF_T > 4) && \ 219 (!defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)) 220 "smb", 221 # ifdef USE_SSL 222 "smbs", 223 # endif 224 #endif 225 #ifndef CURL_DISABLE_SMTP 226 "smtp", 227 #endif 228 #if defined(USE_SSL) && !defined(CURL_DISABLE_SMTP) 229 "smtps", 230 #endif 231 #ifndef CURL_DISABLE_TELNET 232 "telnet", 233 #endif 234 #ifndef CURL_DISABLE_TFTP 235 "tftp", 236 #endif 237 238 NULL 239 }; 240 241 static curl_version_info_data version_info = { 242 CURLVERSION_NOW, 243 LIBCURL_VERSION, 244 LIBCURL_VERSION_NUM, 245 OS, /* as found by configure or set by hand at build-time */ 246 0 /* features is 0 by default */ 247 #ifdef ENABLE_IPV6 248 | CURL_VERSION_IPV6 249 #endif 250 #ifdef USE_SSL 251 | CURL_VERSION_SSL 252 #endif 253 #ifdef USE_NTLM 254 | CURL_VERSION_NTLM 255 #endif 256 #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \ 257 defined(NTLM_WB_ENABLED) 258 | CURL_VERSION_NTLM_WB 259 #endif 260 #ifdef USE_SPNEGO 261 | CURL_VERSION_SPNEGO 262 #endif 263 #ifdef USE_KERBEROS5 264 | CURL_VERSION_KERBEROS5 265 #endif 266 #ifdef HAVE_GSSAPI 267 | CURL_VERSION_GSSAPI 268 #endif 269 #ifdef USE_WINDOWS_SSPI 270 | CURL_VERSION_SSPI 271 #endif 272 #ifdef HAVE_LIBZ 273 | CURL_VERSION_LIBZ 274 #endif 275 #ifdef DEBUGBUILD 276 | CURL_VERSION_DEBUG 277 #endif 278 #ifdef CURLDEBUG 279 | CURL_VERSION_CURLDEBUG 280 #endif 281 #ifdef CURLRES_ASYNCH 282 | CURL_VERSION_ASYNCHDNS 283 #endif 284 #if (CURL_SIZEOF_CURL_OFF_T > 4) && \ 285 ( (SIZEOF_OFF_T > 4) || defined(USE_WIN32_LARGE_FILES) ) 286 | CURL_VERSION_LARGEFILE 287 #endif 288 #if defined(CURL_DOES_CONVERSIONS) 289 | CURL_VERSION_CONV 290 #endif 291 #if defined(USE_TLS_SRP) 292 | CURL_VERSION_TLSAUTH_SRP 293 #endif 294 #if defined(USE_NGHTTP2) 295 | CURL_VERSION_HTTP2 296 #endif 297 #if defined(USE_UNIX_SOCKETS) 298 | CURL_VERSION_UNIX_SOCKETS 299 #endif 300 , 301 NULL, /* ssl_version */ 302 0, /* ssl_version_num, this is kept at zero */ 303 NULL, /* zlib_version */ 304 protocols, 305 NULL, /* c-ares version */ 306 0, /* c-ares version numerical */ 307 NULL, /* libidn version */ 308 0, /* iconv version */ 309 NULL, /* ssh lib version */ 310 }; 311 312 curl_version_info_data *curl_version_info(CURLversion stamp) 313 { 314 #ifdef USE_LIBSSH2 315 static char ssh_buffer[80]; 316 #endif 317 318 #ifdef USE_SSL 319 static char ssl_buffer[80]; 320 Curl_ssl_version(ssl_buffer, sizeof(ssl_buffer)); 321 version_info.ssl_version = ssl_buffer; 322 #endif 323 324 #ifdef HAVE_LIBZ 325 version_info.libz_version = zlibVersion(); 326 /* libz left NULL if non-existing */ 327 #endif 328 #ifdef USE_ARES 329 { 330 int aresnum; 331 version_info.ares = ares_version(&aresnum); 332 version_info.ares_num = aresnum; 333 } 334 #endif 335 #ifdef USE_LIBIDN 336 /* This returns a version string if we use the given version or later, 337 otherwise it returns NULL */ 338 version_info.libidn = stringprep_check_version(LIBIDN_REQUIRED_VERSION); 339 if(version_info.libidn) 340 version_info.features |= CURL_VERSION_IDN; 341 #elif defined(USE_WIN32_IDN) 342 version_info.features |= CURL_VERSION_IDN; 343 #endif 344 345 #if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS) 346 #ifdef _LIBICONV_VERSION 347 version_info.iconv_ver_num = _LIBICONV_VERSION; 348 #else 349 /* version unknown */ 350 version_info.iconv_ver_num = -1; 351 #endif /* _LIBICONV_VERSION */ 352 #endif 353 354 #ifdef USE_LIBSSH2 355 snprintf(ssh_buffer, sizeof(ssh_buffer), "libssh2/%s", LIBSSH2_VERSION); 356 version_info.libssh_version = ssh_buffer; 357 #endif 358 359 (void)stamp; /* avoid compiler warnings, we don't use this */ 360 361 return &version_info; 362 } 363