btardump.cc

00001 ///
00002 /// \file       tardump.cc
00003 ///             Utility to dump tarball backup records to stdout.
00004 ///
00005 
00006 /*
00007     Copyright (C) 2010-2011, Net Direct Inc. (http://www.netdirect.ca/)
00008 
00009     This program is free software; you can redistribute it and/or modify
00010     it under the terms of the GNU General Public License as published by
00011     the Free Software Foundation; either version 2 of the License, or
00012     (at your option) any later version.
00013 
00014     This program is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00017 
00018     See the GNU General Public License in the COPYING file at the
00019     root directory of this project for more details.
00020 */
00021 
00022 #include <barry/barry.h>
00023 #ifdef __BARRY_SYNC_MODE__
00024 #include <barry/barrysync.h>
00025 #include "mimedump.h"
00026 #endif
00027 #include <barry/barrybackup.h>
00028 #include <iostream>
00029 #include <iomanip>
00030 #include <getopt.h>
00031 
00032 using namespace std;
00033 using namespace Barry;
00034 
00035 void Usage()
00036 {
00037    int major, minor;
00038    const char *Version = Barry::Version(major, minor);
00039 
00040    cerr
00041    << "btardump - Command line parser for Barry backup files\n"
00042    << "           Copyright 2010-2011, Net Direct Inc. (http://www.netdirect.ca/)\n"
00043    << "           Using: " << Version << "\n"
00044    << "\n"
00045    << "   -d db     Name of database to dump.  Can be used multiple times\n"
00046    << "             to parse multiple databases at once.  If not specified\n"
00047    << "             at all, all available databases from the backup are\n"
00048    << "             dumped.\n"
00049    << "   -h        This help\n"
00050    << "   -i cs     International charset for string conversions\n"
00051    << "             Valid values here are available with 'iconv --list'\n"
00052 #ifdef __BARRY_SYNC_MODE__
00053    << "   -V        Dump records using MIME vformats where possible\n"
00054 #endif
00055    << "\n"
00056    << "   [files...] Backup file(s), created by btool or the backup GUI.\n"
00057    << endl;
00058 }
00059 
00060 class MyAllRecordDumpStore : public AllRecordStore
00061 {
00062         bool m_vformat_mode;
00063         std::ostream &m_os;
00064 
00065 public:
00066         explicit MyAllRecordDumpStore(std::ostream &os, bool vformat_mode=false)
00067                 : m_vformat_mode(vformat_mode)
00068                 , m_os(os)
00069         {
00070         }
00071 
00072 #undef HANDLE_PARSER
00073 #define HANDLE_PARSER(tname) \
00074         void operator() (const Barry::tname &r) \
00075         { \
00076                 if( m_vformat_mode ) \
00077                         MimeDump<tname>::Dump(m_os, r); \
00078                 else \
00079                         m_os << r << std::endl; \
00080         }
00081 
00082         ALL_KNOWN_PARSER_TYPES
00083 };
00084 
00085 int main(int argc, char *argv[])
00086 {
00087         try {
00088                 bool vformat_mode = false;
00089 
00090                 vector<string> db_names;
00091                 vector<string> backup_files;
00092                 string iconvCharset;
00093 
00094                 // process command line options
00095                 for(;;) {
00096                         int cmd = getopt(argc, argv, "d:hi:V");
00097                         if( cmd == -1 )
00098                                 break;
00099 
00100                         switch( cmd )
00101                         {
00102                         case 'd':       // show dbname
00103                                 db_names.push_back(string(optarg));
00104                                 break;
00105 
00106                         case 'V':       // vformat MIME mode
00107 #ifdef __BARRY_SYNC_MODE__
00108                                 vformat_mode = true;
00109 #else
00110                                 cerr << "-V option not supported - no Sync "
00111                                         "library support available\n";
00112                                 return 1;
00113 #endif
00114                                 break;
00115 
00116                         case 'i':       // international charset (iconv)
00117                                 iconvCharset = optarg;
00118                                 break;
00119 
00120                         case 'h':       // help
00121                         default:
00122                                 Usage();
00123                                 return 0;
00124                         }
00125                 }
00126 
00127                 // grab all backup filenames
00128                 while( optind < argc ) {
00129                         backup_files.push_back(string(argv[optind++]));
00130                 }
00131 
00132                 if( backup_files.size() == 0 ) {
00133                         Usage();
00134                         return 0;
00135                 }
00136 
00137 
00138 
00139                 Barry::Init();
00140 
00141                 // Create an IConverter object if needed
00142                 auto_ptr<IConverter> ic;
00143                 if( iconvCharset.size() ) {
00144                         ic.reset( new IConverter(iconvCharset.c_str(), true) );
00145                 }
00146 
00147                 // create the parser, and use stdout dump objects for output
00148                 AllRecordParser parser(cout,
00149                         new HexDumpParser(cout),
00150                         new MyAllRecordDumpStore(cout, vformat_mode));
00151 
00152                 for( size_t i = 0; i < backup_files.size(); i++ ) {
00153 
00154                         cout << "Reading file: " << backup_files[i] << endl;
00155 
00156                         Restore builder(backup_files[i]);
00157 
00158                         // add desired database names
00159                         for( size_t j = 0; j < db_names.size(); j++ ) {
00160                                 builder.AddDB(db_names[i]);
00161                         }
00162 
00163                         // create the pipe to connect builder to parser and
00164                         // move the data
00165                         Pipe pipe(builder);
00166                         pipe.PumpFile(parser, ic.get());
00167                 }
00168 
00169         }
00170         catch( exception &e ) {
00171                 cerr << e.what() << endl;
00172                 return 1;
00173         }
00174 
00175         return 0;
00176 }
00177