Fsutil: sources reformatted to 4-space indents.

This commit is contained in:
Serge Vakulenko
2014-07-31 18:37:15 -07:00
parent 4d8233582a
commit c2b3647d5e
8 changed files with 2609 additions and 2604 deletions

View File

@@ -28,29 +28,29 @@ extern int verbose;
int fs_read_block (fs_t *fs, unsigned bnum, unsigned char *data)
{
if (verbose > 3)
printf ("read block %d\n", bnum);
if (bnum < fs->isize)
return 0;
if (! fs_seek (fs, bnum * BSDFS_BSIZE))
return 0;
if (! fs_read (fs, data, BSDFS_BSIZE))
return 0;
return 1;
if (verbose > 3)
printf ("read block %d\n", bnum);
if (bnum < fs->isize)
return 0;
if (! fs_seek (fs, bnum * BSDFS_BSIZE))
return 0;
if (! fs_read (fs, data, BSDFS_BSIZE))
return 0;
return 1;
}
int fs_write_block (fs_t *fs, unsigned bnum, unsigned char *data)
{
if (verbose > 3)
printf ("write block %d\n", bnum);
if (! fs->writable || bnum < fs->isize)
return 0;
if (! fs_seek (fs, bnum * BSDFS_BSIZE))
return 0;
if (! fs_write (fs, data, BSDFS_BSIZE))
return 0;
fs->modified = 1;
return 1;
if (verbose > 3)
printf ("write block %d\n", bnum);
if (! fs->writable || bnum < fs->isize)
return 0;
if (! fs_seek (fs, bnum * BSDFS_BSIZE))
return 0;
if (! fs_write (fs, data, BSDFS_BSIZE))
return 0;
fs->modified = 1;
return 1;
}
/*
@@ -58,27 +58,27 @@ int fs_write_block (fs_t *fs, unsigned bnum, unsigned char *data)
*/
int fs_block_free (fs_t *fs, unsigned int bno)
{
int i;
unsigned buf [BSDFS_BSIZE / 4];
int i;
unsigned buf [BSDFS_BSIZE / 4];
if (verbose > 1)
printf ("free block %d, total %d\n", bno, fs->nfree);
if (fs->nfree >= NICFREE) {
buf[0] = fs->nfree;
for (i=0; i<NICFREE; i++)
buf[i+1] = fs->free[i];
if (! fs_write_block (fs, bno, (unsigned char*) buf)) {
fprintf (stderr, "block_free: write error at block %d\n", bno);
return 0;
}
fs->nfree = 0;
}
fs->free [fs->nfree] = bno;
fs->nfree++;
fs->dirty = 1;
if (bno) /* Count total free blocks. */
++fs->tfree;
return 1;
if (verbose > 1)
printf ("free block %d, total %d\n", bno, fs->nfree);
if (fs->nfree >= NICFREE) {
buf[0] = fs->nfree;
for (i=0; i<NICFREE; i++)
buf[i+1] = fs->free[i];
if (! fs_write_block (fs, bno, (unsigned char*) buf)) {
fprintf (stderr, "block_free: write error at block %d\n", bno);
return 0;
}
fs->nfree = 0;
}
fs->free [fs->nfree] = bno;
fs->nfree++;
fs->dirty = 1;
if (bno) /* Count total free blocks. */
++fs->tfree;
return 1;
}
/*
@@ -86,26 +86,26 @@ int fs_block_free (fs_t *fs, unsigned int bno)
*/
int fs_indirect_block_free (fs_t *fs, unsigned int bno, int nblk)
{
unsigned nb;
unsigned char data [BSDFS_BSIZE];
int i;
unsigned nb;
unsigned char data [BSDFS_BSIZE];
int i;
if (! fs_read_block (fs, bno, data)) {
fprintf (stderr, "inode_clear: read error at block %d\n", bno);
return 0;
}
for (i=BSDFS_BSIZE-4; i>=0; i-=4) {
if (i/4 < nblk) {
/* Truncate up to required size. */
return 0;
}
nb = data [i+3] << 24 | data [i+2] << 16 |
data [i+1] << 8 | data [i];
if (nb)
fs_block_free (fs, nb);
}
fs_block_free (fs, bno);
return 1;
if (! fs_read_block (fs, bno, data)) {
fprintf (stderr, "inode_clear: read error at block %d\n", bno);
return 0;
}
for (i=BSDFS_BSIZE-4; i>=0; i-=4) {
if (i/4 < nblk) {
/* Truncate up to required size. */
return 0;
}
nb = data [i+3] << 24 | data [i+2] << 16 |
data [i+1] << 8 | data [i];
if (nb)
fs_block_free (fs, nb);
}
fs_block_free (fs, bno);
return 1;
}
/*
@@ -113,27 +113,27 @@ int fs_indirect_block_free (fs_t *fs, unsigned int bno, int nblk)
*/
int fs_double_indirect_block_free (fs_t *fs, unsigned int bno, int nblk)
{
unsigned nb;
unsigned char data [BSDFS_BSIZE];
int i;
unsigned nb;
unsigned char data [BSDFS_BSIZE];
int i;
if (! fs_read_block (fs, bno, data)) {
fprintf (stderr, "inode_clear: read error at block %d\n", bno);
return 0;
}
for (i=BSDFS_BSIZE-4; i>=0; i-=4) {
if (i/4 * BSDFS_BSIZE/4 < nblk) {
/* Truncate up to required size. */
return 0;
}
nb = data [i+3] << 24 | data [i+2] << 16 |
data [i+1] << 8 | data [i];
if (nb)
fs_indirect_block_free (fs, nb,
nblk - i/4 * BSDFS_BSIZE/4);
}
fs_block_free (fs, bno);
return 1;
if (! fs_read_block (fs, bno, data)) {
fprintf (stderr, "inode_clear: read error at block %d\n", bno);
return 0;
}
for (i=BSDFS_BSIZE-4; i>=0; i-=4) {
if (i/4 * BSDFS_BSIZE/4 < nblk) {
/* Truncate up to required size. */
return 0;
}
nb = data [i+3] << 24 | data [i+2] << 16 |
data [i+1] << 8 | data [i];
if (nb)
fs_indirect_block_free (fs, nb,
nblk - i/4 * BSDFS_BSIZE/4);
}
fs_block_free (fs, bno);
return 1;
}
/*
@@ -141,27 +141,27 @@ int fs_double_indirect_block_free (fs_t *fs, unsigned int bno, int nblk)
*/
int fs_triple_indirect_block_free (fs_t *fs, unsigned int bno, int nblk)
{
unsigned nb;
unsigned char data [BSDFS_BSIZE];
int i;
unsigned nb;
unsigned char data [BSDFS_BSIZE];
int i;
if (! fs_read_block (fs, bno, data)) {
fprintf (stderr, "inode_clear: read error at block %d\n", bno);
return 0;
}
for (i=BSDFS_BSIZE-4; i>=0; i-=4) {
if (i/4 * BSDFS_BSIZE/4 * BSDFS_BSIZE/4 < nblk) {
/* Truncate up to required size. */
return 0;
}
nb = data [i+3] << 24 | data [i+2] << 16 |
data [i+1] << 8 | data [i];
if (nb)
fs_double_indirect_block_free (fs, nb,
nblk - i/4 * BSDFS_BSIZE/4 * BSDFS_BSIZE/4);
}
fs_block_free (fs, bno);
return 1;
if (! fs_read_block (fs, bno, data)) {
fprintf (stderr, "inode_clear: read error at block %d\n", bno);
return 0;
}
for (i=BSDFS_BSIZE-4; i>=0; i-=4) {
if (i/4 * BSDFS_BSIZE/4 * BSDFS_BSIZE/4 < nblk) {
/* Truncate up to required size. */
return 0;
}
nb = data [i+3] << 24 | data [i+2] << 16 |
data [i+1] << 8 | data [i];
if (nb)
fs_double_indirect_block_free (fs, nb,
nblk - i/4 * BSDFS_BSIZE/4 * BSDFS_BSIZE/4);
}
fs_block_free (fs, bno);
return 1;
}
/*
@@ -169,26 +169,26 @@ int fs_triple_indirect_block_free (fs_t *fs, unsigned int bno, int nblk)
*/
int fs_block_alloc (fs_t *fs, unsigned int *bno)
{
int i;
unsigned buf [BSDFS_BSIZE / 4];
int i;
unsigned buf [BSDFS_BSIZE / 4];
again:
if (fs->nfree == 0)
return 0;
fs->nfree--;
--fs->tfree; /* Count total free blocks. */
*bno = fs->free [fs->nfree];
if (verbose)
printf ("allocate new block %d from slot %d\n", *bno, fs->nfree);
fs->free [fs->nfree] = 0;
fs->dirty = 1;
if (fs->nfree <= 0) {
if (! fs_read_block (fs, *bno, (unsigned char*) buf))
return 0;
fs->nfree = buf[0];
for (i=0; i<NICFREE; i++)
fs->free[i] = buf[i+1];
}
if (*bno == 0)
goto again;
return 1;
if (fs->nfree == 0)
return 0;
fs->nfree--;
--fs->tfree; /* Count total free blocks. */
*bno = fs->free [fs->nfree];
if (verbose)
printf ("allocate new block %d from slot %d\n", *bno, fs->nfree);
fs->free [fs->nfree] = 0;
fs->dirty = 1;
if (fs->nfree <= 0) {
if (! fs_read_block (fs, *bno, (unsigned char*) buf))
return 0;
fs->nfree = buf[0];
for (i=0; i<NICFREE; i++)
fs->free[i] = buf[i+1];
}
if (*bno == 0)
goto again;
return 1;
}

View File

@@ -21,135 +21,135 @@
* arising out of or in connection with the use or performance of
* this software.
*/
#define BSDFS_BSIZE 1024 /* block size */
#define BSDFS_ROOT_INODE 2 /* root directory in inode 2 */
#define BSDFS_LOSTFOUND_INODE 3 /* lost+found directory in inode 3 */
#define BSDFS_SWAP_INODE 4 /* swap file in inode 4 */
#define BSDFS_INODES_PER_BLOCK 16 /* inodes per block */
#define BSDFS_BSIZE 1024 /* block size */
#define BSDFS_ROOT_INODE 2 /* root directory in inode 2 */
#define BSDFS_LOSTFOUND_INODE 3 /* lost+found directory in inode 3 */
#define BSDFS_SWAP_INODE 4 /* swap file in inode 4 */
#define BSDFS_INODES_PER_BLOCK 16 /* inodes per block */
#define NICINOD 32 /* number of superblock inodes */
#define NICFREE 200 /* number of superblock free blocks */
#define NICINOD 32 /* number of superblock inodes */
#define NICFREE 200 /* number of superblock free blocks */
/*
* 28 of the di_addr address bytes are used; 7 addresses of 4
* bytes each: 4 direct (4Kb directly accessible) and 3 indirect.
*/
#define NDADDR 4 /* direct addresses in inode */
#define NIADDR 3 /* indirect addresses in inode */
#define NADDR (NDADDR + NIADDR) /* total addresses in inode */
#define NDADDR 4 /* direct addresses in inode */
#define NIADDR 3 /* indirect addresses in inode */
#define NADDR (NDADDR + NIADDR) /* total addresses in inode */
/*
* NINDIR is the number of indirects in a file system block.
*/
#define NINDIR (DEV_BSIZE / sizeof(daddr_t))
#define NSHIFT 8 /* log2(NINDIR) */
#define NMASK 0377L /* NINDIR - 1 */
#define NINDIR (DEV_BSIZE / sizeof(daddr_t))
#define NSHIFT 8 /* log2(NINDIR) */
#define NMASK 0377L /* NINDIR - 1 */
/*
* The path name on which the file system is mounted is maintained
* in fs_fsmnt. MAXMNTLEN defines the amount of space allocated in
* the super block for this name.
*/
#define MAXMNTLEN 28
#define MAXMNTLEN 28
#define FSMAGIC1 ('F' | 'S'<<8 | '<'<<16 | '<'<<24)
#define FSMAGIC2 ('>' | '>'<<8 | 'F'<<16 | 'S'<<24)
#define FSMAGIC1 ('F' | 'S'<<8 | '<'<<16 | '<'<<24)
#define FSMAGIC2 ('>' | '>'<<8 | 'F'<<16 | 'S'<<24)
typedef struct {
const char *filename;
int fd;
unsigned long seek;
int writable;
int dirty; /* sync needed */
int modified; /* write_block was called */
const char *filename;
int fd;
unsigned long seek;
int writable;
int dirty; /* sync needed */
int modified; /* write_block was called */
unsigned isize; /* size in blocks of superblock + I list */
unsigned fsize; /* size in blocks of entire volume */
unsigned swapsz; /* size in blocks of swap area */
unsigned nfree; /* number of in core free blocks (0-100) */
unsigned free [NICFREE]; /* in core free blocks */
unsigned ninode; /* number of in core I nodes (0-100) */
unsigned inode [NICINOD]; /* in core free I nodes */
unsigned flock; /* lock during free list manipulation */
unsigned ilock; /* lock during I list manipulation */
unsigned fmod; /* super block modified flag */
unsigned ronly; /* mounted read-only flag */
long utime; /* current date of last update */
unsigned tfree; /* total free blocks */
unsigned tinode; /* total free inodes */
char fsmnt [MAXMNTLEN]; /* ordinary file mounted on */
unsigned lasti; /* start place for circular search */
unsigned nbehind; /* est # free inodes before s_lasti */
unsigned flags; /* mount time flags */
unsigned isize; /* size in blocks of superblock + I list */
unsigned fsize; /* size in blocks of entire volume */
unsigned swapsz; /* size in blocks of swap area */
unsigned nfree; /* number of in core free blocks (0-100) */
unsigned free [NICFREE]; /* in core free blocks */
unsigned ninode; /* number of in core I nodes (0-100) */
unsigned inode [NICINOD]; /* in core free I nodes */
unsigned flock; /* lock during free list manipulation */
unsigned ilock; /* lock during I list manipulation */
unsigned fmod; /* super block modified flag */
unsigned ronly; /* mounted read-only flag */
long utime; /* current date of last update */
unsigned tfree; /* total free blocks */
unsigned tinode; /* total free inodes */
char fsmnt [MAXMNTLEN]; /* ordinary file mounted on */
unsigned lasti; /* start place for circular search */
unsigned nbehind; /* est # free inodes before s_lasti */
unsigned flags; /* mount time flags */
} fs_t;
typedef struct {
fs_t *fs;
unsigned number;
int dirty; /* save needed */
fs_t *fs;
unsigned number;
int dirty; /* save needed */
unsigned short mode; /* file type and access mode */
#define INODE_MODE_FMT 0170000 /* type of file */
#define INODE_MODE_FCHR 020000 /* character special */
#define INODE_MODE_FDIR 040000 /* directory */
#define INODE_MODE_FBLK 060000 /* block special */
#define INODE_MODE_FREG 0100000 /* regular */
#define INODE_MODE_FLNK 0120000 /* symbolic link */
#define INODE_MODE_FSOCK 0140000 /* socket */
#define INODE_MODE_SUID 04000 /* set user id on execution */
#define INODE_MODE_SGID 02000 /* set group id on execution */
#define INODE_MODE_SVTX 01000 /* save swapped text even after use */
#define INODE_MODE_READ 0400 /* read, write, execute permissions */
#define INODE_MODE_WRITE 0200
#define INODE_MODE_EXEC 0100
unsigned short mode; /* file type and access mode */
#define INODE_MODE_FMT 0170000 /* type of file */
#define INODE_MODE_FCHR 020000 /* character special */
#define INODE_MODE_FDIR 040000 /* directory */
#define INODE_MODE_FBLK 060000 /* block special */
#define INODE_MODE_FREG 0100000 /* regular */
#define INODE_MODE_FLNK 0120000 /* symbolic link */
#define INODE_MODE_FSOCK 0140000 /* socket */
#define INODE_MODE_SUID 04000 /* set user id on execution */
#define INODE_MODE_SGID 02000 /* set group id on execution */
#define INODE_MODE_SVTX 01000 /* save swapped text even after use */
#define INODE_MODE_READ 0400 /* read, write, execute permissions */
#define INODE_MODE_WRITE 0200
#define INODE_MODE_EXEC 0100
unsigned short nlink; /* directory entries */
unsigned uid; /* owner */
unsigned gid; /* group */
unsigned long size; /* size */
unsigned addr [7]; /* device addresses constituting file */
unsigned flags; /* user defined flags */
unsigned short nlink; /* directory entries */
unsigned uid; /* owner */
unsigned gid; /* group */
unsigned long size; /* size */
unsigned addr [7]; /* device addresses constituting file */
unsigned flags; /* user defined flags */
/*
* Super-user and owner changeable flags.
*/
#define USER_SETTABLE 0x00ff /* mask of owner changeable flags */
#define USER_NODUMP 0x0001 /* do not dump file */
#define USER_IMMUTABLE 0x0002 /* file may not be changed */
#define USER_APPEND 0x0004 /* writes to file may only append */
#define USER_SETTABLE 0x00ff /* mask of owner changeable flags */
#define USER_NODUMP 0x0001 /* do not dump file */
#define USER_IMMUTABLE 0x0002 /* file may not be changed */
#define USER_APPEND 0x0004 /* writes to file may only append */
/*
* Super-user changeable flags.
*/
#define SYS_SETTABLE 0xff00 /* mask of superuser changeable flags */
#define SYS_ARCHIVED 0x0100 /* file is archived */
#define SYS_IMMUTABLE 0x0200 /* file may not be changed */
#define SYS_APPEND 0x0400 /* writes to file may only append */
#define SYS_SETTABLE 0xff00 /* mask of superuser changeable flags */
#define SYS_ARCHIVED 0x0100 /* file is archived */
#define SYS_IMMUTABLE 0x0200 /* file may not be changed */
#define SYS_APPEND 0x0400 /* writes to file may only append */
long atime; /* time last accessed */
long mtime; /* time last modified */
long ctime; /* time created */
long atime; /* time last accessed */
long mtime; /* time last modified */
long ctime; /* time created */
} fs_inode_t;
typedef struct {
unsigned ino;
unsigned reclen;
unsigned namlen;
char name [63+1];
unsigned ino;
unsigned reclen;
unsigned namlen;
char name [63+1];
} fs_dirent_t;
typedef void (*fs_directory_scanner_t) (fs_inode_t *dir,
fs_inode_t *file, char *dirname, char *filename, void *arg);
fs_inode_t *file, char *dirname, char *filename, void *arg);
typedef struct {
fs_inode_t inode;
int writable; /* write allowed */
unsigned long offset; /* current i/o offset */
fs_inode_t inode;
int writable; /* write allowed */
unsigned long offset; /* current i/o offset */
} fs_file_t;
typedef enum {
INODE_OP_LOOKUP, /* lookup inode by name */
INODE_OP_CREATE, /* create new file */
INODE_OP_DELETE, /* delete file */
INODE_OP_LINK, /* make a link to a file */
INODE_OP_LOOKUP, /* lookup inode by name */
INODE_OP_CREATE, /* create new file */
INODE_OP_DELETE, /* delete file */
INODE_OP_LINK, /* make a link to a file */
} fs_op_t;
int fs_seek (fs_t *fs, unsigned long offset);
@@ -167,7 +167,7 @@ int fs_open (fs_t *fs, const char *filename, int writable);
void fs_close (fs_t *fs);
int fs_sync (fs_t *fs, int force);
int fs_create (fs_t *fs, const char *filename, unsigned kbytes,
unsigned swap_kbytes);
unsigned swap_kbytes);
int fs_check (fs_t *fs);
void fs_print (fs_t *fs, FILE *out);
@@ -179,12 +179,12 @@ void fs_inode_clear (fs_inode_t *inode);
void fs_inode_truncate (fs_inode_t *inode, unsigned long size);
void fs_inode_print (fs_inode_t *inode, FILE *out);
int fs_inode_read (fs_inode_t *inode, unsigned long offset,
unsigned char *data, unsigned long bytes);
unsigned char *data, unsigned long bytes);
int fs_inode_write (fs_inode_t *inode, unsigned long offset,
unsigned char *data, unsigned long bytes);
unsigned char *data, unsigned long bytes);
int fs_inode_alloc (fs_t *fs, fs_inode_t *inode);
int fs_inode_by_name (fs_t *fs, fs_inode_t *inode, const char *name,
fs_op_t op, int mode);
fs_op_t op, int mode);
int inode_build_list (fs_t *fs);
int fs_write_block (fs_t *fs, unsigned bnum, unsigned char *data);
@@ -196,14 +196,14 @@ int fs_double_indirect_block_free (fs_t *fs, unsigned int bno, int nblk);
int fs_triple_indirect_block_free (fs_t *fs, unsigned int bno, int nblk);
void fs_directory_scan (fs_inode_t *inode, char *dirname,
fs_directory_scanner_t scanner, void *arg);
fs_directory_scanner_t scanner, void *arg);
void fs_dirent_pack (unsigned char *data, fs_dirent_t *dirent);
void fs_dirent_unpack (fs_dirent_t *dirent, unsigned char *data);
int fs_file_create (fs_t *fs, fs_file_t *file, const char *name, int mode);
int fs_file_open (fs_t *fs, fs_file_t *file, const char *name, int wflag);
int fs_file_read (fs_file_t *file, unsigned char *data,
unsigned long bytes);
unsigned long bytes);
int fs_file_write (fs_file_t *file, unsigned char *data,
unsigned long bytes);
unsigned long bytes);
int fs_file_close (fs_file_t *file);

File diff suppressed because it is too large Load Diff

View File

@@ -33,368 +33,370 @@ extern int verbose;
int inode_build_list (fs_t *fs)
{
fs_inode_t inode;
unsigned int inum, total_inodes;
fs_inode_t inode;
unsigned int inum, total_inodes;
total_inodes = (fs->isize - 1) * BSDFS_INODES_PER_BLOCK;
for (inum = 1; inum <= total_inodes; inum++) {
if (! fs_inode_get (fs, &inode, inum))
return 0;
if (inode.mode == 0) {
fs->inode [fs->ninode++] = inum;
if (fs->ninode >= NICINOD)
break;
}
}
return 1;
total_inodes = (fs->isize - 1) * BSDFS_INODES_PER_BLOCK;
for (inum = 1; inum <= total_inodes; inum++) {
if (! fs_inode_get (fs, &inode, inum))
return 0;
if (inode.mode == 0) {
fs->inode [fs->ninode++] = inum;
if (fs->ninode >= NICINOD)
break;
}
}
return 1;
}
static int create_inode1 (fs_t *fs)
{
fs_inode_t inode;
fs_inode_t inode;
memset (&inode, 0, sizeof(inode));
inode.mode = INODE_MODE_FREG;
inode.fs = fs;
inode.number = 1;
if (! fs_inode_save (&inode, 1))
return 0;
fs->tinode--;
return 1;
memset (&inode, 0, sizeof(inode));
inode.mode = INODE_MODE_FREG;
inode.fs = fs;
inode.number = 1;
if (! fs_inode_save (&inode, 1))
return 0;
fs->tinode--;
return 1;
}
static int create_root_directory (fs_t *fs)
{
fs_inode_t inode;
unsigned char buf [BSDFS_BSIZE];
unsigned int bno;
fs_inode_t inode;
unsigned char buf [BSDFS_BSIZE];
unsigned int bno;
memset (&inode, 0, sizeof(inode));
inode.mode = INODE_MODE_FDIR | 0777;
inode.fs = fs;
inode.number = BSDFS_ROOT_INODE;
inode.size = BSDFS_BSIZE;
inode.flags = 0;
memset (&inode, 0, sizeof(inode));
inode.mode = INODE_MODE_FDIR | 0777;
inode.fs = fs;
inode.number = BSDFS_ROOT_INODE;
inode.size = BSDFS_BSIZE;
inode.flags = 0;
time (&inode.ctime);
time (&inode.atime);
time (&inode.mtime);
time (&inode.ctime);
time (&inode.atime);
time (&inode.mtime);
/* directory - put in extra links */
memset (buf, 0, sizeof(buf));
buf[0] = inode.number;
buf[1] = inode.number >> 8;
buf[2] = inode.number >> 16;
buf[3] = inode.number >> 24;
buf[4] = 12;
buf[5] = 12 >> 8;
buf[6] = 1;
buf[7] = 1 >> 8;
buf[8] = '.';
buf[9] = 0;
buf[10] = 0;
buf[11] = 0;
/* directory - put in extra links */
memset (buf, 0, sizeof(buf));
buf[0] = inode.number;
buf[1] = inode.number >> 8;
buf[2] = inode.number >> 16;
buf[3] = inode.number >> 24;
buf[4] = 12;
buf[5] = 12 >> 8;
buf[6] = 1;
buf[7] = 1 >> 8;
buf[8] = '.';
buf[9] = 0;
buf[10] = 0;
buf[11] = 0;
buf[12+0] = BSDFS_ROOT_INODE;
buf[12+1] = BSDFS_ROOT_INODE >> 8;
buf[12+2] = BSDFS_ROOT_INODE >> 16;
buf[12+3] = BSDFS_ROOT_INODE >> 24;
buf[12+4] = 12;
buf[12+5] = 12 >> 8;
buf[12+6] = 2;
buf[12+7] = 2 >> 8;
buf[12+8] = '.';
buf[12+9] = '.';
buf[12+10] = 0;
buf[12+11] = 0;
buf[12+0] = BSDFS_ROOT_INODE;
buf[12+1] = BSDFS_ROOT_INODE >> 8;
buf[12+2] = BSDFS_ROOT_INODE >> 16;
buf[12+3] = BSDFS_ROOT_INODE >> 24;
buf[12+4] = 12;
buf[12+5] = 12 >> 8;
buf[12+6] = 2;
buf[12+7] = 2 >> 8;
buf[12+8] = '.';
buf[12+9] = '.';
buf[12+10] = 0;
buf[12+11] = 0;
buf[24+0] = BSDFS_LOSTFOUND_INODE;
buf[24+1] = BSDFS_LOSTFOUND_INODE >> 8;
buf[24+2] = BSDFS_LOSTFOUND_INODE >> 16;
buf[24+3] = BSDFS_LOSTFOUND_INODE >> 24;
buf[24+4] = (unsigned char) (BSDFS_BSIZE - 12 - 12);
buf[24+5] = (BSDFS_BSIZE - 12 - 12) >> 8;
buf[24+6] = 10;
buf[24+7] = 10 >> 8;
memcpy (&buf[24+8], "lost+found\0\0", 12);
buf[24+0] = BSDFS_LOSTFOUND_INODE;
buf[24+1] = BSDFS_LOSTFOUND_INODE >> 8;
buf[24+2] = BSDFS_LOSTFOUND_INODE >> 16;
buf[24+3] = BSDFS_LOSTFOUND_INODE >> 24;
buf[24+4] = (unsigned char) (BSDFS_BSIZE - 12 - 12);
buf[24+5] = (BSDFS_BSIZE - 12 - 12) >> 8;
buf[24+6] = 10;
buf[24+7] = 10 >> 8;
memcpy (&buf[24+8], "lost+found\0\0", 12);
if (fs->swapsz != 0) {
buf[24+4] = 20;
buf[24+5] = 20 >> 8;
buf[44+0] = BSDFS_SWAP_INODE;
buf[44+1] = BSDFS_SWAP_INODE >> 8;
buf[44+2] = BSDFS_SWAP_INODE >> 16;
buf[44+3] = BSDFS_SWAP_INODE >> 24;
buf[44+4] = (unsigned char) (BSDFS_BSIZE - 12 - 12 - 20);
buf[44+5] = (BSDFS_BSIZE - 12 - 12 - 20) >> 8;
buf[44+6] = 4;
buf[44+7] = 4 >> 8;
memcpy (&buf[44+8], "swap\0\0\0\0", 8);
}
inode.nlink = 3;
if (fs->swapsz != 0) {
buf[24+4] = 20;
buf[24+5] = 20 >> 8;
buf[44+0] = BSDFS_SWAP_INODE;
buf[44+1] = BSDFS_SWAP_INODE >> 8;
buf[44+2] = BSDFS_SWAP_INODE >> 16;
buf[44+3] = BSDFS_SWAP_INODE >> 24;
buf[44+4] = (unsigned char) (BSDFS_BSIZE - 12 - 12 - 20);
buf[44+5] = (BSDFS_BSIZE - 12 - 12 - 20) >> 8;
buf[44+6] = 4;
buf[44+7] = 4 >> 8;
memcpy (&buf[44+8], "swap\0\0\0\0", 8);
}
inode.nlink = 3;
if (! fs_block_alloc (fs, &bno))
return 0;
if (! fs_write_block (fs, bno, buf))
return 0;
inode.addr[0] = bno;
if (! fs_block_alloc (fs, &bno))
return 0;
if (! fs_write_block (fs, bno, buf))
return 0;
inode.addr[0] = bno;
if (! fs_inode_save (&inode, 1))
return 0;
fs->tinode--;
return 1;
if (! fs_inode_save (&inode, 1))
return 0;
fs->tinode--;
return 1;
}
static int create_lost_found_directory (fs_t *fs)
{
fs_inode_t inode;
unsigned char buf [BSDFS_BSIZE];
unsigned int bno;
fs_inode_t inode;
unsigned char buf [BSDFS_BSIZE];
unsigned int bno;
memset (&inode, 0, sizeof(inode));
inode.mode = INODE_MODE_FDIR | 0777;
inode.fs = fs;
inode.number = BSDFS_LOSTFOUND_INODE;
inode.size = BSDFS_BSIZE;
inode.flags = 0;
memset (&inode, 0, sizeof(inode));
inode.mode = INODE_MODE_FDIR | 0777;
inode.fs = fs;
inode.number = BSDFS_LOSTFOUND_INODE;
inode.size = BSDFS_BSIZE;
inode.flags = 0;
time (&inode.ctime);
time (&inode.atime);
time (&inode.mtime);
time (&inode.ctime);
time (&inode.atime);
time (&inode.mtime);
/* directory - put in extra links */
memset (buf, 0, sizeof(buf));
buf[0] = inode.number;
buf[1] = inode.number >> 8;
buf[2] = inode.number >> 16;
buf[3] = inode.number >> 24;
buf[4] = 12;
buf[5] = 12 >> 8;
buf[6] = 1;
buf[7] = 1 >> 8;
buf[8] = '.';
buf[9] = 0;
buf[10] = 0;
buf[11] = 0;
/* directory - put in extra links */
memset (buf, 0, sizeof(buf));
buf[0] = inode.number;
buf[1] = inode.number >> 8;
buf[2] = inode.number >> 16;
buf[3] = inode.number >> 24;
buf[4] = 12;
buf[5] = 12 >> 8;
buf[6] = 1;
buf[7] = 1 >> 8;
buf[8] = '.';
buf[9] = 0;
buf[10] = 0;
buf[11] = 0;
buf[12+0] = BSDFS_ROOT_INODE;
buf[12+1] = BSDFS_ROOT_INODE >> 8;
buf[12+2] = BSDFS_ROOT_INODE >> 16;
buf[12+3] = BSDFS_ROOT_INODE >> 24;
buf[12+4] = (unsigned char) (BSDFS_BSIZE - 12);
buf[12+5] = (BSDFS_BSIZE - 12) >> 8;
buf[12+6] = 2;
buf[12+7] = 2 >> 8;
buf[12+8] = '.';
buf[12+9] = '.';
buf[12+10] = 0;
buf[12+11] = 0;
buf[12+0] = BSDFS_ROOT_INODE;
buf[12+1] = BSDFS_ROOT_INODE >> 8;
buf[12+2] = BSDFS_ROOT_INODE >> 16;
buf[12+3] = BSDFS_ROOT_INODE >> 24;
buf[12+4] = (unsigned char) (BSDFS_BSIZE - 12);
buf[12+5] = (BSDFS_BSIZE - 12) >> 8;
buf[12+6] = 2;
buf[12+7] = 2 >> 8;
buf[12+8] = '.';
buf[12+9] = '.';
buf[12+10] = 0;
buf[12+11] = 0;
inode.nlink = 2;
inode.nlink = 2;
if (! fs_block_alloc (fs, &bno))
return 0;
if (! fs_write_block (fs, bno, buf))
return 0;
inode.addr[0] = bno;
if (! fs_block_alloc (fs, &bno))
return 0;
if (! fs_write_block (fs, bno, buf))
return 0;
inode.addr[0] = bno;
if (! fs_inode_save (&inode, 1))
return 0;
fs->tinode--;
return 1;
if (! fs_inode_save (&inode, 1))
return 0;
fs->tinode--;
return 1;
}
static void map_block_swap (fs_inode_t *inode, unsigned lbn)
{
unsigned block [BSDFS_BSIZE / 4];
unsigned int bn, indir, newb, shift, i, j;
unsigned block [BSDFS_BSIZE / 4];
unsigned int bn, indir, newb, shift, i, j;
/*
* Blocks 0..NADDR-3 are direct blocks.
*/
if (lbn < NADDR-3) {
/* small file algorithm */
inode->addr[lbn] = inode->fs->isize + lbn;
return;
}
/*
* Blocks 0..NADDR-3 are direct blocks.
*/
if (lbn < NADDR-3) {
/* small file algorithm */
inode->addr[lbn] = inode->fs->isize + lbn;
return;
}
/*
* Addresses NADDR-3, NADDR-2, and NADDR-1
* have single, double, triple indirect blocks.
* The first step is to determine
* how many levels of indirection.
*/
shift = 0;
i = 1;
bn = lbn - (NADDR-3);
for (j=3; ; j--) {
if (j == 0) {
fprintf (stderr, "swap: too large size\n");
exit (-1);
}
shift += NSHIFT;
i <<= NSHIFT;
if (bn < i)
break;
bn -= i;
}
/*
* Addresses NADDR-3, NADDR-2, and NADDR-1
* have single, double, triple indirect blocks.
* The first step is to determine
* how many levels of indirection.
*/
shift = 0;
i = 1;
bn = lbn - (NADDR-3);
for (j=3; ; j--) {
if (j == 0) {
fprintf (stderr, "swap: too large size\n");
exit (-1);
}
shift += NSHIFT;
i <<= NSHIFT;
if (bn < i)
break;
bn -= i;
}
/*
* Fetch the first indirect block.
*/
indir = inode->addr [NADDR-j];
if (indir == 0) {
if (! fs_block_alloc (inode->fs, &indir)) {
alloc_error: fprintf (stderr, "swap: cannot allocate indirect block\n");
exit (-1);
}
if (verbose)
printf ("swap: allocate indirect block %d (j=%d)\n", indir, j);
memset (block, 0, BSDFS_BSIZE);
if (! fs_write_block (inode->fs, indir, (unsigned char*) block)) {
write_error: fprintf (stderr, "swap: cannot write indirect block %d\n", indir);
exit (-1);
}
inode->addr [NADDR-j] = indir;
}
/*
* Fetch the first indirect block.
*/
indir = inode->addr [NADDR-j];
if (indir == 0) {
if (! fs_block_alloc (inode->fs, &indir)) {
alloc_error:
fprintf (stderr, "swap: cannot allocate indirect block\n");
exit (-1);
}
if (verbose)
printf ("swap: allocate indirect block %d (j=%d)\n", indir, j);
memset (block, 0, BSDFS_BSIZE);
if (! fs_write_block (inode->fs, indir, (unsigned char*) block)) {
write_error:
fprintf (stderr, "swap: cannot write indirect block %d\n", indir);
exit (-1);
}
inode->addr [NADDR-j] = indir;
}
/*
* Fetch through the indirect blocks
*/
for (; ; j++) {
if (! fs_read_block (inode->fs, indir, (unsigned char*) block)) {
fprintf (stderr, "swap: cannot read indirect block %d\n", indir);
exit (-1);
}
shift -= NSHIFT;
i = (bn >> shift) & NMASK;
if (j == 3) {
block[i] = inode->fs->isize + lbn;
if (! fs_write_block (inode->fs, indir, (unsigned char*) block))
goto write_error;
return;
}
if (block[i] != 0) {
indir = block [i];
continue;
}
/* Allocate new indirect block. */
if (! fs_block_alloc (inode->fs, &newb))
goto alloc_error;
if (verbose)
printf ("swap: allocate new block %d (j=%d)\n", newb, j);
block[i] = newb;
if (! fs_write_block (inode->fs, indir, (unsigned char*) block))
goto write_error;
memset (block, 0, BSDFS_BSIZE);
if (! fs_write_block (inode->fs, newb, (unsigned char*) block)) {
fprintf (stderr, "swap: cannot write block %d\n", newb);
exit (-1);
}
indir = newb;
}
/*
* Fetch through the indirect blocks
*/
for (; ; j++) {
if (! fs_read_block (inode->fs, indir, (unsigned char*) block)) {
fprintf (stderr, "swap: cannot read indirect block %d\n", indir);
exit (-1);
}
shift -= NSHIFT;
i = (bn >> shift) & NMASK;
if (j == 3) {
block[i] = inode->fs->isize + lbn;
if (! fs_write_block (inode->fs, indir, (unsigned char*) block))
goto write_error;
return;
}
if (block[i] != 0) {
indir = block [i];
continue;
}
/* Allocate new indirect block. */
if (! fs_block_alloc (inode->fs, &newb))
goto alloc_error;
if (verbose)
printf ("swap: allocate new block %d (j=%d)\n", newb, j);
block[i] = newb;
if (! fs_write_block (inode->fs, indir, (unsigned char*) block))
goto write_error;
memset (block, 0, BSDFS_BSIZE);
if (! fs_write_block (inode->fs, newb, (unsigned char*) block)) {
fprintf (stderr, "swap: cannot write block %d\n", newb);
exit (-1);
}
indir = newb;
}
}
static int create_swap_file (fs_t *fs)
{
fs_inode_t inode;
unsigned lbn;
fs_inode_t inode;
unsigned lbn;
memset (&inode, 0, sizeof(inode));
inode.mode = INODE_MODE_FREG | 0400;
inode.fs = fs;
inode.number = BSDFS_SWAP_INODE;
inode.size = fs->swapsz * BSDFS_BSIZE;
inode.flags = /*SYS_IMMUTABLE |*/ USER_IMMUTABLE | USER_NODUMP;
inode.nlink = 1;
inode.dirty = 1;
memset (&inode, 0, sizeof(inode));
inode.mode = INODE_MODE_FREG | 0400;
inode.fs = fs;
inode.number = BSDFS_SWAP_INODE;
inode.size = fs->swapsz * BSDFS_BSIZE;
inode.flags = /*SYS_IMMUTABLE |*/ USER_IMMUTABLE | USER_NODUMP;
inode.nlink = 1;
inode.dirty = 1;
time (&inode.ctime);
time (&inode.atime);
time (&inode.mtime);
time (&inode.ctime);
time (&inode.atime);
time (&inode.mtime);
for (lbn=0; lbn<fs->swapsz; lbn++)
map_block_swap (&inode, lbn);
for (lbn=0; lbn<fs->swapsz; lbn++)
map_block_swap (&inode, lbn);
if (! fs_inode_save (&inode, 0)) {
fprintf (stderr, "swap: cannot save file inode\n");
return 0;
}
return 1;
if (! fs_inode_save (&inode, 0)) {
fprintf (stderr, "swap: cannot save file inode\n");
return 0;
}
return 1;
}
int fs_create (fs_t *fs, const char *filename, unsigned kbytes,
unsigned swap_kbytes)
unsigned swap_kbytes)
{
int n;
unsigned char buf [BSDFS_BSIZE];
off_t bytes, offset;
int n;
unsigned char buf [BSDFS_BSIZE];
off_t bytes, offset;
memset (fs, 0, sizeof (*fs));
fs->filename = filename;
fs->seek = 0;
memset (fs, 0, sizeof (*fs));
fs->filename = filename;
fs->seek = 0;
fs->fd = open (fs->filename, O_CREAT | O_RDWR, 0666);
if (fs->fd < 0)
return 0;
fs->writable = 1;
fs->fd = open (fs->filename, O_CREAT | O_RDWR, 0666);
if (fs->fd < 0)
return 0;
fs->writable = 1;
/* get total disk size
* and inode block size */
bytes = (off_t) kbytes * 1024ULL;
fs->fsize = bytes / BSDFS_BSIZE;
fs->isize = 1 + (fs->fsize / 16 + BSDFS_INODES_PER_BLOCK - 1) /
BSDFS_INODES_PER_BLOCK;
if (fs->isize < 2)
return 0;
/* get total disk size
* and inode block size */
bytes = (off_t) kbytes * 1024ULL;
fs->fsize = bytes / BSDFS_BSIZE;
fs->isize = 1 + (fs->fsize / 16 + BSDFS_INODES_PER_BLOCK - 1) /
BSDFS_INODES_PER_BLOCK;
if (fs->isize < 2)
return 0;
/* make sure the file is of proper size */
offset = lseek (fs->fd, bytes-1, SEEK_SET);
if (offset != bytes-1)
return 0;
if (write (fs->fd, "", 1) != 1) {
perror ("write");
return 0;
}
lseek (fs->fd, 0, SEEK_SET);
/* make sure the file is of proper size */
offset = lseek (fs->fd, bytes-1, SEEK_SET);
if (offset != bytes-1)
return 0;
if (write (fs->fd, "", 1) != 1) {
perror ("write");
return 0;
}
lseek (fs->fd, 0, SEEK_SET);
/* build a list of free blocks */
fs->swapsz = swap_kbytes * 1024 / BSDFS_BSIZE;
fs_block_free (fs, 0);
for (n = fs->fsize - 1; n >= fs->isize + fs->swapsz; n--)
if (! fs_block_free (fs, n))
return 0;
/* build a list of free blocks */
fs->swapsz = swap_kbytes * 1024 / BSDFS_BSIZE;
fs_block_free (fs, 0);
for (n = fs->fsize - 1; n >= fs->isize + fs->swapsz; n--)
if (! fs_block_free (fs, n))
return 0;
/* initialize inodes */
memset (buf, 0, BSDFS_BSIZE);
if (! fs_seek (fs, BSDFS_BSIZE))
return 0;
for (n=1; n < fs->isize; n++) {
if (! fs_write (fs, buf, BSDFS_BSIZE))
return 0;
fs->tinode += BSDFS_INODES_PER_BLOCK;
}
/* initialize inodes */
memset (buf, 0, BSDFS_BSIZE);
if (! fs_seek (fs, BSDFS_BSIZE))
return 0;
for (n=1; n < fs->isize; n++) {
if (! fs_write (fs, buf, BSDFS_BSIZE))
return 0;
fs->tinode += BSDFS_INODES_PER_BLOCK;
}
/* legacy empty inode 1 */
if (! create_inode1 (fs))
return 0;
/* legacy empty inode 1 */
if (! create_inode1 (fs))
return 0;
/* lost+found directory */
if (! create_lost_found_directory (fs))
return 0;
/* lost+found directory */
if (! create_lost_found_directory (fs))
return 0;
/* root directory */
if (! create_root_directory (fs))
return 0;
/* root directory */
if (! create_root_directory (fs))
return 0;
/* swap file */
if (fs->swapsz != 0 && ! create_swap_file (fs))
return 0;
/* swap file */
if (fs->swapsz != 0 && ! create_swap_file (fs))
return 0;
/* build a list of free inodes */
if (! inode_build_list (fs))
return 0;
/* build a list of free inodes */
if (! inode_build_list (fs))
return 0;
/* write out super block */
return fs_sync (fs, 1);
/* write out super block */
return fs_sync (fs, 1);
}

View File

@@ -29,68 +29,68 @@ extern int verbose;
int fs_file_create (fs_t *fs, fs_file_t *file, const char *name, int mode)
{
if (! fs_inode_by_name (fs, &file->inode, name, INODE_OP_CREATE, mode)) {
fprintf (stderr, "%s: inode open failed\n", name);
return 0;
}
if ((file->inode.mode & INODE_MODE_FMT) == INODE_MODE_FDIR) {
/* Cannot open directory on write. */
return 0;
}
fs_inode_truncate (&file->inode, 0);
fs_inode_save (&file->inode, 0);
file->writable = 1;
file->offset = 0;
return 1;
if (! fs_inode_by_name (fs, &file->inode, name, INODE_OP_CREATE, mode)) {
fprintf (stderr, "%s: inode open failed\n", name);
return 0;
}
if ((file->inode.mode & INODE_MODE_FMT) == INODE_MODE_FDIR) {
/* Cannot open directory on write. */
return 0;
}
fs_inode_truncate (&file->inode, 0);
fs_inode_save (&file->inode, 0);
file->writable = 1;
file->offset = 0;
return 1;
}
int fs_file_open (fs_t *fs, fs_file_t *file, const char *name, int wflag)
{
if (! fs_inode_by_name (fs, &file->inode, name, INODE_OP_LOOKUP, 0)) {
fprintf (stderr, "%s: inode open failed\n", name);
return 0;
}
if (wflag && (file->inode.mode & INODE_MODE_FMT) == INODE_MODE_FDIR) {
/* Cannot open directory on write. */
return 0;
}
file->writable = wflag;
file->offset = 0;
return 1;
if (! fs_inode_by_name (fs, &file->inode, name, INODE_OP_LOOKUP, 0)) {
fprintf (stderr, "%s: inode open failed\n", name);
return 0;
}
if (wflag && (file->inode.mode & INODE_MODE_FMT) == INODE_MODE_FDIR) {
/* Cannot open directory on write. */
return 0;
}
file->writable = wflag;
file->offset = 0;
return 1;
}
int fs_file_read (fs_file_t *file, unsigned char *data, unsigned long bytes)
{
if (! fs_inode_read (&file->inode, file->offset, data, bytes)) {
fprintf (stderr, "inode %d: file read failed, %lu bytes at offset %lu\n",
file->inode.number, bytes, file->offset);
return 0;
}
file->offset += bytes;
return 1;
if (! fs_inode_read (&file->inode, file->offset, data, bytes)) {
fprintf (stderr, "inode %d: file read failed, %lu bytes at offset %lu\n",
file->inode.number, bytes, file->offset);
return 0;
}
file->offset += bytes;
return 1;
}
int fs_file_write (fs_file_t *file, unsigned char *data, unsigned long bytes)
{
if (! file->writable)
return 0;
if (! fs_inode_write (&file->inode, file->offset, data, bytes)) {
fprintf (stderr, "inode %d: file write failed, %lu bytes at offset %lu\n",
file->inode.number, bytes, file->offset);
return 0;
}
file->offset += bytes;
return 1;
if (! file->writable)
return 0;
if (! fs_inode_write (&file->inode, file->offset, data, bytes)) {
fprintf (stderr, "inode %d: file write failed, %lu bytes at offset %lu\n",
file->inode.number, bytes, file->offset);
return 0;
}
file->offset += bytes;
return 1;
}
int fs_file_close (fs_file_t *file)
{
if (file->writable) {
if (! fs_inode_save (&file->inode, 0)) {
fprintf (stderr, "inode %d: file close failed\n",
file->inode.number);
return 0;
}
}
return 1;
if (file->writable) {
if (! fs_inode_save (&file->inode, 0)) {
fprintf (stderr, "inode %d: file close failed\n",
file->inode.number);
return 0;
}
}
return 1;
}

View File

@@ -43,249 +43,249 @@ unsigned kbytes;
unsigned swap_kbytes;
static const char *program_version =
"BSD 2.x file system utility, version 1.1\n"
"Copyright (C) 2011-2014 Serge Vakulenko";
"BSD 2.x file system utility, version 1.1\n"
"Copyright (C) 2011-2014 Serge Vakulenko";
static const char *program_bug_address = "<serge@vak.ru>";
static struct option program_options[] = {
{ "help", no_argument, 0, 'h' },
{ "version", no_argument, 0, 'V' },
{ "verbose", no_argument, 0, 'v' },
{ "add", no_argument, 0, 'a' },
{ "extract", no_argument, 0, 'x' },
{ "check", no_argument, 0, 'c' },
{ "fix", no_argument, 0, 'f' },
{ "mount", no_argument, 0, 'm' },
{ "new", required_argument, 0, 'n' },
{ "swap", required_argument, 0, 's' },
{ "manifest", required_argument, 0, 'M' },
{ 0 }
{ "help", no_argument, 0, 'h' },
{ "version", no_argument, 0, 'V' },
{ "verbose", no_argument, 0, 'v' },
{ "add", no_argument, 0, 'a' },
{ "extract", no_argument, 0, 'x' },
{ "check", no_argument, 0, 'c' },
{ "fix", no_argument, 0, 'f' },
{ "mount", no_argument, 0, 'm' },
{ "new", required_argument, 0, 'n' },
{ "swap", required_argument, 0, 's' },
{ "manifest", required_argument, 0, 'M' },
{ 0 }
};
static void print_help (char *progname)
{
char *p = strrchr (progname, '/');
if (p)
progname = p+1;
char *p = strrchr (progname, '/');
if (p)
progname = p+1;
printf ("%s\n", program_version);
printf ("This program is free software; it comes with ABSOLUTELY NO WARRANTY;\n"
"see the GNU General Public License for more details.\n");
printf ("\n");
printf ("Usage:\n");
printf (" %s [--verbose] filesys.img\n", progname);
printf (" %s --add filesys.img files...\n", progname);
printf (" %s --extract filesys.img\n", progname);
printf (" %s --check [--fix] filesys.img\n", progname);
printf (" %s --new=kbytes [--swap=kbytes] [--manifest=file] filesys.img [dir]\n", progname);
printf (" %s --mount filesys.img dir\n", progname);
printf ("\n");
printf ("Options:\n");
printf (" -a, --add Add files to filesystem.\n");
printf (" -x, --extract Extract all files.\n");
printf (" -c, --check Check filesystem, use -c -f to fix.\n");
printf (" -f, --fix Fix bugs in filesystem.\n");
printf (" -n NUM, --new=NUM Create new filesystem, size in kbytes.\n");
printf (" Add files from specified directory (optional)\n");
printf (" -s NUM, --swap=NUM Size of swap area in kbytes.\n");
printf (" -M file, --manifest=file List of files and attributes to create.\n");
printf (" -m, --mount Mount the filesystem.\n");
printf (" -v, --verbose Be verbose.\n");
printf (" -V, --version Print version information and then exit.\n");
printf (" -h, --help Print this message.\n");
printf ("\n");
printf ("Report bugs to \"%s\".\n", program_bug_address);
printf ("%s\n", program_version);
printf ("This program is free software; it comes with ABSOLUTELY NO WARRANTY;\n"
"see the GNU General Public License for more details.\n");
printf ("\n");
printf ("Usage:\n");
printf (" %s [--verbose] filesys.img\n", progname);
printf (" %s --add filesys.img files...\n", progname);
printf (" %s --extract filesys.img\n", progname);
printf (" %s --check [--fix] filesys.img\n", progname);
printf (" %s --new=kbytes [--swap=kbytes] [--manifest=file] filesys.img [dir]\n", progname);
printf (" %s --mount filesys.img dir\n", progname);
printf ("\n");
printf ("Options:\n");
printf (" -a, --add Add files to filesystem.\n");
printf (" -x, --extract Extract all files.\n");
printf (" -c, --check Check filesystem, use -c -f to fix.\n");
printf (" -f, --fix Fix bugs in filesystem.\n");
printf (" -n NUM, --new=NUM Create new filesystem, size in kbytes.\n");
printf (" Add files from specified directory (optional)\n");
printf (" -s NUM, --swap=NUM Size of swap area in kbytes.\n");
printf (" -M file, --manifest=file List of files and attributes to create.\n");
printf (" -m, --mount Mount the filesystem.\n");
printf (" -v, --verbose Be verbose.\n");
printf (" -V, --version Print version information and then exit.\n");
printf (" -h, --help Print this message.\n");
printf ("\n");
printf ("Report bugs to \"%s\".\n", program_bug_address);
}
void print_inode (fs_inode_t *inode,
char *dirname, char *filename, FILE *out)
char *dirname, char *filename, FILE *out)
{
fprintf (out, "%s/%s", dirname, filename);
switch (inode->mode & INODE_MODE_FMT) {
case INODE_MODE_FDIR:
if (filename[0] != 0)
fprintf (out, "/");
break;
case INODE_MODE_FCHR:
fprintf (out, " - char %d %d",
inode->addr[1] >> 8, inode->addr[1] & 0xff);
break;
case INODE_MODE_FBLK:
fprintf (out, " - block %d %d",
inode->addr[1] >> 8, inode->addr[1] & 0xff);
break;
default:
fprintf (out, " - %lu bytes", inode->size);
break;
}
fprintf (out, "\n");
fprintf (out, "%s/%s", dirname, filename);
switch (inode->mode & INODE_MODE_FMT) {
case INODE_MODE_FDIR:
if (filename[0] != 0)
fprintf (out, "/");
break;
case INODE_MODE_FCHR:
fprintf (out, " - char %d %d",
inode->addr[1] >> 8, inode->addr[1] & 0xff);
break;
case INODE_MODE_FBLK:
fprintf (out, " - block %d %d",
inode->addr[1] >> 8, inode->addr[1] & 0xff);
break;
default:
fprintf (out, " - %lu bytes", inode->size);
break;
}
fprintf (out, "\n");
}
void print_indirect_block (fs_t *fs, unsigned int bno, FILE *out)
{
unsigned short nb;
unsigned char data [BSDFS_BSIZE];
int i;
unsigned short nb;
unsigned char data [BSDFS_BSIZE];
int i;
fprintf (out, " [%d]", bno);
if (! fs_read_block (fs, bno, data)) {
fprintf (stderr, "read error at block %d\n", bno);
return;
}
for (i=0; i<BSDFS_BSIZE-2; i+=2) {
nb = data [i+1] << 8 | data [i];
if (nb)
fprintf (out, " %d", nb);
}
fprintf (out, " [%d]", bno);
if (! fs_read_block (fs, bno, data)) {
fprintf (stderr, "read error at block %d\n", bno);
return;
}
for (i=0; i<BSDFS_BSIZE-2; i+=2) {
nb = data [i+1] << 8 | data [i];
if (nb)
fprintf (out, " %d", nb);
}
}
void print_double_indirect_block (fs_t *fs, unsigned int bno, FILE *out)
{
unsigned short nb;
unsigned char data [BSDFS_BSIZE];
int i;
unsigned short nb;
unsigned char data [BSDFS_BSIZE];
int i;
fprintf (out, " [%d]", bno);
if (! fs_read_block (fs, bno, data)) {
fprintf (stderr, "read error at block %d\n", bno);
return;
}
for (i=0; i<BSDFS_BSIZE-2; i+=2) {
nb = data [i+1] << 8 | data [i];
if (nb)
print_indirect_block (fs, nb, out);
}
fprintf (out, " [%d]", bno);
if (! fs_read_block (fs, bno, data)) {
fprintf (stderr, "read error at block %d\n", bno);
return;
}
for (i=0; i<BSDFS_BSIZE-2; i+=2) {
nb = data [i+1] << 8 | data [i];
if (nb)
print_indirect_block (fs, nb, out);
}
}
void print_triple_indirect_block (fs_t *fs, unsigned int bno, FILE *out)
{
unsigned short nb;
unsigned char data [BSDFS_BSIZE];
int i;
unsigned short nb;
unsigned char data [BSDFS_BSIZE];
int i;
fprintf (out, " [%d]", bno);
if (! fs_read_block (fs, bno, data)) {
fprintf (stderr, "read error at block %d\n", bno);
return;
}
for (i=0; i<BSDFS_BSIZE-2; i+=2) {
nb = data [i+1] << 8 | data [i];
if (nb)
print_indirect_block (fs, nb, out);
}
fprintf (out, " [%d]", bno);
if (! fs_read_block (fs, bno, data)) {
fprintf (stderr, "read error at block %d\n", bno);
return;
}
for (i=0; i<BSDFS_BSIZE-2; i+=2) {
nb = data [i+1] << 8 | data [i];
if (nb)
print_indirect_block (fs, nb, out);
}
}
void print_inode_blocks (fs_inode_t *inode, FILE *out)
{
int i;
int i;
if ((inode->mode & INODE_MODE_FMT) == INODE_MODE_FCHR ||
(inode->mode & INODE_MODE_FMT) == INODE_MODE_FBLK)
return;
if ((inode->mode & INODE_MODE_FMT) == INODE_MODE_FCHR ||
(inode->mode & INODE_MODE_FMT) == INODE_MODE_FBLK)
return;
fprintf (out, " ");
for (i=0; i<NDADDR; ++i) {
if (inode->addr[i] == 0)
continue;
fprintf (out, " %d", inode->addr[i]);
}
if (inode->addr[NDADDR] != 0)
print_indirect_block (inode->fs, inode->addr[NDADDR], out);
if (inode->addr[NDADDR+1] != 0)
print_double_indirect_block (inode->fs,
inode->addr[NDADDR+1], out);
if (inode->addr[NDADDR+2] != 0)
print_triple_indirect_block (inode->fs,
inode->addr[NDADDR+2], out);
fprintf (out, "\n");
fprintf (out, " ");
for (i=0; i<NDADDR; ++i) {
if (inode->addr[i] == 0)
continue;
fprintf (out, " %d", inode->addr[i]);
}
if (inode->addr[NDADDR] != 0)
print_indirect_block (inode->fs, inode->addr[NDADDR], out);
if (inode->addr[NDADDR+1] != 0)
print_double_indirect_block (inode->fs,
inode->addr[NDADDR+1], out);
if (inode->addr[NDADDR+2] != 0)
print_triple_indirect_block (inode->fs,
inode->addr[NDADDR+2], out);
fprintf (out, "\n");
}
void extract_inode (fs_inode_t *inode, char *path)
{
int fd, n, mode;
unsigned long offset;
unsigned char data [BSDFS_BSIZE];
int fd, n, mode;
unsigned long offset;
unsigned char data [BSDFS_BSIZE];
/* Allow read/write for user. */
mode = (inode->mode & 0777) | 0600;
fd = open (path, O_CREAT | O_RDWR, mode);
if (fd < 0) {
perror (path);
return;
}
for (offset = 0; offset < inode->size; offset += BSDFS_BSIZE) {
n = inode->size - offset;
if (n > BSDFS_BSIZE)
n = BSDFS_BSIZE;
if (! fs_inode_read (inode, offset, data, n)) {
fprintf (stderr, "%s: read error at offset %ld\n",
path, offset);
break;
}
if (write (fd, data, n) != n) {
fprintf (stderr, "%s: write error\n", path);
break;
}
}
close (fd);
/* Allow read/write for user. */
mode = (inode->mode & 0777) | 0600;
fd = open (path, O_CREAT | O_RDWR, mode);
if (fd < 0) {
perror (path);
return;
}
for (offset = 0; offset < inode->size; offset += BSDFS_BSIZE) {
n = inode->size - offset;
if (n > BSDFS_BSIZE)
n = BSDFS_BSIZE;
if (! fs_inode_read (inode, offset, data, n)) {
fprintf (stderr, "%s: read error at offset %ld\n",
path, offset);
break;
}
if (write (fd, data, n) != n) {
fprintf (stderr, "%s: write error\n", path);
break;
}
}
close (fd);
}
void extractor (fs_inode_t *dir, fs_inode_t *inode,
char *dirname, char *filename, void *arg)
char *dirname, char *filename, void *arg)
{
FILE *out = arg;
char *path, *relpath;
FILE *out = arg;
char *path, *relpath;
if (verbose)
print_inode (inode, dirname, filename, out);
if (verbose)
print_inode (inode, dirname, filename, out);
if ((inode->mode & INODE_MODE_FMT) != INODE_MODE_FDIR &&
(inode->mode & INODE_MODE_FMT) != INODE_MODE_FREG)
return;
if ((inode->mode & INODE_MODE_FMT) != INODE_MODE_FDIR &&
(inode->mode & INODE_MODE_FMT) != INODE_MODE_FREG)
return;
path = alloca (strlen (dirname) + strlen (filename) + 2);
strcpy (path, dirname);
strcat (path, "/");
strcat (path, filename);
for (relpath=path; *relpath == '/'; relpath++)
continue;
path = alloca (strlen (dirname) + strlen (filename) + 2);
strcpy (path, dirname);
strcat (path, "/");
strcat (path, filename);
for (relpath=path; *relpath == '/'; relpath++)
continue;
if ((inode->mode & INODE_MODE_FMT) == INODE_MODE_FDIR) {
if (mkdir (relpath, 0775) < 0 && errno != EEXIST)
perror (relpath);
/* Scan subdirectory. */
fs_directory_scan (inode, path, extractor, arg);
} else {
extract_inode (inode, relpath);
}
if ((inode->mode & INODE_MODE_FMT) == INODE_MODE_FDIR) {
if (mkdir (relpath, 0775) < 0 && errno != EEXIST)
perror (relpath);
/* Scan subdirectory. */
fs_directory_scan (inode, path, extractor, arg);
} else {
extract_inode (inode, relpath);
}
}
void scanner (fs_inode_t *dir, fs_inode_t *inode,
char *dirname, char *filename, void *arg)
char *dirname, char *filename, void *arg)
{
FILE *out = arg;
char *path;
FILE *out = arg;
char *path;
print_inode (inode, dirname, filename, out);
print_inode (inode, dirname, filename, out);
if (verbose > 1) {
/* Print a list of blocks. */
print_inode_blocks (inode, out);
if (verbose > 2) {
fs_inode_print (inode, out);
printf ("--------\n");
}
}
if ((inode->mode & INODE_MODE_FMT) == INODE_MODE_FDIR &&
inode->number != BSDFS_ROOT_INODE) {
/* Scan subdirectory. */
path = alloca (strlen (dirname) + strlen (filename) + 2);
strcpy (path, dirname);
strcat (path, "/");
strcat (path, filename);
fs_directory_scan (inode, path, scanner, arg);
}
if (verbose > 1) {
/* Print a list of blocks. */
print_inode_blocks (inode, out);
if (verbose > 2) {
fs_inode_print (inode, out);
printf ("--------\n");
}
}
if ((inode->mode & INODE_MODE_FMT) == INODE_MODE_FDIR &&
inode->number != BSDFS_ROOT_INODE) {
/* Scan subdirectory. */
path = alloca (strlen (dirname) + strlen (filename) + 2);
strcpy (path, dirname);
strcat (path, "/");
strcat (path, filename);
fs_directory_scan (inode, path, scanner, arg);
}
}
/*
@@ -293,46 +293,46 @@ void scanner (fs_inode_t *dir, fs_inode_t *inode,
*/
void add_directory (fs_t *fs, char *name)
{
fs_inode_t dir, parent;
char buf [BSDFS_BSIZE], *p;
fs_inode_t dir, parent;
char buf [BSDFS_BSIZE], *p;
/* Open parent directory. */
strcpy (buf, name);
p = strrchr (buf, '/');
if (p)
*p = 0;
else
*buf = 0;
if (! fs_inode_by_name (fs, &parent, buf, INODE_OP_LOOKUP, 0)) {
fprintf (stderr, "%s: cannot open directory\n", buf);
return;
}
/* Open parent directory. */
strcpy (buf, name);
p = strrchr (buf, '/');
if (p)
*p = 0;
else
*buf = 0;
if (! fs_inode_by_name (fs, &parent, buf, INODE_OP_LOOKUP, 0)) {
fprintf (stderr, "%s: cannot open directory\n", buf);
return;
}
/* Create directory. */
int done = fs_inode_by_name (fs, &dir, name, INODE_OP_CREATE, INODE_MODE_FDIR | 0777);
if (! done) {
fprintf (stderr, "%s: directory inode create failed\n", name);
return;
}
if (done == 1) {
/* The directory already existed. */
return;
}
fs_inode_save (&dir, 0);
/* Create directory. */
int done = fs_inode_by_name (fs, &dir, name, INODE_OP_CREATE, INODE_MODE_FDIR | 0777);
if (! done) {
fprintf (stderr, "%s: directory inode create failed\n", name);
return;
}
if (done == 1) {
/* The directory already existed. */
return;
}
fs_inode_save (&dir, 0);
/* Make parent link '..' */
strcpy (buf, name);
strcat (buf, "/..");
if (! fs_inode_by_name (fs, &dir, buf, INODE_OP_LINK, parent.number)) {
fprintf (stderr, "%s: dotdot link failed\n", name);
return;
}
if (! fs_inode_get (fs, &parent, parent.number)) {
fprintf (stderr, "inode %d: cannot open parent\n", parent.number);
return;
}
++parent.nlink;
fs_inode_save (&parent, 1);
/* Make parent link '..' */
strcpy (buf, name);
strcat (buf, "/..");
if (! fs_inode_by_name (fs, &dir, buf, INODE_OP_LINK, parent.number)) {
fprintf (stderr, "%s: dotdot link failed\n", name);
return;
}
if (! fs_inode_get (fs, &parent, parent.number)) {
fprintf (stderr, "inode %d: cannot open parent\n", parent.number);
return;
}
++parent.nlink;
fs_inode_save (&parent, 1);
/*printf ("*** inode %d: increment link counter to %d\n", parent.number, parent.nlink);*/
}
@@ -341,25 +341,25 @@ void add_directory (fs_t *fs, char *name)
*/
void add_device (fs_t *fs, char *name, char *spec)
{
fs_inode_t dev;
int majr, minr;
char type;
fs_inode_t dev;
int majr, minr;
char type;
if (sscanf (spec, "%c%d:%d", &type, &majr, &minr) != 3 ||
(type != 'c' && type != 'b') ||
majr < 0 || majr > 255 || minr < 0 || minr > 255) {
fprintf (stderr, "%s: invalid device specification\n", spec);
fprintf (stderr, "expected c<major>:<minor> or b<major>:<minor>\n");
return;
}
if (! fs_inode_by_name (fs, &dev, name, INODE_OP_CREATE, 0666 |
((type == 'b') ? INODE_MODE_FBLK : INODE_MODE_FCHR))) {
fprintf (stderr, "%s: device inode create failed\n", name);
return;
}
dev.addr[1] = majr << 8 | minr;
time (&dev.mtime);
fs_inode_save (&dev, 1);
if (sscanf (spec, "%c%d:%d", &type, &majr, &minr) != 3 ||
(type != 'c' && type != 'b') ||
majr < 0 || majr > 255 || minr < 0 || minr > 255) {
fprintf (stderr, "%s: invalid device specification\n", spec);
fprintf (stderr, "expected c<major>:<minor> or b<major>:<minor>\n");
return;
}
if (! fs_inode_by_name (fs, &dev, name, INODE_OP_CREATE, 0666 |
((type == 'b') ? INODE_MODE_FBLK : INODE_MODE_FCHR))) {
fprintf (stderr, "%s: device inode create failed\n", name);
return;
}
dev.addr[1] = majr << 8 | minr;
time (&dev.mtime);
fs_inode_save (&dev, 1);
}
/*
@@ -368,54 +368,54 @@ void add_device (fs_t *fs, char *name, char *spec)
*/
void add_file (fs_t *fs, char *name)
{
fs_file_t file;
FILE *fd;
unsigned char data [BSDFS_BSIZE];
struct stat st;
char *p;
int len;
fs_file_t file;
FILE *fd;
unsigned char data [BSDFS_BSIZE];
struct stat st;
char *p;
int len;
if (verbose) {
printf ("%s\n", name);
}
p = strrchr (name, '/');
if (p && p[1] == 0) {
*p = 0;
add_directory (fs, name);
return;
}
p = strrchr (name, '!');
if (p) {
*p++ = 0;
add_device (fs, name, p);
return;
}
fd = fopen (name, "r");
if (! fd) {
perror (name);
return;
}
stat (name, &st);
if (! fs_file_create (fs, &file, name, st.st_mode)) {
fprintf (stderr, "%s: cannot create\n", name);
return;
}
for (;;) {
len = fread (data, 1, sizeof (data), fd);
/* printf ("read %d bytes from %s\n", len, name);*/
if (len < 0)
perror (name);
if (len <= 0)
break;
if (! fs_file_write (&file, data, len)) {
fprintf (stderr, "%s: write error\n", name);
break;
}
}
file.inode.mtime = st.st_mtime;
file.inode.dirty = 1;
fs_file_close (&file);
fclose (fd);
if (verbose) {
printf ("%s\n", name);
}
p = strrchr (name, '/');
if (p && p[1] == 0) {
*p = 0;
add_directory (fs, name);
return;
}
p = strrchr (name, '!');
if (p) {
*p++ = 0;
add_device (fs, name, p);
return;
}
fd = fopen (name, "r");
if (! fd) {
perror (name);
return;
}
stat (name, &st);
if (! fs_file_create (fs, &file, name, st.st_mode)) {
fprintf (stderr, "%s: cannot create\n", name);
return;
}
for (;;) {
len = fread (data, 1, sizeof (data), fd);
/* printf ("read %d bytes from %s\n", len, name);*/
if (len < 0)
perror (name);
if (len <= 0)
break;
if (! fs_file_write (&file, data, len)) {
fprintf (stderr, "%s: write error\n", name);
break;
}
}
file.inode.mtime = st.st_mtime;
file.inode.dirty = 1;
fs_file_close (&file);
fclose (fd);
}
/*
@@ -424,156 +424,157 @@ void add_file (fs_t *fs, char *name)
*/
void add_contents (fs_t *fs, const char *dirname, const char *manifest)
{
printf ("TODO: add contents from directory '%s'\n", dirname);
if (manifest)
printf ("TODO: use manifest '%s'\n", manifest);
printf ("TODO: add contents from directory '%s'\n", dirname);
if (manifest)
printf ("TODO: use manifest '%s'\n", manifest);
}
int main (int argc, char **argv)
{
int i, key;
fs_t fs;
fs_inode_t inode;
const char *manifest = 0;
int i, key;
fs_t fs;
fs_inode_t inode;
const char *manifest = 0;
for (;;) {
key = getopt_long (argc, argv, "vaxmMn:cfs:",
program_options, 0);
if (key == -1)
break;
switch (key) {
case 'v':
++verbose;
break;
case 'a':
++add;
break;
case 'x':
++extract;
break;
case 'n':
++newfs;
kbytes = strtol (optarg, 0, 0);
break;
case 'c':
++check;
break;
case 'f':
++fix;
break;
case 'm':
++mount;
break;
case 's':
swap_kbytes = strtol (optarg, 0, 0);
break;
case 'M':
manifest = optarg;
break;
case 'V':
printf ("%s\n", program_version);
return 0;
case 'h':
print_help (argv[0]);
return 0;
default:
print_help (argv[0]);
return -1;
}
}
i = optind;
if ((! add && ! mount && ! newfs && i != argc-1) ||
(add && i >= argc) ||
(newfs && i != argc-1 && i != argc-2) ||
(mount && i != argc-2) ||
(extract + newfs + check + add + mount > 1) ||
(newfs && kbytes < BSDFS_BSIZE * 10 / 1024)) {
print_help (argv[0]);
return -1;
}
for (;;) {
key = getopt_long (argc, argv, "vaxmMn:cfs:",
program_options, 0);
if (key == -1)
break;
switch (key) {
case 'v':
++verbose;
break;
case 'a':
++add;
break;
case 'x':
++extract;
break;
case 'n':
++newfs;
kbytes = strtol (optarg, 0, 0);
break;
case 'c':
++check;
break;
case 'f':
++fix;
break;
case 'm':
++mount;
break;
case 's':
swap_kbytes = strtol (optarg, 0, 0);
break;
case 'M':
manifest = optarg;
break;
case 'V':
printf ("%s\n", program_version);
return 0;
case 'h':
print_help (argv[0]);
return 0;
default:
print_help (argv[0]);
return -1;
}
}
i = optind;
if ((! add && ! mount && ! newfs && i != argc-1) ||
(add && i >= argc) ||
(newfs && i != argc-1 && i != argc-2) ||
(mount && i != argc-2) ||
(extract + newfs + check + add + mount > 1) ||
(newfs && kbytes < BSDFS_BSIZE * 10 / 1024))
{
print_help (argv[0]);
return -1;
}
if (newfs) {
/* Create new filesystem. */
if (! fs_create (&fs, argv[i], kbytes, swap_kbytes)) {
fprintf (stderr, "%s: cannot create filesystem\n", argv[i]);
return -1;
}
printf ("Created filesystem %s - %u kbytes\n", argv[i], kbytes);
if (newfs) {
/* Create new filesystem. */
if (! fs_create (&fs, argv[i], kbytes, swap_kbytes)) {
fprintf (stderr, "%s: cannot create filesystem\n", argv[i]);
return -1;
}
printf ("Created filesystem %s - %u kbytes\n", argv[i], kbytes);
if (i == argc-2) {
/* Add the contents from the specified directory.
* Use the optional manifest file. */
add_contents (&fs, argv[i+1], manifest);
}
fs_close (&fs);
return 0;
}
if (i == argc-2) {
/* Add the contents from the specified directory.
* Use the optional manifest file. */
add_contents (&fs, argv[i+1], manifest);
}
fs_close (&fs);
return 0;
}
if (check) {
/* Check filesystem for errors, and optionally fix them. */
if (! fs_open (&fs, argv[i], fix)) {
fprintf (stderr, "%s: cannot open\n", argv[i]);
return -1;
}
fs_check (&fs);
fs_close (&fs);
return 0;
}
if (check) {
/* Check filesystem for errors, and optionally fix them. */
if (! fs_open (&fs, argv[i], fix)) {
fprintf (stderr, "%s: cannot open\n", argv[i]);
return -1;
}
fs_check (&fs);
fs_close (&fs);
return 0;
}
/* Add or extract or info. */
if (! fs_open (&fs, argv[i], (add + mount != 0))) {
fprintf (stderr, "%s: cannot open\n", argv[i]);
return -1;
}
/* Add or extract or info. */
if (! fs_open (&fs, argv[i], (add + mount != 0))) {
fprintf (stderr, "%s: cannot open\n", argv[i]);
return -1;
}
if (extract) {
/* Extract all files to current directory. */
if (! fs_inode_get (&fs, &inode, BSDFS_ROOT_INODE)) {
fprintf (stderr, "%s: cannot get inode 1\n", argv[i]);
return -1;
}
fs_directory_scan (&inode, "", extractor, (void*) stdout);
fs_close (&fs);
return 0;
}
if (extract) {
/* Extract all files to current directory. */
if (! fs_inode_get (&fs, &inode, BSDFS_ROOT_INODE)) {
fprintf (stderr, "%s: cannot get inode 1\n", argv[i]);
return -1;
}
fs_directory_scan (&inode, "", extractor, (void*) stdout);
fs_close (&fs);
return 0;
}
if (add) {
/* Add files i+1..argc-1 to filesystem. */
while (++i < argc)
add_file (&fs, argv[i]);
fs_sync (&fs, 0);
fs_close (&fs);
return 0;
}
if (add) {
/* Add files i+1..argc-1 to filesystem. */
while (++i < argc)
add_file (&fs, argv[i]);
fs_sync (&fs, 0);
fs_close (&fs);
return 0;
}
if (mount) {
/* Mount the filesystem. */
if (++i >= argc) {
print_help (argv[0]);
return -1;
}
return fs_mount(&fs, argv[i]);
}
if (mount) {
/* Mount the filesystem. */
if (++i >= argc) {
print_help (argv[0]);
return -1;
}
return fs_mount(&fs, argv[i]);
}
/* Print the structure of flesystem. */
fs_print (&fs, stdout);
if (verbose) {
printf ("--------\n");
if (! fs_inode_get (&fs, &inode, BSDFS_ROOT_INODE)) {
fprintf (stderr, "%s: cannot get inode 1\n", argv[i]);
return -1;
}
printf ("/\n");
if (verbose > 1) {
/* Print a list of blocks. */
print_inode_blocks (&inode, stdout);
if (verbose > 2) {
fs_inode_print (&inode, stdout);
printf ("--------\n");
}
}
fs_directory_scan (&inode, "", scanner, (void*) stdout);
}
fs_close (&fs);
return 0;
/* Print the structure of flesystem. */
fs_print (&fs, stdout);
if (verbose) {
printf ("--------\n");
if (! fs_inode_get (&fs, &inode, BSDFS_ROOT_INODE)) {
fprintf (stderr, "%s: cannot get inode 1\n", argv[i]);
return -1;
}
printf ("/\n");
if (verbose > 1) {
/* Print a list of blocks. */
print_inode_blocks (&inode, stdout);
if (verbose > 2) {
fs_inode_print (&inode, stdout);
printf ("--------\n");
}
}
fs_directory_scan (&inode, "", scanner, (void*) stdout);
}
fs_close (&fs);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -32,298 +32,300 @@ extern int verbose;
int fs_seek (fs_t *fs, unsigned long offset)
{
/* printf ("seek %ld, block %ld\n", offset, offset / BSDFS_BSIZE);*/
if (lseek (fs->fd, offset, 0) < 0) {
if (verbose)
printf ("error seeking %ld, block %ld\n",
offset, offset / BSDFS_BSIZE);
return 0;
}
fs->seek = offset;
return 1;
/* printf ("seek %ld, block %ld\n", offset, offset / BSDFS_BSIZE);*/
if (lseek (fs->fd, offset, 0) < 0) {
if (verbose)
printf ("error seeking %ld, block %ld\n",
offset, offset / BSDFS_BSIZE);
return 0;
}
fs->seek = offset;
return 1;
}
int fs_read8 (fs_t *fs, unsigned char *val)
{
if (read (fs->fd, val, 1) != 1) {
if (verbose)
printf ("error read8, seek %ld block %ld\n", fs->seek, fs->seek / BSDFS_BSIZE);
return 0;
}
return 1;
if (read (fs->fd, val, 1) != 1) {
if (verbose)
printf ("error read8, seek %ld block %ld\n", fs->seek, fs->seek / BSDFS_BSIZE);
return 0;
}
return 1;
}
int fs_read16 (fs_t *fs, unsigned short *val)
{
unsigned char data [2];
unsigned char data [2];
if (read (fs->fd, data, 2) != 2) {
if (verbose)
printf ("error read16, seek %ld block %ld\n", fs->seek, fs->seek / BSDFS_BSIZE);
return 0;
}
*val = data[1] << 8 | data[0];
return 1;
if (read (fs->fd, data, 2) != 2) {
if (verbose)
printf ("error read16, seek %ld block %ld\n", fs->seek, fs->seek / BSDFS_BSIZE);
return 0;
}
*val = data[1] << 8 | data[0];
return 1;
}
int fs_read32 (fs_t *fs, unsigned *val)
{
unsigned char data [4];
unsigned char data [4];
if (read (fs->fd, data, 4) != 4) {
if (verbose)
printf ("error read32, seek %ld block %ld\n", fs->seek, fs->seek / BSDFS_BSIZE);
return 0;
}
*val = (unsigned long) data[0] | (unsigned long) data[1] << 8 |
data[2] << 16 | data[3] << 24;
return 1;
if (read (fs->fd, data, 4) != 4) {
if (verbose)
printf ("error read32, seek %ld block %ld\n", fs->seek, fs->seek / BSDFS_BSIZE);
return 0;
}
*val = (unsigned long) data[0] | (unsigned long) data[1] << 8 |
data[2] << 16 | data[3] << 24;
return 1;
}
int fs_write8 (fs_t *fs, unsigned char val)
{
if (write (fs->fd, &val, 1) != 1)
return 0;
return 1;
if (write (fs->fd, &val, 1) != 1)
return 0;
return 1;
}
int fs_write16 (fs_t *fs, unsigned short val)
{
unsigned char data [2];
unsigned char data [2];
data[0] = val;
data[1] = val >> 8;
if (write (fs->fd, data, 2) != 2)
return 0;
return 1;
data[0] = val;
data[1] = val >> 8;
if (write (fs->fd, data, 2) != 2)
return 0;
return 1;
}
int fs_write32 (fs_t *fs, unsigned val)
{
unsigned char data [4];
unsigned char data [4];
data[0] = val;
data[1] = val >> 8;
data[2] = val >> 16;
data[3] = val >> 24;
if (write (fs->fd, data, 4) != 4)
return 0;
return 1;
data[0] = val;
data[1] = val >> 8;
data[2] = val >> 16;
data[3] = val >> 24;
if (write (fs->fd, data, 4) != 4)
return 0;
return 1;
}
int fs_read (fs_t *fs, unsigned char *data, int bytes)
{
int len;
int len;
while (bytes > 0) {
len = bytes;
if (len > 16*BSDFS_BSIZE)
len = 16*BSDFS_BSIZE;
if (read (fs->fd, data, len) != len)
return 0;
data += len;
bytes -= len;
}
return 1;
while (bytes > 0) {
len = bytes;
if (len > 16*BSDFS_BSIZE)
len = 16*BSDFS_BSIZE;
if (read (fs->fd, data, len) != len)
return 0;
data += len;
bytes -= len;
}
return 1;
}
int fs_write (fs_t *fs, unsigned char *data, int bytes)
{
int len;
int len;
if (! fs->writable)
return 0;
while (bytes > 0) {
len = bytes;
if (len > 16*BSDFS_BSIZE)
len = 16*BSDFS_BSIZE;
if (write (fs->fd, data, len) != len)
return 0;
data += len;
bytes -= len;
}
return 1;
if (! fs->writable)
return 0;
while (bytes > 0) {
len = bytes;
if (len > 16*BSDFS_BSIZE)
len = 16*BSDFS_BSIZE;
if (write (fs->fd, data, len) != len)
return 0;
data += len;
bytes -= len;
}
return 1;
}
int fs_open (fs_t *fs, const char *filename, int writable)
{
int i;
unsigned magic;
int i;
unsigned magic;
memset (fs, 0, sizeof (*fs));
fs->filename = filename;
fs->seek = 0;
memset (fs, 0, sizeof (*fs));
fs->filename = filename;
fs->seek = 0;
fs->fd = open (fs->filename, writable ? O_RDWR : O_RDONLY);
if (fs->fd < 0)
return 0;
fs->writable = writable;
fs->fd = open (fs->filename, writable ? O_RDWR : O_RDONLY);
if (fs->fd < 0)
return 0;
fs->writable = writable;
if (! fs_read32 (fs, &magic) || /* magic word */
magic != FSMAGIC1) {
if (verbose)
printf ("fs_open: bad magic1 = %08x, expected %08x\n",
magic, FSMAGIC1);
return 0;
}
if (! fs_read32 (fs, &fs->isize)) /* size in blocks of I list */
return 0;
if (! fs_read32 (fs, &fs->fsize)) /* size in blocks of entire volume */
return 0;
if (! fs_read32 (fs, &fs->swapsz)) /* size in blocks of swap area */
return 0;
if (! fs_read32 (fs, &fs->nfree)) /* number of in core free blocks */
return 0;
for (i=0; i<NICFREE; ++i) { /* in core free blocks */
if (! fs_read32 (fs, &fs->free[i]))
return 0;
}
if (! fs_read32 (fs, &fs->ninode)) /* number of in core I nodes */
return 0;
for (i=0; i<NICINOD; ++i) { /* in core free I nodes */
if (! fs_read32 (fs, &fs->inode[i]))
return 0;
}
if (! fs_read32 (fs, &fs->flock))
return 0;
if (! fs_read32 (fs, &fs->fmod))
return 0;
if (! fs_read32 (fs, &fs->ilock))
return 0;
if (! fs_read32 (fs, &fs->ronly))
return 0;
if (! fs_read32 (fs, (unsigned*) &fs->utime))
return 0; /* current date of last update */
if (! fs_read32 (fs, &fs->tfree)) /* total free blocks */
return 0;
if (! fs_read32 (fs, &fs->tinode)) /* total free inodes */
return 0;
if (! fs_read (fs, (unsigned char*) fs->fsmnt, MAXMNTLEN))
return 0; /* ordinary file mounted on */
if (! fs_read32 (fs, &fs->lasti)) /* start place for circular search */
return 0;
if (! fs_read32 (fs, &fs->nbehind)) /* est # free inodes before s_lasti */
return 0;
if (! fs_read32 (fs, &fs->flags)) /* mount time flags */
return 0;
if (! fs_read32 (fs, &magic) || /* magic word */
magic != FSMAGIC2) {
if (verbose)
printf ("fs_open: bad magic2 = %08x, expected %08x\n",
magic, FSMAGIC2);
return 0;
}
return 1;
if (! fs_read32 (fs, &magic) || /* magic word */
magic != FSMAGIC1) {
if (verbose)
printf ("fs_open: bad magic1 = %08x, expected %08x\n",
magic, FSMAGIC1);
return 0;
}
if (! fs_read32 (fs, &fs->isize)) /* size in blocks of I list */
return 0;
if (! fs_read32 (fs, &fs->fsize)) /* size in blocks of entire volume */
return 0;
if (! fs_read32 (fs, &fs->swapsz)) /* size in blocks of swap area */
return 0;
if (! fs_read32 (fs, &fs->nfree)) /* number of in core free blocks */
return 0;
for (i=0; i<NICFREE; ++i) { /* in core free blocks */
if (! fs_read32 (fs, &fs->free[i]))
return 0;
}
if (! fs_read32 (fs, &fs->ninode)) /* number of in core I nodes */
return 0;
for (i=0; i<NICINOD; ++i) { /* in core free I nodes */
if (! fs_read32 (fs, &fs->inode[i]))
return 0;
}
if (! fs_read32 (fs, &fs->flock))
return 0;
if (! fs_read32 (fs, &fs->fmod))
return 0;
if (! fs_read32 (fs, &fs->ilock))
return 0;
if (! fs_read32 (fs, &fs->ronly))
return 0;
if (! fs_read32 (fs, (unsigned*) &fs->utime))
return 0; /* current date of last update */
if (! fs_read32 (fs, &fs->tfree)) /* total free blocks */
return 0;
if (! fs_read32 (fs, &fs->tinode)) /* total free inodes */
return 0;
if (! fs_read (fs, (unsigned char*) fs->fsmnt, MAXMNTLEN))
return 0; /* ordinary file mounted on */
if (! fs_read32 (fs, &fs->lasti)) /* start place for circular search */
return 0;
if (! fs_read32 (fs, &fs->nbehind)) /* est # free inodes before s_lasti */
return 0;
if (! fs_read32 (fs, &fs->flags)) /* mount time flags */
return 0;
if (! fs_read32 (fs, &magic) || /* magic word */
magic != FSMAGIC2) {
if (verbose)
printf ("fs_open: bad magic2 = %08x, expected %08x\n",
magic, FSMAGIC2);
return 0;
}
return 1;
}
int fs_sync (fs_t *fs, int force)
{
int i;
int i;
if (! fs->writable)
return 0;
if (! force && ! fs->dirty)
return 1;
if (! fs->writable)
return 0;
if (! force && ! fs->dirty)
return 1;
time (&fs->utime);
if (! fs_seek (fs, 0))
return 0;
time (&fs->utime);
if (! fs_seek (fs, 0))
return 0;
if (! fs_write32 (fs, FSMAGIC1)) /* magic word */
return 0;
if (! fs_write32 (fs, fs->isize)) /* size in blocks of I list */
return 0;
if (! fs_write32 (fs, fs->fsize)) /* size in blocks of entire volume */
return 0;
if (! fs_write32 (fs, fs->swapsz)) /* size in blocks of swap area */
return 0;
if (! fs_write32 (fs, fs->nfree)) /* number of in core free blocks */
return 0;
for (i=0; i<NICFREE; ++i) { /* in core free blocks */
if (! fs_write32 (fs, fs->free[i]))
return 0;
}
if (! fs_write32 (fs, fs->ninode)) /* number of in core I nodes */
return 0;
for (i=0; i<NICINOD; ++i) { /* in core free I nodes */
if (! fs_write32 (fs, fs->inode[i]))
return 0;
}
if (! fs_write32 (fs, fs->flock))
return 0;
if (! fs_write32 (fs, fs->fmod))
return 0;
if (! fs_write32 (fs, fs->ilock))
return 0;
if (! fs_write32 (fs, fs->ronly))
return 0;
if (! fs_write32 (fs, fs->utime)) /* current date of last update */
return 0;
if (! fs_write32 (fs, fs->tfree)) /* total free blocks */
return 0;
if (! fs_write32 (fs, fs->tinode)) /* total free inodes */
return 0;
if (! fs_write (fs, (unsigned char*) fs->fsmnt, MAXMNTLEN))
return 0; /* ordinary file mounted on */
if (! fs_write32 (fs, 0)) /* lasti*/
return 0;
if (! fs_write32 (fs, 0)) /* nbehind */
return 0;
if (! fs_write32 (fs, 0)) /* flags */
return 0;
if (! fs_write32 (fs, FSMAGIC2)) /* magic word */
return 0;
fs->dirty = 0;
return 1;
if (! fs_write32 (fs, FSMAGIC1)) /* magic word */
return 0;
if (! fs_write32 (fs, fs->isize)) /* size in blocks of I list */
return 0;
if (! fs_write32 (fs, fs->fsize)) /* size in blocks of entire volume */
return 0;
if (! fs_write32 (fs, fs->swapsz)) /* size in blocks of swap area */
return 0;
if (! fs_write32 (fs, fs->nfree)) /* number of in core free blocks */
return 0;
for (i=0; i<NICFREE; ++i) { /* in core free blocks */
if (! fs_write32 (fs, fs->free[i]))
return 0;
}
if (! fs_write32 (fs, fs->ninode)) /* number of in core I nodes */
return 0;
for (i=0; i<NICINOD; ++i) { /* in core free I nodes */
if (! fs_write32 (fs, fs->inode[i]))
return 0;
}
if (! fs_write32 (fs, fs->flock))
return 0;
if (! fs_write32 (fs, fs->fmod))
return 0;
if (! fs_write32 (fs, fs->ilock))
return 0;
if (! fs_write32 (fs, fs->ronly))
return 0;
if (! fs_write32 (fs, fs->utime)) /* current date of last update */
return 0;
if (! fs_write32 (fs, fs->tfree)) /* total free blocks */
return 0;
if (! fs_write32 (fs, fs->tinode)) /* total free inodes */
return 0;
if (! fs_write (fs, (unsigned char*) fs->fsmnt, MAXMNTLEN))
return 0; /* ordinary file mounted on */
if (! fs_write32 (fs, 0)) /* lasti*/
return 0;
if (! fs_write32 (fs, 0)) /* nbehind */
return 0;
if (! fs_write32 (fs, 0)) /* flags */
return 0;
if (! fs_write32 (fs, FSMAGIC2)) /* magic word */
return 0;
fs->dirty = 0;
return 1;
}
void fs_print (fs_t *fs, FILE *out)
{
int i;
int i;
fprintf (out, " File: %s\n", fs->filename);
fprintf (out, " Volume size: %u blocks\n", fs->fsize);
fprintf (out, " Inode list size: %u blocks\n", fs->isize);
fprintf (out, " Swap size: %u blocks\n", fs->swapsz);
fprintf (out, " Total free blocks: %u blocks\n", fs->tfree);
fprintf (out, " Total free inodes: %u inodes\n", fs->tinode);
fprintf (out, " Last mounted on: %.*s\n", MAXMNTLEN,
fs->fsmnt[0] ? fs->fsmnt : "(none)");
fprintf (out, " In-core free list: %u blocks", fs->nfree);
if (verbose)
for (i=0; i < NICFREE && i < fs->nfree; ++i) {
if (i % 10 == 0)
fprintf (out, "\n ");
fprintf (out, " %u", fs->free[i]);
}
fprintf (out, "\n");
fprintf (out, " File: %s\n", fs->filename);
fprintf (out, " Volume size: %u blocks\n", fs->fsize);
fprintf (out, " Inode list size: %u blocks\n", fs->isize);
fprintf (out, " Swap size: %u blocks\n", fs->swapsz);
fprintf (out, " Total free blocks: %u blocks\n", fs->tfree);
fprintf (out, " Total free inodes: %u inodes\n", fs->tinode);
fprintf (out, " Last mounted on: %.*s\n", MAXMNTLEN,
fs->fsmnt[0] ? fs->fsmnt : "(none)");
fprintf (out, " In-core free list: %u blocks", fs->nfree);
if (verbose) {
for (i=0; i < NICFREE && i < fs->nfree; ++i) {
if (i % 10 == 0)
fprintf (out, "\n ");
fprintf (out, " %u", fs->free[i]);
}
}
fprintf (out, "\n");
fprintf (out, " In-core free inodes: %u inodes", fs->ninode);
if (verbose)
for (i=0; i < NICINOD && i < fs->ninode; ++i) {
if (i % 10 == 0)
fprintf (out, "\n ");
fprintf (out, " %u", fs->inode[i]);
}
fprintf (out, "\n");
if (verbose) {
// fprintf (out, " Free list lock: %u\n", fs->flock);
// fprintf (out, " Inode list lock: %u\n", fs->ilock);
// fprintf (out, "Super block modified: %u\n", fs->fmod);
// fprintf (out, " Mounted read-only: %u\n", fs->ronly);
// fprintf (out, " Circ.search start: %u\n", fs->lasti);
// fprintf (out, " Circ.search behind: %u\n", fs->nbehind);
// fprintf (out, " Mount flags: 0x%x\n", fs->flags);
}
fprintf (out, " In-core free inodes: %u inodes", fs->ninode);
if (verbose) {
for (i=0; i < NICINOD && i < fs->ninode; ++i) {
if (i % 10 == 0)
fprintf (out, "\n ");
fprintf (out, " %u", fs->inode[i]);
}
}
fprintf (out, "\n");
if (verbose) {
// fprintf (out, " Free list lock: %u\n", fs->flock);
// fprintf (out, " Inode list lock: %u\n", fs->ilock);
// fprintf (out, "Super block modified: %u\n", fs->fmod);
// fprintf (out, " Mounted read-only: %u\n", fs->ronly);
// fprintf (out, " Circ.search start: %u\n", fs->lasti);
// fprintf (out, " Circ.search behind: %u\n", fs->nbehind);
// fprintf (out, " Mount flags: 0x%x\n", fs->flags);
}
fprintf (out, " Last update time: %s", ctime (&fs->utime));
fprintf (out, " Last update time: %s", ctime (&fs->utime));
}
void fs_close (fs_t *fs)
{
if (fs->fd < 0)
return;
if (fs->fd < 0)
return;
close (fs->fd);
fs->fd = -1;
close (fs->fd);
fs->fd = -1;
}