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

📄 log.cc

📁 About: Paco (pacKAGE oRGANIZER) is a simple, yet powerful tool to aid package management when insta
💻 CC
字号:
//=======================================================================// Log.cc//-----------------------------------------------------------------------// This file is part of the package paco// Copyright (C) 2004-2007 David Rosal <david.3r@gmail.com>// For more information visit http://paco.sourceforge.net//=======================================================================#include "config.h"#include "global.h"#include "PkgSet.h"#include "Pkg.h"#include "Log.h"#include "LogInfo.h"#include <fstream>#include <sstream>#include <iostream>#include <iterator>#include <algorithm>#include <glob.h>using namespace Paco;using namespace std;// Forward declarationsstatic string searchLibpaco();static void setEnv(char const* var, string const& val);static string getTmpName();static string stripSuffix(string const&);static bool isNotValidPath(string const&);Log::Log(Options const& opt):	mOpt(opt),	mAppend(opt.append()),	mPkgName(opt.logPkg()),	mTmpFile(),	mFiles(){	if (opt.args().size())		fromCmd();	else		fromStdin();	if (mFiles.empty())		return;	filterFiles();	if (mPkgName.size())		toPkg();	else		toStream(cout);}Log::~Log(){	unlink(mTmpFile.c_str());	rmdir(Config::logdir().c_str());}// [static]void Log::run(Options const& opt){	static Log log(opt);}void Log::fromStdin(){	getFilesFromStream(cin);}void Log::toStream(ostream& s){	copy(mFiles.begin(), mFiles.end(), ostream_iterator<string>(s, "\n"));}void Log::getFilesFromStream(istream& f){	vector<string> x;	remove_copy_if(istream_iterator<string>(f), istream_iterator<string>(),		back_inserter(x), isNotValidPath);	transform(x.begin(), x.end(), inserter(mFiles, mFiles.begin()), realDir);}void Log::fromCmd(){	mTmpFile = getTmpName();	pid_t pid = fork();	if (pid == 0) { // child		string command;		string libpaco = searchLibpaco();				for (uint i = 0; i < mOpt.args().size(); ++i)			command += mOpt.args()[i] + " ";				setEnv("PACO_TMPFILE", mTmpFile);		setEnv("LD_PRELOAD", libpaco);		setEnv("PACO_DEBUG", gOut.verbosity() > Out::VERBOSE ? "yes" : "");		gOut.dbgTitle("settings");		gOut.dbg("TMPFILE=" + mTmpFile + "\n"); 		gOut.dbg("INCLUDE=" + mOpt.include() + "\n"); 		gOut.dbg("EXCLUDE=" + mOpt.exclude() + "\n"); 		gOut.dbg("IGNORE_ERRORS=" + string(mOpt.logIgnoreErrors() ? "1" : "0")			+ "\n");		gOut.dbg("IGNORE_SHARED=" + string(mOpt.logIgnoreShared() ? "1" : "0")			+ "\n");		gOut.dbg("LD_PRELOAD=" + libpaco + "\n"); 		gOut.dbg("command: " + command + "\n");		gOut.dbgTitle("libpaco-log");		char* cmd[] = { "sh", "-c", const_cast<char*>(command.c_str()), NULL };		execv("/bin/sh", cmd);		throw XErrno("execv()");	}	else if (pid == -1)		throw XErrno("fork()");	int status;	waitpid(pid, &status, 0);		if (!WIFEXITED(status))		gExitStatus = EXIT_FAILURE_EXTERNAL;	else		gExitStatus = WEXITSTATUS(status);	if (!mOpt.logIgnoreErrors() && gExitStatus != EXIT_SUCCESS)		exit(gExitStatus);		FileStream<ifstream> f(mTmpFile);	getFilesFromStream(f);}void Log::appendPkgFiles(){	Pkg old(mPkgName);	old.getFiles();	for (Pkg::iterator p = old.begin(); p != old.end(); ++p)		mFiles.insert(stripSuffix((*p)->name()));}void Log::filterFiles(){	Out::Silencer* s = mPkgName.empty() ? new Out::Silencer() : NULL;	vector<string> x;		remove_copy_if(mFiles.begin(), mFiles.end(), back_inserter(x),		Excluder(*this));	gOut.dbgTitle("logged files");	mFiles.clear();		if (mPkgName.empty())		copy(x.begin(), x.end(), inserter(mFiles, mFiles.begin()));	else {		transform(x.begin(), x.end(), inserter(mFiles, mFiles.begin()),			stripSuffix);	}	delete s;}void Log::writeFiles(string const& logFile){	vector<string> head;	FileStream<ifstream> fi(logFile);	string buf;	while (getline(fi, buf) && buf[0] == '#')		head.push_back(buf);	fi.close();	assert(head.empty() == false);	FileStream<ofstream> fo(logFile);	copy(head.begin(), head.end(), ostream_iterator<string>(fo, "\n"));	copy(mFiles.begin(), mFiles.end(), ostream_iterator<string>(fo, "\n"));}void Log::toPkg(){	assert(!mPkgName.empty());	if (mFiles.empty()) {		if (!mAppend) {			gOut.dbg("Package not logged (no files)\n");			gOut.dbgTitle("");		}		return;	}	if (mAppend) {		try 		{ appendPkgFiles(); }		catch (...)	{ mAppend = false; }	}	if (!mAppend) {		mkdir(Config::logdir().c_str(), 0755);		LogInfo info(*this);	}		string const logFile(Config::logdir() + "/" + mPkgName);		writeFiles(logFile);	if (!Pkg::updateLog(logFile))		gOut.dbg("Package not logged\n");	else if (gOut.verbosity() == Out::VERBOSE)		toStream(cerr);}//---------------//// Log::Excluder ////---------------//Log::Excluder::Excluder(Log const& log):	mInclude(log.mOpt.include()),	mExclude(log.mOpt.exclude()),	mLogMissing(log.mOpt.logMissing()),	mIgnoreShared(log.mOpt.logIgnoreShared()),	mPkgSet(),	mCnt(0){	if (mIgnoreShared) {		mPkgSet.getAllPkgs();		mPkgSet.getFiles();	}}bool Log::Excluder::isShared(string const& path){	for (PkgSet::iterator p = mPkgSet.begin(); p != mPkgSet.end(); ++p) {		if ((*p)->hasFile(path))			return true;	}	return false;}void Log::Excluder::logDebug(string const& msg){	if (!mCnt++)		gOut.dbgTitle("excluded files");	gOut.dbg(msg);}bool Log::Excluder::operator()(string const& path){	struct stat s;	bool ret = true;	if (inPaths(path, mExclude) || !inPaths(path, mInclude))		logDebug(path + "\n");		// non-existent files	else if (lstat(path.c_str(), &s) < 0) {		if (mLogMissing)			ret = false;		else			logDebug(path + " (missing)\n");	}	// skip directories	else if (UNLIKELY(S_ISDIR(s.st_mode)))		logDebug(path + " (directory)\n");	else if (mIgnoreShared && isShared(path))		logDebug(path + " (shared)\n");	else		ret = false;	return ret;}//-------------------//// Static free funcs ////-------------------//static bool isNotValidPath(string const& path){	return UNLIKELY(path[0] == '#');}static string stripSuffix(string const& mPath){	string path(mPath);	string::size_type p;	if ((p = path.rfind(".bz2")) == path.size() - 4	||	(p = path.rfind(".gz")) == path.size() - 3)		path.erase(p);	gOut.dbg(path + "\n");	return path;}//// Search for libpaco-log.so in the filesystem.// Take into account libpaco-log.so.0.1.0, libpaco-log.so.0.0 and so.//static string searchLibpaco(){	string libpath(LIBDIR "/libpaco-log.so");	struct stat s;		if (!stat(libpath.c_str(), &s))		return libpath;		glob_t g;	memset(&g, 0, sizeof(g));		if (!glob(LIBDIR "/libpaco-log.so.[0-9]*", GLOB_NOSORT,0, &g) && g.gl_pathc)		libpath = g.gl_pathv[0];		globfree(&g);		return libpath;}static void setEnv(char const* var, string const& val){#if HAVE_SETENV	if (setenv(var, val.c_str(), 1) < 0)		throw XErrno(string("setenv(") + var + ", " + val + ", 1)");#else	string str(var + "=" + val);	if (putenv(str.c_str()) < 0)		throw XErrno("putenv(" + str + ")");#endif}static string getTmpName(){	char* tmpFile = getenv("PACO_TMPFILE");	if (tmpFile)		return tmpFile;	char* tmpDir = getenv("TMPDIR");	char name[4096];	snprintf(name, sizeof(name), "%s/pacoXXXXXX", tmpDir ? tmpDir : "/tmp");		int fd = mkstemp(name);	if (fd > 0) {		fchmod(fd, 0644);		close(fd);	}	else		snprintf(name, sizeof(name), "/tmp/paco%d", getpid());	return name;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -