1 /** $MirOS: src/usr.sbin/makefs/makefs.h,v 1.16 2013/10/31 20:07:26 tg Exp $ */ 2 /* $NetBSD: makefs.h,v 1.20 2008/12/28 21:51:46 christos Exp $ */ 3 4 /* 5 * Copyright (c) 2009, 2010, 2013 6 * Thorsten Glaser <tg@mirbsd.org> 7 * Copyright (c) 2001 Wasabi Systems, Inc. 8 * All rights reserved. 9 * 10 * Written by Luke Mewburn for Wasabi Systems, Inc. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgement: 22 * This product includes software developed for the NetBSD Project by 23 * Wasabi Systems, Inc. 24 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 25 * or promote products derived from this software without specific prior 26 * written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 31 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 32 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38 * POSSIBILITY OF SUCH DAMAGE. 39 */ 40 41 #ifndef _MAKEFS_H 42 #define _MAKEFS_H 43 44 #if HAVE_NBTOOL_CONFIG_H 45 #include "nbtool_config.h" 46 #else 47 #ifndef HAVE_STRUCT_STAT_ST_FLAGS 48 #define HAVE_STRUCT_STAT_ST_FLAGS 1 49 #endif 50 #ifndef HAVE_STRUCT_STAT_ST_GEN 51 #define HAVE_STRUCT_STAT_ST_GEN 1 52 #endif 53 #ifndef HAVE_STRUCT_STAT_ST_MTIMENSEC 54 #define HAVE_STRUCT_STAT_ST_MTIMENSEC 1 55 #endif 56 #ifndef HAVE_STRUCT_STATVFS_F_IOSIZE 57 #define HAVE_STRUCT_STATVFS_F_IOSIZE 1 58 #endif 59 #ifndef HAVE_STRUCT_STAT_BIRTHTIME 60 #define HAVE_STRUCT_STAT_BIRTHTIME 1 61 #endif 62 #ifndef HAVE_FSTATVFS 63 #define HAVE_FSTATVFS 1 64 #endif 65 #endif 66 67 #include <sys/types.h> 68 #include <sys/stat.h> 69 #include <err.h> 70 71 #ifdef DEBIAN 72 #include <stdint.h> 73 #undef __unused 74 #define __unused __attribute__((__unused__)) 75 #endif 76 77 /* 78 * fsnode - 79 * a component of the tree; contains a filename, a pointer to 80 * fsinode, optional symlink name, and tree pointers 81 * 82 * fsinode - 83 * equivalent to an inode, containing serial number (sort of virtual 84 * fs independent inode number) target file system inode number (file 85 * data sector in the cd9660 case), refcount (nlink), and stat buffer 86 * 87 * A tree of fsnodes looks like this: 88 * 89 * name "." "bin" "netbsd" 90 * type S_IFDIR S_IFDIR S_IFREG 91 * next > > NULL 92 * parent NULL NULL NULL 93 * child NULL v 94 * 95 * name "." "ls" 96 * type S_IFDIR S_IFREG 97 * next > NULL 98 * parent ^ ^ (to "bin") 99 * child NULL NULL 100 * 101 * Notes: 102 * - first always points to first entry, at current level, which 103 * must be "." when the tree has been built; during build it may 104 * not be if "." hasn't yet been found by readdir(2). 105 * 106 * - serno is the same for a directory and its dot entry, but they 107 * are not hardlinked to each other because the ffs code doesn't 108 * like that; otherwise, they are unique and mostly sequential, 109 * and the filesystems' code does the right thing anyway 110 */ 111 112 enum fi_flags { 113 FI_SIZED = 1<<0, /* inode sized */ 114 FI_ALLOCATED = 1<<1, /* fsinode->ino allocated */ 115 FI_WRITTEN = 1<<2, /* inode written */ 116 }; 117 118 typedef struct { 119 uint32_t serno; /* serial number / virtual inode no. */ 120 uint32_t ino; /* inode number used on target fs */ 121 uint32_t nlink; /* number of links to this entry */ 122 enum fi_flags flags; /* flags used by fs specific code */ 123 struct stat st; /* stat entry */ 124 } fsinode; 125 126 typedef struct _fsnode { 127 struct _fsnode *parent; /* parent (NULL if root) */ 128 struct _fsnode *child; /* child (if type == S_IFDIR) */ 129 struct _fsnode *next; /* next */ 130 struct _fsnode *first; /* first node of current level (".") */ 131 uint32_t type; /* type of entry */ 132 fsinode *inode; /* actual inode data */ 133 char *symlink; /* symlink target */ 134 char *name; /* file name */ 135 int flags; /* misc flags */ 136 } fsnode; 137 138 #define FSNODE_F_HASSPEC 0x01 /* fsnode has a spec entry */ 139 140 /* 141 * fsinfo_t - contains various settings and parameters pertaining to 142 * the image, including current settings, global options, and fs 143 * specific options 144 */ 145 typedef struct { 146 /* current settings */ 147 off_t size; /* total size */ 148 off_t inodes; /* number of inodes */ 149 uint32_t curinode; /* current inode */ 150 151 /* image settings */ 152 int fd; /* file descriptor of image */ 153 void *superblock; /* superblock */ 154 int onlyspec; /* only add entries in specfile */ 155 156 157 /* global options */ 158 off_t minsize; /* minimum size image should be */ 159 off_t maxsize; /* maximum size image can be */ 160 off_t freefiles; /* free file entries to leave */ 161 int freefilepc; /* free file % */ 162 off_t freeblocks; /* free blocks to leave */ 163 int freeblockpc; /* free block % */ 164 int needswap; /* non-zero if byte swapping needed */ 165 int sectorsize; /* sector size */ 166 167 void *fs_specific; /* File system specific additions. */ 168 } fsinfo_t; 169 170 171 /* 172 * option_t - contains option name, description, pointer to location to store 173 * result, and range checks for the result. Used to simplify fs specific 174 * option setting 175 */ 176 typedef struct { 177 const char *name; /* option name */ 178 int *value; /* where to stuff the value */ 179 int minimum; /* minimum for value */ 180 int maximum; /* maximum for value */ 181 const char *desc; /* option description */ 182 } option_t; 183 184 185 void apply_specfile(const char *, const char *, fsnode *, int); 186 void dump_fsnodes(const char *, fsnode *); 187 const char * inode_type(mode_t); 188 int set_option(option_t *, const char *, const char *); 189 fsnode * walk_dir(const char *, fsnode *); 190 void free_fsnodes(fsnode *); 191 192 void ffs_prep_opts(fsinfo_t *); 193 int ffs_parse_opts(const char *, fsinfo_t *); 194 void ffs_cleanup_opts(fsinfo_t *); 195 void ffs_makefs(const char *, const char *, fsnode *, fsinfo_t *); 196 197 void cd9660_prep_opts(fsinfo_t *); 198 int cd9660_parse_opts(const char *, fsinfo_t *); 199 void cd9660_cleanup_opts(fsinfo_t *); 200 void cd9660_makefs(const char *, const char *, fsnode *, fsinfo_t *); 201 202 203 extern u_int debug; 204 extern size_t maxpathlen; 205 extern struct timespec start_time; 206 207 /* 208 * If -x is specified, we want to exclude nodes which do not appear 209 * in the spec file. 210 */ 211 #define FSNODE_EXCLUDE_P(opts, fsnode) \ 212 ((opts)->onlyspec != 0 && ((fsnode)->flags & FSNODE_F_HASSPEC) == 0) 213 214 #define DEBUG_TIME 0x00000001 215 /* debug bits 1..3 unused at this time */ 216 #define DEBUG_WALK_DIR 0x00000010 217 #define DEBUG_WALK_DIR_NODE 0x00000020 218 #define DEBUG_WALK_DIR_LINKCHECK 0x00000040 219 #define DEBUG_DUMP_FSNODES 0x00000080 220 #define DEBUG_DUMP_FSNODES_VERBOSE 0x00000100 221 #define DEBUG_FS_PARSE_OPTS 0x00000200 222 #define DEBUG_FS_MAKEFS 0x00000400 223 #define DEBUG_FS_VALIDATE 0x00000800 224 #define DEBUG_FS_CREATE_IMAGE 0x00001000 225 #define DEBUG_FS_SIZE_DIR 0x00002000 226 #define DEBUG_FS_SIZE_DIR_NODE 0x00004000 227 #define DEBUG_FS_SIZE_DIR_ADD_DIRENT 0x00008000 228 #define DEBUG_FS_POPULATE 0x00010000 229 #define DEBUG_FS_POPULATE_DIRBUF 0x00020000 230 #define DEBUG_FS_POPULATE_NODE 0x00040000 231 #define DEBUG_FS_WRITE_FILE 0x00080000 232 #define DEBUG_FS_WRITE_FILE_BLOCK 0x00100000 233 #define DEBUG_FS_MAKE_DIRBUF 0x00200000 234 #define DEBUG_FS_WRITE_INODE 0x00400000 235 #define DEBUG_BUF_BREAD 0x00800000 236 #define DEBUG_BUF_BWRITE 0x01000000 237 #define DEBUG_BUF_GETBLK 0x02000000 238 #define DEBUG_APPLY_SPECFILE 0x04000000 239 #define DEBUG_APPLY_SPECENTRY 0x08000000 240 #define DEBUG_APPLY_SPECONLY 0x10000000 241 242 243 #define TIMER_START(x) \ 244 if (debug & DEBUG_TIME) \ 245 gettimeofday(&(x), NULL) 246 247 #define TIMER_RESULTS(x,d) \ 248 if (debug & DEBUG_TIME) { \ 249 struct timeval end, td; \ 250 gettimeofday(&end, NULL); \ 251 timersub(&end, &(x), &td); \ 252 printf("%s took %lld.%06ld seconds\n", \ 253 (d), (long long)td.tv_sec, \ 254 (long)td.tv_usec); \ 255 } 256 257 258 #ifndef DEFAULT_FSTYPE 259 #define DEFAULT_FSTYPE "ffs" 260 #endif 261 262 263 /* 264 * ffs specific settings 265 * --------------------- 266 */ 267 268 #define FFS_EI /* for opposite endian support in ffs headers */ 269 270 271 #endif /* _MAKEFS_H */ 272