archive_read_support_format_mtree.c 49 KB

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