208 lines
3.7 KiB
C
208 lines
3.7 KiB
C
#include "libfs/bio/bio.h"
|
|
#include "libfs/inode.h"
|
|
#include "libfs/super.h"
|
|
#include "stupidfs.h"
|
|
#include <ctype.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
#ifdef HAVE_CONFIG_H
|
|
# include "config.h"
|
|
#endif /* HAVE_CONFIG_H */
|
|
#ifdef HAVE_LIBGEN_H
|
|
# include <libgen.h>
|
|
#endif /* HAVE_LIBGEN_H */
|
|
#ifdef HAVE_GETOPT_H
|
|
# include <getopt.h>
|
|
#endif /* HAVE_GETOPT_H */
|
|
#include <libfs/fs.h>
|
|
|
|
static const char *prg_name;
|
|
static const char *device;
|
|
static int inode = -1;
|
|
static int block = -1;
|
|
static int super = 0;
|
|
|
|
#ifdef HAVE_STRUCT_OPTION
|
|
static struct option long_options[] = {
|
|
{"help", no_argument, 0, 'h'},
|
|
{"version", no_argument, 0, 'V'},
|
|
{"inode", required_argument, 0, 'i'},
|
|
{"block", required_argument, 0, 'b'},
|
|
{"super", no_argument, 0, 's'},
|
|
{0, 0, 0, 0}
|
|
};
|
|
#endif /* HAVE_STRUCT_OPTION */
|
|
|
|
static int
|
|
inspect(void)
|
|
{
|
|
struct fs_super sb;
|
|
struct fs_inode *ip;
|
|
struct fs_buffer *buff;
|
|
time_t time;
|
|
int idx;
|
|
int j;
|
|
char c;
|
|
|
|
if (fs_super_open(&sb, device) != 0)
|
|
{
|
|
fprintf(stderr, "Bad super\n");
|
|
return (EXIT_FAILURE);
|
|
}
|
|
|
|
if (super)
|
|
{
|
|
printf("Super:\n");
|
|
printf(" magic: %x\n", sb.sb.magic);
|
|
printf(" isize: %u\n", sb.sb.isize);
|
|
printf(" fsize: %u\n", sb.sb.fsize);
|
|
printf(" freelist:\n");
|
|
for (idx = 0; idx < sb.sb.freelist.nfree; idx++)
|
|
{
|
|
printf("\tblock[%02u]: %x\n", idx, sb.sb.freelist.free[idx]);
|
|
}
|
|
printf(" revision: %u\n", sb.sb.revision);
|
|
printf(" state: %hu\n", sb.sb.state);
|
|
time = sb.sb.time;
|
|
printf(" time: %s", ctime(&time));
|
|
}
|
|
|
|
if (inode > 0)
|
|
{
|
|
ip = fs_inode_get(&sb, inode);
|
|
if (ip->valid == 0)
|
|
{
|
|
fs_inode_read(ip);
|
|
}
|
|
|
|
printf("Inode %d:\n", inode);
|
|
printf(" mode: %ho\n", ip->inode.mode);
|
|
printf(" nlink: %hu\n", ip->inode.nlink);
|
|
printf(" uid: %hx\n", ip->inode.uid);
|
|
printf(" gid: %hx\n", ip->inode.gid);
|
|
printf(" flags: %hx\n", ip->inode.flags);
|
|
printf(" size: %u\n", ip->inode.size);
|
|
for (idx = 0; idx < 10; idx++)
|
|
{
|
|
printf(" zone[%d]: 0x%X\n", idx, ip->inode.zones[idx]);
|
|
}
|
|
time = ip->inode.actime;
|
|
printf(" actime: %s", ctime(&time));
|
|
time = ip->inode.modtime;
|
|
printf(" modtime: %s", ctime(&time));
|
|
}
|
|
|
|
if (block >= 0)
|
|
{
|
|
buff = fs_bio_bread(sb.fd, block);
|
|
if (buff != NULL)
|
|
{
|
|
idx = 0;
|
|
while (idx < STPDFS_BLOCK_SIZE)
|
|
{
|
|
printf("\033[32m%04x\033[0m\t", idx);
|
|
for (j = 0; j < 8; j++)
|
|
{
|
|
printf("%02x ", buff->data[idx+j]);
|
|
}
|
|
printf(" | ");
|
|
for (j = 0; j < 8; j++)
|
|
{
|
|
c = buff->data[idx++];
|
|
if (isgraph(c))
|
|
{
|
|
printf("\033[31m%c\033[0m", c);
|
|
}
|
|
else
|
|
{
|
|
printf(".");
|
|
}
|
|
}
|
|
printf("\n");
|
|
}
|
|
fs_bio_brelse(buff);
|
|
}
|
|
}
|
|
|
|
|
|
fs_super_kill(&sb);
|
|
return (EXIT_SUCCESS);
|
|
}
|
|
|
|
static void
|
|
usage(int retval)
|
|
{
|
|
if (retval == EXIT_FAILURE)
|
|
{
|
|
fprintf(stderr, "Try '%s -h' for more information.\n", prg_name);
|
|
}
|
|
else
|
|
{
|
|
printf("Usage %s: [options] /dev/name\n\n", prg_name);
|
|
}
|
|
|
|
exit(retval);
|
|
}
|
|
|
|
static void
|
|
version(void)
|
|
{
|
|
printf("%s (%s) %s\n", prg_name, PACKAGE_NAME, PACKAGE_VERSION);
|
|
exit(EXIT_SUCCESS);
|
|
}
|
|
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
int idx;
|
|
int c;
|
|
|
|
#ifdef HAVE_LIBGEN_H
|
|
prg_name = basename(argv[0]);
|
|
#else
|
|
prg_name = argv[0];
|
|
#endif /* HAVE_LIBGEN_H */
|
|
|
|
#if defined(HAVE_GETOPT_LONG) && defined(HAVE_STRUCT_OPTION)
|
|
while ((c = getopt_long(argc, argv, "hVi:b:s", long_options, &idx)) != EOF)
|
|
#else
|
|
while ((c = getopt(argc, argv, "hVi:b:s")) != EOF)
|
|
#endif /* HAVE_GETOPT_LONG && HAVE_STRUCT_OPTION */
|
|
{
|
|
switch (c)
|
|
{
|
|
case 'h':
|
|
usage(EXIT_SUCCESS);
|
|
break;
|
|
|
|
case 'V':
|
|
version();
|
|
break;
|
|
|
|
case 'i':
|
|
inode = atoi(optarg);
|
|
break;
|
|
|
|
case 'b':
|
|
block = atoi(optarg);
|
|
break;
|
|
|
|
case 's':
|
|
super = 1;
|
|
break;
|
|
|
|
default:
|
|
usage(EXIT_FAILURE);
|
|
}
|
|
}
|
|
|
|
if (optind >= argc)
|
|
{
|
|
usage(EXIT_FAILURE);
|
|
}
|
|
|
|
device = argv[optind];
|
|
|
|
return (inspect());
|
|
}
|