1139804Simp/*- 2139013Sdavidxu * Copyright (c) 2007 Joerg Sonnenberger <joerg@NetBSD.org>. 3112904Sjeff * All rights reserved. 4112904Sjeff * 5112904Sjeff * Redistribution and use in source and binary forms, with or without 6112904Sjeff * modification, are permitted provided that the following conditions 7112904Sjeff * are met: 8112904Sjeff * 9112904Sjeff * 1. Redistributions of source code must retain the above copyright 10112904Sjeff * notice, this list of conditions and the following disclaimer. 11112904Sjeff * 2. Redistributions in binary form must reproduce the above copyright 12112904Sjeff * notice, this list of conditions and the following disclaimer in 13112904Sjeff * the documentation and/or other materials provided with the 14112904Sjeff * distribution. 15112904Sjeff * 16112904Sjeff * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17112904Sjeff * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18112904Sjeff * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 19112904Sjeff * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 20112904Sjeff * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 21112904Sjeff * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 22112904Sjeff * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23112904Sjeff * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 24112904Sjeff * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25112904Sjeff * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 26112904Sjeff * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27112904Sjeff * SUCH DAMAGE. 28116182Sobrien */ 29116182Sobrien 30116182Sobrien#if HAVE_CONFIG_H 31162536Sdavidxu#include "config.h" 32112904Sjeff#endif 33112904Sjeff 34131431Smarcel#include <nbcompat.h> 35112904Sjeff 36115765Sjeff#if HAVE_SYS_STAT_H 37112904Sjeff#include <sys/stat.h> 38164033Srwatson#endif 39112904Sjeff#if HAVE_ERR_H 40161678Sdavidxu#include <err.h> 41165369Sdavidxu#endif 42161678Sdavidxu#include <fcntl.h> 43112904Sjeff#if HAVE_PWD_H 44112904Sjeff#include <grp.h> 45112904Sjeff#endif 46216641Sdavidxu#include <limits.h> 47139013Sdavidxu#if HAVE_PWD_H 48112904Sjeff#include <pwd.h> 49112904Sjeff#endif 50139013Sdavidxu#include <stdlib.h> 51139013Sdavidxu#include <string.h> 52139013Sdavidxu#include <time.h> 53139013Sdavidxu#include <unistd.h> 54139013Sdavidxu 55139013Sdavidxu#include "lib.h" 56165369Sdavidxu#include "create.h" 57165369Sdavidxu 58205014Snwhitehornstatic void 59162536Sdavidxuupdate_ids(struct memory_file *file) 60162536Sdavidxu{ 61162536Sdavidxu const char *s; 62179970Sdavidxu 63179970Sdavidxu if (file->owner != NULL) { 64179970Sdavidxu uid_t uid; 65161678Sdavidxu 66161678Sdavidxu if (uid_from_user(file->owner, &uid) == -1) 67161678Sdavidxu errx(2, "user %s unknown", file->owner); 68161678Sdavidxu file->st.st_uid = uid; 69161678Sdavidxu } else { 70161678Sdavidxu if ((s = user_from_uid(file->st.st_uid, 1)) == NULL) 71161678Sdavidxu errx(2, "unknown user name for uid %u", 72161678Sdavidxu (unsigned) file->st.st_uid); 73161678Sdavidxu file->owner = xstrdup(s); 74161678Sdavidxu } 75161678Sdavidxu 76161678Sdavidxu if (file->group != NULL) { 77161678Sdavidxu gid_t gid; 78161678Sdavidxu 79161678Sdavidxu if (gid_from_group(file->group, &gid) == -1) 80161678Sdavidxu errx(2, "group %s unknown", file->group); 81161678Sdavidxu file->st.st_gid = gid; 82161678Sdavidxu } else { 83161678Sdavidxu if ((s = group_from_gid(file->st.st_gid, 1)) == NULL) 84161678Sdavidxu errx(2, "unknown group name for gid %u", 85161678Sdavidxu (unsigned) file->st.st_gid); 86161678Sdavidxu file->group = xstrdup(s); 87115765Sjeff } 88161678Sdavidxu} 89161678Sdavidxu 90161678Sdavidxustruct memory_file * 91161678Sdavidxumake_memory_file(const char *archive_name, void *data, size_t len, 92161678Sdavidxu const char *owner, const char *group, mode_t mode) 93161678Sdavidxu{ 94161678Sdavidxu struct memory_file *file; 95161678Sdavidxu 96161678Sdavidxu file = xmalloc(sizeof(*file)); 97161678Sdavidxu file->name = archive_name; 98161678Sdavidxu file->owner = (owner != NULL) ? xstrdup(owner) : NULL; 99161678Sdavidxu file->group = (group != NULL) ? xstrdup(group) : NULL; 100161678Sdavidxu file->data = data; 101161678Sdavidxu file->len = len; 102161678Sdavidxu 103170300Sjeff memset(&file->st, 0, sizeof(file->st)); 104170300Sjeff 105161678Sdavidxu file->st.st_atime = file->st.st_ctime = file->st.st_mtime = time(NULL); 106161678Sdavidxu 107161678Sdavidxu file->st.st_nlink = 1; 108161678Sdavidxu file->st.st_size = len; 109161678Sdavidxu file->st.st_mode = mode | S_IFREG; 110161678Sdavidxu 111161678Sdavidxu update_ids(file); 112161678Sdavidxu 113161678Sdavidxu return file; 114161742Sdavidxu} 115161678Sdavidxu 116201991Sdavidxustruct memory_file * 117201991Sdavidxuload_memory_file(const char *disk_name, 118201991Sdavidxu const char *archive_name, const char *owner, const char *group, 119201991Sdavidxu mode_t mode) 120201991Sdavidxu{ 121201991Sdavidxu struct memory_file *file; 122115765Sjeff int fd; 123115765Sjeff 124161678Sdavidxu file = xmalloc(sizeof(*file)); 125161678Sdavidxu file->name = archive_name; 126201991Sdavidxu file->owner = (owner != NULL) ? xstrdup(owner) : NULL; 127201991Sdavidxu file->group = (group != NULL) ? xstrdup(group) : NULL; 128201991Sdavidxu file->mode = mode; 129201991Sdavidxu 130201991Sdavidxu fd = open(disk_name, O_RDONLY); 131201991Sdavidxu if (fd == -1) 132201991Sdavidxu err(2, "cannot open file %s", disk_name); 133201991Sdavidxu if (fstat(fd, &file->st) == -1) 134201991Sdavidxu err(2, "cannot stat file %s", disk_name); 135201991Sdavidxu 136161678Sdavidxu update_ids(file); 137138224Sdavidxu 138161678Sdavidxu if ((file->st.st_mode & S_IFMT) != S_IFREG) 139161678Sdavidxu errx(1, "meta data file %s is not regular file", disk_name); 140161678Sdavidxu if (file->st.st_size > SSIZE_MAX) 141161678Sdavidxu errx(2, "meta data file too large: %s", disk_name); 142201991Sdavidxu file->data = xmalloc(file->st.st_size); 143177848Sdavidxu 144177848Sdavidxu if (read(fd, file->data, file->st.st_size) != file->st.st_size) 145161678Sdavidxu err(2, "cannot read file into memory %s", disk_name); 146201991Sdavidxu 147201991Sdavidxu file->len = file->st.st_size; 148161678Sdavidxu 149161678Sdavidxu close(fd); 150161678Sdavidxu 151161678Sdavidxu return file; 152158377Sdavidxu} 153161678Sdavidxu 154161678Sdavidxuvoid 155161678Sdavidxufree_memory_file(struct memory_file *file) 156201991Sdavidxu{ 157138224Sdavidxu if (file != NULL) { 158115765Sjeff free(__UNCONST(file->owner)); 159161678Sdavidxu free(__UNCONST(file->group)); 160189756Sdavidxu free(file->data); 161161678Sdavidxu free(file); 162161678Sdavidxu } 163161678Sdavidxu} 164161678Sdavidxu