#define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #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 */