Index: nkvd.c ================================================================== --- nkvd.c +++ nkvd.c @@ -168,11 +168,12 @@ static const char* redir_to; static size_t redir_len; static const char* hq; static size_t hq_len; -void configdirs() { +static void +configdirs() { const char* nkvd = getenv("nkvd_gulag"); if (nkvd != NULL) redir_to = nkvd, redir_len = strlen(nkvd); const char* xdg = getenv("XDG_CONFIG_HOME"); if (xdg != NULL) redir_to = xdg, redir_len = strlen(xdg); @@ -210,11 +211,12 @@ # undef CONFDIR redir_to = buf; } -bool checkpath(const char* path, size_t len, char* gulag) { +static bool +checkpath(const char* path, size_t len, char* gulag) { char c[hq_len + len + 4]; strncpy(c, hq, hq_len); c[hq_len] = '/'; c[hq_len+1] = '.'; c[hq_len+2] = 0; @@ -241,11 +243,12 @@ /* no further questions, citizen */ return false; } } -bool interrogate(const char* path, size_t plen, char* gulag) { +static bool +interrogate(const char* path, size_t plen, char* gulag) { /* papers, please */ if (path[0] != '/') for (size_t i = 64; i (b) ? (a) : (b)) +int rename(const char* volatile from, + const char* volatile to) { + if (intercept) { + const size_t fromlen = strlen(from), + tolen = strlen(from); + char fromgulag[redir_len + tolen ], + togulag[redir_len + fromlen]; + + const char* fromfinal, + * tofinal; + + if (interrogate(from, fromlen, fromgulag)) + fromfinal = fromgulag; + else fromfinal = from; + + if (interrogate(to, tolen, togulag)) + tofinal = togulag; + else tofinal = to; + + return (*libc_rename)(fromfinal,tofinal); + } + + return (*libc_rename)(from,to); +}; int open(const char* volatile path, int flags, ...) { /* fuck you for using varargs, asshole */ va_list v; va_start(v,flags); mode_t m; @@ -386,10 +440,11 @@ } } return (*libc_open)(path, flags, m); } +#include int nkvd_init(int argc, const char** argv) { wiretap_argc = argc; wiretap_argv = argv; # ifndef _USE_RTLD_NEXT @@ -402,18 +457,25 @@ "compile command line."); # endif # define load_fn(fn,pfx) libc_##fn = dlsym(SYMSRC, #pfx #fn) load_fn(open,); load_fn(unlink,); + load_fn(access,); load_fn(eaccess,); + load_fn(rename,); load_fn(stat,); load_fn(lstat,); load_fn(stat64,); load_fn(lstat64,); # ifndef _NO_GNU load_fn(xstat,__); load_fn(lxstat,__); load_fn(xstat64,__); load_fn(lxstat64,__); # endif # undef load_fn +# define dump(v) printf("-- " #v ": %p", libc_##v) + dump(lstat); + dump(lstat64); + dump(lxstat); + dump(lxstat64); /* have enough stat fns been found for us to proceed? */ bool statfns = ( (libc_stat && libc_lstat) || (libc_stat64 && libc_lstat64) #ifndef _NO_GNU @@ -420,11 +482,12 @@ || (libc_xstat && libc_lxstat) || (libc_xstat64 && libc_lxstat64) #endif ); - if (! (libc_open && statfns && libc_unlink)) + if (! (libc_open && statfns && libc_unlink && + libc_access && libc_eaccess && libc_rename)) fail(-3, "your libc is defective. bailing."); intercept = shitlist(argv[0]); if (intercept) { configdirs();