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