feat(libfs): parse disk offset

This commit is contained in:
d0p1 🏳️‍⚧️ 2024-09-16 14:54:31 +02:00
parent 560a5000da
commit 31976c4c9f
8 changed files with 138 additions and 3 deletions

View file

@ -32,6 +32,8 @@ AC_CHECK_INCLUDES_DEFAULT
AC_C_CONST AC_C_CONST
AC_C_INLINE AC_C_INLINE
AC_CHECK_FUNCS_ONCE(strtoull)
AC_CHECK_HEADERS(m4_normalize([ AC_CHECK_HEADERS(m4_normalize([
libgen.h libgen.h
getopt.h getopt.h
@ -52,6 +54,7 @@ AC_CONFIG_FILES([Makefile
liblzp/Makefile liblzp/Makefile
liblzp/tests/Makefile liblzp/tests/Makefile
libfs/Makefile libfs/Makefile
libfs/tests/Makefile
tools/Makefile tools/Makefile
linux/Makefile linux/Makefile
fuse/Makefile]) fuse/Makefile])

View file

@ -1,3 +1,5 @@
SUBDIRS = tests
AM_CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir) AM_CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)
noinst_LIBRARIES = libfs.a noinst_LIBRARIES = libfs.a
libfs_a_SOURCES = bio/raw.c bio/bio.c balloc.c dir.c inode.c rw.c super.c libfs_a_SOURCES = bio/raw.c bio/bio.c balloc.c dir.c inode.c rw.c super.c offset.c

60
libfs/offset.c Normal file
View file

@ -0,0 +1,60 @@
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include <stdio.h>
/*
* S = sectors (512)
* K = kilobytes
* M = Megabytes
* G = Gigabytes
* T = Terabytes
*/
static const struct {
char unit;
uint64_t mult;
} units[] = {
{'S', 512},
{'K', 1000},
{'M', 1000000},
{'G', 1000000000},
{'T', 1000000000000},
{0, 0}
};
uint64_t fs_str2offset(const char *str)
{
char u;
uint64_t mult;
uint64_t off;
int idx;
if (str == NULL)
{
return (0);
}
/* default to sectors */
mult = units[0].mult;
u = str[strlen(str) - 1];
for (idx = 0; units[idx].unit != 0; idx++)
{
if (u == units[idx].unit)
{
mult = units[idx].mult;
break;
}
}
#ifdef HAVE_STRTOULL
off = strtoull(str, NULL, 0);
#else
off = strtoul(str, NULL, 0);
#endif /* HAVE_STRTOULL */
return (off * mult);
}

View file

@ -1,11 +1,14 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <time.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <stupidfs.h> #include <stupidfs.h>
#include "super.h" #include "super.h"
#include "bio/bio.h" #include "bio/bio.h"
uint64_t fs_str2offset(const char *str);
int int
fs_super_valide(struct stpdfs_sb *sb) fs_super_valide(struct stpdfs_sb *sb)
{ {
@ -36,12 +39,20 @@ fs_super_valide(struct stpdfs_sb *sb)
return (0); return (0);
} }
/**
* \param super
* \param fname
*/
int int
fs_super_open(struct fs_super *super, const char *fname) fs_super_open(struct fs_super *super, const char *fname)
{ {
struct fs_buffer *buff; struct fs_buffer *buff;
char *ptr;
ptr = (char *)fname;
#ifdef _WIN32 #ifdef _WIN32
super->fd = open(fname, O_RDWR | O_BINARY); super->fd = open(strtok(ptr, "@@"), O_RDWR | O_BINARY);
#else #else
super->fd = open(fname, O_RDWR); super->fd = open(fname, O_RDWR);
#endif #endif
@ -51,6 +62,8 @@ fs_super_open(struct fs_super *super, const char *fname)
return (-1); return (-1);
} }
super->offset = fs_str2offset(strtok(NULL, "@@"));
buff = fs_bio_bread(super->fd, STPDFS_SB_BLOCK); buff = fs_bio_bread(super->fd, STPDFS_SB_BLOCK);
if (!buff) goto err; if (!buff) goto err;

View file

@ -6,6 +6,7 @@
struct fs_super { struct fs_super {
int fd; int fd;
uint64_t offset;
struct stpdfs_sb sb; struct stpdfs_sb sb;
}; };

7
libfs/tests/Makefile.am Normal file
View file

@ -0,0 +1,7 @@
TESTS = test_offset
check_PROGRAMS = test_offset
AM_CFLAGS = -I../
LDADD = -lcmocka ../libfs.a
test_offset_SOURCES = test_offset.c

43
libfs/tests/test_offset.c Normal file
View file

@ -0,0 +1,43 @@
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <setjmp.h>
#include <cmocka.h>
int64_t fs_str2offset(const char *str);
static void
test_default(void **state)
{
assert_int_equal(0, fs_str2offset(NULL));
assert_int_equal(512, fs_str2offset("1"));
}
static void
test_valid_units(void **state)
{
assert_int_equal(1024, fs_str2offset("2S"));
assert_int_equal(2000, fs_str2offset("2K"));
assert_int_equal(4000000, fs_str2offset("4M"));
assert_int_equal(8000000000, fs_str2offset("8G"));
assert_int_equal(3000000000000, fs_str2offset("3T"));
}
static void
test_invalid_units(void **state)
{
assert_int_equal(2048, fs_str2offset("4D"));
assert_int_equal(5120, fs_str2offset("10H"));
}
int
main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_default),
cmocka_unit_test(test_valid_units),
cmocka_unit_test(test_invalid_units),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}

View file

@ -161,7 +161,13 @@ usage(int retval)
} }
else else
{ {
printf("Usage %s: [options] /dev/name\n\n", prg_name); printf("Usage %s: [OPTIONS]... /dev/name\n\n", prg_name);
printf("Options:\n");
printf(" -i, --inode <inum> inspect inode\n.");
printf(" -b, --block <bnum> inspect block\n");
printf(" -s, --super inspect superblock\n");
printf(" -h, --help display this menu\n");
printf(" -V, --version display version information\n");
} }
exit(retval); exit(retval);