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