Pathrewrite
Appearance
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 ofcourse /etc.
Libc provides a interface to work around these problems without completely rewriting the application, and thus easying the maintenance for the porter.
In this article I'll try to outline the posibilities from what I used myself and will give a example.
First lets see what is documented inside the libc hooks.c file:
/** @page pg_hooks Hooks * * Presently this is a simple feature to load and call dlls as specified in * the LIBC_HOOK_DLLS environment variable. * * * @subsection LIBC_HOOK_DLLS * * The format is <dllname>@<export>[!<type>]. LIBC will load <dllname>, * resolve <export>and call <export> according to the convention of <type>. * Single of double quotes can be applied to the <dllname>. If multiple hooks * is desired, they shall be separated by the semicolon, space or tab character. * Failure to parse this variable, load dlls and resolve functions as specified * bye this variable will not prevent libc processes from starting. So, do NOT * count on it as a security measure. * * @subsubsection Types * * The default type is 'generic' and means that the libc module handle and * the address of __libc_Back_ldrSymbol will be passed. * * 'pathrewrite' is another type. The parameters here are the three * __libc_PathRewrite functions. The function should * * * @subsubsection Examples * * set LIBC_HOOK_DLLS=prwhome.dll@_instprws!pathrewrite * set LIBC_HOOK_DLLS=/usr/lib/prwhome.dll@_instprws!pathrewrite * set LIBC_HOOK_DLLS="c:\My Plugins\prwhome.dll"@_instprws!pathrewrite * set LIBC_HOOK_DLLS=prwhome@_insthomeprws!pathrewrite prwhome@_instetcprws!pathrewrite */
so we need to create a DLL which export a function that sets the rewritten paths.
Creating an example
So we want to creat 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.
- ecsprw.dll should be somewhere in the LIBPATH, lets put it in ecs\dll
- ecsprw.dll should export _ecsInitPath
The source files
ecsprw.def
LIBRARY ECSPRW EXPORTS _ecsInitPath
note: the DESCRIPTION tag comes later
ecsprw.c
#include <InnoTekLIBC/pathrewrite.h> #include <string.h> #include <stdio.h> #include <stdlib.h> char gszEtcTo[256]; char gszVARLOGTo[256]; char gszTMPTo[256]; __LIBC_PATHREWRITE gEtcRule = { __LIBC_PRWF_TYPE_DIR | __LIBC_PRWF_CASE_SENSITIVE, "/etc", 4, &gszEtcTo[0], 0 }; __LIBC_PATHREWRITE gTMPRule = { __LIBC_PRWF_TYPE_DIR | __LIBC_PRWF_CASE_SENSITIVE, "/tmp", 4, &gszTMPTo[0], 0 }; __LIBC_PATHREWRITE gVARLOGRule = { __LIBC_PRWF_TYPE_DIR | __LIBC_PRWF_CASE_SENSITIVE, "/var/log", 8, &gszVARLOGTo[0], 0 }; void ecsInitPath(int (*pfnAdd)(), int (*pfnRemove)(), int (*pfnRewrite)()); void ecsInitPath(int (*pfnAdd)(), int (*pfnRemove)(), int (*pfnRewrite)()) { int rcRet = 0; strcpy(&gszEtcTo[0], getenv("ETC")); strcpy(&gszVARLOGTo[0], getenv("LOGFILES")); strcpy(&gszTMPTo[0], getenv("TMP")); gEtcRule.cchTo = strlen(gEtcRule.pszTo); gVARLOGRule.cchTo = strlen(gVARLOGRule.pszTo); gTMPRule.cchTo = strlen(gTMPRule.pszTo); if ((*pfnAdd)(&gEtcRule, 1)) { rcRet++; } if ((*pfnAdd)(&gTMPRule, 1)) { rcRet++; } if ((*pfnAdd)(&gVARLOGRule, 1)) { rcRet++; } }