URL
https://opencores.org/ocsvn/eco32/eco32/trunk
Subversion Repositories eco32
Compare Revisions
- This comparison shows the changes necessary to convert path
/eco32
- from Rev 173 to Rev 174
- ↔ Reverse comparison
Rev 173 → Rev 174
/trunk/disk/tools/fs-NetBSD/Makefile.run
8,7 → 8,7
all: proto-fs |
$(BUILD)/bin/NetBSD-makefs -t ffs -B be -s 106496b \ |
-f 20000 -o version=1,bsize=8192,fsize=1024 \ |
fs.img ./root |
-F add.spec fs.img ./root |
dd if=fs.img of=$(DISK) bs=512 seek=81920 conv=notrunc |
$(BUILD)/bin/NetBSD-wrboot ./bootblk $(DISK) 3 |
$(BUILD)/bin/NetBSD-dsklbl -wb $(DISK) 3 |
/trunk/disk/tools/fs-NetBSD/add.spec
0,0 → 1,7
# |
# add.spec -- additional specifications for NetBSD file system |
# |
|
. type dir |
dev type dir |
console type char mode 777 uid 0 gid 0 device 0 |
/trunk/disk/tools/fs-NetBSD/makefs/walk.c
310,10 → 310,7
if ((fp = fopen(specfile, "r")) == NULL) |
err(1, "Can't open `%s'", specfile); |
TIMER_START(start); |
/* !!!!! HG: */ |
//root = spec(fp); |
root = NULL; |
/* :HG !!!!! */ |
root = spec(fp); |
TIMER_RESULTS(start, "spec"); |
if (fclose(fp) == EOF) |
err(1, "Can't close `%s'", specfile); |
327,9 → 324,7
/* merge in the changes */ |
apply_specdir(dir, root, parent, speconly); |
|
/* !!!!! HG: */ |
//free_nodes(root); |
/* :HG !!!!! */ |
free_nodes(root); |
} |
|
static void |
/trunk/disk/tools/fs-NetBSD/makefs/setmode.c
0,0 → 1,487
/* $NetBSD: setmode.c,v 1.31 2005/10/01 20:08:01 christos Exp $ */ |
|
/* |
* Copyright (c) 1989, 1993, 1994 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Dave Borman at Cray Research, Inc. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
|
#define S_ISTXT 0001000 /* sticky bit */ |
|
#include <sys/cdefs.h> |
|
#include <sys/types.h> |
#include <sys/stat.h> |
|
#include <assert.h> |
#include <ctype.h> |
#include <errno.h> |
#include <signal.h> |
#include <stdlib.h> |
#include <limits.h> |
#include <unistd.h> |
#include <assert.h> |
|
#ifdef SETMODE_DEBUG |
#include <stdio.h> |
#endif |
|
#ifdef __weak_alias |
__weak_alias(getmode,_getmode) |
__weak_alias(setmode,_setmode) |
#endif |
|
#define SET_LEN 6 /* initial # of bitcmd struct to malloc */ |
#define SET_LEN_INCR 4 /* # of bitcmd structs to add as needed */ |
|
typedef struct bitcmd { |
char cmd; |
char cmd2; |
mode_t bits; |
} BITCMD; |
|
#define CMD2_CLR 0x01 |
#define CMD2_SET 0x02 |
#define CMD2_GBITS 0x04 |
#define CMD2_OBITS 0x08 |
#define CMD2_UBITS 0x10 |
|
static BITCMD *addcmd __P((BITCMD *, mode_t, mode_t, mode_t, mode_t)); |
static void compress_mode __P((BITCMD *)); |
#ifdef SETMODE_DEBUG |
static void dumpmode __P((BITCMD *)); |
#endif |
|
/* |
* Given the old mode and an array of bitcmd structures, apply the operations |
* described in the bitcmd structures to the old mode, and return the new mode. |
* Note that there is no '=' command; a strict assignment is just a '-' (clear |
* bits) followed by a '+' (set bits). |
*/ |
mode_t |
getmode(bbox, omode) |
const void *bbox; |
mode_t omode; |
{ |
const BITCMD *set; |
mode_t clrval, newmode, value; |
|
assert(bbox != NULL); |
|
set = (const BITCMD *)bbox; |
newmode = omode; |
for (value = 0;; set++) |
switch(set->cmd) { |
/* |
* When copying the user, group or other bits around, we "know" |
* where the bits are in the mode so that we can do shifts to |
* copy them around. If we don't use shifts, it gets real |
* grundgy with lots of single bit checks and bit sets. |
*/ |
case 'u': |
value = (newmode & S_IRWXU) >> 6; |
goto common; |
|
case 'g': |
value = (newmode & S_IRWXG) >> 3; |
goto common; |
|
case 'o': |
value = newmode & S_IRWXO; |
common: if (set->cmd2 & CMD2_CLR) { |
clrval = |
(set->cmd2 & CMD2_SET) ? S_IRWXO : value; |
if (set->cmd2 & CMD2_UBITS) |
newmode &= ~((clrval<<6) & set->bits); |
if (set->cmd2 & CMD2_GBITS) |
newmode &= ~((clrval<<3) & set->bits); |
if (set->cmd2 & CMD2_OBITS) |
newmode &= ~(clrval & set->bits); |
} |
if (set->cmd2 & CMD2_SET) { |
if (set->cmd2 & CMD2_UBITS) |
newmode |= (value<<6) & set->bits; |
if (set->cmd2 & CMD2_GBITS) |
newmode |= (value<<3) & set->bits; |
if (set->cmd2 & CMD2_OBITS) |
newmode |= value & set->bits; |
} |
break; |
|
case '+': |
newmode |= set->bits; |
break; |
|
case '-': |
newmode &= ~set->bits; |
break; |
|
case 'X': |
if (omode & (S_IFDIR|S_IXUSR|S_IXGRP|S_IXOTH)) |
newmode |= set->bits; |
break; |
|
case '\0': |
default: |
#ifdef SETMODE_DEBUG |
(void)printf("getmode:%04o -> %04o\n", omode, newmode); |
#endif |
return (newmode); |
} |
} |
|
#define ADDCMD(a, b, c, d) do { \ |
if (set >= endset) { \ |
BITCMD *newset; \ |
setlen += SET_LEN_INCR; \ |
newset = realloc(saveset, sizeof(BITCMD) * setlen); \ |
if (newset == NULL) \ |
goto out; \ |
set = newset + (set - saveset); \ |
saveset = newset; \ |
endset = newset + (setlen - 2); \ |
} \ |
set = addcmd(set, (mode_t)(a), (mode_t)(b), (mode_t)(c), (d)); \ |
} while (/*CONSTCOND*/0) |
|
#define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) |
|
void * |
setmode(p) |
const char *p; |
{ |
int serrno; |
char op, *ep; |
BITCMD *set, *saveset, *endset; |
sigset_t signset, sigoset; |
mode_t mask, perm, permXbits, who; |
long lval; |
int equalopdone = 0; /* pacify gcc */ |
int setlen; |
|
if (!*p) { |
errno = EINVAL; |
return NULL; |
} |
|
/* |
* Get a copy of the mask for the permissions that are mask relative. |
* Flip the bits, we want what's not set. Since it's possible that |
* the caller is opening files inside a signal handler, protect them |
* as best we can. |
*/ |
sigfillset(&signset); |
(void)sigprocmask(SIG_BLOCK, &signset, &sigoset); |
(void)umask(mask = umask(0)); |
mask = ~mask; |
(void)sigprocmask(SIG_SETMASK, &sigoset, NULL); |
|
setlen = SET_LEN + 2; |
|
if ((set = malloc((u_int)(sizeof(BITCMD) * setlen))) == NULL) |
return (NULL); |
saveset = set; |
endset = set + (setlen - 2); |
|
/* |
* If an absolute number, get it and return; disallow non-octal digits |
* or illegal bits. |
*/ |
if (isdigit((unsigned char)*p)) { |
errno = 0; |
lval = strtol(p, &ep, 8); |
if (*ep) { |
errno = EINVAL; |
goto out; |
} |
if (errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN)) |
goto out; |
if (lval & ~(STANDARD_BITS|S_ISTXT)) { |
errno = EINVAL; |
goto out; |
} |
perm = (mode_t)lval; |
ADDCMD('=', (STANDARD_BITS|S_ISTXT), perm, mask); |
set->cmd = 0; |
return (saveset); |
} |
|
/* |
* Build list of structures to set/clear/copy bits as described by |
* each clause of the symbolic mode. |
*/ |
for (;;) { |
/* First, find out which bits might be modified. */ |
for (who = 0;; ++p) { |
switch (*p) { |
case 'a': |
who |= STANDARD_BITS; |
break; |
case 'u': |
who |= S_ISUID|S_IRWXU; |
break; |
case 'g': |
who |= S_ISGID|S_IRWXG; |
break; |
case 'o': |
who |= S_IRWXO; |
break; |
default: |
goto getop; |
} |
} |
|
getop: if ((op = *p++) != '+' && op != '-' && op != '=') { |
errno = EINVAL; |
goto out; |
} |
if (op == '=') |
equalopdone = 0; |
|
who &= ~S_ISTXT; |
for (perm = 0, permXbits = 0;; ++p) { |
switch (*p) { |
case 'r': |
perm |= S_IRUSR|S_IRGRP|S_IROTH; |
break; |
case 's': |
/* |
* If specific bits where requested and |
* only "other" bits ignore set-id. |
*/ |
if (who == 0 || (who & ~S_IRWXO)) |
perm |= S_ISUID|S_ISGID; |
break; |
case 't': |
/* |
* If specific bits where requested and |
* only "other" bits ignore set-id. |
*/ |
if (who == 0 || (who & ~S_IRWXO)) { |
who |= S_ISTXT; |
perm |= S_ISTXT; |
} |
break; |
case 'w': |
perm |= S_IWUSR|S_IWGRP|S_IWOTH; |
break; |
case 'X': |
permXbits = S_IXUSR|S_IXGRP|S_IXOTH; |
break; |
case 'x': |
perm |= S_IXUSR|S_IXGRP|S_IXOTH; |
break; |
case 'u': |
case 'g': |
case 'o': |
/* |
* When ever we hit 'u', 'g', or 'o', we have |
* to flush out any partial mode that we have, |
* and then do the copying of the mode bits. |
*/ |
if (perm) { |
ADDCMD(op, who, perm, mask); |
perm = 0; |
} |
if (op == '=') |
equalopdone = 1; |
if (op == '+' && permXbits) { |
ADDCMD('X', who, permXbits, mask); |
permXbits = 0; |
} |
ADDCMD(*p, who, op, mask); |
break; |
|
default: |
/* |
* Add any permissions that we haven't already |
* done. |
*/ |
if (perm || (op == '=' && !equalopdone)) { |
if (op == '=') |
equalopdone = 1; |
ADDCMD(op, who, perm, mask); |
perm = 0; |
} |
if (permXbits) { |
ADDCMD('X', who, permXbits, mask); |
permXbits = 0; |
} |
goto apply; |
} |
} |
|
apply: if (!*p) |
break; |
if (*p != ',') |
goto getop; |
++p; |
} |
set->cmd = 0; |
#ifdef SETMODE_DEBUG |
(void)printf("Before compress_mode()\n"); |
dumpmode(saveset); |
#endif |
compress_mode(saveset); |
#ifdef SETMODE_DEBUG |
(void)printf("After compress_mode()\n"); |
dumpmode(saveset); |
#endif |
return (saveset); |
out: |
serrno = errno; |
free(saveset); |
errno = serrno; |
return NULL; |
} |
|
static BITCMD * |
addcmd(set, op, who, oparg, mask) |
BITCMD *set; |
mode_t oparg, who, op, mask; |
{ |
|
assert(set != NULL); |
|
switch (op) { |
case '=': |
set->cmd = '-'; |
set->bits = who ? who : STANDARD_BITS; |
set++; |
|
op = '+'; |
/* FALLTHROUGH */ |
case '+': |
case '-': |
case 'X': |
set->cmd = op; |
set->bits = (who ? who : mask) & oparg; |
break; |
|
case 'u': |
case 'g': |
case 'o': |
set->cmd = op; |
if (who) { |
set->cmd2 = ((who & S_IRUSR) ? CMD2_UBITS : 0) | |
((who & S_IRGRP) ? CMD2_GBITS : 0) | |
((who & S_IROTH) ? CMD2_OBITS : 0); |
set->bits = (mode_t)~0; |
} else { |
set->cmd2 = CMD2_UBITS | CMD2_GBITS | CMD2_OBITS; |
set->bits = mask; |
} |
|
if (oparg == '+') |
set->cmd2 |= CMD2_SET; |
else if (oparg == '-') |
set->cmd2 |= CMD2_CLR; |
else if (oparg == '=') |
set->cmd2 |= CMD2_SET|CMD2_CLR; |
break; |
} |
return (set + 1); |
} |
|
#ifdef SETMODE_DEBUG |
static void |
dumpmode(set) |
BITCMD *set; |
{ |
|
assert(set != NULL); |
|
for (; set->cmd; ++set) |
(void)printf("cmd: '%c' bits %04o%s%s%s%s%s%s\n", |
set->cmd, set->bits, set->cmd2 ? " cmd2:" : "", |
set->cmd2 & CMD2_CLR ? " CLR" : "", |
set->cmd2 & CMD2_SET ? " SET" : "", |
set->cmd2 & CMD2_UBITS ? " UBITS" : "", |
set->cmd2 & CMD2_GBITS ? " GBITS" : "", |
set->cmd2 & CMD2_OBITS ? " OBITS" : ""); |
} |
#endif |
|
/* |
* Given an array of bitcmd structures, compress by compacting consecutive |
* '+', '-' and 'X' commands into at most 3 commands, one of each. The 'u', |
* 'g' and 'o' commands continue to be separate. They could probably be |
* compacted, but it's not worth the effort. |
*/ |
static void |
compress_mode(set) |
BITCMD *set; |
{ |
BITCMD *nset; |
int setbits, clrbits, Xbits, op; |
|
assert(set != NULL); |
|
for (nset = set;;) { |
/* Copy over any 'u', 'g' and 'o' commands. */ |
while ((op = nset->cmd) != '+' && op != '-' && op != 'X') { |
*set++ = *nset++; |
if (!op) |
return; |
} |
|
for (setbits = clrbits = Xbits = 0;; nset++) { |
if ((op = nset->cmd) == '-') { |
clrbits |= nset->bits; |
setbits &= ~nset->bits; |
Xbits &= ~nset->bits; |
} else if (op == '+') { |
setbits |= nset->bits; |
clrbits &= ~nset->bits; |
Xbits &= ~nset->bits; |
} else if (op == 'X') |
Xbits |= nset->bits & ~setbits; |
else |
break; |
} |
if (clrbits) { |
set->cmd = '-'; |
set->cmd2 = 0; |
set->bits = clrbits; |
set++; |
} |
if (setbits) { |
set->cmd = '+'; |
set->cmd2 = 0; |
set->bits = setbits; |
set++; |
} |
if (Xbits) { |
set->cmd = 'X'; |
set->cmd2 = 0; |
set->bits = Xbits; |
set++; |
} |
} |
} |
/trunk/disk/tools/fs-NetBSD/makefs/mkfs.c
155,7 → 155,7
// sizeof(sblock.fs_volname)); |
strncpy((char *)sblock.fs_volname, ffs_opts->label, |
sizeof(sblock.fs_volname)); |
/* :HG !!!!! */ |
/* :HG !!!!! */ |
|
if (Oflag == 0) { |
sblock.fs_old_inodefmt = FS_42INODEFMT; |
/trunk/disk/tools/fs-NetBSD/makefs/pack_dev.c
0,0 → 1,287
/* $NetBSD: pack_dev.c,v 1.11 2011/08/27 18:37:41 joerg Exp $ */ |
|
/*- |
* Copyright (c) 1998, 2001 The NetBSD Foundation, Inc. |
* All rights reserved. |
* |
* This code is derived from software contributed to The NetBSD Foundation |
* by Charles M. Hannum. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* |
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
* POSSIBILITY OF SUCH DAMAGE. |
*/ |
|
#if HAVE_NBTOOL_CONFIG_H |
#include "nbtool_config.h" |
#endif |
|
#include <sys/cdefs.h> |
|
#include <sys/types.h> |
#include <sys/stat.h> |
|
#include <limits.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <unistd.h> |
|
#include "pack_dev.h" |
|
static pack_t pack_netbsd; |
static pack_t pack_freebsd; |
static pack_t pack_8_8; |
static pack_t pack_12_20; |
static pack_t pack_14_18; |
static pack_t pack_8_24; |
static pack_t pack_bsdos; |
static int compare_format(const void *, const void *); |
|
static const char iMajorError[] = "invalid major number"; |
static const char iMinorError[] = "invalid minor number"; |
static const char tooManyFields[] = "too many fields for format"; |
|
/* exported */ |
portdev_t |
pack_native(int n, u_long numbers[], const char **error) |
{ |
portdev_t dev = 0; |
|
if (n == 2) { |
dev = makedev(numbers[0], numbers[1]); |
if ((u_long)major(dev) != numbers[0]) |
*error = iMajorError; |
else if ((u_long)minor(dev) != numbers[1]) |
*error = iMinorError; |
} else |
*error = tooManyFields; |
return (dev); |
} |
|
|
static portdev_t |
pack_netbsd(int n, u_long numbers[], const char **error) |
{ |
portdev_t dev = 0; |
|
if (n == 2) { |
dev = makedev_netbsd(numbers[0], numbers[1]); |
if ((u_long)major_netbsd(dev) != numbers[0]) |
*error = iMajorError; |
else if ((u_long)minor_netbsd(dev) != numbers[1]) |
*error = iMinorError; |
} else |
*error = tooManyFields; |
return (dev); |
} |
|
|
#define major_freebsd(x) ((int32_t)(((x) & 0x0000ff00) >> 8)) |
#define minor_freebsd(x) ((int32_t)(((x) & 0xffff00ff) >> 0)) |
#define makedev_freebsd(x,y) ((portdev_t)((((x) << 8) & 0x0000ff00) | \ |
(((y) << 0) & 0xffff00ff))) |
|
static portdev_t |
pack_freebsd(int n, u_long numbers[], const char **error) |
{ |
portdev_t dev = 0; |
|
if (n == 2) { |
dev = makedev_freebsd(numbers[0], numbers[1]); |
if ((u_long)major_freebsd(dev) != numbers[0]) |
*error = iMajorError; |
if ((u_long)minor_freebsd(dev) != numbers[1]) |
*error = iMinorError; |
} else |
*error = tooManyFields; |
return (dev); |
} |
|
|
#define major_8_8(x) ((int32_t)(((x) & 0x0000ff00) >> 8)) |
#define minor_8_8(x) ((int32_t)(((x) & 0x000000ff) >> 0)) |
#define makedev_8_8(x,y) ((portdev_t)((((x) << 8) & 0x0000ff00) | \ |
(((y) << 0) & 0x000000ff))) |
|
static portdev_t |
pack_8_8(int n, u_long numbers[], const char **error) |
{ |
portdev_t dev = 0; |
|
if (n == 2) { |
dev = makedev_8_8(numbers[0], numbers[1]); |
if ((u_long)major_8_8(dev) != numbers[0]) |
*error = iMajorError; |
if ((u_long)minor_8_8(dev) != numbers[1]) |
*error = iMinorError; |
} else |
*error = tooManyFields; |
return (dev); |
} |
|
|
#define major_12_20(x) ((int32_t)(((x) & 0xfff00000) >> 20)) |
#define minor_12_20(x) ((int32_t)(((x) & 0x000fffff) >> 0)) |
#define makedev_12_20(x,y) ((portdev_t)((((x) << 20) & 0xfff00000) | \ |
(((y) << 0) & 0x000fffff))) |
|
static portdev_t |
pack_12_20(int n, u_long numbers[], const char **error) |
{ |
portdev_t dev = 0; |
|
if (n == 2) { |
dev = makedev_12_20(numbers[0], numbers[1]); |
if ((u_long)major_12_20(dev) != numbers[0]) |
*error = iMajorError; |
if ((u_long)minor_12_20(dev) != numbers[1]) |
*error = iMinorError; |
} else |
*error = tooManyFields; |
return (dev); |
} |
|
|
#define major_14_18(x) ((int32_t)(((x) & 0xfffc0000) >> 18)) |
#define minor_14_18(x) ((int32_t)(((x) & 0x0003ffff) >> 0)) |
#define makedev_14_18(x,y) ((portdev_t)((((x) << 18) & 0xfffc0000) | \ |
(((y) << 0) & 0x0003ffff))) |
|
static portdev_t |
pack_14_18(int n, u_long numbers[], const char **error) |
{ |
portdev_t dev = 0; |
|
if (n == 2) { |
dev = makedev_14_18(numbers[0], numbers[1]); |
if ((u_long)major_14_18(dev) != numbers[0]) |
*error = iMajorError; |
if ((u_long)minor_14_18(dev) != numbers[1]) |
*error = iMinorError; |
} else |
*error = tooManyFields; |
return (dev); |
} |
|
|
#define major_8_24(x) ((int32_t)(((x) & 0xff000000) >> 24)) |
#define minor_8_24(x) ((int32_t)(((x) & 0x00ffffff) >> 0)) |
#define makedev_8_24(x,y) ((portdev_t)((((x) << 24) & 0xff000000) | \ |
(((y) << 0) & 0x00ffffff))) |
|
static portdev_t |
pack_8_24(int n, u_long numbers[], const char **error) |
{ |
portdev_t dev = 0; |
|
if (n == 2) { |
dev = makedev_8_24(numbers[0], numbers[1]); |
if ((u_long)major_8_24(dev) != numbers[0]) |
*error = iMajorError; |
if ((u_long)minor_8_24(dev) != numbers[1]) |
*error = iMinorError; |
} else |
*error = tooManyFields; |
return (dev); |
} |
|
|
#define major_12_12_8(x) ((int32_t)(((x) & 0xfff00000) >> 20)) |
#define unit_12_12_8(x) ((int32_t)(((x) & 0x000fff00) >> 8)) |
#define subunit_12_12_8(x) ((int32_t)(((x) & 0x000000ff) >> 0)) |
#define makedev_12_12_8(x,y,z) ((portdev_t)((((x) << 20) & 0xfff00000) | \ |
(((y) << 8) & 0x000fff00) | \ |
(((z) << 0) & 0x000000ff))) |
|
static portdev_t |
pack_bsdos(int n, u_long numbers[], const char **error) |
{ |
portdev_t dev = 0; |
|
if (n == 2) { |
dev = makedev_12_20(numbers[0], numbers[1]); |
if ((u_long)major_12_20(dev) != numbers[0]) |
*error = iMajorError; |
if ((u_long)minor_12_20(dev) != numbers[1]) |
*error = iMinorError; |
} else if (n == 3) { |
dev = makedev_12_12_8(numbers[0], numbers[1], numbers[2]); |
if ((u_long)major_12_12_8(dev) != numbers[0]) |
*error = iMajorError; |
if ((u_long)unit_12_12_8(dev) != numbers[1]) |
*error = "invalid unit number"; |
if ((u_long)subunit_12_12_8(dev) != numbers[2]) |
*error = "invalid subunit number"; |
} else |
*error = tooManyFields; |
return (dev); |
} |
|
|
/* list of formats and pack functions */ |
/* this list must be sorted lexically */ |
static struct format { |
const char *name; |
pack_t *pack; |
} formats[] = { |
{"386bsd", pack_8_8}, |
{"4bsd", pack_8_8}, |
{"bsdos", pack_bsdos}, |
{"freebsd", pack_freebsd}, |
{"hpux", pack_8_24}, |
{"isc", pack_8_8}, |
{"linux", pack_8_8}, |
{"native", pack_native}, |
{"netbsd", pack_netbsd}, |
{"osf1", pack_12_20}, |
{"sco", pack_8_8}, |
{"solaris", pack_14_18}, |
{"sunos", pack_8_8}, |
{"svr3", pack_8_8}, |
{"svr4", pack_14_18}, |
{"ultrix", pack_8_8}, |
}; |
|
static int |
compare_format(const void *key, const void *element) |
{ |
const char *name; |
const struct format *format; |
|
name = key; |
format = element; |
|
return (strcmp(name, format->name)); |
} |
|
|
pack_t * |
pack_find(const char *name) |
{ |
struct format *format; |
|
format = bsearch(name, formats, |
sizeof(formats)/sizeof(formats[0]), |
sizeof(formats[0]), compare_format); |
if (format == 0) |
return (NULL); |
return (format->pack); |
} |
/trunk/disk/tools/fs-NetBSD/makefs/README
5,6 → 5,9
walk |
ffs |
|
walk |
spec |
|
ffs |
mkfs |
ffs_balloc |
/trunk/disk/tools/fs-NetBSD/makefs/mtree.h
136,4 → 136,7
#define CH_MASK (UF_MASK | SF_MASK) /* all settable flags */ |
#define SP_FLGS (SF_IMMUTABLE | SF_APPEND) /* special flags */ |
|
void *setmode(const char *p); |
mode_t getmode(const void *bbox, mode_t omode); |
|
#endif /* _MTREE_H_ */ |
/trunk/disk/tools/fs-NetBSD/makefs/pack_dev.h
0,0 → 1,52
/* $NetBSD: pack_dev.h,v 1.7 2008/04/28 20:23:09 martin Exp $ */ |
|
/*- |
* Copyright (c) 1998, 2001 The NetBSD Foundation, Inc. |
* All rights reserved. |
* |
* This code is derived from software contributed to The NetBSD Foundation |
* by Charles M. Hannum. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* |
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
* POSSIBILITY OF SUCH DAMAGE. |
*/ |
|
#ifndef _PACK_DEV_H |
#define _PACK_DEV_H |
|
#ifdef __CYGWIN__ |
typedef __dev32_t portdev_t; |
#else |
typedef dev_t portdev_t; |
#endif |
typedef portdev_t pack_t(int, u_long [], const char **); |
|
pack_t *pack_find(const char *); |
pack_t pack_native; |
|
#define major_netbsd(x) ((int32_t)((((x) & 0x000fff00) >> 8))) |
#define minor_netbsd(x) ((int32_t)((((x) & 0xfff00000) >> 12) | \ |
(((x) & 0x000000ff) >> 0))) |
#define makedev_netbsd(x,y) ((dev_t)((((x) << 8) & 0x000fff00) | \ |
(((y) << 12) & 0xfff00000) | \ |
(((y) << 0) & 0x000000ff))) |
|
#endif /* _PACK_DEV_H */ |
/trunk/disk/tools/fs-NetBSD/makefs/spec.c
0,0 → 1,869
/* |
* spec.c -- specfile parser |
*/ |
|
|
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <stdarg.h> |
#include <ctype.h> |
#include <errno.h> |
#include <assert.h> |
|
#include "mtree.h" |
#include "pack_dev.h" |
|
|
#define BUFSIZE 2000 |
#define REPLACEPTR(x,v) do { if ((x)) free((x)); (x) = (v); } while (0) |
#define REPLACE(x) cur->x = new->x |
#define REPLACESTR(x) REPLACEPTR(cur->x,new->x) |
|
|
static int mtree_lineno = 0; /* Current spec line number */ |
static int mtree_Mflag = 0; /* Merge duplicate entries */ |
static int mtree_Wflag = 0; /* Don't "whack" permissions */ |
static int mtree_Sflag = 0; /* Sort entries */ |
|
|
static void addchild(NODE *pathparent, NODE *centry); |
static void replacenode(NODE *cur, NODE *new); |
static void set(char *t, NODE *ip); |
static void unset(char *t, NODE *ip); |
|
|
/**************************************************************/ |
|
|
static void mtree_err(const char *fmt, ...) { |
va_list ap; |
|
va_start(ap, fmt); |
vprintf(fmt, ap); |
va_end(ap); |
if (mtree_lineno) { |
printf("\nfailed at line %lu of the specification", |
(u_long) mtree_lineno); |
} |
printf("\n"); |
exit(1); |
} |
|
|
static const char *nodetype(u_int type) { |
return inotype(nodetoino(type)); |
} |
|
|
static int strunvis(char *dst, const char *src) { |
int i; |
|
i = 0; |
while ((*dst++ = *src++) != '\0') { |
i++; |
} |
return i; |
} |
|
|
/**************************************************************/ |
|
|
#define TEST(a, b, f) { \ |
if (!strcmp(a, b)) { \ |
if (clear) { \ |
if (clrp) \ |
*clrp |= (f); \ |
if (setp) \ |
*setp &= ~(f); \ |
} else { \ |
if (setp) \ |
*setp |= (f); \ |
if (clrp) \ |
*clrp &= ~(f); \ |
} \ |
break; \ |
} \ |
} |
|
|
/* |
* string_to_flags -- |
* Take string of arguments and return stat flags. Return 0 on |
* success, 1 on failure. On failure, stringp is set to point |
* to the offending token. |
*/ |
int |
string_to_flags(char **stringp, u_long *setp, u_long *clrp) |
{ |
#if HAVE_STRUCT_STAT_ST_FLAGS |
int clear; |
char *string; |
char *p; |
#endif |
|
if (setp) |
*setp = 0; |
if (clrp) |
*clrp = 0; |
|
#if HAVE_STRUCT_STAT_ST_FLAGS |
string = *stringp; |
while ((p = strsep(&string, "\t ,")) != NULL) { |
clear = 0; |
*stringp = p; |
if (*p == '\0') |
continue; |
if (p[0] == 'n' && p[1] == 'o') { |
clear = 1; |
p += 2; |
} |
switch (p[0]) { |
case 'a': |
TEST(p, "arch", SF_ARCHIVED); |
TEST(p, "archived", SF_ARCHIVED); |
return (1); |
case 'd': |
clear = !clear; |
TEST(p, "dump", UF_NODUMP); |
return (1); |
case 'n': |
/* |
* Support `nonodump'. Note that |
* the state of clear is not changed. |
*/ |
TEST(p, "nodump", UF_NODUMP); |
return (1); |
case 'o': |
TEST(p, "opaque", UF_OPAQUE); |
return (1); |
case 's': |
TEST(p, "sappnd", SF_APPEND); |
TEST(p, "sappend", SF_APPEND); |
TEST(p, "schg", SF_IMMUTABLE); |
TEST(p, "schange", SF_IMMUTABLE); |
TEST(p, "simmutable", SF_IMMUTABLE); |
return (1); |
case 'u': |
TEST(p, "uappnd", UF_APPEND); |
TEST(p, "uappend", UF_APPEND); |
TEST(p, "uchg", UF_IMMUTABLE); |
TEST(p, "uchange", UF_IMMUTABLE); |
TEST(p, "uimmutable", UF_IMMUTABLE); |
return (1); |
default: |
return (1); |
} |
} |
#endif |
|
return (0); |
} |
|
|
/**************************************************************/ |
|
|
int uid_from_user(const char *name, uid_t *uid) { |
*uid = 0; |
return 0; |
} |
|
|
int gid_from_group(const char *name, gid_t *gid) { |
*gid = 0; |
return 0; |
} |
|
|
/**************************************************************/ |
|
|
#define NEEDVALUE 0x01 |
|
|
typedef struct _key { |
const char *name; /* key name */ |
u_int val; /* value */ |
u_int flags; |
} KEY; |
|
|
static KEY keylist[] = { |
{"cksum", F_CKSUM, NEEDVALUE}, |
{"device", F_DEV, NEEDVALUE}, |
{"flags", F_FLAGS, NEEDVALUE}, |
{"gid", F_GID, NEEDVALUE}, |
{"gname", F_GNAME, NEEDVALUE}, |
{"ignore", F_IGN, 0}, |
{"link", F_SLINK, NEEDVALUE}, |
{"md5", F_MD5, NEEDVALUE}, |
{"md5digest", F_MD5, NEEDVALUE}, |
{"mode", F_MODE, NEEDVALUE}, |
{"nlink", F_NLINK, NEEDVALUE}, |
{"optional", F_OPT, 0}, |
{"rmd160", F_RMD160, NEEDVALUE}, |
{"rmd160digest",F_RMD160, NEEDVALUE}, |
{"sha1", F_SHA1, NEEDVALUE}, |
{"sha1digest", F_SHA1, NEEDVALUE}, |
{"sha256", F_SHA256, NEEDVALUE}, |
{"sha256digest",F_SHA256, NEEDVALUE}, |
{"sha384", F_SHA384, NEEDVALUE}, |
{"sha384digest",F_SHA384, NEEDVALUE}, |
{"sha512", F_SHA512, NEEDVALUE}, |
{"sha512digest",F_SHA512, NEEDVALUE}, |
{"size", F_SIZE, NEEDVALUE}, |
{"tags", F_TAGS, NEEDVALUE}, |
{"time", F_TIME, NEEDVALUE}, |
{"type", F_TYPE, NEEDVALUE}, |
{"uid", F_UID, NEEDVALUE}, |
{"uname", F_UNAME, NEEDVALUE} |
}; |
|
|
static KEY typelist[] = { |
{"block", F_BLOCK, 0}, |
{"char", F_CHAR, 0}, |
{"dir", F_DIR, 0}, |
#ifdef S_IFDOOR |
{"door", F_DOOR, 0}, |
#endif |
{"fifo", F_FIFO, 0}, |
{"file", F_FILE, 0}, |
{"link", F_LINK, 0}, |
{"socket", F_SOCK, 0}, |
}; |
|
|
int keycompare(const void *a, const void *b) { |
return strcmp(((const KEY *)a)->name, ((const KEY *)b)->name); |
} |
|
|
u_int parsekey(const char *name, int *needvaluep) { |
static int allbits; |
KEY *k, tmp; |
|
if (allbits == 0) { |
size_t i; |
|
for (i = 0; i < sizeof(keylist) / sizeof(KEY); i++) |
allbits |= keylist[i].val; |
} |
tmp.name = name; |
if (strcmp(name, "all") == 0) |
return (allbits); |
k = (KEY *)bsearch(&tmp, keylist, sizeof(keylist) / sizeof(KEY), |
sizeof(KEY), keycompare); |
if (k == NULL) |
mtree_err("unknown keyword `%s'", name); |
|
if (needvaluep) |
*needvaluep = k->flags & NEEDVALUE ? 1 : 0; |
|
return k->val; |
} |
|
|
u_int parsetype(const char *name) { |
KEY *k, tmp; |
|
tmp.name = name; |
k = (KEY *) bsearch(&tmp, typelist, sizeof(typelist) / sizeof(KEY), |
sizeof(KEY), keycompare); |
if (k == NULL) { |
mtree_err("unknown file type `%s'", name); |
} |
return k->val; |
} |
|
|
/**************************************************************/ |
|
|
#define MAX_PACK_ARGS 3 |
|
|
static dev_t parsedev(char *arg) { |
u_long numbers[MAX_PACK_ARGS]; |
char *p, *ep, *dev; |
int argc; |
pack_t *pack; |
dev_t result; |
const char *error = NULL; |
|
if ((dev = strchr(arg, ',')) != NULL) { |
*dev++='\0'; |
if ((pack = pack_find(arg)) == NULL) |
mtree_err("unknown format `%s'", arg); |
argc = 0; |
while ((p = strsep(&dev, ",")) != NULL) { |
if (*p == '\0') |
mtree_err("missing number"); |
numbers[argc++] = strtoul(p, &ep, 0); |
if (*ep != '\0') |
mtree_err("invalid number `%s'", |
p); |
if (argc > MAX_PACK_ARGS) |
mtree_err("too many arguments"); |
} |
if (argc < 2) |
mtree_err("not enough arguments"); |
result = (*pack)(argc, numbers, &error); |
if (error != NULL) |
mtree_err("%s", error); |
} else { |
result = (dev_t)strtoul(arg, &ep, 0); |
if (*ep != '\0') |
mtree_err("invalid device `%s'", arg); |
} |
return result; |
} |
|
|
/**************************************************************/ |
|
|
/* |
* nodecmp -- |
* used as a comparison function by addchild() to control the order |
* in which entries appear within a list of sibling nodes. We make |
* directories sort after non-directories, but otherwise sort in |
* strcmp() order. |
* |
* Keep this in sync with dcmp() in create.c. |
*/ |
static int nodecmp(const NODE *a, const NODE *b) { |
if ((a->type & F_DIR) != 0) { |
if ((b->type & F_DIR) == 0) |
return 1; |
} else if ((b->type & F_DIR) != 0) |
return -1; |
return strcmp(a->name, b->name); |
} |
|
|
/**************************************************************/ |
|
|
NODE *spec(FILE *fp) { |
NODE *centry, *last, *pathparent, *cur; |
char *p, *e, *next; |
NODE ginfo, *root; |
char *tname, *ntname; |
size_t tnamelen, plen; |
char buf[BUFSIZE]; |
int ll; |
|
root = NULL; |
centry = last = NULL; |
tname = NULL; |
tnamelen = 0; |
memset(&ginfo, 0, sizeof(ginfo)); |
mtree_lineno = 0; |
while (fgets(buf, BUFSIZE, fp) != NULL) { |
mtree_lineno++; |
/* Delete trailing newline. */ |
ll = strlen(buf); |
if (ll > 0 && buf[ll - 1] == '\n') { |
buf[ll - 1] = '\0'; |
} |
/* Skip leading whitespace. */ |
for (p = buf; *p && isspace((unsigned char)*p); ++p) |
continue; |
|
/* If nothing but whitespace (or comment), continue. */ |
if (*p == '\0' || *p == '#') |
continue; |
|
#ifdef DEBUG |
fprintf(stderr, "line %lu: {%s}\n", |
(u_long)mtree_lineno, p); |
#endif |
/* Grab file name, "$", "set", or "unset". */ |
next = buf; |
while ((p = strsep(&next, " \t")) != NULL && *p == '\0') |
continue; |
if (p == NULL) |
mtree_err("missing field"); |
|
if (p[0] == '/') { |
if (strcmp(p + 1, "set") == 0) |
set(next, &ginfo); |
else if (strcmp(p + 1, "unset") == 0) |
unset(next, &ginfo); |
else |
mtree_err("invalid specification `%s'", p); |
continue; |
} |
|
if (strcmp(p, "..") == 0) { |
/* Don't go up, if haven't gone down. */ |
if (root == NULL) |
goto noparent; |
if (last->type != F_DIR || last->flags & F_DONE) { |
if (last == root) |
goto noparent; |
last = last->parent; |
} |
last->flags |= F_DONE; |
continue; |
|
noparent: mtree_err("no parent node"); |
} |
|
plen = strlen(p) + 1; |
if (plen > tnamelen) { |
if ((ntname = realloc(tname, plen)) == NULL) |
mtree_err("realloc: %s", strerror(errno)); |
tname = ntname; |
tnamelen = plen; |
} |
if (strunvis(tname, p) == -1) |
mtree_err("strunvis failed on `%s'", p); |
p = tname; |
|
pathparent = NULL; |
if (strchr(p, '/') != NULL) { |
cur = root; |
for (; (e = strchr(p, '/')) != NULL; p = e+1) { |
if (p == e) |
continue; /* handle // */ |
*e = '\0'; |
if (strcmp(p, ".") != 0) { |
while (cur && |
strcmp(cur->name, p) != 0) { |
cur = cur->next; |
} |
} |
if (cur == NULL || cur->type != F_DIR) { |
mtree_err("%s: %s", tname, |
"missing directory in specification"); |
} |
*e = '/'; |
pathparent = cur; |
cur = cur->child; |
} |
if (*p == '\0') |
mtree_err("%s: empty leaf element", tname); |
} |
|
if ((centry = calloc(1, sizeof(NODE) + strlen(p))) == NULL) |
mtree_err("%s", strerror(errno)); |
*centry = ginfo; |
centry->lineno = mtree_lineno; |
strcpy(centry->name, p); |
#define MAGIC "?*[" |
if (strpbrk(p, MAGIC)) |
centry->flags |= F_MAGIC; |
set(next, centry); |
|
if (root == NULL) { |
/* |
* empty tree |
*/ |
if (strcmp(centry->name, ".") != 0 || |
centry->type != F_DIR) |
mtree_err( |
"root node must be the directory `.'"); |
last = root = centry; |
root->parent = root; |
} else if (pathparent != NULL) { |
/* |
* full path entry; add or replace |
*/ |
centry->parent = pathparent; |
addchild(pathparent, centry); |
last = centry; |
} else if (strcmp(centry->name, ".") == 0) { |
/* |
* duplicate "." entry; always replace |
*/ |
replacenode(root, centry); |
} else if (last->type == F_DIR && !(last->flags & F_DONE)) { |
/* |
* new relative child in current dir; |
* add or replace |
*/ |
centry->parent = last; |
addchild(last, centry); |
last = centry; |
} else { |
/* |
* new relative child in parent dir |
* (after encountering ".." entry); |
* add or replace |
*/ |
centry->parent = last->parent; |
addchild(last->parent, centry); |
last = centry; |
} |
} |
return root; |
} |
|
|
/* |
* addchild -- |
* Add the centry node as a child of the pathparent node. If |
* centry is a duplicate, call replacenode(). If centry is not |
* a duplicate, insert it into the linked list referenced by |
* pathparent->child. Keep the list sorted if Sflag is set. |
*/ |
static void addchild(NODE *pathparent, NODE *centry) { |
NODE *samename; /* node with the same name as centry */ |
NODE *replacepos; /* if non-NULL, centry should replace this node */ |
NODE *insertpos; /* if non-NULL, centry should be inserted |
* after this node */ |
NODE *cur; /* for stepping through the list */ |
NODE *last; /* the last node in the list */ |
int cmp; |
|
samename = NULL; |
replacepos = NULL; |
insertpos = NULL; |
last = NULL; |
cur = pathparent->child; |
if (cur == NULL) { |
/* centry is pathparent's first and only child node so far */ |
pathparent->child = centry; |
return; |
} |
|
/* |
* pathparent already has at least one other child, so add the |
* centry node to the list. |
* |
* We first scan through the list looking for an existing node |
* with the same name (setting samename), and also looking |
* for the correct position to replace or insert the new node |
* (setting replacepos and/or insertpos). |
*/ |
for (; cur != NULL; last = cur, cur = cur->next) { |
if (strcmp(centry->name, cur->name) == 0) { |
samename = cur; |
} |
if (mtree_Sflag) { |
cmp = nodecmp(centry, cur); |
if (cmp == 0) { |
replacepos = cur; |
} else if (cmp > 0) { |
insertpos = cur; |
} |
} |
} |
if (! mtree_Sflag) { |
if (samename != NULL) { |
/* replace node with same name */ |
replacepos = samename; |
} else { |
/* add new node at end of list */ |
insertpos = last; |
} |
} |
|
if (samename != NULL) { |
/* |
* We found a node with the same name above. Call |
* replacenode(), which will either exit with an error, |
* or replace the information in the samename node and |
* free the information in the centry node. |
*/ |
replacenode(samename, centry); |
if (samename == replacepos) { |
/* The just-replaced node was in the correct position */ |
return; |
} |
if (samename == insertpos || samename->prev == insertpos) { |
/* |
* We thought the new node should be just before |
* or just after the replaced node, but that would |
* be equivalent to just retaining the replaced node. |
*/ |
return; |
} |
|
/* |
* The just-replaced node is in the wrong position in |
* the list. This can happen if sort order depends on |
* criteria other than the node name. |
* |
* Make centry point to the just-replaced node. Unlink |
* the just-replaced node from the list, and allow it to |
* be insterted in the correct position later. |
*/ |
centry = samename; |
if (centry->prev) |
centry->prev->next = centry->next; |
else { |
/* centry->next is the new head of the list */ |
pathparent->child = centry->next; |
assert(centry->next != NULL); |
} |
if (centry->next) |
centry->next->prev = centry->prev; |
centry->prev = NULL; |
centry->next = NULL; |
} |
|
if (insertpos == NULL) { |
/* insert centry at the beginning of the list */ |
pathparent->child->prev = centry; |
centry->next = pathparent->child; |
centry->prev = NULL; |
pathparent->child = centry; |
} else { |
/* insert centry into the list just after insertpos */ |
centry->next = insertpos->next; |
insertpos->next = centry; |
centry->prev = insertpos; |
if (centry->next) |
centry->next->prev = centry; |
} |
return; |
} |
|
|
static void replacenode(NODE *cur, NODE *new) { |
if (cur->type != new->type) { |
if (mtree_Mflag) { |
/* |
* merge entries with different types; we |
* don't want children retained in this case. |
*/ |
REPLACE(type); |
free_nodes(cur->child); |
cur->child = NULL; |
} else { |
mtree_err( |
"existing entry for `%s', type `%s'" |
" does not match type `%s'", |
cur->name, nodetype(cur->type), |
nodetype(new->type)); |
} |
} |
|
REPLACE(st_size); |
REPLACE(st_mtimespec); |
REPLACESTR(slink); |
if (cur->slink != NULL) { |
if ((cur->slink = strdup(new->slink)) == NULL) |
mtree_err("memory allocation error"); |
if (strunvis(cur->slink, new->slink) == -1) |
mtree_err("strunvis failed on `%s'", new->slink); |
free(new->slink); |
} |
REPLACE(st_uid); |
REPLACE(st_gid); |
REPLACE(st_mode); |
REPLACE(st_rdev); |
REPLACE(st_flags); |
REPLACE(st_nlink); |
REPLACE(cksum); |
REPLACESTR(md5digest); |
REPLACESTR(rmd160digest); |
REPLACESTR(sha1digest); |
REPLACESTR(sha256digest); |
REPLACESTR(sha384digest); |
REPLACESTR(sha512digest); |
REPLACESTR(tags); |
REPLACE(lineno); |
REPLACE(flags); |
free(new); |
} |
|
|
static void set(char *t, NODE *ip) { |
int type, value, len; |
gid_t gid; |
uid_t uid; |
char *kw, *val, *md, *ep; |
void *m; |
|
while ((kw = strsep(&t, "= \t")) != NULL) { |
if (*kw == '\0') |
continue; |
if (strcmp(kw, "all") == 0) |
mtree_err("invalid keyword `all'"); |
ip->flags |= type = parsekey(kw, &value); |
if (!value) |
/* Just set flag bit (F_IGN and F_OPT) */ |
continue; |
while ((val = strsep(&t, " \t")) != NULL && *val == '\0') |
continue; |
if (val == NULL) |
mtree_err("missing value"); |
switch (type) { |
case F_CKSUM: |
ip->cksum = strtoul(val, &ep, 10); |
if (*ep) |
mtree_err("invalid checksum `%s'", val); |
break; |
case F_DEV: |
ip->st_rdev = parsedev(val); |
break; |
case F_FLAGS: |
if (strcmp("none", val) == 0) |
ip->st_flags = 0; |
else if (string_to_flags(&val, &ip->st_flags, NULL) |
!= 0) |
mtree_err("invalid flag `%s'", val); |
break; |
case F_GID: |
ip->st_gid = (gid_t)strtoul(val, &ep, 10); |
if (*ep) |
mtree_err("invalid gid `%s'", val); |
break; |
case F_GNAME: |
if (mtree_Wflag) /* don't parse if whacking */ |
break; |
if (gid_from_group(val, &gid) == -1) |
mtree_err("unknown group `%s'", val); |
ip->st_gid = gid; |
break; |
case F_MD5: |
if (val[0]=='0' && val[1]=='x') |
md=&val[2]; |
else |
md=val; |
if ((ip->md5digest = strdup(md)) == NULL) |
mtree_err("memory allocation error"); |
break; |
case F_MODE: |
if ((m = setmode(val)) == NULL) |
mtree_err("cannot set file mode `%s' (%s)", |
val, strerror(errno)); |
ip->st_mode = getmode(m, 0); |
free(m); |
break; |
case F_NLINK: |
ip->st_nlink = (nlink_t)strtoul(val, &ep, 10); |
if (*ep) |
mtree_err("invalid link count `%s'", val); |
break; |
case F_RMD160: |
if (val[0]=='0' && val[1]=='x') |
md=&val[2]; |
else |
md=val; |
if ((ip->rmd160digest = strdup(md)) == NULL) |
mtree_err("memory allocation error"); |
break; |
case F_SHA1: |
if (val[0]=='0' && val[1]=='x') |
md=&val[2]; |
else |
md=val; |
if ((ip->sha1digest = strdup(md)) == NULL) |
mtree_err("memory allocation error"); |
break; |
case F_SIZE: |
ip->st_size = (off_t)strtoll(val, &ep, 10); |
if (*ep) |
mtree_err("invalid size `%s'", val); |
break; |
case F_SLINK: |
if ((ip->slink = strdup(val)) == NULL) |
mtree_err("memory allocation error"); |
if (strunvis(ip->slink, val) == -1) |
mtree_err("strunvis failed on `%s'", val); |
break; |
case F_TAGS: |
len = strlen(val) + 3; /* "," + str + ",\0" */ |
if ((ip->tags = malloc(len)) == NULL) |
mtree_err("memory allocation error"); |
snprintf(ip->tags, len, ",%s,", val); |
break; |
case F_TIME: |
ip->st_mtimespec.tv_sec = |
(time_t)strtoll(val, &ep, 10); |
if (*ep != '.') |
mtree_err("invalid time `%s'", val); |
val = ep + 1; |
ip->st_mtimespec.tv_nsec = strtol(val, &ep, 10); |
if (*ep) |
mtree_err("invalid time `%s'", val); |
break; |
case F_TYPE: |
ip->type = parsetype(val); |
break; |
case F_UID: |
ip->st_uid = (uid_t)strtoul(val, &ep, 10); |
if (*ep) |
mtree_err("invalid uid `%s'", val); |
break; |
case F_UNAME: |
if (mtree_Wflag) /* don't parse if whacking */ |
break; |
if (uid_from_user(val, &uid) == -1) |
mtree_err("unknown user `%s'", val); |
ip->st_uid = uid; |
break; |
case F_SHA256: |
if (val[0]=='0' && val[1]=='x') |
md=&val[2]; |
else |
md=val; |
if ((ip->sha256digest = strdup(md)) == NULL) |
mtree_err("memory allocation error"); |
break; |
case F_SHA384: |
if (val[0]=='0' && val[1]=='x') |
md=&val[2]; |
else |
md=val; |
if ((ip->sha384digest = strdup(md)) == NULL) |
mtree_err("memory allocation error"); |
break; |
case F_SHA512: |
if (val[0]=='0' && val[1]=='x') |
md=&val[2]; |
else |
md=val; |
if ((ip->sha512digest = strdup(md)) == NULL) |
mtree_err("memory allocation error"); |
break; |
default: |
mtree_err( |
"set(): unsupported key type 0x%x (INTERNAL ERROR)", |
type); |
/* NOTREACHED */ |
} |
} |
} |
|
|
static void unset(char *t, NODE *ip) { |
char *p; |
|
while ((p = strsep(&t, " \t")) != NULL) { |
if (*p == '\0') { |
continue; |
} |
ip->flags &= ~parsekey(p, NULL); |
} |
} |
|
|
void free_nodes(NODE *root) { |
NODE *cur, *next; |
|
if (root == NULL) { |
return; |
} |
next = NULL; |
for (cur = root; cur != NULL; cur = next) { |
next = cur->next; |
free_nodes(cur->child); |
REPLACEPTR(cur->slink, NULL); |
REPLACEPTR(cur->md5digest, NULL); |
REPLACEPTR(cur->rmd160digest, NULL); |
REPLACEPTR(cur->sha1digest, NULL); |
REPLACEPTR(cur->sha256digest, NULL); |
REPLACEPTR(cur->sha384digest, NULL); |
REPLACEPTR(cur->sha512digest, NULL); |
REPLACEPTR(cur->tags, NULL); |
REPLACEPTR(cur, NULL); |
} |
} |
/trunk/disk/tools/fs-NetBSD/makefs/Makefile
9,8 → 9,9
LDFLAGS = -g |
LDLIBS = -lm |
|
SRCS = makefs.c walk.c ffs.c mkfs.c ffs_bswap.c ffs_balloc.c \ |
ufs_bmap.c ffs_alloc.c ffs_subr.c ffs_tables.c buf.c |
SRCS = makefs.c walk.c spec.c ffs.c mkfs.c ffs_bswap.c ffs_balloc.c \ |
ufs_bmap.c ffs_alloc.c ffs_subr.c ffs_tables.c buf.c pack_dev.c \ |
setmode.c |
OBJS = $(patsubst %.c,%.o,$(SRCS)) |
BIN = NetBSD-makefs |
|
/trunk/disk/tools/fs-NetBSD/Makefile
19,6 → 19,7
done |
mkdir -p $(BUILD)/run/fs-NetBSD |
cp Makefile.run $(BUILD)/run/fs-NetBSD/Makefile |
cp add.spec $(BUILD)/run/fs-NetBSD/add.spec |
|
clean: |
for i in $(DIRS) ; do \ |