1248590Smm/*- 2248590Smm * Copyright (c) 2003-2007 Tim Kientzle 3248590Smm * All rights reserved. 4248590Smm * 5248590Smm * Redistribution and use in source and binary forms, with or without 6248590Smm * modification, are permitted provided that the following conditions 7248590Smm * are met: 8248590Smm * 1. Redistributions of source code must retain the above copyright 9248590Smm * notice, this list of conditions and the following disclaimer. 10248590Smm * 2. Redistributions in binary form must reproduce the above copyright 11248590Smm * notice, this list of conditions and the following disclaimer in the 12248590Smm * documentation and/or other materials provided with the distribution. 13248590Smm * 14248590Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15248590Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16248590Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17248590Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18248590Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19248590Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20248590Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21248590Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22248590Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23248590Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24248590Smm */ 25248590Smm 26248590Smm#include "archive_platform.h" 27248590Smm 28248590Smm__FBSDID("$FreeBSD$"); 29248590Smm 30248590Smm 31248590Smm#ifdef HAVE_ERRNO_H 32248590Smm#include <errno.h> 33248590Smm#endif 34248590Smm#ifdef HAVE_STDLIB_H 35248590Smm#include <stdlib.h> 36248590Smm#endif 37248590Smm#ifdef HAVE_STRING_H 38248590Smm#include <string.h> 39248590Smm#endif 40248590Smm#ifdef HAVE_UNISTD_H 41248590Smm#include <unistd.h> 42248590Smm#endif 43248590Smm 44248590Smm#include "archive.h" 45248590Smm#include "archive_private.h" 46248590Smm#include "archive_read_private.h" 47248590Smm 48248590Smm#define LRZIP_HEADER_MAGIC "LRZI" 49248590Smm#define LRZIP_HEADER_MAGIC_LEN 4 50248590Smm 51248590Smmstatic int lrzip_bidder_bid(struct archive_read_filter_bidder *, 52248590Smm struct archive_read_filter *); 53248590Smmstatic int lrzip_bidder_init(struct archive_read_filter *); 54248590Smm 55248590Smm 56248590Smmstatic int 57248590Smmlrzip_reader_free(struct archive_read_filter_bidder *self) 58248590Smm{ 59248590Smm (void)self; /* UNUSED */ 60248590Smm return (ARCHIVE_OK); 61248590Smm} 62248590Smm 63248590Smmint 64248590Smmarchive_read_support_filter_lrzip(struct archive *_a) 65248590Smm{ 66248590Smm struct archive_read *a = (struct archive_read *)_a; 67248590Smm struct archive_read_filter_bidder *reader; 68248590Smm 69248590Smm archive_check_magic(_a, ARCHIVE_READ_MAGIC, 70248590Smm ARCHIVE_STATE_NEW, "archive_read_support_filter_lrzip"); 71248590Smm 72248590Smm if (__archive_read_get_bidder(a, &reader) != ARCHIVE_OK) 73248590Smm return (ARCHIVE_FATAL); 74248590Smm 75248590Smm reader->data = NULL; 76248590Smm reader->name = "lrzip"; 77248590Smm reader->bid = lrzip_bidder_bid; 78248590Smm reader->init = lrzip_bidder_init; 79248590Smm reader->options = NULL; 80248590Smm reader->free = lrzip_reader_free; 81248590Smm /* This filter always uses an external program. */ 82248590Smm archive_set_error(_a, ARCHIVE_ERRNO_MISC, 83248590Smm "Using external lrzip program for lrzip decompression"); 84248590Smm return (ARCHIVE_WARN); 85248590Smm} 86248590Smm 87248590Smm/* 88248590Smm * Bidder just verifies the header and returns the number of verified bits. 89248590Smm */ 90248590Smmstatic int 91248590Smmlrzip_bidder_bid(struct archive_read_filter_bidder *self, 92248590Smm struct archive_read_filter *filter) 93248590Smm{ 94248590Smm const unsigned char *p; 95248590Smm ssize_t avail, len; 96248590Smm int i; 97248590Smm 98248590Smm (void)self; /* UNUSED */ 99248590Smm /* Start by looking at the first six bytes of the header, which 100248590Smm * is all fixed layout. */ 101248590Smm len = 6; 102248590Smm p = __archive_read_filter_ahead(filter, len, &avail); 103248590Smm if (p == NULL || avail == 0) 104248590Smm return (0); 105248590Smm 106248590Smm if (memcmp(p, LRZIP_HEADER_MAGIC, LRZIP_HEADER_MAGIC_LEN)) 107248590Smm return (0); 108248590Smm 109248590Smm /* current major version is always 0, verify this */ 110248590Smm if (p[LRZIP_HEADER_MAGIC_LEN]) 111248590Smm return 0; 112248590Smm /* support only v0.6+ lrzip for sanity */ 113248590Smm i = p[LRZIP_HEADER_MAGIC_LEN + 1]; 114248590Smm if ((i < 6) || (i > 10)) 115248590Smm return 0; 116248590Smm 117248590Smm return (int)len; 118248590Smm} 119248590Smm 120248590Smmstatic int 121248590Smmlrzip_bidder_init(struct archive_read_filter *self) 122248590Smm{ 123248590Smm int r; 124248590Smm 125248590Smm r = __archive_read_program(self, "lrzip -d -q"); 126248590Smm /* Note: We set the format here even if __archive_read_program() 127248590Smm * above fails. We do, after all, know what the format is 128248590Smm * even if we weren't able to read it. */ 129248590Smm self->code = ARCHIVE_FILTER_LRZIP; 130248590Smm self->name = "lrzip"; 131248590Smm return (r); 132248590Smm} 133