archive_read_support_format_mtree.c 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993
  1. /*-
  2. * Copyright (c) 2003-2007 Tim Kientzle
  3. * Copyright (c) 2008 Joerg Sonnenberger
  4. * Copyright (c) 2011-2012 Michihiro NAKAJIMA
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
  17. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  18. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  19. * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
  20. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  21. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  22. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  23. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  25. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. #include "archive_platform.h"
  28. __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_mtree.c 201165 2009-12-29 05:52:13Z kientzle $");
  29. #ifdef HAVE_SYS_STAT_H
  30. #include <sys/stat.h>
  31. #endif
  32. #ifdef HAVE_ERRNO_H
  33. #include <errno.h>
  34. #endif
  35. #ifdef HAVE_FCNTL_H
  36. #include <fcntl.h>
  37. #endif
  38. #include <stddef.h>
  39. /* #include <stdint.h> */ /* See archive_platform.h */
  40. #ifdef HAVE_STDLIB_H
  41. #include <stdlib.h>
  42. #endif
  43. #ifdef HAVE_STRING_H
  44. #include <string.h>
  45. #endif
  46. #include "archive.h"
  47. #include "archive_entry.h"
  48. #include "archive_private.h"
  49. #include "archive_read_private.h"
  50. #include "archive_string.h"
  51. #include "archive_pack_dev.h"
  52. #ifndef O_BINARY
  53. #define O_BINARY 0
  54. #endif
  55. #ifndef O_CLOEXEC
  56. #define O_CLOEXEC 0
  57. #endif
  58. #define MTREE_HAS_DEVICE 0x0001
  59. #define MTREE_HAS_FFLAGS 0x0002
  60. #define MTREE_HAS_GID 0x0004
  61. #define MTREE_HAS_GNAME 0x0008
  62. #define MTREE_HAS_MTIME 0x0010
  63. #define MTREE_HAS_NLINK 0x0020
  64. #define MTREE_HAS_PERM 0x0040
  65. #define MTREE_HAS_SIZE 0x0080
  66. #define MTREE_HAS_TYPE 0x0100
  67. #define MTREE_HAS_UID 0x0200
  68. #define MTREE_HAS_UNAME 0x0400
  69. #define MTREE_HAS_OPTIONAL 0x0800
  70. #define MTREE_HAS_NOCHANGE 0x1000 /* FreeBSD specific */
  71. struct mtree_option {
  72. struct mtree_option *next;
  73. char *value;
  74. };
  75. struct mtree_entry {
  76. struct mtree_entry *next;
  77. struct mtree_option *options;
  78. char *name;
  79. char full;
  80. char used;
  81. };
  82. struct mtree {
  83. struct archive_string line;
  84. size_t buffsize;
  85. char *buff;
  86. int64_t offset;
  87. int fd;
  88. int archive_format;
  89. const char *archive_format_name;
  90. struct mtree_entry *entries;
  91. struct mtree_entry *this_entry;
  92. struct archive_string current_dir;
  93. struct archive_string contents_name;
  94. struct archive_entry_linkresolver *resolver;
  95. int64_t cur_size;
  96. char checkfs;
  97. };
  98. static int bid_keycmp(const char *, const char *, ssize_t);
  99. static int cleanup(struct archive_read *);
  100. static int detect_form(struct archive_read *, int *);
  101. static int mtree_bid(struct archive_read *, int);
  102. static int parse_file(struct archive_read *, struct archive_entry *,
  103. struct mtree *, struct mtree_entry *, int *);
  104. static void parse_escapes(char *, struct mtree_entry *);
  105. static int parse_line(struct archive_read *, struct archive_entry *,
  106. struct mtree *, struct mtree_entry *, int *);
  107. static int parse_keyword(struct archive_read *, struct mtree *,
  108. struct archive_entry *, struct mtree_option *, int *);
  109. static int read_data(struct archive_read *a,
  110. const void **buff, size_t *size, int64_t *offset);
  111. static ssize_t readline(struct archive_read *, struct mtree *, char **, ssize_t);
  112. static int skip(struct archive_read *a);
  113. static int read_header(struct archive_read *,
  114. struct archive_entry *);
  115. static int64_t mtree_atol10(char **);
  116. static int64_t mtree_atol8(char **);
  117. static int64_t mtree_atol(char **);
  118. /*
  119. * There's no standard for TIME_T_MAX/TIME_T_MIN. So we compute them
  120. * here. TODO: Move this to configure time, but be careful
  121. * about cross-compile environments.
  122. */
  123. static int64_t
  124. get_time_t_max(void)
  125. {
  126. #if defined(TIME_T_MAX)
  127. return TIME_T_MAX;
  128. #else
  129. /* ISO C allows time_t to be a floating-point type,
  130. but POSIX requires an integer type. The following
  131. should work on any system that follows the POSIX
  132. conventions. */
  133. if (((time_t)0) < ((time_t)-1)) {
  134. /* Time_t is unsigned */
  135. return (~(time_t)0);
  136. } else {
  137. /* Time_t is signed. */
  138. /* Assume it's the same as int64_t or int32_t */
  139. if (sizeof(time_t) == sizeof(int64_t)) {
  140. return (time_t)INT64_MAX;
  141. } else {
  142. return (time_t)INT32_MAX;
  143. }
  144. }
  145. #endif
  146. }
  147. static int64_t
  148. get_time_t_min(void)
  149. {
  150. #if defined(TIME_T_MIN)
  151. return TIME_T_MIN;
  152. #else
  153. if (((time_t)0) < ((time_t)-1)) {
  154. /* Time_t is unsigned */
  155. return (time_t)0;
  156. } else {
  157. /* Time_t is signed. */
  158. if (sizeof(time_t) == sizeof(int64_t)) {
  159. return (time_t)INT64_MIN;
  160. } else {
  161. return (time_t)INT32_MIN;
  162. }
  163. }
  164. #endif
  165. }
  166. static int
  167. archive_read_format_mtree_options(struct archive_read *a,
  168. const char *key, const char *val)
  169. {
  170. struct mtree *mtree;
  171. mtree = (struct mtree *)(a->format->data);
  172. if (strcmp(key, "checkfs") == 0) {
  173. /* Allows to read information missing from the mtree from the file system */
  174. if (val == NULL || val[0] == 0) {
  175. mtree->checkfs = 0;
  176. } else {
  177. mtree->checkfs = 1;
  178. }
  179. return (ARCHIVE_OK);
  180. }
  181. /* Note: The "warn" return is just to inform the options
  182. * supervisor that we didn't handle it. It will generate
  183. * a suitable error if no one used this option. */
  184. return (ARCHIVE_WARN);
  185. }
  186. static void
  187. free_options(struct mtree_option *head)
  188. {
  189. struct mtree_option *next;
  190. for (; head != NULL; head = next) {
  191. next = head->next;
  192. free(head->value);
  193. free(head);
  194. }
  195. }
  196. int
  197. archive_read_support_format_mtree(struct archive *_a)
  198. {
  199. struct archive_read *a = (struct archive_read *)_a;
  200. struct mtree *mtree;
  201. int r;
  202. archive_check_magic(_a, ARCHIVE_READ_MAGIC,
  203. ARCHIVE_STATE_NEW, "archive_read_support_format_mtree");
  204. mtree = (struct mtree *)malloc(sizeof(*mtree));
  205. if (mtree == NULL) {
  206. archive_set_error(&a->archive, ENOMEM,
  207. "Can't allocate mtree data");
  208. return (ARCHIVE_FATAL);
  209. }
  210. memset(mtree, 0, sizeof(*mtree));
  211. mtree->fd = -1;
  212. r = __archive_read_register_format(a, mtree, "mtree",
  213. mtree_bid, archive_read_format_mtree_options, read_header, read_data, skip, NULL, cleanup, NULL, NULL);
  214. if (r != ARCHIVE_OK)
  215. free(mtree);
  216. return (ARCHIVE_OK);
  217. }
  218. static int
  219. cleanup(struct archive_read *a)
  220. {
  221. struct mtree *mtree;
  222. struct mtree_entry *p, *q;
  223. mtree = (struct mtree *)(a->format->data);
  224. p = mtree->entries;
  225. while (p != NULL) {
  226. q = p->next;
  227. free(p->name);
  228. free_options(p->options);
  229. free(p);
  230. p = q;
  231. }
  232. archive_string_free(&mtree->line);
  233. archive_string_free(&mtree->current_dir);
  234. archive_string_free(&mtree->contents_name);
  235. archive_entry_linkresolver_free(mtree->resolver);
  236. free(mtree->buff);
  237. free(mtree);
  238. (a->format->data) = NULL;
  239. return (ARCHIVE_OK);
  240. }
  241. static ssize_t
  242. get_line_size(const char *b, ssize_t avail, ssize_t *nlsize)
  243. {
  244. ssize_t len;
  245. len = 0;
  246. while (len < avail) {
  247. switch (*b) {
  248. case '\0':/* Non-ascii character or control character. */
  249. if (nlsize != NULL)
  250. *nlsize = 0;
  251. return (-1);
  252. case '\r':
  253. if (avail-len > 1 && b[1] == '\n') {
  254. if (nlsize != NULL)
  255. *nlsize = 2;
  256. return (len+2);
  257. }
  258. /* FALL THROUGH */
  259. case '\n':
  260. if (nlsize != NULL)
  261. *nlsize = 1;
  262. return (len+1);
  263. default:
  264. b++;
  265. len++;
  266. break;
  267. }
  268. }
  269. if (nlsize != NULL)
  270. *nlsize = 0;
  271. return (avail);
  272. }
  273. static ssize_t
  274. next_line(struct archive_read *a,
  275. const char **b, ssize_t *avail, ssize_t *ravail, ssize_t *nl)
  276. {
  277. ssize_t len;
  278. int quit;
  279. quit = 0;
  280. if (*avail == 0) {
  281. *nl = 0;
  282. len = 0;
  283. } else
  284. len = get_line_size(*b, *avail, nl);
  285. /*
  286. * Read bytes more while it does not reach the end of line.
  287. */
  288. while (*nl == 0 && len == *avail && !quit) {
  289. ssize_t diff = *ravail - *avail;
  290. size_t nbytes_req = (*ravail+1023) & ~1023U;
  291. ssize_t tested;
  292. /* Increase reading bytes if it is not enough to at least
  293. * new two lines. */
  294. if (nbytes_req < (size_t)*ravail + 160)
  295. nbytes_req <<= 1;
  296. *b = __archive_read_ahead(a, nbytes_req, avail);
  297. if (*b == NULL) {
  298. if (*ravail >= *avail)
  299. return (0);
  300. /* Reading bytes reaches the end of file. */
  301. *b = __archive_read_ahead(a, *avail, avail);
  302. quit = 1;
  303. }
  304. *ravail = *avail;
  305. *b += diff;
  306. *avail -= diff;
  307. tested = len;/* Skip some bytes we already determinated. */
  308. len = get_line_size(*b, *avail, nl);
  309. if (len >= 0)
  310. len += tested;
  311. }
  312. return (len);
  313. }
  314. /*
  315. * Compare characters with a mtree keyword.
  316. * Returns the length of a mtree keyword if matched.
  317. * Returns 0 if not matched.
  318. */
  319. static int
  320. bid_keycmp(const char *p, const char *key, ssize_t len)
  321. {
  322. int match_len = 0;
  323. while (len > 0 && *p && *key) {
  324. if (*p == *key) {
  325. --len;
  326. ++p;
  327. ++key;
  328. ++match_len;
  329. continue;
  330. }
  331. return (0);/* Not match */
  332. }
  333. if (*key != '\0')
  334. return (0);/* Not match */
  335. /* A following character should be specified characters */
  336. if (p[0] == '=' || p[0] == ' ' || p[0] == '\t' ||
  337. p[0] == '\n' || p[0] == '\r' ||
  338. (p[0] == '\\' && (p[1] == '\n' || p[1] == '\r')))
  339. return (match_len);
  340. return (0);/* Not match */
  341. }
  342. /*
  343. * Test whether the characters 'p' has is mtree keyword.
  344. * Returns the length of a detected keyword.
  345. * Returns 0 if any keywords were not found.
  346. */
  347. static int
  348. bid_keyword(const char *p, ssize_t len)
  349. {
  350. static const char *keys_c[] = {
  351. "content", "contents", "cksum", NULL
  352. };
  353. static const char *keys_df[] = {
  354. "device", "flags", NULL
  355. };
  356. static const char *keys_g[] = {
  357. "gid", "gname", NULL
  358. };
  359. static const char *keys_il[] = {
  360. "ignore", "inode", "link", NULL
  361. };
  362. static const char *keys_m[] = {
  363. "md5", "md5digest", "mode", NULL
  364. };
  365. static const char *keys_no[] = {
  366. "nlink", "nochange", "optional", NULL
  367. };
  368. static const char *keys_r[] = {
  369. "resdevice", "rmd160", "rmd160digest", NULL
  370. };
  371. static const char *keys_s[] = {
  372. "sha1", "sha1digest",
  373. "sha256", "sha256digest",
  374. "sha384", "sha384digest",
  375. "sha512", "sha512digest",
  376. "size", NULL
  377. };
  378. static const char *keys_t[] = {
  379. "tags", "time", "type", NULL
  380. };
  381. static const char *keys_u[] = {
  382. "uid", "uname", NULL
  383. };
  384. const char **keys;
  385. int i;
  386. switch (*p) {
  387. case 'c': keys = keys_c; break;
  388. case 'd': case 'f': keys = keys_df; break;
  389. case 'g': keys = keys_g; break;
  390. case 'i': case 'l': keys = keys_il; break;
  391. case 'm': keys = keys_m; break;
  392. case 'n': case 'o': keys = keys_no; break;
  393. case 'r': keys = keys_r; break;
  394. case 's': keys = keys_s; break;
  395. case 't': keys = keys_t; break;
  396. case 'u': keys = keys_u; break;
  397. default: return (0);/* Unknown key */
  398. }
  399. for (i = 0; keys[i] != NULL; i++) {
  400. int l = bid_keycmp(p, keys[i], len);
  401. if (l > 0)
  402. return (l);
  403. }
  404. return (0);/* Unknown key */
  405. }
  406. /*
  407. * Test whether there is a set of mtree keywords.
  408. * Returns the number of keyword.
  409. * Returns -1 if we got incorrect sequence.
  410. * This function expects a set of "<space characters>keyword=value".
  411. * When "unset" is specified, expects a set of "<space characters>keyword".
  412. */
  413. static int
  414. bid_keyword_list(const char *p, ssize_t len, int unset, int last_is_path)
  415. {
  416. int l;
  417. int keycnt = 0;
  418. while (len > 0 && *p) {
  419. int blank = 0;
  420. /* Test whether there are blank characters in the line. */
  421. while (len >0 && (*p == ' ' || *p == '\t')) {
  422. ++p;
  423. --len;
  424. blank = 1;
  425. }
  426. if (*p == '\n' || *p == '\r')
  427. break;
  428. if (p[0] == '\\' && (p[1] == '\n' || p[1] == '\r'))
  429. break;
  430. if (!blank && !last_is_path) /* No blank character. */
  431. return (-1);
  432. if (last_is_path && len == 0)
  433. return (keycnt);
  434. if (unset) {
  435. l = bid_keycmp(p, "all", len);
  436. if (l > 0)
  437. return (1);
  438. }
  439. /* Test whether there is a correct key in the line. */
  440. l = bid_keyword(p, len);
  441. if (l == 0)
  442. return (-1);/* Unknown keyword was found. */
  443. p += l;
  444. len -= l;
  445. keycnt++;
  446. /* Skip value */
  447. if (*p == '=') {
  448. int value = 0;
  449. ++p;
  450. --len;
  451. while (len > 0 && *p != ' ' && *p != '\t') {
  452. ++p;
  453. --len;
  454. value = 1;
  455. }
  456. /* A keyword should have a its value unless
  457. * "/unset" operation. */
  458. if (!unset && value == 0)
  459. return (-1);
  460. }
  461. }
  462. return (keycnt);
  463. }
  464. static int
  465. bid_entry(const char *p, ssize_t len, ssize_t nl, int *last_is_path)
  466. {
  467. int f = 0;
  468. static const unsigned char safe_char[256] = {
  469. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 0F */
  470. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1F */
  471. /* !"$%&'()*+,-./ EXCLUSION:( )(#) */
  472. 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 - 2F */
  473. /* 0123456789:;<>? EXCLUSION:(=) */
  474. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, /* 30 - 3F */
  475. /* @ABCDEFGHIJKLMNO */
  476. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */
  477. /* PQRSTUVWXYZ[\]^_ */
  478. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 50 - 5F */
  479. /* `abcdefghijklmno */
  480. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 - 6F */
  481. /* pqrstuvwxyz{|}~ */
  482. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* 70 - 7F */
  483. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */
  484. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */
  485. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */
  486. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */
  487. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */
  488. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */
  489. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */
  490. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F0 - FF */
  491. };
  492. ssize_t ll;
  493. const char *pp = p;
  494. const char * const pp_end = pp + len;
  495. *last_is_path = 0;
  496. /*
  497. * Skip the path-name which is quoted.
  498. */
  499. for (;pp < pp_end; ++pp) {
  500. if (!safe_char[*(const unsigned char *)pp]) {
  501. if (*pp != ' ' && *pp != '\t' && *pp != '\r'
  502. && *pp != '\n')
  503. f = 0;
  504. break;
  505. }
  506. f = 1;
  507. }
  508. ll = pp_end - pp;
  509. /* If a path-name was not found at the first, try to check
  510. * a mtree format(a.k.a form D) ``NetBSD's mtree -D'' creates,
  511. * which places the path-name at the last. */
  512. if (f == 0) {
  513. const char *pb = p + len - nl;
  514. int name_len = 0;
  515. int slash;
  516. /* The form D accepts only a single line for an entry. */
  517. if (pb-2 >= p &&
  518. pb[-1] == '\\' && (pb[-2] == ' ' || pb[-2] == '\t'))
  519. return (-1);
  520. if (pb-1 >= p && pb[-1] == '\\')
  521. return (-1);
  522. slash = 0;
  523. while (p <= --pb && *pb != ' ' && *pb != '\t') {
  524. if (!safe_char[*(const unsigned char *)pb])
  525. return (-1);
  526. name_len++;
  527. /* The pathname should have a slash in this
  528. * format. */
  529. if (*pb == '/')
  530. slash = 1;
  531. }
  532. if (name_len == 0 || slash == 0)
  533. return (-1);
  534. /* If '/' is placed at the first in this field, this is not
  535. * a valid filename. */
  536. if (pb[1] == '/')
  537. return (-1);
  538. ll = len - nl - name_len;
  539. pp = p;
  540. *last_is_path = 1;
  541. }
  542. return (bid_keyword_list(pp, ll, 0, *last_is_path));
  543. }
  544. #define MAX_BID_ENTRY 3
  545. static int
  546. mtree_bid(struct archive_read *a, int best_bid)
  547. {
  548. const char *signature = "#mtree";
  549. const char *p;
  550. (void)best_bid; /* UNUSED */
  551. /* Now let's look at the actual header and see if it matches. */
  552. p = __archive_read_ahead(a, strlen(signature), NULL);
  553. if (p == NULL)
  554. return (-1);
  555. if (memcmp(p, signature, strlen(signature)) == 0)
  556. return (8 * (int)strlen(signature));
  557. /*
  558. * There is not a mtree signature. Let's try to detect mtree format.
  559. */
  560. return (detect_form(a, NULL));
  561. }
  562. static int
  563. detect_form(struct archive_read *a, int *is_form_d)
  564. {
  565. const char *p;
  566. ssize_t avail, ravail;
  567. ssize_t detected_bytes = 0, len, nl;
  568. int entry_cnt = 0, multiline = 0;
  569. int form_D = 0;/* The archive is generated by `NetBSD mtree -D'
  570. * (In this source we call it `form D') . */
  571. if (is_form_d != NULL)
  572. *is_form_d = 0;
  573. p = __archive_read_ahead(a, 1, &avail);
  574. if (p == NULL)
  575. return (-1);
  576. ravail = avail;
  577. for (;;) {
  578. len = next_line(a, &p, &avail, &ravail, &nl);
  579. /* The terminal character of the line should be
  580. * a new line character, '\r\n' or '\n'. */
  581. if (len <= 0 || nl == 0)
  582. break;
  583. if (!multiline) {
  584. /* Leading whitespace is never significant,
  585. * ignore it. */
  586. while (len > 0 && (*p == ' ' || *p == '\t')) {
  587. ++p;
  588. --avail;
  589. --len;
  590. }
  591. /* Skip comment or empty line. */
  592. if (p[0] == '#' || p[0] == '\n' || p[0] == '\r') {
  593. p += len;
  594. avail -= len;
  595. continue;
  596. }
  597. } else {
  598. /* A continuance line; the terminal
  599. * character of previous line was '\' character. */
  600. if (bid_keyword_list(p, len, 0, 0) <= 0)
  601. break;
  602. if (multiline == 1)
  603. detected_bytes += len;
  604. if (p[len-nl-1] != '\\') {
  605. if (multiline == 1 &&
  606. ++entry_cnt >= MAX_BID_ENTRY)
  607. break;
  608. multiline = 0;
  609. }
  610. p += len;
  611. avail -= len;
  612. continue;
  613. }
  614. if (p[0] != '/') {
  615. int last_is_path, keywords;
  616. keywords = bid_entry(p, len, nl, &last_is_path);
  617. if (keywords >= 0) {
  618. detected_bytes += len;
  619. if (form_D == 0) {
  620. if (last_is_path)
  621. form_D = 1;
  622. else if (keywords > 0)
  623. /* This line is not `form D'. */
  624. form_D = -1;
  625. } else if (form_D == 1) {
  626. if (!last_is_path && keywords > 0)
  627. /* This this is not `form D'
  628. * and We cannot accept mixed
  629. * format. */
  630. break;
  631. }
  632. if (!last_is_path && p[len-nl-1] == '\\')
  633. /* This line continues. */
  634. multiline = 1;
  635. else {
  636. /* We've got plenty of correct lines
  637. * to assume that this file is a mtree
  638. * format. */
  639. if (++entry_cnt >= MAX_BID_ENTRY)
  640. break;
  641. }
  642. } else
  643. break;
  644. } else if (strncmp(p, "/set", 4) == 0) {
  645. if (bid_keyword_list(p+4, len-4, 0, 0) <= 0)
  646. break;
  647. /* This line continues. */
  648. if (p[len-nl-1] == '\\')
  649. multiline = 2;
  650. } else if (strncmp(p, "/unset", 6) == 0) {
  651. if (bid_keyword_list(p+6, len-6, 1, 0) <= 0)
  652. break;
  653. /* This line continues. */
  654. if (p[len-nl-1] == '\\')
  655. multiline = 2;
  656. } else
  657. break;
  658. /* Test next line. */
  659. p += len;
  660. avail -= len;
  661. }
  662. if (entry_cnt >= MAX_BID_ENTRY || (entry_cnt > 0 && len == 0)) {
  663. if (is_form_d != NULL) {
  664. if (form_D == 1)
  665. *is_form_d = 1;
  666. }
  667. return (32);
  668. }
  669. return (0);
  670. }
  671. /*
  672. * The extended mtree format permits multiple lines specifying
  673. * attributes for each file. For those entries, only the last line
  674. * is actually used. Practically speaking, that means we have
  675. * to read the entire mtree file into memory up front.
  676. *
  677. * The parsing is done in two steps. First, it is decided if a line
  678. * changes the global defaults and if it is, processed accordingly.
  679. * Otherwise, the options of the line are merged with the current
  680. * global options.
  681. */
  682. static int
  683. add_option(struct archive_read *a, struct mtree_option **global,
  684. const char *value, size_t len)
  685. {
  686. struct mtree_option *opt;
  687. if ((opt = malloc(sizeof(*opt))) == NULL) {
  688. archive_set_error(&a->archive, errno, "Can't allocate memory");
  689. return (ARCHIVE_FATAL);
  690. }
  691. if ((opt->value = malloc(len + 1)) == NULL) {
  692. free(opt);
  693. archive_set_error(&a->archive, errno, "Can't allocate memory");
  694. return (ARCHIVE_FATAL);
  695. }
  696. memcpy(opt->value, value, len);
  697. opt->value[len] = '\0';
  698. opt->next = *global;
  699. *global = opt;
  700. return (ARCHIVE_OK);
  701. }
  702. static void
  703. remove_option(struct mtree_option **global, const char *value, size_t len)
  704. {
  705. struct mtree_option *iter, *last;
  706. last = NULL;
  707. for (iter = *global; iter != NULL; last = iter, iter = iter->next) {
  708. if (strncmp(iter->value, value, len) == 0 &&
  709. (iter->value[len] == '\0' ||
  710. iter->value[len] == '='))
  711. break;
  712. }
  713. if (iter == NULL)
  714. return;
  715. if (last == NULL)
  716. *global = iter->next;
  717. else
  718. last->next = iter->next;
  719. free(iter->value);
  720. free(iter);
  721. }
  722. static int
  723. process_global_set(struct archive_read *a,
  724. struct mtree_option **global, const char *line)
  725. {
  726. const char *next, *eq;
  727. size_t len;
  728. int r;
  729. line += 4;
  730. for (;;) {
  731. next = line + strspn(line, " \t\r\n");
  732. if (*next == '\0')
  733. return (ARCHIVE_OK);
  734. line = next;
  735. next = line + strcspn(line, " \t\r\n");
  736. eq = strchr(line, '=');
  737. if (eq > next)
  738. len = next - line;
  739. else
  740. len = eq - line;
  741. remove_option(global, line, len);
  742. r = add_option(a, global, line, next - line);
  743. if (r != ARCHIVE_OK)
  744. return (r);
  745. line = next;
  746. }
  747. }
  748. static int
  749. process_global_unset(struct archive_read *a,
  750. struct mtree_option **global, const char *line)
  751. {
  752. const char *next;
  753. size_t len;
  754. line += 6;
  755. if (strchr(line, '=') != NULL) {
  756. archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
  757. "/unset shall not contain `='");
  758. return ARCHIVE_FATAL;
  759. }
  760. for (;;) {
  761. next = line + strspn(line, " \t\r\n");
  762. if (*next == '\0')
  763. return (ARCHIVE_OK);
  764. line = next;
  765. len = strcspn(line, " \t\r\n");
  766. if (len == 3 && strncmp(line, "all", 3) == 0) {
  767. free_options(*global);
  768. *global = NULL;
  769. } else {
  770. remove_option(global, line, len);
  771. }
  772. line += len;
  773. }
  774. }
  775. static int
  776. process_add_entry(struct archive_read *a, struct mtree *mtree,
  777. struct mtree_option **global, const char *line, ssize_t line_len,
  778. struct mtree_entry **last_entry, int is_form_d)
  779. {
  780. struct mtree_entry *entry;
  781. struct mtree_option *iter;
  782. const char *next, *eq, *name, *end;
  783. size_t name_len, len;
  784. int r, i;
  785. if ((entry = malloc(sizeof(*entry))) == NULL) {
  786. archive_set_error(&a->archive, errno, "Can't allocate memory");
  787. return (ARCHIVE_FATAL);
  788. }
  789. entry->next = NULL;
  790. entry->options = NULL;
  791. entry->name = NULL;
  792. entry->used = 0;
  793. entry->full = 0;
  794. /* Add this entry to list. */
  795. if (*last_entry == NULL)
  796. mtree->entries = entry;
  797. else
  798. (*last_entry)->next = entry;
  799. *last_entry = entry;
  800. if (is_form_d) {
  801. /* Filename is last item on line. */
  802. /* Adjust line_len to trim trailing whitespace */
  803. while (line_len > 0) {
  804. char last_character = line[line_len - 1];
  805. if (last_character == '\r'
  806. || last_character == '\n'
  807. || last_character == '\t'
  808. || last_character == ' ') {
  809. line_len--;
  810. } else {
  811. break;
  812. }
  813. }
  814. /* Name starts after the last whitespace separator */
  815. name = line;
  816. for (i = 0; i < line_len; i++) {
  817. if (line[i] == '\r'
  818. || line[i] == '\n'
  819. || line[i] == '\t'
  820. || line[i] == ' ') {
  821. name = line + i + 1;
  822. }
  823. }
  824. name_len = line + line_len - name;
  825. end = name;
  826. } else {
  827. /* Filename is first item on line */
  828. name_len = strcspn(line, " \t\r\n");
  829. name = line;
  830. line += name_len;
  831. end = line + line_len;
  832. }
  833. /* name/name_len is the name within the line. */
  834. /* line..end brackets the entire line except the name */
  835. if ((entry->name = malloc(name_len + 1)) == NULL) {
  836. archive_set_error(&a->archive, errno, "Can't allocate memory");
  837. return (ARCHIVE_FATAL);
  838. }
  839. memcpy(entry->name, name, name_len);
  840. entry->name[name_len] = '\0';
  841. parse_escapes(entry->name, entry);
  842. for (iter = *global; iter != NULL; iter = iter->next) {
  843. r = add_option(a, &entry->options, iter->value,
  844. strlen(iter->value));
  845. if (r != ARCHIVE_OK)
  846. return (r);
  847. }
  848. for (;;) {
  849. next = line + strspn(line, " \t\r\n");
  850. if (*next == '\0')
  851. return (ARCHIVE_OK);
  852. if (next >= end)
  853. return (ARCHIVE_OK);
  854. line = next;
  855. next = line + strcspn(line, " \t\r\n");
  856. eq = strchr(line, '=');
  857. if (eq == NULL || eq > next)
  858. len = next - line;
  859. else
  860. len = eq - line;
  861. remove_option(&entry->options, line, len);
  862. r = add_option(a, &entry->options, line, next - line);
  863. if (r != ARCHIVE_OK)
  864. return (r);
  865. line = next;
  866. }
  867. }
  868. static int
  869. read_mtree(struct archive_read *a, struct mtree *mtree)
  870. {
  871. ssize_t len;
  872. uintmax_t counter;
  873. char *p;
  874. struct mtree_option *global;
  875. struct mtree_entry *last_entry;
  876. int r, is_form_d;
  877. mtree->archive_format = ARCHIVE_FORMAT_MTREE;
  878. mtree->archive_format_name = "mtree";
  879. global = NULL;
  880. last_entry = NULL;
  881. (void)detect_form(a, &is_form_d);
  882. for (counter = 1; ; ++counter) {
  883. len = readline(a, mtree, &p, 65536);
  884. if (len == 0) {
  885. mtree->this_entry = mtree->entries;
  886. free_options(global);
  887. return (ARCHIVE_OK);
  888. }
  889. if (len < 0) {
  890. free_options(global);
  891. return ((int)len);
  892. }
  893. /* Leading whitespace is never significant, ignore it. */
  894. while (*p == ' ' || *p == '\t') {
  895. ++p;
  896. --len;
  897. }
  898. /* Skip content lines and blank lines. */
  899. if (*p == '#')
  900. continue;
  901. if (*p == '\r' || *p == '\n' || *p == '\0')
  902. continue;
  903. if (*p != '/') {
  904. r = process_add_entry(a, mtree, &global, p, len,
  905. &last_entry, is_form_d);
  906. } else if (strncmp(p, "/set", 4) == 0) {
  907. if (p[4] != ' ' && p[4] != '\t')
  908. break;
  909. r = process_global_set(a, &global, p);
  910. } else if (strncmp(p, "/unset", 6) == 0) {
  911. if (p[6] != ' ' && p[6] != '\t')
  912. break;
  913. r = process_global_unset(a, &global, p);
  914. } else
  915. break;
  916. if (r != ARCHIVE_OK) {
  917. free_options(global);
  918. return r;
  919. }
  920. }
  921. archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
  922. "Can't parse line %ju", counter);
  923. free_options(global);
  924. return (ARCHIVE_FATAL);
  925. }
  926. /*
  927. * Read in the entire mtree file into memory on the first request.
  928. * Then use the next unused file to satisfy each header request.
  929. */
  930. static int
  931. read_header(struct archive_read *a, struct archive_entry *entry)
  932. {
  933. struct mtree *mtree;
  934. char *p;
  935. int r, use_next;
  936. mtree = (struct mtree *)(a->format->data);
  937. if (mtree->fd >= 0) {
  938. close(mtree->fd);
  939. mtree->fd = -1;
  940. }
  941. if (mtree->entries == NULL) {
  942. mtree->resolver = archive_entry_linkresolver_new();
  943. if (mtree->resolver == NULL)
  944. return ARCHIVE_FATAL;
  945. archive_entry_linkresolver_set_strategy(mtree->resolver,
  946. ARCHIVE_FORMAT_MTREE);
  947. r = read_mtree(a, mtree);
  948. if (r != ARCHIVE_OK)
  949. return (r);
  950. }
  951. a->archive.archive_format = mtree->archive_format;
  952. a->archive.archive_format_name = mtree->archive_format_name;
  953. for (;;) {
  954. if (mtree->this_entry == NULL)
  955. return (ARCHIVE_EOF);
  956. if (strcmp(mtree->this_entry->name, "..") == 0) {
  957. mtree->this_entry->used = 1;
  958. if (archive_strlen(&mtree->current_dir) > 0) {
  959. /* Roll back current path. */
  960. p = mtree->current_dir.s
  961. + mtree->current_dir.length - 1;
  962. while (p >= mtree->current_dir.s && *p != '/')
  963. --p;
  964. if (p >= mtree->current_dir.s)
  965. --p;
  966. mtree->current_dir.length
  967. = p - mtree->current_dir.s + 1;
  968. }
  969. }
  970. if (!mtree->this_entry->used) {
  971. use_next = 0;
  972. r = parse_file(a, entry, mtree, mtree->this_entry,
  973. &use_next);
  974. if (use_next == 0)
  975. return (r);
  976. }
  977. mtree->this_entry = mtree->this_entry->next;
  978. }
  979. }
  980. /*
  981. * A single file can have multiple lines contribute specifications.
  982. * Parse as many lines as necessary, then pull additional information
  983. * from a backing file on disk as necessary.
  984. */
  985. static int
  986. parse_file(struct archive_read *a, struct archive_entry *entry,
  987. struct mtree *mtree, struct mtree_entry *mentry, int *use_next)
  988. {
  989. const char *path;
  990. struct stat st_storage, *st;
  991. struct mtree_entry *mp;
  992. struct archive_entry *sparse_entry;
  993. int r = ARCHIVE_OK, r1, parsed_kws;
  994. mentry->used = 1;
  995. /* Initialize reasonable defaults. */
  996. archive_entry_set_filetype(entry, AE_IFREG);
  997. archive_entry_set_size(entry, 0);
  998. archive_string_empty(&mtree->contents_name);
  999. /* Parse options from this line. */
  1000. parsed_kws = 0;
  1001. r = parse_line(a, entry, mtree, mentry, &parsed_kws);
  1002. if (mentry->full) {
  1003. archive_entry_copy_pathname(entry, mentry->name);
  1004. /*
  1005. * "Full" entries are allowed to have multiple lines
  1006. * and those lines aren't required to be adjacent. We
  1007. * don't support multiple lines for "relative" entries
  1008. * nor do we make any attempt to merge data from
  1009. * separate "relative" and "full" entries. (Merging
  1010. * "relative" and "full" entries would require dealing
  1011. * with pathname canonicalization, which is a very
  1012. * tricky subject.)
  1013. */
  1014. for (mp = mentry->next; mp != NULL; mp = mp->next) {
  1015. if (mp->full && !mp->used
  1016. && strcmp(mentry->name, mp->name) == 0) {
  1017. /* Later lines override earlier ones. */
  1018. mp->used = 1;
  1019. r1 = parse_line(a, entry, mtree, mp,
  1020. &parsed_kws);
  1021. if (r1 < r)
  1022. r = r1;
  1023. }
  1024. }
  1025. } else {
  1026. /*
  1027. * Relative entries require us to construct
  1028. * the full path and possibly update the
  1029. * current directory.
  1030. */
  1031. size_t n = archive_strlen(&mtree->current_dir);
  1032. if (n > 0)
  1033. archive_strcat(&mtree->current_dir, "/");
  1034. archive_strcat(&mtree->current_dir, mentry->name);
  1035. archive_entry_copy_pathname(entry, mtree->current_dir.s);
  1036. if (archive_entry_filetype(entry) != AE_IFDIR)
  1037. mtree->current_dir.length = n;
  1038. }
  1039. if (mtree->checkfs) {
  1040. /*
  1041. * Try to open and stat the file to get the real size
  1042. * and other file info. It would be nice to avoid
  1043. * this here so that getting a listing of an mtree
  1044. * wouldn't require opening every referenced contents
  1045. * file. But then we wouldn't know the actual
  1046. * contents size, so I don't see a really viable way
  1047. * around this. (Also, we may want to someday pull
  1048. * other unspecified info from the contents file on
  1049. * disk.)
  1050. */
  1051. mtree->fd = -1;
  1052. if (archive_strlen(&mtree->contents_name) > 0)
  1053. path = mtree->contents_name.s;
  1054. else
  1055. path = archive_entry_pathname(entry);
  1056. if (archive_entry_filetype(entry) == AE_IFREG ||
  1057. archive_entry_filetype(entry) == AE_IFDIR) {
  1058. mtree->fd = open(path, O_RDONLY | O_BINARY | O_CLOEXEC);
  1059. __archive_ensure_cloexec_flag(mtree->fd);
  1060. if (mtree->fd == -1 &&
  1061. (errno != ENOENT ||
  1062. archive_strlen(&mtree->contents_name) > 0)) {
  1063. archive_set_error(&a->archive, errno,
  1064. "Can't open %s", path);
  1065. r = ARCHIVE_WARN;
  1066. }
  1067. }
  1068. st = &st_storage;
  1069. if (mtree->fd >= 0) {
  1070. if (fstat(mtree->fd, st) == -1) {
  1071. archive_set_error(&a->archive, errno,
  1072. "Could not fstat %s", path);
  1073. r = ARCHIVE_WARN;
  1074. /* If we can't stat it, don't keep it open. */
  1075. close(mtree->fd);
  1076. mtree->fd = -1;
  1077. st = NULL;
  1078. }
  1079. } else if (lstat(path, st) == -1) {
  1080. st = NULL;
  1081. }
  1082. /*
  1083. * Check for a mismatch between the type in the specification
  1084. * and the type of the contents object on disk.
  1085. */
  1086. if (st != NULL) {
  1087. if (((st->st_mode & S_IFMT) == S_IFREG &&
  1088. archive_entry_filetype(entry) == AE_IFREG)
  1089. #ifdef S_IFLNK
  1090. ||((st->st_mode & S_IFMT) == S_IFLNK &&
  1091. archive_entry_filetype(entry) == AE_IFLNK)
  1092. #endif
  1093. #ifdef S_IFSOCK
  1094. ||((st->st_mode & S_IFSOCK) == S_IFSOCK &&
  1095. archive_entry_filetype(entry) == AE_IFSOCK)
  1096. #endif
  1097. #ifdef S_IFCHR
  1098. ||((st->st_mode & S_IFMT) == S_IFCHR &&
  1099. archive_entry_filetype(entry) == AE_IFCHR)
  1100. #endif
  1101. #ifdef S_IFBLK
  1102. ||((st->st_mode & S_IFMT) == S_IFBLK &&
  1103. archive_entry_filetype(entry) == AE_IFBLK)
  1104. #endif
  1105. ||((st->st_mode & S_IFMT) == S_IFDIR &&
  1106. archive_entry_filetype(entry) == AE_IFDIR)
  1107. #ifdef S_IFIFO
  1108. ||((st->st_mode & S_IFMT) == S_IFIFO &&
  1109. archive_entry_filetype(entry) == AE_IFIFO)
  1110. #endif
  1111. ) {
  1112. /* Types match. */
  1113. } else {
  1114. /* Types don't match; bail out gracefully. */
  1115. if (mtree->fd >= 0)
  1116. close(mtree->fd);
  1117. mtree->fd = -1;
  1118. if (parsed_kws & MTREE_HAS_OPTIONAL) {
  1119. /* It's not an error for an optional
  1120. * entry to not match disk. */
  1121. *use_next = 1;
  1122. } else if (r == ARCHIVE_OK) {
  1123. archive_set_error(&a->archive,
  1124. ARCHIVE_ERRNO_MISC,
  1125. "mtree specification has different"
  1126. " type for %s",
  1127. archive_entry_pathname(entry));
  1128. r = ARCHIVE_WARN;
  1129. }
  1130. return (r);
  1131. }
  1132. }
  1133. /*
  1134. * If there is a contents file on disk, pick some of the
  1135. * metadata from that file. For most of these, we only
  1136. * set it from the contents if it wasn't already parsed
  1137. * from the specification.
  1138. */
  1139. if (st != NULL) {
  1140. if (((parsed_kws & MTREE_HAS_DEVICE) == 0 ||
  1141. (parsed_kws & MTREE_HAS_NOCHANGE) != 0) &&
  1142. (archive_entry_filetype(entry) == AE_IFCHR ||
  1143. archive_entry_filetype(entry) == AE_IFBLK))
  1144. archive_entry_set_rdev(entry, st->st_rdev);
  1145. if ((parsed_kws & (MTREE_HAS_GID | MTREE_HAS_GNAME))
  1146. == 0 ||
  1147. (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
  1148. archive_entry_set_gid(entry, st->st_gid);
  1149. if ((parsed_kws & (MTREE_HAS_UID | MTREE_HAS_UNAME))
  1150. == 0 ||
  1151. (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
  1152. archive_entry_set_uid(entry, st->st_uid);
  1153. if ((parsed_kws & MTREE_HAS_MTIME) == 0 ||
  1154. (parsed_kws & MTREE_HAS_NOCHANGE) != 0) {
  1155. #if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
  1156. archive_entry_set_mtime(entry, st->st_mtime,
  1157. st->st_mtimespec.tv_nsec);
  1158. #elif HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
  1159. archive_entry_set_mtime(entry, st->st_mtime,
  1160. st->st_mtim.tv_nsec);
  1161. #elif HAVE_STRUCT_STAT_ST_MTIME_N
  1162. archive_entry_set_mtime(entry, st->st_mtime,
  1163. st->st_mtime_n);
  1164. #elif HAVE_STRUCT_STAT_ST_UMTIME
  1165. archive_entry_set_mtime(entry, st->st_mtime,
  1166. st->st_umtime*1000);
  1167. #elif HAVE_STRUCT_STAT_ST_MTIME_USEC
  1168. archive_entry_set_mtime(entry, st->st_mtime,
  1169. st->st_mtime_usec*1000);
  1170. #else
  1171. archive_entry_set_mtime(entry, st->st_mtime, 0);
  1172. #endif
  1173. }
  1174. if ((parsed_kws & MTREE_HAS_NLINK) == 0 ||
  1175. (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
  1176. archive_entry_set_nlink(entry, st->st_nlink);
  1177. if ((parsed_kws & MTREE_HAS_PERM) == 0 ||
  1178. (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
  1179. archive_entry_set_perm(entry, st->st_mode);
  1180. if ((parsed_kws & MTREE_HAS_SIZE) == 0 ||
  1181. (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
  1182. archive_entry_set_size(entry, st->st_size);
  1183. archive_entry_set_ino(entry, st->st_ino);
  1184. archive_entry_set_dev(entry, st->st_dev);
  1185. archive_entry_linkify(mtree->resolver, &entry,
  1186. &sparse_entry);
  1187. } else if (parsed_kws & MTREE_HAS_OPTIONAL) {
  1188. /*
  1189. * Couldn't open the entry, stat it or the on-disk type
  1190. * didn't match. If this entry is optional, just
  1191. * ignore it and read the next header entry.
  1192. */
  1193. *use_next = 1;
  1194. return ARCHIVE_OK;
  1195. }
  1196. }
  1197. mtree->cur_size = archive_entry_size(entry);
  1198. mtree->offset = 0;
  1199. return r;
  1200. }
  1201. /*
  1202. * Each line contains a sequence of keywords.
  1203. */
  1204. static int
  1205. parse_line(struct archive_read *a, struct archive_entry *entry,
  1206. struct mtree *mtree, struct mtree_entry *mp, int *parsed_kws)
  1207. {
  1208. struct mtree_option *iter;
  1209. int r = ARCHIVE_OK, r1;
  1210. for (iter = mp->options; iter != NULL; iter = iter->next) {
  1211. r1 = parse_keyword(a, mtree, entry, iter, parsed_kws);
  1212. if (r1 < r)
  1213. r = r1;
  1214. }
  1215. if (r == ARCHIVE_OK && (*parsed_kws & MTREE_HAS_TYPE) == 0) {
  1216. archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
  1217. "Missing type keyword in mtree specification");
  1218. return (ARCHIVE_WARN);
  1219. }
  1220. return (r);
  1221. }
  1222. /*
  1223. * Device entries have one of the following forms:
  1224. * - raw dev_t
  1225. * - format,major,minor[,subdevice]
  1226. * When parsing succeeded, `pdev' will contain the appropriate dev_t value.
  1227. */
  1228. /* strsep() is not in C90, but strcspn() is. */
  1229. /* Taken from http://unixpapa.com/incnote/string.html */
  1230. static char *
  1231. la_strsep(char **sp, const char *sep)
  1232. {
  1233. char *p, *s;
  1234. if (sp == NULL || *sp == NULL || **sp == '\0')
  1235. return(NULL);
  1236. s = *sp;
  1237. p = s + strcspn(s, sep);
  1238. if (*p != '\0')
  1239. *p++ = '\0';
  1240. *sp = p;
  1241. return(s);
  1242. }
  1243. static int
  1244. parse_device(dev_t *pdev, struct archive *a, char *val)
  1245. {
  1246. #define MAX_PACK_ARGS 3
  1247. unsigned long numbers[MAX_PACK_ARGS];
  1248. char *p, *dev;
  1249. int argc;
  1250. pack_t *pack;
  1251. dev_t result;
  1252. const char *error = NULL;
  1253. memset(pdev, 0, sizeof(*pdev));
  1254. if ((dev = strchr(val, ',')) != NULL) {
  1255. /*
  1256. * Device's major/minor are given in a specified format.
  1257. * Decode and pack it accordingly.
  1258. */
  1259. *dev++ = '\0';
  1260. if ((pack = pack_find(val)) == NULL) {
  1261. archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
  1262. "Unknown format `%s'", val);
  1263. return ARCHIVE_WARN;
  1264. }
  1265. argc = 0;
  1266. while ((p = la_strsep(&dev, ",")) != NULL) {
  1267. if (*p == '\0') {
  1268. archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
  1269. "Missing number");
  1270. return ARCHIVE_WARN;
  1271. }
  1272. if (argc >= MAX_PACK_ARGS) {
  1273. archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
  1274. "Too many arguments");
  1275. return ARCHIVE_WARN;
  1276. }
  1277. numbers[argc++] = (unsigned long)mtree_atol(&p);
  1278. }
  1279. if (argc < 2) {
  1280. archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
  1281. "Not enough arguments");
  1282. return ARCHIVE_WARN;
  1283. }
  1284. result = (*pack)(argc, numbers, &error);
  1285. if (error != NULL) {
  1286. archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
  1287. "%s", error);
  1288. return ARCHIVE_WARN;
  1289. }
  1290. } else {
  1291. /* file system raw value. */
  1292. result = (dev_t)mtree_atol(&val);
  1293. }
  1294. *pdev = result;
  1295. return ARCHIVE_OK;
  1296. #undef MAX_PACK_ARGS
  1297. }
  1298. /*
  1299. * Parse a single keyword and its value.
  1300. */
  1301. static int
  1302. parse_keyword(struct archive_read *a, struct mtree *mtree,
  1303. struct archive_entry *entry, struct mtree_option *opt, int *parsed_kws)
  1304. {
  1305. char *val, *key;
  1306. key = opt->value;
  1307. if (*key == '\0')
  1308. return (ARCHIVE_OK);
  1309. if (strcmp(key, "nochange") == 0) {
  1310. *parsed_kws |= MTREE_HAS_NOCHANGE;
  1311. return (ARCHIVE_OK);
  1312. }
  1313. if (strcmp(key, "optional") == 0) {
  1314. *parsed_kws |= MTREE_HAS_OPTIONAL;
  1315. return (ARCHIVE_OK);
  1316. }
  1317. if (strcmp(key, "ignore") == 0) {
  1318. /*
  1319. * The mtree processing is not recursive, so
  1320. * recursion will only happen for explicitly listed
  1321. * entries.
  1322. */
  1323. return (ARCHIVE_OK);
  1324. }
  1325. val = strchr(key, '=');
  1326. if (val == NULL) {
  1327. archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
  1328. "Malformed attribute \"%s\" (%d)", key, key[0]);
  1329. return (ARCHIVE_WARN);
  1330. }
  1331. *val = '\0';
  1332. ++val;
  1333. switch (key[0]) {
  1334. case 'c':
  1335. if (strcmp(key, "content") == 0
  1336. || strcmp(key, "contents") == 0) {
  1337. parse_escapes(val, NULL);
  1338. archive_strcpy(&mtree->contents_name, val);
  1339. break;
  1340. }
  1341. if (strcmp(key, "cksum") == 0)
  1342. break;
  1343. case 'd':
  1344. if (strcmp(key, "device") == 0) {
  1345. /* stat(2) st_rdev field, e.g. the major/minor IDs
  1346. * of a char/block special file */
  1347. int r;
  1348. dev_t dev;
  1349. *parsed_kws |= MTREE_HAS_DEVICE;
  1350. r = parse_device(&dev, &a->archive, val);
  1351. if (r == ARCHIVE_OK)
  1352. archive_entry_set_rdev(entry, dev);
  1353. return r;
  1354. }
  1355. case 'f':
  1356. if (strcmp(key, "flags") == 0) {
  1357. *parsed_kws |= MTREE_HAS_FFLAGS;
  1358. archive_entry_copy_fflags_text(entry, val);
  1359. break;
  1360. }
  1361. case 'g':
  1362. if (strcmp(key, "gid") == 0) {
  1363. *parsed_kws |= MTREE_HAS_GID;
  1364. archive_entry_set_gid(entry, mtree_atol10(&val));
  1365. break;
  1366. }
  1367. if (strcmp(key, "gname") == 0) {
  1368. *parsed_kws |= MTREE_HAS_GNAME;
  1369. archive_entry_copy_gname(entry, val);
  1370. break;
  1371. }
  1372. case 'i':
  1373. if (strcmp(key, "inode") == 0) {
  1374. archive_entry_set_ino(entry, mtree_atol10(&val));
  1375. break;
  1376. }
  1377. case 'l':
  1378. if (strcmp(key, "link") == 0) {
  1379. archive_entry_copy_symlink(entry, val);
  1380. break;
  1381. }
  1382. case 'm':
  1383. if (strcmp(key, "md5") == 0 || strcmp(key, "md5digest") == 0)
  1384. break;
  1385. if (strcmp(key, "mode") == 0) {
  1386. if (val[0] >= '0' && val[0] <= '9') {
  1387. *parsed_kws |= MTREE_HAS_PERM;
  1388. archive_entry_set_perm(entry,
  1389. (mode_t)mtree_atol8(&val));
  1390. } else {
  1391. archive_set_error(&a->archive,
  1392. ARCHIVE_ERRNO_FILE_FORMAT,
  1393. "Symbolic mode \"%s\" unsupported", val);
  1394. return ARCHIVE_WARN;
  1395. }
  1396. break;
  1397. }
  1398. case 'n':
  1399. if (strcmp(key, "nlink") == 0) {
  1400. *parsed_kws |= MTREE_HAS_NLINK;
  1401. archive_entry_set_nlink(entry,
  1402. (unsigned int)mtree_atol10(&val));
  1403. break;
  1404. }
  1405. case 'r':
  1406. if (strcmp(key, "resdevice") == 0) {
  1407. /* stat(2) st_dev field, e.g. the device ID where the
  1408. * inode resides */
  1409. int r;
  1410. dev_t dev;
  1411. r = parse_device(&dev, &a->archive, val);
  1412. if (r == ARCHIVE_OK)
  1413. archive_entry_set_dev(entry, dev);
  1414. return r;
  1415. }
  1416. if (strcmp(key, "rmd160") == 0 ||
  1417. strcmp(key, "rmd160digest") == 0)
  1418. break;
  1419. case 's':
  1420. if (strcmp(key, "sha1") == 0 || strcmp(key, "sha1digest") == 0)
  1421. break;
  1422. if (strcmp(key, "sha256") == 0 ||
  1423. strcmp(key, "sha256digest") == 0)
  1424. break;
  1425. if (strcmp(key, "sha384") == 0 ||
  1426. strcmp(key, "sha384digest") == 0)
  1427. break;
  1428. if (strcmp(key, "sha512") == 0 ||
  1429. strcmp(key, "sha512digest") == 0)
  1430. break;
  1431. if (strcmp(key, "size") == 0) {
  1432. archive_entry_set_size(entry, mtree_atol10(&val));
  1433. break;
  1434. }
  1435. case 't':
  1436. if (strcmp(key, "tags") == 0) {
  1437. /*
  1438. * Comma delimited list of tags.
  1439. * Ignore the tags for now, but the interface
  1440. * should be extended to allow inclusion/exclusion.
  1441. */
  1442. break;
  1443. }
  1444. if (strcmp(key, "time") == 0) {
  1445. int64_t m;
  1446. int64_t my_time_t_max = get_time_t_max();
  1447. int64_t my_time_t_min = get_time_t_min();
  1448. long ns = 0;
  1449. *parsed_kws |= MTREE_HAS_MTIME;
  1450. m = mtree_atol10(&val);
  1451. /* Replicate an old mtree bug:
  1452. * 123456789.1 represents 123456789
  1453. * seconds and 1 nanosecond. */
  1454. if (*val == '.') {
  1455. ++val;
  1456. ns = (long)mtree_atol10(&val);
  1457. } else
  1458. ns = 0;
  1459. if (m > my_time_t_max)
  1460. m = my_time_t_max;
  1461. else if (m < my_time_t_min)
  1462. m = my_time_t_min;
  1463. archive_entry_set_mtime(entry, (time_t)m, ns);
  1464. break;
  1465. }
  1466. if (strcmp(key, "type") == 0) {
  1467. switch (val[0]) {
  1468. case 'b':
  1469. if (strcmp(val, "block") == 0) {
  1470. archive_entry_set_filetype(entry, AE_IFBLK);
  1471. break;
  1472. }
  1473. case 'c':
  1474. if (strcmp(val, "char") == 0) {
  1475. archive_entry_set_filetype(entry,
  1476. AE_IFCHR);
  1477. break;
  1478. }
  1479. case 'd':
  1480. if (strcmp(val, "dir") == 0) {
  1481. archive_entry_set_filetype(entry,
  1482. AE_IFDIR);
  1483. break;
  1484. }
  1485. case 'f':
  1486. if (strcmp(val, "fifo") == 0) {
  1487. archive_entry_set_filetype(entry,
  1488. AE_IFIFO);
  1489. break;
  1490. }
  1491. if (strcmp(val, "file") == 0) {
  1492. archive_entry_set_filetype(entry,
  1493. AE_IFREG);
  1494. break;
  1495. }
  1496. case 'l':
  1497. if (strcmp(val, "link") == 0) {
  1498. archive_entry_set_filetype(entry,
  1499. AE_IFLNK);
  1500. break;
  1501. }
  1502. default:
  1503. archive_set_error(&a->archive,
  1504. ARCHIVE_ERRNO_FILE_FORMAT,
  1505. "Unrecognized file type \"%s\"; "
  1506. "assuming \"file\"", val);
  1507. archive_entry_set_filetype(entry, AE_IFREG);
  1508. return (ARCHIVE_WARN);
  1509. }
  1510. *parsed_kws |= MTREE_HAS_TYPE;
  1511. break;
  1512. }
  1513. case 'u':
  1514. if (strcmp(key, "uid") == 0) {
  1515. *parsed_kws |= MTREE_HAS_UID;
  1516. archive_entry_set_uid(entry, mtree_atol10(&val));
  1517. break;
  1518. }
  1519. if (strcmp(key, "uname") == 0) {
  1520. *parsed_kws |= MTREE_HAS_UNAME;
  1521. archive_entry_copy_uname(entry, val);
  1522. break;
  1523. }
  1524. default:
  1525. archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
  1526. "Unrecognized key %s=%s", key, val);
  1527. return (ARCHIVE_WARN);
  1528. }
  1529. return (ARCHIVE_OK);
  1530. }
  1531. static int
  1532. read_data(struct archive_read *a, const void **buff, size_t *size,
  1533. int64_t *offset)
  1534. {
  1535. size_t bytes_to_read;
  1536. ssize_t bytes_read;
  1537. struct mtree *mtree;
  1538. mtree = (struct mtree *)(a->format->data);
  1539. if (mtree->fd < 0) {
  1540. *buff = NULL;
  1541. *offset = 0;
  1542. *size = 0;
  1543. return (ARCHIVE_EOF);
  1544. }
  1545. if (mtree->buff == NULL) {
  1546. mtree->buffsize = 64 * 1024;
  1547. mtree->buff = malloc(mtree->buffsize);
  1548. if (mtree->buff == NULL) {
  1549. archive_set_error(&a->archive, ENOMEM,
  1550. "Can't allocate memory");
  1551. return (ARCHIVE_FATAL);
  1552. }
  1553. }
  1554. *buff = mtree->buff;
  1555. *offset = mtree->offset;
  1556. if ((int64_t)mtree->buffsize > mtree->cur_size - mtree->offset)
  1557. bytes_to_read = (size_t)(mtree->cur_size - mtree->offset);
  1558. else
  1559. bytes_to_read = mtree->buffsize;
  1560. bytes_read = read(mtree->fd, mtree->buff, bytes_to_read);
  1561. if (bytes_read < 0) {
  1562. archive_set_error(&a->archive, errno, "Can't read");
  1563. return (ARCHIVE_WARN);
  1564. }
  1565. if (bytes_read == 0) {
  1566. *size = 0;
  1567. return (ARCHIVE_EOF);
  1568. }
  1569. mtree->offset += bytes_read;
  1570. *size = bytes_read;
  1571. return (ARCHIVE_OK);
  1572. }
  1573. /* Skip does nothing except possibly close the contents file. */
  1574. static int
  1575. skip(struct archive_read *a)
  1576. {
  1577. struct mtree *mtree;
  1578. mtree = (struct mtree *)(a->format->data);
  1579. if (mtree->fd >= 0) {
  1580. close(mtree->fd);
  1581. mtree->fd = -1;
  1582. }
  1583. return (ARCHIVE_OK);
  1584. }
  1585. /*
  1586. * Since parsing backslash sequences always makes strings shorter,
  1587. * we can always do this conversion in-place.
  1588. */
  1589. static void
  1590. parse_escapes(char *src, struct mtree_entry *mentry)
  1591. {
  1592. char *dest = src;
  1593. char c;
  1594. if (mentry != NULL && strcmp(src, ".") == 0)
  1595. mentry->full = 1;
  1596. while (*src != '\0') {
  1597. c = *src++;
  1598. if (c == '/' && mentry != NULL)
  1599. mentry->full = 1;
  1600. if (c == '\\') {
  1601. switch (src[0]) {
  1602. case '0':
  1603. if (src[1] < '0' || src[1] > '7') {
  1604. c = 0;
  1605. ++src;
  1606. break;
  1607. }
  1608. /* FALLTHROUGH */
  1609. case '1':
  1610. case '2':
  1611. case '3':
  1612. if (src[1] >= '0' && src[1] <= '7' &&
  1613. src[2] >= '0' && src[2] <= '7') {
  1614. c = (src[0] - '0') << 6;
  1615. c |= (src[1] - '0') << 3;
  1616. c |= (src[2] - '0');
  1617. src += 3;
  1618. }
  1619. break;
  1620. case 'a':
  1621. c = '\a';
  1622. ++src;
  1623. break;
  1624. case 'b':
  1625. c = '\b';
  1626. ++src;
  1627. break;
  1628. case 'f':
  1629. c = '\f';
  1630. ++src;
  1631. break;
  1632. case 'n':
  1633. c = '\n';
  1634. ++src;
  1635. break;
  1636. case 'r':
  1637. c = '\r';
  1638. ++src;
  1639. break;
  1640. case 's':
  1641. c = ' ';
  1642. ++src;
  1643. break;
  1644. case 't':
  1645. c = '\t';
  1646. ++src;
  1647. break;
  1648. case 'v':
  1649. c = '\v';
  1650. ++src;
  1651. break;
  1652. case '\\':
  1653. c = '\\';
  1654. ++src;
  1655. break;
  1656. }
  1657. }
  1658. *dest++ = c;
  1659. }
  1660. *dest = '\0';
  1661. }
  1662. /*
  1663. * Note that this implementation does not (and should not!) obey
  1664. * locale settings; you cannot simply substitute strtol here, since
  1665. * it does obey locale.
  1666. */
  1667. static int64_t
  1668. mtree_atol8(char **p)
  1669. {
  1670. int64_t l, limit, last_digit_limit;
  1671. int digit, base;
  1672. base = 8;
  1673. limit = INT64_MAX / base;
  1674. last_digit_limit = INT64_MAX % base;
  1675. l = 0;
  1676. digit = **p - '0';
  1677. while (digit >= 0 && digit < base) {
  1678. if (l>limit || (l == limit && digit > last_digit_limit)) {
  1679. l = INT64_MAX; /* Truncate on overflow. */
  1680. break;
  1681. }
  1682. l = (l * base) + digit;
  1683. digit = *++(*p) - '0';
  1684. }
  1685. return (l);
  1686. }
  1687. /*
  1688. * Note that this implementation does not (and should not!) obey
  1689. * locale settings; you cannot simply substitute strtol here, since
  1690. * it does obey locale.
  1691. */
  1692. static int64_t
  1693. mtree_atol10(char **p)
  1694. {
  1695. int64_t l, limit, last_digit_limit;
  1696. int base, digit, sign;
  1697. base = 10;
  1698. if (**p == '-') {
  1699. sign = -1;
  1700. limit = ((uint64_t)(INT64_MAX) + 1) / base;
  1701. last_digit_limit = ((uint64_t)(INT64_MAX) + 1) % base;
  1702. ++(*p);
  1703. } else {
  1704. sign = 1;
  1705. limit = INT64_MAX / base;
  1706. last_digit_limit = INT64_MAX % base;
  1707. }
  1708. l = 0;
  1709. digit = **p - '0';
  1710. while (digit >= 0 && digit < base) {
  1711. if (l > limit || (l == limit && digit > last_digit_limit))
  1712. return (sign < 0) ? INT64_MIN : INT64_MAX;
  1713. l = (l * base) + digit;
  1714. digit = *++(*p) - '0';
  1715. }
  1716. return (sign < 0) ? -l : l;
  1717. }
  1718. /* Parse a hex digit. */
  1719. static int
  1720. parsehex(char c)
  1721. {
  1722. if (c >= '0' && c <= '9')
  1723. return c - '0';
  1724. else if (c >= 'a' && c <= 'f')
  1725. return c - 'a';
  1726. else if (c >= 'A' && c <= 'F')
  1727. return c - 'A';
  1728. else
  1729. return -1;
  1730. }
  1731. /*
  1732. * Note that this implementation does not (and should not!) obey
  1733. * locale settings; you cannot simply substitute strtol here, since
  1734. * it does obey locale.
  1735. */
  1736. static int64_t
  1737. mtree_atol16(char **p)
  1738. {
  1739. int64_t l, limit, last_digit_limit;
  1740. int base, digit, sign;
  1741. base = 16;
  1742. if (**p == '-') {
  1743. sign = -1;
  1744. limit = ((uint64_t)(INT64_MAX) + 1) / base;
  1745. last_digit_limit = ((uint64_t)(INT64_MAX) + 1) % base;
  1746. ++(*p);
  1747. } else {
  1748. sign = 1;
  1749. limit = INT64_MAX / base;
  1750. last_digit_limit = INT64_MAX % base;
  1751. }
  1752. l = 0;
  1753. digit = parsehex(**p);
  1754. while (digit >= 0 && digit < base) {
  1755. if (l > limit || (l == limit && digit > last_digit_limit))
  1756. return (sign < 0) ? INT64_MIN : INT64_MAX;
  1757. l = (l * base) + digit;
  1758. digit = parsehex(*++(*p));
  1759. }
  1760. return (sign < 0) ? -l : l;
  1761. }
  1762. static int64_t
  1763. mtree_atol(char **p)
  1764. {
  1765. if (**p != '0')
  1766. return mtree_atol10(p);
  1767. if ((*p)[1] == 'x' || (*p)[1] == 'X') {
  1768. *p += 2;
  1769. return mtree_atol16(p);
  1770. }
  1771. return mtree_atol8(p);
  1772. }
  1773. /*
  1774. * Returns length of line (including trailing newline)
  1775. * or negative on error. 'start' argument is updated to
  1776. * point to first character of line.
  1777. */
  1778. static ssize_t
  1779. readline(struct archive_read *a, struct mtree *mtree, char **start,
  1780. ssize_t limit)
  1781. {
  1782. ssize_t bytes_read;
  1783. ssize_t total_size = 0;
  1784. ssize_t find_off = 0;
  1785. const void *t;
  1786. void *nl;
  1787. char *u;
  1788. /* Accumulate line in a line buffer. */
  1789. for (;;) {
  1790. /* Read some more. */
  1791. t = __archive_read_ahead(a, 1, &bytes_read);
  1792. if (t == NULL)
  1793. return (0);
  1794. if (bytes_read < 0)
  1795. return (ARCHIVE_FATAL);
  1796. nl = memchr(t, '\n', bytes_read);
  1797. /* If we found '\n', trim the read to end exactly there. */
  1798. if (nl != NULL) {
  1799. bytes_read = ((const char *)nl) - ((const char *)t) + 1;
  1800. }
  1801. if (total_size + bytes_read + 1 > limit) {
  1802. archive_set_error(&a->archive,
  1803. ARCHIVE_ERRNO_FILE_FORMAT,
  1804. "Line too long");
  1805. return (ARCHIVE_FATAL);
  1806. }
  1807. if (archive_string_ensure(&mtree->line,
  1808. total_size + bytes_read + 1) == NULL) {
  1809. archive_set_error(&a->archive, ENOMEM,
  1810. "Can't allocate working buffer");
  1811. return (ARCHIVE_FATAL);
  1812. }
  1813. /* Append new bytes to string. */
  1814. memcpy(mtree->line.s + total_size, t, bytes_read);
  1815. __archive_read_consume(a, bytes_read);
  1816. total_size += bytes_read;
  1817. mtree->line.s[total_size] = '\0';
  1818. for (u = mtree->line.s + find_off; *u; ++u) {
  1819. if (u[0] == '\n') {
  1820. /* Ends with unescaped newline. */
  1821. *start = mtree->line.s;
  1822. return total_size;
  1823. } else if (u[0] == '#') {
  1824. /* Ends with comment sequence #...\n */
  1825. if (nl == NULL) {
  1826. /* But we've not found the \n yet */
  1827. break;
  1828. }
  1829. } else if (u[0] == '\\') {
  1830. if (u[1] == '\n') {
  1831. /* Trim escaped newline. */
  1832. total_size -= 2;
  1833. mtree->line.s[total_size] = '\0';
  1834. break;
  1835. } else if (u[1] != '\0') {
  1836. /* Skip the two-char escape sequence */
  1837. ++u;
  1838. }
  1839. }
  1840. }
  1841. find_off = u - mtree->line.s;
  1842. }
  1843. }