archive_match.c 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841
  1. /*-
  2. * Copyright (c) 2003-2007 Tim Kientzle
  3. * Copyright (c) 2012 Michihiro NAKAJIMA
  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$");
  28. #ifdef HAVE_ERRNO_H
  29. #include <errno.h>
  30. #endif
  31. #ifdef HAVE_STDLIB_H
  32. #include <stdlib.h>
  33. #endif
  34. #ifdef HAVE_STRING_H
  35. #include <string.h>
  36. #endif
  37. #include "archive.h"
  38. #include "archive_private.h"
  39. #include "archive_entry.h"
  40. #include "archive_pathmatch.h"
  41. #include "archive_rb.h"
  42. #include "archive_string.h"
  43. struct match {
  44. struct match *next;
  45. int matches;
  46. struct archive_mstring pattern;
  47. };
  48. struct match_list {
  49. struct match *first;
  50. struct match **last;
  51. int count;
  52. int unmatched_count;
  53. struct match *unmatched_next;
  54. int unmatched_eof;
  55. };
  56. struct match_file {
  57. struct archive_rb_node node;
  58. struct match_file *next;
  59. struct archive_mstring pathname;
  60. int flag;
  61. time_t mtime_sec;
  62. long mtime_nsec;
  63. time_t ctime_sec;
  64. long ctime_nsec;
  65. };
  66. struct entry_list {
  67. struct match_file *first;
  68. struct match_file **last;
  69. int count;
  70. };
  71. struct id_array {
  72. size_t size;/* Allocated size */
  73. size_t count;
  74. int64_t *ids;
  75. };
  76. #define PATTERN_IS_SET 1
  77. #define TIME_IS_SET 2
  78. #define ID_IS_SET 4
  79. struct archive_match {
  80. struct archive archive;
  81. /* exclusion/inclusion set flag. */
  82. int setflag;
  83. /*
  84. * Matching filename patterns.
  85. */
  86. struct match_list exclusions;
  87. struct match_list inclusions;
  88. /*
  89. * Matching time stamps.
  90. */
  91. time_t now;
  92. int newer_mtime_filter;
  93. time_t newer_mtime_sec;
  94. long newer_mtime_nsec;
  95. int newer_ctime_filter;
  96. time_t newer_ctime_sec;
  97. long newer_ctime_nsec;
  98. int older_mtime_filter;
  99. time_t older_mtime_sec;
  100. long older_mtime_nsec;
  101. int older_ctime_filter;
  102. time_t older_ctime_sec;
  103. long older_ctime_nsec;
  104. /*
  105. * Matching time stamps with its filename.
  106. */
  107. struct archive_rb_tree exclusion_tree;
  108. struct entry_list exclusion_entry_list;
  109. /*
  110. * Matching file owners.
  111. */
  112. struct id_array inclusion_uids;
  113. struct id_array inclusion_gids;
  114. struct match_list inclusion_unames;
  115. struct match_list inclusion_gnames;
  116. };
  117. static int add_pattern_from_file(struct archive_match *,
  118. struct match_list *, int, const void *, int);
  119. static int add_entry(struct archive_match *, int,
  120. struct archive_entry *);
  121. static int add_owner_id(struct archive_match *, struct id_array *,
  122. int64_t);
  123. static int add_owner_name(struct archive_match *, struct match_list *,
  124. int, const void *);
  125. static int add_pattern_mbs(struct archive_match *, struct match_list *,
  126. const char *);
  127. static int add_pattern_wcs(struct archive_match *, struct match_list *,
  128. const wchar_t *);
  129. static int cmp_key_mbs(const struct archive_rb_node *, const void *);
  130. static int cmp_key_wcs(const struct archive_rb_node *, const void *);
  131. static int cmp_node_mbs(const struct archive_rb_node *,
  132. const struct archive_rb_node *);
  133. static int cmp_node_wcs(const struct archive_rb_node *,
  134. const struct archive_rb_node *);
  135. static void entry_list_add(struct entry_list *, struct match_file *);
  136. static void entry_list_free(struct entry_list *);
  137. static void entry_list_init(struct entry_list *);
  138. static int error_nomem(struct archive_match *);
  139. static void match_list_add(struct match_list *, struct match *);
  140. static void match_list_free(struct match_list *);
  141. static void match_list_init(struct match_list *);
  142. static int match_list_unmatched_inclusions_next(struct archive_match *,
  143. struct match_list *, int, const void **);
  144. static int match_owner_id(struct id_array *, int64_t);
  145. #if !defined(_WIN32) || defined(__CYGWIN__)
  146. static int match_owner_name_mbs(struct archive_match *,
  147. struct match_list *, const char *);
  148. #else
  149. static int match_owner_name_wcs(struct archive_match *,
  150. struct match_list *, const wchar_t *);
  151. #endif
  152. static int match_path_exclusion(struct archive_match *,
  153. struct match *, int, const void *);
  154. static int match_path_inclusion(struct archive_match *,
  155. struct match *, int, const void *);
  156. static int owner_excluded(struct archive_match *,
  157. struct archive_entry *);
  158. static int path_excluded(struct archive_match *, int, const void *);
  159. static int set_timefilter(struct archive_match *, int, time_t, long,
  160. time_t, long);
  161. static int set_timefilter_pathname_mbs(struct archive_match *,
  162. int, const char *);
  163. static int set_timefilter_pathname_wcs(struct archive_match *,
  164. int, const wchar_t *);
  165. static int set_timefilter_date(struct archive_match *, int, const char *);
  166. static int set_timefilter_date_w(struct archive_match *, int,
  167. const wchar_t *);
  168. static int time_excluded(struct archive_match *,
  169. struct archive_entry *);
  170. static int validate_time_flag(struct archive *, int, const char *);
  171. time_t __archive_get_date(time_t now, const char *);
  172. #define get_date __archive_get_date
  173. static const struct archive_rb_tree_ops rb_ops_mbs = {
  174. cmp_node_mbs, cmp_key_mbs
  175. };
  176. static const struct archive_rb_tree_ops rb_ops_wcs = {
  177. cmp_node_wcs, cmp_key_wcs
  178. };
  179. /*
  180. * The matching logic here needs to be re-thought. I started out to
  181. * try to mimic gtar's matching logic, but it's not entirely
  182. * consistent. In particular 'tar -t' and 'tar -x' interpret patterns
  183. * on the command line as anchored, but --exclude doesn't.
  184. */
  185. static int
  186. error_nomem(struct archive_match *a)
  187. {
  188. archive_set_error(&(a->archive), ENOMEM, "No memory");
  189. a->archive.state = ARCHIVE_STATE_FATAL;
  190. return (ARCHIVE_FATAL);
  191. }
  192. /*
  193. * Create an ARCHIVE_MATCH object.
  194. */
  195. struct archive *
  196. archive_match_new(void)
  197. {
  198. struct archive_match *a;
  199. a = (struct archive_match *)calloc(1, sizeof(*a));
  200. if (a == NULL)
  201. return (NULL);
  202. a->archive.magic = ARCHIVE_MATCH_MAGIC;
  203. a->archive.state = ARCHIVE_STATE_NEW;
  204. match_list_init(&(a->inclusions));
  205. match_list_init(&(a->exclusions));
  206. __archive_rb_tree_init(&(a->exclusion_tree), &rb_ops_mbs);
  207. entry_list_init(&(a->exclusion_entry_list));
  208. match_list_init(&(a->inclusion_unames));
  209. match_list_init(&(a->inclusion_gnames));
  210. time(&a->now);
  211. return (&(a->archive));
  212. }
  213. /*
  214. * Free an ARCHIVE_MATCH object.
  215. */
  216. int
  217. archive_match_free(struct archive *_a)
  218. {
  219. struct archive_match *a;
  220. if (_a == NULL)
  221. return (ARCHIVE_OK);
  222. archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
  223. ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_match_free");
  224. a = (struct archive_match *)_a;
  225. match_list_free(&(a->inclusions));
  226. match_list_free(&(a->exclusions));
  227. entry_list_free(&(a->exclusion_entry_list));
  228. free(a->inclusion_uids.ids);
  229. free(a->inclusion_gids.ids);
  230. match_list_free(&(a->inclusion_unames));
  231. match_list_free(&(a->inclusion_gnames));
  232. free(a);
  233. return (ARCHIVE_OK);
  234. }
  235. /*
  236. * Convenience function to perform all exclusion tests.
  237. *
  238. * Returns 1 if archive entry is excluded.
  239. * Returns 0 if archive entry is not excluded.
  240. * Returns <0 if something error happened.
  241. */
  242. int
  243. archive_match_excluded(struct archive *_a, struct archive_entry *entry)
  244. {
  245. struct archive_match *a;
  246. int r;
  247. archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
  248. ARCHIVE_STATE_NEW, "archive_match_excluded_ae");
  249. a = (struct archive_match *)_a;
  250. if (entry == NULL) {
  251. archive_set_error(&(a->archive), EINVAL, "entry is NULL");
  252. return (ARCHIVE_FAILED);
  253. }
  254. r = 0;
  255. if (a->setflag & PATTERN_IS_SET) {
  256. #if defined(_WIN32) && !defined(__CYGWIN__)
  257. r = path_excluded(a, 0, archive_entry_pathname_w(entry));
  258. #else
  259. r = path_excluded(a, 1, archive_entry_pathname(entry));
  260. #endif
  261. if (r != 0)
  262. return (r);
  263. }
  264. if (a->setflag & TIME_IS_SET) {
  265. r = time_excluded(a, entry);
  266. if (r != 0)
  267. return (r);
  268. }
  269. if (a->setflag & ID_IS_SET)
  270. r = owner_excluded(a, entry);
  271. return (r);
  272. }
  273. /*
  274. * Utility functions to manage exclusion/inclusion patterns
  275. */
  276. int
  277. archive_match_exclude_pattern(struct archive *_a, const char *pattern)
  278. {
  279. struct archive_match *a;
  280. int r;
  281. archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
  282. ARCHIVE_STATE_NEW, "archive_match_exclude_pattern");
  283. a = (struct archive_match *)_a;
  284. if (pattern == NULL || *pattern == '\0') {
  285. archive_set_error(&(a->archive), EINVAL, "pattern is empty");
  286. return (ARCHIVE_FAILED);
  287. }
  288. if ((r = add_pattern_mbs(a, &(a->exclusions), pattern)) != ARCHIVE_OK)
  289. return (r);
  290. return (ARCHIVE_OK);
  291. }
  292. int
  293. archive_match_exclude_pattern_w(struct archive *_a, const wchar_t *pattern)
  294. {
  295. struct archive_match *a;
  296. int r;
  297. archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
  298. ARCHIVE_STATE_NEW, "archive_match_exclude_pattern_w");
  299. a = (struct archive_match *)_a;
  300. if (pattern == NULL || *pattern == L'\0') {
  301. archive_set_error(&(a->archive), EINVAL, "pattern is empty");
  302. return (ARCHIVE_FAILED);
  303. }
  304. if ((r = add_pattern_wcs(a, &(a->exclusions), pattern)) != ARCHIVE_OK)
  305. return (r);
  306. return (ARCHIVE_OK);
  307. }
  308. int
  309. archive_match_exclude_pattern_from_file(struct archive *_a,
  310. const char *pathname, int nullSeparator)
  311. {
  312. struct archive_match *a;
  313. archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
  314. ARCHIVE_STATE_NEW, "archive_match_exclude_pattern_from_file");
  315. a = (struct archive_match *)_a;
  316. return add_pattern_from_file(a, &(a->exclusions), 1, pathname,
  317. nullSeparator);
  318. }
  319. int
  320. archive_match_exclude_pattern_from_file_w(struct archive *_a,
  321. const wchar_t *pathname, int nullSeparator)
  322. {
  323. struct archive_match *a;
  324. archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
  325. ARCHIVE_STATE_NEW, "archive_match_exclude_pattern_from_file_w");
  326. a = (struct archive_match *)_a;
  327. return add_pattern_from_file(a, &(a->exclusions), 0, pathname,
  328. nullSeparator);
  329. }
  330. int
  331. archive_match_include_pattern(struct archive *_a, const char *pattern)
  332. {
  333. struct archive_match *a;
  334. int r;
  335. archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
  336. ARCHIVE_STATE_NEW, "archive_match_include_pattern");
  337. a = (struct archive_match *)_a;
  338. if (pattern == NULL || *pattern == '\0') {
  339. archive_set_error(&(a->archive), EINVAL, "pattern is empty");
  340. return (ARCHIVE_FAILED);
  341. }
  342. if ((r = add_pattern_mbs(a, &(a->inclusions), pattern)) != ARCHIVE_OK)
  343. return (r);
  344. return (ARCHIVE_OK);
  345. }
  346. int
  347. archive_match_include_pattern_w(struct archive *_a, const wchar_t *pattern)
  348. {
  349. struct archive_match *a;
  350. int r;
  351. archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
  352. ARCHIVE_STATE_NEW, "archive_match_include_pattern_w");
  353. a = (struct archive_match *)_a;
  354. if (pattern == NULL || *pattern == L'\0') {
  355. archive_set_error(&(a->archive), EINVAL, "pattern is empty");
  356. return (ARCHIVE_FAILED);
  357. }
  358. if ((r = add_pattern_wcs(a, &(a->inclusions), pattern)) != ARCHIVE_OK)
  359. return (r);
  360. return (ARCHIVE_OK);
  361. }
  362. int
  363. archive_match_include_pattern_from_file(struct archive *_a,
  364. const char *pathname, int nullSeparator)
  365. {
  366. struct archive_match *a;
  367. archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
  368. ARCHIVE_STATE_NEW, "archive_match_include_pattern_from_file");
  369. a = (struct archive_match *)_a;
  370. return add_pattern_from_file(a, &(a->inclusions), 1, pathname,
  371. nullSeparator);
  372. }
  373. int
  374. archive_match_include_pattern_from_file_w(struct archive *_a,
  375. const wchar_t *pathname, int nullSeparator)
  376. {
  377. struct archive_match *a;
  378. archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
  379. ARCHIVE_STATE_NEW, "archive_match_include_pattern_from_file_w");
  380. a = (struct archive_match *)_a;
  381. return add_pattern_from_file(a, &(a->inclusions), 0, pathname,
  382. nullSeparator);
  383. }
  384. /*
  385. * Test functions for pathname patterns.
  386. *
  387. * Returns 1 if archive entry is excluded.
  388. * Returns 0 if archive entry is not excluded.
  389. * Returns <0 if something error happened.
  390. */
  391. int
  392. archive_match_path_excluded(struct archive *_a,
  393. struct archive_entry *entry)
  394. {
  395. struct archive_match *a;
  396. archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
  397. ARCHIVE_STATE_NEW, "archive_match_path_excluded");
  398. a = (struct archive_match *)_a;
  399. if (entry == NULL) {
  400. archive_set_error(&(a->archive), EINVAL, "entry is NULL");
  401. return (ARCHIVE_FAILED);
  402. }
  403. /* If we don't have exclusion/inclusion pattern set at all,
  404. * the entry is always not excluded. */
  405. if ((a->setflag & PATTERN_IS_SET) == 0)
  406. return (0);
  407. #if defined(_WIN32) && !defined(__CYGWIN__)
  408. return (path_excluded(a, 0, archive_entry_pathname_w(entry)));
  409. #else
  410. return (path_excluded(a, 1, archive_entry_pathname(entry)));
  411. #endif
  412. }
  413. /*
  414. * Utilty functions to get statistic information for inclusion patterns.
  415. */
  416. int
  417. archive_match_path_unmatched_inclusions(struct archive *_a)
  418. {
  419. struct archive_match *a;
  420. archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
  421. ARCHIVE_STATE_NEW, "archive_match_unmatched_inclusions");
  422. a = (struct archive_match *)_a;
  423. return (a->inclusions.unmatched_count);
  424. }
  425. int
  426. archive_match_path_unmatched_inclusions_next(struct archive *_a,
  427. const char **_p)
  428. {
  429. struct archive_match *a;
  430. const void *v;
  431. int r;
  432. archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
  433. ARCHIVE_STATE_NEW, "archive_match_unmatched_inclusions_next");
  434. a = (struct archive_match *)_a;
  435. r = match_list_unmatched_inclusions_next(a, &(a->inclusions), 1, &v);
  436. *_p = (const char *)v;
  437. return (r);
  438. }
  439. int
  440. archive_match_path_unmatched_inclusions_next_w(struct archive *_a,
  441. const wchar_t **_p)
  442. {
  443. struct archive_match *a;
  444. const void *v;
  445. int r;
  446. archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
  447. ARCHIVE_STATE_NEW, "archive_match_unmatched_inclusions_next_w");
  448. a = (struct archive_match *)_a;
  449. r = match_list_unmatched_inclusions_next(a, &(a->inclusions), 0, &v);
  450. *_p = (const wchar_t *)v;
  451. return (r);
  452. }
  453. /*
  454. * Add inclusion/exclusion patterns.
  455. */
  456. static int
  457. add_pattern_mbs(struct archive_match *a, struct match_list *list,
  458. const char *pattern)
  459. {
  460. struct match *match;
  461. size_t len;
  462. match = calloc(1, sizeof(*match));
  463. if (match == NULL)
  464. return (error_nomem(a));
  465. /* Both "foo/" and "foo" should match "foo/bar". */
  466. len = strlen(pattern);
  467. if (len && pattern[len - 1] == '/')
  468. --len;
  469. archive_mstring_copy_mbs_len(&(match->pattern), pattern, len);
  470. match_list_add(list, match);
  471. a->setflag |= PATTERN_IS_SET;
  472. return (ARCHIVE_OK);
  473. }
  474. static int
  475. add_pattern_wcs(struct archive_match *a, struct match_list *list,
  476. const wchar_t *pattern)
  477. {
  478. struct match *match;
  479. size_t len;
  480. match = calloc(1, sizeof(*match));
  481. if (match == NULL)
  482. return (error_nomem(a));
  483. /* Both "foo/" and "foo" should match "foo/bar". */
  484. len = wcslen(pattern);
  485. if (len && pattern[len - 1] == L'/')
  486. --len;
  487. archive_mstring_copy_wcs_len(&(match->pattern), pattern, len);
  488. match_list_add(list, match);
  489. a->setflag |= PATTERN_IS_SET;
  490. return (ARCHIVE_OK);
  491. }
  492. static int
  493. add_pattern_from_file(struct archive_match *a, struct match_list *mlist,
  494. int mbs, const void *pathname, int nullSeparator)
  495. {
  496. struct archive *ar;
  497. struct archive_entry *ae;
  498. struct archive_string as;
  499. const void *buff;
  500. size_t size;
  501. int64_t offset;
  502. int r;
  503. ar = archive_read_new();
  504. if (ar == NULL) {
  505. archive_set_error(&(a->archive), ENOMEM, "No memory");
  506. return (ARCHIVE_FATAL);
  507. }
  508. r = archive_read_support_format_raw(ar);
  509. if (r != ARCHIVE_OK) {
  510. archive_copy_error(&(a->archive), ar);
  511. archive_read_free(ar);
  512. return (r);
  513. }
  514. if (mbs)
  515. r = archive_read_open_filename(ar, pathname, 512*20);
  516. else
  517. r = archive_read_open_filename_w(ar, pathname, 512*20);
  518. if (r != ARCHIVE_OK) {
  519. archive_copy_error(&(a->archive), ar);
  520. archive_read_free(ar);
  521. return (r);
  522. }
  523. r = archive_read_next_header(ar, &ae);
  524. if (r != ARCHIVE_OK) {
  525. archive_copy_error(&(a->archive), ar);
  526. archive_read_free(ar);
  527. return (r);
  528. }
  529. archive_string_init(&as);
  530. while ((r = archive_read_data_block(ar, &buff, &size, &offset))
  531. == ARCHIVE_OK) {
  532. const char *b = (const char *)buff;
  533. while (size) {
  534. const char *s = (const char *)b;
  535. size_t length = 0;
  536. int found_separator = 0;
  537. while (length < size) {
  538. if (nullSeparator) {
  539. if (*b == '\0') {
  540. found_separator = 1;
  541. break;
  542. }
  543. } else {
  544. if (*b == 0x0d || *b == 0x0a) {
  545. found_separator = 1;
  546. break;
  547. }
  548. }
  549. b++;
  550. length++;
  551. }
  552. if (!found_separator) {
  553. archive_strncat(&as, s, length);
  554. /* Read next data block. */
  555. break;
  556. }
  557. b++;
  558. size -= length + 1;
  559. archive_strncat(&as, s, length);
  560. /* If the line is not empty, add the pattern. */
  561. if (archive_strlen(&as) > 0) {
  562. /* Add pattern. */
  563. r = add_pattern_mbs(a, mlist, as.s);
  564. if (r != ARCHIVE_OK) {
  565. archive_read_free(ar);
  566. archive_string_free(&as);
  567. return (r);
  568. }
  569. archive_string_empty(&as);
  570. }
  571. }
  572. }
  573. /* If something error happend, report it immediately. */
  574. if (r < ARCHIVE_OK) {
  575. archive_copy_error(&(a->archive), ar);
  576. archive_read_free(ar);
  577. archive_string_free(&as);
  578. return (r);
  579. }
  580. /* If the line is not empty, add the pattern. */
  581. if (r == ARCHIVE_EOF && archive_strlen(&as) > 0) {
  582. /* Add pattern. */
  583. r = add_pattern_mbs(a, mlist, as.s);
  584. if (r != ARCHIVE_OK) {
  585. archive_read_free(ar);
  586. archive_string_free(&as);
  587. return (r);
  588. }
  589. }
  590. archive_read_free(ar);
  591. archive_string_free(&as);
  592. return (ARCHIVE_OK);
  593. }
  594. /*
  595. * Test if pathname is excluded by inclusion/exclusion patterns.
  596. */
  597. static int
  598. path_excluded(struct archive_match *a, int mbs, const void *pathname)
  599. {
  600. struct match *match;
  601. struct match *matched;
  602. int r;
  603. if (a == NULL)
  604. return (0);
  605. /* Mark off any unmatched inclusions. */
  606. /* In particular, if a filename does appear in the archive and
  607. * is explicitly included and excluded, then we don't report
  608. * it as missing even though we don't extract it.
  609. */
  610. matched = NULL;
  611. for (match = a->inclusions.first; match != NULL;
  612. match = match->next){
  613. if (match->matches == 0 &&
  614. (r = match_path_inclusion(a, match, mbs, pathname)) != 0) {
  615. if (r < 0)
  616. return (r);
  617. a->inclusions.unmatched_count--;
  618. match->matches++;
  619. matched = match;
  620. }
  621. }
  622. /* Exclusions take priority */
  623. for (match = a->exclusions.first; match != NULL;
  624. match = match->next){
  625. r = match_path_exclusion(a, match, mbs, pathname);
  626. if (r)
  627. return (r);
  628. }
  629. /* It's not excluded and we found an inclusion above, so it's
  630. * included. */
  631. if (matched != NULL)
  632. return (0);
  633. /* We didn't find an unmatched inclusion, check the remaining ones. */
  634. for (match = a->inclusions.first; match != NULL;
  635. match = match->next){
  636. /* We looked at previously-unmatched inclusions already. */
  637. if (match->matches > 0 &&
  638. (r = match_path_inclusion(a, match, mbs, pathname)) != 0) {
  639. if (r < 0)
  640. return (r);
  641. match->matches++;
  642. return (0);
  643. }
  644. }
  645. /* If there were inclusions, default is to exclude. */
  646. if (a->inclusions.first != NULL)
  647. return (1);
  648. /* No explicit inclusions, default is to match. */
  649. return (0);
  650. }
  651. /*
  652. * This is a little odd, but it matches the default behavior of
  653. * gtar. In particular, 'a*b' will match 'foo/a1111/222b/bar'
  654. *
  655. */
  656. static int
  657. match_path_exclusion(struct archive_match *a, struct match *m,
  658. int mbs, const void *pn)
  659. {
  660. int flag = PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END;
  661. int r;
  662. if (mbs) {
  663. const char *p;
  664. r = archive_mstring_get_mbs(&(a->archive), &(m->pattern), &p);
  665. if (r == 0)
  666. return (archive_pathmatch(p, (const char *)pn, flag));
  667. } else {
  668. const wchar_t *p;
  669. r = archive_mstring_get_wcs(&(a->archive), &(m->pattern), &p);
  670. if (r == 0)
  671. return (archive_pathmatch_w(p, (const wchar_t *)pn,
  672. flag));
  673. }
  674. if (errno == ENOMEM)
  675. return (error_nomem(a));
  676. return (0);
  677. }
  678. /*
  679. * Again, mimic gtar: inclusions are always anchored (have to match
  680. * the beginning of the path) even though exclusions are not anchored.
  681. */
  682. static int
  683. match_path_inclusion(struct archive_match *a, struct match *m,
  684. int mbs, const void *pn)
  685. {
  686. int flag = PATHMATCH_NO_ANCHOR_END;
  687. int r;
  688. if (mbs) {
  689. const char *p;
  690. r = archive_mstring_get_mbs(&(a->archive), &(m->pattern), &p);
  691. if (r == 0)
  692. return (archive_pathmatch(p, (const char *)pn, flag));
  693. } else {
  694. const wchar_t *p;
  695. r = archive_mstring_get_wcs(&(a->archive), &(m->pattern), &p);
  696. if (r == 0)
  697. return (archive_pathmatch_w(p, (const wchar_t *)pn,
  698. flag));
  699. }
  700. if (errno == ENOMEM)
  701. return (error_nomem(a));
  702. return (0);
  703. }
  704. static void
  705. match_list_init(struct match_list *list)
  706. {
  707. list->first = NULL;
  708. list->last = &(list->first);
  709. list->count = 0;
  710. }
  711. static void
  712. match_list_free(struct match_list *list)
  713. {
  714. struct match *p, *q;
  715. for (p = list->first; p != NULL; ) {
  716. q = p;
  717. p = p->next;
  718. archive_mstring_clean(&(q->pattern));
  719. free(q);
  720. }
  721. }
  722. static void
  723. match_list_add(struct match_list *list, struct match *m)
  724. {
  725. *list->last = m;
  726. list->last = &(m->next);
  727. list->count++;
  728. list->unmatched_count++;
  729. }
  730. static int
  731. match_list_unmatched_inclusions_next(struct archive_match *a,
  732. struct match_list *list, int mbs, const void **vp)
  733. {
  734. struct match *m;
  735. *vp = NULL;
  736. if (list->unmatched_eof) {
  737. list->unmatched_eof = 0;
  738. return (ARCHIVE_EOF);
  739. }
  740. if (list->unmatched_next == NULL) {
  741. if (list->unmatched_count == 0)
  742. return (ARCHIVE_EOF);
  743. list->unmatched_next = list->first;
  744. }
  745. for (m = list->unmatched_next; m != NULL; m = m->next) {
  746. int r;
  747. if (m->matches)
  748. continue;
  749. if (mbs) {
  750. const char *p;
  751. r = archive_mstring_get_mbs(&(a->archive),
  752. &(m->pattern), &p);
  753. if (r < 0 && errno == ENOMEM)
  754. return (error_nomem(a));
  755. if (p == NULL)
  756. p = "";
  757. *vp = p;
  758. } else {
  759. const wchar_t *p;
  760. r = archive_mstring_get_wcs(&(a->archive),
  761. &(m->pattern), &p);
  762. if (r < 0 && errno == ENOMEM)
  763. return (error_nomem(a));
  764. if (p == NULL)
  765. p = L"";
  766. *vp = p;
  767. }
  768. list->unmatched_next = m->next;
  769. if (list->unmatched_next == NULL)
  770. /* To return EOF next time. */
  771. list->unmatched_eof = 1;
  772. return (ARCHIVE_OK);
  773. }
  774. list->unmatched_next = NULL;
  775. return (ARCHIVE_EOF);
  776. }
  777. /*
  778. * Utility functions to manage inclusion timestamps.
  779. */
  780. int
  781. archive_match_include_time(struct archive *_a, int flag, time_t sec,
  782. long nsec)
  783. {
  784. int r;
  785. r = validate_time_flag(_a, flag, "archive_match_include_time");
  786. if (r != ARCHIVE_OK)
  787. return (r);
  788. return set_timefilter((struct archive_match *)_a, flag,
  789. sec, nsec, sec, nsec);
  790. }
  791. int
  792. archive_match_include_date(struct archive *_a, int flag,
  793. const char *datestr)
  794. {
  795. int r;
  796. r = validate_time_flag(_a, flag, "archive_match_include_date");
  797. if (r != ARCHIVE_OK)
  798. return (r);
  799. return set_timefilter_date((struct archive_match *)_a, flag, datestr);
  800. }
  801. int
  802. archive_match_include_date_w(struct archive *_a, int flag,
  803. const wchar_t *datestr)
  804. {
  805. int r;
  806. r = validate_time_flag(_a, flag, "archive_match_include_date_w");
  807. if (r != ARCHIVE_OK)
  808. return (r);
  809. return set_timefilter_date_w((struct archive_match *)_a, flag, datestr);
  810. }
  811. int
  812. archive_match_include_file_time(struct archive *_a, int flag,
  813. const char *pathname)
  814. {
  815. int r;
  816. r = validate_time_flag(_a, flag, "archive_match_include_file_time");
  817. if (r != ARCHIVE_OK)
  818. return (r);
  819. return set_timefilter_pathname_mbs((struct archive_match *)_a,
  820. flag, pathname);
  821. }
  822. int
  823. archive_match_include_file_time_w(struct archive *_a, int flag,
  824. const wchar_t *pathname)
  825. {
  826. int r;
  827. r = validate_time_flag(_a, flag, "archive_match_include_file_time_w");
  828. if (r != ARCHIVE_OK)
  829. return (r);
  830. return set_timefilter_pathname_wcs((struct archive_match *)_a,
  831. flag, pathname);
  832. }
  833. int
  834. archive_match_exclude_entry(struct archive *_a, int flag,
  835. struct archive_entry *entry)
  836. {
  837. struct archive_match *a;
  838. int r;
  839. archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
  840. ARCHIVE_STATE_NEW, "archive_match_time_include_entry");
  841. a = (struct archive_match *)_a;
  842. if (entry == NULL) {
  843. archive_set_error(&(a->archive), EINVAL, "entry is NULL");
  844. return (ARCHIVE_FAILED);
  845. }
  846. r = validate_time_flag(_a, flag, "archive_match_exclude_entry");
  847. if (r != ARCHIVE_OK)
  848. return (r);
  849. return (add_entry(a, flag, entry));
  850. }
  851. /*
  852. * Test function for time stamps.
  853. *
  854. * Returns 1 if archive entry is excluded.
  855. * Returns 0 if archive entry is not excluded.
  856. * Returns <0 if something error happened.
  857. */
  858. int
  859. archive_match_time_excluded(struct archive *_a,
  860. struct archive_entry *entry)
  861. {
  862. struct archive_match *a;
  863. archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
  864. ARCHIVE_STATE_NEW, "archive_match_time_excluded_ae");
  865. a = (struct archive_match *)_a;
  866. if (entry == NULL) {
  867. archive_set_error(&(a->archive), EINVAL, "entry is NULL");
  868. return (ARCHIVE_FAILED);
  869. }
  870. /* If we don't have inclusion time set at all, the entry is always
  871. * not excluded. */
  872. if ((a->setflag & TIME_IS_SET) == 0)
  873. return (0);
  874. return (time_excluded(a, entry));
  875. }
  876. static int
  877. validate_time_flag(struct archive *_a, int flag, const char *_fn)
  878. {
  879. archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
  880. ARCHIVE_STATE_NEW, _fn);
  881. /* Check a type of time. */
  882. if (flag &
  883. ((~(ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME)) & 0xff00)) {
  884. archive_set_error(_a, EINVAL, "Invalid time flag");
  885. return (ARCHIVE_FAILED);
  886. }
  887. if ((flag & (ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME)) == 0) {
  888. archive_set_error(_a, EINVAL, "No time flag");
  889. return (ARCHIVE_FAILED);
  890. }
  891. /* Check a type of comparison. */
  892. if (flag &
  893. ((~(ARCHIVE_MATCH_NEWER | ARCHIVE_MATCH_OLDER
  894. | ARCHIVE_MATCH_EQUAL)) & 0x00ff)) {
  895. archive_set_error(_a, EINVAL, "Invalid comparison flag");
  896. return (ARCHIVE_FAILED);
  897. }
  898. if ((flag & (ARCHIVE_MATCH_NEWER | ARCHIVE_MATCH_OLDER
  899. | ARCHIVE_MATCH_EQUAL)) == 0) {
  900. archive_set_error(_a, EINVAL, "No comparison flag");
  901. return (ARCHIVE_FAILED);
  902. }
  903. return (ARCHIVE_OK);
  904. }
  905. #define JUST_EQUAL(t) (((t) & (ARCHIVE_MATCH_EQUAL |\
  906. ARCHIVE_MATCH_NEWER | ARCHIVE_MATCH_OLDER)) == ARCHIVE_MATCH_EQUAL)
  907. static int
  908. set_timefilter(struct archive_match *a, int timetype,
  909. time_t mtime_sec, long mtime_nsec, time_t ctime_sec, long ctime_nsec)
  910. {
  911. if (timetype & ARCHIVE_MATCH_MTIME) {
  912. if ((timetype & ARCHIVE_MATCH_NEWER) || JUST_EQUAL(timetype)) {
  913. a->newer_mtime_filter = timetype;
  914. a->newer_mtime_sec = mtime_sec;
  915. a->newer_mtime_nsec = mtime_nsec;
  916. a->setflag |= TIME_IS_SET;
  917. }
  918. if ((timetype & ARCHIVE_MATCH_OLDER) || JUST_EQUAL(timetype)) {
  919. a->older_mtime_filter = timetype;
  920. a->older_mtime_sec = mtime_sec;
  921. a->older_mtime_nsec = mtime_nsec;
  922. a->setflag |= TIME_IS_SET;
  923. }
  924. }
  925. if (timetype & ARCHIVE_MATCH_CTIME) {
  926. if ((timetype & ARCHIVE_MATCH_NEWER) || JUST_EQUAL(timetype)) {
  927. a->newer_ctime_filter = timetype;
  928. a->newer_ctime_sec = ctime_sec;
  929. a->newer_ctime_nsec = ctime_nsec;
  930. a->setflag |= TIME_IS_SET;
  931. }
  932. if ((timetype & ARCHIVE_MATCH_OLDER) || JUST_EQUAL(timetype)) {
  933. a->older_ctime_filter = timetype;
  934. a->older_ctime_sec = ctime_sec;
  935. a->older_ctime_nsec = ctime_nsec;
  936. a->setflag |= TIME_IS_SET;
  937. }
  938. }
  939. return (ARCHIVE_OK);
  940. }
  941. static int
  942. set_timefilter_date(struct archive_match *a, int timetype, const char *datestr)
  943. {
  944. time_t t;
  945. if (datestr == NULL || *datestr == '\0') {
  946. archive_set_error(&(a->archive), EINVAL, "date is empty");
  947. return (ARCHIVE_FAILED);
  948. }
  949. t = get_date(a->now, datestr);
  950. if (t == (time_t)-1) {
  951. archive_set_error(&(a->archive), EINVAL, "invalid date string");
  952. return (ARCHIVE_FAILED);
  953. }
  954. return set_timefilter(a, timetype, t, 0, t, 0);
  955. }
  956. static int
  957. set_timefilter_date_w(struct archive_match *a, int timetype,
  958. const wchar_t *datestr)
  959. {
  960. struct archive_string as;
  961. time_t t;
  962. if (datestr == NULL || *datestr == L'\0') {
  963. archive_set_error(&(a->archive), EINVAL, "date is empty");
  964. return (ARCHIVE_FAILED);
  965. }
  966. archive_string_init(&as);
  967. if (archive_string_append_from_wcs(&as, datestr, wcslen(datestr)) < 0) {
  968. archive_string_free(&as);
  969. if (errno == ENOMEM)
  970. return (error_nomem(a));
  971. archive_set_error(&(a->archive), -1,
  972. "Failed to convert WCS to MBS");
  973. return (ARCHIVE_FAILED);
  974. }
  975. t = get_date(a->now, as.s);
  976. archive_string_free(&as);
  977. if (t == (time_t)-1) {
  978. archive_set_error(&(a->archive), EINVAL, "invalid date string");
  979. return (ARCHIVE_FAILED);
  980. }
  981. return set_timefilter(a, timetype, t, 0, t, 0);
  982. }
  983. #if defined(_WIN32) && !defined(__CYGWIN__)
  984. #define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
  985. static int
  986. set_timefilter_find_data(struct archive_match *a, int timetype,
  987. DWORD ftLastWriteTime_dwHighDateTime, DWORD ftLastWriteTime_dwLowDateTime,
  988. DWORD ftCreationTime_dwHighDateTime, DWORD ftCreationTime_dwLowDateTime)
  989. {
  990. ULARGE_INTEGER utc;
  991. time_t ctime_sec, mtime_sec;
  992. long ctime_ns, mtime_ns;
  993. utc.HighPart = ftCreationTime_dwHighDateTime;
  994. utc.LowPart = ftCreationTime_dwLowDateTime;
  995. if (utc.QuadPart >= EPOC_TIME) {
  996. utc.QuadPart -= EPOC_TIME;
  997. ctime_sec = (time_t)(utc.QuadPart / 10000000);
  998. ctime_ns = (long)(utc.QuadPart % 10000000) * 100;
  999. } else {
  1000. ctime_sec = 0;
  1001. ctime_ns = 0;
  1002. }
  1003. utc.HighPart = ftLastWriteTime_dwHighDateTime;
  1004. utc.LowPart = ftLastWriteTime_dwLowDateTime;
  1005. if (utc.QuadPart >= EPOC_TIME) {
  1006. utc.QuadPart -= EPOC_TIME;
  1007. mtime_sec = (time_t)(utc.QuadPart / 10000000);
  1008. mtime_ns = (long)(utc.QuadPart % 10000000) * 100;
  1009. } else {
  1010. mtime_sec = 0;
  1011. mtime_ns = 0;
  1012. }
  1013. return set_timefilter(a, timetype,
  1014. mtime_sec, mtime_ns, ctime_sec, ctime_ns);
  1015. }
  1016. static int
  1017. set_timefilter_pathname_mbs(struct archive_match *a, int timetype,
  1018. const char *path)
  1019. {
  1020. /* NOTE: stat() on Windows cannot handle nano seconds. */
  1021. HANDLE h;
  1022. WIN32_FIND_DATAA d;
  1023. if (path == NULL || *path == '\0') {
  1024. archive_set_error(&(a->archive), EINVAL, "pathname is empty");
  1025. return (ARCHIVE_FAILED);
  1026. }
  1027. h = FindFirstFileA(path, &d);
  1028. if (h == INVALID_HANDLE_VALUE) {
  1029. la_dosmaperr(GetLastError());
  1030. archive_set_error(&(a->archive), errno,
  1031. "Failed to FindFirstFileA");
  1032. return (ARCHIVE_FAILED);
  1033. }
  1034. FindClose(h);
  1035. return set_timefilter_find_data(a, timetype,
  1036. d.ftLastWriteTime.dwHighDateTime, d.ftLastWriteTime.dwLowDateTime,
  1037. d.ftCreationTime.dwHighDateTime, d.ftCreationTime.dwLowDateTime);
  1038. }
  1039. static int
  1040. set_timefilter_pathname_wcs(struct archive_match *a, int timetype,
  1041. const wchar_t *path)
  1042. {
  1043. HANDLE h;
  1044. WIN32_FIND_DATAW d;
  1045. if (path == NULL || *path == L'\0') {
  1046. archive_set_error(&(a->archive), EINVAL, "pathname is empty");
  1047. return (ARCHIVE_FAILED);
  1048. }
  1049. h = FindFirstFileW(path, &d);
  1050. if (h == INVALID_HANDLE_VALUE) {
  1051. la_dosmaperr(GetLastError());
  1052. archive_set_error(&(a->archive), errno,
  1053. "Failed to FindFirstFile");
  1054. return (ARCHIVE_FAILED);
  1055. }
  1056. FindClose(h);
  1057. return set_timefilter_find_data(a, timetype,
  1058. d.ftLastWriteTime.dwHighDateTime, d.ftLastWriteTime.dwLowDateTime,
  1059. d.ftCreationTime.dwHighDateTime, d.ftCreationTime.dwLowDateTime);
  1060. }
  1061. #else /* _WIN32 && !__CYGWIN__ */
  1062. static int
  1063. set_timefilter_stat(struct archive_match *a, int timetype, struct stat *st)
  1064. {
  1065. struct archive_entry *ae;
  1066. time_t ctime_sec, mtime_sec;
  1067. long ctime_ns, mtime_ns;
  1068. ae = archive_entry_new();
  1069. if (ae == NULL)
  1070. return (error_nomem(a));
  1071. archive_entry_copy_stat(ae, st);
  1072. ctime_sec = archive_entry_ctime(ae);
  1073. ctime_ns = archive_entry_ctime_nsec(ae);
  1074. mtime_sec = archive_entry_mtime(ae);
  1075. mtime_ns = archive_entry_mtime_nsec(ae);
  1076. archive_entry_free(ae);
  1077. return set_timefilter(a, timetype, mtime_sec, mtime_ns,
  1078. ctime_sec, ctime_ns);
  1079. }
  1080. static int
  1081. set_timefilter_pathname_mbs(struct archive_match *a, int timetype,
  1082. const char *path)
  1083. {
  1084. struct stat st;
  1085. if (path == NULL || *path == '\0') {
  1086. archive_set_error(&(a->archive), EINVAL, "pathname is empty");
  1087. return (ARCHIVE_FAILED);
  1088. }
  1089. if (stat(path, &st) != 0) {
  1090. archive_set_error(&(a->archive), errno, "Failed to stat()");
  1091. return (ARCHIVE_FAILED);
  1092. }
  1093. return (set_timefilter_stat(a, timetype, &st));
  1094. }
  1095. static int
  1096. set_timefilter_pathname_wcs(struct archive_match *a, int timetype,
  1097. const wchar_t *path)
  1098. {
  1099. struct archive_string as;
  1100. int r;
  1101. if (path == NULL || *path == L'\0') {
  1102. archive_set_error(&(a->archive), EINVAL, "pathname is empty");
  1103. return (ARCHIVE_FAILED);
  1104. }
  1105. /* Convert WCS filename to MBS filename. */
  1106. archive_string_init(&as);
  1107. if (archive_string_append_from_wcs(&as, path, wcslen(path)) < 0) {
  1108. archive_string_free(&as);
  1109. if (errno == ENOMEM)
  1110. return (error_nomem(a));
  1111. archive_set_error(&(a->archive), -1,
  1112. "Failed to convert WCS to MBS");
  1113. return (ARCHIVE_FAILED);
  1114. }
  1115. r = set_timefilter_pathname_mbs(a, timetype, as.s);
  1116. archive_string_free(&as);
  1117. return (r);
  1118. }
  1119. #endif /* _WIN32 && !__CYGWIN__ */
  1120. /*
  1121. * Call back funtions for archive_rb.
  1122. */
  1123. static int
  1124. cmp_node_mbs(const struct archive_rb_node *n1,
  1125. const struct archive_rb_node *n2)
  1126. {
  1127. struct match_file *f1 = (struct match_file *)(uintptr_t)n1;
  1128. struct match_file *f2 = (struct match_file *)(uintptr_t)n2;
  1129. const char *p1, *p2;
  1130. archive_mstring_get_mbs(NULL, &(f1->pathname), &p1);
  1131. archive_mstring_get_mbs(NULL, &(f2->pathname), &p2);
  1132. if (p1 == NULL)
  1133. return (1);
  1134. if (p2 == NULL)
  1135. return (-1);
  1136. return (strcmp(p1, p2));
  1137. }
  1138. static int
  1139. cmp_key_mbs(const struct archive_rb_node *n, const void *key)
  1140. {
  1141. struct match_file *f = (struct match_file *)(uintptr_t)n;
  1142. const char *p;
  1143. archive_mstring_get_mbs(NULL, &(f->pathname), &p);
  1144. if (p == NULL)
  1145. return (-1);
  1146. return (strcmp(p, (const char *)key));
  1147. }
  1148. static int
  1149. cmp_node_wcs(const struct archive_rb_node *n1,
  1150. const struct archive_rb_node *n2)
  1151. {
  1152. struct match_file *f1 = (struct match_file *)(uintptr_t)n1;
  1153. struct match_file *f2 = (struct match_file *)(uintptr_t)n2;
  1154. const wchar_t *p1, *p2;
  1155. archive_mstring_get_wcs(NULL, &(f1->pathname), &p1);
  1156. archive_mstring_get_wcs(NULL, &(f2->pathname), &p2);
  1157. if (p1 == NULL)
  1158. return (1);
  1159. if (p2 == NULL)
  1160. return (-1);
  1161. return (wcscmp(p1, p2));
  1162. }
  1163. static int
  1164. cmp_key_wcs(const struct archive_rb_node *n, const void *key)
  1165. {
  1166. struct match_file *f = (struct match_file *)(uintptr_t)n;
  1167. const wchar_t *p;
  1168. archive_mstring_get_wcs(NULL, &(f->pathname), &p);
  1169. if (p == NULL)
  1170. return (-1);
  1171. return (wcscmp(p, (const wchar_t *)key));
  1172. }
  1173. static void
  1174. entry_list_init(struct entry_list *list)
  1175. {
  1176. list->first = NULL;
  1177. list->last = &(list->first);
  1178. list->count = 0;
  1179. }
  1180. static void
  1181. entry_list_free(struct entry_list *list)
  1182. {
  1183. struct match_file *p, *q;
  1184. for (p = list->first; p != NULL; ) {
  1185. q = p;
  1186. p = p->next;
  1187. archive_mstring_clean(&(q->pathname));
  1188. free(q);
  1189. }
  1190. }
  1191. static void
  1192. entry_list_add(struct entry_list *list, struct match_file *file)
  1193. {
  1194. *list->last = file;
  1195. list->last = &(file->next);
  1196. list->count++;
  1197. }
  1198. static int
  1199. add_entry(struct archive_match *a, int flag,
  1200. struct archive_entry *entry)
  1201. {
  1202. struct match_file *f;
  1203. const void *pathname;
  1204. int r;
  1205. f = calloc(1, sizeof(*f));
  1206. if (f == NULL)
  1207. return (error_nomem(a));
  1208. #if defined(_WIN32) && !defined(__CYGWIN__)
  1209. pathname = archive_entry_pathname_w(entry);
  1210. if (pathname == NULL) {
  1211. free(f);
  1212. archive_set_error(&(a->archive), EINVAL, "pathname is NULL");
  1213. return (ARCHIVE_FAILED);
  1214. }
  1215. archive_mstring_copy_wcs(&(f->pathname), pathname);
  1216. a->exclusion_tree.rbt_ops = &rb_ops_wcs;
  1217. #else
  1218. (void)rb_ops_wcs;
  1219. pathname = archive_entry_pathname(entry);
  1220. if (pathname == NULL) {
  1221. free(f);
  1222. archive_set_error(&(a->archive), EINVAL, "pathname is NULL");
  1223. return (ARCHIVE_FAILED);
  1224. }
  1225. archive_mstring_copy_mbs(&(f->pathname), pathname);
  1226. a->exclusion_tree.rbt_ops = &rb_ops_mbs;
  1227. #endif
  1228. f->flag = flag;
  1229. f->mtime_sec = archive_entry_mtime(entry);
  1230. f->mtime_nsec = archive_entry_mtime_nsec(entry);
  1231. f->ctime_sec = archive_entry_ctime(entry);
  1232. f->ctime_nsec = archive_entry_ctime_nsec(entry);
  1233. r = __archive_rb_tree_insert_node(&(a->exclusion_tree), &(f->node));
  1234. if (!r) {
  1235. struct match_file *f2;
  1236. /* Get the duplicated file. */
  1237. f2 = (struct match_file *)__archive_rb_tree_find_node(
  1238. &(a->exclusion_tree), pathname);
  1239. /*
  1240. * We always overwrite comparison condision.
  1241. * If you do not want to overwrite it, you should not
  1242. * call archive_match_exclude_entry(). We cannot know
  1243. * what behavior you really expect since overwriting
  1244. * condition might be different with the flag.
  1245. */
  1246. if (f2 != NULL) {
  1247. f2->flag = f->flag;
  1248. f2->mtime_sec = f->mtime_sec;
  1249. f2->mtime_nsec = f->mtime_nsec;
  1250. f2->ctime_sec = f->ctime_sec;
  1251. f2->ctime_nsec = f->ctime_nsec;
  1252. }
  1253. /* Release the duplicated file. */
  1254. archive_mstring_clean(&(f->pathname));
  1255. free(f);
  1256. return (ARCHIVE_OK);
  1257. }
  1258. entry_list_add(&(a->exclusion_entry_list), f);
  1259. a->setflag |= TIME_IS_SET;
  1260. return (ARCHIVE_OK);
  1261. }
  1262. /*
  1263. * Test if entry is excluded by its timestamp.
  1264. */
  1265. static int
  1266. time_excluded(struct archive_match *a, struct archive_entry *entry)
  1267. {
  1268. struct match_file *f;
  1269. const void *pathname;
  1270. time_t sec;
  1271. long nsec;
  1272. /*
  1273. * If this file/dir is excluded by a time comparison, skip it.
  1274. */
  1275. if (a->newer_ctime_filter) {
  1276. /* If ctime is not set, use mtime instead. */
  1277. if (archive_entry_ctime_is_set(entry))
  1278. sec = archive_entry_ctime(entry);
  1279. else
  1280. sec = archive_entry_mtime(entry);
  1281. if (sec < a->newer_ctime_sec)
  1282. return (1); /* Too old, skip it. */
  1283. if (sec == a->newer_ctime_sec) {
  1284. if (archive_entry_ctime_is_set(entry))
  1285. nsec = archive_entry_ctime_nsec(entry);
  1286. else
  1287. nsec = archive_entry_mtime_nsec(entry);
  1288. if (nsec < a->newer_ctime_nsec)
  1289. return (1); /* Too old, skip it. */
  1290. if (nsec == a->newer_ctime_nsec &&
  1291. (a->newer_ctime_filter & ARCHIVE_MATCH_EQUAL)
  1292. == 0)
  1293. return (1); /* Equal, skip it. */
  1294. }
  1295. }
  1296. if (a->older_ctime_filter) {
  1297. /* If ctime is not set, use mtime instead. */
  1298. if (archive_entry_ctime_is_set(entry))
  1299. sec = archive_entry_ctime(entry);
  1300. else
  1301. sec = archive_entry_mtime(entry);
  1302. if (sec > a->older_ctime_sec)
  1303. return (1); /* Too new, skip it. */
  1304. if (sec == a->older_ctime_sec) {
  1305. if (archive_entry_ctime_is_set(entry))
  1306. nsec = archive_entry_ctime_nsec(entry);
  1307. else
  1308. nsec = archive_entry_mtime_nsec(entry);
  1309. if (nsec > a->older_ctime_nsec)
  1310. return (1); /* Too new, skip it. */
  1311. if (nsec == a->older_ctime_nsec &&
  1312. (a->older_ctime_filter & ARCHIVE_MATCH_EQUAL)
  1313. == 0)
  1314. return (1); /* Eeual, skip it. */
  1315. }
  1316. }
  1317. if (a->newer_mtime_filter) {
  1318. sec = archive_entry_mtime(entry);
  1319. if (sec < a->newer_mtime_sec)
  1320. return (1); /* Too old, skip it. */
  1321. if (sec == a->newer_mtime_sec) {
  1322. nsec = archive_entry_mtime_nsec(entry);
  1323. if (nsec < a->newer_mtime_nsec)
  1324. return (1); /* Too old, skip it. */
  1325. if (nsec == a->newer_mtime_nsec &&
  1326. (a->newer_mtime_filter & ARCHIVE_MATCH_EQUAL)
  1327. == 0)
  1328. return (1); /* Equal, skip it. */
  1329. }
  1330. }
  1331. if (a->older_mtime_filter) {
  1332. sec = archive_entry_mtime(entry);
  1333. if (sec > a->older_mtime_sec)
  1334. return (1); /* Too new, skip it. */
  1335. nsec = archive_entry_mtime_nsec(entry);
  1336. if (sec == a->older_mtime_sec) {
  1337. if (nsec > a->older_mtime_nsec)
  1338. return (1); /* Too new, skip it. */
  1339. if (nsec == a->older_mtime_nsec &&
  1340. (a->older_mtime_filter & ARCHIVE_MATCH_EQUAL)
  1341. == 0)
  1342. return (1); /* Equal, skip it. */
  1343. }
  1344. }
  1345. /* If there is no excluson list, include the file. */
  1346. if (a->exclusion_entry_list.count == 0)
  1347. return (0);
  1348. #if defined(_WIN32) && !defined(__CYGWIN__)
  1349. pathname = archive_entry_pathname_w(entry);
  1350. a->exclusion_tree.rbt_ops = &rb_ops_wcs;
  1351. #else
  1352. (void)rb_ops_wcs;
  1353. pathname = archive_entry_pathname(entry);
  1354. a->exclusion_tree.rbt_ops = &rb_ops_mbs;
  1355. #endif
  1356. if (pathname == NULL)
  1357. return (0);
  1358. f = (struct match_file *)__archive_rb_tree_find_node(
  1359. &(a->exclusion_tree), pathname);
  1360. /* If the file wasn't rejected, include it. */
  1361. if (f == NULL)
  1362. return (0);
  1363. if (f->flag & ARCHIVE_MATCH_CTIME) {
  1364. sec = archive_entry_ctime(entry);
  1365. if (f->ctime_sec > sec) {
  1366. if (f->flag & ARCHIVE_MATCH_OLDER)
  1367. return (1);
  1368. } else if (f->ctime_sec < sec) {
  1369. if (f->flag & ARCHIVE_MATCH_NEWER)
  1370. return (1);
  1371. } else {
  1372. nsec = archive_entry_ctime_nsec(entry);
  1373. if (f->ctime_nsec > nsec) {
  1374. if (f->flag & ARCHIVE_MATCH_OLDER)
  1375. return (1);
  1376. } else if (f->ctime_nsec < nsec) {
  1377. if (f->flag & ARCHIVE_MATCH_NEWER)
  1378. return (1);
  1379. } else if (f->flag & ARCHIVE_MATCH_EQUAL)
  1380. return (1);
  1381. }
  1382. }
  1383. if (f->flag & ARCHIVE_MATCH_MTIME) {
  1384. sec = archive_entry_mtime(entry);
  1385. if (f->mtime_sec > sec) {
  1386. if (f->flag & ARCHIVE_MATCH_OLDER)
  1387. return (1);
  1388. } else if (f->mtime_sec < sec) {
  1389. if (f->flag & ARCHIVE_MATCH_NEWER)
  1390. return (1);
  1391. } else {
  1392. nsec = archive_entry_mtime_nsec(entry);
  1393. if (f->mtime_nsec > nsec) {
  1394. if (f->flag & ARCHIVE_MATCH_OLDER)
  1395. return (1);
  1396. } else if (f->mtime_nsec < nsec) {
  1397. if (f->flag & ARCHIVE_MATCH_NEWER)
  1398. return (1);
  1399. } else if (f->flag & ARCHIVE_MATCH_EQUAL)
  1400. return (1);
  1401. }
  1402. }
  1403. return (0);
  1404. }
  1405. /*
  1406. * Utility functions to manage inclusion owners
  1407. */
  1408. int
  1409. archive_match_include_uid(struct archive *_a, int64_t uid)
  1410. {
  1411. struct archive_match *a;
  1412. archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
  1413. ARCHIVE_STATE_NEW, "archive_match_include_uid");
  1414. a = (struct archive_match *)_a;
  1415. return (add_owner_id(a, &(a->inclusion_uids), uid));
  1416. }
  1417. int
  1418. archive_match_include_gid(struct archive *_a, int64_t gid)
  1419. {
  1420. struct archive_match *a;
  1421. archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
  1422. ARCHIVE_STATE_NEW, "archive_match_include_gid");
  1423. a = (struct archive_match *)_a;
  1424. return (add_owner_id(a, &(a->inclusion_gids), gid));
  1425. }
  1426. int
  1427. archive_match_include_uname(struct archive *_a, const char *uname)
  1428. {
  1429. struct archive_match *a;
  1430. archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
  1431. ARCHIVE_STATE_NEW, "archive_match_include_uname");
  1432. a = (struct archive_match *)_a;
  1433. return (add_owner_name(a, &(a->inclusion_unames), 1, uname));
  1434. }
  1435. int
  1436. archive_match_include_uname_w(struct archive *_a, const wchar_t *uname)
  1437. {
  1438. struct archive_match *a;
  1439. archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
  1440. ARCHIVE_STATE_NEW, "archive_match_include_uname_w");
  1441. a = (struct archive_match *)_a;
  1442. return (add_owner_name(a, &(a->inclusion_unames), 0, uname));
  1443. }
  1444. int
  1445. archive_match_include_gname(struct archive *_a, const char *gname)
  1446. {
  1447. struct archive_match *a;
  1448. archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
  1449. ARCHIVE_STATE_NEW, "archive_match_include_gname");
  1450. a = (struct archive_match *)_a;
  1451. return (add_owner_name(a, &(a->inclusion_gnames), 1, gname));
  1452. }
  1453. int
  1454. archive_match_include_gname_w(struct archive *_a, const wchar_t *gname)
  1455. {
  1456. struct archive_match *a;
  1457. archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
  1458. ARCHIVE_STATE_NEW, "archive_match_include_gname_w");
  1459. a = (struct archive_match *)_a;
  1460. return (add_owner_name(a, &(a->inclusion_gnames), 0, gname));
  1461. }
  1462. /*
  1463. * Test function for owner(uid, gid, uname, gname).
  1464. *
  1465. * Returns 1 if archive entry is excluded.
  1466. * Returns 0 if archive entry is not excluded.
  1467. * Returns <0 if something error happened.
  1468. */
  1469. int
  1470. archive_match_owner_excluded(struct archive *_a,
  1471. struct archive_entry *entry)
  1472. {
  1473. struct archive_match *a;
  1474. archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
  1475. ARCHIVE_STATE_NEW, "archive_match_id_excluded_ae");
  1476. a = (struct archive_match *)_a;
  1477. if (entry == NULL) {
  1478. archive_set_error(&(a->archive), EINVAL, "entry is NULL");
  1479. return (ARCHIVE_FAILED);
  1480. }
  1481. /* If we don't have inclusion id set at all, the entry is always
  1482. * not excluded. */
  1483. if ((a->setflag & ID_IS_SET) == 0)
  1484. return (0);
  1485. return (owner_excluded(a, entry));
  1486. }
  1487. static int
  1488. add_owner_id(struct archive_match *a, struct id_array *ids, int64_t id)
  1489. {
  1490. unsigned i;
  1491. if (ids->count + 1 >= ids->size) {
  1492. void *p;
  1493. if (ids->size == 0)
  1494. ids->size = 8;
  1495. else
  1496. ids->size *= 2;
  1497. p = realloc(ids->ids, sizeof(*ids->ids) * ids->size);
  1498. if (p == NULL)
  1499. return (error_nomem(a));
  1500. ids->ids = (int64_t *)p;
  1501. }
  1502. /* Find an insert point. */
  1503. for (i = 0; i < ids->count; i++) {
  1504. if (ids->ids[i] >= id)
  1505. break;
  1506. }
  1507. /* Add oowner id. */
  1508. if (i == ids->count)
  1509. ids->ids[ids->count++] = id;
  1510. else if (ids->ids[i] != id) {
  1511. memmove(&(ids->ids[i+1]), &(ids->ids[i]),
  1512. (ids->count - i) * sizeof(ids->ids[0]));
  1513. ids->ids[i] = id;
  1514. ids->count++;
  1515. }
  1516. a->setflag |= ID_IS_SET;
  1517. return (ARCHIVE_OK);
  1518. }
  1519. static int
  1520. match_owner_id(struct id_array *ids, int64_t id)
  1521. {
  1522. unsigned b, m, t;
  1523. t = 0;
  1524. b = (unsigned)ids->count;
  1525. while (t < b) {
  1526. m = (t + b)>>1;
  1527. if (ids->ids[m] == id)
  1528. return (1);
  1529. if (ids->ids[m] < id)
  1530. t = m + 1;
  1531. else
  1532. b = m;
  1533. }
  1534. return (0);
  1535. }
  1536. static int
  1537. add_owner_name(struct archive_match *a, struct match_list *list,
  1538. int mbs, const void *name)
  1539. {
  1540. struct match *match;
  1541. match = calloc(1, sizeof(*match));
  1542. if (match == NULL)
  1543. return (error_nomem(a));
  1544. if (mbs)
  1545. archive_mstring_copy_mbs(&(match->pattern), name);
  1546. else
  1547. archive_mstring_copy_wcs(&(match->pattern), name);
  1548. match_list_add(list, match);
  1549. a->setflag |= ID_IS_SET;
  1550. return (ARCHIVE_OK);
  1551. }
  1552. #if !defined(_WIN32) || defined(__CYGWIN__)
  1553. static int
  1554. match_owner_name_mbs(struct archive_match *a, struct match_list *list,
  1555. const char *name)
  1556. {
  1557. struct match *m;
  1558. const char *p;
  1559. if (name == NULL || *name == '\0')
  1560. return (0);
  1561. for (m = list->first; m; m = m->next) {
  1562. if (archive_mstring_get_mbs(&(a->archive), &(m->pattern), &p)
  1563. < 0 && errno == ENOMEM)
  1564. return (error_nomem(a));
  1565. if (p != NULL && strcmp(p, name) == 0) {
  1566. m->matches++;
  1567. return (1);
  1568. }
  1569. }
  1570. return (0);
  1571. }
  1572. #else
  1573. static int
  1574. match_owner_name_wcs(struct archive_match *a, struct match_list *list,
  1575. const wchar_t *name)
  1576. {
  1577. struct match *m;
  1578. const wchar_t *p;
  1579. if (name == NULL || *name == L'\0')
  1580. return (0);
  1581. for (m = list->first; m; m = m->next) {
  1582. if (archive_mstring_get_wcs(&(a->archive), &(m->pattern), &p)
  1583. < 0 && errno == ENOMEM)
  1584. return (error_nomem(a));
  1585. if (p != NULL && wcscmp(p, name) == 0) {
  1586. m->matches++;
  1587. return (1);
  1588. }
  1589. }
  1590. return (0);
  1591. }
  1592. #endif
  1593. /*
  1594. * Test if entry is excluded by uid, gid, uname or gname.
  1595. */
  1596. static int
  1597. owner_excluded(struct archive_match *a, struct archive_entry *entry)
  1598. {
  1599. int r;
  1600. if (a->inclusion_uids.count) {
  1601. if (!match_owner_id(&(a->inclusion_uids),
  1602. archive_entry_uid(entry)))
  1603. return (1);
  1604. }
  1605. if (a->inclusion_gids.count) {
  1606. if (!match_owner_id(&(a->inclusion_gids),
  1607. archive_entry_gid(entry)))
  1608. return (1);
  1609. }
  1610. if (a->inclusion_unames.count) {
  1611. #if defined(_WIN32) && !defined(__CYGWIN__)
  1612. r = match_owner_name_wcs(a, &(a->inclusion_unames),
  1613. archive_entry_uname_w(entry));
  1614. #else
  1615. r = match_owner_name_mbs(a, &(a->inclusion_unames),
  1616. archive_entry_uname(entry));
  1617. #endif
  1618. if (!r)
  1619. return (1);
  1620. else if (r < 0)
  1621. return (r);
  1622. }
  1623. if (a->inclusion_gnames.count) {
  1624. #if defined(_WIN32) && !defined(__CYGWIN__)
  1625. r = match_owner_name_wcs(a, &(a->inclusion_gnames),
  1626. archive_entry_gname_w(entry));
  1627. #else
  1628. r = match_owner_name_mbs(a, &(a->inclusion_gnames),
  1629. archive_entry_gname(entry));
  1630. #endif
  1631. if (!r)
  1632. return (1);
  1633. else if (r < 0)
  1634. return (r);
  1635. }
  1636. return (0);
  1637. }