+#include <string>
+#include <vector>
#include <set>
#include <map>
-#include <string>
#include <iostream>
#include <sys/stat.h>
#include <boost/filesystem.hpp>
-#include <boost/algorithm/string/regex.hpp>
#include <boost/regex.hpp>
#include <boost/format.hpp>
#include <boost/program_options.hpp>
+#include <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/algorithm/string.hpp>
+
+#include "spacecounter.hh"
using namespace std;
using namespace boost::filesystem;
namespace po = boost::program_options;
-set<ino_t> inodes;
-map<path,long> dirs;
+//set<ino_t> inodes;
+//map<path,long> dirs;
-boost::regex prefix_re;
-
-path strip_path( const path& dir ) {
- return erase_regex_copy(dir.string(), prefix_re );
-}
+// boost::regex prefix_re;
string ToHumanReadable(long x)
{
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 start_dir;
+ string base_dir;
string prefix;
+ string pc_list;
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<string>(&start_dir)->default_value("/var/lib/backuppc/pc/nogrod"), "Starting directory")
- ("prefix,p", po::value<string>(&prefix)->default_value("/var/lib/backuppc/pc/nogrod/[0-9]*/(f%2f|f)"), "Prefix to remove for counting (regular expression)")
+ ("base-dir,d", po::value<string>(&base_dir)->default_value("/var/lib/backuppc/pc/"), "Base directory for BackupPC backup hardlinks")
+ ("pc,p", po::value<string>(&pc_list)->default_value("all"), "Comma-separated list of BackupPC hosts ('all': all hosts)")
+// ("start-dir,s", po::value<string>(&start_dir)->default_value("/var/lib/backuppc/pc/nogrod"), "Starting directory")
+ ("prefix,p", po::value<string>(&prefix)->default_value("/var/lib/backuppc/pc/[0-9a-zA-Z_]*/[0-9]*/(f%2f|f)"), "Prefix to remove for counting (regular expression)")
("limit,l", po::value<long>(&size_limit)->default_value(1), "Minimal directory size to show")
;
return 1;
}
- prefix_re = boost::regex(prefix);
-
- handle_dir( start_dir );
+// prefix_re = boost::regex(prefix);
+ vector<string> pc_list_split;
+ split( pc_list_split, pc_list, boost::is_any_of(","), token_compress_on );
- map<long,path> result;
- for( map<path,long>::const_iterator i = dirs.begin(); i != dirs.end(); ++i ) {
- if ( i->second >= size_limit ) result[i->second] = i->first;
+ spacecounter counter = spacecounter(boost::regex(prefix));
+ for (vector<string>::const_iterator i = pc_list_split.begin(); i != pc_list_split.end(); ++i ) {
+ cout << "Examining PC " << *i << endl;
+ counter.handle_dir( path(base_dir) / *i );
}
+
+ map<long,path> result = counter.get_result( size_limit );
+
for( map<long,path>::const_iterator i = result.begin(); i != result.end(); ++i ) {
cout << ToHumanReadable(i->first) << " (" << i->first << ") " << i->second << endl;
}
--- /dev/null
+#include <string>
+#include <vector>
+#include <set>
+#include <map>
+#include <iostream>
+#include <sys/stat.h>
+#include <boost/filesystem.hpp>
+#include <boost/algorithm/string/regex.hpp>
+#include <boost/regex.hpp>
+#include <boost/format.hpp>
+#include <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/algorithm/string.hpp>
+
+#include "spacecounter.hh"
+
+using namespace std;
+using namespace boost::filesystem;
+using namespace boost::algorithm;
+
+spacecounter::spacecounter( boost::regex a_prefix_re ) {
+ prefix_re = a_prefix_re;
+}
+
+path spacecounter::strip_path( const path& dir ) {
+ return erase_regex_copy(dir.string(), prefix_re );
+}
+
+void spacecounter::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 spacecounter::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 );
+ }
+ }
+}
+
+map<long,path> spacecounter::get_result( long size_limit ) {
+ map<long,path> result;
+ for( map<path,long>::const_iterator i = dirs.begin(); i != dirs.end(); ++i ) {
+ if ( i->second >= size_limit ) result[i->second] = i->first;
+ }
+ return result;
+}
+