1 /*- 2 * Copyright (c) 2007 Joerg Sonnenberger <joerg@NetBSD.org>. 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 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in 13 * the documentation and/or other materials provided with the 14 * distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 19 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 20 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 26 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #if HAVE_CONFIG_H 31 #include "config.h" 32 #endif 33 34 #include <nbcompat.h> 35 36 #if HAVE_SYS_STAT_H 37 #include <sys/stat.h> 38 #endif 39 #if HAVE_ERR_H 40 #include <err.h> 41 #endif 42 #if HAVE_PWD_H 43 #include <grp.h> 44 #endif 45 #if HAVE_PWD_H 46 #include <pwd.h> 47 #endif 48 #if HAVE_STDLIB_H 49 #include <stdlib.h> 50 #endif 51 #if HAVE_STRING_H 52 #include <string.h> 53 #endif 54 #if HAVE_TIME_H 55 #include <time.h> 56 #endif 57 #if HAVE_UNISTD_H 58 #include <unistd.h> 59 #endif 60 #if HAVE_FCNTL_H 61 #include <fcntl.h> 62 #endif 63 64 #include "lib.h" 65 #include "create.h" 66 67 static void 68 update_ids(struct memory_file *file) 69 { 70 if (file->owner != NULL) { 71 uid_t uid; 72 73 if (uid_from_user(file->owner, &uid) == -1) 74 errx(2, "user %s unknown", file->owner); 75 file->st.st_uid = uid; 76 } else { 77 file->owner = user_from_uid(file->st.st_uid, 1); 78 } 79 80 if (file->group != NULL) { 81 gid_t gid; 82 83 if (gid_from_group(file->group, &gid) == -1) 84 errx(2, "group %s unknown", file->group); 85 file->group = file->group; 86 file->st.st_gid = gid; 87 } else { 88 file->group = group_from_gid(file->st.st_gid, 1); 89 } 90 } 91 92 struct memory_file * 93 make_memory_file(const char *archive_name, void *data, size_t len, 94 const char *owner, const char *group, mode_t mode) 95 { 96 struct memory_file *file; 97 98 file = xmalloc(sizeof(*file)); 99 file->name = archive_name; 100 file->owner = owner; 101 file->group = group; 102 file->data = data; 103 file->len = len; 104 105 memset(&file->st, 0, sizeof(file->st)); 106 107 file->st.st_atime = file->st.st_ctime = file->st.st_mtime = time(NULL); 108 109 file->st.st_nlink = 1; 110 file->st.st_size = len; 111 file->st.st_mode = mode | S_IFREG; 112 113 update_ids(file); 114 115 return file; 116 } 117 118 struct memory_file * 119 load_memory_file(const char *disk_name, 120 const char *archive_name, const char *owner, const char *group, 121 mode_t mode) 122 { 123 struct memory_file *file; 124 int fd; 125 126 file = xmalloc(sizeof(*file)); 127 file->name = archive_name; 128 file->owner = owner; 129 file->group = group; 130 file->mode = mode; 131 132 fd = open(disk_name, O_RDONLY); 133 if (fd == -1) 134 err(2, "cannot open file %s", disk_name); 135 if (fstat(fd, &file->st) == -1) 136 err(2, "cannot stat file %s", disk_name); 137 138 update_ids(file); 139 140 if ((file->st.st_mode & S_IFMT) != S_IFREG) 141 errx(1, "meta data file %s is not regular file", disk_name); 142 if (file->st.st_size > SSIZE_MAX) 143 errx(2, "meta data file too large: %s", disk_name); 144 file->data = xmalloc(file->st.st_size); 145 146 if (read(fd, file->data, file->st.st_size) != file->st.st_size) 147 err(2, "cannot read file into memory %s", disk_name); 148 149 file->len = file->st.st_size; 150 151 close(fd); 152 153 return file; 154 } 155 156 void 157 free_memory_file(struct memory_file *file) 158 { 159 if (file != NULL) { 160 free(file->data); 161 free(file); 162 } 163 } 164