1248590Smm/*- 2248590Smm * Copyright (c) 2012 Michihiro NAKAJIMA 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 48248590Smmstatic const unsigned char grzip_magic[] = { 49248590Smm 0x47, 0x52, 0x5a, 0x69, 0x70, 0x49, 0x49, 0x00, 50248590Smm 0x02, 0x04, 0x3a, 0x29 }; 51248590Smm 52248590Smmstatic int grzip_bidder_bid(struct archive_read_filter_bidder *, 53248590Smm struct archive_read_filter *); 54248590Smmstatic int grzip_bidder_init(struct archive_read_filter *); 55248590Smm 56248590Smm 57248590Smmstatic int 58248590Smmgrzip_reader_free(struct archive_read_filter_bidder *self) 59248590Smm{ 60248590Smm (void)self; /* UNUSED */ 61248590Smm return (ARCHIVE_OK); 62248590Smm} 63248590Smm 64248590Smmint 65248590Smmarchive_read_support_filter_grzip(struct archive *_a) 66248590Smm{ 67248590Smm struct archive_read *a = (struct archive_read *)_a; 68248590Smm struct archive_read_filter_bidder *reader; 69248590Smm 70248590Smm archive_check_magic(_a, ARCHIVE_READ_MAGIC, 71248590Smm ARCHIVE_STATE_NEW, "archive_read_support_filter_grzip"); 72248590Smm 73248590Smm if (__archive_read_get_bidder(a, &reader) != ARCHIVE_OK) 74248590Smm return (ARCHIVE_FATAL); 75248590Smm 76248590Smm reader->data = NULL; 77248590Smm reader->bid = grzip_bidder_bid; 78248590Smm reader->init = grzip_bidder_init; 79248590Smm reader->options = NULL; 80248590Smm reader->free = grzip_reader_free; 81248590Smm /* This filter always uses an external program. */ 82248590Smm archive_set_error(_a, ARCHIVE_ERRNO_MISC, 83248590Smm "Using external grzip program for grzip decompression"); 84248590Smm return (ARCHIVE_WARN); 85248590Smm} 86248590Smm 87248590Smm/* 88248590Smm * Bidder just verifies the header and returns the number of verified bits. 89248590Smm */ 90248590Smmstatic int 91248590Smmgrzip_bidder_bid(struct archive_read_filter_bidder *self, 92248590Smm struct archive_read_filter *filter) 93248590Smm{ 94248590Smm const unsigned char *p; 95248590Smm ssize_t avail; 96248590Smm 97248590Smm (void)self; /* UNUSED */ 98248590Smm 99248590Smm p = __archive_read_filter_ahead(filter, sizeof(grzip_magic), &avail); 100248590Smm if (p == NULL || avail == 0) 101248590Smm return (0); 102248590Smm 103248590Smm if (memcmp(p, grzip_magic, sizeof(grzip_magic))) 104248590Smm return (0); 105248590Smm 106248590Smm return (sizeof(grzip_magic) * 8); 107248590Smm} 108248590Smm 109248590Smmstatic int 110248590Smmgrzip_bidder_init(struct archive_read_filter *self) 111248590Smm{ 112248590Smm int r; 113248590Smm 114248590Smm r = __archive_read_program(self, "grzip -d"); 115248590Smm /* Note: We set the format here even if __archive_read_program() 116248590Smm * above fails. We do, after all, know what the format is 117248590Smm * even if we weren't able to read it. */ 118248590Smm self->code = ARCHIVE_FILTER_GRZIP; 119248590Smm self->name = "grzip"; 120248590Smm return (r); 121248590Smm} 122