Annotation of embedaddon/curl/lib/version.c, revision 1.1.1.1
1.1 misho 1: /***************************************************************************
2: * _ _ ____ _
3: * Project ___| | | | _ \| |
4: * / __| | | | |_) | |
5: * | (__| |_| | _ <| |___
6: * \___|\___/|_| \_\_____|
7: *
8: * Copyright (C) 1998 - 2020, 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 https://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 "vssh/ssh.h"
30: #include "quic.h"
31: #include "curl_printf.h"
32:
33: #ifdef USE_ARES
34: # if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \
35: (defined(WIN32) || defined(__SYMBIAN32__))
36: # define CARES_STATICLIB
37: # endif
38: # include <ares.h>
39: #endif
40:
41: #ifdef USE_LIBIDN2
42: #include <idn2.h>
43: #endif
44:
45: #ifdef USE_LIBPSL
46: #include <libpsl.h>
47: #endif
48:
49: #if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS)
50: #include <iconv.h>
51: #endif
52:
53: #ifdef USE_LIBRTMP
54: #include <librtmp/rtmp.h>
55: #endif
56:
57: #ifdef HAVE_ZLIB_H
58: #include <zlib.h>
59: #ifdef __SYMBIAN32__
60: /* zlib pollutes the namespace with this definition */
61: #undef WIN32
62: #endif
63: #endif
64:
65: #ifdef HAVE_BROTLI
66: #include <brotli/decode.h>
67: #endif
68:
69: #ifdef HAVE_BROTLI
70: static size_t brotli_version(char *buf, size_t bufsz)
71: {
72: uint32_t brotli_version = BrotliDecoderVersion();
73: unsigned int major = brotli_version >> 24;
74: unsigned int minor = (brotli_version & 0x00FFFFFF) >> 12;
75: unsigned int patch = brotli_version & 0x00000FFF;
76:
77: return msnprintf(buf, bufsz, "%u.%u.%u", major, minor, patch);
78: }
79: #endif
80:
81: /*
82: * curl_version() returns a pointer to a static buffer.
83: *
84: * It is implemented to work multi-threaded by making sure repeated invokes
85: * generate the exact same string and never write any temporary data like
86: * zeros in the data.
87: */
88:
89: #define VERSION_PARTS 14 /* number of substrings we can concatenate */
90:
91: char *curl_version(void)
92: {
93: static char out[300];
94: char *outp;
95: size_t outlen;
96: const char *src[VERSION_PARTS];
97: #ifdef USE_SSL
98: char ssl_version[200];
99: #endif
100: #ifdef HAVE_LIBZ
101: char z_version[40];
102: #endif
103: #ifdef HAVE_BROTLI
104: char br_version[40] = "brotli/";
105: #endif
106: #ifdef USE_ARES
107: char cares_version[40];
108: #endif
109: #if defined(USE_LIBIDN2)
110: char idn_version[40];
111: #endif
112: #ifdef USE_LIBPSL
113: char psl_version[40];
114: #endif
115: #if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS)
116: char iconv_version[40]="iconv";
117: #endif
118: #ifdef USE_SSH
119: char ssh_version[40];
120: #endif
121: #ifdef USE_NGHTTP2
122: char h2_version[40];
123: #endif
124: #ifdef ENABLE_QUIC
125: char h3_version[40];
126: #endif
127: #ifdef USE_LIBRTMP
128: char rtmp_version[40];
129: #endif
130: int i = 0;
131: int j;
132:
133: #ifdef DEBUGBUILD
134: /* Override version string when environment variable CURL_VERSION is set */
135: const char *debugversion = getenv("CURL_VERSION");
136: if(debugversion) {
137: strncpy(out, debugversion, sizeof(out)-1);
138: out[sizeof(out)-1] = '\0';
139: return out;
140: }
141: #endif
142:
143: src[i++] = LIBCURL_NAME "/" LIBCURL_VERSION;
144: #ifdef USE_SSL
145: Curl_ssl_version(ssl_version, sizeof(ssl_version));
146: src[i++] = ssl_version;
147: #endif
148: #ifdef HAVE_LIBZ
149: msnprintf(z_version, sizeof(z_version), "zlib/%s", zlibVersion());
150: src[i++] = z_version;
151: #endif
152: #ifdef HAVE_BROTLI
153: brotli_version(&br_version[7], sizeof(br_version) - 7);
154: src[i++] = br_version;
155: #endif
156: #ifdef USE_ARES
157: msnprintf(cares_version, sizeof(cares_version),
158: "c-ares/%s", ares_version(NULL));
159: src[i++] = cares_version;
160: #endif
161: #ifdef USE_LIBIDN2
162: msnprintf(idn_version, sizeof(idn_version),
163: "libidn2/%s", idn2_check_version(NULL));
164: src[i++] = idn_version;
165: #elif defined(USE_WIN32_IDN)
166: src[i++] = (char *)"WinIDN";
167: #endif
168:
169: #ifdef USE_LIBPSL
170: msnprintf(psl_version, sizeof(psl_version), "libpsl/%s", psl_get_version());
171: src[i++] = psl_version;
172: #endif
173: #if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS)
174: #ifdef _LIBICONV_VERSION
175: msnprintf(iconv_version, sizeof(iconv_version), "iconv/%d.%d",
176: _LIBICONV_VERSION >> 8, _LIBICONV_VERSION & 255);
177: #else
178: /* version unknown, let the default stand */
179: #endif /* _LIBICONV_VERSION */
180: src[i++] = iconv_version;
181: #endif
182: #ifdef USE_SSH
183: Curl_ssh_version(ssh_version, sizeof(ssh_version));
184: src[i++] = ssh_version;
185: #endif
186: #ifdef USE_NGHTTP2
187: Curl_http2_ver(h2_version, sizeof(h2_version));
188: src[i++] = h2_version;
189: #endif
190: #ifdef ENABLE_QUIC
191: Curl_quic_ver(h3_version, sizeof(h3_version));
192: src[i++] = h3_version;
193: #endif
194: #ifdef USE_LIBRTMP
195: {
196: char suff[2];
197: if(RTMP_LIB_VERSION & 0xff) {
198: suff[0] = (RTMP_LIB_VERSION & 0xff) + 'a' - 1;
199: suff[1] = '\0';
200: }
201: else
202: suff[0] = '\0';
203:
204: msnprintf(rtmp_version, sizeof(rtmp_version), "librtmp/%d.%d%s",
205: RTMP_LIB_VERSION >> 16, (RTMP_LIB_VERSION >> 8) & 0xff,
206: suff);
207: src[i++] = rtmp_version;
208: }
209: #endif
210:
211: DEBUGASSERT(i <= VERSION_PARTS);
212:
213: outp = &out[0];
214: outlen = sizeof(out);
215: for(j = 0; j < i; j++) {
216: size_t n = strlen(src[j]);
217: /* we need room for a space, the string and the final zero */
218: if(outlen <= (n + 2))
219: break;
220: if(j) {
221: /* prepend a space if not the first */
222: *outp++ = ' ';
223: outlen--;
224: }
225: memcpy(outp, src[j], n);
226: outp += n;
227: outlen -= n;
228: }
229: *outp = 0;
230:
231: return out;
232: }
233:
234: /* data for curl_version_info
235:
236: Keep the list sorted alphabetically. It is also written so that each
237: protocol line has its own #if line to make things easier on the eye.
238: */
239:
240: static const char * const protocols[] = {
241: #ifndef CURL_DISABLE_DICT
242: "dict",
243: #endif
244: #ifndef CURL_DISABLE_FILE
245: "file",
246: #endif
247: #ifndef CURL_DISABLE_FTP
248: "ftp",
249: #endif
250: #if defined(USE_SSL) && !defined(CURL_DISABLE_FTP)
251: "ftps",
252: #endif
253: #ifndef CURL_DISABLE_GOPHER
254: "gopher",
255: #endif
256: #ifndef CURL_DISABLE_HTTP
257: "http",
258: #endif
259: #if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
260: "https",
261: #endif
262: #ifndef CURL_DISABLE_IMAP
263: "imap",
264: #endif
265: #if defined(USE_SSL) && !defined(CURL_DISABLE_IMAP)
266: "imaps",
267: #endif
268: #ifndef CURL_DISABLE_LDAP
269: "ldap",
270: #if !defined(CURL_DISABLE_LDAPS) && \
271: ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \
272: (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))
273: "ldaps",
274: #endif
275: #endif
276: #ifdef CURL_ENABLE_MQTT
277: "mqtt",
278: #endif
279: #ifndef CURL_DISABLE_POP3
280: "pop3",
281: #endif
282: #if defined(USE_SSL) && !defined(CURL_DISABLE_POP3)
283: "pop3s",
284: #endif
285: #ifdef USE_LIBRTMP
286: "rtmp",
287: #endif
288: #ifndef CURL_DISABLE_RTSP
289: "rtsp",
290: #endif
291: #if defined(USE_SSH) && !defined(USE_WOLFSSH)
292: "scp",
293: #endif
294: #ifdef USE_SSH
295: "sftp",
296: #endif
297: #if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
298: (CURL_SIZEOF_CURL_OFF_T > 4) && \
299: (!defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO))
300: "smb",
301: # ifdef USE_SSL
302: "smbs",
303: # endif
304: #endif
305: #ifndef CURL_DISABLE_SMTP
306: "smtp",
307: #endif
308: #if defined(USE_SSL) && !defined(CURL_DISABLE_SMTP)
309: "smtps",
310: #endif
311: #ifndef CURL_DISABLE_TELNET
312: "telnet",
313: #endif
314: #ifndef CURL_DISABLE_TFTP
315: "tftp",
316: #endif
317:
318: NULL
319: };
320:
321: static curl_version_info_data version_info = {
322: CURLVERSION_NOW,
323: LIBCURL_VERSION,
324: LIBCURL_VERSION_NUM,
325: OS, /* as found by configure or set by hand at build-time */
326: 0 /* features is 0 by default */
327: #ifdef ENABLE_IPV6
328: | CURL_VERSION_IPV6
329: #endif
330: #ifdef USE_SSL
331: | CURL_VERSION_SSL
332: #endif
333: #ifdef USE_NTLM
334: | CURL_VERSION_NTLM
335: #endif
336: #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
337: defined(NTLM_WB_ENABLED)
338: | CURL_VERSION_NTLM_WB
339: #endif
340: #ifdef USE_SPNEGO
341: | CURL_VERSION_SPNEGO
342: #endif
343: #ifdef USE_KERBEROS5
344: | CURL_VERSION_KERBEROS5
345: #endif
346: #ifdef HAVE_GSSAPI
347: | CURL_VERSION_GSSAPI
348: #endif
349: #ifdef USE_WINDOWS_SSPI
350: | CURL_VERSION_SSPI
351: #endif
352: #ifdef HAVE_LIBZ
353: | CURL_VERSION_LIBZ
354: #endif
355: #ifdef DEBUGBUILD
356: | CURL_VERSION_DEBUG
357: #endif
358: #ifdef CURLDEBUG
359: | CURL_VERSION_CURLDEBUG
360: #endif
361: #ifdef CURLRES_ASYNCH
362: | CURL_VERSION_ASYNCHDNS
363: #endif
364: #if (CURL_SIZEOF_CURL_OFF_T > 4) && \
365: ( (SIZEOF_OFF_T > 4) || defined(USE_WIN32_LARGE_FILES) )
366: | CURL_VERSION_LARGEFILE
367: #endif
368: #if defined(CURL_DOES_CONVERSIONS)
369: | CURL_VERSION_CONV
370: #endif
371: #if defined(USE_TLS_SRP)
372: | CURL_VERSION_TLSAUTH_SRP
373: #endif
374: #if defined(USE_NGHTTP2)
375: | CURL_VERSION_HTTP2
376: #endif
377: #if defined(ENABLE_QUIC)
378: | CURL_VERSION_HTTP3
379: #endif
380: #if defined(USE_UNIX_SOCKETS)
381: | CURL_VERSION_UNIX_SOCKETS
382: #endif
383: #if defined(USE_LIBPSL)
384: | CURL_VERSION_PSL
385: #endif
386: #if defined(CURL_WITH_MULTI_SSL)
387: | CURL_VERSION_MULTI_SSL
388: #endif
389: #if defined(HAVE_BROTLI)
390: | CURL_VERSION_BROTLI
391: #endif
392: #if defined(USE_ALTSVC)
393: | CURL_VERSION_ALTSVC
394: #endif
395: ,
396: NULL, /* ssl_version */
397: 0, /* ssl_version_num, this is kept at zero */
398: NULL, /* zlib_version */
399: protocols,
400: NULL, /* c-ares version */
401: 0, /* c-ares version numerical */
402: NULL, /* libidn version */
403: 0, /* iconv version */
404: NULL, /* ssh lib version */
405: 0, /* brotli_ver_num */
406: NULL, /* brotli version */
407: 0, /* nghttp2 version number */
408: NULL, /* nghttp2 version string */
409: NULL, /* quic library string */
410: #ifdef CURL_CA_BUNDLE
411: CURL_CA_BUNDLE, /* cainfo */
412: #else
413: NULL,
414: #endif
415: #ifdef CURL_CA_PATH
416: CURL_CA_PATH /* capath */
417: #else
418: NULL
419: #endif
420: };
421:
422: curl_version_info_data *curl_version_info(CURLversion stamp)
423: {
424: #if defined(USE_SSH)
425: static char ssh_buffer[80];
426: #endif
427: #ifdef USE_SSL
428: #ifdef CURL_WITH_MULTI_SSL
429: static char ssl_buffer[200];
430: #else
431: static char ssl_buffer[80];
432: #endif
433: #endif
434: #ifdef HAVE_BROTLI
435: static char brotli_buffer[80];
436: #endif
437:
438: #ifdef USE_SSL
439: Curl_ssl_version(ssl_buffer, sizeof(ssl_buffer));
440: version_info.ssl_version = ssl_buffer;
441: if(Curl_ssl->supports & SSLSUPP_HTTPS_PROXY)
442: version_info.features |= CURL_VERSION_HTTPS_PROXY;
443: else
444: version_info.features &= ~CURL_VERSION_HTTPS_PROXY;
445: #endif
446:
447: #ifdef HAVE_LIBZ
448: version_info.libz_version = zlibVersion();
449: /* libz left NULL if non-existing */
450: #endif
451: #ifdef USE_ARES
452: {
453: int aresnum;
454: version_info.ares = ares_version(&aresnum);
455: version_info.ares_num = aresnum;
456: }
457: #endif
458: #ifdef USE_LIBIDN2
459: /* This returns a version string if we use the given version or later,
460: otherwise it returns NULL */
461: version_info.libidn = idn2_check_version(IDN2_VERSION);
462: if(version_info.libidn)
463: version_info.features |= CURL_VERSION_IDN;
464: #elif defined(USE_WIN32_IDN)
465: version_info.features |= CURL_VERSION_IDN;
466: #endif
467:
468: #if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS)
469: #ifdef _LIBICONV_VERSION
470: version_info.iconv_ver_num = _LIBICONV_VERSION;
471: #else
472: /* version unknown */
473: version_info.iconv_ver_num = -1;
474: #endif /* _LIBICONV_VERSION */
475: #endif
476:
477: #if defined(USE_SSH)
478: Curl_ssh_version(ssh_buffer, sizeof(ssh_buffer));
479: version_info.libssh_version = ssh_buffer;
480: #endif
481:
482: #ifdef HAVE_BROTLI
483: version_info.brotli_ver_num = BrotliDecoderVersion();
484: brotli_version(brotli_buffer, sizeof(brotli_buffer));
485: version_info.brotli_version = brotli_buffer;
486: #endif
487:
488: #ifdef USE_NGHTTP2
489: {
490: nghttp2_info *h2 = nghttp2_version(0);
491: version_info.nghttp2_ver_num = h2->version_num;
492: version_info.nghttp2_version = h2->version_str;
493: }
494: #endif
495:
496: #ifdef ENABLE_QUIC
497: {
498: static char quicbuffer[80];
499: Curl_quic_ver(quicbuffer, sizeof(quicbuffer));
500: version_info.quic_version = quicbuffer;
501: }
502: #endif
503:
504: (void)stamp; /* avoid compiler warnings, we don't use this */
505: return &version_info;
506: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>