Added fusefile-olydump
authorRalph Ronnquist <ralph.ronnquist@gmail.com>
Wed, 14 Jun 2023 08:34:14 +0000 (18:34 +1000)
committerRalph Ronnquist <ralph.ronnquist@gmail.com>
Wed, 14 Jun 2023 08:34:14 +0000 (18:34 +1000)
Makefile
fusefile-olydump.c [new file with mode: 0644]

index b0ca2be22a702f5811cdf0db7c5dcc8d3e199b7e..a96aeace7b458cc62cff1f0239d12e7229e12af5 100644 (file)
--- 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 (file)
index 0000000..950771f
--- /dev/null
@@ -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
+    <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+/**
+ * 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 );
+}