1/*- 2 * Copyright (c) 2003-2009 Tim Kientzle 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer 10 * in this position and unchanged. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include "archive_platform.h" 28__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk.c 189429 2009-03-06 04:35:31Z kientzle $"); 29 30#include "archive.h" 31#include "archive_string.h" 32#include "archive_entry.h" 33#include "archive_private.h" 34#include "archive_read_disk_private.h" 35 36static int _archive_read_finish(struct archive *); 37static int _archive_read_close(struct archive *); 38static const char *trivial_lookup_gname(void *, gid_t gid); 39static const char *trivial_lookup_uname(void *, uid_t uid); 40 41static struct archive_vtable * 42archive_read_disk_vtable(void) 43{ 44 static struct archive_vtable av; 45 static int inited = 0; 46 47 if (!inited) { 48 av.archive_finish = _archive_read_finish; 49 av.archive_close = _archive_read_close; 50 } 51 return (&av); 52} 53 54const char * 55archive_read_disk_gname(struct archive *_a, gid_t gid) 56{ 57 struct archive_read_disk *a = (struct archive_read_disk *)_a; 58 if (a->lookup_gname != NULL) 59 return ((*a->lookup_gname)(a->lookup_gname_data, gid)); 60 return (NULL); 61} 62 63const char * 64archive_read_disk_uname(struct archive *_a, uid_t uid) 65{ 66 struct archive_read_disk *a = (struct archive_read_disk *)_a; 67 if (a->lookup_uname != NULL) 68 return ((*a->lookup_uname)(a->lookup_uname_data, uid)); 69 return (NULL); 70} 71 72int 73archive_read_disk_set_gname_lookup(struct archive *_a, 74 void *private_data, 75 const char * (*lookup_gname)(void *private, gid_t gid), 76 void (*cleanup_gname)(void *private)) 77{ 78 struct archive_read_disk *a = (struct archive_read_disk *)_a; 79 __archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC, 80 ARCHIVE_STATE_ANY, "archive_read_disk_set_gname_lookup"); 81 82 if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL) 83 (a->cleanup_gname)(a->lookup_gname_data); 84 85 a->lookup_gname = lookup_gname; 86 a->cleanup_gname = cleanup_gname; 87 a->lookup_gname_data = private_data; 88 return (ARCHIVE_OK); 89} 90 91int 92archive_read_disk_set_uname_lookup(struct archive *_a, 93 void *private_data, 94 const char * (*lookup_uname)(void *private, uid_t uid), 95 void (*cleanup_uname)(void *private)) 96{ 97 struct archive_read_disk *a = (struct archive_read_disk *)_a; 98 __archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC, 99 ARCHIVE_STATE_ANY, "archive_read_disk_set_uname_lookup"); 100 101 if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL) 102 (a->cleanup_uname)(a->lookup_uname_data); 103 104 a->lookup_uname = lookup_uname; 105 a->cleanup_uname = cleanup_uname; 106 a->lookup_uname_data = private_data; 107 return (ARCHIVE_OK); 108} 109 110/* 111 * Create a new archive_read_disk object and initialize it with global state. 112 */ 113struct archive * 114archive_read_disk_new(void) 115{ 116 struct archive_read_disk *a; 117 118 a = (struct archive_read_disk *)malloc(sizeof(*a)); 119 if (a == NULL) 120 return (NULL); 121 memset(a, 0, sizeof(*a)); 122 a->archive.magic = ARCHIVE_READ_DISK_MAGIC; 123 /* We're ready to write a header immediately. */ 124 a->archive.state = ARCHIVE_STATE_HEADER; 125 a->archive.vtable = archive_read_disk_vtable(); 126 a->lookup_uname = trivial_lookup_uname; 127 a->lookup_gname = trivial_lookup_gname; 128 return (&a->archive); 129} 130 131static int 132_archive_read_finish(struct archive *_a) 133{ 134 struct archive_read_disk *a = (struct archive_read_disk *)_a; 135 136 if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL) 137 (a->cleanup_gname)(a->lookup_gname_data); 138 if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL) 139 (a->cleanup_uname)(a->lookup_uname_data); 140 archive_string_free(&a->archive.error_string); 141 free(a); 142 return (ARCHIVE_OK); 143} 144 145static int 146_archive_read_close(struct archive *_a) 147{ 148 (void)_a; /* UNUSED */ 149 return (ARCHIVE_OK); 150} 151 152int 153archive_read_disk_set_symlink_logical(struct archive *_a) 154{ 155 struct archive_read_disk *a = (struct archive_read_disk *)_a; 156 a->symlink_mode = 'L'; 157 a->follow_symlinks = 1; 158 return (ARCHIVE_OK); 159} 160 161int 162archive_read_disk_set_symlink_physical(struct archive *_a) 163{ 164 struct archive_read_disk *a = (struct archive_read_disk *)_a; 165 a->symlink_mode = 'P'; 166 a->follow_symlinks = 0; 167 return (ARCHIVE_OK); 168} 169 170int 171archive_read_disk_set_symlink_hybrid(struct archive *_a) 172{ 173 struct archive_read_disk *a = (struct archive_read_disk *)_a; 174 a->symlink_mode = 'H'; 175 a->follow_symlinks = 1; /* Follow symlinks initially. */ 176 return (ARCHIVE_OK); 177} 178 179/* 180 * Trivial implementations of gname/uname lookup functions. 181 * These are normally overridden by the client, but these stub 182 * versions ensure that we always have something that works. 183 */ 184static const char * 185trivial_lookup_gname(void *private_data, gid_t gid) 186{ 187 (void)private_data; /* UNUSED */ 188 (void)gid; /* UNUSED */ 189 return (NULL); 190} 191 192static const char * 193trivial_lookup_uname(void *private_data, uid_t uid) 194{ 195 (void)private_data; /* UNUSED */ 196 (void)uid; /* UNUSED */ 197 return (NULL); 198} 199