int count;
int root_length;
char *root;
+ int root_index;
} prefix;
// Alphabetical ordering of char* records.
return x;
}
+// Binary search for a given path prefix.
+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;
+ }
+ }
+ return - lo - 1;
+}
+
+// Use binary search for a given path prefix, and for mismatch check
+// if entry prior to insertion is a path prefix. Returns the index of
+// longest path prefix match or (-i-1)<0 for mismatch (indicating
+// insertion point i)
+static int prefixsearch(const char *path) {
+ int lo = binsearch( path );
+#if 0
+ if ( lo >= 0 ) {
+ fprintf( stderr, "libpathmap: [%d] %s\n", lo, prefix.data[ lo ] );
+ } else {
+ fprintf( stderr, "libpathmap: [%d] ... \n", lo );
+ }
+#endif
+ if ( lo >= -1 ) {
+ return lo;
+ }
+ int p = - lo - 2;
+ // p = before insertion point for mismatch; check if it's prefix
+ int n = strlen( prefix.data[ p ] );
+ if ( ( strncmp( prefix.data[ p ], path, n ) != 0 ) ) {
+ return lo; // Not a prefix
+ }
+ if ( *(path+n) == '/' ) {
+ //fprintf( stderr, "libpathmap: exclude prefix %s\n",
+ // prefix.data[ p ] );
+ return p; // matching prefix at p
+ }
+ // The root path must be prefix; any exclude path may match in full
+ if ( ( p != prefix.root_index ) && *(path+n) == 0 ) {
+ //fprintf( stderr, "libpathmap: exclude match %s\n",
+ // prefix.data[ p ] );
+ return p;
+ }
+ return lo;
+}
+
// Utility function to load the prefixes.
static void load_prefixes() {
char *data = getenv( PATHMAPNOT );
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;
+ prefix.root_index = binsearch( prefix.root );
}
// Utility function to lookup a matching prefix for the given path. If
// by the given path. Note that prefixing only applies to absolute
// paths.
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: check %s\n", path );
+ int x = prefixsearch( 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 );
+ //fprintf( stderr, "libpathmap: [%s] %s\n", prefix.root, path );
return p;
+ } else {
+ //fprintf( stderr, "libpathmap: [] %s\n", path );
}
}
return 0;
}
//fprintf( stderr, "libtarmap: %s\n", tarfile? tarfile : "(null)" );
libc6 = dlopen( "libc.so.6", RTLD_LAZY );
- real_openat = dlsym( libc6, "openat" );
- real_open = dlsym( libc6, "open" );
- real_fopen = dlsym( libc6, "fopen" );
+ //real_openat = dlsym( libc6, "openat" );
+ //real_open = dlsym( libc6, "open" );
+ //real_fopen = dlsym( libc6, "fopen" );
if ( ( data.tarmap = realpath( tarfile, 0 ) ) == 0 ) {
// Cannot find the tar file .. that's total badness!
perror( tarfile );