From 0dbecf1d5e1f4da1289654b8d11246aca6d005b6 Mon Sep 17 00:00:00 2001 From: Ralph Ronnquist Date: Wed, 14 Jun 2023 18:34:14 +1000 Subject: [PATCH] Added fusefile-olydump --- Makefile | 12 ++-- fusefile-olydump.c | 142 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+), 4 deletions(-) create mode 100644 fusefile-olydump.c diff --git a/Makefile b/Makefile index b0ca2be..a96aeac 100644 --- a/Makefile +++ b/Makefile @@ -1,20 +1,24 @@ -BINS = fusefile +BINS = fusefile fusefile-olydump default: $(BINS) ifneq (${DEBUG},) -fusefile: CFLAGS += -DDEBUG=1 -g +${BINS}: CFLAGS += -DDEBUG=1 -g endif -fusefile: CFLAGS += -Wall -D_FILE_OFFSET_BITS=64 +${BINS}: CFLAGS += -Wall -D_FILE_OFFSET_BITS=64 fusefile: LDFLAGS = -lfuse -pthread -.INTERMEDIATE: fusefile.o +.INTERMEDIATE: fusefile.o fusefile-olydump.o fusefile.o: fusefile.c +fusefile-olydump.o: fusefile-olydump.c fusefile: fusefile.o $(CC) $(CFLAGS) $(CPPFLAGS) $? $(LDFLAGS) $(TARGET_ARCH) -o $@ +fusefile-olydump: fusefile-olydump.o + $(CC) $(CFLAGS) $(CPPFLAGS) $? $(LDFLAGS) $(TARGET_ARCH) -o $@ + clean: rm -f $(BINS) diff --git a/fusefile-olydump.c b/fusefile-olydump.c new file mode 100644 index 0000000..950771f --- /dev/null +++ b/fusefile-olydump.c @@ -0,0 +1,142 @@ +/*** + fusefile-merge - merge a fusefile overlay into its underling + + Copyright (C) 2023- Ralph Ronnquist + + This program is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see + . +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * An overlay file consists of a data block followed by a count of + * struct Region elements plus that many elements. + */ +struct Region { + off_t beg; + off_t end; +}; + +/** + * Table head + */ +struct Table { + size_t count; + struct Region regions[]; +}; + +struct FileInfo { + char *name; + size_t size; +}; + +struct FileInfo basefile, olyfile; + +/** + * + */ +static struct Table *loadtable() { + if ( basefile.size >= olyfile.size ) { +#if DEBUG + fprintf( stderr, "basefile.size >= olyfile.size\n" ); +#endif + return 0; + } + size_t tbl = ( olyfile.size - basefile.size ); + if ( ( tbl % sizeof( off_t ) ) != 0 ) { +#if DEBUG + fprintf( stderr, "( tbl %% sizeof( off_t ) ) != 0\n" ); +#endif + return 0; + } + size_t count = tbl / sizeof( off_t ); + if ( ( count & 1 ) == 0 ) { // Needs an odd number of off_t values +#if DEBUG + fprintf( stderr, "( count & 1 ) == 0\n" ); +#endif + return 0; + } + count = ( count - 1 ) / 2; + int fd = open( olyfile.name, O_RDONLY ); + if ( fd < 0 ) { + perror( olyfile.name ); + return 0; + } + struct Table *ptr = + mmap( 0, tbl, PROT_READ, MAP_PRIVATE, fd, basefile.size ); + return ( ptr->count != count )? 0 : ptr; +} + +static void usage() { + fprintf( stderr, "Usage: basefile overlayfile\n" ); + exit( 1 ); +} + +/** + * Application entry. This program dumps the overlay table as a + * fusefile fragments sequence, with newline? + */ +int main(int argc,char **argv) { + static struct stat info; + + if ( argc != 3 ) { + usage(); + } + basefile.name = argv[1]; + if ( stat( basefile.name, &info ) ) { + perror( basefile.name ); + exit( 1 ); + } + basefile.size = info.st_size; + + olyfile.name = argv[2]; + if ( stat( olyfile.name, &info ) ) { + perror( olyfile.name ); + exit( 1 ); + } + olyfile.size = info.st_size; + + struct Table *table = loadtable(); + if ( table == 0 ) { + fprintf( stderr, "%s is not onverlay for %s\n", + olyfile.name, basefile.name ); + fprintf( stderr, " %s: %ld\n", basefile.name, basefile.size ); + fprintf( stderr, " %s: %ld\n", olyfile.name, olyfile.size ); + exit( 1 ); + } + int i; + size_t pos = 0; + for ( i = 0; i < table->count; i++ ) { + struct Region *r = &(table->regions[i]); + if ( pos < r->beg ) { + fprintf( stdout, "%s/%ld:%ld\n", basefile.name, pos, r->beg ); + } + fprintf( stdout, "%s/%ld:%ld\n", olyfile.name, r->beg, r->end ); + pos = r->end; + } + if ( pos < basefile.size ) { + fprintf( stdout, "%s/%ld:%ld\n", basefile.name, pos, basefile.size ); + } + return( 0 ); +} -- 2.39.2