17ec681f3Smrg/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ 27ec681f3Smrg 37ec681f3Smrg/* 47ec681f3Smrg * Copyright (C) 2014 Rob Clark <robclark@freedesktop.org> 57ec681f3Smrg * 67ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 77ec681f3Smrg * copy of this software and associated documentation files (the "Software"), 87ec681f3Smrg * to deal in the Software without restriction, including without limitation 97ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 107ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the 117ec681f3Smrg * Software is furnished to do so, subject to the following conditions: 127ec681f3Smrg * 137ec681f3Smrg * The above copyright notice and this permission notice (including the next 147ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the 157ec681f3Smrg * Software. 167ec681f3Smrg * 177ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 187ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 197ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 207ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 217ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 227ec681f3Smrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 237ec681f3Smrg * SOFTWARE. 247ec681f3Smrg * 257ec681f3Smrg * Authors: 267ec681f3Smrg * Rob Clark <robclark@freedesktop.org> 277ec681f3Smrg */ 287ec681f3Smrg 297ec681f3Smrg#include <archive.h> 307ec681f3Smrg#include <fcntl.h> 317ec681f3Smrg#include <stdlib.h> 327ec681f3Smrg#include <string.h> 337ec681f3Smrg#include <sys/stat.h> 347ec681f3Smrg#include <sys/types.h> 357ec681f3Smrg#include <archive_entry.h> 367ec681f3Smrg 377ec681f3Smrg#include "io.h" 387ec681f3Smrg 397ec681f3Smrgstruct io { 407ec681f3Smrg struct archive *a; 417ec681f3Smrg struct archive_entry *entry; 427ec681f3Smrg unsigned offset; 437ec681f3Smrg}; 447ec681f3Smrg 457ec681f3Smrgstatic void 467ec681f3Smrgio_error(struct io *io) 477ec681f3Smrg{ 487ec681f3Smrg fprintf(stderr, "%s\n", archive_error_string(io->a)); 497ec681f3Smrg io_close(io); 507ec681f3Smrg} 517ec681f3Smrg 527ec681f3Smrgstatic struct io * 537ec681f3Smrgio_new(void) 547ec681f3Smrg{ 557ec681f3Smrg struct io *io = calloc(1, sizeof(*io)); 567ec681f3Smrg int ret; 577ec681f3Smrg 587ec681f3Smrg if (!io) 597ec681f3Smrg return NULL; 607ec681f3Smrg 617ec681f3Smrg io->a = archive_read_new(); 627ec681f3Smrg ret = archive_read_support_filter_gzip(io->a); 637ec681f3Smrg if (ret != ARCHIVE_OK) { 647ec681f3Smrg io_error(io); 657ec681f3Smrg return NULL; 667ec681f3Smrg } 677ec681f3Smrg 687ec681f3Smrg ret = archive_read_support_filter_none(io->a); 697ec681f3Smrg if (ret != ARCHIVE_OK) { 707ec681f3Smrg io_error(io); 717ec681f3Smrg return NULL; 727ec681f3Smrg } 737ec681f3Smrg 747ec681f3Smrg ret = archive_read_support_format_all(io->a); 757ec681f3Smrg if (ret != ARCHIVE_OK) { 767ec681f3Smrg io_error(io); 777ec681f3Smrg return NULL; 787ec681f3Smrg } 797ec681f3Smrg 807ec681f3Smrg ret = archive_read_support_format_raw(io->a); 817ec681f3Smrg if (ret != ARCHIVE_OK) { 827ec681f3Smrg io_error(io); 837ec681f3Smrg return NULL; 847ec681f3Smrg } 857ec681f3Smrg 867ec681f3Smrg return io; 877ec681f3Smrg} 887ec681f3Smrg 897ec681f3Smrgstruct io * 907ec681f3Smrgio_open(const char *filename) 917ec681f3Smrg{ 927ec681f3Smrg struct io *io = io_new(); 937ec681f3Smrg int ret; 947ec681f3Smrg 957ec681f3Smrg if (!io) 967ec681f3Smrg return NULL; 977ec681f3Smrg 987ec681f3Smrg ret = archive_read_open_filename(io->a, filename, 10240); 997ec681f3Smrg if (ret != ARCHIVE_OK) { 1007ec681f3Smrg io_error(io); 1017ec681f3Smrg return NULL; 1027ec681f3Smrg } 1037ec681f3Smrg 1047ec681f3Smrg ret = archive_read_next_header(io->a, &io->entry); 1057ec681f3Smrg if (ret != ARCHIVE_OK) { 1067ec681f3Smrg io_error(io); 1077ec681f3Smrg return NULL; 1087ec681f3Smrg } 1097ec681f3Smrg 1107ec681f3Smrg return io; 1117ec681f3Smrg} 1127ec681f3Smrg 1137ec681f3Smrgstruct io * 1147ec681f3Smrgio_openfd(int fd) 1157ec681f3Smrg{ 1167ec681f3Smrg struct io *io = io_new(); 1177ec681f3Smrg int ret; 1187ec681f3Smrg 1197ec681f3Smrg if (!io) 1207ec681f3Smrg return NULL; 1217ec681f3Smrg 1227ec681f3Smrg ret = archive_read_open_fd(io->a, fd, 10240); 1237ec681f3Smrg if (ret != ARCHIVE_OK) { 1247ec681f3Smrg io_error(io); 1257ec681f3Smrg return NULL; 1267ec681f3Smrg } 1277ec681f3Smrg 1287ec681f3Smrg ret = archive_read_next_header(io->a, &io->entry); 1297ec681f3Smrg if (ret != ARCHIVE_OK) { 1307ec681f3Smrg io_error(io); 1317ec681f3Smrg return NULL; 1327ec681f3Smrg } 1337ec681f3Smrg 1347ec681f3Smrg return io; 1357ec681f3Smrg} 1367ec681f3Smrg 1377ec681f3Smrgvoid 1387ec681f3Smrgio_close(struct io *io) 1397ec681f3Smrg{ 1407ec681f3Smrg archive_read_free(io->a); 1417ec681f3Smrg free(io); 1427ec681f3Smrg} 1437ec681f3Smrg 1447ec681f3Smrgunsigned 1457ec681f3Smrgio_offset(struct io *io) 1467ec681f3Smrg{ 1477ec681f3Smrg return io->offset; 1487ec681f3Smrg} 1497ec681f3Smrg 1507ec681f3Smrg#include <assert.h> 1517ec681f3Smrgint 1527ec681f3Smrgio_readn(struct io *io, void *buf, int nbytes) 1537ec681f3Smrg{ 1547ec681f3Smrg char *ptr = buf; 1557ec681f3Smrg int ret = 0; 1567ec681f3Smrg while (nbytes > 0) { 1577ec681f3Smrg int n = archive_read_data(io->a, ptr, nbytes); 1587ec681f3Smrg if (n < 0) { 1597ec681f3Smrg fprintf(stderr, "%s\n", archive_error_string(io->a)); 1607ec681f3Smrg return n; 1617ec681f3Smrg } 1627ec681f3Smrg if (n == 0) 1637ec681f3Smrg break; 1647ec681f3Smrg ptr += n; 1657ec681f3Smrg nbytes -= n; 1667ec681f3Smrg ret += n; 1677ec681f3Smrg io->offset += n; 1687ec681f3Smrg } 1697ec681f3Smrg return ret; 1707ec681f3Smrg} 171