archive_read_disk.c revision 228753
133965Sjdp/*- 289857Sobrien * Copyright (c) 2003-2009 Tim Kientzle 3130561Sobrien * All rights reserved. 433965Sjdp * 533965Sjdp * Redistribution and use in source and binary forms, with or without 6130561Sobrien * modification, are permitted provided that the following conditions 733965Sjdp * are met: 8130561Sobrien * 1. Redistributions of source code must retain the above copyright 9130561Sobrien * notice, this list of conditions and the following disclaimer 10130561Sobrien * in this position and unchanged. 11130561Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1233965Sjdp * notice, this list of conditions and the following disclaimer in the 13130561Sobrien * documentation and/or other materials provided with the distribution. 14130561Sobrien * 15130561Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 16130561Sobrien * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1733965Sjdp * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18130561Sobrien * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 19130561Sobrien * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20130561Sobrien * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2133965Sjdp * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2233965Sjdp * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2333965Sjdp * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2433965Sjdp * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2533965Sjdp */ 2633965Sjdp 2733965Sjdp#include "archive_platform.h" 2833965Sjdp__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk.c 189429 2009-03-06 04:35:31Z kientzle $"); 2933965Sjdp 3078828Sobrien#include "archive.h" 3189857Sobrien#include "archive_string.h" 3278828Sobrien#include "archive_entry.h" 3378828Sobrien#include "archive_private.h" 3478828Sobrien#include "archive_read_disk_private.h" 3533965Sjdp 3633965Sjdpstatic int _archive_read_finish(struct archive *); 37130561Sobrienstatic int _archive_read_close(struct archive *); 38130561Sobrienstatic const char *trivial_lookup_gname(void *, gid_t gid); 3933965Sjdpstatic const char *trivial_lookup_uname(void *, uid_t uid); 40130561Sobrien 41130561Sobrienstatic struct archive_vtable * 4233965Sjdparchive_read_disk_vtable(void) 4333965Sjdp{ 4433965Sjdp static struct archive_vtable av; 4533965Sjdp static int inited = 0; 46130561Sobrien 4733965Sjdp if (!inited) { 4833965Sjdp av.archive_finish = _archive_read_finish; 4933965Sjdp av.archive_close = _archive_read_close; 5033965Sjdp } 5133965Sjdp return (&av); 5233965Sjdp} 5333965Sjdp 5433965Sjdpconst char * 5533965Sjdparchive_read_disk_gname(struct archive *_a, gid_t gid) 5633965Sjdp{ 5733965Sjdp struct archive_read_disk *a = (struct archive_read_disk *)_a; 5833965Sjdp if (a->lookup_gname != NULL) 5933965Sjdp return ((*a->lookup_gname)(a->lookup_gname_data, gid)); 6033965Sjdp return (NULL); 6133965Sjdp} 6233965Sjdp 6333965Sjdpconst char * 6433965Sjdparchive_read_disk_uname(struct archive *_a, uid_t uid) 6533965Sjdp{ 6633965Sjdp struct archive_read_disk *a = (struct archive_read_disk *)_a; 67130561Sobrien if (a->lookup_uname != NULL) 68130561Sobrien return ((*a->lookup_uname)(a->lookup_uname_data, uid)); 6933965Sjdp return (NULL); 7033965Sjdp} 7133965Sjdp 7233965Sjdpint 7333965Sjdparchive_read_disk_set_gname_lookup(struct archive *_a, 7433965Sjdp void *private_data, 7533965Sjdp const char * (*lookup_gname)(void *private, gid_t gid), 7633965Sjdp void (*cleanup_gname)(void *private)) 7733965Sjdp{ 7833965Sjdp struct archive_read_disk *a = (struct archive_read_disk *)_a; 7989857Sobrien __archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC, 80130561Sobrien ARCHIVE_STATE_ANY, "archive_read_disk_set_gname_lookup"); 81130561Sobrien 8289857Sobrien if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL) 8333965Sjdp (a->cleanup_gname)(a->lookup_gname_data); 8433965Sjdp 8533965Sjdp a->lookup_gname = lookup_gname; 8633965Sjdp a->cleanup_gname = cleanup_gname; 8733965Sjdp a->lookup_gname_data = private_data; 8833965Sjdp return (ARCHIVE_OK); 8933965Sjdp} 9033965Sjdp 9133965Sjdpint 9233965Sjdparchive_read_disk_set_uname_lookup(struct archive *_a, 9333965Sjdp void *private_data, 9433965Sjdp const char * (*lookup_uname)(void *private, uid_t uid), 9560484Sobrien void (*cleanup_uname)(void *private)) 9660484Sobrien{ 9760484Sobrien struct archive_read_disk *a = (struct archive_read_disk *)_a; 9860484Sobrien __archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC, 9960484Sobrien ARCHIVE_STATE_ANY, "archive_read_disk_set_uname_lookup"); 10060484Sobrien 10160484Sobrien if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL) 10260484Sobrien (a->cleanup_uname)(a->lookup_uname_data); 10360484Sobrien 10460484Sobrien a->lookup_uname = lookup_uname; 10533965Sjdp a->cleanup_uname = cleanup_uname; 10633965Sjdp a->lookup_uname_data = private_data; 10733965Sjdp return (ARCHIVE_OK); 10833965Sjdp} 10933965Sjdp 11089857Sobrien/* 11189857Sobrien * Create a new archive_read_disk object and initialize it with global state. 11289857Sobrien */ 11333965Sjdpstruct archive * 11433965Sjdparchive_read_disk_new(void) 11533965Sjdp{ 11633965Sjdp struct archive_read_disk *a; 11733965Sjdp 11833965Sjdp a = (struct archive_read_disk *)malloc(sizeof(*a)); 11933965Sjdp if (a == NULL) 12033965Sjdp return (NULL); 12133965Sjdp memset(a, 0, sizeof(*a)); 12233965Sjdp a->archive.magic = ARCHIVE_READ_DISK_MAGIC; 12333965Sjdp /* We're ready to write a header immediately. */ 12433965Sjdp a->archive.state = ARCHIVE_STATE_HEADER; 12533965Sjdp a->archive.vtable = archive_read_disk_vtable(); 12633965Sjdp a->lookup_uname = trivial_lookup_uname; 12733965Sjdp a->lookup_gname = trivial_lookup_gname; 12833965Sjdp return (&a->archive); 12933965Sjdp} 13033965Sjdp 13160484Sobrienstatic int 13260484Sobrien_archive_read_finish(struct archive *_a) 13360484Sobrien{ 13460484Sobrien struct archive_read_disk *a = (struct archive_read_disk *)_a; 13560484Sobrien 136130561Sobrien if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL) 13760484Sobrien (a->cleanup_gname)(a->lookup_gname_data); 13860484Sobrien if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL) 13960484Sobrien (a->cleanup_uname)(a->lookup_uname_data); 14060484Sobrien archive_string_free(&a->archive.error_string); 14189857Sobrien free(a); 14289857Sobrien return (ARCHIVE_OK); 143130561Sobrien} 144130561Sobrien 145130561Sobrienstatic int 146130561Sobrien_archive_read_close(struct archive *_a) 147130561Sobrien{ 148130561Sobrien (void)_a; /* UNUSED */ 149130561Sobrien return (ARCHIVE_OK); 150130561Sobrien} 15189857Sobrien 15289857Sobrienint 15389857Sobrienarchive_read_disk_set_symlink_logical(struct archive *_a) 154130561Sobrien{ 155130561Sobrien struct archive_read_disk *a = (struct archive_read_disk *)_a; 15689857Sobrien a->symlink_mode = 'L'; 15789857Sobrien a->follow_symlinks = 1; 15889857Sobrien return (ARCHIVE_OK); 159130561Sobrien} 16089857Sobrien 16189857Sobrienint 16289857Sobrienarchive_read_disk_set_symlink_physical(struct archive *_a) 16389857Sobrien{ 16433965Sjdp struct archive_read_disk *a = (struct archive_read_disk *)_a; 16533965Sjdp a->symlink_mode = 'P'; 16633965Sjdp a->follow_symlinks = 0; 16760484Sobrien return (ARCHIVE_OK); 16833965Sjdp} 16933965Sjdp 17033965Sjdpint 17133965Sjdparchive_read_disk_set_symlink_hybrid(struct archive *_a) 17233965Sjdp{ 17333965Sjdp struct archive_read_disk *a = (struct archive_read_disk *)_a; 17433965Sjdp a->symlink_mode = 'H'; 17533965Sjdp a->follow_symlinks = 1; /* Follow symlinks initially. */ 17633965Sjdp return (ARCHIVE_OK); 17733965Sjdp} 17833965Sjdp 17933965Sjdp/* 18060484Sobrien * Trivial implementations of gname/uname lookup functions. 18160484Sobrien * These are normally overridden by the client, but these stub 18233965Sjdp * versions ensure that we always have something that works. 18360484Sobrien */ 18433965Sjdpstatic const char * 18560484Sobrientrivial_lookup_gname(void *private_data, gid_t gid) 18633965Sjdp{ 18760484Sobrien (void)private_data; /* UNUSED */ 18833965Sjdp (void)gid; /* UNUSED */ 18960484Sobrien return (NULL); 19033965Sjdp} 19160484Sobrien 19233965Sjdpstatic const char * 19360484Sobrientrivial_lookup_uname(void *private_data, uid_t uid) 19460484Sobrien{ 19560484Sobrien (void)private_data; /* UNUSED */ 19660484Sobrien (void)uid; /* UNUSED */ 19760484Sobrien return (NULL); 19860484Sobrien} 199130561Sobrien