archive_read.c revision 349901
1310490Scy/*-
251292Sobrien * Copyright (c) 2003-2011 Tim Kientzle
3310490Scy * All rights reserved.
4310490Scy *
5310490Scy * Redistribution and use in source and binary forms, with or without
6310490Scy * modification, are permitted provided that the following conditions
7310490Scy * are met:
8310490Scy * 1. Redistributions of source code must retain the above copyright
9310490Scy *    notice, this list of conditions and the following disclaimer.
10310490Scy * 2. Redistributions in binary form must reproduce the above copyright
11310490Scy *    notice, this list of conditions and the following disclaimer in the
12310490Scy *    documentation and/or other materials provided with the distribution.
13310490Scy *
14310490Scy * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15310490Scy * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16310490Scy * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17310490Scy * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18310490Scy * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19310490Scy * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20310490Scy * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21310490Scy * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22310490Scy * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23310490Scy * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24310490Scy */
25310490Scy
26310490Scy/*
27310490Scy * This file contains the "essential" portions of the read API, that
28310490Scy * is, stuff that will probably always be used by any client that
29310490Scy * actually needs to read an archive.  Optional pieces have been, as
30310490Scy * far as possible, separated out into separate files to avoid
31310490Scy * needlessly bloating statically-linked clients.
32310490Scy */
33310490Scy
34310490Scy#include "archive_platform.h"
35310490Scy__FBSDID("$FreeBSD: stable/10/contrib/libarchive/libarchive/archive_read.c 349901 2019-07-11 00:22:10Z mm $");
36310490Scy
37310490Scy#ifdef HAVE_ERRNO_H
38310490Scy#include <errno.h>
39310490Scy#endif
40310490Scy#include <stdio.h>
41310490Scy#ifdef HAVE_STDLIB_H
42310490Scy#include <stdlib.h>
43174294Sobrien#endif
44174294Sobrien#ifdef HAVE_STRING_H
45174294Sobrien#include <string.h>
46174294Sobrien#endif
47174294Sobrien#ifdef HAVE_UNISTD_H
48174294Sobrien#include <unistd.h>
49174294Sobrien#endif
50174294Sobrien
51174294Sobrien#include "archive.h"
52174294Sobrien#include "archive_entry.h"
53174294Sobrien#include "archive_private.h"
54174294Sobrien#include "archive_read_private.h"
55174294Sobrien
56174294Sobrien#define minimum(a, b) (a < b ? a : b)
57174294Sobrien
58174294Sobrienstatic int	choose_filters(struct archive_read *);
59174294Sobrienstatic int	choose_format(struct archive_read *);
60174294Sobrienstatic int	close_filters(struct archive_read *);
61174294Sobrienstatic struct archive_vtable *archive_read_vtable(void);
62174294Sobrienstatic int64_t	_archive_filter_bytes(struct archive *, int);
63174294Sobrienstatic int	_archive_filter_code(struct archive *, int);
64174294Sobrienstatic const char *_archive_filter_name(struct archive *, int);
65174294Sobrienstatic int  _archive_filter_count(struct archive *);
66174294Sobrienstatic int	_archive_read_close(struct archive *);
67174294Sobrienstatic int	_archive_read_data_block(struct archive *,
68174294Sobrien		    const void **, size_t *, int64_t *);
69310490Scystatic int	_archive_read_free(struct archive *);
70174294Sobrienstatic int	_archive_read_next_header(struct archive *,
71174294Sobrien		    struct archive_entry **);
72174294Sobrienstatic int	_archive_read_next_header2(struct archive *,
73310490Scy		    struct archive_entry *);
74174294Sobrienstatic int64_t  advance_file_pointer(struct archive_read_filter *, int64_t);
75310490Scy
76174294Sobrienstatic struct archive_vtable *
77174294Sobrienarchive_read_vtable(void)
78174294Sobrien{
79174294Sobrien	static struct archive_vtable av;
80174294Sobrien	static int inited = 0;
81174294Sobrien
82310490Scy	if (!inited) {
83310490Scy		av.archive_filter_bytes = _archive_filter_bytes;
84174294Sobrien		av.archive_filter_code = _archive_filter_code;
85310490Scy		av.archive_filter_name = _archive_filter_name;
86310490Scy		av.archive_filter_count = _archive_filter_count;
87310490Scy		av.archive_read_data_block = _archive_read_data_block;
88310490Scy		av.archive_read_next_header = _archive_read_next_header;
89174294Sobrien		av.archive_read_next_header2 = _archive_read_next_header2;
90310490Scy		av.archive_free = _archive_read_free;
91174294Sobrien		av.archive_close = _archive_read_close;
92174294Sobrien		inited = 1;
93174294Sobrien	}
94174294Sobrien	return (&av);
95174294Sobrien}
96174294Sobrien
97174294Sobrien/*
98174294Sobrien * Allocate, initialize and return a struct archive object.
99174294Sobrien */
100174294Sobrienstruct archive *
101174294Sobrienarchive_read_new(void)
102174294Sobrien{
103174294Sobrien	struct archive_read *a;
104174294Sobrien
105174294Sobrien	a = (struct archive_read *)calloc(1, sizeof(*a));
106174294Sobrien	if (a == NULL)
107174294Sobrien		return (NULL);
108174294Sobrien	a->archive.magic = ARCHIVE_READ_MAGIC;
109174294Sobrien
110174294Sobrien	a->archive.state = ARCHIVE_STATE_NEW;
111174294Sobrien	a->entry = archive_entry_new2(&a->archive);
112174294Sobrien	a->archive.vtable = archive_read_vtable();
113174294Sobrien
114174294Sobrien	a->passphrases.last = &a->passphrases.first;
115174294Sobrien
116174294Sobrien	return (&a->archive);
117174294Sobrien}
118174294Sobrien
119174294Sobrien/*
120174294Sobrien * Record the do-not-extract-to file. This belongs in archive_read_extract.c.
121174294Sobrien */
122174294Sobrienvoid
123174294Sobrienarchive_read_extract_set_skip_file(struct archive *_a, la_int64_t d,
124174294Sobrien    la_int64_t i)
125174294Sobrien{
126310490Scy	struct archive_read *a = (struct archive_read *)_a;
127310490Scy
128310490Scy	if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_MAGIC,
129310490Scy		ARCHIVE_STATE_ANY, "archive_read_extract_set_skip_file"))
130310490Scy		return;
131310490Scy	a->skip_file_set = 1;
132310490Scy	a->skip_file_dev = d;
133310490Scy	a->skip_file_ino = i;
134310490Scy}
135310490Scy
136310490Scy/*
137310490Scy * Open the archive
138310490Scy */
139310490Scyint
140310490Scyarchive_read_open(struct archive *a, void *client_data,
141310490Scy    archive_open_callback *client_opener, archive_read_callback *client_reader,
142310490Scy    archive_close_callback *client_closer)
143310490Scy{
144310490Scy	/* Old archive_read_open() is just a thin shell around
145310490Scy	 * archive_read_open1. */
146310490Scy	archive_read_set_open_callback(a, client_opener);
147310490Scy	archive_read_set_read_callback(a, client_reader);
148310490Scy	archive_read_set_close_callback(a, client_closer);
149310490Scy	archive_read_set_callback_data(a, client_data);
150310490Scy	return archive_read_open1(a);
151310490Scy}
152310490Scy
153310490Scy
154310490Scyint
155310490Scyarchive_read_open2(struct archive *a, void *client_data,
156310490Scy    archive_open_callback *client_opener,
157310490Scy    archive_read_callback *client_reader,
158310490Scy    archive_skip_callback *client_skipper,
159310490Scy    archive_close_callback *client_closer)
160310490Scy{
161310490Scy	/* Old archive_read_open2() is just a thin shell around
162310490Scy	 * archive_read_open1. */
163310490Scy	archive_read_set_callback_data(a, client_data);
164310490Scy	archive_read_set_open_callback(a, client_opener);
165310490Scy	archive_read_set_read_callback(a, client_reader);
166310490Scy	archive_read_set_skip_callback(a, client_skipper);
167310490Scy	archive_read_set_close_callback(a, client_closer);
168310490Scy	return archive_read_open1(a);
169310490Scy}
170310490Scy
171310490Scystatic ssize_t
172310490Scyclient_read_proxy(struct archive_read_filter *self, const void **buff)
173310490Scy{
174310490Scy	ssize_t r;
175310490Scy	r = (self->archive->client.reader)(&self->archive->archive,
176310490Scy	    self->data, buff);
177310490Scy	return (r);
178310490Scy}
179310490Scy
180310490Scystatic int64_t
181310490Scyclient_skip_proxy(struct archive_read_filter *self, int64_t request)
182310490Scy{
183310490Scy	if (request < 0)
184310490Scy		__archive_errx(1, "Negative skip requested.");
185174294Sobrien	if (request == 0)
186174294Sobrien		return 0;
187310490Scy
188174294Sobrien	if (self->archive->client.skipper != NULL) {
189174294Sobrien		/* Seek requests over 1GiB are broken down into
190310490Scy		 * multiple seeks.  This avoids overflows when the
191310490Scy		 * requests get passed through 32-bit arguments. */
192310490Scy		int64_t skip_limit = (int64_t)1 << 30;
193310490Scy		int64_t total = 0;
194310490Scy		for (;;) {
195310490Scy			int64_t get, ask = request;
196310490Scy			if (ask > skip_limit)
197310490Scy				ask = skip_limit;
198310490Scy			get = (self->archive->client.skipper)
199310490Scy				(&self->archive->archive, self->data, ask);
200310490Scy			total += get;
201310490Scy			if (get == 0 || get == request)
202174294Sobrien				return (total);
203174294Sobrien			if (get > request)
204174294Sobrien				return ARCHIVE_FATAL;
205174294Sobrien			request -= get;
206174294Sobrien		}
207174294Sobrien	} else if (self->archive->client.seeker != NULL
208174294Sobrien		&& request > 64 * 1024) {
209174294Sobrien		/* If the client provided a seeker but not a skipper,
210174294Sobrien		 * we can use the seeker to skip forward.
211174294Sobrien		 *
212174294Sobrien		 * Note: This isn't always a good idea.  The client
213174294Sobrien		 * skipper is allowed to skip by less than requested
214174294Sobrien		 * if it needs to maintain block alignment.  The
215174294Sobrien		 * seeker is not allowed to play such games, so using
216174294Sobrien		 * the seeker here may be a performance loss compared
217174294Sobrien		 * to just reading and discarding.  That's why we
218174294Sobrien		 * only do this for skips of over 64k.
219174294Sobrien		 */
220174294Sobrien		int64_t before = self->position;
221174294Sobrien		int64_t after = (self->archive->client.seeker)
222174294Sobrien		    (&self->archive->archive, self->data, request, SEEK_CUR);
223174294Sobrien		if (after != before + request)
224174294Sobrien			return ARCHIVE_FATAL;
225174294Sobrien		return after - before;
226174294Sobrien	}
227174294Sobrien	return 0;
228174294Sobrien}
229174294Sobrien
230174294Sobrienstatic int64_t
231174294Sobrienclient_seek_proxy(struct archive_read_filter *self, int64_t offset, int whence)
232174294Sobrien{
233174294Sobrien	/* DO NOT use the skipper here!  If we transparently handled
234174294Sobrien	 * forward seek here by using the skipper, that will break
235174294Sobrien	 * other libarchive code that assumes a successful forward
236174294Sobrien	 * seek means it can also seek backwards.
237174294Sobrien	 */
238174294Sobrien	if (self->archive->client.seeker == NULL) {
239174294Sobrien		archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
240174294Sobrien		    "Current client reader does not support seeking a device");
241174294Sobrien		return (ARCHIVE_FAILED);
242174294Sobrien	}
243174294Sobrien	return (self->archive->client.seeker)(&self->archive->archive,
244174294Sobrien	    self->data, offset, whence);
245174294Sobrien}
246174294Sobrien
247174294Sobrienstatic int
248174294Sobrienclient_close_proxy(struct archive_read_filter *self)
249174294Sobrien{
250174294Sobrien	int r = ARCHIVE_OK, r2;
251174294Sobrien	unsigned int i;
252174294Sobrien
253174294Sobrien	if (self->archive->client.closer == NULL)
254174294Sobrien		return (r);
255174294Sobrien	for (i = 0; i < self->archive->client.nodes; i++)
256174294Sobrien	{
257174294Sobrien		r2 = (self->archive->client.closer)
258174294Sobrien			((struct archive *)self->archive,
259174294Sobrien				self->archive->client.dataset[i].data);
260174294Sobrien		if (r > r2)
261174294Sobrien			r = r2;
262174294Sobrien	}
263174294Sobrien	return (r);
264174294Sobrien}
265174294Sobrien
266174294Sobrienstatic int
267174294Sobrienclient_open_proxy(struct archive_read_filter *self)
268174294Sobrien{
269174294Sobrien  int r = ARCHIVE_OK;
270174294Sobrien	if (self->archive->client.opener != NULL)
271174294Sobrien		r = (self->archive->client.opener)(
272174294Sobrien		    (struct archive *)self->archive, self->data);
273174294Sobrien	return (r);
274174294Sobrien}
275174294Sobrien
276174294Sobrienstatic int
277174294Sobrienclient_switch_proxy(struct archive_read_filter *self, unsigned int iindex)
278174294Sobrien{
279174294Sobrien  int r1 = ARCHIVE_OK, r2 = ARCHIVE_OK;
280174294Sobrien	void *data2 = NULL;
281174294Sobrien
282174294Sobrien	/* Don't do anything if already in the specified data node */
283174294Sobrien	if (self->archive->client.cursor == iindex)
284174294Sobrien		return (ARCHIVE_OK);
285174294Sobrien
286174294Sobrien	self->archive->client.cursor = iindex;
287174294Sobrien	data2 = self->archive->client.dataset[self->archive->client.cursor].data;
288174294Sobrien	if (self->archive->client.switcher != NULL)
289174294Sobrien	{
290174294Sobrien		r1 = r2 = (self->archive->client.switcher)
291174294Sobrien			((struct archive *)self->archive, self->data, data2);
292174294Sobrien		self->data = data2;
293174294Sobrien	}
294174294Sobrien	else
295174294Sobrien	{
296174294Sobrien		/* Attempt to call close and open instead */
297174294Sobrien		if (self->archive->client.closer != NULL)
298174294Sobrien			r1 = (self->archive->client.closer)
299174294Sobrien				((struct archive *)self->archive, self->data);
300174294Sobrien		self->data = data2;
301174294Sobrien		if (self->archive->client.opener != NULL)
302174294Sobrien			r2 = (self->archive->client.opener)
303174294Sobrien				((struct archive *)self->archive, self->data);
304174294Sobrien	}
305174294Sobrien	return (r1 < r2) ? r1 : r2;
306174294Sobrien}
307174294Sobrien
308174294Sobrienint
309174294Sobrienarchive_read_set_open_callback(struct archive *_a,
310174294Sobrien    archive_open_callback *client_opener)
311174294Sobrien{
312174294Sobrien	struct archive_read *a = (struct archive_read *)_a;
313174294Sobrien	archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
314174294Sobrien	    "archive_read_set_open_callback");
315174294Sobrien	a->client.opener = client_opener;
316174294Sobrien	return ARCHIVE_OK;
317174294Sobrien}
318174294Sobrien
319174294Sobrienint
320174294Sobrienarchive_read_set_read_callback(struct archive *_a,
321174294Sobrien    archive_read_callback *client_reader)
322174294Sobrien{
323174294Sobrien	struct archive_read *a = (struct archive_read *)_a;
324174294Sobrien	archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
325174294Sobrien	    "archive_read_set_read_callback");
326174294Sobrien	a->client.reader = client_reader;
327174294Sobrien	return ARCHIVE_OK;
328174294Sobrien}
329174294Sobrien
330174294Sobrienint
331174294Sobrienarchive_read_set_skip_callback(struct archive *_a,
332174294Sobrien    archive_skip_callback *client_skipper)
333174294Sobrien{
334174294Sobrien	struct archive_read *a = (struct archive_read *)_a;
335174294Sobrien	archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
336174294Sobrien	    "archive_read_set_skip_callback");
337174294Sobrien	a->client.skipper = client_skipper;
338174294Sobrien	return ARCHIVE_OK;
339174294Sobrien}
340174294Sobrien
341174294Sobrienint
342174294Sobrienarchive_read_set_seek_callback(struct archive *_a,
343174294Sobrien    archive_seek_callback *client_seeker)
344131702Smbr{
345174294Sobrien	struct archive_read *a = (struct archive_read *)_a;
346174294Sobrien	archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
347174294Sobrien	    "archive_read_set_seek_callback");
348131702Smbr	a->client.seeker = client_seeker;
349174294Sobrien	return ARCHIVE_OK;
350174294Sobrien}
351174294Sobrien
352174294Sobrienint
353174294Sobrienarchive_read_set_close_callback(struct archive *_a,
354174294Sobrien    archive_close_callback *client_closer)
355174294Sobrien{
356174294Sobrien	struct archive_read *a = (struct archive_read *)_a;
357174294Sobrien	archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
358174294Sobrien	    "archive_read_set_close_callback");
359174294Sobrien	a->client.closer = client_closer;
360174294Sobrien	return ARCHIVE_OK;
361174294Sobrien}
362174294Sobrien
363174294Sobrienint
364174294Sobrienarchive_read_set_switch_callback(struct archive *_a,
365174294Sobrien    archive_switch_callback *client_switcher)
366119679Smbr{
367174294Sobrien	struct archive_read *a = (struct archive_read *)_a;
368174294Sobrien	archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
369174294Sobrien	    "archive_read_set_switch_callback");
370174294Sobrien	a->client.switcher = client_switcher;
371174294Sobrien	return ARCHIVE_OK;
372174294Sobrien}
373174294Sobrien
374174294Sobrienint
375131702Smbrarchive_read_set_callback_data(struct archive *_a, void *client_data)
376131702Smbr{
377131702Smbr	return archive_read_set_callback_data2(_a, client_data, 0);
378174294Sobrien}
379174294Sobrien
380174294Sobrienint
381119679Smbrarchive_read_set_callback_data2(struct archive *_a, void *client_data,
382174294Sobrien    unsigned int iindex)
383174294Sobrien{
384174294Sobrien	struct archive_read *a = (struct archive_read *)_a;
385174294Sobrien	archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
386119679Smbr	    "archive_read_set_callback_data2");
387174294Sobrien
388174294Sobrien	if (a->client.nodes == 0)
389174294Sobrien	{
390174294Sobrien		a->client.dataset = (struct archive_read_data_node *)
391174294Sobrien		    calloc(1, sizeof(*a->client.dataset));
392174294Sobrien		if (a->client.dataset == NULL)
393174294Sobrien		{
394174294Sobrien			archive_set_error(&a->archive, ENOMEM,
395174294Sobrien				"No memory.");
396174294Sobrien			return ARCHIVE_FATAL;
397174294Sobrien		}
398174294Sobrien		a->client.nodes = 1;
399174294Sobrien	}
400174294Sobrien
401174294Sobrien	if (iindex > a->client.nodes - 1)
402174294Sobrien	{
403174294Sobrien		archive_set_error(&a->archive, EINVAL,
404174294Sobrien			"Invalid index specified.");
405174294Sobrien		return ARCHIVE_FATAL;
406174294Sobrien	}
407174294Sobrien	a->client.dataset[iindex].data = client_data;
408174294Sobrien	a->client.dataset[iindex].begin_position = -1;
409310490Scy	a->client.dataset[iindex].total_size = -1;
410174294Sobrien	return ARCHIVE_OK;
411174294Sobrien}
412174294Sobrien
413174294Sobrienint
414174294Sobrienarchive_read_add_callback_data(struct archive *_a, void *client_data,
415174294Sobrien    unsigned int iindex)
416174294Sobrien{
417174294Sobrien	struct archive_read *a = (struct archive_read *)_a;
418174294Sobrien	void *p;
419174294Sobrien	unsigned int i;
420174294Sobrien
421174294Sobrien	archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
422174294Sobrien	    "archive_read_add_callback_data");
423174294Sobrien	if (iindex > a->client.nodes) {
424174294Sobrien		archive_set_error(&a->archive, EINVAL,
425174294Sobrien			"Invalid index specified.");
426174294Sobrien		return ARCHIVE_FATAL;
427174294Sobrien	}
428174294Sobrien	p = realloc(a->client.dataset, sizeof(*a->client.dataset)
429174294Sobrien		* (++(a->client.nodes)));
430174294Sobrien	if (p == NULL) {
431174294Sobrien		archive_set_error(&a->archive, ENOMEM,
432174294Sobrien			"No memory.");
433174294Sobrien		return ARCHIVE_FATAL;
434174294Sobrien	}
435174294Sobrien	a->client.dataset = (struct archive_read_data_node *)p;
436174294Sobrien	for (i = a->client.nodes - 1; i > iindex && i > 0; i--) {
437174294Sobrien		a->client.dataset[i].data = a->client.dataset[i-1].data;
438174294Sobrien		a->client.dataset[i].begin_position = -1;
439174294Sobrien		a->client.dataset[i].total_size = -1;
440174294Sobrien	}
441174294Sobrien	a->client.dataset[iindex].data = client_data;
442174294Sobrien	a->client.dataset[iindex].begin_position = -1;
443174294Sobrien	a->client.dataset[iindex].total_size = -1;
444174294Sobrien	return ARCHIVE_OK;
445174294Sobrien}
446174294Sobrien
447174294Sobrienint
448174294Sobrienarchive_read_append_callback_data(struct archive *_a, void *client_data)
449174294Sobrien{
450174294Sobrien	struct archive_read *a = (struct archive_read *)_a;
451174294Sobrien	return archive_read_add_callback_data(_a, client_data, a->client.nodes);
452174294Sobrien}
453174294Sobrien
454174294Sobrienint
455174294Sobrienarchive_read_prepend_callback_data(struct archive *_a, void *client_data)
456174294Sobrien{
457174294Sobrien	return archive_read_add_callback_data(_a, client_data, 0);
458174294Sobrien}
459174294Sobrien
460174294Sobrienint
461174294Sobrienarchive_read_open1(struct archive *_a)
462174294Sobrien{
463174294Sobrien	struct archive_read *a = (struct archive_read *)_a;
464174294Sobrien	struct archive_read_filter *filter, *tmp;
465174294Sobrien	int slot, e = ARCHIVE_OK;
466174294Sobrien	unsigned int i;
467174294Sobrien
468174294Sobrien	archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
469174294Sobrien	    "archive_read_open");
470174294Sobrien	archive_clear_error(&a->archive);
471174294Sobrien
472174294Sobrien	if (a->client.reader == NULL) {
473174294Sobrien		archive_set_error(&a->archive, EINVAL,
474174294Sobrien		    "No reader function provided to archive_read_open");
475174294Sobrien		a->archive.state = ARCHIVE_STATE_FATAL;
476174294Sobrien		return (ARCHIVE_FATAL);
477174294Sobrien	}
478174294Sobrien
479174294Sobrien	/* Open data source. */
480174294Sobrien	if (a->client.opener != NULL) {
481174294Sobrien		e = (a->client.opener)(&a->archive, a->client.dataset[0].data);
482174294Sobrien		if (e != 0) {
483174294Sobrien			/* If the open failed, call the closer to clean up. */
484174294Sobrien			if (a->client.closer) {
485174294Sobrien				for (i = 0; i < a->client.nodes; i++)
486174294Sobrien					(a->client.closer)(&a->archive,
487174294Sobrien					    a->client.dataset[i].data);
488174294Sobrien			}
489174294Sobrien			return (e);
490174294Sobrien		}
491174294Sobrien	}
492174294Sobrien
493174294Sobrien	filter = calloc(1, sizeof(*filter));
494174294Sobrien	if (filter == NULL)
495174294Sobrien		return (ARCHIVE_FATAL);
496174294Sobrien	filter->bidder = NULL;
497174294Sobrien	filter->upstream = NULL;
498174294Sobrien	filter->archive = a;
499174294Sobrien	filter->data = a->client.dataset[0].data;
500174294Sobrien	filter->open = client_open_proxy;
501174294Sobrien	filter->read = client_read_proxy;
502174294Sobrien	filter->skip = client_skip_proxy;
503174294Sobrien	filter->seek = client_seek_proxy;
504174294Sobrien	filter->close = client_close_proxy;
505174294Sobrien	filter->sswitch = client_switch_proxy;
506174294Sobrien	filter->name = "none";
507174294Sobrien	filter->code = ARCHIVE_FILTER_NONE;
508174294Sobrien
509174294Sobrien	a->client.dataset[0].begin_position = 0;
510174294Sobrien	if (!a->filter || !a->bypass_filter_bidding)
511174294Sobrien	{
512174294Sobrien		a->filter = filter;
513174294Sobrien		/* Build out the input pipeline. */
514174294Sobrien		e = choose_filters(a);
515174294Sobrien		if (e < ARCHIVE_WARN) {
516174294Sobrien			a->archive.state = ARCHIVE_STATE_FATAL;
517174294Sobrien			return (ARCHIVE_FATAL);
518174294Sobrien		}
519174294Sobrien	}
520174294Sobrien	else
521174294Sobrien	{
522174294Sobrien		/* Need to add "NONE" type filter at the end of the filter chain */
523174294Sobrien		tmp = a->filter;
524174294Sobrien		while (tmp->upstream)
525174294Sobrien			tmp = tmp->upstream;
526174294Sobrien		tmp->upstream = filter;
527174294Sobrien	}
528174294Sobrien
529174294Sobrien	if (!a->format)
530174294Sobrien	{
531174294Sobrien		slot = choose_format(a);
532174294Sobrien		if (slot < 0) {
533174294Sobrien			close_filters(a);
534174294Sobrien			a->archive.state = ARCHIVE_STATE_FATAL;
535174294Sobrien			return (ARCHIVE_FATAL);
536174294Sobrien		}
537174294Sobrien		a->format = &(a->formats[slot]);
538174294Sobrien	}
539174294Sobrien
540174294Sobrien	a->archive.state = ARCHIVE_STATE_HEADER;
541174294Sobrien
542174294Sobrien	/* Ensure libarchive starts from the first node in a multivolume set */
543174294Sobrien	client_switch_proxy(a->filter, 0);
544174294Sobrien	return (e);
545174294Sobrien}
546174294Sobrien
547174294Sobrien/*
548174294Sobrien * Allow each registered stream transform to bid on whether
549174294Sobrien * it wants to handle this stream.  Repeat until we've finished
550174294Sobrien * building the pipeline.
551174294Sobrien */
552174294Sobrien
553174294Sobrien/* We won't build a filter pipeline with more stages than this. */
554174294Sobrien#define MAX_NUMBER_FILTERS 25
555174294Sobrien
556174294Sobrienstatic int
557174294Sobrienchoose_filters(struct archive_read *a)
558174294Sobrien{
559174294Sobrien	int number_bidders, i, bid, best_bid, number_filters;
560174294Sobrien	struct archive_read_filter_bidder *bidder, *best_bidder;
561174294Sobrien	struct archive_read_filter *filter;
562174294Sobrien	ssize_t avail;
563174294Sobrien	int r;
564174294Sobrien
565174294Sobrien	for (number_filters = 0; number_filters < MAX_NUMBER_FILTERS; ++number_filters) {
566174294Sobrien		number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]);
567174294Sobrien
568174294Sobrien		best_bid = 0;
569174294Sobrien		best_bidder = NULL;
570174294Sobrien
571174294Sobrien		bidder = a->bidders;
572174294Sobrien		for (i = 0; i < number_bidders; i++, bidder++) {
573174294Sobrien			if (bidder->bid != NULL) {
574174294Sobrien				bid = (bidder->bid)(bidder, a->filter);
575174294Sobrien				if (bid > best_bid) {
576174294Sobrien					best_bid = bid;
577174294Sobrien					best_bidder = bidder;
578174294Sobrien				}
579174294Sobrien			}
580174294Sobrien		}
581174294Sobrien
582174294Sobrien		/* If no bidder, we're done. */
583174294Sobrien		if (best_bidder == NULL) {
584174294Sobrien			/* Verify the filter by asking it for some data. */
585174294Sobrien			__archive_read_filter_ahead(a->filter, 1, &avail);
586174294Sobrien			if (avail < 0) {
587174294Sobrien				__archive_read_free_filters(a);
588174294Sobrien				return (ARCHIVE_FATAL);
589174294Sobrien			}
590174294Sobrien			a->archive.compression_name = a->filter->name;
591174294Sobrien			a->archive.compression_code = a->filter->code;
592174294Sobrien			return (ARCHIVE_OK);
593174294Sobrien		}
594174294Sobrien
595174294Sobrien		filter
596174294Sobrien		    = (struct archive_read_filter *)calloc(1, sizeof(*filter));
597174294Sobrien		if (filter == NULL)
598119679Smbr			return (ARCHIVE_FATAL);
599174294Sobrien		filter->bidder = best_bidder;
600174294Sobrien		filter->archive = a;
601119679Smbr		filter->upstream = a->filter;
602119679Smbr		a->filter = filter;
603174294Sobrien		r = (best_bidder->init)(a->filter);
604174294Sobrien		if (r != ARCHIVE_OK) {
605174294Sobrien			__archive_read_free_filters(a);
606174294Sobrien			return (ARCHIVE_FATAL);
607174294Sobrien		}
608174294Sobrien	}
609119679Smbr	archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
610119679Smbr	    "Input requires too many filters for decoding");
611174294Sobrien	return (ARCHIVE_FATAL);
612174294Sobrien}
613174294Sobrien
614174294Sobrienint
615174294Sobrien__archive_read_header(struct archive_read *a, struct archive_entry *entry)
616174294Sobrien{
617174294Sobrien	if (a->filter->read_header)
618119679Smbr		return a->filter->read_header(a->filter, entry);
619119679Smbr	else
620119679Smbr		return (ARCHIVE_OK);
621119679Smbr}
622174294Sobrien
623119679Smbr/*
624174294Sobrien * Read header of next entry.
625119679Smbr */
626174294Sobrienstatic int
627174294Sobrien_archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
628174294Sobrien{
629174294Sobrien	struct archive_read *a = (struct archive_read *)_a;
630174294Sobrien	int r1 = ARCHIVE_OK, r2;
631174294Sobrien
632174294Sobrien	archive_check_magic(_a, ARCHIVE_READ_MAGIC,
633119679Smbr	    ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
634119679Smbr	    "archive_read_next_header");
635174294Sobrien
636119679Smbr	archive_entry_clear(entry);
637119679Smbr	archive_clear_error(&a->archive);
638119679Smbr
639174294Sobrien	/*
640174294Sobrien	 * If client didn't consume entire data, skip any remainder
641174294Sobrien	 * (This is especially important for GNU incremental directories.)
642119679Smbr	 */
643174294Sobrien	if (a->archive.state == ARCHIVE_STATE_DATA) {
644119679Smbr		r1 = archive_read_data_skip(&a->archive);
645174294Sobrien		if (r1 == ARCHIVE_EOF)
646119679Smbr			archive_set_error(&a->archive, EIO,
647174294Sobrien			    "Premature end-of-file.");
648174294Sobrien		if (r1 == ARCHIVE_EOF || r1 == ARCHIVE_FATAL) {
649174294Sobrien			a->archive.state = ARCHIVE_STATE_FATAL;
650174294Sobrien			return (ARCHIVE_FATAL);
651174294Sobrien		}
652174294Sobrien	}
653174294Sobrien
654119679Smbr	/* Record start-of-header offset in uncompressed stream. */
655174294Sobrien	a->header_position = a->filter->position;
656119679Smbr
657174294Sobrien	++_a->file_count;
658174294Sobrien	r2 = (a->format->read_header)(a, entry);
659174294Sobrien
660174294Sobrien	/*
661174294Sobrien	 * EOF and FATAL are persistent at this layer.  By
662174294Sobrien	 * modifying the state, we guarantee that future calls to
663174294Sobrien	 * read a header or read data will fail.
664174294Sobrien	 */
665174294Sobrien	switch (r2) {
666174294Sobrien	case ARCHIVE_EOF:
667174294Sobrien		a->archive.state = ARCHIVE_STATE_EOF;
668174294Sobrien		--_a->file_count;/* Revert a file counter. */
669174294Sobrien		break;
670119679Smbr	case ARCHIVE_OK:
671119679Smbr		a->archive.state = ARCHIVE_STATE_DATA;
672174294Sobrien		break;
673119679Smbr	case ARCHIVE_WARN:
674119679Smbr		a->archive.state = ARCHIVE_STATE_DATA;
675119679Smbr		break;
676119679Smbr	case ARCHIVE_RETRY:
677119679Smbr		break;
678174294Sobrien	case ARCHIVE_FATAL:
679174294Sobrien		a->archive.state = ARCHIVE_STATE_FATAL;
680174294Sobrien		break;
681174294Sobrien	}
682174294Sobrien
683174294Sobrien	__archive_reset_read_data(&a->archive);
684174294Sobrien
685174294Sobrien	a->data_start_node = a->client.cursor;
686119679Smbr	/* EOF always wins; otherwise return the worst error. */
687174294Sobrien	return (r2 < r1 || r2 == ARCHIVE_EOF) ? r2 : r1;
68882794Sobrien}
689174294Sobrien
690174294Sobrienstatic int
69182794Sobrien_archive_read_next_header(struct archive *_a, struct archive_entry **entryp)
692174294Sobrien{
69382794Sobrien	int ret;
694174294Sobrien	struct archive_read *a = (struct archive_read *)_a;
69582794Sobrien	*entryp = NULL;
696174294Sobrien	ret = _archive_read_next_header2(_a, a->entry);
69782794Sobrien	*entryp = a->entry;
698174294Sobrien	return ret;
69982794Sobrien}
700174294Sobrien
701174294Sobrien/*
70282794Sobrien * Allow each registered format to bid on whether it wants to handle
703174294Sobrien * the next entry.  Return index of winning bidder.
70482794Sobrien */
705174294Sobrienstatic int
70682794Sobrienchoose_format(struct archive_read *a)
707174294Sobrien{
70882794Sobrien	int slots;
709174294Sobrien	int i;
710174294Sobrien	int bid, best_bid;
711174294Sobrien	int best_bid_slot;
712174294Sobrien
71382794Sobrien	slots = sizeof(a->formats) / sizeof(a->formats[0]);
714174294Sobrien	best_bid = -1;
71582794Sobrien	best_bid_slot = -1;
716174294Sobrien
71782794Sobrien	/* Set up a->format for convenience of bidders. */
718174294Sobrien	a->format = &(a->formats[0]);
71982794Sobrien	for (i = 0; i < slots; i++, a->format++) {
720174294Sobrien		if (a->format->bid) {
72182794Sobrien			bid = (a->format->bid)(a, best_bid);
722174294Sobrien			if (bid == ARCHIVE_FATAL)
723174294Sobrien				return (ARCHIVE_FATAL);
724174294Sobrien			if (a->filter->position != 0)
725174294Sobrien				__archive_read_seek(a, 0, SEEK_SET);
726174294Sobrien			if ((bid > best_bid) || (best_bid_slot < 0)) {
72782794Sobrien				best_bid = bid;
728174294Sobrien				best_bid_slot = i;
72982794Sobrien			}
730174294Sobrien		}
73182794Sobrien	}
732174294Sobrien
73382794Sobrien	/*
734174294Sobrien	 * There were no bidders; this is a serious programmer error
735174294Sobrien	 * and demands a quick and definitive abort.
73682794Sobrien	 */
737174294Sobrien	if (best_bid_slot < 0) {
738174294Sobrien		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
739174294Sobrien		    "No formats registered");
74082794Sobrien		return (ARCHIVE_FATAL);
74182794Sobrien	}
74282794Sobrien
74382794Sobrien	/*
74482794Sobrien	 * There were bidders, but no non-zero bids; this means we
74582794Sobrien	 * can't support this stream.
74682794Sobrien	 */
74782794Sobrien	if (best_bid < 1) {
74882794Sobrien		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
74982794Sobrien		    "Unrecognized archive format");
75082794Sobrien		return (ARCHIVE_FATAL);
75182794Sobrien	}
75282794Sobrien
75382794Sobrien	return (best_bid_slot);
75482794Sobrien}
75582794Sobrien
75682794Sobrien/*
75782794Sobrien * Return the file offset (within the uncompressed data stream) where
75882794Sobrien * the last header started.
75982794Sobrien */
76082794Sobrienla_int64_t
76182794Sobrienarchive_read_header_position(struct archive *_a)
76282794Sobrien{
76382794Sobrien	struct archive_read *a = (struct archive_read *)_a;
76482794Sobrien	archive_check_magic(_a, ARCHIVE_READ_MAGIC,
76582794Sobrien	    ARCHIVE_STATE_ANY, "archive_read_header_position");
76682794Sobrien	return (a->header_position);
76782794Sobrien}
76882794Sobrien
76982794Sobrien/*
77082794Sobrien * Returns 1 if the archive contains at least one encrypted entry.
77182794Sobrien * If the archive format not support encryption at all
77282794Sobrien * ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED is returned.
77382794Sobrien * If for any other reason (e.g. not enough data read so far)
77482794Sobrien * we cannot say whether there are encrypted entries, then
77582794Sobrien * ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW is returned.
77682794Sobrien * In general, this function will return values below zero when the
77782794Sobrien * reader is uncertain or totally incapable of encryption support.
77882794Sobrien * When this function returns 0 you can be sure that the reader
77982794Sobrien * supports encryption detection but no encrypted entries have
78082794Sobrien * been found yet.
78182794Sobrien *
78282794Sobrien * NOTE: If the metadata/header of an archive is also encrypted, you
78382794Sobrien * cannot rely on the number of encrypted entries. That is why this
78482794Sobrien * function does not return the number of encrypted entries but#
78582794Sobrien * just shows that there are some.
78682794Sobrien */
78782794Sobrienint
78882794Sobrienarchive_read_has_encrypted_entries(struct archive *_a)
78982794Sobrien{
79082794Sobrien	struct archive_read *a = (struct archive_read *)_a;
79182794Sobrien	int format_supports_encryption = archive_read_format_capabilities(_a)
79282794Sobrien			& (ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA | ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA);
79382794Sobrien
79482794Sobrien	if (!_a || !format_supports_encryption) {
79582794Sobrien		/* Format in general doesn't support encryption */
79682794Sobrien		return ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED;
79782794Sobrien	}
79882794Sobrien
79982794Sobrien	/* A reader potentially has read enough data now. */
80082794Sobrien	if (a->format && a->format->has_encrypted_entries) {
80182794Sobrien		return (a->format->has_encrypted_entries)(a);
80282794Sobrien	}
80382794Sobrien
80482794Sobrien	/* For any other reason we cannot say how many entries are there. */
80582794Sobrien	return ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
80682794Sobrien}
80782794Sobrien
80852894Sobrien/*
80952894Sobrien * Returns a bitmask of capabilities that are supported by the archive format reader.
81052894Sobrien * If the reader has no special capabilities, ARCHIVE_READ_FORMAT_CAPS_NONE is returned.
81152894Sobrien */
81252894Sobrienint
81352894Sobrienarchive_read_format_capabilities(struct archive *_a)
81452894Sobrien{
81552894Sobrien	struct archive_read *a = (struct archive_read *)_a;
81652894Sobrien	if (a && a->format && a->format->format_capabilties) {
81752894Sobrien		return (a->format->format_capabilties)(a);
81852894Sobrien	}
81952894Sobrien	return ARCHIVE_READ_FORMAT_CAPS_NONE;
82052894Sobrien}
82152894Sobrien
82252894Sobrien/*
82352894Sobrien * Read data from an archive entry, using a read(2)-style interface.
82452894Sobrien * This is a convenience routine that just calls
82552894Sobrien * archive_read_data_block and copies the results into the client
82652894Sobrien * buffer, filling any gaps with zero bytes.  Clients using this
82752894Sobrien * API can be completely ignorant of sparse-file issues; sparse files
82852894Sobrien * will simply be padded with nulls.
82952894Sobrien *
83052894Sobrien * DO NOT intermingle calls to this function and archive_read_data_block
83152894Sobrien * to read a single entry body.
83252894Sobrien */
83352894Sobrienla_ssize_t
83451292Sobrienarchive_read_data(struct archive *_a, void *buff, size_t s)
83551292Sobrien{
83651292Sobrien	struct archive *a = (struct archive *)_a;
83751292Sobrien	char	*dest;
83851292Sobrien	const void *read_buf;
83951292Sobrien	size_t	 bytes_read;
84051292Sobrien	size_t	 len;
84151292Sobrien	int	 r;
84251292Sobrien
84351292Sobrien	bytes_read = 0;
84451292Sobrien	dest = (char *)buff;
84551292Sobrien
84651292Sobrien	while (s > 0) {
84751292Sobrien		if (a->read_data_offset == a->read_data_output_offset &&
84851292Sobrien		    a->read_data_remaining == 0) {
84951292Sobrien			read_buf = a->read_data_block;
85051292Sobrien			a->read_data_is_posix_read = 1;
85151292Sobrien			a->read_data_requested = s;
85251292Sobrien			r = archive_read_data_block(a, &read_buf,
85351292Sobrien			    &a->read_data_remaining, &a->read_data_offset);
85451292Sobrien			a->read_data_block = read_buf;
85551292Sobrien			if (r == ARCHIVE_EOF)
85651292Sobrien				return (bytes_read);
85751292Sobrien			/*
85851292Sobrien			 * Error codes are all negative, so the status
85951292Sobrien			 * return here cannot be confused with a valid
86051292Sobrien			 * byte count.  (ARCHIVE_OK is zero.)
86151292Sobrien			 */
86251292Sobrien			if (r < ARCHIVE_OK)
86351292Sobrien				return (r);
86451292Sobrien		}
86551292Sobrien
86651292Sobrien		if (a->read_data_offset < a->read_data_output_offset) {
86751292Sobrien			archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
86851292Sobrien			    "Encountered out-of-order sparse blocks");
86951292Sobrien			return (ARCHIVE_RETRY);
87051292Sobrien		}
87151292Sobrien
87251292Sobrien		/* Compute the amount of zero padding needed. */
87351292Sobrien		if (a->read_data_output_offset + (int64_t)s <
87451292Sobrien		    a->read_data_offset) {
87551292Sobrien			len = s;
87651292Sobrien		} else if (a->read_data_output_offset <
87751292Sobrien		    a->read_data_offset) {
87851292Sobrien			len = (size_t)(a->read_data_offset -
87951292Sobrien			    a->read_data_output_offset);
88051292Sobrien		} else
88151292Sobrien			len = 0;
88251292Sobrien
88351292Sobrien		/* Add zeroes. */
88451292Sobrien		memset(dest, 0, len);
88551292Sobrien		s -= len;
88651292Sobrien		a->read_data_output_offset += len;
88751292Sobrien		dest += len;
88851292Sobrien		bytes_read += len;
88951292Sobrien
89051292Sobrien		/* Copy data if there is any space left. */
89151292Sobrien		if (s > 0) {
89242629Sobrien			len = a->read_data_remaining;
89342629Sobrien			if (len > s)
89442629Sobrien				len = s;
89542629Sobrien			if (len)
89642629Sobrien				memcpy(dest, a->read_data_block, len);
89742629Sobrien			s -= len;
89842629Sobrien			a->read_data_block += len;
89942629Sobrien			a->read_data_remaining -= len;
90042629Sobrien			a->read_data_output_offset += len;
90142629Sobrien			a->read_data_offset += len;
90242629Sobrien			dest += len;
90342629Sobrien			bytes_read += len;
90442629Sobrien		}
90542629Sobrien	}
90642629Sobrien	a->read_data_is_posix_read = 0;
90742629Sobrien	a->read_data_requested = 0;
90842629Sobrien	return (bytes_read);
90942629Sobrien}
91042629Sobrien
91142629Sobrien/*
91242629Sobrien * Reset the read_data_* variables, used for starting a new entry.
91342629Sobrien */
91442629Sobrienvoid __archive_reset_read_data(struct archive * a)
91542629Sobrien{
91642629Sobrien	a->read_data_output_offset = 0;
91742629Sobrien	a->read_data_remaining = 0;
91842629Sobrien	a->read_data_is_posix_read = 0;
91942629Sobrien	a->read_data_requested = 0;
92042629Sobrien
92142629Sobrien   /* extra resets, from rar.c */
92242629Sobrien   a->read_data_block = NULL;
92342629Sobrien   a->read_data_offset = 0;
92441142Sobrien}
92541142Sobrien
92641142Sobrien/*
92741142Sobrien * Skip over all remaining data in this entry.
92841142Sobrien */
92941142Sobrienint
93041142Sobrienarchive_read_data_skip(struct archive *_a)
93141142Sobrien{
93241142Sobrien	struct archive_read *a = (struct archive_read *)_a;
93341142Sobrien	int r;
93441142Sobrien	const void *buff;
93541142Sobrien	size_t size;
93641142Sobrien	int64_t offset;
93741142Sobrien
93841142Sobrien	archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA,
93941142Sobrien	    "archive_read_data_skip");
94038494Sobrien
94138494Sobrien	if (a->format->read_data_skip != NULL)
94238494Sobrien		r = (a->format->read_data_skip)(a);
94338494Sobrien	else {
94438494Sobrien		while ((r = archive_read_data_block(&a->archive,
94538494Sobrien			    &buff, &size, &offset))
94638494Sobrien		    == ARCHIVE_OK)
94738494Sobrien			;
94838494Sobrien	}
94938494Sobrien
95038494Sobrien	if (r == ARCHIVE_EOF)
95138494Sobrien		r = ARCHIVE_OK;
95238494Sobrien
95338494Sobrien	a->archive.state = ARCHIVE_STATE_HEADER;
95438494Sobrien	return (r);
95538494Sobrien}
95638494Sobrien
95738494Sobrienla_int64_t
95838494Sobrienarchive_seek_data(struct archive *_a, int64_t offset, int whence)
95938494Sobrien{
96038494Sobrien	struct archive_read *a = (struct archive_read *)_a;
96138494Sobrien	archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA,
96238494Sobrien	    "archive_seek_data_block");
96338494Sobrien
96438494Sobrien	if (a->format->seek_data == NULL) {
96538494Sobrien		archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
96638494Sobrien		    "Internal error: "
96738494Sobrien		    "No format_seek_data_block function registered");
96838494Sobrien		return (ARCHIVE_FATAL);
96938494Sobrien	}
97038494Sobrien
97138494Sobrien	return (a->format->seek_data)(a, offset, whence);
97238494Sobrien}
97338494Sobrien
97438494Sobrien/*
97538494Sobrien * Read the next block of entry data from the archive.
97638494Sobrien * This is a zero-copy interface; the client receives a pointer,
97738494Sobrien * size, and file offset of the next available block of data.
97838494Sobrien *
97938494Sobrien * Returns ARCHIVE_OK if the operation is successful, ARCHIVE_EOF if
98038494Sobrien * the end of entry is encountered.
98138494Sobrien */
98238494Sobrienstatic int
98338494Sobrien_archive_read_data_block(struct archive *_a,
98438494Sobrien    const void **buff, size_t *size, int64_t *offset)
98538494Sobrien{
98638494Sobrien	struct archive_read *a = (struct archive_read *)_a;
98738494Sobrien	archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA,
98838494Sobrien	    "archive_read_data_block");
98938494Sobrien
99038494Sobrien	if (a->format->read_data == NULL) {
99138494Sobrien		archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
99238494Sobrien		    "Internal error: "
99338494Sobrien		    "No format->read_data function registered");
99438494Sobrien		return (ARCHIVE_FATAL);
99538494Sobrien	}
99638494Sobrien
99738494Sobrien	return (a->format->read_data)(a, buff, size, offset);
99838494Sobrien}
99938494Sobrien
100038494Sobrienstatic int
100138494Sobrienclose_filters(struct archive_read *a)
100238494Sobrien{
100338494Sobrien	struct archive_read_filter *f = a->filter;
100438494Sobrien	int r = ARCHIVE_OK;
100538494Sobrien	/* Close each filter in the pipeline. */
100638494Sobrien	while (f != NULL) {
100738494Sobrien		struct archive_read_filter *t = f->upstream;
100838494Sobrien		if (!f->closed && f->close != NULL) {
100938494Sobrien			int r1 = (f->close)(f);
101038494Sobrien			f->closed = 1;
101138494Sobrien			if (r1 < r)
101238494Sobrien				r = r1;
101338494Sobrien		}
101438494Sobrien		free(f->buffer);
101538494Sobrien		f->buffer = NULL;
101638494Sobrien		f = t;
101738494Sobrien	}
101838494Sobrien	return r;
101938494Sobrien}
102038494Sobrien
102138494Sobrienvoid
102238494Sobrien__archive_read_free_filters(struct archive_read *a)
102338494Sobrien{
102438494Sobrien	/* Make sure filters are closed and their buffers are freed */
102538494Sobrien	close_filters(a);
102638494Sobrien
102738494Sobrien	while (a->filter != NULL) {
102838494Sobrien		struct archive_read_filter *t = a->filter->upstream;
102938494Sobrien		free(a->filter);
103038494Sobrien		a->filter = t;
103138494Sobrien	}
103238494Sobrien}
103338494Sobrien
103438494Sobrien/*
103538494Sobrien * return the count of # of filters in use
103638494Sobrien */
103738494Sobrienstatic int
103838494Sobrien_archive_filter_count(struct archive *_a)
103938494Sobrien{
104038494Sobrien	struct archive_read *a = (struct archive_read *)_a;
104138494Sobrien	struct archive_read_filter *p = a->filter;
104238494Sobrien	int count = 0;
104338494Sobrien	while(p) {
104438494Sobrien		count++;
104538494Sobrien		p = p->upstream;
104638494Sobrien	}
104738494Sobrien	return count;
104838494Sobrien}
104938494Sobrien
105038494Sobrien/*
105138494Sobrien * Close the file and all I/O.
105238494Sobrien */
105338494Sobrienstatic int
105438494Sobrien_archive_read_close(struct archive *_a)
105538494Sobrien{
105638494Sobrien	struct archive_read *a = (struct archive_read *)_a;
105738494Sobrien	int r = ARCHIVE_OK, r1 = ARCHIVE_OK;
105838494Sobrien
105938494Sobrien	archive_check_magic(&a->archive, ARCHIVE_READ_MAGIC,
106038494Sobrien	    ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_close");
106138494Sobrien	if (a->archive.state == ARCHIVE_STATE_CLOSED)
106238494Sobrien		return (ARCHIVE_OK);
106338494Sobrien	archive_clear_error(&a->archive);
106438494Sobrien	a->archive.state = ARCHIVE_STATE_CLOSED;
106538494Sobrien
106638494Sobrien	/* TODO: Clean up the formatters. */
106738494Sobrien
106838494Sobrien	/* Release the filter objects. */
106938494Sobrien	r1 = close_filters(a);
107038494Sobrien	if (r1 < r)
107138494Sobrien		r = r1;
107238494Sobrien
107338494Sobrien	return (r);
107438494Sobrien}
107538494Sobrien
107638494Sobrien/*
107738494Sobrien * Release memory and other resources.
107838494Sobrien */
107938494Sobrienstatic int
108038494Sobrien_archive_read_free(struct archive *_a)
108138494Sobrien{
108238494Sobrien	struct archive_read *a = (struct archive_read *)_a;
108338494Sobrien	struct archive_read_passphrase *p;
108438494Sobrien	int i, n;
108538494Sobrien	int slots;
108638494Sobrien	int r = ARCHIVE_OK;
108738494Sobrien
108838494Sobrien	if (_a == NULL)
108938494Sobrien		return (ARCHIVE_OK);
109038494Sobrien	archive_check_magic(_a, ARCHIVE_READ_MAGIC,
109138494Sobrien	    ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_free");
109238494Sobrien	if (a->archive.state != ARCHIVE_STATE_CLOSED
109338494Sobrien	    && a->archive.state != ARCHIVE_STATE_FATAL)
109438494Sobrien		r = archive_read_close(&a->archive);
109538494Sobrien
109638494Sobrien	/* Call cleanup functions registered by optional components. */
109738494Sobrien	if (a->cleanup_archive_extract != NULL)
109838494Sobrien		r = (a->cleanup_archive_extract)(a);
109938494Sobrien
110038494Sobrien	/* Cleanup format-specific data. */
110138494Sobrien	slots = sizeof(a->formats) / sizeof(a->formats[0]);
110238494Sobrien	for (i = 0; i < slots; i++) {
110338494Sobrien		a->format = &(a->formats[i]);
110438494Sobrien		if (a->formats[i].cleanup)
110538494Sobrien			(a->formats[i].cleanup)(a);
110638494Sobrien	}
110738494Sobrien
110838494Sobrien	/* Free the filters */
110938494Sobrien	__archive_read_free_filters(a);
111038494Sobrien
1111174294Sobrien	/* Release the bidder objects. */
111238494Sobrien	n = sizeof(a->bidders)/sizeof(a->bidders[0]);
111338494Sobrien	for (i = 0; i < n; i++) {
111438494Sobrien		if (a->bidders[i].free != NULL) {
111538494Sobrien			int r1 = (a->bidders[i].free)(&a->bidders[i]);
111638494Sobrien			if (r1 < r)
111738494Sobrien				r = r1;
111838494Sobrien		}
111938494Sobrien	}
112038494Sobrien
112138494Sobrien	/* Release passphrase list. */
112238494Sobrien	p = a->passphrases.first;
112338494Sobrien	while (p != NULL) {
112438494Sobrien		struct archive_read_passphrase *np = p->next;
112538494Sobrien
112638494Sobrien		/* A passphrase should be cleaned. */
112738494Sobrien		memset(p->passphrase, 0, strlen(p->passphrase));
112838494Sobrien		free(p->passphrase);
112938494Sobrien		free(p);
113038494Sobrien		p = np;
113138494Sobrien	}
113238494Sobrien
113338494Sobrien	archive_string_free(&a->archive.error_string);
113438494Sobrien	archive_entry_free(a->entry);
113538494Sobrien	a->archive.magic = 0;
113638494Sobrien	__archive_clean(&a->archive);
113738494Sobrien	free(a->client.dataset);
113838494Sobrien	free(a);
113938494Sobrien	return (r);
114038494Sobrien}
114138494Sobrien
114238494Sobrienstatic struct archive_read_filter *
114338494Sobrienget_filter(struct archive *_a, int n)
114438494Sobrien{
114538494Sobrien	struct archive_read *a = (struct archive_read *)_a;
114638494Sobrien	struct archive_read_filter *f = a->filter;
114738494Sobrien	/* We use n == -1 for 'the last filter', which is always the
114882794Sobrien	 * client proxy. */
114938494Sobrien	if (n == -1 && f != NULL) {
115038494Sobrien		struct archive_read_filter *last = f;
115138494Sobrien		f = f->upstream;
115238494Sobrien		while (f != NULL) {
115338494Sobrien			last = f;
115438494Sobrien			f = f->upstream;
115538494Sobrien		}
115638494Sobrien		return (last);
115738494Sobrien	}
115838494Sobrien	if (n < 0)
115938494Sobrien		return NULL;
116038494Sobrien	while (n > 0 && f != NULL) {
116138494Sobrien		f = f->upstream;
116238494Sobrien		--n;
116338494Sobrien	}
116438494Sobrien	return (f);
116538494Sobrien}
116638494Sobrien
116738494Sobrienstatic int
116838494Sobrien_archive_filter_code(struct archive *_a, int n)
116938494Sobrien{
117038494Sobrien	struct archive_read_filter *f = get_filter(_a, n);
117138494Sobrien	return f == NULL ? -1 : f->code;
117238494Sobrien}
117338494Sobrien
117438494Sobrienstatic const char *
117538494Sobrien_archive_filter_name(struct archive *_a, int n)
117638494Sobrien{
117738494Sobrien	struct archive_read_filter *f = get_filter(_a, n);
117838494Sobrien	return f != NULL ? f->name : NULL;
117938494Sobrien}
118038494Sobrien
118138494Sobrienstatic int64_t
118238494Sobrien_archive_filter_bytes(struct archive *_a, int n)
118338494Sobrien{
118438494Sobrien	struct archive_read_filter *f = get_filter(_a, n);
118538494Sobrien	return f == NULL ? -1 : f->position;
118638494Sobrien}
118738494Sobrien
118838494Sobrien/*
118938494Sobrien * Used internally by read format handlers to register their bid and
119038494Sobrien * initialization functions.
119138494Sobrien */
119238494Sobrienint
119338494Sobrien__archive_read_register_format(struct archive_read *a,
119438494Sobrien    void *format_data,
119538494Sobrien    const char *name,
119638494Sobrien    int (*bid)(struct archive_read *, int),
119738494Sobrien    int (*options)(struct archive_read *, const char *, const char *),
119838494Sobrien    int (*read_header)(struct archive_read *, struct archive_entry *),
119938494Sobrien    int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *),
120038494Sobrien    int (*read_data_skip)(struct archive_read *),
120138494Sobrien    int64_t (*seek_data)(struct archive_read *, int64_t, int),
120238494Sobrien    int (*cleanup)(struct archive_read *),
120338494Sobrien    int (*format_capabilities)(struct archive_read *),
120438494Sobrien    int (*has_encrypted_entries)(struct archive_read *))
120538494Sobrien{
120638494Sobrien	int i, number_slots;
120738494Sobrien
120838494Sobrien	archive_check_magic(&a->archive,
120938494Sobrien	    ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
121038494Sobrien	    "__archive_read_register_format");
121138494Sobrien
121238494Sobrien	number_slots = sizeof(a->formats) / sizeof(a->formats[0]);
121338494Sobrien
121438494Sobrien	for (i = 0; i < number_slots; i++) {
121538494Sobrien		if (a->formats[i].bid == bid)
121638494Sobrien			return (ARCHIVE_WARN); /* We've already installed */
121738494Sobrien		if (a->formats[i].bid == NULL) {
121838494Sobrien			a->formats[i].bid = bid;
121938494Sobrien			a->formats[i].options = options;
122038494Sobrien			a->formats[i].read_header = read_header;
122138494Sobrien			a->formats[i].read_data = read_data;
122238494Sobrien			a->formats[i].read_data_skip = read_data_skip;
122338494Sobrien			a->formats[i].seek_data = seek_data;
122438494Sobrien			a->formats[i].cleanup = cleanup;
122538494Sobrien			a->formats[i].data = format_data;
122638494Sobrien			a->formats[i].name = name;
122738494Sobrien			a->formats[i].format_capabilties = format_capabilities;
122838494Sobrien			a->formats[i].has_encrypted_entries = has_encrypted_entries;
122938494Sobrien			return (ARCHIVE_OK);
123038494Sobrien		}
123138494Sobrien	}
123238494Sobrien
123338494Sobrien	archive_set_error(&a->archive, ENOMEM,
123438494Sobrien	    "Not enough slots for format registration");
123538494Sobrien	return (ARCHIVE_FATAL);
123638494Sobrien}
123738494Sobrien
123838494Sobrien/*
123938494Sobrien * Used internally by decompression routines to register their bid and
124038494Sobrien * initialization functions.
124138494Sobrien */
124238494Sobrienint
124338494Sobrien__archive_read_get_bidder(struct archive_read *a,
124438494Sobrien    struct archive_read_filter_bidder **bidder)
124538494Sobrien{
124638494Sobrien	int i, number_slots;
124738494Sobrien
124838494Sobrien	number_slots = sizeof(a->bidders) / sizeof(a->bidders[0]);
124938494Sobrien
125038494Sobrien	for (i = 0; i < number_slots; i++) {
125138494Sobrien		if (a->bidders[i].bid == NULL) {
125238494Sobrien			memset(a->bidders + i, 0, sizeof(a->bidders[0]));
125338494Sobrien			*bidder = (a->bidders + i);
125438494Sobrien			return (ARCHIVE_OK);
125538494Sobrien		}
125638494Sobrien	}
125738494Sobrien
125838494Sobrien	archive_set_error(&a->archive, ENOMEM,
125938494Sobrien	    "Not enough slots for filter registration");
126038494Sobrien	return (ARCHIVE_FATAL);
126138494Sobrien}
126238494Sobrien
126338494Sobrien/*
126438494Sobrien * The next section implements the peek/consume internal I/O
126538494Sobrien * system used by archive readers.  This system allows simple
126638494Sobrien * read-ahead for consumers while preserving zero-copy operation
126738494Sobrien * most of the time.
126838494Sobrien *
126938494Sobrien * The two key operations:
127038494Sobrien *  * The read-ahead function returns a pointer to a block of data
127138494Sobrien *    that satisfies a minimum request.
127238494Sobrien *  * The consume function advances the file pointer.
127338494Sobrien *
127438494Sobrien * In the ideal case, filters generate blocks of data
127538494Sobrien * and __archive_read_ahead() just returns pointers directly into
127638494Sobrien * those blocks.  Then __archive_read_consume() just bumps those
127738494Sobrien * pointers.  Only if your request would span blocks does the I/O
127838494Sobrien * layer use a copy buffer to provide you with a contiguous block of
127938494Sobrien * data.
128038494Sobrien *
128138494Sobrien * A couple of useful idioms:
128238494Sobrien *  * "I just want some data."  Ask for 1 byte and pay attention to
128338494Sobrien *    the "number of bytes available" from __archive_read_ahead().
128438494Sobrien *    Consume whatever you actually use.
128538494Sobrien *  * "I want to output a large block of data."  As above, ask for 1 byte,
128638494Sobrien *    emit all that's available (up to whatever limit you have), consume
128738494Sobrien *    it all, then repeat until you're done.  This effectively means that
128838494Sobrien *    you're passing along the blocks that came from your provider.
128938494Sobrien *  * "I want to peek ahead by a large amount."  Ask for 4k or so, then
129038494Sobrien *    double and repeat until you get an error or have enough.  Note
129138494Sobrien *    that the I/O layer will likely end up expanding its copy buffer
129238494Sobrien *    to fit your request, so use this technique cautiously.  This
129338494Sobrien *    technique is used, for example, by some of the format tasting
129438494Sobrien *    code that has uncertain look-ahead needs.
129538494Sobrien */
129638494Sobrien
129738494Sobrien/*
129838494Sobrien * Looks ahead in the input stream:
129938494Sobrien *  * If 'avail' pointer is provided, that returns number of bytes available
130038494Sobrien *    in the current buffer, which may be much larger than requested.
130138494Sobrien *  * If end-of-file, *avail gets set to zero.
130238494Sobrien *  * If error, *avail gets error code.
130338494Sobrien *  * If request can be met, returns pointer to data.
130438494Sobrien *  * If minimum request cannot be met, returns NULL.
130538494Sobrien *
130638494Sobrien * Note: If you just want "some data", ask for 1 byte and pay attention
130738494Sobrien * to *avail, which will have the actual amount available.  If you
130838494Sobrien * know exactly how many bytes you need, just ask for that and treat
130938494Sobrien * a NULL return as an error.
131038494Sobrien *
131138494Sobrien * Important:  This does NOT move the file pointer.  See
131238494Sobrien * __archive_read_consume() below.
131338494Sobrien */
131438494Sobrienconst void *
131538494Sobrien__archive_read_ahead(struct archive_read *a, size_t min, ssize_t *avail)
131638494Sobrien{
131738494Sobrien	return (__archive_read_filter_ahead(a->filter, min, avail));
131838494Sobrien}
131938494Sobrien
132038494Sobrienconst void *
132138494Sobrien__archive_read_filter_ahead(struct archive_read_filter *filter,
132238494Sobrien    size_t min, ssize_t *avail)
132338494Sobrien{
132438494Sobrien	ssize_t bytes_read;
132538494Sobrien	size_t tocopy;
132638494Sobrien
132738494Sobrien	if (filter->fatal) {
132838494Sobrien		if (avail)
132938494Sobrien			*avail = ARCHIVE_FATAL;
133038494Sobrien		return (NULL);
133138494Sobrien	}
133238494Sobrien
133338494Sobrien	/*
133438494Sobrien	 * Keep pulling more data until we can satisfy the request.
133538494Sobrien	 */
133638494Sobrien	for (;;) {
133738494Sobrien
133838494Sobrien		/*
133938494Sobrien		 * If we can satisfy from the copy buffer (and the
134038494Sobrien		 * copy buffer isn't empty), we're done.  In particular,
134138494Sobrien		 * note that min == 0 is a perfectly well-defined
134238494Sobrien		 * request.
134338494Sobrien		 */
134438494Sobrien		if (filter->avail >= min && filter->avail > 0) {
134538494Sobrien			if (avail != NULL)
134638494Sobrien				*avail = filter->avail;
134738494Sobrien			return (filter->next);
134838494Sobrien		}
134938494Sobrien
135038494Sobrien		/*
135138494Sobrien		 * We can satisfy directly from client buffer if everything
135238494Sobrien		 * currently in the copy buffer is still in the client buffer.
135338494Sobrien		 */
135438494Sobrien		if (filter->client_total >= filter->client_avail + filter->avail
135538494Sobrien		    && filter->client_avail + filter->avail >= min) {
135638494Sobrien			/* "Roll back" to client buffer. */
135738494Sobrien			filter->client_avail += filter->avail;
135838494Sobrien			filter->client_next -= filter->avail;
135938494Sobrien			/* Copy buffer is now empty. */
136038494Sobrien			filter->avail = 0;
136138494Sobrien			filter->next = filter->buffer;
136238494Sobrien			/* Return data from client buffer. */
136338494Sobrien			if (avail != NULL)
136438494Sobrien				*avail = filter->client_avail;
136538494Sobrien			return (filter->client_next);
136638494Sobrien		}
136738494Sobrien
136838494Sobrien		/* Move data forward in copy buffer if necessary. */
136938494Sobrien		if (filter->next > filter->buffer &&
137038494Sobrien		    filter->next + min > filter->buffer + filter->buffer_size) {
137138494Sobrien			if (filter->avail > 0)
137238494Sobrien				memmove(filter->buffer, filter->next,
137338494Sobrien				    filter->avail);
137438494Sobrien			filter->next = filter->buffer;
137538494Sobrien		}
137638494Sobrien
137738494Sobrien		/* If we've used up the client data, get more. */
137838494Sobrien		if (filter->client_avail <= 0) {
137938494Sobrien			if (filter->end_of_file) {
138038494Sobrien				if (avail != NULL)
138138494Sobrien					*avail = 0;
138238494Sobrien				return (NULL);
138338494Sobrien			}
138438494Sobrien			bytes_read = (filter->read)(filter,
138538494Sobrien			    &filter->client_buff);
138638494Sobrien			if (bytes_read < 0) {		/* Read error. */
138738494Sobrien				filter->client_total = filter->client_avail = 0;
138838494Sobrien				filter->client_next =
138938494Sobrien				    filter->client_buff = NULL;
139038494Sobrien				filter->fatal = 1;
139138494Sobrien				if (avail != NULL)
139238494Sobrien					*avail = ARCHIVE_FATAL;
139338494Sobrien				return (NULL);
139438494Sobrien			}
139538494Sobrien			if (bytes_read == 0) {
139638494Sobrien				/* Check for another client object first */
139738494Sobrien				if (filter->archive->client.cursor !=
139838494Sobrien				      filter->archive->client.nodes - 1) {
139938494Sobrien					if (client_switch_proxy(filter,
140038494Sobrien					    filter->archive->client.cursor + 1)
140138494Sobrien					    == ARCHIVE_OK)
140238494Sobrien						continue;
140338494Sobrien				}
140438494Sobrien				/* Premature end-of-file. */
140538494Sobrien				filter->client_total = filter->client_avail = 0;
140638494Sobrien				filter->client_next =
140738494Sobrien				    filter->client_buff = NULL;
140838494Sobrien				filter->end_of_file = 1;
140938494Sobrien				/* Return whatever we do have. */
141038494Sobrien				if (avail != NULL)
141138494Sobrien					*avail = filter->avail;
141238494Sobrien				return (NULL);
141338494Sobrien			}
141438494Sobrien			filter->client_total = bytes_read;
141538494Sobrien			filter->client_avail = filter->client_total;
141638494Sobrien			filter->client_next = filter->client_buff;
141738494Sobrien		} else {
141838494Sobrien			/*
141938494Sobrien			 * We can't satisfy the request from the copy
142038494Sobrien			 * buffer or the existing client data, so we
142138494Sobrien			 * need to copy more client data over to the
142238494Sobrien			 * copy buffer.
142338494Sobrien			 */
142438494Sobrien
142538494Sobrien			/* Ensure the buffer is big enough. */
142638494Sobrien			if (min > filter->buffer_size) {
142738494Sobrien				size_t s, t;
142838494Sobrien				char *p;
142938494Sobrien
143038494Sobrien				/* Double the buffer; watch for overflow. */
143138494Sobrien				s = t = filter->buffer_size;
143238494Sobrien				if (s == 0)
143338494Sobrien					s = min;
143438494Sobrien				while (s < min) {
143538494Sobrien					t *= 2;
143638494Sobrien					if (t <= s) { /* Integer overflow! */
143738494Sobrien						archive_set_error(
143838494Sobrien						    &filter->archive->archive,
143938494Sobrien						    ENOMEM,
144038494Sobrien						    "Unable to allocate copy"
144138494Sobrien						    " buffer");
144238494Sobrien						filter->fatal = 1;
144338494Sobrien						if (avail != NULL)
144438494Sobrien							*avail = ARCHIVE_FATAL;
144538494Sobrien						return (NULL);
144638494Sobrien					}
144738494Sobrien					s = t;
144838494Sobrien				}
144938494Sobrien				/* Now s >= min, so allocate a new buffer. */
145038494Sobrien				p = (char *)malloc(s);
145138494Sobrien				if (p == NULL) {
145238494Sobrien					archive_set_error(
145338494Sobrien						&filter->archive->archive,
145438494Sobrien						ENOMEM,
145538494Sobrien					    "Unable to allocate copy buffer");
145638494Sobrien					filter->fatal = 1;
145738494Sobrien					if (avail != NULL)
145838494Sobrien						*avail = ARCHIVE_FATAL;
145938494Sobrien					return (NULL);
146038494Sobrien				}
146138494Sobrien				/* Move data into newly-enlarged buffer. */
146238494Sobrien				if (filter->avail > 0)
146338494Sobrien					memmove(p, filter->next, filter->avail);
146438494Sobrien				free(filter->buffer);
146538494Sobrien				filter->next = filter->buffer = p;
146638494Sobrien				filter->buffer_size = s;
146738494Sobrien			}
146838494Sobrien
146938494Sobrien			/* We can add client data to copy buffer. */
147038494Sobrien			/* First estimate: copy to fill rest of buffer. */
147138494Sobrien			tocopy = (filter->buffer + filter->buffer_size)
147238494Sobrien			    - (filter->next + filter->avail);
147338494Sobrien			/* Don't waste time buffering more than we need to. */
147438494Sobrien			if (tocopy + filter->avail > min)
147538494Sobrien				tocopy = min - filter->avail;
147638494Sobrien			/* Don't copy more than is available. */
147738494Sobrien			if (tocopy > filter->client_avail)
147838494Sobrien				tocopy = filter->client_avail;
147938494Sobrien
148038494Sobrien			memcpy(filter->next + filter->avail,
148138494Sobrien			    filter->client_next, tocopy);
148238494Sobrien			/* Remove this data from client buffer. */
148338494Sobrien			filter->client_next += tocopy;
148438494Sobrien			filter->client_avail -= tocopy;
148538494Sobrien			/* add it to copy buffer. */
148638494Sobrien			filter->avail += tocopy;
148738494Sobrien		}
148838494Sobrien	}
148938494Sobrien}
149038494Sobrien
149138494Sobrien/*
149238494Sobrien * Move the file pointer forward.
149338494Sobrien */
149438494Sobrienint64_t
149538494Sobrien__archive_read_consume(struct archive_read *a, int64_t request)
149638494Sobrien{
149738494Sobrien	return (__archive_read_filter_consume(a->filter, request));
149838494Sobrien}
149938494Sobrien
150038494Sobrienint64_t
150138494Sobrien__archive_read_filter_consume(struct archive_read_filter * filter,
150238494Sobrien    int64_t request)
150338494Sobrien{
150438494Sobrien	int64_t skipped;
150538494Sobrien
150638494Sobrien	if (request < 0)
150738494Sobrien		return ARCHIVE_FATAL;
150838494Sobrien	if (request == 0)
150938494Sobrien		return 0;
151038494Sobrien
151138494Sobrien	skipped = advance_file_pointer(filter, request);
151238494Sobrien	if (skipped == request)
151338494Sobrien		return (skipped);
151438494Sobrien	/* We hit EOF before we satisfied the skip request. */
151538494Sobrien	if (skipped < 0)  /* Map error code to 0 for error message below. */
151638494Sobrien		skipped = 0;
151738494Sobrien	archive_set_error(&filter->archive->archive,
151838494Sobrien	    ARCHIVE_ERRNO_MISC,
151938494Sobrien	    "Truncated input file (needed %jd bytes, only %jd available)",
152038494Sobrien	    (intmax_t)request, (intmax_t)skipped);
152138494Sobrien	return (ARCHIVE_FATAL);
152238494Sobrien}
152338494Sobrien
152438494Sobrien/*
152538494Sobrien * Advance the file pointer by the amount requested.
152638494Sobrien * Returns the amount actually advanced, which may be less than the
152738494Sobrien * request if EOF is encountered first.
1528174294Sobrien * Returns a negative value if there's an I/O error.
152938494Sobrien */
153038494Sobrienstatic int64_t
153138494Sobrienadvance_file_pointer(struct archive_read_filter *filter, int64_t request)
1532174294Sobrien{
153338494Sobrien	int64_t bytes_skipped, total_bytes_skipped = 0;
153438494Sobrien	ssize_t bytes_read;
153538494Sobrien	size_t min;
153638494Sobrien
153738494Sobrien	if (filter->fatal)
153838494Sobrien		return (-1);
153938494Sobrien
154038494Sobrien	/* Use up the copy buffer first. */
154138494Sobrien	if (filter->avail > 0) {
154238494Sobrien		min = (size_t)minimum(request, (int64_t)filter->avail);
154338494Sobrien		filter->next += min;
154438494Sobrien		filter->avail -= min;
154538494Sobrien		request -= min;
154638494Sobrien		filter->position += min;
154738494Sobrien		total_bytes_skipped += min;
154838494Sobrien	}
154938494Sobrien
155038494Sobrien	/* Then use up the client buffer. */
155138494Sobrien	if (filter->client_avail > 0) {
155238494Sobrien		min = (size_t)minimum(request, (int64_t)filter->client_avail);
155338494Sobrien		filter->client_next += min;
155438494Sobrien		filter->client_avail -= min;
155538494Sobrien		request -= min;
155638494Sobrien		filter->position += min;
155738494Sobrien		total_bytes_skipped += min;
155838494Sobrien	}
155938494Sobrien	if (request == 0)
156038494Sobrien		return (total_bytes_skipped);
156138494Sobrien
156238494Sobrien	/* If there's an optimized skip function, use it. */
156338494Sobrien	if (filter->skip != NULL) {
156438494Sobrien		bytes_skipped = (filter->skip)(filter, request);
156538494Sobrien		if (bytes_skipped < 0) {	/* error */
156638494Sobrien			filter->fatal = 1;
156738494Sobrien			return (bytes_skipped);
1568		}
1569		filter->position += bytes_skipped;
1570		total_bytes_skipped += bytes_skipped;
1571		request -= bytes_skipped;
1572		if (request == 0)
1573			return (total_bytes_skipped);
1574	}
1575
1576	/* Use ordinary reads as necessary to complete the request. */
1577	for (;;) {
1578		bytes_read = (filter->read)(filter, &filter->client_buff);
1579		if (bytes_read < 0) {
1580			filter->client_buff = NULL;
1581			filter->fatal = 1;
1582			return (bytes_read);
1583		}
1584
1585		if (bytes_read == 0) {
1586			if (filter->archive->client.cursor !=
1587			      filter->archive->client.nodes - 1) {
1588				if (client_switch_proxy(filter,
1589				    filter->archive->client.cursor + 1)
1590				    == ARCHIVE_OK)
1591					continue;
1592			}
1593			filter->client_buff = NULL;
1594			filter->end_of_file = 1;
1595			return (total_bytes_skipped);
1596		}
1597
1598		if (bytes_read >= request) {
1599			filter->client_next =
1600			    ((const char *)filter->client_buff) + request;
1601			filter->client_avail = (size_t)(bytes_read - request);
1602			filter->client_total = bytes_read;
1603			total_bytes_skipped += request;
1604			filter->position += request;
1605			return (total_bytes_skipped);
1606		}
1607
1608		filter->position += bytes_read;
1609		total_bytes_skipped += bytes_read;
1610		request -= bytes_read;
1611	}
1612}
1613
1614/**
1615 * Returns ARCHIVE_FAILED if seeking isn't supported.
1616 */
1617int64_t
1618__archive_read_seek(struct archive_read *a, int64_t offset, int whence)
1619{
1620	return __archive_read_filter_seek(a->filter, offset, whence);
1621}
1622
1623int64_t
1624__archive_read_filter_seek(struct archive_read_filter *filter, int64_t offset,
1625    int whence)
1626{
1627	struct archive_read_client *client;
1628	int64_t r;
1629	unsigned int cursor;
1630
1631	if (filter->closed || filter->fatal)
1632		return (ARCHIVE_FATAL);
1633	if (filter->seek == NULL)
1634		return (ARCHIVE_FAILED);
1635
1636	client = &(filter->archive->client);
1637	switch (whence) {
1638	case SEEK_CUR:
1639		/* Adjust the offset and use SEEK_SET instead */
1640		offset += filter->position;
1641		__LA_FALLTHROUGH;
1642	case SEEK_SET:
1643		cursor = 0;
1644		while (1)
1645		{
1646			if (client->dataset[cursor].begin_position < 0 ||
1647			    client->dataset[cursor].total_size < 0 ||
1648			    client->dataset[cursor].begin_position +
1649			      client->dataset[cursor].total_size - 1 > offset ||
1650			    cursor + 1 >= client->nodes)
1651				break;
1652			r = client->dataset[cursor].begin_position +
1653				client->dataset[cursor].total_size;
1654			client->dataset[++cursor].begin_position = r;
1655		}
1656		while (1) {
1657			r = client_switch_proxy(filter, cursor);
1658			if (r != ARCHIVE_OK)
1659				return r;
1660			if ((r = client_seek_proxy(filter, 0, SEEK_END)) < 0)
1661				return r;
1662			client->dataset[cursor].total_size = r;
1663			if (client->dataset[cursor].begin_position +
1664			    client->dataset[cursor].total_size - 1 > offset ||
1665			    cursor + 1 >= client->nodes)
1666				break;
1667			r = client->dataset[cursor].begin_position +
1668				client->dataset[cursor].total_size;
1669			client->dataset[++cursor].begin_position = r;
1670		}
1671		offset -= client->dataset[cursor].begin_position;
1672		if (offset < 0
1673		    || offset > client->dataset[cursor].total_size)
1674			return ARCHIVE_FATAL;
1675		if ((r = client_seek_proxy(filter, offset, SEEK_SET)) < 0)
1676			return r;
1677		break;
1678
1679	case SEEK_END:
1680		cursor = 0;
1681		while (1) {
1682			if (client->dataset[cursor].begin_position < 0 ||
1683			    client->dataset[cursor].total_size < 0 ||
1684			    cursor + 1 >= client->nodes)
1685				break;
1686			r = client->dataset[cursor].begin_position +
1687				client->dataset[cursor].total_size;
1688			client->dataset[++cursor].begin_position = r;
1689		}
1690		while (1) {
1691			r = client_switch_proxy(filter, cursor);
1692			if (r != ARCHIVE_OK)
1693				return r;
1694			if ((r = client_seek_proxy(filter, 0, SEEK_END)) < 0)
1695				return r;
1696			client->dataset[cursor].total_size = r;
1697			r = client->dataset[cursor].begin_position +
1698				client->dataset[cursor].total_size;
1699			if (cursor + 1 >= client->nodes)
1700				break;
1701			client->dataset[++cursor].begin_position = r;
1702		}
1703		while (1) {
1704			if (r + offset >=
1705			    client->dataset[cursor].begin_position)
1706				break;
1707			offset += client->dataset[cursor].total_size;
1708			if (cursor == 0)
1709				break;
1710			cursor--;
1711			r = client->dataset[cursor].begin_position +
1712				client->dataset[cursor].total_size;
1713		}
1714		offset = (r + offset) - client->dataset[cursor].begin_position;
1715		if ((r = client_switch_proxy(filter, cursor)) != ARCHIVE_OK)
1716			return r;
1717		r = client_seek_proxy(filter, offset, SEEK_SET);
1718		if (r < ARCHIVE_OK)
1719			return r;
1720		break;
1721
1722	default:
1723		return (ARCHIVE_FATAL);
1724	}
1725	r += client->dataset[cursor].begin_position;
1726
1727	if (r >= 0) {
1728		/*
1729		 * Ouch.  Clearing the buffer like this hurts, especially
1730		 * at bid time.  A lot of our efficiency at bid time comes
1731		 * from having bidders reuse the data we've already read.
1732		 *
1733		 * TODO: If the seek request is in data we already
1734		 * have, then don't call the seek callback.
1735		 *
1736		 * TODO: Zip seeks to end-of-file at bid time.  If
1737		 * other formats also start doing this, we may need to
1738		 * find a way for clients to fudge the seek offset to
1739		 * a block boundary.
1740		 *
1741		 * Hmmm... If whence was SEEK_END, we know the file
1742		 * size is (r - offset).  Can we use that to simplify
1743		 * the TODO items above?
1744		 */
1745		filter->avail = filter->client_avail = 0;
1746		filter->next = filter->buffer;
1747		filter->position = r;
1748		filter->end_of_file = 0;
1749	}
1750	return r;
1751}
1752