archive_read_support_format_mtree.c revision 337352
121308Sache/*-
221308Sache * Copyright (c) 2003-2007 Tim Kientzle
321308Sache * Copyright (c) 2008 Joerg Sonnenberger
421308Sache * Copyright (c) 2011-2012 Michihiro NAKAJIMA
521308Sache * All rights reserved.
621308Sache *
7157184Sache * Redistribution and use in source and binary forms, with or without
821308Sache * modification, are permitted provided that the following conditions
921308Sache * are met:
1021308Sache * 1. Redistributions of source code must retain the above copyright
1121308Sache *    notice, this list of conditions and the following disclaimer.
1221308Sache * 2. Redistributions in binary form must reproduce the above copyright
1321308Sache *    notice, this list of conditions and the following disclaimer in the
1421308Sache *    documentation and/or other materials provided with the distribution.
1558310Sache *
1621308Sache * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
1721308Sache * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1821308Sache * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1921308Sache * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
2021308Sache * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2121308Sache * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2221308Sache * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2321308Sache * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2421308Sache * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2521308Sache * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2658310Sache */
2721308Sache
2821308Sache#include "archive_platform.h"
2921308Sache__FBSDID("$FreeBSD: stable/10/contrib/libarchive/libarchive/archive_read_support_format_mtree.c 337352 2018-08-05 14:36:12Z mm $");
3021308Sache
3121308Sache#ifdef HAVE_SYS_STAT_H
3221308Sache#include <sys/stat.h>
3326497Sache#endif
3426497Sache#ifdef HAVE_ERRNO_H
3521308Sache#include <errno.h>
3621308Sache#endif
3721308Sache#ifdef HAVE_FCNTL_H
3821308Sache#include <fcntl.h>
3921308Sache#endif
4021308Sache#include <stddef.h>
4126497Sache/* #include <stdint.h> */ /* See archive_platform.h */
4226497Sache#ifdef HAVE_STDLIB_H
4326497Sache#include <stdlib.h>
4426497Sache#endif
4526497Sache#ifdef HAVE_STRING_H
4621308Sache#include <string.h>
4721308Sache#endif
48119610Sache
49119610Sache#include "archive.h"
5021308Sache#include "archive_entry.h"
5121308Sache#include "archive_private.h"
5221308Sache#include "archive_rb.h"
5358310Sache#include "archive_read_private.h"
5458310Sache#include "archive_string.h"
5558310Sache#include "archive_pack_dev.h"
5647558Sache
57119610Sache#ifndef O_BINARY
5847558Sache#define	O_BINARY 0
59157184Sache#endif
60157184Sache#ifndef O_CLOEXEC
6121308Sache#define O_CLOEXEC	0
6275406Sache#endif
6321308Sache
64119610Sache#define	MTREE_HAS_DEVICE	0x0001
6521308Sache#define	MTREE_HAS_FFLAGS	0x0002
66157184Sache#define	MTREE_HAS_GID		0x0004
67157184Sache#define	MTREE_HAS_GNAME		0x0008
68157184Sache#define	MTREE_HAS_MTIME		0x0010
69157184Sache#define	MTREE_HAS_NLINK		0x0020
7021308Sache#define	MTREE_HAS_PERM		0x0040
71165670Sache#define	MTREE_HAS_SIZE		0x0080
72165670Sache#define	MTREE_HAS_TYPE		0x0100
7321308Sache#define	MTREE_HAS_UID		0x0200
74119610Sache#define	MTREE_HAS_UNAME		0x0400
75119610Sache
76119610Sache#define	MTREE_HAS_OPTIONAL	0x0800
7775406Sache#define	MTREE_HAS_NOCHANGE	0x1000 /* FreeBSD specific */
78119610Sache
79119610Sache#define	MAX_LINE_LEN		(1024 * 1024)
80157184Sache
81157184Sachestruct mtree_option {
82157184Sache	struct mtree_option *next;
83157184Sache	char *value;
84157184Sache};
85157184Sache
86157184Sachestruct mtree_entry {
87157184Sache	struct archive_rb_node rbnode;
88157184Sache	struct mtree_entry *next_dup;
89157184Sache	struct mtree_entry *next;
90157184Sache	struct mtree_option *options;
91157184Sache	char *name;
92157184Sache	char full;
93157184Sache	char used;
94157184Sache};
95157184Sache
96157184Sachestruct mtree {
97157184Sache	struct archive_string	 line;
98157184Sache	size_t			 buffsize;
99157184Sache	char			*buff;
100157184Sache	int64_t			 offset;
101157184Sache	int			 fd;
102157184Sache	int			 archive_format;
103157184Sache	const char		*archive_format_name;
104157184Sache	struct mtree_entry	*entries;
105157184Sache	struct mtree_entry	*this_entry;
106157184Sache	struct archive_rb_tree	 entry_rbtree;
107157184Sache	struct archive_string	 current_dir;
108157184Sache	struct archive_string	 contents_name;
109157184Sache
110157184Sache	struct archive_entry_linkresolver *resolver;
111157184Sache	struct archive_rb_tree rbtree;
112157184Sache
113157184Sache	int64_t			 cur_size;
114157184Sache	char checkfs;
115157184Sache};
116157184Sache
117157184Sachestatic int	bid_keycmp(const char *, const char *, ssize_t);
118157184Sachestatic int	cleanup(struct archive_read *);
119157184Sachestatic int	detect_form(struct archive_read *, int *);
120157184Sachestatic int	mtree_bid(struct archive_read *, int);
121157184Sachestatic int	parse_file(struct archive_read *, struct archive_entry *,
122157184Sache		    struct mtree *, struct mtree_entry *, int *);
123157184Sachestatic void	parse_escapes(char *, struct mtree_entry *);
124157184Sachestatic int	parse_line(struct archive_read *, struct archive_entry *,
125157184Sache		    struct mtree *, struct mtree_entry *, int *);
126157184Sachestatic int	parse_keyword(struct archive_read *, struct mtree *,
127157184Sache		    struct archive_entry *, struct mtree_option *, int *);
128157184Sachestatic int	read_data(struct archive_read *a,
129157184Sache		    const void **buff, size_t *size, int64_t *offset);
130157184Sachestatic ssize_t	readline(struct archive_read *, struct mtree *, char **, ssize_t);
13121308Sachestatic int	skip(struct archive_read *a);
13221308Sachestatic int	read_header(struct archive_read *,
13321308Sache		    struct archive_entry *);
13421308Sachestatic int64_t	mtree_atol(char **, int base);
13521308Sache
13621308Sache/*
13721308Sache * There's no standard for TIME_T_MAX/TIME_T_MIN.  So we compute them
13821308Sache * here.  TODO: Move this to configure time, but be careful
13921308Sache * about cross-compile environments.
14021308Sache */
14121308Sachestatic int64_t
14221308Sacheget_time_t_max(void)
14321308Sache{
14421308Sache#if defined(TIME_T_MAX)
14521308Sache	return TIME_T_MAX;
14621308Sache#else
14721308Sache	/* ISO C allows time_t to be a floating-point type,
14821308Sache	   but POSIX requires an integer type.  The following
14921308Sache	   should work on any system that follows the POSIX
15021308Sache	   conventions. */
151157184Sache	if (((time_t)0) < ((time_t)-1)) {
15221308Sache		/* Time_t is unsigned */
15321308Sache		return (~(time_t)0);
15421308Sache	} else {
15521308Sache		/* Time_t is signed. */
15621308Sache		/* Assume it's the same as int64_t or int32_t */
15721308Sache		if (sizeof(time_t) == sizeof(int64_t)) {
15821308Sache			return (time_t)INT64_MAX;
15921308Sache		} else {
16021308Sache			return (time_t)INT32_MAX;
16121308Sache		}
16221308Sache	}
16321308Sache#endif
164119610Sache}
16521308Sache
16621308Sachestatic int64_t
16721308Sacheget_time_t_min(void)
16821308Sache{
16921308Sache#if defined(TIME_T_MIN)
17021308Sache	return TIME_T_MIN;
17121308Sache#else
17221308Sache	if (((time_t)0) < ((time_t)-1)) {
17321308Sache		/* Time_t is unsigned */
17421308Sache		return (time_t)0;
17521308Sache	} else {
17621308Sache		/* Time_t is signed. */
17721308Sache		if (sizeof(time_t) == sizeof(int64_t)) {
17821308Sache			return (time_t)INT64_MIN;
17921308Sache		} else {
18021308Sache			return (time_t)INT32_MIN;
18121308Sache		}
18221308Sache	}
18321308Sache#endif
18421308Sache}
18521308Sache
18621308Sachestatic int
18721308Sachearchive_read_format_mtree_options(struct archive_read *a,
18821308Sache    const char *key, const char *val)
18921308Sache{
19021308Sache	struct mtree *mtree;
19121308Sache
19221308Sache	mtree = (struct mtree *)(a->format->data);
19321308Sache	if (strcmp(key, "checkfs")  == 0) {
194119610Sache		/* Allows to read information missing from the mtree from the file system */
19521308Sache		if (val == NULL || val[0] == 0) {
19621308Sache			mtree->checkfs = 0;
19721308Sache		} else {
19821308Sache			mtree->checkfs = 1;
199157184Sache		}
200157184Sache		return (ARCHIVE_OK);
201157184Sache	}
20221308Sache
203157184Sache	/* Note: The "warn" return is just to inform the options
204157184Sache	 * supervisor that we didn't handle it.  It will generate
20521308Sache	 * a suitable error if no one used this option. */
20621308Sache	return (ARCHIVE_WARN);
207157184Sache}
208157184Sache
209157184Sachestatic void
21021308Sachefree_options(struct mtree_option *head)
211157184Sache{
21275406Sache	struct mtree_option *next;
21347558Sache
21421308Sache	for (; head != NULL; head = next) {
215157184Sache		next = head->next;
21675406Sache		free(head->value);
21721308Sache		free(head);
21821308Sache	}
21921308Sache}
22021308Sache
22121308Sachestatic int
22221308Sachemtree_cmp_node(const struct archive_rb_node *n1,
223157184Sache    const struct archive_rb_node *n2)
224157184Sache{
225157184Sache	const struct mtree_entry *e1 = (const struct mtree_entry *)n1;
22621308Sache	const struct mtree_entry *e2 = (const struct mtree_entry *)n2;
22775406Sache
228157184Sache	return (strcmp(e1->name, e2->name));
22921308Sache}
23021308Sache
23121308Sachestatic int
232157184Sachemtree_cmp_key(const struct archive_rb_node *n, const void *key)
233157184Sache{
234157184Sache	const struct mtree_entry *e = (const struct mtree_entry *)n;
23521308Sache
23621308Sache	return (strcmp(e->name, key));
237157184Sache}
23821308Sache
23921308Sacheint
240157184Sachearchive_read_support_format_mtree(struct archive *_a)
24121308Sache{
24247558Sache	static const struct archive_rb_tree_ops rb_ops = {
24321308Sache		mtree_cmp_node, mtree_cmp_key,
24421308Sache	};
245157184Sache	struct archive_read *a = (struct archive_read *)_a;
246157184Sache	struct mtree *mtree;
24721308Sache	int r;
24821308Sache
249157184Sache	archive_check_magic(_a, ARCHIVE_READ_MAGIC,
25021308Sache	    ARCHIVE_STATE_NEW, "archive_read_support_format_mtree");
251157184Sache
252157184Sache	mtree = (struct mtree *)calloc(1, sizeof(*mtree));
253157184Sache	if (mtree == NULL) {
25421308Sache		archive_set_error(&a->archive, ENOMEM,
255157184Sache		    "Can't allocate mtree data");
25621308Sache		return (ARCHIVE_FATAL);
257157184Sache	}
258157184Sache	mtree->fd = -1;
259157184Sache
260157184Sache	__archive_rb_tree_init(&mtree->rbtree, &rb_ops);
261157184Sache
262157184Sache	r = __archive_read_register_format(a, mtree, "mtree",
263157184Sache           mtree_bid, archive_read_format_mtree_options, read_header, read_data, skip, NULL, cleanup, NULL, NULL);
264157184Sache
265157184Sache	if (r != ARCHIVE_OK)
266157184Sache		free(mtree);
267157184Sache	return (ARCHIVE_OK);
268157184Sache}
269157184Sache
270157184Sachestatic int
271157184Sachecleanup(struct archive_read *a)
272157184Sache{
273157184Sache	struct mtree *mtree;
274157184Sache	struct mtree_entry *p, *q;
275157184Sache
276157184Sache	mtree = (struct mtree *)(a->format->data);
277157184Sache
278157184Sache	p = mtree->entries;
279157184Sache	while (p != NULL) {
280157184Sache		q = p->next;
281157184Sache		free(p->name);
282157184Sache		free_options(p->options);
283157184Sache		free(p);
28421308Sache		p = q;
285157184Sache	}
286157184Sache	archive_string_free(&mtree->line);
287157184Sache	archive_string_free(&mtree->current_dir);
288157184Sache	archive_string_free(&mtree->contents_name);
289157184Sache	archive_entry_linkresolver_free(mtree->resolver);
290157184Sache
29121308Sache	free(mtree->buff);
292157184Sache	free(mtree);
293157184Sache	(a->format->data) = NULL;
294157184Sache	return (ARCHIVE_OK);
29521308Sache}
296157184Sache
297157184Sachestatic ssize_t
298157184Sacheget_line_size(const char *b, ssize_t avail, ssize_t *nlsize)
299157184Sache{
300157184Sache	ssize_t len;
301157184Sache
302157184Sache	len = 0;
303157184Sache	while (len < avail) {
304157184Sache		switch (*b) {
305157184Sache		case '\0':/* Non-ascii character or control character. */
306157184Sache			if (nlsize != NULL)
307157184Sache				*nlsize = 0;
308157184Sache			return (-1);
309157184Sache		case '\r':
310119610Sache			if (avail-len > 1 && b[1] == '\n') {
311157184Sache				if (nlsize != NULL)
312157184Sache					*nlsize = 2;
313119610Sache				return (len+2);
314119610Sache			}
315157184Sache			/* FALL THROUGH */
316157184Sache		case '\n':
31721308Sache			if (nlsize != NULL)
318157184Sache				*nlsize = 1;
319157184Sache			return (len+1);
320157184Sache		default:
321157184Sache			b++;
322157184Sache			len++;
323157184Sache			break;
324157184Sache		}
325157184Sache	}
326157184Sache	if (nlsize != NULL)
327157184Sache		*nlsize = 0;
32821308Sache	return (avail);
329157184Sache}
330173403Sache
331173403Sache/*
332173403Sache *  <---------------- ravail --------------------->
333173403Sache *  <-- diff ------> <---  avail ----------------->
334173403Sache *                   <---- len ----------->
335173403Sache * | Previous lines | line being parsed  nl extra |
336173403Sache *                  ^
337173403Sache *                  b
338173403Sache *
339157184Sache */
340157184Sachestatic ssize_t
341157184Sachenext_line(struct archive_read *a,
34221308Sache    const char **b, ssize_t *avail, ssize_t *ravail, ssize_t *nl)
343157184Sache{
344157184Sache	ssize_t len;
345157184Sache	int quit;
346157184Sache
347157184Sache	quit = 0;
348157184Sache	if (*avail == 0) {
349157184Sache		*nl = 0;
350157184Sache		len = 0;
351157184Sache	} else
352157184Sache		len = get_line_size(*b, *avail, nl);
353157184Sache	/*
354157184Sache	 * Read bytes more while it does not reach the end of line.
355157184Sache	 */
356157184Sache	while (*nl == 0 && len == *avail && !quit) {
357157184Sache		ssize_t diff = *ravail - *avail;
358157184Sache		size_t nbytes_req = (*ravail+1023) & ~1023U;
359157184Sache		ssize_t tested;
360157184Sache
361157184Sache		/*
362157184Sache		 * Place an arbitrary limit on the line length.
363157184Sache		 * mtree is almost free-form input and without line length limits,
364157184Sache		 * it can consume a lot of memory.
365157184Sache		 */
366157184Sache		if (len >= MAX_LINE_LEN)
367157184Sache			return (-1);
368157184Sache
369157184Sache		/* Increase reading bytes if it is not enough to at least
370157184Sache		 * new two lines. */
371157184Sache		if (nbytes_req < (size_t)*ravail + 160)
372157184Sache			nbytes_req <<= 1;
373157184Sache
374157184Sache		*b = __archive_read_ahead(a, nbytes_req, avail);
375157184Sache		if (*b == NULL) {
376157184Sache			if (*ravail >= *avail)
377119610Sache				return (0);
378119610Sache			/* Reading bytes reaches the end of file. */
379119610Sache			*b = __archive_read_ahead(a, *avail, avail);
380119610Sache			quit = 1;
381157184Sache		}
382157184Sache		*ravail = *avail;
383157184Sache		*b += diff;
38421308Sache		*avail -= diff;
38575406Sache		tested = len;/* Skip some bytes we already determinated. */
38675406Sache		len = get_line_size(*b + len, *avail - len, nl);
387157184Sache		if (len >= 0)
388157184Sache			len += tested;
38921308Sache	}
390157184Sache	return (len);
391157184Sache}
392157184Sache
393157184Sache/*
394157184Sache * Compare characters with a mtree keyword.
395157184Sache * Returns the length of a mtree keyword if matched.
396157184Sache * Returns 0 if not matched.
397157184Sache */
398157184Sachestatic int
399157184Sachebid_keycmp(const char *p, const char *key, ssize_t len)
40021308Sache{
401157184Sache	int match_len = 0;
402157184Sache
403157184Sache	while (len > 0 && *p && *key) {
404157184Sache		if (*p == *key) {
405157184Sache			--len;
406157184Sache			++p;
407157184Sache			++key;
40821308Sache			++match_len;
409157184Sache			continue;
410119610Sache		}
411157184Sache		return (0);/* Not match */
412157184Sache	}
413157184Sache	if (*key != '\0')
414157184Sache		return (0);/* Not match */
415157184Sache
416157184Sache	/* A following character should be specified characters */
417119610Sache	if (p[0] == '=' || p[0] == ' ' || p[0] == '\t' ||
418157184Sache	    p[0] == '\n' || p[0] == '\r' ||
419157184Sache	   (p[0] == '\\' && (p[1] == '\n' || p[1] == '\r')))
420157184Sache		return (match_len);
421157184Sache	return (0);/* Not match */
422157184Sache}
423157184Sache
424157184Sache/*
425157184Sache * Test whether the characters 'p' has is mtree keyword.
426157184Sache * Returns the length of a detected keyword.
42721308Sache * Returns 0 if any keywords were not found.
428157184Sache */
429157184Sachestatic int
430157184Sachebid_keyword(const char *p,  ssize_t len)
431157184Sache{
432157184Sache	static const char * const keys_c[] = {
433157184Sache		"content", "contents", "cksum", NULL
434157184Sache	};
435157184Sache	static const char * const keys_df[] = {
43621308Sache		"device", "flags", NULL
437157184Sache	};
438157184Sache	static const char * const keys_g[] = {
439157184Sache		"gid", "gname", NULL
440157184Sache	};
441157184Sache	static const char * const keys_il[] = {
442157184Sache		"ignore", "inode", "link", NULL
443157184Sache	};
444157184Sache	static const char * const keys_m[] = {
445157184Sache		"md5", "md5digest", "mode", NULL
446157184Sache	};
447157184Sache	static const char * const keys_no[] = {
448119610Sache		"nlink", "nochange", "optional", NULL
449157184Sache	};
450157184Sache	static const char * const keys_r[] = {
451157184Sache		"resdevice", "rmd160", "rmd160digest", NULL
452157184Sache	};
453157184Sache	static const char * const keys_s[] = {
454157184Sache		"sha1", "sha1digest",
455119610Sache		"sha256", "sha256digest",
456157184Sache		"sha384", "sha384digest",
45721308Sache		"sha512", "sha512digest",
458157184Sache		"size", NULL
459157184Sache	};
460157184Sache	static const char * const keys_t[] = {
461157184Sache		"tags", "time", "type", NULL
462157184Sache	};
463157184Sache	static const char * const keys_u[] = {
464157184Sache		"uid", "uname",	NULL
465157184Sache	};
466119610Sache	const char * const *keys;
467157184Sache	int i;
468157184Sache
469157184Sache	switch (*p) {
470157184Sache	case 'c': keys = keys_c; break;
471157184Sache	case 'd': case 'f': keys = keys_df; break;
47235486Sache	case 'g': keys = keys_g; break;
473157184Sache	case 'i': case 'l': keys = keys_il; break;
474157184Sache	case 'm': keys = keys_m; break;
475157184Sache	case 'n': case 'o': keys = keys_no; break;
476157184Sache	case 'r': keys = keys_r; break;
477157184Sache	case 's': keys = keys_s; break;
478157184Sache	case 't': keys = keys_t; break;
479157184Sache	case 'u': keys = keys_u; break;
480157184Sache	default: return (0);/* Unknown key */
481157184Sache	}
482157184Sache
483157184Sache	for (i = 0; keys[i] != NULL; i++) {
484157184Sache		int l = bid_keycmp(p, keys[i], len);
485157184Sache		if (l > 0)
486157184Sache			return (l);
487157184Sache	}
488157184Sache	return (0);/* Unknown key */
489157184Sache}
490157184Sache
491157184Sache/*
49235486Sache * Test whether there is a set of mtree keywords.
493157184Sache * Returns the number of keyword.
494157184Sache * Returns -1 if we got incorrect sequence.
495157184Sache * This function expects a set of "<space characters>keyword=value".
496157184Sache * When "unset" is specified, expects a set of "<space characters>keyword".
497157184Sache */
498157184Sachestatic int
499119610Sachebid_keyword_list(const char *p,  ssize_t len, int unset, int last_is_path)
500157184Sache{
501157184Sache	int l;
502157184Sache	int keycnt = 0;
503157184Sache
504157184Sache	while (len > 0 && *p) {
505157184Sache		int blank = 0;
506157184Sache
507157184Sache		/* Test whether there are blank characters in the line. */
508157184Sache		while (len >0 && (*p == ' ' || *p == '\t')) {
509157184Sache			++p;
510157184Sache			--len;
511119610Sache			blank = 1;
512157184Sache		}
513157184Sache		if (*p == '\n' || *p == '\r')
514157184Sache			break;
515157184Sache		if (p[0] == '\\' && (p[1] == '\n' || p[1] == '\r'))
516157184Sache			break;
517157184Sache		if (!blank && !last_is_path) /* No blank character. */
518157184Sache			return (-1);
519119610Sache		if (last_is_path && len == 0)
520157184Sache				return (keycnt);
521157184Sache
522157184Sache		if (unset) {
523157184Sache			l = bid_keycmp(p, "all", len);
524157184Sache			if (l > 0)
525157184Sache				return (1);
526157184Sache		}
527157184Sache		/* Test whether there is a correct key in the line. */
528157184Sache		l = bid_keyword(p, len);
529157184Sache		if (l == 0)
530157184Sache			return (-1);/* Unknown keyword was found. */
531157184Sache		p += l;
532157184Sache		len -= l;
533157184Sache		keycnt++;
534157184Sache
535157184Sache		/* Skip value */
536157184Sache		if (*p == '=') {
537157184Sache			int value = 0;
538157184Sache			++p;
539157184Sache			--len;
540157184Sache			while (len > 0 && *p != ' ' && *p != '\t') {
541119610Sache				++p;
542157184Sache				--len;
543157184Sache				value = 1;
544119610Sache			}
545119610Sache			/* A keyword should have a its value unless
546157184Sache			 * "/unset" operation. */
54721308Sache			if (!unset && value == 0)
548157184Sache				return (-1);
549157184Sache		}
55021308Sache	}
551157184Sache	return (keycnt);
552157184Sache}
553157184Sache
554157184Sachestatic int
55521308Sachebid_entry(const char *p, ssize_t len, ssize_t nl, int *last_is_path)
556157184Sache{
557157184Sache	int f = 0;
55821308Sache	static const unsigned char safe_char[256] = {
559157184Sache		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 0F */
560157184Sache		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1F */
56121308Sache		/* !"$%&'()*+,-./  EXCLUSION:( )(#) */
562157184Sache		0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 - 2F */
563157184Sache		/* 0123456789:;<>?  EXCLUSION:(=) */
56421308Sache		1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, /* 30 - 3F */
56521308Sache		/* @ABCDEFGHIJKLMNO */
566157184Sache		1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */
567157184Sache		/* PQRSTUVWXYZ[\]^_  */
568157184Sache		1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 50 - 5F */
569157184Sache		/* `abcdefghijklmno */
570157184Sache		1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 - 6F */
571157184Sache		/* pqrstuvwxyz{|}~ */
57221308Sache		1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* 70 - 7F */
573157184Sache		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */
574157184Sache		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */
57521308Sache		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */
576157184Sache		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */
577157184Sache		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */
578157184Sache		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */
57921308Sache		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */
580157184Sache		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F0 - FF */
581157184Sache	};
582157184Sache	ssize_t ll;
583157184Sache	const char *pp = p;
584157184Sache	const char * const pp_end = pp + len;
585157184Sache
586157184Sache	*last_is_path = 0;
58721308Sache	/*
588157184Sache	 * Skip the path-name which is quoted.
589157184Sache	 */
590157184Sache	for (;pp < pp_end; ++pp) {
591157184Sache		if (!safe_char[*(const unsigned char *)pp]) {
592157184Sache			if (*pp != ' ' && *pp != '\t' && *pp != '\r'
593157184Sache			    && *pp != '\n')
594157184Sache				f = 0;
595157184Sache			break;
596157184Sache		}
597157184Sache		f = 1;
598157184Sache	}
59921308Sache	ll = pp_end - pp;
600157184Sache
601157184Sache	/* If a path-name was not found at the first, try to check
60221308Sache	 * a mtree format(a.k.a form D) ``NetBSD's mtree -D'' creates,
603157184Sache	 * which places the path-name at the last. */
604157184Sache	if (f == 0) {
605157184Sache		const char *pb = p + len - nl;
606157184Sache		int name_len = 0;
607157184Sache		int slash;
608157184Sache
609157184Sache		/* The form D accepts only a single line for an entry. */
610157184Sache		if (pb-2 >= p &&
611157184Sache		    pb[-1] == '\\' && (pb[-2] == ' ' || pb[-2] == '\t'))
61221308Sache			return (-1);
613157184Sache		if (pb-1 >= p && pb[-1] == '\\')
61421308Sache			return (-1);
615157184Sache
616157184Sache		slash = 0;
61721308Sache		while (p <= --pb && *pb != ' ' && *pb != '\t') {
618157184Sache			if (!safe_char[*(const unsigned char *)pb])
619157184Sache				return (-1);
620157184Sache			name_len++;
621157184Sache			/* The pathname should have a slash in this
622157184Sache			 * format. */
623157184Sache			if (*pb == '/')
624157184Sache				slash = 1;
625157184Sache		}
626157184Sache		if (name_len == 0 || slash == 0)
627157184Sache			return (-1);
62821308Sache		/* If '/' is placed at the first in this field, this is not
629157184Sache		 * a valid filename. */
630157184Sache		if (pb[1] == '/')
63121308Sache			return (-1);
632157184Sache		ll = len - nl - name_len;
63321308Sache		pp = p;
634157184Sache		*last_is_path = 1;
635157184Sache	}
636157184Sache
637157184Sache	return (bid_keyword_list(pp, ll, 0, *last_is_path));
638157184Sache}
639157184Sache
640157184Sache#define MAX_BID_ENTRY	3
641119610Sache
642157184Sachestatic int
643157184Sachemtree_bid(struct archive_read *a, int best_bid)
644157184Sache{
645157184Sache	const char *signature = "#mtree";
646157184Sache	const char *p;
647119610Sache
648119610Sache	(void)best_bid; /* UNUSED */
649157184Sache
650157184Sache	/* Now let's look at the actual header and see if it matches. */
651157184Sache	p = __archive_read_ahead(a, strlen(signature), NULL);
652157184Sache	if (p == NULL)
653157184Sache		return (-1);
654157184Sache
655119610Sache	if (memcmp(p, signature, strlen(signature)) == 0)
656157184Sache		return (8 * (int)strlen(signature));
657157184Sache
658157184Sache	/*
659157184Sache	 * There is not a mtree signature. Let's try to detect mtree format.
660157184Sache	 */
661157184Sache	return (detect_form(a, NULL));
662157184Sache}
663157184Sache
664157184Sachestatic int
665157184Sachedetect_form(struct archive_read *a, int *is_form_d)
66621308Sache{
667157184Sache	const char *p;
668157184Sache	ssize_t avail, ravail;
669157184Sache	ssize_t detected_bytes = 0, len, nl;
67021308Sache	int entry_cnt = 0, multiline = 0;
671157184Sache	int form_D = 0;/* The archive is generated by `NetBSD mtree -D'
67221308Sache			* (In this source we call it `form D') . */
673157184Sache
674	if (is_form_d != NULL)
675		*is_form_d = 0;
676	p = __archive_read_ahead(a, 1, &avail);
677	if (p == NULL)
678		return (-1);
679	ravail = avail;
680	for (;;) {
681		len = next_line(a, &p, &avail, &ravail, &nl);
682		/* The terminal character of the line should be
683		 * a new line character, '\r\n' or '\n'. */
684		if (len <= 0 || nl == 0)
685			break;
686		if (!multiline) {
687			/* Leading whitespace is never significant,
688			 * ignore it. */
689			while (len > 0 && (*p == ' ' || *p == '\t')) {
690				++p;
691				--avail;
692				--len;
693			}
694			/* Skip comment or empty line. */
695			if (p[0] == '#' || p[0] == '\n' || p[0] == '\r') {
696				p += len;
697				avail -= len;
698				continue;
699			}
700		} else {
701			/* A continuance line; the terminal
702			 * character of previous line was '\' character. */
703			if (bid_keyword_list(p, len, 0, 0) <= 0)
704				break;
705			if (multiline == 1)
706				detected_bytes += len;
707			if (p[len-nl-1] != '\\') {
708				if (multiline == 1 &&
709				    ++entry_cnt >= MAX_BID_ENTRY)
710					break;
711				multiline = 0;
712			}
713			p += len;
714			avail -= len;
715			continue;
716		}
717		if (p[0] != '/') {
718			int last_is_path, keywords;
719
720			keywords = bid_entry(p, len, nl, &last_is_path);
721			if (keywords >= 0) {
722				detected_bytes += len;
723				if (form_D == 0) {
724					if (last_is_path)
725						form_D = 1;
726					else if (keywords > 0)
727						/* This line is not `form D'. */
728						form_D = -1;
729				} else if (form_D == 1) {
730					if (!last_is_path && keywords > 0)
731						/* This this is not `form D'
732						 * and We cannot accept mixed
733						 * format. */
734						break;
735				}
736				if (!last_is_path && p[len-nl-1] == '\\')
737					/* This line continues. */
738					multiline = 1;
739				else {
740					/* We've got plenty of correct lines
741					 * to assume that this file is a mtree
742					 * format. */
743					if (++entry_cnt >= MAX_BID_ENTRY)
744						break;
745				}
746			} else
747				break;
748		} else if (len > 4 && strncmp(p, "/set", 4) == 0) {
749			if (bid_keyword_list(p+4, len-4, 0, 0) <= 0)
750				break;
751			/* This line continues. */
752			if (p[len-nl-1] == '\\')
753				multiline = 2;
754		} else if (len > 6 && strncmp(p, "/unset", 6) == 0) {
755			if (bid_keyword_list(p+6, len-6, 1, 0) <= 0)
756				break;
757			/* This line continues. */
758			if (p[len-nl-1] == '\\')
759				multiline = 2;
760		} else
761			break;
762
763		/* Test next line. */
764		p += len;
765		avail -= len;
766	}
767	if (entry_cnt >= MAX_BID_ENTRY || (entry_cnt > 0 && len == 0)) {
768		if (is_form_d != NULL) {
769			if (form_D == 1)
770				*is_form_d = 1;
771		}
772		return (32);
773	}
774
775	return (0);
776}
777
778/*
779 * The extended mtree format permits multiple lines specifying
780 * attributes for each file.  For those entries, only the last line
781 * is actually used.  Practically speaking, that means we have
782 * to read the entire mtree file into memory up front.
783 *
784 * The parsing is done in two steps.  First, it is decided if a line
785 * changes the global defaults and if it is, processed accordingly.
786 * Otherwise, the options of the line are merged with the current
787 * global options.
788 */
789static int
790add_option(struct archive_read *a, struct mtree_option **global,
791    const char *value, size_t len)
792{
793	struct mtree_option *opt;
794
795	if ((opt = malloc(sizeof(*opt))) == NULL) {
796		archive_set_error(&a->archive, errno, "Can't allocate memory");
797		return (ARCHIVE_FATAL);
798	}
799	if ((opt->value = malloc(len + 1)) == NULL) {
800		free(opt);
801		archive_set_error(&a->archive, errno, "Can't allocate memory");
802		return (ARCHIVE_FATAL);
803	}
804	memcpy(opt->value, value, len);
805	opt->value[len] = '\0';
806	opt->next = *global;
807	*global = opt;
808	return (ARCHIVE_OK);
809}
810
811static void
812remove_option(struct mtree_option **global, const char *value, size_t len)
813{
814	struct mtree_option *iter, *last;
815
816	last = NULL;
817	for (iter = *global; iter != NULL; last = iter, iter = iter->next) {
818		if (strncmp(iter->value, value, len) == 0 &&
819		    (iter->value[len] == '\0' ||
820		     iter->value[len] == '='))
821			break;
822	}
823	if (iter == NULL)
824		return;
825	if (last == NULL)
826		*global = iter->next;
827	else
828		last->next = iter->next;
829
830	free(iter->value);
831	free(iter);
832}
833
834static int
835process_global_set(struct archive_read *a,
836    struct mtree_option **global, const char *line)
837{
838	const char *next, *eq;
839	size_t len;
840	int r;
841
842	line += 4;
843	for (;;) {
844		next = line + strspn(line, " \t\r\n");
845		if (*next == '\0')
846			return (ARCHIVE_OK);
847		line = next;
848		next = line + strcspn(line, " \t\r\n");
849		eq = strchr(line, '=');
850		if (eq > next)
851			len = next - line;
852		else
853			len = eq - line;
854
855		remove_option(global, line, len);
856		r = add_option(a, global, line, next - line);
857		if (r != ARCHIVE_OK)
858			return (r);
859		line = next;
860	}
861}
862
863static int
864process_global_unset(struct archive_read *a,
865    struct mtree_option **global, const char *line)
866{
867	const char *next;
868	size_t len;
869
870	line += 6;
871	if (strchr(line, '=') != NULL) {
872		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
873		    "/unset shall not contain `='");
874		return ARCHIVE_FATAL;
875	}
876
877	for (;;) {
878		next = line + strspn(line, " \t\r\n");
879		if (*next == '\0')
880			return (ARCHIVE_OK);
881		line = next;
882		len = strcspn(line, " \t\r\n");
883
884		if (len == 3 && strncmp(line, "all", 3) == 0) {
885			free_options(*global);
886			*global = NULL;
887		} else {
888			remove_option(global, line, len);
889		}
890
891		line += len;
892	}
893}
894
895static int
896process_add_entry(struct archive_read *a, struct mtree *mtree,
897    struct mtree_option **global, const char *line, ssize_t line_len,
898    struct mtree_entry **last_entry, int is_form_d)
899{
900	struct mtree_entry *entry;
901	struct mtree_option *iter;
902	const char *next, *eq, *name, *end;
903	size_t name_len, len;
904	int r, i;
905
906	if ((entry = malloc(sizeof(*entry))) == NULL) {
907		archive_set_error(&a->archive, errno, "Can't allocate memory");
908		return (ARCHIVE_FATAL);
909	}
910	entry->next = NULL;
911	entry->options = NULL;
912	entry->name = NULL;
913	entry->used = 0;
914	entry->full = 0;
915
916	/* Add this entry to list. */
917	if (*last_entry == NULL)
918		mtree->entries = entry;
919	else
920		(*last_entry)->next = entry;
921	*last_entry = entry;
922
923	if (is_form_d) {
924		/* Filename is last item on line. */
925		/* Adjust line_len to trim trailing whitespace */
926		while (line_len > 0) {
927			char last_character = line[line_len - 1];
928			if (last_character == '\r'
929			    || last_character == '\n'
930			    || last_character == '\t'
931			    || last_character == ' ') {
932				line_len--;
933			} else {
934				break;
935			}
936		}
937		/* Name starts after the last whitespace separator */
938		name = line;
939		for (i = 0; i < line_len; i++) {
940			if (line[i] == '\r'
941			    || line[i] == '\n'
942			    || line[i] == '\t'
943			    || line[i] == ' ') {
944				name = line + i + 1;
945			}
946		}
947		name_len = line + line_len - name;
948		end = name;
949	} else {
950		/* Filename is first item on line */
951		name_len = strcspn(line, " \t\r\n");
952		name = line;
953		line += name_len;
954		end = line + line_len;
955	}
956	/* name/name_len is the name within the line. */
957	/* line..end brackets the entire line except the name */
958
959	if ((entry->name = malloc(name_len + 1)) == NULL) {
960		archive_set_error(&a->archive, errno, "Can't allocate memory");
961		return (ARCHIVE_FATAL);
962	}
963
964	memcpy(entry->name, name, name_len);
965	entry->name[name_len] = '\0';
966	parse_escapes(entry->name, entry);
967
968	entry->next_dup = NULL;
969	if (entry->full) {
970		if (!__archive_rb_tree_insert_node(&mtree->rbtree, &entry->rbnode)) {
971			struct mtree_entry *alt;
972			alt = (struct mtree_entry *)__archive_rb_tree_find_node(
973			    &mtree->rbtree, entry->name);
974			while (alt->next_dup)
975				alt = alt->next_dup;
976			alt->next_dup = entry;
977		}
978	}
979
980	for (iter = *global; iter != NULL; iter = iter->next) {
981		r = add_option(a, &entry->options, iter->value,
982		    strlen(iter->value));
983		if (r != ARCHIVE_OK)
984			return (r);
985	}
986
987	for (;;) {
988		next = line + strspn(line, " \t\r\n");
989		if (*next == '\0')
990			return (ARCHIVE_OK);
991		if (next >= end)
992			return (ARCHIVE_OK);
993		line = next;
994		next = line + strcspn(line, " \t\r\n");
995		eq = strchr(line, '=');
996		if (eq == NULL || eq > next)
997			len = next - line;
998		else
999			len = eq - line;
1000
1001		remove_option(&entry->options, line, len);
1002		r = add_option(a, &entry->options, line, next - line);
1003		if (r != ARCHIVE_OK)
1004			return (r);
1005		line = next;
1006	}
1007}
1008
1009static int
1010read_mtree(struct archive_read *a, struct mtree *mtree)
1011{
1012	ssize_t len;
1013	uintmax_t counter;
1014	char *p;
1015	struct mtree_option *global;
1016	struct mtree_entry *last_entry;
1017	int r, is_form_d;
1018
1019	mtree->archive_format = ARCHIVE_FORMAT_MTREE;
1020	mtree->archive_format_name = "mtree";
1021
1022	global = NULL;
1023	last_entry = NULL;
1024
1025	(void)detect_form(a, &is_form_d);
1026
1027	for (counter = 1; ; ++counter) {
1028		len = readline(a, mtree, &p, 65536);
1029		if (len == 0) {
1030			mtree->this_entry = mtree->entries;
1031			free_options(global);
1032			return (ARCHIVE_OK);
1033		}
1034		if (len < 0) {
1035			free_options(global);
1036			return ((int)len);
1037		}
1038		/* Leading whitespace is never significant, ignore it. */
1039		while (*p == ' ' || *p == '\t') {
1040			++p;
1041			--len;
1042		}
1043		/* Skip content lines and blank lines. */
1044		if (*p == '#')
1045			continue;
1046		if (*p == '\r' || *p == '\n' || *p == '\0')
1047			continue;
1048		if (*p != '/') {
1049			r = process_add_entry(a, mtree, &global, p, len,
1050			    &last_entry, is_form_d);
1051		} else if (len > 4 && strncmp(p, "/set", 4) == 0) {
1052			if (p[4] != ' ' && p[4] != '\t')
1053				break;
1054			r = process_global_set(a, &global, p);
1055		} else if (len > 6 && strncmp(p, "/unset", 6) == 0) {
1056			if (p[6] != ' ' && p[6] != '\t')
1057				break;
1058			r = process_global_unset(a, &global, p);
1059		} else
1060			break;
1061
1062		if (r != ARCHIVE_OK) {
1063			free_options(global);
1064			return r;
1065		}
1066	}
1067
1068	archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1069	    "Can't parse line %ju", counter);
1070	free_options(global);
1071	return (ARCHIVE_FATAL);
1072}
1073
1074/*
1075 * Read in the entire mtree file into memory on the first request.
1076 * Then use the next unused file to satisfy each header request.
1077 */
1078static int
1079read_header(struct archive_read *a, struct archive_entry *entry)
1080{
1081	struct mtree *mtree;
1082	char *p;
1083	int r, use_next;
1084
1085	mtree = (struct mtree *)(a->format->data);
1086
1087	if (mtree->fd >= 0) {
1088		close(mtree->fd);
1089		mtree->fd = -1;
1090	}
1091
1092	if (mtree->entries == NULL) {
1093		mtree->resolver = archive_entry_linkresolver_new();
1094		if (mtree->resolver == NULL)
1095			return ARCHIVE_FATAL;
1096		archive_entry_linkresolver_set_strategy(mtree->resolver,
1097		    ARCHIVE_FORMAT_MTREE);
1098		r = read_mtree(a, mtree);
1099		if (r != ARCHIVE_OK)
1100			return (r);
1101	}
1102
1103	a->archive.archive_format = mtree->archive_format;
1104	a->archive.archive_format_name = mtree->archive_format_name;
1105
1106	for (;;) {
1107		if (mtree->this_entry == NULL)
1108			return (ARCHIVE_EOF);
1109		if (strcmp(mtree->this_entry->name, "..") == 0) {
1110			mtree->this_entry->used = 1;
1111			if (archive_strlen(&mtree->current_dir) > 0) {
1112				/* Roll back current path. */
1113				p = mtree->current_dir.s
1114				    + mtree->current_dir.length - 1;
1115				while (p >= mtree->current_dir.s && *p != '/')
1116					--p;
1117				if (p >= mtree->current_dir.s)
1118					--p;
1119				mtree->current_dir.length
1120				    = p - mtree->current_dir.s + 1;
1121			}
1122		}
1123		if (!mtree->this_entry->used) {
1124			use_next = 0;
1125			r = parse_file(a, entry, mtree, mtree->this_entry,
1126				&use_next);
1127			if (use_next == 0)
1128				return (r);
1129		}
1130		mtree->this_entry = mtree->this_entry->next;
1131	}
1132}
1133
1134/*
1135 * A single file can have multiple lines contribute specifications.
1136 * Parse as many lines as necessary, then pull additional information
1137 * from a backing file on disk as necessary.
1138 */
1139static int
1140parse_file(struct archive_read *a, struct archive_entry *entry,
1141    struct mtree *mtree, struct mtree_entry *mentry, int *use_next)
1142{
1143	const char *path;
1144	struct stat st_storage, *st;
1145	struct mtree_entry *mp;
1146	struct archive_entry *sparse_entry;
1147	int r = ARCHIVE_OK, r1, parsed_kws;
1148
1149	mentry->used = 1;
1150
1151	/* Initialize reasonable defaults. */
1152	archive_entry_set_filetype(entry, AE_IFREG);
1153	archive_entry_set_size(entry, 0);
1154	archive_string_empty(&mtree->contents_name);
1155
1156	/* Parse options from this line. */
1157	parsed_kws = 0;
1158	r = parse_line(a, entry, mtree, mentry, &parsed_kws);
1159
1160	if (mentry->full) {
1161		archive_entry_copy_pathname(entry, mentry->name);
1162		/*
1163		 * "Full" entries are allowed to have multiple lines
1164		 * and those lines aren't required to be adjacent.  We
1165		 * don't support multiple lines for "relative" entries
1166		 * nor do we make any attempt to merge data from
1167		 * separate "relative" and "full" entries.  (Merging
1168		 * "relative" and "full" entries would require dealing
1169		 * with pathname canonicalization, which is a very
1170		 * tricky subject.)
1171		 */
1172		mp = (struct mtree_entry *)__archive_rb_tree_find_node(
1173		    &mtree->rbtree, mentry->name);
1174		for (; mp; mp = mp->next_dup) {
1175			if (mp->full && !mp->used) {
1176				/* Later lines override earlier ones. */
1177				mp->used = 1;
1178				r1 = parse_line(a, entry, mtree, mp, &parsed_kws);
1179				if (r1 < r)
1180					r = r1;
1181			}
1182		}
1183	} else {
1184		/*
1185		 * Relative entries require us to construct
1186		 * the full path and possibly update the
1187		 * current directory.
1188		 */
1189		size_t n = archive_strlen(&mtree->current_dir);
1190		if (n > 0)
1191			archive_strcat(&mtree->current_dir, "/");
1192		archive_strcat(&mtree->current_dir, mentry->name);
1193		archive_entry_copy_pathname(entry, mtree->current_dir.s);
1194		if (archive_entry_filetype(entry) != AE_IFDIR)
1195			mtree->current_dir.length = n;
1196	}
1197
1198	if (mtree->checkfs) {
1199		/*
1200		 * Try to open and stat the file to get the real size
1201		 * and other file info.  It would be nice to avoid
1202		 * this here so that getting a listing of an mtree
1203		 * wouldn't require opening every referenced contents
1204		 * file.  But then we wouldn't know the actual
1205		 * contents size, so I don't see a really viable way
1206		 * around this.  (Also, we may want to someday pull
1207		 * other unspecified info from the contents file on
1208		 * disk.)
1209		 */
1210		mtree->fd = -1;
1211		if (archive_strlen(&mtree->contents_name) > 0)
1212			path = mtree->contents_name.s;
1213		else
1214			path = archive_entry_pathname(entry);
1215
1216		if (archive_entry_filetype(entry) == AE_IFREG ||
1217				archive_entry_filetype(entry) == AE_IFDIR) {
1218			mtree->fd = open(path, O_RDONLY | O_BINARY | O_CLOEXEC);
1219			__archive_ensure_cloexec_flag(mtree->fd);
1220			if (mtree->fd == -1 &&
1221				(errno != ENOENT ||
1222				 archive_strlen(&mtree->contents_name) > 0)) {
1223				archive_set_error(&a->archive, errno,
1224						"Can't open %s", path);
1225				r = ARCHIVE_WARN;
1226			}
1227		}
1228
1229		st = &st_storage;
1230		if (mtree->fd >= 0) {
1231			if (fstat(mtree->fd, st) == -1) {
1232				archive_set_error(&a->archive, errno,
1233						"Could not fstat %s", path);
1234				r = ARCHIVE_WARN;
1235				/* If we can't stat it, don't keep it open. */
1236				close(mtree->fd);
1237				mtree->fd = -1;
1238				st = NULL;
1239			}
1240		} else if (lstat(path, st) == -1) {
1241			st = NULL;
1242		}
1243
1244		/*
1245		 * Check for a mismatch between the type in the specification
1246		 * and the type of the contents object on disk.
1247		 */
1248		if (st != NULL) {
1249			if (((st->st_mode & S_IFMT) == S_IFREG &&
1250			      archive_entry_filetype(entry) == AE_IFREG)
1251#ifdef S_IFLNK
1252			  ||((st->st_mode & S_IFMT) == S_IFLNK &&
1253			      archive_entry_filetype(entry) == AE_IFLNK)
1254#endif
1255#ifdef S_IFSOCK
1256			  ||((st->st_mode & S_IFSOCK) == S_IFSOCK &&
1257			      archive_entry_filetype(entry) == AE_IFSOCK)
1258#endif
1259#ifdef S_IFCHR
1260			  ||((st->st_mode & S_IFMT) == S_IFCHR &&
1261			      archive_entry_filetype(entry) == AE_IFCHR)
1262#endif
1263#ifdef S_IFBLK
1264			  ||((st->st_mode & S_IFMT) == S_IFBLK &&
1265			      archive_entry_filetype(entry) == AE_IFBLK)
1266#endif
1267			  ||((st->st_mode & S_IFMT) == S_IFDIR &&
1268			      archive_entry_filetype(entry) == AE_IFDIR)
1269#ifdef S_IFIFO
1270			  ||((st->st_mode & S_IFMT) == S_IFIFO &&
1271			      archive_entry_filetype(entry) == AE_IFIFO)
1272#endif
1273			) {
1274				/* Types match. */
1275			} else {
1276				/* Types don't match; bail out gracefully. */
1277				if (mtree->fd >= 0)
1278					close(mtree->fd);
1279				mtree->fd = -1;
1280				if (parsed_kws & MTREE_HAS_OPTIONAL) {
1281					/* It's not an error for an optional
1282					 * entry to not match disk. */
1283					*use_next = 1;
1284				} else if (r == ARCHIVE_OK) {
1285					archive_set_error(&a->archive,
1286					    ARCHIVE_ERRNO_MISC,
1287					    "mtree specification has different"
1288					    " type for %s",
1289					    archive_entry_pathname(entry));
1290					r = ARCHIVE_WARN;
1291				}
1292				return (r);
1293			}
1294		}
1295
1296		/*
1297		 * If there is a contents file on disk, pick some of the
1298		 * metadata from that file.  For most of these, we only
1299		 * set it from the contents if it wasn't already parsed
1300		 * from the specification.
1301		 */
1302		if (st != NULL) {
1303			if (((parsed_kws & MTREE_HAS_DEVICE) == 0 ||
1304				(parsed_kws & MTREE_HAS_NOCHANGE) != 0) &&
1305				(archive_entry_filetype(entry) == AE_IFCHR ||
1306				 archive_entry_filetype(entry) == AE_IFBLK))
1307				archive_entry_set_rdev(entry, st->st_rdev);
1308			if ((parsed_kws & (MTREE_HAS_GID | MTREE_HAS_GNAME))
1309				== 0 ||
1310			    (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
1311				archive_entry_set_gid(entry, st->st_gid);
1312			if ((parsed_kws & (MTREE_HAS_UID | MTREE_HAS_UNAME))
1313				== 0 ||
1314			    (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
1315				archive_entry_set_uid(entry, st->st_uid);
1316			if ((parsed_kws & MTREE_HAS_MTIME) == 0 ||
1317			    (parsed_kws & MTREE_HAS_NOCHANGE) != 0) {
1318#if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
1319				archive_entry_set_mtime(entry, st->st_mtime,
1320						st->st_mtimespec.tv_nsec);
1321#elif HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
1322				archive_entry_set_mtime(entry, st->st_mtime,
1323						st->st_mtim.tv_nsec);
1324#elif HAVE_STRUCT_STAT_ST_MTIME_N
1325				archive_entry_set_mtime(entry, st->st_mtime,
1326						st->st_mtime_n);
1327#elif HAVE_STRUCT_STAT_ST_UMTIME
1328				archive_entry_set_mtime(entry, st->st_mtime,
1329						st->st_umtime*1000);
1330#elif HAVE_STRUCT_STAT_ST_MTIME_USEC
1331				archive_entry_set_mtime(entry, st->st_mtime,
1332						st->st_mtime_usec*1000);
1333#else
1334				archive_entry_set_mtime(entry, st->st_mtime, 0);
1335#endif
1336			}
1337			if ((parsed_kws & MTREE_HAS_NLINK) == 0 ||
1338			    (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
1339				archive_entry_set_nlink(entry, st->st_nlink);
1340			if ((parsed_kws & MTREE_HAS_PERM) == 0 ||
1341			    (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
1342				archive_entry_set_perm(entry, st->st_mode);
1343			if ((parsed_kws & MTREE_HAS_SIZE) == 0 ||
1344			    (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
1345				archive_entry_set_size(entry, st->st_size);
1346			archive_entry_set_ino(entry, st->st_ino);
1347			archive_entry_set_dev(entry, st->st_dev);
1348
1349			archive_entry_linkify(mtree->resolver, &entry,
1350				&sparse_entry);
1351		} else if (parsed_kws & MTREE_HAS_OPTIONAL) {
1352			/*
1353			 * Couldn't open the entry, stat it or the on-disk type
1354			 * didn't match.  If this entry is optional, just
1355			 * ignore it and read the next header entry.
1356			 */
1357			*use_next = 1;
1358			return ARCHIVE_OK;
1359		}
1360	}
1361
1362	mtree->cur_size = archive_entry_size(entry);
1363	mtree->offset = 0;
1364
1365	return r;
1366}
1367
1368/*
1369 * Each line contains a sequence of keywords.
1370 */
1371static int
1372parse_line(struct archive_read *a, struct archive_entry *entry,
1373    struct mtree *mtree, struct mtree_entry *mp, int *parsed_kws)
1374{
1375	struct mtree_option *iter;
1376	int r = ARCHIVE_OK, r1;
1377
1378	for (iter = mp->options; iter != NULL; iter = iter->next) {
1379		r1 = parse_keyword(a, mtree, entry, iter, parsed_kws);
1380		if (r1 < r)
1381			r = r1;
1382	}
1383	if (r == ARCHIVE_OK && (*parsed_kws & MTREE_HAS_TYPE) == 0) {
1384		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1385		    "Missing type keyword in mtree specification");
1386		return (ARCHIVE_WARN);
1387	}
1388	return (r);
1389}
1390
1391/*
1392 * Device entries have one of the following forms:
1393 *  - raw dev_t
1394 *  - format,major,minor[,subdevice]
1395 * When parsing succeeded, `pdev' will contain the appropriate dev_t value.
1396 */
1397
1398/* strsep() is not in C90, but strcspn() is. */
1399/* Taken from http://unixpapa.com/incnote/string.html */
1400static char *
1401la_strsep(char **sp, const char *sep)
1402{
1403	char *p, *s;
1404	if (sp == NULL || *sp == NULL || **sp == '\0')
1405		return(NULL);
1406	s = *sp;
1407	p = s + strcspn(s, sep);
1408	if (*p != '\0')
1409		*p++ = '\0';
1410	*sp = p;
1411	return(s);
1412}
1413
1414static int
1415parse_device(dev_t *pdev, struct archive *a, char *val)
1416{
1417#define MAX_PACK_ARGS 3
1418	unsigned long numbers[MAX_PACK_ARGS];
1419	char *p, *dev;
1420	int argc;
1421	pack_t *pack;
1422	dev_t result;
1423	const char *error = NULL;
1424
1425	memset(pdev, 0, sizeof(*pdev));
1426	if ((dev = strchr(val, ',')) != NULL) {
1427		/*
1428		 * Device's major/minor are given in a specified format.
1429		 * Decode and pack it accordingly.
1430		 */
1431		*dev++ = '\0';
1432		if ((pack = pack_find(val)) == NULL) {
1433			archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
1434			    "Unknown format `%s'", val);
1435			return ARCHIVE_WARN;
1436		}
1437		argc = 0;
1438		while ((p = la_strsep(&dev, ",")) != NULL) {
1439			if (*p == '\0') {
1440				archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
1441				    "Missing number");
1442				return ARCHIVE_WARN;
1443			}
1444			if (argc >= MAX_PACK_ARGS) {
1445				archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
1446				    "Too many arguments");
1447				return ARCHIVE_WARN;
1448			}
1449			numbers[argc++] = (unsigned long)mtree_atol(&p, 0);
1450		}
1451		if (argc < 2) {
1452			archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
1453			    "Not enough arguments");
1454			return ARCHIVE_WARN;
1455		}
1456		result = (*pack)(argc, numbers, &error);
1457		if (error != NULL) {
1458			archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
1459			    "%s", error);
1460			return ARCHIVE_WARN;
1461		}
1462	} else {
1463		/* file system raw value. */
1464		result = (dev_t)mtree_atol(&val, 0);
1465	}
1466	*pdev = result;
1467	return ARCHIVE_OK;
1468#undef MAX_PACK_ARGS
1469}
1470
1471/*
1472 * Parse a single keyword and its value.
1473 */
1474static int
1475parse_keyword(struct archive_read *a, struct mtree *mtree,
1476    struct archive_entry *entry, struct mtree_option *opt, int *parsed_kws)
1477{
1478	char *val, *key;
1479
1480	key = opt->value;
1481
1482	if (*key == '\0')
1483		return (ARCHIVE_OK);
1484
1485	if (strcmp(key, "nochange") == 0) {
1486		*parsed_kws |= MTREE_HAS_NOCHANGE;
1487		return (ARCHIVE_OK);
1488	}
1489	if (strcmp(key, "optional") == 0) {
1490		*parsed_kws |= MTREE_HAS_OPTIONAL;
1491		return (ARCHIVE_OK);
1492	}
1493	if (strcmp(key, "ignore") == 0) {
1494		/*
1495		 * The mtree processing is not recursive, so
1496		 * recursion will only happen for explicitly listed
1497		 * entries.
1498		 */
1499		return (ARCHIVE_OK);
1500	}
1501
1502	val = strchr(key, '=');
1503	if (val == NULL) {
1504		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1505		    "Malformed attribute \"%s\" (%d)", key, key[0]);
1506		return (ARCHIVE_WARN);
1507	}
1508
1509	*val = '\0';
1510	++val;
1511
1512	switch (key[0]) {
1513	case 'c':
1514		if (strcmp(key, "content") == 0
1515		    || strcmp(key, "contents") == 0) {
1516			parse_escapes(val, NULL);
1517			archive_strcpy(&mtree->contents_name, val);
1518			break;
1519		}
1520		if (strcmp(key, "cksum") == 0)
1521			break;
1522		__LA_FALLTHROUGH;
1523	case 'd':
1524		if (strcmp(key, "device") == 0) {
1525			/* stat(2) st_rdev field, e.g. the major/minor IDs
1526			 * of a char/block special file */
1527			int r;
1528			dev_t dev;
1529
1530			*parsed_kws |= MTREE_HAS_DEVICE;
1531			r = parse_device(&dev, &a->archive, val);
1532			if (r == ARCHIVE_OK)
1533				archive_entry_set_rdev(entry, dev);
1534			return r;
1535		}
1536		__LA_FALLTHROUGH;
1537	case 'f':
1538		if (strcmp(key, "flags") == 0) {
1539			*parsed_kws |= MTREE_HAS_FFLAGS;
1540			archive_entry_copy_fflags_text(entry, val);
1541			break;
1542		}
1543		__LA_FALLTHROUGH;
1544	case 'g':
1545		if (strcmp(key, "gid") == 0) {
1546			*parsed_kws |= MTREE_HAS_GID;
1547			archive_entry_set_gid(entry, mtree_atol(&val, 10));
1548			break;
1549		}
1550		if (strcmp(key, "gname") == 0) {
1551			*parsed_kws |= MTREE_HAS_GNAME;
1552			archive_entry_copy_gname(entry, val);
1553			break;
1554		}
1555		__LA_FALLTHROUGH;
1556	case 'i':
1557		if (strcmp(key, "inode") == 0) {
1558			archive_entry_set_ino(entry, mtree_atol(&val, 10));
1559			break;
1560		}
1561		__LA_FALLTHROUGH;
1562	case 'l':
1563		if (strcmp(key, "link") == 0) {
1564			archive_entry_copy_symlink(entry, val);
1565			break;
1566		}
1567		__LA_FALLTHROUGH;
1568	case 'm':
1569		if (strcmp(key, "md5") == 0 || strcmp(key, "md5digest") == 0)
1570			break;
1571		if (strcmp(key, "mode") == 0) {
1572			if (val[0] >= '0' && val[0] <= '7') {
1573				*parsed_kws |= MTREE_HAS_PERM;
1574				archive_entry_set_perm(entry,
1575				    (mode_t)mtree_atol(&val, 8));
1576			} else {
1577				archive_set_error(&a->archive,
1578				    ARCHIVE_ERRNO_FILE_FORMAT,
1579				    "Symbolic or non-octal mode \"%s\" unsupported", val);
1580				return ARCHIVE_WARN;
1581			}
1582			break;
1583		}
1584		__LA_FALLTHROUGH;
1585	case 'n':
1586		if (strcmp(key, "nlink") == 0) {
1587			*parsed_kws |= MTREE_HAS_NLINK;
1588			archive_entry_set_nlink(entry,
1589				(unsigned int)mtree_atol(&val, 10));
1590			break;
1591		}
1592		__LA_FALLTHROUGH;
1593	case 'r':
1594		if (strcmp(key, "resdevice") == 0) {
1595			/* stat(2) st_dev field, e.g. the device ID where the
1596			 * inode resides */
1597			int r;
1598			dev_t dev;
1599
1600			r = parse_device(&dev, &a->archive, val);
1601			if (r == ARCHIVE_OK)
1602				archive_entry_set_dev(entry, dev);
1603			return r;
1604		}
1605		if (strcmp(key, "rmd160") == 0 ||
1606		    strcmp(key, "rmd160digest") == 0)
1607			break;
1608		__LA_FALLTHROUGH;
1609	case 's':
1610		if (strcmp(key, "sha1") == 0 || strcmp(key, "sha1digest") == 0)
1611			break;
1612		if (strcmp(key, "sha256") == 0 ||
1613		    strcmp(key, "sha256digest") == 0)
1614			break;
1615		if (strcmp(key, "sha384") == 0 ||
1616		    strcmp(key, "sha384digest") == 0)
1617			break;
1618		if (strcmp(key, "sha512") == 0 ||
1619		    strcmp(key, "sha512digest") == 0)
1620			break;
1621		if (strcmp(key, "size") == 0) {
1622			archive_entry_set_size(entry, mtree_atol(&val, 10));
1623			break;
1624		}
1625		__LA_FALLTHROUGH;
1626	case 't':
1627		if (strcmp(key, "tags") == 0) {
1628			/*
1629			 * Comma delimited list of tags.
1630			 * Ignore the tags for now, but the interface
1631			 * should be extended to allow inclusion/exclusion.
1632			 */
1633			break;
1634		}
1635		if (strcmp(key, "time") == 0) {
1636			int64_t m;
1637			int64_t my_time_t_max = get_time_t_max();
1638			int64_t my_time_t_min = get_time_t_min();
1639			long ns = 0;
1640
1641			*parsed_kws |= MTREE_HAS_MTIME;
1642			m = mtree_atol(&val, 10);
1643			/* Replicate an old mtree bug:
1644			 * 123456789.1 represents 123456789
1645			 * seconds and 1 nanosecond. */
1646			if (*val == '.') {
1647				++val;
1648				ns = (long)mtree_atol(&val, 10);
1649				if (ns < 0)
1650					ns = 0;
1651				else if (ns > 999999999)
1652					ns = 999999999;
1653			}
1654			if (m > my_time_t_max)
1655				m = my_time_t_max;
1656			else if (m < my_time_t_min)
1657				m = my_time_t_min;
1658			archive_entry_set_mtime(entry, (time_t)m, ns);
1659			break;
1660		}
1661		if (strcmp(key, "type") == 0) {
1662			switch (val[0]) {
1663			case 'b':
1664				if (strcmp(val, "block") == 0) {
1665					archive_entry_set_filetype(entry, AE_IFBLK);
1666					break;
1667				}
1668				__LA_FALLTHROUGH;
1669			case 'c':
1670				if (strcmp(val, "char") == 0) {
1671					archive_entry_set_filetype(entry,
1672						AE_IFCHR);
1673					break;
1674				}
1675				__LA_FALLTHROUGH;
1676			case 'd':
1677				if (strcmp(val, "dir") == 0) {
1678					archive_entry_set_filetype(entry,
1679						AE_IFDIR);
1680					break;
1681				}
1682				__LA_FALLTHROUGH;
1683			case 'f':
1684				if (strcmp(val, "fifo") == 0) {
1685					archive_entry_set_filetype(entry,
1686						AE_IFIFO);
1687					break;
1688				}
1689				if (strcmp(val, "file") == 0) {
1690					archive_entry_set_filetype(entry,
1691						AE_IFREG);
1692					break;
1693				}
1694				__LA_FALLTHROUGH;
1695			case 'l':
1696				if (strcmp(val, "link") == 0) {
1697					archive_entry_set_filetype(entry,
1698						AE_IFLNK);
1699					break;
1700				}
1701				__LA_FALLTHROUGH;
1702			default:
1703				archive_set_error(&a->archive,
1704				    ARCHIVE_ERRNO_FILE_FORMAT,
1705				    "Unrecognized file type \"%s\"; "
1706				    "assuming \"file\"", val);
1707				archive_entry_set_filetype(entry, AE_IFREG);
1708				return (ARCHIVE_WARN);
1709			}
1710			*parsed_kws |= MTREE_HAS_TYPE;
1711			break;
1712		}
1713		__LA_FALLTHROUGH;
1714	case 'u':
1715		if (strcmp(key, "uid") == 0) {
1716			*parsed_kws |= MTREE_HAS_UID;
1717			archive_entry_set_uid(entry, mtree_atol(&val, 10));
1718			break;
1719		}
1720		if (strcmp(key, "uname") == 0) {
1721			*parsed_kws |= MTREE_HAS_UNAME;
1722			archive_entry_copy_uname(entry, val);
1723			break;
1724		}
1725		__LA_FALLTHROUGH;
1726	default:
1727		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1728		    "Unrecognized key %s=%s", key, val);
1729		return (ARCHIVE_WARN);
1730	}
1731	return (ARCHIVE_OK);
1732}
1733
1734static int
1735read_data(struct archive_read *a, const void **buff, size_t *size,
1736    int64_t *offset)
1737{
1738	size_t bytes_to_read;
1739	ssize_t bytes_read;
1740	struct mtree *mtree;
1741
1742	mtree = (struct mtree *)(a->format->data);
1743	if (mtree->fd < 0) {
1744		*buff = NULL;
1745		*offset = 0;
1746		*size = 0;
1747		return (ARCHIVE_EOF);
1748	}
1749	if (mtree->buff == NULL) {
1750		mtree->buffsize = 64 * 1024;
1751		mtree->buff = malloc(mtree->buffsize);
1752		if (mtree->buff == NULL) {
1753			archive_set_error(&a->archive, ENOMEM,
1754			    "Can't allocate memory");
1755			return (ARCHIVE_FATAL);
1756		}
1757	}
1758
1759	*buff = mtree->buff;
1760	*offset = mtree->offset;
1761	if ((int64_t)mtree->buffsize > mtree->cur_size - mtree->offset)
1762		bytes_to_read = (size_t)(mtree->cur_size - mtree->offset);
1763	else
1764		bytes_to_read = mtree->buffsize;
1765	bytes_read = read(mtree->fd, mtree->buff, bytes_to_read);
1766	if (bytes_read < 0) {
1767		archive_set_error(&a->archive, errno, "Can't read");
1768		return (ARCHIVE_WARN);
1769	}
1770	if (bytes_read == 0) {
1771		*size = 0;
1772		return (ARCHIVE_EOF);
1773	}
1774	mtree->offset += bytes_read;
1775	*size = bytes_read;
1776	return (ARCHIVE_OK);
1777}
1778
1779/* Skip does nothing except possibly close the contents file. */
1780static int
1781skip(struct archive_read *a)
1782{
1783	struct mtree *mtree;
1784
1785	mtree = (struct mtree *)(a->format->data);
1786	if (mtree->fd >= 0) {
1787		close(mtree->fd);
1788		mtree->fd = -1;
1789	}
1790	return (ARCHIVE_OK);
1791}
1792
1793/*
1794 * Since parsing backslash sequences always makes strings shorter,
1795 * we can always do this conversion in-place.
1796 */
1797static void
1798parse_escapes(char *src, struct mtree_entry *mentry)
1799{
1800	char *dest = src;
1801	char c;
1802
1803	if (mentry != NULL && strcmp(src, ".") == 0)
1804		mentry->full = 1;
1805
1806	while (*src != '\0') {
1807		c = *src++;
1808		if (c == '/' && mentry != NULL)
1809			mentry->full = 1;
1810		if (c == '\\') {
1811			switch (src[0]) {
1812			case '0':
1813				if (src[1] < '0' || src[1] > '7') {
1814					c = 0;
1815					++src;
1816					break;
1817				}
1818				/* FALLTHROUGH */
1819			case '1':
1820			case '2':
1821			case '3':
1822				if (src[1] >= '0' && src[1] <= '7' &&
1823				    src[2] >= '0' && src[2] <= '7') {
1824					c = (src[0] - '0') << 6;
1825					c |= (src[1] - '0') << 3;
1826					c |= (src[2] - '0');
1827					src += 3;
1828				}
1829				break;
1830			case 'a':
1831				c = '\a';
1832				++src;
1833				break;
1834			case 'b':
1835				c = '\b';
1836				++src;
1837				break;
1838			case 'f':
1839				c = '\f';
1840				++src;
1841				break;
1842			case 'n':
1843				c = '\n';
1844				++src;
1845				break;
1846			case 'r':
1847				c = '\r';
1848				++src;
1849				break;
1850			case 's':
1851				c = ' ';
1852				++src;
1853				break;
1854			case 't':
1855				c = '\t';
1856				++src;
1857				break;
1858			case 'v':
1859				c = '\v';
1860				++src;
1861				break;
1862			case '\\':
1863				c = '\\';
1864				++src;
1865				break;
1866			}
1867		}
1868		*dest++ = c;
1869	}
1870	*dest = '\0';
1871}
1872
1873/* Parse a hex digit. */
1874static int
1875parsedigit(char c)
1876{
1877	if (c >= '0' && c <= '9')
1878		return c - '0';
1879	else if (c >= 'a' && c <= 'f')
1880		return c - 'a';
1881	else if (c >= 'A' && c <= 'F')
1882		return c - 'A';
1883	else
1884		return -1;
1885}
1886
1887/*
1888 * Note that this implementation does not (and should not!) obey
1889 * locale settings; you cannot simply substitute strtol here, since
1890 * it does obey locale.
1891 */
1892static int64_t
1893mtree_atol(char **p, int base)
1894{
1895	int64_t l, limit;
1896	int digit, last_digit_limit;
1897
1898	if (base == 0) {
1899		if (**p != '0')
1900			base = 10;
1901		else if ((*p)[1] == 'x' || (*p)[1] == 'X') {
1902			*p += 2;
1903			base = 16;
1904		} else {
1905			base = 8;
1906		}
1907	}
1908
1909	if (**p == '-') {
1910		limit = INT64_MIN / base;
1911		last_digit_limit = INT64_MIN % base;
1912		++(*p);
1913
1914		l = 0;
1915		digit = parsedigit(**p);
1916		while (digit >= 0 && digit < base) {
1917			if (l < limit || (l == limit && digit > last_digit_limit))
1918				return INT64_MIN;
1919			l = (l * base) - digit;
1920			digit = parsedigit(*++(*p));
1921		}
1922		return l;
1923	} else {
1924		limit = INT64_MAX / base;
1925		last_digit_limit = INT64_MAX % base;
1926
1927		l = 0;
1928		digit = parsedigit(**p);
1929		while (digit >= 0 && digit < base) {
1930			if (l > limit || (l == limit && digit > last_digit_limit))
1931				return INT64_MAX;
1932			l = (l * base) + digit;
1933			digit = parsedigit(*++(*p));
1934		}
1935		return l;
1936	}
1937}
1938
1939/*
1940 * Returns length of line (including trailing newline)
1941 * or negative on error.  'start' argument is updated to
1942 * point to first character of line.
1943 */
1944static ssize_t
1945readline(struct archive_read *a, struct mtree *mtree, char **start,
1946    ssize_t limit)
1947{
1948	ssize_t bytes_read;
1949	ssize_t total_size = 0;
1950	ssize_t find_off = 0;
1951	const void *t;
1952	void *nl;
1953	char *u;
1954
1955	/* Accumulate line in a line buffer. */
1956	for (;;) {
1957		/* Read some more. */
1958		t = __archive_read_ahead(a, 1, &bytes_read);
1959		if (t == NULL)
1960			return (0);
1961		if (bytes_read < 0)
1962			return (ARCHIVE_FATAL);
1963		nl = memchr(t, '\n', bytes_read);
1964		/* If we found '\n', trim the read to end exactly there. */
1965		if (nl != NULL) {
1966			bytes_read = ((const char *)nl) - ((const char *)t) + 1;
1967		}
1968		if (total_size + bytes_read + 1 > limit) {
1969			archive_set_error(&a->archive,
1970			    ARCHIVE_ERRNO_FILE_FORMAT,
1971			    "Line too long");
1972			return (ARCHIVE_FATAL);
1973		}
1974		if (archive_string_ensure(&mtree->line,
1975			total_size + bytes_read + 1) == NULL) {
1976			archive_set_error(&a->archive, ENOMEM,
1977			    "Can't allocate working buffer");
1978			return (ARCHIVE_FATAL);
1979		}
1980		/* Append new bytes to string. */
1981		memcpy(mtree->line.s + total_size, t, bytes_read);
1982		__archive_read_consume(a, bytes_read);
1983		total_size += bytes_read;
1984		mtree->line.s[total_size] = '\0';
1985
1986		for (u = mtree->line.s + find_off; *u; ++u) {
1987			if (u[0] == '\n') {
1988				/* Ends with unescaped newline. */
1989				*start = mtree->line.s;
1990				return total_size;
1991			} else if (u[0] == '#') {
1992				/* Ends with comment sequence #...\n */
1993				if (nl == NULL) {
1994					/* But we've not found the \n yet */
1995					break;
1996				}
1997			} else if (u[0] == '\\') {
1998				if (u[1] == '\n') {
1999					/* Trim escaped newline. */
2000					total_size -= 2;
2001					mtree->line.s[total_size] = '\0';
2002					break;
2003				} else if (u[1] != '\0') {
2004					/* Skip the two-char escape sequence */
2005					++u;
2006				}
2007			}
2008		}
2009		find_off = u - mtree->line.s;
2010	}
2011}
2012