archive_read.c revision 238856
1228753Smm/*- 2232153Smm * Copyright (c) 2003-2011 Tim Kientzle 3228753Smm * All rights reserved. 4228753Smm * 5228753Smm * Redistribution and use in source and binary forms, with or without 6228753Smm * modification, are permitted provided that the following conditions 7228753Smm * are met: 8228753Smm * 1. Redistributions of source code must retain the above copyright 9228753Smm * notice, this list of conditions and the following disclaimer. 10228753Smm * 2. Redistributions in binary form must reproduce the above copyright 11228753Smm * notice, this list of conditions and the following disclaimer in the 12228753Smm * documentation and/or other materials provided with the distribution. 13228753Smm * 14228753Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15228753Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16228753Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17228753Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18228753Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19228753Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20228753Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21228753Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22228753Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23228753Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24228753Smm */ 25228753Smm 26228753Smm/* 27228753Smm * This file contains the "essential" portions of the read API, that 28228753Smm * is, stuff that will probably always be used by any client that 29228753Smm * actually needs to read an archive. Optional pieces have been, as 30228753Smm * far as possible, separated out into separate files to avoid 31228753Smm * needlessly bloating statically-linked clients. 32228753Smm */ 33228753Smm 34228753Smm#include "archive_platform.h" 35228763Smm__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_read.c 238856 2012-07-28 06:38:44Z mm $"); 36228753Smm 37228753Smm#ifdef HAVE_ERRNO_H 38228753Smm#include <errno.h> 39228753Smm#endif 40228753Smm#include <stdio.h> 41228753Smm#ifdef HAVE_STDLIB_H 42228753Smm#include <stdlib.h> 43228753Smm#endif 44228753Smm#ifdef HAVE_STRING_H 45228753Smm#include <string.h> 46228753Smm#endif 47228753Smm#ifdef HAVE_UNISTD_H 48228753Smm#include <unistd.h> 49228753Smm#endif 50228753Smm 51228753Smm#include "archive.h" 52228753Smm#include "archive_entry.h" 53228753Smm#include "archive_private.h" 54228753Smm#include "archive_read_private.h" 55228753Smm 56228753Smm#define minimum(a, b) (a < b ? a : b) 57228753Smm 58232153Smmstatic int choose_filters(struct archive_read *); 59228753Smmstatic int choose_format(struct archive_read *); 60232153Smmstatic void free_filters(struct archive_read *); 61232153Smmstatic int close_filters(struct archive_read *); 62228753Smmstatic struct archive_vtable *archive_read_vtable(void); 63232153Smmstatic int64_t _archive_filter_bytes(struct archive *, int); 64232153Smmstatic int _archive_filter_code(struct archive *, int); 65232153Smmstatic const char *_archive_filter_name(struct archive *, int); 66232153Smmstatic int _archive_filter_count(struct archive *); 67228753Smmstatic int _archive_read_close(struct archive *); 68232153Smmstatic int _archive_read_data_block(struct archive *, 69232153Smm const void **, size_t *, int64_t *); 70228773Smmstatic int _archive_read_free(struct archive *); 71232153Smmstatic int _archive_read_next_header(struct archive *, 72232153Smm struct archive_entry **); 73232153Smmstatic int _archive_read_next_header2(struct archive *, 74232153Smm struct archive_entry *); 75232153Smmstatic int64_t advance_file_pointer(struct archive_read_filter *, int64_t); 76228753Smm 77228753Smmstatic struct archive_vtable * 78228753Smmarchive_read_vtable(void) 79228753Smm{ 80228753Smm static struct archive_vtable av; 81228753Smm static int inited = 0; 82228753Smm 83228753Smm if (!inited) { 84232153Smm av.archive_filter_bytes = _archive_filter_bytes; 85232153Smm av.archive_filter_code = _archive_filter_code; 86232153Smm av.archive_filter_name = _archive_filter_name; 87232153Smm av.archive_filter_count = _archive_filter_count; 88232153Smm av.archive_read_data_block = _archive_read_data_block; 89232153Smm av.archive_read_next_header = _archive_read_next_header; 90232153Smm av.archive_read_next_header2 = _archive_read_next_header2; 91228773Smm av.archive_free = _archive_read_free; 92228753Smm av.archive_close = _archive_read_close; 93232153Smm inited = 1; 94228753Smm } 95228753Smm return (&av); 96228753Smm} 97228753Smm 98228753Smm/* 99228753Smm * Allocate, initialize and return a struct archive object. 100228753Smm */ 101228753Smmstruct archive * 102228753Smmarchive_read_new(void) 103228753Smm{ 104228753Smm struct archive_read *a; 105228753Smm 106228753Smm a = (struct archive_read *)malloc(sizeof(*a)); 107228753Smm if (a == NULL) 108228753Smm return (NULL); 109228753Smm memset(a, 0, sizeof(*a)); 110228753Smm a->archive.magic = ARCHIVE_READ_MAGIC; 111228753Smm 112228753Smm a->archive.state = ARCHIVE_STATE_NEW; 113232153Smm a->entry = archive_entry_new2(&a->archive); 114228753Smm a->archive.vtable = archive_read_vtable(); 115228753Smm 116228753Smm return (&a->archive); 117228753Smm} 118228753Smm 119228753Smm/* 120228753Smm * Record the do-not-extract-to file. This belongs in archive_read_extract.c. 121228753Smm */ 122228753Smmvoid 123232153Smmarchive_read_extract_set_skip_file(struct archive *_a, int64_t d, int64_t i) 124228753Smm{ 125228753Smm struct archive_read *a = (struct archive_read *)_a; 126232153Smm 127232153Smm if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_MAGIC, 128232153Smm ARCHIVE_STATE_ANY, "archive_read_extract_set_skip_file")) 129232153Smm return; 130232153Smm a->skip_file_set = 1; 131228753Smm a->skip_file_dev = d; 132228753Smm a->skip_file_ino = i; 133228753Smm} 134228753Smm 135228753Smm/* 136232153Smm * Open the archive 137228753Smm */ 138228753Smmint 139232153Smmarchive_read_open(struct archive *a, void *client_data, 140232153Smm archive_open_callback *client_opener, archive_read_callback *client_reader, 141232153Smm archive_close_callback *client_closer) 142228753Smm{ 143232153Smm /* Old archive_read_open() is just a thin shell around 144232153Smm * archive_read_open1. */ 145232153Smm archive_read_set_open_callback(a, client_opener); 146232153Smm archive_read_set_read_callback(a, client_reader); 147232153Smm archive_read_set_close_callback(a, client_closer); 148232153Smm archive_read_set_callback_data(a, client_data); 149232153Smm return archive_read_open1(a); 150228753Smm} 151228753Smm 152228753Smm 153228753Smmint 154232153Smmarchive_read_open2(struct archive *a, void *client_data, 155232153Smm archive_open_callback *client_opener, 156232153Smm archive_read_callback *client_reader, 157232153Smm archive_skip_callback *client_skipper, 158228753Smm archive_close_callback *client_closer) 159228753Smm{ 160232153Smm /* Old archive_read_open2() is just a thin shell around 161232153Smm * archive_read_open1. */ 162232153Smm archive_read_set_callback_data(a, client_data); 163232153Smm archive_read_set_open_callback(a, client_opener); 164232153Smm archive_read_set_read_callback(a, client_reader); 165232153Smm archive_read_set_skip_callback(a, client_skipper); 166232153Smm archive_read_set_close_callback(a, client_closer); 167232153Smm return archive_read_open1(a); 168228753Smm} 169228753Smm 170228753Smmstatic ssize_t 171228753Smmclient_read_proxy(struct archive_read_filter *self, const void **buff) 172228753Smm{ 173228753Smm ssize_t r; 174228753Smm r = (self->archive->client.reader)(&self->archive->archive, 175228753Smm self->data, buff); 176228753Smm return (r); 177228753Smm} 178228753Smm 179228753Smmstatic int64_t 180228753Smmclient_skip_proxy(struct archive_read_filter *self, int64_t request) 181228753Smm{ 182232153Smm if (request < 0) 183232153Smm __archive_errx(1, "Negative skip requested."); 184232153Smm if (request == 0) 185232153Smm return 0; 186228753Smm 187232153Smm if (self->archive->client.skipper != NULL) { 188232153Smm /* Seek requests over 1GiB are broken down into 189232153Smm * multiple seeks. This avoids overflows when the 190232153Smm * requests get passed through 32-bit arguments. */ 191232153Smm int64_t skip_limit = (int64_t)1 << 30; 192232153Smm int64_t total = 0; 193232153Smm for (;;) { 194232153Smm int64_t get, ask = request; 195232153Smm if (ask > skip_limit) 196232153Smm ask = skip_limit; 197232153Smm get = (self->archive->client.skipper)(&self->archive->archive, 198232153Smm self->data, ask); 199232153Smm if (get == 0) 200232153Smm return (total); 201232153Smm request -= get; 202232153Smm total += get; 203232153Smm } 204232153Smm } else if (self->archive->client.seeker != NULL 205232153Smm && request > 64 * 1024) { 206232153Smm /* If the client provided a seeker but not a skipper, 207232153Smm * we can use the seeker to skip forward. 208232153Smm * 209232153Smm * Note: This isn't always a good idea. The client 210232153Smm * skipper is allowed to skip by less than requested 211232153Smm * if it needs to maintain block alignment. The 212232153Smm * seeker is not allowed to play such games, so using 213232153Smm * the seeker here may be a performance loss compared 214232153Smm * to just reading and discarding. That's why we 215232153Smm * only do this for skips of over 64k. 216232153Smm */ 217232153Smm int64_t before = self->position; 218232153Smm int64_t after = (self->archive->client.seeker)(&self->archive->archive, 219232153Smm self->data, request, SEEK_CUR); 220232153Smm if (after != before + request) 221232153Smm return ARCHIVE_FATAL; 222232153Smm return after - before; 223228753Smm } 224232153Smm return 0; 225228753Smm} 226228753Smm 227232153Smmstatic int64_t 228232153Smmclient_seek_proxy(struct archive_read_filter *self, int64_t offset, int whence) 229232153Smm{ 230232153Smm /* DO NOT use the skipper here! If we transparently handled 231232153Smm * forward seek here by using the skipper, that will break 232232153Smm * other libarchive code that assumes a successful forward 233232153Smm * seek means it can also seek backwards. 234232153Smm */ 235232153Smm if (self->archive->client.seeker == NULL) 236232153Smm return (ARCHIVE_FAILED); 237232153Smm return (self->archive->client.seeker)(&self->archive->archive, 238232153Smm self->data, offset, whence); 239232153Smm} 240232153Smm 241228753Smmstatic int 242228753Smmclient_close_proxy(struct archive_read_filter *self) 243228753Smm{ 244228753Smm int r = ARCHIVE_OK; 245228753Smm 246228753Smm if (self->archive->client.closer != NULL) 247228753Smm r = (self->archive->client.closer)((struct archive *)self->archive, 248228753Smm self->data); 249228753Smm return (r); 250228753Smm} 251228753Smm 252232153Smmint 253232153Smmarchive_read_set_open_callback(struct archive *_a, 254232153Smm archive_open_callback *client_opener) 255232153Smm{ 256232153Smm struct archive_read *a = (struct archive_read *)_a; 257232153Smm archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, 258232153Smm "archive_read_set_open_callback"); 259232153Smm a->client.opener = client_opener; 260232153Smm return ARCHIVE_OK; 261232153Smm} 262228753Smm 263228753Smmint 264232153Smmarchive_read_set_read_callback(struct archive *_a, 265232153Smm archive_read_callback *client_reader) 266232153Smm{ 267232153Smm struct archive_read *a = (struct archive_read *)_a; 268232153Smm archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, 269232153Smm "archive_read_set_read_callback"); 270232153Smm a->client.reader = client_reader; 271232153Smm return ARCHIVE_OK; 272232153Smm} 273232153Smm 274232153Smmint 275232153Smmarchive_read_set_skip_callback(struct archive *_a, 276232153Smm archive_skip_callback *client_skipper) 277232153Smm{ 278232153Smm struct archive_read *a = (struct archive_read *)_a; 279232153Smm archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, 280232153Smm "archive_read_set_skip_callback"); 281232153Smm a->client.skipper = client_skipper; 282232153Smm return ARCHIVE_OK; 283232153Smm} 284232153Smm 285232153Smmint 286232153Smmarchive_read_set_seek_callback(struct archive *_a, 287232153Smm archive_seek_callback *client_seeker) 288232153Smm{ 289232153Smm struct archive_read *a = (struct archive_read *)_a; 290232153Smm archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, 291232153Smm "archive_read_set_seek_callback"); 292232153Smm a->client.seeker = client_seeker; 293232153Smm return ARCHIVE_OK; 294232153Smm} 295232153Smm 296232153Smmint 297232153Smmarchive_read_set_close_callback(struct archive *_a, 298228753Smm archive_close_callback *client_closer) 299228753Smm{ 300228753Smm struct archive_read *a = (struct archive_read *)_a; 301232153Smm archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, 302232153Smm "archive_read_set_close_callback"); 303232153Smm a->client.closer = client_closer; 304232153Smm return ARCHIVE_OK; 305232153Smm} 306232153Smm 307232153Smmint 308232153Smmarchive_read_set_callback_data(struct archive *_a, void *client_data) 309232153Smm{ 310232153Smm struct archive_read *a = (struct archive_read *)_a; 311232153Smm archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, 312232153Smm "archive_read_set_callback_data"); 313232153Smm a->client.data = client_data; 314232153Smm return ARCHIVE_OK; 315232153Smm} 316232153Smm 317232153Smmint 318232153Smmarchive_read_open1(struct archive *_a) 319232153Smm{ 320232153Smm struct archive_read *a = (struct archive_read *)_a; 321228753Smm struct archive_read_filter *filter; 322232153Smm int slot, e; 323228753Smm 324232153Smm archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, 325228753Smm "archive_read_open"); 326228753Smm archive_clear_error(&a->archive); 327228753Smm 328232153Smm if (a->client.reader == NULL) { 329232153Smm archive_set_error(&a->archive, EINVAL, 330228753Smm "No reader function provided to archive_read_open"); 331232153Smm a->archive.state = ARCHIVE_STATE_FATAL; 332232153Smm return (ARCHIVE_FATAL); 333232153Smm } 334228753Smm 335228753Smm /* Open data source. */ 336232153Smm if (a->client.opener != NULL) { 337232153Smm e =(a->client.opener)(&a->archive, a->client.data); 338228753Smm if (e != 0) { 339228753Smm /* If the open failed, call the closer to clean up. */ 340232153Smm if (a->client.closer) 341232153Smm (a->client.closer)(&a->archive, a->client.data); 342228753Smm return (e); 343228753Smm } 344228753Smm } 345228753Smm 346228753Smm filter = calloc(1, sizeof(*filter)); 347228753Smm if (filter == NULL) 348228753Smm return (ARCHIVE_FATAL); 349228753Smm filter->bidder = NULL; 350228753Smm filter->upstream = NULL; 351228753Smm filter->archive = a; 352232153Smm filter->data = a->client.data; 353228753Smm filter->read = client_read_proxy; 354228753Smm filter->skip = client_skip_proxy; 355232153Smm filter->seek = client_seek_proxy; 356228753Smm filter->close = client_close_proxy; 357228753Smm filter->name = "none"; 358228753Smm filter->code = ARCHIVE_COMPRESSION_NONE; 359228753Smm a->filter = filter; 360228753Smm 361228753Smm /* Build out the input pipeline. */ 362232153Smm e = choose_filters(a); 363232153Smm if (e < ARCHIVE_WARN) { 364232153Smm a->archive.state = ARCHIVE_STATE_FATAL; 365232153Smm return (ARCHIVE_FATAL); 366232153Smm } 367228753Smm 368232153Smm slot = choose_format(a); 369232153Smm if (slot < 0) { 370232153Smm close_filters(a); 371232153Smm a->archive.state = ARCHIVE_STATE_FATAL; 372232153Smm return (ARCHIVE_FATAL); 373232153Smm } 374232153Smm a->format = &(a->formats[slot]); 375232153Smm 376232153Smm a->archive.state = ARCHIVE_STATE_HEADER; 377228753Smm return (e); 378228753Smm} 379228753Smm 380228753Smm/* 381228753Smm * Allow each registered stream transform to bid on whether 382228753Smm * it wants to handle this stream. Repeat until we've finished 383228753Smm * building the pipeline. 384228753Smm */ 385228753Smmstatic int 386232153Smmchoose_filters(struct archive_read *a) 387228753Smm{ 388228753Smm int number_bidders, i, bid, best_bid; 389228753Smm struct archive_read_filter_bidder *bidder, *best_bidder; 390228753Smm struct archive_read_filter *filter; 391228753Smm ssize_t avail; 392228753Smm int r; 393228753Smm 394228753Smm for (;;) { 395228753Smm number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]); 396228753Smm 397228753Smm best_bid = 0; 398228753Smm best_bidder = NULL; 399228753Smm 400228753Smm bidder = a->bidders; 401228753Smm for (i = 0; i < number_bidders; i++, bidder++) { 402228753Smm if (bidder->bid != NULL) { 403228753Smm bid = (bidder->bid)(bidder, a->filter); 404228753Smm if (bid > best_bid) { 405228753Smm best_bid = bid; 406228753Smm best_bidder = bidder; 407228753Smm } 408228753Smm } 409228753Smm } 410228753Smm 411228753Smm /* If no bidder, we're done. */ 412228753Smm if (best_bidder == NULL) { 413232153Smm /* Verify the filter by asking it for some data. */ 414228753Smm __archive_read_filter_ahead(a->filter, 1, &avail); 415228753Smm if (avail < 0) { 416232153Smm close_filters(a); 417232153Smm free_filters(a); 418228753Smm return (ARCHIVE_FATAL); 419228753Smm } 420228753Smm a->archive.compression_name = a->filter->name; 421228753Smm a->archive.compression_code = a->filter->code; 422228753Smm return (ARCHIVE_OK); 423228753Smm } 424228753Smm 425228753Smm filter 426228753Smm = (struct archive_read_filter *)calloc(1, sizeof(*filter)); 427228753Smm if (filter == NULL) 428228753Smm return (ARCHIVE_FATAL); 429228753Smm filter->bidder = best_bidder; 430228753Smm filter->archive = a; 431228753Smm filter->upstream = a->filter; 432228753Smm a->filter = filter; 433228753Smm r = (best_bidder->init)(a->filter); 434228753Smm if (r != ARCHIVE_OK) { 435232153Smm close_filters(a); 436232153Smm free_filters(a); 437232153Smm return (ARCHIVE_FATAL); 438228753Smm } 439228753Smm } 440228753Smm} 441228753Smm 442228753Smm/* 443228753Smm * Read header of next entry. 444228753Smm */ 445232153Smmstatic int 446232153Smm_archive_read_next_header2(struct archive *_a, struct archive_entry *entry) 447228753Smm{ 448228753Smm struct archive_read *a = (struct archive_read *)_a; 449232153Smm int r1 = ARCHIVE_OK, r2; 450228753Smm 451232153Smm archive_check_magic(_a, ARCHIVE_READ_MAGIC, 452228753Smm ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, 453228753Smm "archive_read_next_header"); 454228753Smm 455228753Smm archive_entry_clear(entry); 456228753Smm archive_clear_error(&a->archive); 457228753Smm 458228753Smm /* 459228753Smm * If client didn't consume entire data, skip any remainder 460228753Smm * (This is especially important for GNU incremental directories.) 461228753Smm */ 462228753Smm if (a->archive.state == ARCHIVE_STATE_DATA) { 463232153Smm r1 = archive_read_data_skip(&a->archive); 464232153Smm if (r1 == ARCHIVE_EOF) 465232153Smm archive_set_error(&a->archive, EIO, 466232153Smm "Premature end-of-file."); 467232153Smm if (r1 == ARCHIVE_EOF || r1 == ARCHIVE_FATAL) { 468228753Smm a->archive.state = ARCHIVE_STATE_FATAL; 469228753Smm return (ARCHIVE_FATAL); 470228753Smm } 471228753Smm } 472228753Smm 473232153Smm /* Record start-of-header offset in uncompressed stream. */ 474232153Smm a->header_position = a->filter->position; 475228753Smm 476232153Smm ++_a->file_count; 477232153Smm r2 = (a->format->read_header)(a, entry); 478228753Smm 479228753Smm /* 480228753Smm * EOF and FATAL are persistent at this layer. By 481228753Smm * modifying the state, we guarantee that future calls to 482228753Smm * read a header or read data will fail. 483228753Smm */ 484232153Smm switch (r2) { 485228753Smm case ARCHIVE_EOF: 486228753Smm a->archive.state = ARCHIVE_STATE_EOF; 487232153Smm --_a->file_count;/* Revert a file counter. */ 488228753Smm break; 489228753Smm case ARCHIVE_OK: 490228753Smm a->archive.state = ARCHIVE_STATE_DATA; 491228753Smm break; 492228753Smm case ARCHIVE_WARN: 493228753Smm a->archive.state = ARCHIVE_STATE_DATA; 494228753Smm break; 495228753Smm case ARCHIVE_RETRY: 496228753Smm break; 497228753Smm case ARCHIVE_FATAL: 498228753Smm a->archive.state = ARCHIVE_STATE_FATAL; 499228753Smm break; 500228753Smm } 501228753Smm 502228753Smm a->read_data_output_offset = 0; 503228753Smm a->read_data_remaining = 0; 504232153Smm /* EOF always wins; otherwise return the worst error. */ 505232153Smm return (r2 < r1 || r2 == ARCHIVE_EOF) ? r2 : r1; 506228753Smm} 507228753Smm 508228753Smmint 509232153Smm_archive_read_next_header(struct archive *_a, struct archive_entry **entryp) 510228753Smm{ 511228753Smm int ret; 512228753Smm struct archive_read *a = (struct archive_read *)_a; 513228753Smm *entryp = NULL; 514232153Smm ret = _archive_read_next_header2(_a, a->entry); 515228753Smm *entryp = a->entry; 516228753Smm return ret; 517228753Smm} 518228753Smm 519228753Smm/* 520228753Smm * Allow each registered format to bid on whether it wants to handle 521228753Smm * the next entry. Return index of winning bidder. 522228753Smm */ 523228753Smmstatic int 524228753Smmchoose_format(struct archive_read *a) 525228753Smm{ 526228753Smm int slots; 527228753Smm int i; 528228753Smm int bid, best_bid; 529228753Smm int best_bid_slot; 530228753Smm 531228753Smm slots = sizeof(a->formats) / sizeof(a->formats[0]); 532228753Smm best_bid = -1; 533228753Smm best_bid_slot = -1; 534228753Smm 535232153Smm /* Set up a->format for convenience of bidders. */ 536228753Smm a->format = &(a->formats[0]); 537228753Smm for (i = 0; i < slots; i++, a->format++) { 538228753Smm if (a->format->bid) { 539232153Smm bid = (a->format->bid)(a, best_bid); 540228753Smm if (bid == ARCHIVE_FATAL) 541228753Smm return (ARCHIVE_FATAL); 542232153Smm if (a->filter->position != 0) 543232153Smm __archive_read_seek(a, 0, SEEK_SET); 544228753Smm if ((bid > best_bid) || (best_bid_slot < 0)) { 545228753Smm best_bid = bid; 546228753Smm best_bid_slot = i; 547228753Smm } 548228753Smm } 549228753Smm } 550228753Smm 551228753Smm /* 552228753Smm * There were no bidders; this is a serious programmer error 553228753Smm * and demands a quick and definitive abort. 554228753Smm */ 555232153Smm if (best_bid_slot < 0) { 556232153Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 557232153Smm "No formats registered"); 558232153Smm return (ARCHIVE_FATAL); 559232153Smm } 560228753Smm 561228753Smm /* 562228753Smm * There were bidders, but no non-zero bids; this means we 563228753Smm * can't support this stream. 564228753Smm */ 565228753Smm if (best_bid < 1) { 566228753Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 567228753Smm "Unrecognized archive format"); 568228753Smm return (ARCHIVE_FATAL); 569228753Smm } 570228753Smm 571228753Smm return (best_bid_slot); 572228753Smm} 573228753Smm 574228753Smm/* 575228753Smm * Return the file offset (within the uncompressed data stream) where 576228753Smm * the last header started. 577228753Smm */ 578228753Smmint64_t 579228753Smmarchive_read_header_position(struct archive *_a) 580228753Smm{ 581228753Smm struct archive_read *a = (struct archive_read *)_a; 582232153Smm archive_check_magic(_a, ARCHIVE_READ_MAGIC, 583228753Smm ARCHIVE_STATE_ANY, "archive_read_header_position"); 584228753Smm return (a->header_position); 585228753Smm} 586228753Smm 587228753Smm/* 588228753Smm * Read data from an archive entry, using a read(2)-style interface. 589228753Smm * This is a convenience routine that just calls 590228753Smm * archive_read_data_block and copies the results into the client 591228753Smm * buffer, filling any gaps with zero bytes. Clients using this 592228753Smm * API can be completely ignorant of sparse-file issues; sparse files 593228753Smm * will simply be padded with nulls. 594228753Smm * 595228753Smm * DO NOT intermingle calls to this function and archive_read_data_block 596228753Smm * to read a single entry body. 597228753Smm */ 598228753Smmssize_t 599228753Smmarchive_read_data(struct archive *_a, void *buff, size_t s) 600228753Smm{ 601228753Smm struct archive_read *a = (struct archive_read *)_a; 602228753Smm char *dest; 603228753Smm const void *read_buf; 604228753Smm size_t bytes_read; 605228753Smm size_t len; 606228753Smm int r; 607228753Smm 608228753Smm bytes_read = 0; 609228753Smm dest = (char *)buff; 610228753Smm 611228753Smm while (s > 0) { 612228753Smm if (a->read_data_remaining == 0) { 613228753Smm read_buf = a->read_data_block; 614232153Smm r = _archive_read_data_block(&a->archive, &read_buf, 615228753Smm &a->read_data_remaining, &a->read_data_offset); 616228753Smm a->read_data_block = read_buf; 617228753Smm if (r == ARCHIVE_EOF) 618228753Smm return (bytes_read); 619228753Smm /* 620228753Smm * Error codes are all negative, so the status 621228753Smm * return here cannot be confused with a valid 622228753Smm * byte count. (ARCHIVE_OK is zero.) 623228753Smm */ 624228753Smm if (r < ARCHIVE_OK) 625228753Smm return (r); 626228753Smm } 627228753Smm 628228753Smm if (a->read_data_offset < a->read_data_output_offset) { 629228753Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 630228753Smm "Encountered out-of-order sparse blocks"); 631228753Smm return (ARCHIVE_RETRY); 632228753Smm } 633228753Smm 634228753Smm /* Compute the amount of zero padding needed. */ 635232153Smm if (a->read_data_output_offset + (int64_t)s < 636228753Smm a->read_data_offset) { 637228753Smm len = s; 638228753Smm } else if (a->read_data_output_offset < 639228753Smm a->read_data_offset) { 640238856Smm len = (size_t)(a->read_data_offset - 641238856Smm a->read_data_output_offset); 642228753Smm } else 643228753Smm len = 0; 644228753Smm 645228753Smm /* Add zeroes. */ 646228753Smm memset(dest, 0, len); 647228753Smm s -= len; 648228753Smm a->read_data_output_offset += len; 649228753Smm dest += len; 650228753Smm bytes_read += len; 651228753Smm 652228753Smm /* Copy data if there is any space left. */ 653228753Smm if (s > 0) { 654228753Smm len = a->read_data_remaining; 655228753Smm if (len > s) 656228753Smm len = s; 657228753Smm memcpy(dest, a->read_data_block, len); 658228753Smm s -= len; 659228753Smm a->read_data_block += len; 660228753Smm a->read_data_remaining -= len; 661228753Smm a->read_data_output_offset += len; 662228753Smm a->read_data_offset += len; 663228753Smm dest += len; 664228753Smm bytes_read += len; 665228753Smm } 666228753Smm } 667228753Smm return (bytes_read); 668228753Smm} 669228753Smm 670228753Smm/* 671228753Smm * Skip over all remaining data in this entry. 672228753Smm */ 673228753Smmint 674228753Smmarchive_read_data_skip(struct archive *_a) 675228753Smm{ 676228753Smm struct archive_read *a = (struct archive_read *)_a; 677228753Smm int r; 678228753Smm const void *buff; 679228753Smm size_t size; 680232153Smm int64_t offset; 681228753Smm 682232153Smm archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA, 683228753Smm "archive_read_data_skip"); 684228753Smm 685228753Smm if (a->format->read_data_skip != NULL) 686228753Smm r = (a->format->read_data_skip)(a); 687228753Smm else { 688228753Smm while ((r = archive_read_data_block(&a->archive, 689228753Smm &buff, &size, &offset)) 690228753Smm == ARCHIVE_OK) 691228753Smm ; 692228753Smm } 693228753Smm 694228753Smm if (r == ARCHIVE_EOF) 695228753Smm r = ARCHIVE_OK; 696228753Smm 697228753Smm a->archive.state = ARCHIVE_STATE_HEADER; 698228753Smm return (r); 699228753Smm} 700228753Smm 701228753Smm/* 702228753Smm * Read the next block of entry data from the archive. 703228753Smm * This is a zero-copy interface; the client receives a pointer, 704228753Smm * size, and file offset of the next available block of data. 705228753Smm * 706228753Smm * Returns ARCHIVE_OK if the operation is successful, ARCHIVE_EOF if 707228753Smm * the end of entry is encountered. 708228753Smm */ 709232153Smmstatic int 710232153Smm_archive_read_data_block(struct archive *_a, 711232153Smm const void **buff, size_t *size, int64_t *offset) 712228753Smm{ 713228753Smm struct archive_read *a = (struct archive_read *)_a; 714232153Smm archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA, 715228753Smm "archive_read_data_block"); 716228753Smm 717228753Smm if (a->format->read_data == NULL) { 718228753Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, 719228753Smm "Internal error: " 720228753Smm "No format_read_data_block function registered"); 721228753Smm return (ARCHIVE_FATAL); 722228753Smm } 723228753Smm 724228753Smm return (a->format->read_data)(a, buff, size, offset); 725228753Smm} 726228753Smm 727232153Smmstatic int 728232153Smmclose_filters(struct archive_read *a) 729232153Smm{ 730232153Smm struct archive_read_filter *f = a->filter; 731232153Smm int r = ARCHIVE_OK; 732232153Smm /* Close each filter in the pipeline. */ 733232153Smm while (f != NULL) { 734232153Smm struct archive_read_filter *t = f->upstream; 735232153Smm if (!f->closed && f->close != NULL) { 736232153Smm int r1 = (f->close)(f); 737232153Smm f->closed = 1; 738232153Smm if (r1 < r) 739232153Smm r = r1; 740232153Smm } 741232153Smm free(f->buffer); 742232153Smm f->buffer = NULL; 743232153Smm f = t; 744232153Smm } 745232153Smm return r; 746232153Smm} 747232153Smm 748232153Smmstatic void 749232153Smmfree_filters(struct archive_read *a) 750232153Smm{ 751232153Smm while (a->filter != NULL) { 752232153Smm struct archive_read_filter *t = a->filter->upstream; 753232153Smm free(a->filter); 754232153Smm a->filter = t; 755232153Smm } 756232153Smm} 757232153Smm 758228753Smm/* 759232153Smm * return the count of # of filters in use 760228753Smm */ 761228753Smmstatic int 762232153Smm_archive_filter_count(struct archive *_a) 763232153Smm{ 764232153Smm struct archive_read *a = (struct archive_read *)_a; 765232153Smm struct archive_read_filter *p = a->filter; 766232153Smm int count = 0; 767232153Smm while(p) { 768232153Smm count++; 769232153Smm p = p->upstream; 770232153Smm } 771232153Smm return count; 772232153Smm} 773232153Smm 774232153Smm/* 775232153Smm * Close the file and all I/O. 776232153Smm */ 777232153Smmstatic int 778228753Smm_archive_read_close(struct archive *_a) 779228753Smm{ 780228753Smm struct archive_read *a = (struct archive_read *)_a; 781228753Smm int r = ARCHIVE_OK, r1 = ARCHIVE_OK; 782228753Smm 783232153Smm archive_check_magic(&a->archive, ARCHIVE_READ_MAGIC, 784232153Smm ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_close"); 785232153Smm if (a->archive.state == ARCHIVE_STATE_CLOSED) 786232153Smm return (ARCHIVE_OK); 787228753Smm archive_clear_error(&a->archive); 788228753Smm a->archive.state = ARCHIVE_STATE_CLOSED; 789228753Smm 790228753Smm /* TODO: Clean up the formatters. */ 791228753Smm 792228753Smm /* Release the filter objects. */ 793232153Smm r1 = close_filters(a); 794228753Smm if (r1 < r) 795228753Smm r = r1; 796228753Smm 797228753Smm return (r); 798228753Smm} 799228753Smm 800228753Smm/* 801228753Smm * Release memory and other resources. 802228753Smm */ 803228753Smmstatic int 804228773Smm_archive_read_free(struct archive *_a) 805228753Smm{ 806228753Smm struct archive_read *a = (struct archive_read *)_a; 807232153Smm int i, n; 808228753Smm int slots; 809228753Smm int r = ARCHIVE_OK; 810228753Smm 811232153Smm if (_a == NULL) 812232153Smm return (ARCHIVE_OK); 813232153Smm archive_check_magic(_a, ARCHIVE_READ_MAGIC, 814232153Smm ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_free"); 815232153Smm if (a->archive.state != ARCHIVE_STATE_CLOSED 816232153Smm && a->archive.state != ARCHIVE_STATE_FATAL) 817228753Smm r = archive_read_close(&a->archive); 818228753Smm 819232153Smm /* Call cleanup functions registered by optional components. */ 820232153Smm if (a->cleanup_archive_extract != NULL) 821232153Smm r = (a->cleanup_archive_extract)(a); 822232153Smm 823228753Smm /* Cleanup format-specific data. */ 824228753Smm slots = sizeof(a->formats) / sizeof(a->formats[0]); 825228753Smm for (i = 0; i < slots; i++) { 826228753Smm a->format = &(a->formats[i]); 827228753Smm if (a->formats[i].cleanup) 828228753Smm (a->formats[i].cleanup)(a); 829228753Smm } 830228753Smm 831232153Smm /* Free the filters */ 832232153Smm free_filters(a); 833232153Smm 834232153Smm /* Release the bidder objects. */ 835232153Smm n = sizeof(a->bidders)/sizeof(a->bidders[0]); 836232153Smm for (i = 0; i < n; i++) { 837232153Smm if (a->bidders[i].free != NULL) { 838232153Smm int r1 = (a->bidders[i].free)(&a->bidders[i]); 839232153Smm if (r1 < r) 840232153Smm r = r1; 841232153Smm } 842232153Smm } 843232153Smm 844228753Smm archive_string_free(&a->archive.error_string); 845228753Smm if (a->entry) 846228753Smm archive_entry_free(a->entry); 847228753Smm a->archive.magic = 0; 848232153Smm __archive_clean(&a->archive); 849228753Smm free(a); 850228753Smm return (r); 851228753Smm} 852228753Smm 853232153Smmstatic struct archive_read_filter * 854232153Smmget_filter(struct archive *_a, int n) 855232153Smm{ 856232153Smm struct archive_read *a = (struct archive_read *)_a; 857232153Smm struct archive_read_filter *f = a->filter; 858232153Smm /* We use n == -1 for 'the last filter', which is always the client proxy. */ 859232153Smm if (n == -1 && f != NULL) { 860232153Smm struct archive_read_filter *last = f; 861232153Smm f = f->upstream; 862232153Smm while (f != NULL) { 863232153Smm last = f; 864232153Smm f = f->upstream; 865232153Smm } 866232153Smm return (last); 867232153Smm } 868232153Smm if (n < 0) 869232153Smm return NULL; 870232153Smm while (n > 0 && f != NULL) { 871232153Smm f = f->upstream; 872232153Smm --n; 873232153Smm } 874232153Smm return (f); 875232153Smm} 876232153Smm 877232153Smmstatic int 878232153Smm_archive_filter_code(struct archive *_a, int n) 879232153Smm{ 880232153Smm struct archive_read_filter *f = get_filter(_a, n); 881232153Smm return f == NULL ? -1 : f->code; 882232153Smm} 883232153Smm 884232153Smmstatic const char * 885232153Smm_archive_filter_name(struct archive *_a, int n) 886232153Smm{ 887232153Smm struct archive_read_filter *f = get_filter(_a, n); 888232153Smm return f == NULL ? NULL : f->name; 889232153Smm} 890232153Smm 891232153Smmstatic int64_t 892232153Smm_archive_filter_bytes(struct archive *_a, int n) 893232153Smm{ 894232153Smm struct archive_read_filter *f = get_filter(_a, n); 895232153Smm return f == NULL ? -1 : f->position; 896232153Smm} 897232153Smm 898228753Smm/* 899228753Smm * Used internally by read format handlers to register their bid and 900228753Smm * initialization functions. 901228753Smm */ 902228753Smmint 903228753Smm__archive_read_register_format(struct archive_read *a, 904228753Smm void *format_data, 905228753Smm const char *name, 906232153Smm int (*bid)(struct archive_read *, int), 907228753Smm int (*options)(struct archive_read *, const char *, const char *), 908228753Smm int (*read_header)(struct archive_read *, struct archive_entry *), 909232153Smm int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *), 910228753Smm int (*read_data_skip)(struct archive_read *), 911228753Smm int (*cleanup)(struct archive_read *)) 912228753Smm{ 913228753Smm int i, number_slots; 914228753Smm 915232153Smm archive_check_magic(&a->archive, 916228753Smm ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, 917228753Smm "__archive_read_register_format"); 918228753Smm 919228753Smm number_slots = sizeof(a->formats) / sizeof(a->formats[0]); 920228753Smm 921228753Smm for (i = 0; i < number_slots; i++) { 922228753Smm if (a->formats[i].bid == bid) 923228753Smm return (ARCHIVE_WARN); /* We've already installed */ 924228753Smm if (a->formats[i].bid == NULL) { 925228753Smm a->formats[i].bid = bid; 926228753Smm a->formats[i].options = options; 927228753Smm a->formats[i].read_header = read_header; 928228753Smm a->formats[i].read_data = read_data; 929228753Smm a->formats[i].read_data_skip = read_data_skip; 930228753Smm a->formats[i].cleanup = cleanup; 931228753Smm a->formats[i].data = format_data; 932228753Smm a->formats[i].name = name; 933228753Smm return (ARCHIVE_OK); 934228753Smm } 935228753Smm } 936228753Smm 937232153Smm archive_set_error(&a->archive, ENOMEM, 938232153Smm "Not enough slots for format registration"); 939232153Smm return (ARCHIVE_FATAL); 940228753Smm} 941228753Smm 942228753Smm/* 943228753Smm * Used internally by decompression routines to register their bid and 944228753Smm * initialization functions. 945228753Smm */ 946232153Smmint 947232153Smm__archive_read_get_bidder(struct archive_read *a, 948232153Smm struct archive_read_filter_bidder **bidder) 949228753Smm{ 950228753Smm int i, number_slots; 951228753Smm 952228753Smm number_slots = sizeof(a->bidders) / sizeof(a->bidders[0]); 953228753Smm 954228753Smm for (i = 0; i < number_slots; i++) { 955228753Smm if (a->bidders[i].bid == NULL) { 956228753Smm memset(a->bidders + i, 0, sizeof(a->bidders[0])); 957232153Smm *bidder = (a->bidders + i); 958232153Smm return (ARCHIVE_OK); 959228753Smm } 960228753Smm } 961228753Smm 962232153Smm archive_set_error(&a->archive, ENOMEM, 963232153Smm "Not enough slots for filter registration"); 964232153Smm return (ARCHIVE_FATAL); 965228753Smm} 966228753Smm 967228753Smm/* 968232153Smm * The next section implements the peek/consume internal I/O 969232153Smm * system used by archive readers. This system allows simple 970232153Smm * read-ahead for consumers while preserving zero-copy operation 971232153Smm * most of the time. 972228753Smm * 973232153Smm * The two key operations: 974232153Smm * * The read-ahead function returns a pointer to a block of data 975232153Smm * that satisfies a minimum request. 976232153Smm * * The consume function advances the file pointer. 977232153Smm * 978228753Smm * In the ideal case, filters generate blocks of data 979228753Smm * and __archive_read_ahead() just returns pointers directly into 980228753Smm * those blocks. Then __archive_read_consume() just bumps those 981228753Smm * pointers. Only if your request would span blocks does the I/O 982228753Smm * layer use a copy buffer to provide you with a contiguous block of 983232153Smm * data. 984228753Smm * 985228753Smm * A couple of useful idioms: 986228753Smm * * "I just want some data." Ask for 1 byte and pay attention to 987228753Smm * the "number of bytes available" from __archive_read_ahead(). 988232153Smm * Consume whatever you actually use. 989228753Smm * * "I want to output a large block of data." As above, ask for 1 byte, 990232153Smm * emit all that's available (up to whatever limit you have), consume 991232153Smm * it all, then repeat until you're done. This effectively means that 992232153Smm * you're passing along the blocks that came from your provider. 993228753Smm * * "I want to peek ahead by a large amount." Ask for 4k or so, then 994228753Smm * double and repeat until you get an error or have enough. Note 995228753Smm * that the I/O layer will likely end up expanding its copy buffer 996228753Smm * to fit your request, so use this technique cautiously. This 997228753Smm * technique is used, for example, by some of the format tasting 998228753Smm * code that has uncertain look-ahead needs. 999228753Smm */ 1000228753Smm 1001228753Smm/* 1002228753Smm * Looks ahead in the input stream: 1003228753Smm * * If 'avail' pointer is provided, that returns number of bytes available 1004228753Smm * in the current buffer, which may be much larger than requested. 1005228753Smm * * If end-of-file, *avail gets set to zero. 1006228753Smm * * If error, *avail gets error code. 1007232153Smm * * If request can be met, returns pointer to data. 1008232153Smm * * If minimum request cannot be met, returns NULL. 1009228753Smm * 1010228753Smm * Note: If you just want "some data", ask for 1 byte and pay attention 1011228753Smm * to *avail, which will have the actual amount available. If you 1012228753Smm * know exactly how many bytes you need, just ask for that and treat 1013228753Smm * a NULL return as an error. 1014228753Smm * 1015228753Smm * Important: This does NOT move the file pointer. See 1016228753Smm * __archive_read_consume() below. 1017228753Smm */ 1018228753Smmconst void * 1019228753Smm__archive_read_ahead(struct archive_read *a, size_t min, ssize_t *avail) 1020228753Smm{ 1021228753Smm return (__archive_read_filter_ahead(a->filter, min, avail)); 1022228753Smm} 1023228753Smm 1024228753Smmconst void * 1025228753Smm__archive_read_filter_ahead(struct archive_read_filter *filter, 1026228753Smm size_t min, ssize_t *avail) 1027228753Smm{ 1028228753Smm ssize_t bytes_read; 1029228753Smm size_t tocopy; 1030228753Smm 1031228753Smm if (filter->fatal) { 1032228753Smm if (avail) 1033228753Smm *avail = ARCHIVE_FATAL; 1034228753Smm return (NULL); 1035228753Smm } 1036228753Smm 1037228753Smm /* 1038228753Smm * Keep pulling more data until we can satisfy the request. 1039228753Smm */ 1040228753Smm for (;;) { 1041228753Smm 1042228753Smm /* 1043228753Smm * If we can satisfy from the copy buffer (and the 1044228753Smm * copy buffer isn't empty), we're done. In particular, 1045228753Smm * note that min == 0 is a perfectly well-defined 1046228753Smm * request. 1047228753Smm */ 1048228753Smm if (filter->avail >= min && filter->avail > 0) { 1049228753Smm if (avail != NULL) 1050228753Smm *avail = filter->avail; 1051228753Smm return (filter->next); 1052228753Smm } 1053228753Smm 1054228753Smm /* 1055228753Smm * We can satisfy directly from client buffer if everything 1056228753Smm * currently in the copy buffer is still in the client buffer. 1057228753Smm */ 1058228753Smm if (filter->client_total >= filter->client_avail + filter->avail 1059228753Smm && filter->client_avail + filter->avail >= min) { 1060228753Smm /* "Roll back" to client buffer. */ 1061228753Smm filter->client_avail += filter->avail; 1062228753Smm filter->client_next -= filter->avail; 1063228753Smm /* Copy buffer is now empty. */ 1064228753Smm filter->avail = 0; 1065228753Smm filter->next = filter->buffer; 1066228753Smm /* Return data from client buffer. */ 1067228753Smm if (avail != NULL) 1068228753Smm *avail = filter->client_avail; 1069228753Smm return (filter->client_next); 1070228753Smm } 1071228753Smm 1072228753Smm /* Move data forward in copy buffer if necessary. */ 1073228753Smm if (filter->next > filter->buffer && 1074228753Smm filter->next + min > filter->buffer + filter->buffer_size) { 1075228753Smm if (filter->avail > 0) 1076228753Smm memmove(filter->buffer, filter->next, filter->avail); 1077228753Smm filter->next = filter->buffer; 1078228753Smm } 1079228753Smm 1080228753Smm /* If we've used up the client data, get more. */ 1081228753Smm if (filter->client_avail <= 0) { 1082228753Smm if (filter->end_of_file) { 1083228753Smm if (avail != NULL) 1084228753Smm *avail = 0; 1085228753Smm return (NULL); 1086228753Smm } 1087228753Smm bytes_read = (filter->read)(filter, 1088228753Smm &filter->client_buff); 1089228753Smm if (bytes_read < 0) { /* Read error. */ 1090228753Smm filter->client_total = filter->client_avail = 0; 1091228753Smm filter->client_next = filter->client_buff = NULL; 1092228753Smm filter->fatal = 1; 1093228753Smm if (avail != NULL) 1094228753Smm *avail = ARCHIVE_FATAL; 1095228753Smm return (NULL); 1096228753Smm } 1097228753Smm if (bytes_read == 0) { /* Premature end-of-file. */ 1098228753Smm filter->client_total = filter->client_avail = 0; 1099228753Smm filter->client_next = filter->client_buff = NULL; 1100228753Smm filter->end_of_file = 1; 1101228753Smm /* Return whatever we do have. */ 1102228753Smm if (avail != NULL) 1103228753Smm *avail = filter->avail; 1104228753Smm return (NULL); 1105228753Smm } 1106228753Smm filter->client_total = bytes_read; 1107228753Smm filter->client_avail = filter->client_total; 1108228753Smm filter->client_next = filter->client_buff; 1109228753Smm } 1110228753Smm else 1111228753Smm { 1112228753Smm /* 1113228753Smm * We can't satisfy the request from the copy 1114228753Smm * buffer or the existing client data, so we 1115228753Smm * need to copy more client data over to the 1116228753Smm * copy buffer. 1117228753Smm */ 1118228753Smm 1119228753Smm /* Ensure the buffer is big enough. */ 1120228753Smm if (min > filter->buffer_size) { 1121228753Smm size_t s, t; 1122228753Smm char *p; 1123228753Smm 1124228753Smm /* Double the buffer; watch for overflow. */ 1125228753Smm s = t = filter->buffer_size; 1126228753Smm if (s == 0) 1127228753Smm s = min; 1128228753Smm while (s < min) { 1129228753Smm t *= 2; 1130228753Smm if (t <= s) { /* Integer overflow! */ 1131228753Smm archive_set_error( 1132228753Smm &filter->archive->archive, 1133228753Smm ENOMEM, 1134228753Smm "Unable to allocate copy buffer"); 1135228753Smm filter->fatal = 1; 1136228753Smm if (avail != NULL) 1137228753Smm *avail = ARCHIVE_FATAL; 1138228753Smm return (NULL); 1139228753Smm } 1140228753Smm s = t; 1141228753Smm } 1142228753Smm /* Now s >= min, so allocate a new buffer. */ 1143228753Smm p = (char *)malloc(s); 1144228753Smm if (p == NULL) { 1145228753Smm archive_set_error( 1146228753Smm &filter->archive->archive, 1147228753Smm ENOMEM, 1148228753Smm "Unable to allocate copy buffer"); 1149228753Smm filter->fatal = 1; 1150228753Smm if (avail != NULL) 1151228753Smm *avail = ARCHIVE_FATAL; 1152228753Smm return (NULL); 1153228753Smm } 1154228753Smm /* Move data into newly-enlarged buffer. */ 1155228753Smm if (filter->avail > 0) 1156228753Smm memmove(p, filter->next, filter->avail); 1157228753Smm free(filter->buffer); 1158228753Smm filter->next = filter->buffer = p; 1159228753Smm filter->buffer_size = s; 1160228753Smm } 1161228753Smm 1162228753Smm /* We can add client data to copy buffer. */ 1163228753Smm /* First estimate: copy to fill rest of buffer. */ 1164228753Smm tocopy = (filter->buffer + filter->buffer_size) 1165228753Smm - (filter->next + filter->avail); 1166228753Smm /* Don't waste time buffering more than we need to. */ 1167228753Smm if (tocopy + filter->avail > min) 1168228753Smm tocopy = min - filter->avail; 1169228753Smm /* Don't copy more than is available. */ 1170228753Smm if (tocopy > filter->client_avail) 1171228753Smm tocopy = filter->client_avail; 1172228753Smm 1173228753Smm memcpy(filter->next + filter->avail, filter->client_next, 1174228753Smm tocopy); 1175228753Smm /* Remove this data from client buffer. */ 1176228753Smm filter->client_next += tocopy; 1177228753Smm filter->client_avail -= tocopy; 1178228753Smm /* add it to copy buffer. */ 1179228753Smm filter->avail += tocopy; 1180228753Smm } 1181228753Smm } 1182228753Smm} 1183228753Smm 1184228753Smm/* 1185232153Smm * Move the file pointer forward. 1186228753Smm */ 1187232153Smmint64_t 1188232153Smm__archive_read_consume(struct archive_read *a, int64_t request) 1189228753Smm{ 1190232153Smm return (__archive_read_filter_consume(a->filter, request)); 1191228753Smm} 1192228753Smm 1193232153Smmint64_t 1194228753Smm__archive_read_filter_consume(struct archive_read_filter * filter, 1195232153Smm int64_t request) 1196228753Smm{ 1197232153Smm int64_t skipped; 1198228753Smm 1199232153Smm if (request == 0) 1200232153Smm return 0; 1201232153Smm 1202232153Smm skipped = advance_file_pointer(filter, request); 1203228753Smm if (skipped == request) 1204228753Smm return (skipped); 1205228753Smm /* We hit EOF before we satisfied the skip request. */ 1206232153Smm if (skipped < 0) /* Map error code to 0 for error message below. */ 1207228753Smm skipped = 0; 1208232153Smm archive_set_error(&filter->archive->archive, 1209228753Smm ARCHIVE_ERRNO_MISC, 1210228753Smm "Truncated input file (needed %jd bytes, only %jd available)", 1211228753Smm (intmax_t)request, (intmax_t)skipped); 1212228753Smm return (ARCHIVE_FATAL); 1213228753Smm} 1214228753Smm 1215232153Smm/* 1216232153Smm * Advance the file pointer by the amount requested. 1217232153Smm * Returns the amount actually advanced, which may be less than the 1218232153Smm * request if EOF is encountered first. 1219232153Smm * Returns a negative value if there's an I/O error. 1220232153Smm */ 1221232153Smmstatic int64_t 1222232153Smmadvance_file_pointer(struct archive_read_filter *filter, int64_t request) 1223228753Smm{ 1224228753Smm int64_t bytes_skipped, total_bytes_skipped = 0; 1225232153Smm ssize_t bytes_read; 1226228753Smm size_t min; 1227228753Smm 1228228753Smm if (filter->fatal) 1229228753Smm return (-1); 1230232153Smm 1231232153Smm /* Use up the copy buffer first. */ 1232228753Smm if (filter->avail > 0) { 1233238856Smm min = (size_t)minimum(request, (int64_t)filter->avail); 1234232153Smm filter->next += min; 1235232153Smm filter->avail -= min; 1236232153Smm request -= min; 1237232153Smm filter->position += min; 1238232153Smm total_bytes_skipped += min; 1239228753Smm } 1240232153Smm 1241232153Smm /* Then use up the client buffer. */ 1242228753Smm if (filter->client_avail > 0) { 1243238856Smm min = (size_t)minimum(request, (int64_t)filter->client_avail); 1244232153Smm filter->client_next += min; 1245232153Smm filter->client_avail -= min; 1246232153Smm request -= min; 1247232153Smm filter->position += min; 1248232153Smm total_bytes_skipped += min; 1249228753Smm } 1250228753Smm if (request == 0) 1251228753Smm return (total_bytes_skipped); 1252232153Smm 1253232153Smm /* If there's an optimized skip function, use it. */ 1254228753Smm if (filter->skip != NULL) { 1255228753Smm bytes_skipped = (filter->skip)(filter, request); 1256228753Smm if (bytes_skipped < 0) { /* error */ 1257228753Smm filter->fatal = 1; 1258228753Smm return (bytes_skipped); 1259228753Smm } 1260232153Smm filter->position += bytes_skipped; 1261228753Smm total_bytes_skipped += bytes_skipped; 1262228753Smm request -= bytes_skipped; 1263232153Smm if (request == 0) 1264232153Smm return (total_bytes_skipped); 1265228753Smm } 1266232153Smm 1267232153Smm /* Use ordinary reads as necessary to complete the request. */ 1268232153Smm for (;;) { 1269232153Smm bytes_read = (filter->read)(filter, &filter->client_buff); 1270232153Smm if (bytes_read < 0) { 1271232153Smm filter->client_buff = NULL; 1272232153Smm filter->fatal = 1; 1273228753Smm return (bytes_read); 1274232153Smm } 1275232153Smm 1276228753Smm if (bytes_read == 0) { 1277232153Smm filter->client_buff = NULL; 1278232153Smm filter->end_of_file = 1; 1279228753Smm return (total_bytes_skipped); 1280228753Smm } 1281232153Smm 1282232153Smm if (bytes_read >= request) { 1283232153Smm filter->client_next = 1284232153Smm ((const char *)filter->client_buff) + request; 1285238856Smm filter->client_avail = (size_t)(bytes_read - request); 1286232153Smm filter->client_total = bytes_read; 1287232153Smm total_bytes_skipped += request; 1288232153Smm filter->position += request; 1289232153Smm return (total_bytes_skipped); 1290232153Smm } 1291232153Smm 1292232153Smm filter->position += bytes_read; 1293228753Smm total_bytes_skipped += bytes_read; 1294228753Smm request -= bytes_read; 1295228753Smm } 1296228753Smm} 1297232153Smm 1298232153Smm/** 1299232153Smm * Returns ARCHIVE_FAILED if seeking isn't supported. 1300232153Smm */ 1301232153Smmint64_t 1302232153Smm__archive_read_seek(struct archive_read *a, int64_t offset, int whence) 1303232153Smm{ 1304232153Smm return __archive_read_filter_seek(a->filter, offset, whence); 1305232153Smm} 1306232153Smm 1307232153Smmint64_t 1308232153Smm__archive_read_filter_seek(struct archive_read_filter *filter, int64_t offset, int whence) 1309232153Smm{ 1310232153Smm int64_t r; 1311232153Smm 1312232153Smm if (filter->closed || filter->fatal) 1313232153Smm return (ARCHIVE_FATAL); 1314232153Smm if (filter->seek == NULL) 1315232153Smm return (ARCHIVE_FAILED); 1316232153Smm r = filter->seek(filter, offset, whence); 1317232153Smm if (r >= 0) { 1318232153Smm /* 1319232153Smm * Ouch. Clearing the buffer like this hurts, especially 1320232153Smm * at bid time. A lot of our efficiency at bid time comes 1321232153Smm * from having bidders reuse the data we've already read. 1322232153Smm * 1323232153Smm * TODO: If the seek request is in data we already 1324232153Smm * have, then don't call the seek callback. 1325232153Smm * 1326232153Smm * TODO: Zip seeks to end-of-file at bid time. If 1327232153Smm * other formats also start doing this, we may need to 1328232153Smm * find a way for clients to fudge the seek offset to 1329232153Smm * a block boundary. 1330232153Smm * 1331232153Smm * Hmmm... If whence was SEEK_END, we know the file 1332232153Smm * size is (r - offset). Can we use that to simplify 1333232153Smm * the TODO items above? 1334232153Smm */ 1335232153Smm filter->avail = filter->client_avail = 0; 1336232153Smm filter->next = filter->buffer; 1337232153Smm filter->position = r; 1338232153Smm filter->end_of_file = 0; 1339232153Smm } 1340232153Smm return r; 1341232153Smm} 1342