⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 log.c

📁 About: Paco (pacKAGE oRGANIZER) is a simple, yet powerful tool to aid package management when insta
💻 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 + -