Main Page   Namespace List   Compound List   File List   Compound Members   File Members  

chm_dissect.cpp

Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #include <iostream>
00006 #include <cstdlib>
00007 #include <iterator>
00008 #include <algorithm>
00009 #include <list>
00010 
00011 #include <fstream>
00012 
00013 #include <sys/types.h>
00014 #include <sys/stat.h>
00015 
00016 #include <cerrno>
00017 #include <cstring>
00018 
00019 #include "chmxx.h"
00020 
00021 using namespace std;
00022 using namespace chm;
00023 
00024 namespace {
00025 
00026 void print_topics_tree (const chm_topics_tree *tree, int level = 0)
00027 {
00028   if ( level != 0 )
00029       cout << string(level * 4, ' ') << tree->title << endl;
00030 
00031   for_each (tree->children.begin(), tree->children.end(),
00032       bind2nd(ptr_fun(print_topics_tree), level + 1));
00033 }
00034 
00035 void error (const string& pname, const string& err = "") {
00036   if ( err == "" ) {
00037       cerr << pname << ": Usage: " << pname << " <file.chm> list|get|listall|export|stats|topics|index|indexall [<path|text>]" << endl;
00038   } else {
00039       cerr << pname << ": " << err << endl;
00040   }
00041   exit(1);
00042 }
00043 
00044 void do_export (const string& pname, const chmfile& chm, const string& root, const string& p)
00045 {
00046   if ( mkdir(root.c_str(), 0755) == -1 && errno != EEXIST)
00047       error (pname, string() + "Unable to create the target directory [" + root + "]: " + strerror(errno));
00048 
00049   list<string> dirs;
00050   chm.readdir(p, dirs, chmfile::dirs);
00051 
00052   list<string> files;
00053   chm.readdir(p, files, chmfile::files);
00054 
00055   for ( list<string>::iterator it = dirs.begin(); it != dirs.end(); it++ ) {
00056       do_export (pname, chm, root + *it, p + *it);
00057   }
00058 
00059   for ( list<string>::iterator it = files.begin(); it != files.end(); it++ ) {
00060       string path = root + *it;
00061       ofstream out(path.c_str());
00062       if ( !out )
00063           error (pname, string() + "Unable to open export file for writing: " + strerror (errno));
00064       chm.read (p + *it, out);
00065       out.close();
00066   }
00067 }
00068 
00069 void list_all (const string& pname, const chmfile& chm, const string& root = "/")
00070 {
00071   list<string> l;
00072   chm.readdir (root, l);
00073   for (list<string>::iterator it = l.begin(); it != l.end(); it++ ) {
00074       string& n = *it;
00075       cout << root << n << endl;
00076       if ( n[n.size()-1] == '/' ) list_all (pname, chm, root + n);
00077   }
00078 }
00079 
00080 }
00081 
00082 int main(int argc, char *argv[])
00083 {
00084   if ( argc < 3 ) error(argv[0]);
00085 
00086   chmfile chm(argv[1]);
00087   if ( !chm ) error (argv[0], "Invalid chm file");
00088 
00089   string cmd = argv[2];
00090 
00091   if (  cmd == "list" ) {
00092       if ( argc != 4 ) error(argv[0]);
00093       list<string> dc;
00094       chm.readdir (argv[3], dc);
00095       ostream_iterator<string> out(cout, "\n");
00096       copy(dc.begin(), dc.end(), out);
00097       return 0;
00098   } else if ( cmd == "get" ) {
00099       if ( argc != 4 ) error(argv[0]);
00100       streambuf *sb = chm.open(argv[3]);
00101       if ( !sb )
00102           error (argv[0], "Could not find given path inside the archive");
00103       cout << sb;
00104       delete sb;
00105       return 0;
00106   } else if ( cmd == "listall" ) {
00107       list_all (argv[0], chm);
00108       return 0;
00109   } else if ( cmd == "stats" ) {
00110       cout << "---Statistics---" << endl;
00111       cout << "     Title: " << chm.get_title() << endl;
00112       cout << " Generator: " << chm.get_generator() << endl;
00113       cout << "      Home: " << chm.get_home_file() << endl;
00114       cout << "    Topics: " << chm.get_topics_file() << endl;
00115       cout << "     Index: " << chm.get_index_file() << endl;
00116       return 0;
00117   } else if ( cmd == "topics" ) {
00118       if ( chm.get_topics_tree() ) {
00119           cout << "Topics tree:" << endl;
00120           print_topics_tree (chm.get_topics_tree());
00121       } else {
00122           cout << "No topics tree found" << endl;
00123       }
00124       return 0;
00125   } else if ( cmd == "export" ) {
00126       if ( argc != 4 ) error(argv[0]);
00127       cout << "Exporting.." << endl;
00128       string w = argv[3];
00129       if ( !w.empty() && w[w.size() - 1] != '/' ) w += '/';
00130       do_export (argv[0], chm, w, "/");
00131       return 0;
00132   } else if ( cmd == "index" ) {
00133       if ( argc != 4 ) error(argv[0]);
00134 
00135       list<chm_search_match> f;
00136       chm.cache_search_database();
00137       chm.search_index(argv[3], f);
00138 
00139       for ( list<chm_search_match>::iterator it = f.begin(); it != f.end(); it++ )
00140           for ( size_t i = 0; i < it->documents.size(); i++ )
00141               cout << it->key << "|" << it->is_title << "|" << it->documents[i].offsets.size() << "|"
00142                   << it->documents[i].path << "|" << it->documents[i].title << endl;
00143 
00144       return 0;
00145   } else if ( cmd == "indexall" ) {
00146       if ( argc != 4 ) error(argv[0]);
00147 
00148       list<chm_search_match> f;
00149       chm.cache_search_database();
00150       chm.search_index(argv[3], f, false, false);
00151 
00152       for ( list<chm_search_match>::iterator it = f.begin(); it != f.end(); it++ )
00153           for ( size_t i = 0; i < it->documents.size(); i++ )
00154               cout << it->key << "|" << it->is_title << "|" << it->documents[i].offsets.size() << "|"
00155                   << it->documents[i].path << "|" << it->documents[i].title << endl;
00156 
00157       return 0;
00158   }
00159 
00160   error (argv[0], "Invalid second argument");
00161 }

Copyright © 2003 Indrek Mandre