Pathrewrite

Using the Innotek Libc pathrewrite function
When porting application from unix flavours you might run into the problem that some parts are hardcoded into the application, most famous is of course /etc.

Libc provides a interface to work around these problems without completely rewriting the application, and thus easying the maintenance for the porter.

This interface is called pathrewrite, Let me try to explain how it works.
 * Through an environment setting you tell libc to load a DLL in which a pathrewrite function is available.
 * Libc loads this DLL on every load instance calls the specified entry point with 3 parameters
 * Pathrewrite add function
 * Pathrewrite remove function
 * Pathrewrite modify function
 * with these parameters the function inside the user supplied DLL can alter LIBC internals which are responsible for Path rewriting.
 * Every path rewrite entry is a structure with some parameters, I will not go into them here.
 * Whenever LIBC encounters a function call which uses file names as parameters it will apply the rules of the pathrewriters

e.g. if a path rewriter is set to rewrite '/etc' to 'c:\mptn\etc' this is what will happen:

a program issues: fp = fopen('/etc/test.txt','b');

Libc will actually do: fp = fopen('c:\mptn\etc/test.txt','b');

In this article I'll try to outline the possibilities from what I used myself and will give an example.

First lets see what is documented inside the libc hooks.c file: so we need to create a DLL which export a function that sets the rewritten paths.

Creating an example
So we want to create a DLL which we place in the CONFIG.SYS with a line like: set LIBC_HOOK_DLLS=ecsprw.dll@_ecsInitPath!pathrewrite

This means 2 things.
 * 1) ecsprw.dll should be somewhere in the LIBPATH, lets put it in ecs\dll
 * 2) ecsprw.dll should export _ecsInitPath

ecsprw.def
note: the DESCRIPTION tag comes later

ecsprw.c
What do we see in the source file ??

we declare some structures to hold the rewrite data: we tell that gVARLOGRule holds information for a case sensitive directory rewrite of: '/var/log' to the contents of variable gszVARLOGTo.

This variable is initialized in: strcpy(&gszVARLOGTo[0], getenv("LOGFILES")); where we fill it whith the contents of the environment variable 'LOGFILES' ( e.g. C:\VAR\LOG )

When called by LIBC the ecsInitPath functions gets 3 parameters, the first is only used here, which is a function pointer, this pointer is to a function which extends the path rewrite table and it takes a structure as described above as parameter.

this is how we call it:

Compiling
compiling is very easy, make sure you have GCC 3.3.5 CSD1 gcc -Zdll ecsprw.c ecsprw.def Of course this is a very easy example which we could easely extend with a administration program to maintain a database of which paths to rewrite.

Using pathrewrite in your executable
Pathrewrite functions can also be used inside your executable, without creating an external dll to handle them.

This allows you to access files (e.g. clamd.conf) in different places other than the hard-coded paths (e.g. /etc/clamd.conf), because many Unix programs have fixed names or coded when running then configure scripts, so they depend on user configuration.

Instead of modifying a lot of files, you can use __libc_PathRewriteAdd to modify your program behaviour. You need to create an array enough big to contain all your static redirection rules, fill the __LIBC_PATHREWRITE fields (either as static members or at runtime), and call __libc_PathRewriteAdd where the first parameter is the address of your array and the second parameter is the number of items in the array.

Call os2_init_paths as the first line of main and it will do the trick :-)