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 * in this position and unchanged. 11228753Smm * 2. Redistributions in binary form must reproduce the above copyright 12228753Smm * notice, this list of conditions and the following disclaimer in the 13228753Smm * documentation and/or other materials provided with the distribution. 14228753Smm * 15228753Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 16228753Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17228753Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18228753Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 19228753Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20228753Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21228753Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22228753Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23228753Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24228753Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25228753Smm */ 26228753Smm 27228753Smm#include "archive_platform.h" 28229592Smm__FBSDID("$FreeBSD$"); 29228753Smm 30228753Smm#include "archive.h" 31228753Smm#include "archive_string.h" 32228753Smm#include "archive_entry.h" 33228753Smm#include "archive_private.h" 34228753Smm#include "archive_read_disk_private.h" 35228753Smm 36229592Smmstatic int _archive_read_free(struct archive *); 37228753Smmstatic int _archive_read_close(struct archive *); 38228753Smmstatic const char *trivial_lookup_gname(void *, gid_t gid); 39228753Smmstatic const char *trivial_lookup_uname(void *, uid_t uid); 40228753Smm 41228753Smmstatic struct archive_vtable * 42228753Smmarchive_read_disk_vtable(void) 43228753Smm{ 44228753Smm static struct archive_vtable av; 45228753Smm static int inited = 0; 46228753Smm 47228753Smm if (!inited) { 48229592Smm av.archive_free = _archive_read_free; 49228753Smm av.archive_close = _archive_read_close; 50228753Smm } 51228753Smm return (&av); 52228753Smm} 53228753Smm 54228753Smmconst char * 55228753Smmarchive_read_disk_gname(struct archive *_a, gid_t gid) 56228753Smm{ 57228753Smm struct archive_read_disk *a = (struct archive_read_disk *)_a; 58228753Smm if (a->lookup_gname != NULL) 59228753Smm return ((*a->lookup_gname)(a->lookup_gname_data, gid)); 60228753Smm return (NULL); 61228753Smm} 62228753Smm 63228753Smmconst char * 64228753Smmarchive_read_disk_uname(struct archive *_a, uid_t uid) 65228753Smm{ 66228753Smm struct archive_read_disk *a = (struct archive_read_disk *)_a; 67228753Smm if (a->lookup_uname != NULL) 68228753Smm return ((*a->lookup_uname)(a->lookup_uname_data, uid)); 69228753Smm return (NULL); 70228753Smm} 71228753Smm 72228753Smmint 73228753Smmarchive_read_disk_set_gname_lookup(struct archive *_a, 74228753Smm void *private_data, 75228753Smm const char * (*lookup_gname)(void *private, gid_t gid), 76228753Smm void (*cleanup_gname)(void *private)) 77228753Smm{ 78228753Smm struct archive_read_disk *a = (struct archive_read_disk *)_a; 79228753Smm __archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC, 80228753Smm ARCHIVE_STATE_ANY, "archive_read_disk_set_gname_lookup"); 81228753Smm 82228753Smm if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL) 83228753Smm (a->cleanup_gname)(a->lookup_gname_data); 84228753Smm 85228753Smm a->lookup_gname = lookup_gname; 86228753Smm a->cleanup_gname = cleanup_gname; 87228753Smm a->lookup_gname_data = private_data; 88228753Smm return (ARCHIVE_OK); 89228753Smm} 90228753Smm 91228753Smmint 92228753Smmarchive_read_disk_set_uname_lookup(struct archive *_a, 93228753Smm void *private_data, 94228753Smm const char * (*lookup_uname)(void *private, uid_t uid), 95228753Smm void (*cleanup_uname)(void *private)) 96228753Smm{ 97228753Smm struct archive_read_disk *a = (struct archive_read_disk *)_a; 98228753Smm __archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC, 99228753Smm ARCHIVE_STATE_ANY, "archive_read_disk_set_uname_lookup"); 100228753Smm 101228753Smm if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL) 102228753Smm (a->cleanup_uname)(a->lookup_uname_data); 103228753Smm 104228753Smm a->lookup_uname = lookup_uname; 105228753Smm a->cleanup_uname = cleanup_uname; 106228753Smm a->lookup_uname_data = private_data; 107228753Smm return (ARCHIVE_OK); 108228753Smm} 109228753Smm 110228753Smm/* 111228753Smm * Create a new archive_read_disk object and initialize it with global state. 112228753Smm */ 113228753Smmstruct archive * 114228753Smmarchive_read_disk_new(void) 115228753Smm{ 116228753Smm struct archive_read_disk *a; 117228753Smm 118228753Smm a = (struct archive_read_disk *)malloc(sizeof(*a)); 119228753Smm if (a == NULL) 120228753Smm return (NULL); 121228753Smm memset(a, 0, sizeof(*a)); 122228753Smm a->archive.magic = ARCHIVE_READ_DISK_MAGIC; 123228753Smm /* We're ready to write a header immediately. */ 124228753Smm a->archive.state = ARCHIVE_STATE_HEADER; 125228753Smm a->archive.vtable = archive_read_disk_vtable(); 126228753Smm a->lookup_uname = trivial_lookup_uname; 127228753Smm a->lookup_gname = trivial_lookup_gname; 128228753Smm return (&a->archive); 129228753Smm} 130228753Smm 131228753Smmstatic int 132229592Smm_archive_read_free(struct archive *_a) 133228753Smm{ 134228753Smm struct archive_read_disk *a = (struct archive_read_disk *)_a; 135228753Smm 136228753Smm if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL) 137228753Smm (a->cleanup_gname)(a->lookup_gname_data); 138228753Smm if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL) 139228753Smm (a->cleanup_uname)(a->lookup_uname_data); 140228753Smm archive_string_free(&a->archive.error_string); 141228753Smm free(a); 142228753Smm return (ARCHIVE_OK); 143228753Smm} 144228753Smm 145228753Smmstatic int 146228753Smm_archive_read_close(struct archive *_a) 147228753Smm{ 148228753Smm (void)_a; /* UNUSED */ 149228753Smm return (ARCHIVE_OK); 150228753Smm} 151228753Smm 152228753Smmint 153228753Smmarchive_read_disk_set_symlink_logical(struct archive *_a) 154228753Smm{ 155228753Smm struct archive_read_disk *a = (struct archive_read_disk *)_a; 156228753Smm a->symlink_mode = 'L'; 157228753Smm a->follow_symlinks = 1; 158228753Smm return (ARCHIVE_OK); 159228753Smm} 160228753Smm 161228753Smmint 162228753Smmarchive_read_disk_set_symlink_physical(struct archive *_a) 163228753Smm{ 164228753Smm struct archive_read_disk *a = (struct archive_read_disk *)_a; 165228753Smm a->symlink_mode = 'P'; 166228753Smm a->follow_symlinks = 0; 167228753Smm return (ARCHIVE_OK); 168228753Smm} 169228753Smm 170228753Smmint 171228753Smmarchive_read_disk_set_symlink_hybrid(struct archive *_a) 172228753Smm{ 173228753Smm struct archive_read_disk *a = (struct archive_read_disk *)_a; 174228753Smm a->symlink_mode = 'H'; 175228753Smm a->follow_symlinks = 1; /* Follow symlinks initially. */ 176228753Smm return (ARCHIVE_OK); 177228753Smm} 178228753Smm 179228753Smm/* 180228753Smm * Trivial implementations of gname/uname lookup functions. 181228753Smm * These are normally overridden by the client, but these stub 182228753Smm * versions ensure that we always have something that works. 183228753Smm */ 184228753Smmstatic const char * 185228753Smmtrivial_lookup_gname(void *private_data, gid_t gid) 186228753Smm{ 187228753Smm (void)private_data; /* UNUSED */ 188228753Smm (void)gid; /* UNUSED */ 189228753Smm return (NULL); 190228753Smm} 191228753Smm 192228753Smmstatic const char * 193228753Smmtrivial_lookup_uname(void *private_data, uid_t uid) 194228753Smm{ 195228753Smm (void)private_data; /* UNUSED */ 196228753Smm (void)uid; /* UNUSED */ 197228753Smm return (NULL); 198228753Smm} 199