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#include <fcntl.h> 43#if HAVE_PWD_H 44#include <grp.h> 45#endif 46#include <limits.h> 47#if HAVE_PWD_H 48#include <pwd.h> 49#endif 50#include <stdlib.h> 51#include <string.h> 52#include <time.h> 53#include <unistd.h> 54 55#include "lib.h" 56#include "create.h" 57 58static void 59update_ids(struct memory_file *file) 60{ 61 const char *s; 62 63 if (file->owner != NULL) { 64 uid_t uid; 65 66 if (uid_from_user(file->owner, &uid) == -1) 67 errx(2, "user %s unknown", file->owner); 68 file->st.st_uid = uid; 69 } else { 70 if ((s = user_from_uid(file->st.st_uid, 1)) == NULL) 71 errx(2, "unknown user name for uid %u", 72 (unsigned) file->st.st_uid); 73 file->owner = xstrdup(s); 74 } 75 76 if (file->group != NULL) { 77 gid_t gid; 78 79 if (gid_from_group(file->group, &gid) == -1) 80 errx(2, "group %s unknown", file->group); 81 file->st.st_gid = gid; 82 } else { 83 if ((s = group_from_gid(file->st.st_gid, 1)) == NULL) 84 errx(2, "unknown group name for gid %u", 85 (unsigned) file->st.st_gid); 86 file->group = xstrdup(s); 87 } 88} 89 90struct memory_file * 91make_memory_file(const char *archive_name, void *data, size_t len, 92 const char *owner, const char *group, mode_t mode) 93{ 94 struct memory_file *file; 95 96 file = xmalloc(sizeof(*file)); 97 file->name = archive_name; 98 file->owner = (owner != NULL) ? xstrdup(owner) : NULL; 99 file->group = (group != NULL) ? xstrdup(group) : NULL; 100 file->data = data; 101 file->len = len; 102 103 memset(&file->st, 0, sizeof(file->st)); 104 105 file->st.st_atime = file->st.st_ctime = file->st.st_mtime = time(NULL); 106 107 file->st.st_nlink = 1; 108 file->st.st_size = len; 109 file->st.st_mode = mode | S_IFREG; 110 111 update_ids(file); 112 113 return file; 114} 115 116struct memory_file * 117load_memory_file(const char *disk_name, 118 const char *archive_name, const char *owner, const char *group, 119 mode_t mode) 120{ 121 struct memory_file *file; 122 int fd; 123 124 file = xmalloc(sizeof(*file)); 125 file->name = archive_name; 126 file->owner = (owner != NULL) ? xstrdup(owner) : NULL; 127 file->group = (group != NULL) ? xstrdup(group) : NULL; 128 file->mode = mode; 129 130 fd = open(disk_name, O_RDONLY); 131 if (fd == -1) 132 err(2, "cannot open file %s", disk_name); 133 if (fstat(fd, &file->st) == -1) 134 err(2, "cannot stat file %s", disk_name); 135 136 update_ids(file); 137 138 if ((file->st.st_mode & S_IFMT) != S_IFREG) 139 errx(1, "meta data file %s is not regular file", disk_name); 140 if (file->st.st_size > SSIZE_MAX) 141 errx(2, "meta data file too large: %s", disk_name); 142 file->data = xmalloc(file->st.st_size); 143 144 if (read(fd, file->data, file->st.st_size) != file->st.st_size) 145 err(2, "cannot read file into memory %s", disk_name); 146 147 file->len = file->st.st_size; 148 149 close(fd); 150 151 return file; 152} 153 154void 155free_memory_file(struct memory_file *file) 156{ 157 if (file != NULL) { 158 free(__UNCONST(file->owner)); 159 free(__UNCONST(file->group)); 160 free(file->data); 161 free(file); 162 } 163} 164