Fsutil: sources reformatted to 4-space indents.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user