xref: /freebsd/contrib/libarchive/libarchive/archive_version_details.c (revision 185becb1e1bd2657c156f78aeb52edac05ba5fb5)
1 /*-
2  * Copyright (c) 2009-2012,2014 Michihiro NAKAJIMA
3  * Copyright (c) 2003-2007 Tim Kientzle
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #include "archive_platform.h"
28 
29 #ifdef HAVE_STDLIB_H
30 #include <stdlib.h>
31 #endif
32 #ifdef HAVE_STRING_H
33 #include <string.h>
34 #endif
35 #ifdef HAVE_ZLIB_H
36 #include <zlib.h>
37 #endif
38 #ifdef HAVE_LZMA_H
39 #include <lzma.h>
40 #endif
41 #ifdef HAVE_BZLIB_H
42 #include <bzlib.h>
43 #endif
44 #ifdef HAVE_LZ4_H
45 #include <lz4.h>
46 #endif
47 #ifdef HAVE_ZSTD_H
48 #include <zstd.h>
49 #include <stdio.h>
50 #endif
51 #ifdef HAVE_LZO_LZOCONF_H
52 #include <lzo/lzoconf.h>
53 #endif
54 #if HAVE_LIBXML_XMLVERSION_H
55 #include <libxml/xmlversion.h>
56 #elif HAVE_BSDXML_H
57 #include <bsdxml.h>
58 #elif HAVE_EXPAT_H
59 #include <expat.h>
60 #endif
61 #if HAVE_MBEDTLS_VERSION_H
62 #include <mbedtls/version.h>
63 #endif
64 #if HAVE_NETTLE_VERSION_H
65 #include <nettle/version.h>
66 #include <stdio.h>
67 #endif
68 #if HAVE_OPENSSL_OPENSSLV_H
69 #include <openssl/opensslv.h>
70 #include <stdio.h>
71 #endif
72 #if HAVE_ICONV_H
73 #include <iconv.h>
74 #endif
75 #if HAVE_PCRE_H
76 #include <pcre.h>
77 #endif
78 #if HAVE_PCRE2_H
79 #include <pcre2.h>
80 #endif
81 
82 #include "archive.h"
83 #include "archive_private.h"
84 #include "archive_string.h"
85 #include "archive_cryptor_private.h"
86 #include "archive_digest_private.h"
87 
88 static void
archive_regex_version(struct archive_string * str)89 archive_regex_version(struct archive_string* str)
90 {
91 #if HAVE_LIBPCREPOSIX && HAVE_PCRE_H
92 	archive_strcat(str, " libpcre/");
93 	archive_strcat(str, archive_libpcre_version());
94 #elif HAVE_LIBPCRE2POSIX && HAVE_PCRE2_H
95 	archive_strcat(str, " libpcre2/");
96 	archive_strcat(str, archive_libpcre2_version());
97 #else
98 	(void)str; /* UNUSED */
99 #endif
100 }
101 
102 static void
archive_xml_version(struct archive_string * str)103 archive_xml_version(struct archive_string* str)
104 {
105 #if HAVE_LIBXML_XMLVERSION_H && HAVE_LIBXML2
106 	archive_strcat(str, " libxml2/");
107 	archive_strcat(str, archive_libxml2_version());
108 #elif HAVE_BSDXML_H && HAVE_LIBBSDXML
109 	archive_strcat(str, " bsdxml/");
110 	archive_strcat(str, archive_libbsdxml_version());
111 #elif HAVE_EXPAT_H && HAVE_LIBEXPAT
112 	archive_strcat(str, " expat/");
113 	archive_strcat(str, archive_libexpat_version());
114 #else
115 	(void)str; /* UNUSED */
116 #endif
117 }
118 
119 static void
archive_libb2_version(struct archive_string * str)120 archive_libb2_version(struct archive_string* str)
121 {
122 	archive_strcat(str, " libb2/");
123 #if HAVE_BLAKE2_H && HAVE_LIBB2
124 #if defined(LIBB2_PKGCONFIG_VERSION)
125 	archive_strcat(str, LIBB2_PKGCONFIG_VERSION);
126 #else
127 	archive_strcat(str, "system");
128 #endif
129 #else
130 	archive_strcat(str, "bundled");
131 #endif
132 }
133 
134 static void
archive_crypto_version(struct archive_string * str)135 archive_crypto_version(struct archive_string* str)
136 {
137 #if defined(ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto)
138 	archive_strcat(str, " CommonCrypto/");
139 	archive_strcat(str, archive_commoncrypto_version());
140 #endif
141 #if defined(ARCHIVE_CRYPTOR_USE_CNG)
142 	archive_strcat(str, " cng/");
143 	archive_strcat(str, archive_cng_version());
144 #endif
145 #if defined(ARCHIVE_CRYPTOR_USE_MBED)
146 	archive_strcat(str, " mbedtls/");
147 	archive_strcat(str, archive_mbedtls_version());
148 #endif
149 #if defined(ARCHIVE_CRYPTOR_USE_NETTLE)
150 	archive_strcat(str, " nettle/");
151 	archive_strcat(str, archive_nettle_version());
152 #endif
153 #if defined(ARCHIVE_CRYPTOR_USE_OPENSSL)
154 	archive_strcat(str, " openssl/");
155 	archive_strcat(str, archive_openssl_version());
156 #endif
157 #if defined(ARCHIVE_CRYPTOR_USE_LIBMD)
158 	archive_strcat(str, " libmd/");
159 	archive_strcat(str, archive_libmd_version());
160 #endif
161 	// Just in case
162 	(void)str; /* UNUSED */
163 }
164 
165 const char *
archive_version_details(void)166 archive_version_details(void)
167 {
168 	static struct archive_string str;
169 	static int init = 0;
170 	const char *zlib = archive_zlib_version();
171 	const char *liblzma = archive_liblzma_version();
172 	const char *bzlib = archive_bzlib_version();
173 	const char *liblz4 = archive_liblz4_version();
174 	const char *libzstd = archive_libzstd_version();
175 	const char *liblzo = archive_liblzo2_version();
176 	const char *libiconv = archive_libiconv_version();
177 	const char *libacl = archive_libacl_version();
178 	const char *librichacl = archive_librichacl_version();
179 	const char *libattr = archive_libattr_version();
180 
181 	if (!init) {
182 		archive_string_init(&str);
183 
184 		archive_strcat(&str, ARCHIVE_VERSION_STRING);
185 		if (zlib) {
186 			archive_strcat(&str, " zlib/");
187 			archive_strcat(&str, zlib);
188 		}
189 		if (liblzma) {
190 			archive_strcat(&str, " liblzma/");
191 			archive_strcat(&str, liblzma);
192 		}
193 		if (bzlib) {
194 			const char *p = bzlib;
195 			const char *sep = strchr(p, ',');
196 			if (sep == NULL)
197 				sep = p + strlen(p);
198 			archive_strcat(&str, " bz2lib/");
199 			archive_strncat(&str, p, sep - p);
200 		}
201 		if (liblz4) {
202 			archive_strcat(&str, " liblz4/");
203 			archive_strcat(&str, liblz4);
204 		}
205 		if (libzstd) {
206 			archive_strcat(&str, " libzstd/");
207 			archive_strcat(&str, libzstd);
208 		}
209 		if (liblzo) {
210 			archive_strcat(&str, " liblzo2/");
211 			archive_strcat(&str, liblzo);
212 		}
213 		archive_xml_version(&str);
214 		archive_regex_version(&str);
215 		archive_crypto_version(&str);
216 		archive_libb2_version(&str);
217 		if (librichacl) {
218 			archive_strcat(&str, " librichacl/");
219 			archive_strcat(&str, librichacl);
220 		}
221 		if (libacl) {
222 			archive_strcat(&str, " libacl/");
223 			archive_strcat(&str, libacl);
224 		}
225 		if (libattr) {
226 			archive_strcat(&str, " libattr/");
227 			archive_strcat(&str, libattr);
228 		}
229 		if (libiconv) {
230 			archive_strcat(&str, " libiconv/");
231 			archive_strcat(&str, libiconv);
232 		}
233 		init = 1;
234 	}
235 	return str.s;
236 }
237 
238 const char *
archive_zlib_version(void)239 archive_zlib_version(void)
240 {
241 #if HAVE_ZLIB_H && HAVE_LIBZ
242 	return zlibVersion();
243 #else
244 	return NULL;
245 #endif
246 }
247 
248 const char *
archive_liblzma_version(void)249 archive_liblzma_version(void)
250 {
251 #if HAVE_LZMA_H && HAVE_LIBLZMA
252 	return lzma_version_string();
253 #else
254 	return NULL;
255 #endif
256 }
257 
258 const char *
archive_bzlib_version(void)259 archive_bzlib_version(void)
260 {
261 #if HAVE_BZLIB_H && HAVE_LIBBZ2
262 	return BZ2_bzlibVersion();
263 #else
264 	return NULL;
265 #endif
266 }
267 
268 const char *
archive_liblz4_version(void)269 archive_liblz4_version(void)
270 {
271 #if HAVE_LZ4_H && HAVE_LIBLZ4
272 #if LZ4_VERSION_NUMBER > 10705
273 	return LZ4_versionString();
274 #elif LZ4_VERSION_NUMBER > 10300
275 	div_t major = div(LZ4_versionNumber(), 10000);
276 	div_t minor = div(major.rem, 100);
277 	static char lz4_version[9];
278 	snprintf(lz4_version, 9, "%d.%d.%d", major.quot, minor.quot, minor.rem);
279 	return lz4_version;
280 #else
281 #define str(s) #s
282 #define NUMBER(x) str(x)
283 	return NUMBER(LZ4_VERSION_MAJOR) "." NUMBER(LZ4_VERSION_MINOR) "." NUMBER(LZ4_VERSION_RELEASE);
284 #undef NUMBER
285 #undef str
286 #endif
287 #else
288 	return NULL;
289 #endif
290 }
291 
292 const char *
archive_libzstd_version(void)293 archive_libzstd_version(void)
294 {
295 #if HAVE_ZSTD_H && HAVE_LIBZSTD
296 #if ZSTD_VERSION_NUMBER > 10300
297 	return ZSTD_versionString();
298 #else
299 	div_t major = div(ZSTD_versionNumber(), 10000);
300 	div_t minor = div(major.rem, 100);
301 	static char zstd_version[9];
302 	snprintf(zstd_version, 9, "%d.%d.%d", major.quot, minor.quot, minor.rem);
303 	return zstd_version;
304 #endif
305 #else
306 	return NULL;
307 #endif
308 }
309 
310 const char *
archive_liblzo2_version(void)311 archive_liblzo2_version(void)
312 {
313 #if HAVE_LZO_LZOCONF_H && HAVE_LIBLZO2
314 	return LZO_VERSION_STRING;
315 #else
316 	return NULL;
317 #endif
318 }
319 
320 const char *
archive_libbsdxml_version(void)321 archive_libbsdxml_version(void)
322 {
323 #if HAVE_BSDXML_H && HAVE_LIBBSDXML
324 	return XML_ExpatVersion();
325 #else
326 	return NULL;
327 #endif
328 }
329 
330 const char *
archive_libxml2_version(void)331 archive_libxml2_version(void)
332 {
333 #if HAVE_LIBXML_XMLVERSION_H && HAVE_LIBXML2
334 	return LIBXML_DOTTED_VERSION;
335 #else
336 	return NULL;
337 #endif
338 }
339 
340 const char *
archive_libexpat_version(void)341 archive_libexpat_version(void)
342 {
343 #if HAVE_EXPAT_H && HAVE_LIBEXPAT
344 	return XML_ExpatVersion();
345 #else
346 	return NULL;
347 #endif
348 }
349 
350 const char *
archive_mbedtls_version(void)351 archive_mbedtls_version(void)
352 {
353 #if defined(ARCHIVE_CRYPTOR_USE_MBED) || defined(ARCHIVE_CRYPTO_MBED)
354 	static char mbed_version[9];
355 	mbedtls_version_get_string(mbed_version);
356 	return mbed_version;
357 #else
358 	return NULL;
359 #endif
360 }
361 
362 const char *
archive_nettle_version(void)363 archive_nettle_version(void)
364 {
365 #if defined(ARCHIVE_CRYPTOR_USE_NETTLE) || defined(ARCHIVE_CRYPTO_NETTLE)
366 	static char nettle_version[6];
367 	snprintf(nettle_version, 6, "%d.%d", nettle_version_major(), nettle_version_minor());
368 	return nettle_version;
369 #else
370 	return NULL;
371 #endif
372 }
373 
374 const char *
archive_openssl_version(void)375 archive_openssl_version(void)
376 {
377 #if defined(ARCHIVE_CRYPTOR_USE_OPENSSL) || defined(ARCHIVE_CRYPTO_OPENSSL)
378 #ifdef OPENSSL_VERSION_STR
379 	return OPENSSL_VERSION_STR;
380 #else
381 #define OPENSSL_MAJOR (OPENSSL_VERSION_NUMBER >> 28)
382 #define OPENSSL_MINOR ((OPENSSL_VERSION_NUMBER >> 20) & 0xFF)
383 	static char openssl_version[6];
384 	snprintf(openssl_version, 6, "%ld.%ld", OPENSSL_MAJOR, OPENSSL_MINOR);
385 	return openssl_version;
386 #undef OPENSSL_MAJOR
387 #undef OPENSSL_MINOR
388 #endif
389 #else
390 	return NULL;
391 #endif
392 }
393 
394 const char *
archive_libmd_version(void)395 archive_libmd_version(void)
396 {
397 #if defined(ARCHIVE_CRYPTOR_USE_LIBMD) || defined(ARCHIVE_CRYPTO_LIBMD)
398 	return "system";
399 #else
400 	return NULL;
401 #endif
402 }
403 
404 const char *
archive_commoncrypto_version(void)405 archive_commoncrypto_version(void)
406 {
407 #if defined(ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto) || defined(ARCHIVE_CRYPTO_CommonCrypto)
408 	return "system";
409 #else
410 	return NULL;
411 #endif
412 }
413 
414 const char *
archive_cng_version(void)415 archive_cng_version(void)
416 {
417 #if defined(ARCHIVE_CRYPTOR_USE_CNG) || defined(ARCHIVE_CRYPTO_CNG)
418 #ifdef BCRYPT_HASH_INTERFACE_MAJORVERSION_2
419 	return "2.0";
420 #else
421 	return "1.0";
422 #endif
423 #else
424 	return NULL;
425 #endif
426 }
427 
428 const char *
archive_wincrypt_version(void)429 archive_wincrypt_version(void)
430 {
431 	return NULL;
432 }
433 
434 const char *
archive_librichacl_version(void)435 archive_librichacl_version(void)
436 {
437 #if HAVE_LIBRICHACL
438 #if defined(LIBRICHACL_PKGCONFIG_VERSION)
439 	return LIBRICHACL_PKGCONFIG_VERSION;
440 #else
441 	return "system";
442 #endif
443 #else
444 	return NULL;
445 #endif
446 }
447 
448 const char *
archive_libacl_version(void)449 archive_libacl_version(void)
450 {
451 #if HAVE_LIBACL
452 #if defined(LIBACL_PKGCONFIG_VERSION)
453 	return LIBACL_PKGCONFIG_VERSION;
454 #else
455 	return "system";
456 #endif
457 #else
458 	return NULL;
459 #endif
460 }
461 
462 const char *
archive_libattr_version(void)463 archive_libattr_version(void)
464 {
465 #if HAVE_LIBATTR
466 #if defined(LIBATTR_PKGCONFIG_VERSION)
467 	return LIBATTR_PKGCONFIG_VERSION;
468 #else
469 	return "system";
470 #endif
471 #else
472 	return NULL;
473 #endif
474 }
475 
476 const char *
archive_libiconv_version(void)477 archive_libiconv_version(void)
478 {
479 #if HAVE_LIBCHARSET && HAVE_ICONV_H
480 	char major = _libiconv_version >> 8;
481 	char minor = _libiconv_version & 0xFF;
482 	static char charset_version[6];
483 	snprintf(charset_version, 6, "%hhd.%hhd", major, minor);
484 	return charset_version;
485 #else
486 	return NULL;
487 #endif
488 }
489 
490 const char *
archive_libpcre_version(void)491 archive_libpcre_version(void)
492 {
493 #if HAVE_LIBPCREPOSIX && HAVE_PCRE_H
494 #define str(s) #s
495 #define NUMBER(x) str(x)
496 	return NUMBER(PCRE_MAJOR) "." NUMBER(PCRE_MINOR);
497 #undef NUMBER
498 #undef str
499 #else
500 	return NULL;
501 #endif
502 }
503 
504 const char *
archive_libpcre2_version(void)505 archive_libpcre2_version(void)
506 {
507 #if HAVE_LIBPCRE2POSIX && HAVE_PCRE2_H
508 #define str(s) #s
509 #define NUMBER(x) str(x)
510 	return NUMBER(PCRE2_MAJOR) "." NUMBER(PCRE2_MINOR);
511 #undef NUMBER
512 #undef str
513 #else
514 	return NULL;
515 #endif
516 }
517