archive_read_support_format_raw.c revision 232153
1228753Smm/*- 2228753Smm * Copyright (c) 2003-2009 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#include "archive_platform.h" 26228763Smm__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/archive_read_support_format_raw.c 232153 2012-02-25 10:58:02Z mm $"); 27228753Smm 28228753Smm#ifdef HAVE_ERRNO_H 29228753Smm#include <errno.h> 30228753Smm#endif 31228753Smm#include <stdio.h> 32228753Smm#ifdef HAVE_STDLIB_H 33228753Smm#include <stdlib.h> 34228753Smm#endif 35228753Smm 36228753Smm#include "archive.h" 37228753Smm#include "archive_entry.h" 38228753Smm#include "archive_private.h" 39228753Smm#include "archive_read_private.h" 40228753Smm 41228753Smmstruct raw_info { 42228753Smm int64_t offset; /* Current position in the file. */ 43232153Smm int64_t unconsumed; 44228753Smm int end_of_file; 45228753Smm}; 46228753Smm 47232153Smmstatic int archive_read_format_raw_bid(struct archive_read *, int); 48228753Smmstatic int archive_read_format_raw_cleanup(struct archive_read *); 49228753Smmstatic int archive_read_format_raw_read_data(struct archive_read *, 50232153Smm const void **, size_t *, int64_t *); 51228753Smmstatic int archive_read_format_raw_read_data_skip(struct archive_read *); 52228753Smmstatic int archive_read_format_raw_read_header(struct archive_read *, 53228753Smm struct archive_entry *); 54228753Smm 55228753Smmint 56228753Smmarchive_read_support_format_raw(struct archive *_a) 57228753Smm{ 58228753Smm struct raw_info *info; 59228753Smm struct archive_read *a = (struct archive_read *)_a; 60228753Smm int r; 61228753Smm 62232153Smm archive_check_magic(_a, ARCHIVE_READ_MAGIC, 63232153Smm ARCHIVE_STATE_NEW, "archive_read_support_format_raw"); 64232153Smm 65228753Smm info = (struct raw_info *)calloc(1, sizeof(*info)); 66228753Smm if (info == NULL) { 67228753Smm archive_set_error(&a->archive, ENOMEM, 68228753Smm "Can't allocate raw_info data"); 69228753Smm return (ARCHIVE_FATAL); 70228753Smm } 71228753Smm 72228753Smm r = __archive_read_register_format(a, 73228753Smm info, 74228753Smm "raw", 75228753Smm archive_read_format_raw_bid, 76228753Smm NULL, 77228753Smm archive_read_format_raw_read_header, 78228753Smm archive_read_format_raw_read_data, 79228753Smm archive_read_format_raw_read_data_skip, 80228753Smm archive_read_format_raw_cleanup); 81228753Smm if (r != ARCHIVE_OK) 82228753Smm free(info); 83228753Smm return (r); 84228753Smm} 85228753Smm 86228753Smm/* 87228753Smm * Bid 1 if this is a non-empty file. Anyone who can really support 88228753Smm * this should outbid us, so it should generally be safe to use "raw" 89228753Smm * in conjunction with other formats. But, this could really confuse 90228753Smm * folks if there are bid errors or minor file damage, so we don't 91228753Smm * include "raw" as part of support_format_all(). 92228753Smm */ 93228753Smmstatic int 94232153Smmarchive_read_format_raw_bid(struct archive_read *a, int best_bid) 95228753Smm{ 96232153Smm if (best_bid < 1 && __archive_read_ahead(a, 1, NULL) != NULL) 97232153Smm return (1); 98232153Smm return (-1); 99228753Smm} 100228753Smm 101228753Smm/* 102228753Smm * Mock up a fake header. 103228753Smm */ 104228753Smmstatic int 105228753Smmarchive_read_format_raw_read_header(struct archive_read *a, 106228753Smm struct archive_entry *entry) 107228753Smm{ 108228753Smm struct raw_info *info; 109228753Smm 110228753Smm info = (struct raw_info *)(a->format->data); 111228753Smm if (info->end_of_file) 112228753Smm return (ARCHIVE_EOF); 113228753Smm 114228753Smm a->archive.archive_format = ARCHIVE_FORMAT_RAW; 115232153Smm a->archive.archive_format_name = "raw"; 116228753Smm archive_entry_set_pathname(entry, "data"); 117232153Smm archive_entry_set_filetype(entry, AE_IFREG); 118232153Smm archive_entry_set_perm(entry, 0644); 119228753Smm /* I'm deliberately leaving most fields unset here. */ 120228753Smm return (ARCHIVE_OK); 121228753Smm} 122228753Smm 123228753Smmstatic int 124228753Smmarchive_read_format_raw_read_data(struct archive_read *a, 125232153Smm const void **buff, size_t *size, int64_t *offset) 126228753Smm{ 127228753Smm struct raw_info *info; 128228753Smm ssize_t avail; 129228753Smm 130228753Smm info = (struct raw_info *)(a->format->data); 131232153Smm 132232153Smm /* Consume the bytes we read last time. */ 133232153Smm if (info->unconsumed) { 134232153Smm __archive_read_consume(a, info->unconsumed); 135232153Smm info->unconsumed = 0; 136232153Smm } 137232153Smm 138228753Smm if (info->end_of_file) 139228753Smm return (ARCHIVE_EOF); 140228753Smm 141228753Smm /* Get whatever bytes are immediately available. */ 142228753Smm *buff = __archive_read_ahead(a, 1, &avail); 143228753Smm if (avail > 0) { 144232153Smm /* Return the bytes we just read */ 145228753Smm *size = avail; 146228753Smm *offset = info->offset; 147228753Smm info->offset += *size; 148232153Smm info->unconsumed = avail; 149228753Smm return (ARCHIVE_OK); 150228753Smm } else if (0 == avail) { 151228753Smm /* Record and return end-of-file. */ 152228753Smm info->end_of_file = 1; 153228753Smm *size = 0; 154228753Smm *offset = info->offset; 155228753Smm return (ARCHIVE_EOF); 156228753Smm } else { 157228753Smm /* Record and return an error. */ 158228753Smm *size = 0; 159228753Smm *offset = info->offset; 160228753Smm return (avail); 161228753Smm } 162228753Smm} 163228753Smm 164228753Smmstatic int 165228753Smmarchive_read_format_raw_read_data_skip(struct archive_read *a) 166228753Smm{ 167232153Smm struct raw_info *info = (struct raw_info *)(a->format->data); 168228753Smm 169232153Smm /* Consume the bytes we read last time. */ 170232153Smm if (info->unconsumed) { 171232153Smm __archive_read_consume(a, info->unconsumed); 172232153Smm info->unconsumed = 0; 173232153Smm } 174228753Smm info->end_of_file = 1; 175232153Smm return (ARCHIVE_OK); 176228753Smm} 177228753Smm 178228753Smmstatic int 179228753Smmarchive_read_format_raw_cleanup(struct archive_read *a) 180228753Smm{ 181228753Smm struct raw_info *info; 182228753Smm 183228753Smm info = (struct raw_info *)(a->format->data); 184228753Smm free(info); 185228753Smm a->format->data = NULL; 186228753Smm return (ARCHIVE_OK); 187228753Smm} 188