archive_util.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649
  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. #include "archive_platform.h"
  27. __FBSDID("$FreeBSD: head/lib/libarchive/archive_util.c 201098 2009-12-28 02:58:14Z kientzle $");
  28. #ifdef HAVE_SYS_TYPES_H
  29. #include <sys/types.h>
  30. #endif
  31. #ifdef HAVE_ERRNO_H
  32. #include <errno.h>
  33. #endif
  34. #ifdef HAVE_FCNTL_H
  35. #include <fcntl.h>
  36. #endif
  37. #ifdef HAVE_STDLIB_H
  38. #include <stdlib.h>
  39. #endif
  40. #ifdef HAVE_STRING_H
  41. #include <string.h>
  42. #endif
  43. #if defined(HAVE_WINCRYPT_H) && !defined(__CYGWIN__)
  44. #include <wincrypt.h>
  45. #endif
  46. #ifdef HAVE_ZLIB_H
  47. #include <cm_zlib.h>
  48. #endif
  49. #ifdef HAVE_LZMA_H
  50. #include <cm_lzma.h>
  51. #endif
  52. #ifdef HAVE_BZLIB_H
  53. #include <cm_bzlib.h>
  54. #endif
  55. #ifdef HAVE_LZ4_H
  56. #include <lz4.h>
  57. #endif
  58. #include "archive.h"
  59. #include "archive_private.h"
  60. #include "archive_random_private.h"
  61. #include "archive_string.h"
  62. #ifndef O_CLOEXEC
  63. #define O_CLOEXEC 0
  64. #endif
  65. static int archive_utility_string_sort_helper(char **, unsigned int);
  66. /* Generic initialization of 'struct archive' objects. */
  67. int
  68. __archive_clean(struct archive *a)
  69. {
  70. archive_string_conversion_free(a);
  71. return (ARCHIVE_OK);
  72. }
  73. int
  74. archive_version_number(void)
  75. {
  76. return (ARCHIVE_VERSION_NUMBER);
  77. }
  78. const char *
  79. archive_version_string(void)
  80. {
  81. return (ARCHIVE_VERSION_STRING);
  82. }
  83. int
  84. archive_errno(struct archive *a)
  85. {
  86. return (a->archive_error_number);
  87. }
  88. const char *
  89. archive_error_string(struct archive *a)
  90. {
  91. if (a->error != NULL && *a->error != '\0')
  92. return (a->error);
  93. else
  94. return (NULL);
  95. }
  96. int
  97. archive_file_count(struct archive *a)
  98. {
  99. return (a->file_count);
  100. }
  101. int
  102. archive_format(struct archive *a)
  103. {
  104. return (a->archive_format);
  105. }
  106. const char *
  107. archive_format_name(struct archive *a)
  108. {
  109. return (a->archive_format_name);
  110. }
  111. int
  112. archive_compression(struct archive *a)
  113. {
  114. return archive_filter_code(a, 0);
  115. }
  116. const char *
  117. archive_compression_name(struct archive *a)
  118. {
  119. return archive_filter_name(a, 0);
  120. }
  121. /*
  122. * Return a count of the number of compressed bytes processed.
  123. */
  124. la_int64_t
  125. archive_position_compressed(struct archive *a)
  126. {
  127. return archive_filter_bytes(a, -1);
  128. }
  129. /*
  130. * Return a count of the number of uncompressed bytes processed.
  131. */
  132. la_int64_t
  133. archive_position_uncompressed(struct archive *a)
  134. {
  135. return archive_filter_bytes(a, 0);
  136. }
  137. void
  138. archive_clear_error(struct archive *a)
  139. {
  140. archive_string_empty(&a->error_string);
  141. a->error = NULL;
  142. a->archive_error_number = 0;
  143. }
  144. void
  145. archive_set_error(struct archive *a, int error_number, const char *fmt, ...)
  146. {
  147. va_list ap;
  148. a->archive_error_number = error_number;
  149. if (fmt == NULL) {
  150. a->error = NULL;
  151. return;
  152. }
  153. archive_string_empty(&(a->error_string));
  154. va_start(ap, fmt);
  155. archive_string_vsprintf(&(a->error_string), fmt, ap);
  156. va_end(ap);
  157. a->error = a->error_string.s;
  158. }
  159. void
  160. archive_copy_error(struct archive *dest, struct archive *src)
  161. {
  162. dest->archive_error_number = src->archive_error_number;
  163. archive_string_copy(&dest->error_string, &src->error_string);
  164. dest->error = dest->error_string.s;
  165. }
  166. void
  167. __archive_errx(int retvalue, const char *msg)
  168. {
  169. static const char msg1[] = "Fatal Internal Error in libarchive: ";
  170. size_t s;
  171. s = write(2, msg1, strlen(msg1));
  172. (void)s; /* UNUSED */
  173. s = write(2, msg, strlen(msg));
  174. (void)s; /* UNUSED */
  175. s = write(2, "\n", 1);
  176. (void)s; /* UNUSED */
  177. exit(retvalue);
  178. }
  179. /*
  180. * Create a temporary file
  181. */
  182. #if defined(_WIN32) && !defined(__CYGWIN__)
  183. /*
  184. * Do not use Windows tmpfile() function.
  185. * It will make a temporary file under the root directory
  186. * and it'll cause permission error if a user who is
  187. * non-Administrator creates temporary files.
  188. * Also Windows version of mktemp family including _mktemp_s
  189. * are not secure.
  190. */
  191. static int
  192. __archive_mktempx(const char *tmpdir, wchar_t *template)
  193. {
  194. static const wchar_t prefix[] = L"libarchive_";
  195. static const wchar_t suffix[] = L"XXXXXXXXXX";
  196. static const wchar_t num[] = {
  197. L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7',
  198. L'8', L'9', L'A', L'B', L'C', L'D', L'E', L'F',
  199. L'G', L'H', L'I', L'J', L'K', L'L', L'M', L'N',
  200. L'O', L'P', L'Q', L'R', L'S', L'T', L'U', L'V',
  201. L'W', L'X', L'Y', L'Z', L'a', L'b', L'c', L'd',
  202. L'e', L'f', L'g', L'h', L'i', L'j', L'k', L'l',
  203. L'm', L'n', L'o', L'p', L'q', L'r', L's', L't',
  204. L'u', L'v', L'w', L'x', L'y', L'z'
  205. };
  206. HCRYPTPROV hProv;
  207. struct archive_wstring temp_name;
  208. wchar_t *ws;
  209. DWORD attr;
  210. wchar_t *xp, *ep;
  211. int fd;
  212. hProv = (HCRYPTPROV)NULL;
  213. fd = -1;
  214. ws = NULL;
  215. if (template == NULL) {
  216. archive_string_init(&temp_name);
  217. /* Get a temporary directory. */
  218. if (tmpdir == NULL) {
  219. size_t l;
  220. wchar_t *tmp;
  221. l = GetTempPathW(0, NULL);
  222. if (l == 0) {
  223. la_dosmaperr(GetLastError());
  224. goto exit_tmpfile;
  225. }
  226. tmp = malloc(l*sizeof(wchar_t));
  227. if (tmp == NULL) {
  228. errno = ENOMEM;
  229. goto exit_tmpfile;
  230. }
  231. GetTempPathW((DWORD)l, tmp);
  232. archive_wstrcpy(&temp_name, tmp);
  233. free(tmp);
  234. } else {
  235. if (archive_wstring_append_from_mbs(&temp_name, tmpdir,
  236. strlen(tmpdir)) < 0)
  237. goto exit_tmpfile;
  238. if (temp_name.s[temp_name.length-1] != L'/')
  239. archive_wstrappend_wchar(&temp_name, L'/');
  240. }
  241. /* Check if temp_name is a directory. */
  242. attr = GetFileAttributesW(temp_name.s);
  243. if (attr == (DWORD)-1) {
  244. if (GetLastError() != ERROR_FILE_NOT_FOUND) {
  245. la_dosmaperr(GetLastError());
  246. goto exit_tmpfile;
  247. }
  248. ws = __la_win_permissive_name_w(temp_name.s);
  249. if (ws == NULL) {
  250. errno = EINVAL;
  251. goto exit_tmpfile;
  252. }
  253. attr = GetFileAttributesW(ws);
  254. if (attr == (DWORD)-1) {
  255. la_dosmaperr(GetLastError());
  256. goto exit_tmpfile;
  257. }
  258. }
  259. if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) {
  260. errno = ENOTDIR;
  261. goto exit_tmpfile;
  262. }
  263. /*
  264. * Create a temporary file.
  265. */
  266. archive_wstrcat(&temp_name, prefix);
  267. archive_wstrcat(&temp_name, suffix);
  268. ep = temp_name.s + archive_strlen(&temp_name);
  269. xp = ep - wcslen(suffix);
  270. template = temp_name.s;
  271. } else {
  272. xp = wcschr(template, L'X');
  273. if (xp == NULL) /* No X, programming error */
  274. abort();
  275. for (ep = xp; *ep == L'X'; ep++)
  276. continue;
  277. if (*ep) /* X followed by non X, programming error */
  278. abort();
  279. }
  280. if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
  281. CRYPT_VERIFYCONTEXT)) {
  282. la_dosmaperr(GetLastError());
  283. goto exit_tmpfile;
  284. }
  285. for (;;) {
  286. wchar_t *p;
  287. HANDLE h;
  288. /* Generate a random file name through CryptGenRandom(). */
  289. p = xp;
  290. if (!CryptGenRandom(hProv, (DWORD)(ep - p)*sizeof(wchar_t),
  291. (BYTE*)p)) {
  292. la_dosmaperr(GetLastError());
  293. goto exit_tmpfile;
  294. }
  295. for (; p < ep; p++)
  296. *p = num[((DWORD)*p) % (sizeof(num)/sizeof(num[0]))];
  297. free(ws);
  298. ws = __la_win_permissive_name_w(template);
  299. if (ws == NULL) {
  300. errno = EINVAL;
  301. goto exit_tmpfile;
  302. }
  303. if (template == temp_name.s) {
  304. attr = FILE_ATTRIBUTE_TEMPORARY |
  305. FILE_FLAG_DELETE_ON_CLOSE;
  306. } else {
  307. /* mkstemp */
  308. attr = FILE_ATTRIBUTE_NORMAL;
  309. }
  310. h = CreateFileW(ws,
  311. GENERIC_READ | GENERIC_WRITE | DELETE,
  312. 0,/* Not share */
  313. NULL,
  314. CREATE_NEW,/* Create a new file only */
  315. attr,
  316. NULL);
  317. if (h == INVALID_HANDLE_VALUE) {
  318. /* The same file already exists. retry with
  319. * a new filename. */
  320. if (GetLastError() == ERROR_FILE_EXISTS)
  321. continue;
  322. /* Otherwise, fail creation temporary file. */
  323. la_dosmaperr(GetLastError());
  324. goto exit_tmpfile;
  325. }
  326. fd = _open_osfhandle((intptr_t)h, _O_BINARY | _O_RDWR);
  327. if (fd == -1) {
  328. CloseHandle(h);
  329. goto exit_tmpfile;
  330. } else
  331. break;/* success! */
  332. }
  333. exit_tmpfile:
  334. if (hProv != (HCRYPTPROV)NULL)
  335. CryptReleaseContext(hProv, 0);
  336. free(ws);
  337. if (template == temp_name.s)
  338. archive_wstring_free(&temp_name);
  339. return (fd);
  340. }
  341. int
  342. __archive_mktemp(const char *tmpdir)
  343. {
  344. return __archive_mktempx(tmpdir, NULL);
  345. }
  346. int
  347. __archive_mkstemp(wchar_t *template)
  348. {
  349. return __archive_mktempx(NULL, template);
  350. }
  351. #else
  352. static int
  353. get_tempdir(struct archive_string *temppath)
  354. {
  355. const char *tmp;
  356. tmp = getenv("TMPDIR");
  357. if (tmp == NULL)
  358. #ifdef _PATH_TMP
  359. tmp = _PATH_TMP;
  360. #else
  361. tmp = "/tmp";
  362. #endif
  363. archive_strcpy(temppath, tmp);
  364. if (temppath->s[temppath->length-1] != '/')
  365. archive_strappend_char(temppath, '/');
  366. return (ARCHIVE_OK);
  367. }
  368. #if defined(HAVE_MKSTEMP)
  369. /*
  370. * We can use mkstemp().
  371. */
  372. int
  373. __archive_mktemp(const char *tmpdir)
  374. {
  375. struct archive_string temp_name;
  376. int fd = -1;
  377. archive_string_init(&temp_name);
  378. if (tmpdir == NULL) {
  379. if (get_tempdir(&temp_name) != ARCHIVE_OK)
  380. goto exit_tmpfile;
  381. } else {
  382. archive_strcpy(&temp_name, tmpdir);
  383. if (temp_name.s[temp_name.length-1] != '/')
  384. archive_strappend_char(&temp_name, '/');
  385. }
  386. archive_strcat(&temp_name, "libarchive_XXXXXX");
  387. fd = mkstemp(temp_name.s);
  388. if (fd < 0)
  389. goto exit_tmpfile;
  390. __archive_ensure_cloexec_flag(fd);
  391. unlink(temp_name.s);
  392. exit_tmpfile:
  393. archive_string_free(&temp_name);
  394. return (fd);
  395. }
  396. int
  397. __archive_mkstemp(char *template)
  398. {
  399. int fd = -1;
  400. fd = mkstemp(template);
  401. if (fd >= 0)
  402. __archive_ensure_cloexec_flag(fd);
  403. return (fd);
  404. }
  405. #else /* !HAVE_MKSTEMP */
  406. /*
  407. * We use a private routine.
  408. */
  409. static int
  410. __archive_mktempx(const char *tmpdir, char *template)
  411. {
  412. static const char num[] = {
  413. '0', '1', '2', '3', '4', '5', '6', '7',
  414. '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
  415. 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
  416. 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
  417. 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
  418. 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
  419. 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
  420. 'u', 'v', 'w', 'x', 'y', 'z'
  421. };
  422. struct archive_string temp_name;
  423. struct stat st;
  424. int fd;
  425. char *tp, *ep;
  426. fd = -1;
  427. if (template == NULL) {
  428. archive_string_init(&temp_name);
  429. if (tmpdir == NULL) {
  430. if (get_tempdir(&temp_name) != ARCHIVE_OK)
  431. goto exit_tmpfile;
  432. } else
  433. archive_strcpy(&temp_name, tmpdir);
  434. if (temp_name.s[temp_name.length-1] == '/') {
  435. temp_name.s[temp_name.length-1] = '\0';
  436. temp_name.length --;
  437. }
  438. if (la_stat(temp_name.s, &st) < 0)
  439. goto exit_tmpfile;
  440. if (!S_ISDIR(st.st_mode)) {
  441. errno = ENOTDIR;
  442. goto exit_tmpfile;
  443. }
  444. archive_strcat(&temp_name, "/libarchive_");
  445. tp = temp_name.s + archive_strlen(&temp_name);
  446. archive_strcat(&temp_name, "XXXXXXXXXX");
  447. ep = temp_name.s + archive_strlen(&temp_name);
  448. template = temp_name.s;
  449. } else {
  450. tp = strchr(template, 'X');
  451. if (tp == NULL) /* No X, programming error */
  452. abort();
  453. for (ep = tp; *ep == 'X'; ep++)
  454. continue;
  455. if (*ep) /* X followed by non X, programming error */
  456. abort();
  457. }
  458. do {
  459. char *p;
  460. p = tp;
  461. archive_random(p, ep - p);
  462. while (p < ep) {
  463. int d = *((unsigned char *)p) % sizeof(num);
  464. *p++ = num[d];
  465. }
  466. fd = open(template, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC,
  467. 0600);
  468. } while (fd < 0 && errno == EEXIST);
  469. if (fd < 0)
  470. goto exit_tmpfile;
  471. __archive_ensure_cloexec_flag(fd);
  472. if (template == temp_name.s)
  473. unlink(temp_name.s);
  474. exit_tmpfile:
  475. if (template == temp_name.s)
  476. archive_string_free(&temp_name);
  477. return (fd);
  478. }
  479. int
  480. __archive_mktemp(const char *tmpdir)
  481. {
  482. return __archive_mktempx(tmpdir, NULL);
  483. }
  484. int
  485. __archive_mkstemp(char *template)
  486. {
  487. return __archive_mktempx(NULL, template);
  488. }
  489. #endif /* !HAVE_MKSTEMP */
  490. #endif /* !_WIN32 || __CYGWIN__ */
  491. /*
  492. * Set FD_CLOEXEC flag to a file descriptor if it is not set.
  493. * We have to set the flag if the platform does not provide O_CLOEXEC
  494. * or F_DUPFD_CLOEXEC flags.
  495. *
  496. * Note: This function is absolutely called after creating a new file
  497. * descriptor even if the platform seemingly provides O_CLOEXEC or
  498. * F_DUPFD_CLOEXEC macros because it is possible that the platform
  499. * merely declares those macros, especially Linux 2.6.18 - 2.6.24 do it.
  500. */
  501. void
  502. __archive_ensure_cloexec_flag(int fd)
  503. {
  504. #if defined(_WIN32) && !defined(__CYGWIN__)
  505. (void)fd; /* UNUSED */
  506. #else
  507. int flags;
  508. if (fd >= 0) {
  509. flags = fcntl(fd, F_GETFD);
  510. if (flags != -1 && (flags & FD_CLOEXEC) == 0)
  511. fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
  512. }
  513. #endif
  514. }
  515. /*
  516. * Utility function to sort a group of strings using quicksort.
  517. */
  518. static int
  519. archive_utility_string_sort_helper(char **strings, unsigned int n)
  520. {
  521. unsigned int i, lesser_count, greater_count;
  522. char **lesser, **greater, **tmp, *pivot;
  523. int retval1, retval2;
  524. /* A list of 0 or 1 elements is already sorted */
  525. if (n <= 1)
  526. return (ARCHIVE_OK);
  527. lesser_count = greater_count = 0;
  528. lesser = greater = NULL;
  529. pivot = strings[0];
  530. for (i = 1; i < n; i++)
  531. {
  532. if (strcmp(strings[i], pivot) < 0)
  533. {
  534. lesser_count++;
  535. tmp = (char **)realloc(lesser,
  536. lesser_count * sizeof(char *));
  537. if (!tmp) {
  538. free(greater);
  539. free(lesser);
  540. return (ARCHIVE_FATAL);
  541. }
  542. lesser = tmp;
  543. lesser[lesser_count - 1] = strings[i];
  544. }
  545. else
  546. {
  547. greater_count++;
  548. tmp = (char **)realloc(greater,
  549. greater_count * sizeof(char *));
  550. if (!tmp) {
  551. free(greater);
  552. free(lesser);
  553. return (ARCHIVE_FATAL);
  554. }
  555. greater = tmp;
  556. greater[greater_count - 1] = strings[i];
  557. }
  558. }
  559. /* quicksort(lesser) */
  560. retval1 = archive_utility_string_sort_helper(lesser, lesser_count);
  561. for (i = 0; i < lesser_count; i++)
  562. strings[i] = lesser[i];
  563. free(lesser);
  564. /* pivot */
  565. strings[lesser_count] = pivot;
  566. /* quicksort(greater) */
  567. retval2 = archive_utility_string_sort_helper(greater, greater_count);
  568. for (i = 0; i < greater_count; i++)
  569. strings[lesser_count + 1 + i] = greater[i];
  570. free(greater);
  571. return (retval1 < retval2) ? retval1 : retval2;
  572. }
  573. int
  574. archive_utility_string_sort(char **strings)
  575. {
  576. unsigned int size = 0;
  577. while (strings[size] != NULL)
  578. size++;
  579. return archive_utility_string_sort_helper(strings, size);
  580. }