#define _GNU_SOURCE
#include <config.h>
#include <dlfcn.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#define LOGNAME "FTRACELOGFILE"
#define IGNOREME "FTRACEIGNOREME"
static int logfd = -1;
static char *ignorepath = NULL;
static int (*real_truncate)(const char *, off_t);
static int (*real_creat)(const char *, mode_t);
static int (*real_open)(const char *, int, ...);
static int (*real_link)(const char *, const char *);
static int (*real_mkdir)(const char *, mode_t);
static int (*real_mknod)(const char *, mode_t, dev_t);
static int (*real_rename)(const char *, const char *);
static int (*real_symlink)(const char *, const char *);
#ifdef HAVE_OPEN64
static int (*real_open64)(const char *, int, ...);
static int (*real_creat64)(const char *, mode_t);
static int (*real_truncate64)(const char *, off64_t);
#endif /* HAVE_OPEN64 */
static void log_open(void)
{
char *x;
logfd = real_open(getenv(LOGNAME), O_WRONLY | O_CREAT | O_APPEND, 0666);
if (logfd == -1) {
perror("Can't open file trace log");
exit(EXIT_FAILURE);
}
x = getenv(IGNOREME);
if (x) {
ignorepath = malloc(strlen(x) + 1);
if (ignorepath) strcpy(ignorepath, x);
}
}
static void log(char *orig)
{
char real[MAXPATHLEN];
if (logfd == -1) log_open();
*real = 0;
if (*orig == '/') {
strcpy(real, orig);
} else {
getcwd(real, MAXPATHLEN);
strcat(real, "/");
strcat(real, orig);
}
/* ignore /tmp and /dev directories */
if (!strncmp("/tmp", real, 4)) return;
if (!strncmp("/dev", real, 4)) return;
if (ignorepath) {
if (!strncmp(ignorepath, real, strlen(ignorepath))) return;
}
strcat(real, "\n");
write(logfd, real, strlen(real));
}
void _init(void)
{
void *lib = NULL;
#if (defined(LINUX_GLIBC) || defined(SOLARIS_LIBC))
lib = RTLD_NEXT;
#else
lib = dlopen("/lib/libc.so.5", RTLD_LAZY);
#endif
real_truncate = dlsym(lib, "truncate");
real_creat = dlsym(lib, "creat");
real_open = dlsym(lib, "open");
real_mkdir = dlsym(lib, "mkdir");
real_mknod = dlsym(lib, "mknod");
real_rename = dlsym(lib, "rename");
real_link = dlsym(lib, "symlink");
real_symlink = dlsym(lib, "symlink");
#ifdef HAVE_OPEN64
real_creat64 = dlsym(lib, "creat64");
real_open64 = dlsym(lib, "open64");
real_truncate64 = dlsym(lib, "truncate64");
#endif /* HAVE_OPEN64 */
}
int truncate(const char *pathname, off_t length)
{
int ret;
ret = real_truncate(pathname, length);
if (ret == -1) return -1;
log((char *) pathname);
return ret;
}
int creat(const char *pathname, mode_t mode)
{
int ret;
ret = real_open(pathname, O_WRONLY | O_CREAT | O_TRUNC, mode);
if (ret == -1) return -1;
log((char *) pathname);
return ret;
}
int open(const char *pathname, int flags, ...)
{
va_list ap;
mode_t mode;
int ret;
va_start(ap, flags);
mode = va_arg(ap, int);
va_end(ap);
ret = real_open(pathname, flags, mode);
if (ret == -1) return -1;
if ((flags & O_WRONLY) || (flags & O_RDWR)) log((char *) pathname);
return ret;
}
int mkdir(const char *pathname, mode_t mode)
{
int ret;
ret = real_mkdir(pathname, mode);
if (ret) return ret;
log((char *) pathname);
return ret;
}
int mknod(const char *pathname, mode_t mode, dev_t dev)
{
int ret;
ret = real_mknod(pathname, mode, dev);
if (ret) return ret;
log((char *) pathname);
return ret;
}
int rename(const char *oldpath, const char *newpath)
{
int ret;
ret = real_rename(oldpath, newpath);
if (ret) return ret;
log((char *) newpath);
return ret;
}
int link(const char *oldpath, const char *newpath)
{
int ret;
ret = real_link(oldpath, newpath);
if (ret) return ret;
log((char *) newpath);
return ret;
}
int symlink(const char *oldpath, const char *newpath)
{
int ret;
ret = real_symlink(oldpath, newpath);
if (ret) return ret;
log((char *) newpath);
return ret;
}
/* 64bit versions of these functions */
#ifdef HAVE_OPEN64
int open64(const char *pathname, int flags, ...)
{
va_list ap;
mode_t mode;
int ret;
va_start(ap, flags);
mode = va_arg(ap, mode_t);
va_end(ap);
ret = real_open64(pathname, flags, mode);
if (ret == -1) return -1;
if (flags & O_CREAT) log((char *) pathname);
return ret;
}
int creat64(const char *pathname, mode_t mode)
{
int ret;
ret = real_open64(pathname, O_WRONLY | O_CREAT | O_TRUNC, mode);
if (ret == -1) return -1;
log((char *) pathname);
return ret;
}
int truncate64(const char *pathname, off64_t length)
{
int ret;
ret = real_truncate64(pathname, length);
if (ret == -1) return -1;
log((char *) pathname);
return ret;
}
#endif /* HAVE_OPEN64 */
syntax highlighted by Code2HTML, v. 0.9.1