archive_read_support_format_mtree.c 47 KB

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