From: Ralph Ronnquist Date: Tue, 25 Oct 2022 07:48:09 +0000 (+1100) Subject: fixes while debugging tarmap X-Git-Url: https://git.rrq.selfhost.au/?a=commitdiff_plain;h=82dc75f624e2093dbb44ab338e5f194dc042a2be;p=rrq%2Fpathmap.git fixes while debugging tarmap --- diff --git a/libpathmap.so.8.adoc b/libpathmap.so.8.adoc index 20fe8e5..7b93dce 100644 --- a/libpathmap.so.8.adoc +++ b/libpathmap.so.8.adoc @@ -30,14 +30,15 @@ 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: +pathnames for a program _prgrm_ then the command line might be: ---- PATHMAPNOT=/elsewhere LD_PRELOAD=libpathmap.so prgrm ---- -However, if +prgrm+ is a dynamically linked executable, then all -libraries +Note however that dynamically linked libraries are loaded via +statically linked function calls and they are therefore not handled +via libpathmap.so. ENVIRONMENT ----------- diff --git a/libtarmap.c b/libtarmap.c index f10c9cc..339fdbd 100644 --- a/libtarmap.c +++ b/libtarmap.c @@ -13,7 +13,7 @@ #include static int (*real_open)(const char *pathname, int flags); -static FILE *(*real_openat)(int dirfd, 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 @@ -57,11 +57,11 @@ static inline FILE *popen_notarmap(const char *cmd) { // Try opening the pathname in the tar static FILE *tryopentar(const char *pathname) { - fprintf( stderr, "libtarmap: %s\n", 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 ); + //fprintf( stderr, "libtarmap: => %s\n", p ); FILE *file = popen_notarmap( p ); free( p ); return file; @@ -70,13 +70,12 @@ static FILE *tryopentar(const char *pathname) { } // Override "openat" -FILE *openat(int dirfd, const char *pathname, int flags) { +int openat(int dirfd, const char *pathname, int flags) { + //fprintf( stderr, "openat( %s )\n", pathname ); if ( data.tarmap ) { - if ( strncmp( pathname, "/", 1 ) == 0 ) { - FILE *file = tryopentar( pathname + 1 ); - if ( file ) { - return file; - } + FILE *file = tryopentar( pathname ); + if ( file ) { + return fileno( file ); } } return ( real_openat )? real_openat( dirfd, pathname, flags ) : 0; @@ -84,12 +83,11 @@ FILE *openat(int dirfd, const char *pathname, int flags) { // Override "open" int open(const char *pathname, int flags) { + //fprintf( stderr, "open( %s )\n", pathname ); if ( data.tarmap ) { - if ( strncmp( pathname, "/", 1 ) == 0 ) { - FILE *file = tryopentar( pathname + 1 ); - if ( file ) { - return fileno( file ); - } + FILE *file = tryopentar( pathname ); + if ( file ) { + return fileno( file ); } } return ( real_open )? real_open( pathname, flags ) : -1; @@ -98,11 +96,9 @@ int open(const char *pathname, int flags) { // Override "fopen" FILE *fopen(const char *pathname, const char *mode) { if ( data.tarmap ) { - if ( strncmp( pathname, "/", 1 ) == 0 ) { - FILE *file = tryopentar( pathname + 1 ); - if ( file ) { - return file; - } + FILE *file = tryopentar( pathname ); + if ( file ) { + return file; } } return ( real_fopen )? real_fopen( pathname, mode ) : 0; @@ -112,17 +108,22 @@ FILE *fopen(const char *pathname, const char *mode) { * 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" ); + //fprintf( stderr, "(libtarmap: no tar)\n" ); data.tarmap = 0; return; // Stop here for unset or cleared environment } - fprintf( stderr, "libtarmap: tarfile = %s\n", tarfile ); + //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 ); diff --git a/libtarmap.so.8.adoc b/libtarmap.so.8.adoc index ca477bc..addc8a5 100644 --- a/libtarmap.so.8.adoc +++ b/libtarmap.so.8.adoc @@ -11,61 +11,27 @@ libtarmap.so - preload utility to map pathnames into a tar file SYNOPSYS -------- -+LD_PRELOAD=libtarmap.so+ +TARMAP=+_tarfile_ _command_ +LD_PRELOAD=libtarmap.so TARMAP=_tarfile_ _command_ DESCRIPTION ----------- -This dynamic library, libtarmap.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. - -+libtarmap.so+ is "configured" by setting environment variable -+PATHMAPNOT+ to be the path prefixes, given as a colon separated list, -that +libtarmap.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=libtarmap.so prgrm ----- - -However, if +prgrm+ is a dynamically linked executable, then all -libraries +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 ----------- -PATHMAPNOT:: +TARMAP:: -This environment variable tells which path prefixes, given as a colon -separated list, +libtarmap.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. +This environment variable tells which tarfile to use. Pathnames are +looked up in the tarfile first. EXAMPLES -------- -Assume there is a directory +/home/test/extra+ - ----- -env PATHMAPNOT=/home/test:/proc:/dev:/lib:/usr:/bin \ - LD_PRELOAD=libtarmap.so \ - ls /extra ----- - SEE ALSO -------- -tarmap:: - -aaa - -libpathmap.so:: -aaa diff --git a/tarmap.8.adoc b/tarmap.8.adoc index 86e7961..3da611b 100644 --- a/tarmap.8.adoc +++ b/tarmap.8.adoc @@ -16,6 +16,10 @@ SYNOPSYS DESCRIPTION ----------- +The given command is executed by "/bin/bash" with an LD_PRELOAD +setting to use libtarmap.so for resolving pathnames into the given tar +file before the filesystem. See libtarmap.so for more details. + TBD This dynamic library, libtarmap.so, is intended to be used as a diff --git a/tarmap.c b/tarmap.c index 215fe5e..e61e788 100644 --- a/tarmap.c +++ b/tarmap.c @@ -27,11 +27,12 @@ static char *makeEnv(char *name,char *value) { fprintf( stderr, "%s\n", "*** tarmap: OOM .. exiting" ); exit( 1 ); } + //fprintf( stderr, ":%s:\n", old ); return old; } int main(int argc,char *argv[],char *envp[]) { - if ( argc < 3 ) { + if ( argc < 2 ) { fprintf( stderr, "tarmap tar-file command [ argument ]\n" ); exit( 1 ); } @@ -39,9 +40,9 @@ int main(int argc,char *argv[],char *envp[]) { int i_preload = -1; int i_tarmap = -1; for ( n = 0; envp[n]; n++) { - if ( strcmp( envp[n], "LD_PRELOAD=" ) == 0 ) { + if ( strncmp( envp[n], "LD_PRELOAD=", 11 ) == 0 ) { i_preload = n; - } else if ( strcmp( envp[n], "TARMAP=" ) ) { + } else if ( strncmp( envp[n], "TARMAP=", 7 ) == 0 ) { i_tarmap = n; } } @@ -55,7 +56,7 @@ int main(int argc,char *argv[],char *envp[]) { memcpy( nenvp, envp, n * sizeof( char*) ); nenvp[ i_preload ] = makeEnv( "LD_PRELOAD", "libtarmap.so" ); nenvp[ i_tarmap ] = makeEnv( "TARMAP", argv[1] ); - execve( argv[2], argv+2, nenvp ); + execve( "/bin/bash", argv+1, nenvp ); perror( "tarmap exec" ); return 1; }