From: Ralph Ronnquist Date: Tue, 25 Oct 2022 11:47:39 +0000 (+1100) Subject: fixes b to please lintian X-Git-Url: https://git.rrq.selfhost.au/?a=commitdiff_plain;h=27199528d936b8b420f3d2d90dc20745f114d1e7;p=rrq%2Fpathmap.git fixes b to please lintian --- diff --git a/Makefile b/Makefile index 5e75dfd..aaa5174 100644 --- a/Makefile +++ b/Makefile @@ -3,8 +3,8 @@ SBINDIR = $(DESTDIR)/usr/sbin MAN8DIR = $(DESTDIR)/usr/share/man/man8 SBINFILES = tarmap -LIBFILES = libtarmap.so libpathmap.so -MAN8FILES = $(addsuffix .8,$(LIBFILES) $(SBINFILES)) +LIBFILES = libtarmap-0.so libpathmap-0.so +MAN8FILES = libpathmap0.so.8 libtarmap0.so.8 tarmap.8 HTMLDOC = $(addsuffix .html,$(MAN8FILES)) GENFILES = $(LIBFILES) $(SBINFILES) $(MAN8FILES) @@ -20,16 +20,15 @@ default: $(GENFILES) asciidoc -bhtml $^ # Generic rule for making a dynamic library form a same named .c file -V := .0 %.so: %.c - gcc -Wall -fPIC -Wl,-init,so_init,-soname,$@$V -shared -o $@$V $^ -ldl + gcc -g -Wall -fPIC -Wl,-init,so_init,-soname,$@ -shared -o $@ $^ -ldl # Generic rule for making a binary from a same named .c file %: %.c - gcc -Wall -fPIC -o $@ $^ -ldl + gcc -g -Wall -fPIC -o $@ $^ -ldl clean: - rm -f $(GENFILES) + rm -f $(GENFILES) pool/* # Installation targets @@ -38,11 +37,7 @@ INSTALLTARGETS = $(addprefix $(LIBDIR)/,$(LIBFILES)) INSTALLTARGETS += $(addprefix $(MAN8DIR)/,$(MAN8FILES)) # Generic rule to install bmo the install command without renaming -$(LIBDIR)/%: % - install -D -T $<$V $@$V - ln -s $<$V $@ - -$(SBINDIR)/% $(MAN8DIR)/%: % +$(LIBDIR)/% $(SBINDIR)/% $(MAN8DIR)/%: % install -D -T $< $@ install: $(INSTALLTARGETS) @@ -54,4 +49,8 @@ pool: deb: pool PREFIX= INCLUDE_PREFIX=/usr XDH_OPTIONS=--destdir=pool \ dpkg-buildpackage -us -uc --build=full - mv ../pathmap_* ../libpathmap[-_]* pool + mv ../pathmap_* pool + mv ../libpathmap-0[-_]* pool + mv ../libtarmap-0[-_]* pool + mv ../tarmap[-_]* pool + lintian --profile=devuan pool/*.deb diff --git a/debian/control b/debian/control index a57ab17..fd49ea6 100644 --- a/debian/control +++ b/debian/control @@ -8,9 +8,21 @@ Build-Depends: debhelper-compat (= 12), Standards-Version: 4.3.0 Vcs-Git: repo@borta.rrq.au:ralph/pathmap.git -Package: libpathmap +Package: libpathmap-0 +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: preload libraries for path mapping + LD_PRELOAD library that overrides file replace the path prefix. + +Package: libtarmap-0 Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: preload libraries for path mapping LD_PRELOAD library that overrides file access so as to offer files from a given tar/tgz archive first. + +Package: tarmap +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libtarmap +Description: preload libraries for path mapping + Utility to run bash with a libtarmap preloaded. diff --git a/debian/files b/debian/files index 4be8d51..99eee85 100644 --- a/debian/files +++ b/debian/files @@ -1,3 +1,7 @@ -libpathmap-dbgsym_0.1_amd64.deb debug optional automatic=yes -libpathmap_0.1_amd64.deb admin optional +libpathmap-0-dbgsym_0.1_amd64.deb debug optional automatic=yes +libpathmap-0_0.1_amd64.deb admin optional +libtarmap-0-dbgsym_0.1_amd64.deb debug optional automatic=yes +libtarmap-0_0.1_amd64.deb admin optional pathmap_0.1_amd64.buildinfo admin optional +tarmap-dbgsym_0.1_amd64.deb debug optional automatic=yes +tarmap_0.1_amd64.deb admin optional diff --git a/debian/libpathmap-0.install b/debian/libpathmap-0.install new file mode 100644 index 0000000..b28dd8f --- /dev/null +++ b/debian/libpathmap-0.install @@ -0,0 +1,2 @@ +libpathmap-0.so usr/lib +libpathmap.so.8 usr/share/man/man8 diff --git a/debian/libpathmap-0.triggers b/debian/libpathmap-0.triggers new file mode 100644 index 0000000..e69de29 diff --git a/debian/libtarmap-0.install b/debian/libtarmap-0.install new file mode 100644 index 0000000..7faf019 --- /dev/null +++ b/debian/libtarmap-0.install @@ -0,0 +1,2 @@ +libtarmap-0.so usr/lib +libtarmap.so.8 usr/share/man/man8 diff --git a/debian/libtarmap-0.triggers b/debian/libtarmap-0.triggers new file mode 100644 index 0000000..e69de29 diff --git a/debian/lintian-overrides b/debian/lintian-overrides index e13b204..e69de29 100644 --- a/debian/lintian-overrides +++ b/debian/lintian-overrides @@ -1,2 +0,0 @@ -libpathmap: link-to-shared-library-in-wrong-package -libpathmap: package-name-doesnt-match-sonames diff --git a/debian/tarmap.install b/debian/tarmap.install new file mode 100644 index 0000000..b5db554 --- /dev/null +++ b/debian/tarmap.install @@ -0,0 +1,2 @@ +tarmap usr/bin +tarmap.8 usr/share/man/man8 diff --git a/libpathmap-0.c b/libpathmap-0.c new file mode 100644 index 0000000..5628030 --- /dev/null +++ b/libpathmap-0.c @@ -0,0 +1,421 @@ +/** + * PRELOAD utility that maps all rooted paths except some to have an + * additional root path prefix. This is configured with an environment + * variable PATHMAPNOT that is a colon separated list of pathname + * prefixes to *not* map with the first one being the additional root + * path prefix. The environment variable is loaded on the first call. + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include + +/************************************************************ + * Data structure for pathname mapping + * + * Pathnames are passed in to the library via the environment variable + * PATHMAPNOT as a colon separated list of pathnames that are not to + * be mapped. The first value of PATHMAPNOT is used as prefix to add + * to all paths except the ones in the list (the first inlcuded). + * + * The given pathnames are loaded into a sorted table, offering + * O[log(n)] lookup complexity, and the map prefix is also held + * separately as the 'root'. + */ + +#define PATHMAPNOT "PATHMAPNOT" + +static struct { + char **data; // Array of char* + int count; + int root_length; + char *root; +} prefix; + +// Alphabetical ordering of char* records. +static int alphorder(const void *a, const void *b) { + int x = strcmp( *(const char**)a, *(const char**)b ); + return x; +} + +// Utility function to load the prefixes. +static void load_prefixes() { + char *data = getenv( PATHMAPNOT ); + char *p = data; + prefix.count = 0; + if ( data == 0 || *data == 0 ) { + return; + } + prefix.count++; + while ( *p ) { + if ( *(p++) == ':' ) { + prefix.count++; + } + } + prefix.data = (char**) calloc( prefix.count, sizeof( char* ) ); + if ( data == 0 ) { + perror( PATHMAPNOT ); + exit( 1 ); + } + char *path = data; + int n = 0; + for ( p = data; *p; p++ ) { + if ( *p == ':' ) { + prefix.data[ n++ ] = strndup( path, ( p - path ) ); + path = p+1; + } + } + prefix.data[ n++ ] = strndup( path, ( p - path ) ); + prefix.root = prefix.data[ 0 ]; + prefix.root_length = strlen( prefix.root ); + qsort( prefix.data, n, sizeof( char* ), alphorder ); +} + +// Binary search for a given path prefix. Returns the index of longest +// prefix match or (-i-1)<0 for mismatch (indicating insertion point i) +static int binsearch(const char *path) { + int lo = 0; + int hi = prefix.count; + while ( lo < hi ) { + int m = ( lo + hi ) / 2; + int x = strcmp( path, prefix.data[ m ] ); + if ( x == 0 ) { + return m; + } + if ( x < 0 ) { + hi = m; + } else { + lo = m + 1; + } + } + // lo = insertion point for mismatch; check if lo-1 is prefix + if ( lo > 0 ) { + int n = strlen( prefix.data[ lo - 1 ] ); + if ( ( strncmp( prefix.data[ lo - 1 ], path, n ) == 0 ) && + ( *(path+n) == '/' ) ) { + return lo - 1; + } + } + return - lo - 1; +} + +// Utility function to lookup a matching prefix for the given path. If +// one is found, then 0 is returned. Otherwise memory is allocated for +// a new string that consists of the root path followed by the given +// path. +static char *maybe_add_prefix(const char *path) { + fprintf( stderr, "libpathmap: check %s\n", path ); + if ( prefix.count > 0 && *path == '/' ) { + int x = binsearch( path ); + //fprintf( stderr, "libpathmap: %d %s\n", x, path ); + if ( x < 0 ) { + char *p = (char*)malloc( strlen( path ) + prefix.root_length + 1 ); + memcpy( p, prefix.root, prefix.root_length ); + strcpy( p + prefix.root_length, path ); + fprintf( stderr, "libpathmap: => %s\n", p ); + return p; + } + } + return 0; +} + +int open(const char *pathname, int flags, ...) { + static int (*real_open) (const char *pathname, int flags, ...); + if ( real_open == 0 ) { + real_open = dlsym( RTLD_NEXT, "open" ); + } + const char *new_path = maybe_add_prefix( pathname ); + if ( new_path ) { + pathname = new_path; + } + int x; + + // If O_CREAT is used to create a file, the file access mode must be given. + if ( flags & O_CREAT ) { + va_list args; + va_start( args, flags ); + int mode = va_arg( args, int ); + va_end( args ); + x = real_open( pathname, flags, mode ); + } else { + x = real_open( pathname, flags); + } + if ( new_path ) { + free( (void*) new_path ); + } + return x; +} + +int __open(const char *pathname, int flags, ...) { + static int (*real_open) (const char *pathname, int flags, ...); + if ( real_open == 0 ) { + real_open = dlsym( RTLD_NEXT, "__open" ); + } + const char *new_path = maybe_add_prefix( pathname ); + if ( new_path ) { + pathname = new_path; + } + int x; + + // If O_CREAT is used to create a file, the file access mode must be given. + if ( flags & O_CREAT ) { + va_list args; + va_start( args, flags ); + int mode = va_arg( args, int ); + va_end( args ); + x = real_open( pathname, flags, mode ); + } else { + x = real_open( pathname, flags); + } + if ( new_path ) { + free( (void*) new_path ); + } + return x; +} + +int open64(const char *pathname, int flags, ...) { + static int (*real_open64)(const char *pathname, int flags, ...); + if ( real_open64 == 0 ) { + real_open64 = dlsym(RTLD_NEXT, "open64"); + } + const char *new_path = maybe_add_prefix( pathname ); + if ( new_path ) { + pathname = new_path; + } + int x; + + // If O_CREAT is used to create a file, the file access mode must be given. + if (flags & O_CREAT) { + va_list args; + va_start(args, flags); + int mode = va_arg(args, int); + va_end(args); + x = real_open64( pathname, flags, mode ); + } else { + x =real_open64( pathname, flags); + } + if ( new_path ) { + free( (void*) new_path ); + } + return x; +} + +int openat(int dirfd,const char *pathname, int flags, ...) { + static int (*real_openat) (int dirfd,const char *pathname, int flags, ...); + if ( real_openat == 0 ) { + real_openat = dlsym( RTLD_NEXT, "openat" ); + } + const char *new_path = maybe_add_prefix( pathname ); + if ( new_path ) { + pathname = new_path; + } + int x; + if ( flags & O_CREAT ) { + va_list args; + va_start( args, flags ); + int mode = va_arg( args, int ); + va_end( args ); + x = real_openat( dirfd, pathname, flags, mode ); + } else { + x = real_openat( dirfd, pathname, flags); + } + if ( new_path ) { + free( (void*) new_path ); + } + return x; +} + +int __openat_2(int dirfd,const char *pathname, int flags, ...) { + static int (*real___openat_2) ( + int dirfd,const char *pathname, int flags, ...); + if ( real___openat_2 == 0 ) { + real___openat_2 = dlsym( RTLD_NEXT, "__openat_2" ); + } + const char *new_path = maybe_add_prefix( pathname ); + if ( new_path ) { + pathname = new_path; + } + int x; + if ( flags & O_CREAT ) { + va_list args; + va_start( args, flags ); + int mode = va_arg( args, int ); + va_end( args ); + x = real___openat_2( dirfd, pathname, flags, mode ); + } else { + x = real___openat_2( dirfd, pathname, flags); + } + if ( new_path ) { + free( (void*) new_path ); + } + return x; +} + +int openat64(int dirfd,const char *pathname, int flags, ...) { + static int (*real_openat64)( + int dirfd,const char *pathname, int flags, ...); + if ( real_openat64 == 0 ) { + real_openat64 = dlsym(RTLD_NEXT, "openat64"); + } + const char *new_path = maybe_add_prefix( pathname ); + if ( new_path ) { + pathname = new_path; + } + int x; + if (flags & O_CREAT) { + va_list args; + va_start(args, flags); + int mode = va_arg(args, int); + va_end(args); + x = real_openat64( dirfd, pathname, flags, mode ); + } else { + x =real_openat64( dirfd, pathname, flags); + } + if ( new_path ) { + free( (void*) new_path ); + } + return x; +} + +FILE *fopen(const char *pathname,const char * mode) { + static FILE *(*real_fopen)(const char *pathname,const char *mode); + if ( real_fopen == 0 ) { + real_fopen = dlsym(RTLD_NEXT, "fopen"); + } + const char *new_path = maybe_add_prefix( pathname ); + if ( new_path ) { + pathname = new_path; + } + FILE *x = real_fopen( pathname, mode ); + if ( new_path ) { + free( (void*) new_path ); + } + return x; +} + +FILE *fopen64(const char *pathname,const char * mode) { + static FILE *(*real_fopen64)(const char *pathname,const char *mode); + if ( real_fopen64 == 0 ) { + real_fopen64 = dlsym(RTLD_NEXT, "fopen64"); + } + const char *new_path = maybe_add_prefix( pathname ); + if ( new_path ) { + pathname = new_path; + } + FILE *x = real_fopen64( pathname, mode ); + if ( new_path ) { + free( (void*) new_path ); + } + return x; +} + +FILE *freopen(const char *pathname,const char * mode,FILE *stream) { + static FILE *(*real_freopen)( + const char *pathname,const char *mode,FILE *stream); + if ( real_freopen == 0 ) { + real_freopen = dlsym(RTLD_NEXT, "freopen"); + } + const char *new_path = maybe_add_prefix( pathname ); + if ( new_path ) { + pathname = new_path; + } + FILE *x = real_freopen( pathname, mode, stream ); + if ( new_path ) { + free( (void*) new_path ); + } + return x; +} + +DIR *opendir(const char *pathname) { + static DIR *(*real_opendir)(const char *pathname); + if ( real_opendir == 0 ) { + real_opendir = dlsym(RTLD_NEXT, "opendir"); + } + const char *new_path = maybe_add_prefix( pathname ); + if ( new_path ) { + pathname = new_path; + } + DIR *x = real_opendir( pathname ); + if ( new_path ) { + free( (void*) new_path ); + } + return x; +} + +int __xstat(int v,const char *pathname, struct stat *statbuf) { + static int (*real_xstat)(int v,const char *pathname,struct stat *statbuf); + if ( real_xstat == 0 ) { + real_xstat = dlsym(RTLD_NEXT, "__xstat"); + } + const char *new_path = maybe_add_prefix( pathname ); + if ( new_path ) { + pathname = new_path; + } + int x = real_xstat( v, pathname, statbuf ); + if ( new_path ) { + free( (void*) new_path ); + } + return x; +} + +int __lxstat(int v,const char *pathname, struct stat *statbuf) { + static int (*real_lxstat)(int v,const char *pathname,struct stat *statbuf); + if ( real_lxstat == 0 ) { + real_lxstat = dlsym(RTLD_NEXT, "__lxstat"); + } + const char *new_path = maybe_add_prefix( pathname ); + if ( new_path ) { + pathname = new_path; + } + int x = real_lxstat( v, pathname, statbuf ); + if ( new_path ) { + free( (void*) new_path ); + } + return x; +} + +int stat(const char *pathname, struct stat *statbuf) { + static int (*real_stat)(const char *pathname,struct stat *statbuf); + if ( real_stat == 0 ) { + real_stat = dlsym(RTLD_NEXT, "stat"); + } + const char *new_path = maybe_add_prefix( pathname ); + if ( new_path ) { + pathname = new_path; + } + int x = real_stat( pathname, statbuf ); + if ( new_path ) { + free( (void*) new_path ); + } + return x; +} + +int lstat(const char *pathname, struct stat *statbuf) { + static int (*real_lstat)(const char *pathname,struct stat *statbuf); + if ( real_lstat == 0 ) { + real_lstat = dlsym(RTLD_NEXT, "lstat"); + } + const char *new_path = maybe_add_prefix( pathname ); + if ( new_path ) { + pathname = new_path; + } + int x = real_lstat( pathname, statbuf ); + if ( new_path ) { + free( (void*) new_path ); + } + return x; +} + +/** + * Initialize the dynamic library. + */ +void so_init() { + load_prefixes(); +} + diff --git a/libpathmap.c b/libpathmap.c deleted file mode 100644 index 5628030..0000000 --- a/libpathmap.c +++ /dev/null @@ -1,421 +0,0 @@ -/** - * PRELOAD utility that maps all rooted paths except some to have an - * additional root path prefix. This is configured with an environment - * variable PATHMAPNOT that is a colon separated list of pathname - * prefixes to *not* map with the first one being the additional root - * path prefix. The environment variable is loaded on the first call. - */ - -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include -#include - -/************************************************************ - * Data structure for pathname mapping - * - * Pathnames are passed in to the library via the environment variable - * PATHMAPNOT as a colon separated list of pathnames that are not to - * be mapped. The first value of PATHMAPNOT is used as prefix to add - * to all paths except the ones in the list (the first inlcuded). - * - * The given pathnames are loaded into a sorted table, offering - * O[log(n)] lookup complexity, and the map prefix is also held - * separately as the 'root'. - */ - -#define PATHMAPNOT "PATHMAPNOT" - -static struct { - char **data; // Array of char* - int count; - int root_length; - char *root; -} prefix; - -// Alphabetical ordering of char* records. -static int alphorder(const void *a, const void *b) { - int x = strcmp( *(const char**)a, *(const char**)b ); - return x; -} - -// Utility function to load the prefixes. -static void load_prefixes() { - char *data = getenv( PATHMAPNOT ); - char *p = data; - prefix.count = 0; - if ( data == 0 || *data == 0 ) { - return; - } - prefix.count++; - while ( *p ) { - if ( *(p++) == ':' ) { - prefix.count++; - } - } - prefix.data = (char**) calloc( prefix.count, sizeof( char* ) ); - if ( data == 0 ) { - perror( PATHMAPNOT ); - exit( 1 ); - } - char *path = data; - int n = 0; - for ( p = data; *p; p++ ) { - if ( *p == ':' ) { - prefix.data[ n++ ] = strndup( path, ( p - path ) ); - path = p+1; - } - } - prefix.data[ n++ ] = strndup( path, ( p - path ) ); - prefix.root = prefix.data[ 0 ]; - prefix.root_length = strlen( prefix.root ); - qsort( prefix.data, n, sizeof( char* ), alphorder ); -} - -// Binary search for a given path prefix. Returns the index of longest -// prefix match or (-i-1)<0 for mismatch (indicating insertion point i) -static int binsearch(const char *path) { - int lo = 0; - int hi = prefix.count; - while ( lo < hi ) { - int m = ( lo + hi ) / 2; - int x = strcmp( path, prefix.data[ m ] ); - if ( x == 0 ) { - return m; - } - if ( x < 0 ) { - hi = m; - } else { - lo = m + 1; - } - } - // lo = insertion point for mismatch; check if lo-1 is prefix - if ( lo > 0 ) { - int n = strlen( prefix.data[ lo - 1 ] ); - if ( ( strncmp( prefix.data[ lo - 1 ], path, n ) == 0 ) && - ( *(path+n) == '/' ) ) { - return lo - 1; - } - } - return - lo - 1; -} - -// Utility function to lookup a matching prefix for the given path. If -// one is found, then 0 is returned. Otherwise memory is allocated for -// a new string that consists of the root path followed by the given -// path. -static char *maybe_add_prefix(const char *path) { - fprintf( stderr, "libpathmap: check %s\n", path ); - if ( prefix.count > 0 && *path == '/' ) { - int x = binsearch( path ); - //fprintf( stderr, "libpathmap: %d %s\n", x, path ); - if ( x < 0 ) { - char *p = (char*)malloc( strlen( path ) + prefix.root_length + 1 ); - memcpy( p, prefix.root, prefix.root_length ); - strcpy( p + prefix.root_length, path ); - fprintf( stderr, "libpathmap: => %s\n", p ); - return p; - } - } - return 0; -} - -int open(const char *pathname, int flags, ...) { - static int (*real_open) (const char *pathname, int flags, ...); - if ( real_open == 0 ) { - real_open = dlsym( RTLD_NEXT, "open" ); - } - const char *new_path = maybe_add_prefix( pathname ); - if ( new_path ) { - pathname = new_path; - } - int x; - - // If O_CREAT is used to create a file, the file access mode must be given. - if ( flags & O_CREAT ) { - va_list args; - va_start( args, flags ); - int mode = va_arg( args, int ); - va_end( args ); - x = real_open( pathname, flags, mode ); - } else { - x = real_open( pathname, flags); - } - if ( new_path ) { - free( (void*) new_path ); - } - return x; -} - -int __open(const char *pathname, int flags, ...) { - static int (*real_open) (const char *pathname, int flags, ...); - if ( real_open == 0 ) { - real_open = dlsym( RTLD_NEXT, "__open" ); - } - const char *new_path = maybe_add_prefix( pathname ); - if ( new_path ) { - pathname = new_path; - } - int x; - - // If O_CREAT is used to create a file, the file access mode must be given. - if ( flags & O_CREAT ) { - va_list args; - va_start( args, flags ); - int mode = va_arg( args, int ); - va_end( args ); - x = real_open( pathname, flags, mode ); - } else { - x = real_open( pathname, flags); - } - if ( new_path ) { - free( (void*) new_path ); - } - return x; -} - -int open64(const char *pathname, int flags, ...) { - static int (*real_open64)(const char *pathname, int flags, ...); - if ( real_open64 == 0 ) { - real_open64 = dlsym(RTLD_NEXT, "open64"); - } - const char *new_path = maybe_add_prefix( pathname ); - if ( new_path ) { - pathname = new_path; - } - int x; - - // If O_CREAT is used to create a file, the file access mode must be given. - if (flags & O_CREAT) { - va_list args; - va_start(args, flags); - int mode = va_arg(args, int); - va_end(args); - x = real_open64( pathname, flags, mode ); - } else { - x =real_open64( pathname, flags); - } - if ( new_path ) { - free( (void*) new_path ); - } - return x; -} - -int openat(int dirfd,const char *pathname, int flags, ...) { - static int (*real_openat) (int dirfd,const char *pathname, int flags, ...); - if ( real_openat == 0 ) { - real_openat = dlsym( RTLD_NEXT, "openat" ); - } - const char *new_path = maybe_add_prefix( pathname ); - if ( new_path ) { - pathname = new_path; - } - int x; - if ( flags & O_CREAT ) { - va_list args; - va_start( args, flags ); - int mode = va_arg( args, int ); - va_end( args ); - x = real_openat( dirfd, pathname, flags, mode ); - } else { - x = real_openat( dirfd, pathname, flags); - } - if ( new_path ) { - free( (void*) new_path ); - } - return x; -} - -int __openat_2(int dirfd,const char *pathname, int flags, ...) { - static int (*real___openat_2) ( - int dirfd,const char *pathname, int flags, ...); - if ( real___openat_2 == 0 ) { - real___openat_2 = dlsym( RTLD_NEXT, "__openat_2" ); - } - const char *new_path = maybe_add_prefix( pathname ); - if ( new_path ) { - pathname = new_path; - } - int x; - if ( flags & O_CREAT ) { - va_list args; - va_start( args, flags ); - int mode = va_arg( args, int ); - va_end( args ); - x = real___openat_2( dirfd, pathname, flags, mode ); - } else { - x = real___openat_2( dirfd, pathname, flags); - } - if ( new_path ) { - free( (void*) new_path ); - } - return x; -} - -int openat64(int dirfd,const char *pathname, int flags, ...) { - static int (*real_openat64)( - int dirfd,const char *pathname, int flags, ...); - if ( real_openat64 == 0 ) { - real_openat64 = dlsym(RTLD_NEXT, "openat64"); - } - const char *new_path = maybe_add_prefix( pathname ); - if ( new_path ) { - pathname = new_path; - } - int x; - if (flags & O_CREAT) { - va_list args; - va_start(args, flags); - int mode = va_arg(args, int); - va_end(args); - x = real_openat64( dirfd, pathname, flags, mode ); - } else { - x =real_openat64( dirfd, pathname, flags); - } - if ( new_path ) { - free( (void*) new_path ); - } - return x; -} - -FILE *fopen(const char *pathname,const char * mode) { - static FILE *(*real_fopen)(const char *pathname,const char *mode); - if ( real_fopen == 0 ) { - real_fopen = dlsym(RTLD_NEXT, "fopen"); - } - const char *new_path = maybe_add_prefix( pathname ); - if ( new_path ) { - pathname = new_path; - } - FILE *x = real_fopen( pathname, mode ); - if ( new_path ) { - free( (void*) new_path ); - } - return x; -} - -FILE *fopen64(const char *pathname,const char * mode) { - static FILE *(*real_fopen64)(const char *pathname,const char *mode); - if ( real_fopen64 == 0 ) { - real_fopen64 = dlsym(RTLD_NEXT, "fopen64"); - } - const char *new_path = maybe_add_prefix( pathname ); - if ( new_path ) { - pathname = new_path; - } - FILE *x = real_fopen64( pathname, mode ); - if ( new_path ) { - free( (void*) new_path ); - } - return x; -} - -FILE *freopen(const char *pathname,const char * mode,FILE *stream) { - static FILE *(*real_freopen)( - const char *pathname,const char *mode,FILE *stream); - if ( real_freopen == 0 ) { - real_freopen = dlsym(RTLD_NEXT, "freopen"); - } - const char *new_path = maybe_add_prefix( pathname ); - if ( new_path ) { - pathname = new_path; - } - FILE *x = real_freopen( pathname, mode, stream ); - if ( new_path ) { - free( (void*) new_path ); - } - return x; -} - -DIR *opendir(const char *pathname) { - static DIR *(*real_opendir)(const char *pathname); - if ( real_opendir == 0 ) { - real_opendir = dlsym(RTLD_NEXT, "opendir"); - } - const char *new_path = maybe_add_prefix( pathname ); - if ( new_path ) { - pathname = new_path; - } - DIR *x = real_opendir( pathname ); - if ( new_path ) { - free( (void*) new_path ); - } - return x; -} - -int __xstat(int v,const char *pathname, struct stat *statbuf) { - static int (*real_xstat)(int v,const char *pathname,struct stat *statbuf); - if ( real_xstat == 0 ) { - real_xstat = dlsym(RTLD_NEXT, "__xstat"); - } - const char *new_path = maybe_add_prefix( pathname ); - if ( new_path ) { - pathname = new_path; - } - int x = real_xstat( v, pathname, statbuf ); - if ( new_path ) { - free( (void*) new_path ); - } - return x; -} - -int __lxstat(int v,const char *pathname, struct stat *statbuf) { - static int (*real_lxstat)(int v,const char *pathname,struct stat *statbuf); - if ( real_lxstat == 0 ) { - real_lxstat = dlsym(RTLD_NEXT, "__lxstat"); - } - const char *new_path = maybe_add_prefix( pathname ); - if ( new_path ) { - pathname = new_path; - } - int x = real_lxstat( v, pathname, statbuf ); - if ( new_path ) { - free( (void*) new_path ); - } - return x; -} - -int stat(const char *pathname, struct stat *statbuf) { - static int (*real_stat)(const char *pathname,struct stat *statbuf); - if ( real_stat == 0 ) { - real_stat = dlsym(RTLD_NEXT, "stat"); - } - const char *new_path = maybe_add_prefix( pathname ); - if ( new_path ) { - pathname = new_path; - } - int x = real_stat( pathname, statbuf ); - if ( new_path ) { - free( (void*) new_path ); - } - return x; -} - -int lstat(const char *pathname, struct stat *statbuf) { - static int (*real_lstat)(const char *pathname,struct stat *statbuf); - if ( real_lstat == 0 ) { - real_lstat = dlsym(RTLD_NEXT, "lstat"); - } - const char *new_path = maybe_add_prefix( pathname ); - if ( new_path ) { - pathname = new_path; - } - int x = real_lstat( pathname, statbuf ); - if ( new_path ) { - free( (void*) new_path ); - } - return x; -} - -/** - * Initialize the dynamic library. - */ -void so_init() { - load_prefixes(); -} - diff --git a/libpathmap.so.8.adoc b/libpathmap.so.8.adoc deleted file mode 100644 index 7b93dce..0000000 --- a/libpathmap.so.8.adoc +++ /dev/null @@ -1,70 +0,0 @@ -libpathmap.so(8) -================ -:doctype: manpage -:revdate: {sys:date "+%Y-%m-%d %H:%M:%S"} -:COLON: : -:EQUALS: = - -NAME ----- -libpathmap.so - preload utility to redirect pathnames - -SYNOPSYS --------- -+LD_PRELOAD=libpathmap.so+ _command_ - -DESCRIPTION ------------ - -This dynamic library, libpathmap.so, is intended to be used as a -"preload" library for programs for which pathnames are to be mapped to -a different common prefix. The effect is somewhat similar to +chroot+ -in that absolute pathnames, which normally are from the root of the -file system, get mapped to be relative to the choosen prefix point. - -+libpathmap.so+ is "configured" by setting environment variable -+PATHMAPNOT+ to be the path prefixes, given as a colon separated list, -that +libpathmap.so+ should be concerned with. The first of them is -then used as the prefix to add to the program's pathnames (when -opening files) except to those pathnames that start with any of the -prefixes in the list, including the first. - -For example, if the prefix +/elsewhere+ should be added to all -pathnames for a program _prgrm_ then the command line might be: - ----- -PATHMAPNOT=/elsewhere LD_PRELOAD=libpathmap.so prgrm ----- - -Note however that dynamically linked libraries are loaded via -statically linked function calls and they are therefore not handled -via libpathmap.so. - -ENVIRONMENT ------------ - -PATHMAPNOT:: - -This environment variable tells which path prefixes, given as a colon -separated list, +libpathmap.so+ should be concerned with. The first -prefix is the one to add to all pathnames except to those of any of -the prefixes in the list. - -EXAMPLES --------- - -Assume there is a directory +/home/test/extra+ - ----- -env PATHMAPNOT=/home/test:/proc:/dev:/lib:/usr:/bin \ - LD_PRELOAD=libpathmap.so \ - ls /extra ----- - -SEE ALSO --------- - -libtarmap.so:: - -something - diff --git a/libpathmap0.so.8.adoc b/libpathmap0.so.8.adoc new file mode 100644 index 0000000..ff8be3d --- /dev/null +++ b/libpathmap0.so.8.adoc @@ -0,0 +1,67 @@ +libpathmap0.so(8) +================ +:doctype: manpage +:revdate: {sys:date "+%Y-%m-%d %H:%M:%S"} +:COLON: : +:EQUALS: = + +NAME +---- +libpathmap0.so - preload utility to redirect pathnames + +SYNOPSYS +-------- ++LD_PRELOAD=libpathmap0.so+ _command_ + +DESCRIPTION +----------- + +This dynamic library, libpathmap0.so, is intended to be used as a +"preload" library for programs for which pathnames are to be mapped to +a different common prefix. The effect is somewhat similar to +chroot+ +in that absolute pathnames, which normally are from the root of the +file system, get mapped to be relative to the choosen prefix point. + ++libpathmap0.so+ is "configured" by setting environment variable ++PATHMAPNOT+ to be the path prefixes, given as a colon separated list, +that +libpathmap0.so+ should be concerned with. The first of them is +then used as the prefix to add to the program's pathnames (when +opening files) except to those pathnames that start with any of the +prefixes in the list, including the first. + +For example, if the prefix +/elsewhere+ should be added to all +pathnames for a program _prgrm_ then the command line might be: + +---- +PATHMAPNOT=/elsewhere LD_PRELOAD=libpathmap0.so prgrm +---- + +Note however that dynamically linked libraries are loaded via +statically linked function calls and they are therefore not handled +via libpathmap0.so. + +ENVIRONMENT +----------- + +PATHMAPNOT:: + +This environment variable tells which path prefixes, given as a colon +separated list, +libpathmap0.so+ should be concerned with. The first +prefix is the one to add to all pathnames except to those of any of +the prefixes in the list. + +EXAMPLES +-------- + +Assume there is a directory +/home/test/extra+ + +---- +env PATHMAPNOT=/home/test:/proc:/dev:/lib:/usr:/bin \ + LD_PRELOAD=libpathmap0.so \ + ls /extra +---- + +SEE ALSO +-------- + +libtarmap0.so, tarmap diff --git a/libtarmap-0.c b/libtarmap-0.c new file mode 100644 index 0000000..339fdbd --- /dev/null +++ b/libtarmap-0.c @@ -0,0 +1,175 @@ +/** + * libtarmap implements a preload library for faked file access that + * opens and reads files from a tar file first where possible. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static int (*real_open)(const char *pathname, int flags); +static int (*real_openat)(int dirfd, const char *pathname, int flags); +static FILE *(*real_fopen)(const char *pathname, const char *mode); + +// The environment variable name +#define TARMAP "TARMAP" + +// Maximal allowed size of filenames ("tar tf" output) +#define DATASZ 10000000 + +static struct { + char *tarmap; // TARMAP value + char *head; // Command preamble + char *buffer; // All file names of the tar file + int size; // Byte size of buffer + char **table; // File name index in alphabetical order + int count; // Number of file names +} data; + +// Ordering condition for two char** +static int alphaorder(const void *a,const void *b) { + int x = strcmp( *(const char**)a, *(const char**)b ); + return x; +} + +// Combine two strings with a space between as a new malloc string +static char *join(const char *head,const char *tail) { + int n = strlen( head ); + char *p = (char*) malloc( n + strlen( tail ) + 2 ); + strcpy( p, head ); + strcpy( p + n, " " ); + strcpy( p + n + 1, tail ); + return p; +} + +// Run popen with TARMAP unset +static inline FILE *popen_notarmap(const char *cmd) { + unsetenv( TARMAP ); // Inhibit tarmap for the command subprocess + FILE *file = popen( cmd, "r" ); + setenv( TARMAP, data.tarmap, 1 ); // Re-enable for this process + return file; +} + +// Try opening the pathname in the tar +static FILE *tryopentar(const char *pathname) { + //fprintf( stderr, "libtarmap open: %s\n", pathname ); + if ( bsearch( &pathname, data.table, data.count, sizeof( char * ), + alphaorder ) ) { + char *p = join( data.head, pathname ); + //fprintf( stderr, "libtarmap: => %s\n", p ); + FILE *file = popen_notarmap( p ); + free( p ); + return file; + } + return 0; +} + +// Override "openat" +int openat(int dirfd, const char *pathname, int flags) { + //fprintf( stderr, "openat( %s )\n", pathname ); + if ( data.tarmap ) { + FILE *file = tryopentar( pathname ); + if ( file ) { + return fileno( file ); + } + } + return ( real_openat )? real_openat( dirfd, pathname, flags ) : 0; +} + +// Override "open" +int open(const char *pathname, int flags) { + //fprintf( stderr, "open( %s )\n", pathname ); + if ( data.tarmap ) { + FILE *file = tryopentar( pathname ); + if ( file ) { + return fileno( file ); + } + } + return ( real_open )? real_open( pathname, flags ) : -1; +} + +// Override "fopen" +FILE *fopen(const char *pathname, const char *mode) { + if ( data.tarmap ) { + FILE *file = tryopentar( pathname ); + if ( file ) { + return file; + } + } + return ( real_fopen )? real_fopen( pathname, mode ) : 0; +} + +/** + * Initialize the dynamic library. + */ +void so_init() { + static int done = 0; + if ( done ) { + return; + } + done = 1; + void *lib = dlopen( "libc.so.6", RTLD_LAZY ); + real_open = dlsym( lib, "open" ); + real_openat = dlsym( lib, "openat" ); + real_fopen = dlsym( lib, "fopen" ); + char *tarfile = getenv( TARMAP ); + if ( tarfile == 0 || *tarfile == 0 ) { + //fprintf( stderr, "(libtarmap: no tar)\n" ); + data.tarmap = 0; + return; // Stop here for unset or cleared environment + } + //fprintf( stderr, "libtarmap: tarfile = %s\n", tarfile ); + if ( ( data.tarmap = realpath( tarfile, 0 ) ) == 0 ) { + // Cannot find the tar file .. that's total badness! + perror( tarfile ); + exit( 1 ); + } + data.head = join( "/bin/tar xOf", data.tarmap ); + char *cmd = join( "/bin/tar tf", data.tarmap ); + FILE *file = popen_notarmap( cmd ); + if ( file == 0 ) { + // cannot open tar file .. that's total badness! + perror( data.tarmap ); + exit( 1 ); + } + data.buffer = malloc( DATASZ ); + data.size = read( fileno( file ), data.buffer, DATASZ ); + if ( data.size == 0 ) { + perror( cmd ); + // Not a tar or empty tar .. that's total badness! + fprintf( stderr, "*** libtarmap: exiting\n" ); + exit( 1 ); + } + if ( data.size >= DATASZ ) { + // Too many filenmames .. that's total badness! ENAMETOOLONG + fprintf( stderr, "*** libtarmap: too large pathname table\n"); + exit( 1 ); + } + data.buffer = realloc( data.buffer, data.size ); + pclose( file ); + free( cmd ); + cmd = 0; + char *end = data.buffer + data.size; + char *p; + int n = 0; + for ( p = data.buffer; p < end; p++ ) { + if ( *p == '\n' ) { + n++; + *p = '\000'; + } + } + data.table = (char**) calloc( sizeof( char* ), data.count ); + char *name = data.buffer; + for ( p = data.buffer; p < end; p++ ) { + if ( *p == 0 ) { + data.table[ data.count++ ] = name; + name = p+1; + } + } + qsort( data.table, data.count, sizeof( char* ), alphaorder ); +} diff --git a/libtarmap.c b/libtarmap.c deleted file mode 100644 index 339fdbd..0000000 --- a/libtarmap.c +++ /dev/null @@ -1,175 +0,0 @@ -/** - * libtarmap implements a preload library for faked file access that - * opens and reads files from a tar file first where possible. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -static int (*real_open)(const char *pathname, int flags); -static int (*real_openat)(int dirfd, const char *pathname, int flags); -static FILE *(*real_fopen)(const char *pathname, const char *mode); - -// The environment variable name -#define TARMAP "TARMAP" - -// Maximal allowed size of filenames ("tar tf" output) -#define DATASZ 10000000 - -static struct { - char *tarmap; // TARMAP value - char *head; // Command preamble - char *buffer; // All file names of the tar file - int size; // Byte size of buffer - char **table; // File name index in alphabetical order - int count; // Number of file names -} data; - -// Ordering condition for two char** -static int alphaorder(const void *a,const void *b) { - int x = strcmp( *(const char**)a, *(const char**)b ); - return x; -} - -// Combine two strings with a space between as a new malloc string -static char *join(const char *head,const char *tail) { - int n = strlen( head ); - char *p = (char*) malloc( n + strlen( tail ) + 2 ); - strcpy( p, head ); - strcpy( p + n, " " ); - strcpy( p + n + 1, tail ); - return p; -} - -// Run popen with TARMAP unset -static inline FILE *popen_notarmap(const char *cmd) { - unsetenv( TARMAP ); // Inhibit tarmap for the command subprocess - FILE *file = popen( cmd, "r" ); - setenv( TARMAP, data.tarmap, 1 ); // Re-enable for this process - return file; -} - -// Try opening the pathname in the tar -static FILE *tryopentar(const char *pathname) { - //fprintf( stderr, "libtarmap open: %s\n", pathname ); - if ( bsearch( &pathname, data.table, data.count, sizeof( char * ), - alphaorder ) ) { - char *p = join( data.head, pathname ); - //fprintf( stderr, "libtarmap: => %s\n", p ); - FILE *file = popen_notarmap( p ); - free( p ); - return file; - } - return 0; -} - -// Override "openat" -int openat(int dirfd, const char *pathname, int flags) { - //fprintf( stderr, "openat( %s )\n", pathname ); - if ( data.tarmap ) { - FILE *file = tryopentar( pathname ); - if ( file ) { - return fileno( file ); - } - } - return ( real_openat )? real_openat( dirfd, pathname, flags ) : 0; -} - -// Override "open" -int open(const char *pathname, int flags) { - //fprintf( stderr, "open( %s )\n", pathname ); - if ( data.tarmap ) { - FILE *file = tryopentar( pathname ); - if ( file ) { - return fileno( file ); - } - } - return ( real_open )? real_open( pathname, flags ) : -1; -} - -// Override "fopen" -FILE *fopen(const char *pathname, const char *mode) { - if ( data.tarmap ) { - FILE *file = tryopentar( pathname ); - if ( file ) { - return file; - } - } - return ( real_fopen )? real_fopen( pathname, mode ) : 0; -} - -/** - * Initialize the dynamic library. - */ -void so_init() { - static int done = 0; - if ( done ) { - return; - } - done = 1; - void *lib = dlopen( "libc.so.6", RTLD_LAZY ); - real_open = dlsym( lib, "open" ); - real_openat = dlsym( lib, "openat" ); - real_fopen = dlsym( lib, "fopen" ); - char *tarfile = getenv( TARMAP ); - if ( tarfile == 0 || *tarfile == 0 ) { - //fprintf( stderr, "(libtarmap: no tar)\n" ); - data.tarmap = 0; - return; // Stop here for unset or cleared environment - } - //fprintf( stderr, "libtarmap: tarfile = %s\n", tarfile ); - if ( ( data.tarmap = realpath( tarfile, 0 ) ) == 0 ) { - // Cannot find the tar file .. that's total badness! - perror( tarfile ); - exit( 1 ); - } - data.head = join( "/bin/tar xOf", data.tarmap ); - char *cmd = join( "/bin/tar tf", data.tarmap ); - FILE *file = popen_notarmap( cmd ); - if ( file == 0 ) { - // cannot open tar file .. that's total badness! - perror( data.tarmap ); - exit( 1 ); - } - data.buffer = malloc( DATASZ ); - data.size = read( fileno( file ), data.buffer, DATASZ ); - if ( data.size == 0 ) { - perror( cmd ); - // Not a tar or empty tar .. that's total badness! - fprintf( stderr, "*** libtarmap: exiting\n" ); - exit( 1 ); - } - if ( data.size >= DATASZ ) { - // Too many filenmames .. that's total badness! ENAMETOOLONG - fprintf( stderr, "*** libtarmap: too large pathname table\n"); - exit( 1 ); - } - data.buffer = realloc( data.buffer, data.size ); - pclose( file ); - free( cmd ); - cmd = 0; - char *end = data.buffer + data.size; - char *p; - int n = 0; - for ( p = data.buffer; p < end; p++ ) { - if ( *p == '\n' ) { - n++; - *p = '\000'; - } - } - data.table = (char**) calloc( sizeof( char* ), data.count ); - char *name = data.buffer; - for ( p = data.buffer; p < end; p++ ) { - if ( *p == 0 ) { - data.table[ data.count++ ] = name; - name = p+1; - } - } - qsort( data.table, data.count, sizeof( char* ), alphaorder ); -} diff --git a/libtarmap.so.8.adoc b/libtarmap.so.8.adoc deleted file mode 100644 index 6fe8cff..0000000 --- a/libtarmap.so.8.adoc +++ /dev/null @@ -1,36 +0,0 @@ -libtarmap.so(8) -=============== -:doctype: manpage -:revdate: {sys:date "+%Y-%m-%d %H:%M:%S"} -:COLON: : -:EQUALS: = - -NAME ----- -libtarmap.so - preload utility to map pathnames into a tar file - -SYNOPSYS --------- -LD_PRELOAD=libtarmap.so TARMAP=_tarfile_ _command_ - -DESCRIPTION ------------ - -This is a dynamic library that is intended to be used as an LD_PRELOAD -library for programs for which pathnames are to be mapped into a -tarfile first. In fact the command may be a bash script file within -the tarfile for executing that - -ENVIRONMENT ------------ - -TARMAP:: - -This environment variable tells which tarfile to use. Pathnames are -looked up in the tarfile first. - - -SEE ALSO --------- - -tarmap, libpathmap diff --git a/libtarmap0.so.8.adoc b/libtarmap0.so.8.adoc new file mode 100644 index 0000000..107893b --- /dev/null +++ b/libtarmap0.so.8.adoc @@ -0,0 +1,36 @@ +libtarmap0.so(8) +=============== +:doctype: manpage +:revdate: {sys:date "+%Y-%m-%d %H:%M:%S"} +:COLON: : +:EQUALS: = + +NAME +---- +libtarmap0.so - preload utility to map pathnames into a tar file + +SYNOPSYS +-------- +LD_PRELOAD=libtarmap0.so TARMAP=_tarfile_ _command_ + +DESCRIPTION +----------- + +This is a dynamic library that is intended to be used as an LD_PRELOAD +library for programs for which pathnames are to be mapped into a +tarfile first. In fact the command may be a bash script file within +the tarfile for executing that + +ENVIRONMENT +----------- + +TARMAP:: + +This environment variable tells which tarfile to use. Pathnames are +looked up in the tarfile first. + + +SEE ALSO +-------- + +tarmap, libpathmap