From: Jan-Pascal van Best Date: Mon, 29 Aug 2011 07:07:46 +0000 (+0200) Subject: Initial commit X-Git-Tag: 0.1~3 X-Git-Url: http://www.vanbest.org/gitweb/?a=commitdiff_plain;h=8121d85751ea2fa0479595be24d5e3a4cfe1d10e;p=backupusage.git Initial commit --- 8121d85751ea2fa0479595be24d5e3a4cfe1d10e diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6dd1022 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +backupusage diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b8c673d --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ +# Dependencies: +# libboost-filesystem.dev +# libboost-regex-dev +# libboost-program-options-dev + +LIBS=-lboost_program_options -lboost_filesystem -lboost_regex + +all: backupusage + +test: backupusage + ./backupusage --limit=1000000 > result.txt + +backupusage: backupusage.cc + g++ $(LIBS) $^ -o $@ diff --git a/backupusage.cc b/backupusage.cc new file mode 100644 index 0000000..2143ce0 --- /dev/null +++ b/backupusage.cc @@ -0,0 +1,117 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace boost::filesystem; +using namespace boost::algorithm; + +namespace po = boost::program_options; + +set inodes; +map dirs; + +boost::regex prefix_re; + +path strip_path( const path& dir ) { + return erase_regex_copy(dir.string(), prefix_re ); +} + +string ToHumanReadable(long x) +{ + //CONSTANTS FOR SIZING + double KB = 1024; + double MB = 1024 * KB; + double GB = 1024 * MB; + + if (x < KB) + return (boost::format("%6d") % x).str(); + else if (x < MB) + { + return (boost::format("%6.1fkB") % (x / KB)).str(); + } + else if (x < GB) + { + return (boost::format("%6.1fMB") % (x / MB)).str(); + } + else if (x >= GB) + { + return (boost::format("%6.1fGB") % (x / GB)).str(); + } +} + + +void handle_file( const path& dir, const path& p ) { + struct stat buf; + if ( lstat(p.string().c_str(), &buf )) { + cout << "error" << endl; + } else { + // cout << "inode: " << buf.st_ino << "; size: " << buf.st_size << endl; + if (inodes.find( buf.st_ino ) == inodes.end() ) { + inodes.insert( buf.st_ino ); + dirs[strip_path(dir)] += buf.st_size; + // cout << "New inode, size of " << strip_path(dir) << " is now " << dirs[strip_path(dir)] << endl; + } else { + // cout << "Old inode" << endl; + } + } +} + +void handle_dir( const path& dir ) { + // cout << dir << endl; + if ( dirs.find(strip_path(dir)) == dirs.end() ) { + dirs[strip_path(dir)] = 0; + } + directory_iterator i(dir), dir_end; + for(;i!= dir_end; ++i) { + if ( is_directory( *i ) ) { + handle_dir( *i ); + } else { + handle_file( dir, *i ); + } + } +} + +int main( int argc, char** argv ) { + string start_dir; + string prefix; + long size_limit; + + // Declare the supported options. + po::options_description desc("Allowed options"); + desc.add_options() + ("help", "produce help message") + ("start-dir,s", po::value(&start_dir)->default_value("/var/lib/backuppc/pc/nogrod"), "Starting directory") + ("prefix,p", po::value(&prefix)->default_value("/var/lib/backuppc/pc/nogrod/[0-9]*/(f%2f|f)"), "Prefix to remove for counting (regular expression)") + ("limit,l", po::value(&size_limit)->default_value(1), "Minimal directory size to show") + ; + + po::variables_map vm; + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) { + cout << desc << "\n"; + return 1; + } + + prefix_re = boost::regex(prefix); + + handle_dir( start_dir ); + + + map result; + for( map::const_iterator i = dirs.begin(); i != dirs.end(); ++i ) { + if ( i->second >= size_limit ) result[i->second] = i->first; + } + for( map::const_iterator i = result.begin(); i != result.end(); ++i ) { + cout << ToHumanReadable(i->first) << " (" << i->first << ") " << i->second << endl; + } +}