?? log.c
字號:
/*********************************************************************** * log.c: Handles the system calls that create files and logs them. *********************************************************************** * This file is part of the package paco * Copyright (C) 2004-2006 David Rosal <david.3r@gmail.com> * For more information visit http://paco.sourceforge.net ***********************************************************************/#include "config.h"#include <dirent.h>#include <dlfcn.h>#include <fcntl.h> #include <stdarg.h>#include <unistd.h>#define __have_64__ (HAVE_OPEN64 && HAVE_CREAT64 && HAVE_TRUNCATE64 \ && HAVE_FOPEN64 && HAVE_FREOPEN64)#define CHECK_INIT do { \ if (!lp_tmpfile) lp_init(); \} while (0)#define PACO_BUFSIZE 4096static int (*libc_creat) (const char*, mode_t);static int (*libc_link) (const char*, const char*);static int (*libc_open) (const char*, int, ...);static int (*libc_rename) (const char*, const char*);static int (*libc_symlink) (const char*, const char*);static int (*libc_truncate) (const char*, off_t);static FILE*(*libc_fopen) (const char*, const char*);static FILE*(*libc_freopen) (const char*, const char*, FILE*);#if __have_64__static int (*libc_creat64) (const char*, mode_t);static int (*libc_open64) (const char*, int, ...);static int (*libc_truncate64) (const char*, off64_t);static FILE*(*libc_fopen64) (const char*, const char*);static FILE*(*libc_freopen64) (const char*, const char*, FILE*);#endif /* __have_64__ */static char* lp_tmpfile;static int lp_debug;static void lp_die(const char* fmt, ...){ va_list ap; fflush(stdout); fputs("libpaco-log: ", stderr); va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); putc('\n', stderr); exit(EXIT_FAILURE);}static void* lp_dlsym(const char* symbol){ void* ret; char* error; dlerror(); if (!(ret = dlsym(RTLD_NEXT, symbol))) { error = (char*)dlerror(); lp_die("dlsym(%p, \"%s\"): %s", RTLD_NEXT, symbol, error ? error : "failed"); } return ret;} static void lp_init(){ static char* dbg = NULL; /* handle libc */ libc_creat = lp_dlsym("creat"); libc_link = lp_dlsym("link"); libc_open = lp_dlsym("open"); libc_rename = lp_dlsym("rename"); libc_symlink = lp_dlsym("symlink"); libc_truncate = lp_dlsym("truncate"); libc_fopen = lp_dlsym("fopen"); libc_freopen = lp_dlsym("freopen");#if __have_64__ libc_open64 = lp_dlsym("open64"); libc_creat64 = lp_dlsym("creat64"); libc_truncate64 = lp_dlsym("truncate64"); libc_fopen64 = lp_dlsym("fopen64"); libc_freopen64 = lp_dlsym("freopen64");#endif /* __have_64__ */ /* read the environment */ if (!lp_tmpfile && !(lp_tmpfile = getenv("PACO_TMPFILE"))) lp_die("variable %s undefined", "PACO_TMPFILE"); \ if (!dbg && (dbg = getenv("PACO_DEBUG"))) lp_debug = !strcmp(dbg, "yes");}static void lp_log(const char* path, const char* fmt, ...){ static char abs_path[PACO_BUFSIZE]; va_list a; int fd, len, __errno = errno; if (!strcmp(path, "/dev/tty") || !strcmp(path, "/dev/null") || !strncmp(path, "/proc/", 6)) goto ____end; CHECK_INIT; if (lp_debug) { fflush(stdout); fprintf(stderr, "paco :: "); va_start(a, fmt); vfprintf(stderr, fmt, a); va_end(a); putc('\n', stderr); } /* "Absolutize" relative paths */ if (path[0] == '/') { strncpy(abs_path, path, PACO_BUFSIZE - 1); abs_path[PACO_BUFSIZE - 1] = '\0'; } else if (getcwd(abs_path, PACO_BUFSIZE)) { strncat(abs_path, "/", PACO_BUFSIZE - strlen(abs_path) - 1); strncat(abs_path, path, PACO_BUFSIZE - strlen(abs_path) - 1); } else snprintf(abs_path, PACO_BUFSIZE, "./%s", path); strncat(abs_path, "\n", PACO_BUFSIZE - strlen(abs_path) - 1); if ((fd = libc_open(lp_tmpfile, O_WRONLY | O_CREAT | O_APPEND, 0644)) < 0) lp_die("open(\"%s\"): %s", lp_tmpfile, strerror(errno)); len = strlen(abs_path); if (write(fd, abs_path, len) != len) lp_die("%s: write(): %s", lp_tmpfile, strerror(errno)); if (close(fd) < 0) lp_die("close(%d): %s", fd, strerror(errno)); ____end: errno = __errno;}/************************//* System call handlers *//************************/FILE* fopen(const char* path, const char* mode){ FILE* ret; CHECK_INIT; ret = libc_fopen(path, mode); if (ret && strpbrk(mode, "wa+")) lp_log(path, "fopen(\"%s\", \"%s\")", path, mode); return ret;}FILE* freopen(const char* path, const char* mode, FILE* stream){ FILE* ret; CHECK_INIT; ret = libc_freopen(path, mode, stream); if (ret && strpbrk(mode, "wa+")) lp_log(path, "freopen(\"%s\", \"%s\")", path, mode); return ret;}/* * If NEWBUF isn't a directory write it to the log, otherwise log files it and * its subdirectories contain. */static void log_rename(const char* oldpath, const char* newpath){ char oldbuf[PACO_BUFSIZE], newbuf[PACO_BUFSIZE]; struct stat st; DIR* dir; struct dirent* e; size_t oldlen, newlen; int __errno = errno; /* save global errno */ /* The NEWpath file doesn't exist. */ if (-1 == lstat(newpath, &st)) goto ____end; else if (!S_ISDIR(st.st_mode)) { /* NEWpath is a file or a symlink. */ lp_log(newpath, "rename(\"%s\", \"%s\")", oldpath, newpath); goto ____end; } /* Make sure we have enough space for the following slashes. */ oldlen = strlen(oldpath); newlen = strlen(newpath); if (oldlen + 2 >= PACO_BUFSIZE || newlen + 2 >= PACO_BUFSIZE) goto ____end; strcpy(oldbuf, oldpath); strcpy(newbuf, newpath); newbuf[PACO_BUFSIZE - 1] = oldbuf[PACO_BUFSIZE - 1] = '\0'; /* We can do this in the loop below, buf it's more efficient to do that once. These slashes will separate the path NEWBUF/OLDBUF contains from names of its files/subdirectories. */ oldbuf[oldlen++] = newbuf[newlen++] = '/'; oldbuf[oldlen] = newbuf[newlen] = '\0'; dir = opendir(newbuf); while ((e = readdir(dir))) { if (!strcmp(e->d_name, ".") || !strcmp(e->d_name, "..")) continue; strncat(oldbuf, e->d_name, PACO_BUFSIZE - oldlen - 1); strncat(newbuf, e->d_name, PACO_BUFSIZE - newlen - 1); log_rename(oldbuf, newbuf); oldbuf[oldlen] = newbuf[newlen] = '\0'; } closedir(dir);____end: /* Restore global errno */ errno = __errno;}int rename(const char* oldpath, const char* newpath){ int ret; CHECK_INIT; if ((ret = libc_rename(oldpath, newpath)) != -1) log_rename(oldpath, newpath); return ret;}int creat(const char* path, mode_t mode){ int ret; CHECK_INIT; ret = libc_open(path, O_CREAT | O_WRONLY | O_TRUNC, mode); if (ret != -1) lp_log(path, "creat(\"%s\", 0%o)", path, (int)mode); return ret;}int link(const char* oldpath, const char* newpath){ int ret; CHECK_INIT; ret = libc_link(oldpath, newpath); if (ret != -1) lp_log(newpath, "link(\"%s\", \"%s\")", oldpath, newpath); return ret;}int truncate(const char* path, off_t length){ int ret; CHECK_INIT; ret = libc_truncate(path, length); if (ret != -1) lp_log(path, "truncate(\"%s\", %d)", path, (int)length); return ret;}int open(const char* path, int flags, ...){ va_list a; mode_t mode; int accmode, ret; CHECK_INIT; va_start(a, flags); mode = va_arg(a, mode_t); va_end(a); ret = libc_open(path, flags, mode); accmode = flags & O_ACCMODE; if (ret != -1 && (accmode == O_WRONLY || accmode == O_RDWR)) lp_log(path, "open(\"%s\")", path); return ret;}int symlink(const char* oldpath, const char* newpath){ int ret; CHECK_INIT; ret = libc_symlink(oldpath, newpath); if (ret != -1) lp_log(newpath, "symlink(\"%s\", \"%s\")", oldpath, newpath); return ret;}#if __have_64__int creat64(const char* path, mode_t mode){ int ret; CHECK_INIT; ret = libc_open64(path, O_CREAT | O_WRONLY | O_TRUNC, mode); if (ret != -1) lp_log(path, "creat64(\"%s\")", path); return ret;}int open64(const char* path, int flags, ...){ va_list a; mode_t mode; int accmode, ret; CHECK_INIT; va_start(a, flags); mode = va_arg(a, mode_t); va_end(a); ret = libc_open64(path, flags, mode); accmode = flags & O_ACCMODE; if (ret != -1 && (accmode == O_WRONLY || accmode == O_RDWR)) lp_log(path, "open64(\"%s\")", path); return ret;}int truncate64(const char* path, off64_t length){ int ret; CHECK_INIT; ret = libc_truncate64(path, length); if (ret != -1) lp_log(path, "truncate64(\"%s\", %d)", path, (int)length); return ret;}FILE* fopen64(const char* path, const char* mode){ FILE* ret; CHECK_INIT; ret = libc_fopen64(path, mode); if (ret && strpbrk(mode, "wa+")) lp_log(path, "fopen64(\"%s\", \"%s\")", path, mode); return ret;}FILE* freopen64(const char* path, const char* mode, FILE* stream){ FILE* ret; CHECK_INIT; ret = libc_freopen64(path, mode, stream); if (ret && strpbrk(mode, "wa+")) lp_log(path, "freopen64(\"%s\", \"%s\")", path, mode); return ret;}#endif /* __have_64__ */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -