* New upstream release.
[debian/mimetic.git] / examples / buildidx.cxx
1 /***************************************************************************
2     copyright            : (C) 2002-2005 by Stefano Barbato
3     email                : stefano@codesink.org
4
5     $Id: buildidx.cxx,v 1.2 2005/02/23 10:26:14 tat Exp $
6  ***************************************************************************/
7
8 /***************************************************************************
9  *                                                                         *
10  *   This program is free software; you can redistribute it and/or modify  *
11  *   it under the terms of the GNU General Public License as published by  *
12  *   the Free Software Foundation; either version 2 of the License, or     *
13  *   (at your option) any later version.                                   *
14  *                                                                         *
15  ***************************************************************************/
16 /** \example buildidx.cc
17  *  extract a Part based on command line parameters
18  *  more info on:
19  *      buildidx -h
20  */ 
21 #include <iostream>
22 #include <sstream>
23 #include <iterator>
24 #include <fstream>
25 #include <cassert>
26 #include <sys/types.h>
27 #include <dirent.h>
28 #include <mimetic/mimetic.h>
29
30 using namespace std;
31 using namespace mimetic;
32
33 unsigned int g_indexed = 0;
34
35 void usage()
36 {
37     cout << "buildidx [file|dir...]" << endl;
38     exit(-1);
39 }
40
41 void die(bool b, const string& msg)
42 {
43     if(b)
44     {
45         cerr << "Error: " << msg << endl << endl;
46         usage();
47     }
48 }
49
50 void indexFile(MimeEntity& head, const string& fqn)
51 {
52     File in(fqn);
53     if(in)
54     {
55         MimeEntity* pMe = new MimeEntity;
56         pMe->load(in.begin(), in.end(), ~imHeader);
57         pMe->header().push_back(Field("X-Filename",fqn));
58         head.body().parts().push_back(pMe);
59         cerr << "." << flush;
60         g_indexed++;
61     } else
62         cerr << "ERR: unable to open file " << fqn << endl;
63
64 }
65
66 void indexDirectory(MimeEntity& head, const string& dirFqn)
67 {
68     DIR* dir = opendir(dirFqn.c_str());
69     if(dir == 0)
70     {
71         cerr << "ERR: unable to read from " << dirFqn << endl;
72         return;
73     }
74     struct dirent* item;
75     struct stat st;
76     string ffqn;
77     while(0 != (item = readdir(dir)))
78     {
79         ffqn = dirFqn + "/" + item->d_name;
80         memset(&st,0,sizeof(struct stat));
81         if(stat(ffqn.c_str(),&st) == -1)
82         {
83             cerr << "ERR: unable to stat " << item->d_name<< endl;
84             return;
85         }
86         if(S_ISREG(st.st_mode) && item->d_name[0] != '.') // reg file
87         {
88             indexFile(head, ffqn);
89         }
90     }
91     closedir(dir);
92 }
93
94 void indexItem(MimeEntity& head, const string& item)
95 {
96     struct stat st;
97     if(stat(item.c_str(), &st) == -1)
98     {
99         cerr << "ERR: unable to stat " << item.c_str() << endl;
100         return;
101     }    
102     if(S_ISREG(st.st_mode)) 
103         indexFile(head, item);
104     else if (S_ISDIR(st.st_mode))
105         indexDirectory(head, item);
106     else
107         cerr << "ERR: unknown file type " << item << endl;
108 }
109
110 int main(int argc, char** argv)
111 {
112     std::ios_base::sync_with_stdio(false);
113
114     if(argc > 1 && string(argv[1]) == "-h")
115         usage();
116     MultipartMixed head;
117     string fqn;
118     if(argc == 1) { 
119         // read filenames from stdin
120         while(getline(cin, fqn))
121             indexItem(head, fqn);
122     } else {
123         for(int fc = 1; fc < argc; ++fc)
124             indexItem(head, argv[fc]);
125     }
126     cout << head << endl;
127     cerr << "index of " << g_indexed << " file(s) built" << endl; 
128     return g_indexed;
129 }
130