#include<stdarg.h>
#include<dlfcn.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<limits.h>
#include<unistd.h>
#include<lua.h>
#include<lualib.h>
#include<lauxlib.h>
static
int
lib_initialized = 0;
static
int
(*orig_open)(
const
char
*,
int
, mode_t) = 0;
static
int
(*orig_open64)(
const
char
*,
int
, mode_t) = 0;
static
int
(*orig_creat)(
const
char
*, mode_t) = 0;
static
lua_State *L = NULL;
void
lib_init();
void
die(
char
*fmt, ...) {
va_list
args;
va_start
(args, fmt);
vfprintf
(stderr, fmt, args);
va_end
(args);
fprintf
(stderr,
"\n"
);
fflush
(stderr);
exit
(-1);
}
static
char
* redirect(
const
char
* file){
int
ret;
const
char
*
new
;
lua_getglobal(L,
"redirect"
);
lua_pushstring(L, file);
ret = lua_pcall(L, 1, 1, 0);
if
(ret){
fprintf
(stderr,
"取得重定向文件路径时出错了: %s\n"
, lua_tostring(L, -1));
lua_pop(L, 1);
return
(
char
*)file;
}
else
{
new
= lua_tostring(L, -1);
lua_pop(L, 1);
}
return
(
char
*)
new
;
}
int
open(
const
char
* file,
int
flags, mode_t mode) {
lib_init();
file = redirect(file);
return
orig_open(file, flags, mode);
}
int
open64(
const
char
* file,
int
flags, mode_t mode) {
lib_init();
file = redirect(file);
return
orig_open64(file, flags, mode);
}
int
creat(
const
char
* file, mode_t mode) {
lib_init();
file = redirect(file);
return
orig_creat(file, mode);
}
void
lib_init() {
void
*libhdl;
char
*dlerr;
if
(lib_initialized)
return
;
if
(!(libhdl=dlopen(
"libc.so.6"
, RTLD_LAZY)))
die(
"Failed to patch library calls: %s"
, dlerror());
orig_open = dlsym(libhdl,
"open"
);
if
((dlerr=dlerror()) != NULL)
die(
"Failed to patch open() library call: %s"
, dlerr);
orig_open64 = dlsym(libhdl,
"open64"
);
if
((dlerr=dlerror()) != NULL)
die(
"Failed to patch open64() library call: %s"
, dlerr);
orig_creat = dlsym(libhdl,
"creat"
);
if
((dlerr=dlerror()) != NULL)
die(
"Failed to patch creat() library call: %s"
, dlerr);
int
ret;
L = luaL_newstate();
luaL_openlibs(L);
char
config[PATH_MAX];
strcpy
(config,
getenv
(
"HOME"
));
strcat
(config,
"/.openredir.lua"
);
ret = luaL_dofile(L, config);
if
(ret){
die(
"Error run ~/.openredir.lua"
);
}
lua_getglobal(L,
"redirect"
);
if
(!lua_isfunction(L,-1)){
die(
"Error run 'redirect' function in openredir.lua"
);
}
lua_pop(L, 1);
lib_initialized = 1;
}