/[debian]/mimetic/branches/upstream/current/examples/catpart.cxx
ViewVC logotype

Contents of /mimetic/branches/upstream/current/examples/catpart.cxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 128 - (show annotations)
Sat Feb 25 16:49:20 2006 UTC (15 years, 5 months ago) by gregoa
File size: 7743 byte(s)
[svn-inject] Installing original source of mimetic
1 /***************************************************************************
2 copyright : (C) 2002-2005 by Stefano Barbato
3 email : stefano@codesink.org
4
5 $Id: catpart.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 catpart.cc
17 * extract a Part based on command line parameters
18 * more info on:
19 * catpart -h
20 */
21 #include <iostream>
22 #include <sstream>
23 #include <iterator>
24 #include <fstream>
25 #include <cassert>
26 #include <mimetic/mimetic.h>
27
28 using namespace std;
29 using namespace mimetic;
30
31 unsigned int g_matches = 0;
32
33 void usage()
34 {
35 cout << "catpart [params] [in_file...]" << endl;
36 cout << "\t-r look for matches in nested entities"<<endl;
37 cout << "\t-t type[/subtype] matches Content-Type" << endl;
38 cout << "\t-p param[=value] matches Content-Type param" << endl;
39 cout << "\t-f name[=value] matches an header field" << endl;
40 cout << "\t-l don't write anything but filename" << endl;
41 cout << "\t-q totaly quiet; exit code = num of matches" << endl;
42 cout << "\t-H ignore header fields" << endl;
43 cout << "\t-B ignore entities' body" << endl;
44 cout << "\t-C ignore child entities" << endl;
45 exit(-1);
46 }
47
48
49 struct MatchParamRq
50 {
51 typedef pair<istring,istring> Param;
52 typedef pair<istring,istring> Field;
53 MatchParamRq()
54 : recursive(0), justFilename(0), quiet(0)
55 {
56 }
57 bool operator()(const MimeEntity* pMe) const
58 {
59 // check for content type match
60 const Header& h = pMe->header();
61 if(type.length() && type != h.contentType().type())
62 return false;
63 if(subtype.length() && subtype != h.contentType().subtype())
64 return false;
65
66 bool matched;
67 // check for params matches
68 if(paramList.size())
69 {
70 ContentType::ParamList::const_iterator ctpbit,ctpeit;
71 ctpbit = h.contentType().paramList().begin();
72 ctpeit = h.contentType().paramList().end();
73 matched = 0;
74 for(; !matched && ctpbit != ctpeit; ++ctpbit)
75 {
76 list<Param>::const_iterator pbit, peit;
77 pbit = paramList.begin(), peit = paramList.end();
78 for(; pbit != peit; ++pbit)
79 {
80 if(ctpbit->name() != pbit->first)
81 break;
82 // case insensitive
83 istring value = ctpbit->value();
84 if(value.find(pbit->second) != string::npos)
85 matched++;
86 }
87 }
88 if(!matched)
89 return false;
90 }
91
92 // check for field matches
93 if(fieldList.size())
94 {
95 matched = 0;
96 Header::const_iterator hbit, heit;
97 hbit = h.begin();
98 heit = h.end();
99 for(; !matched && hbit != heit; ++hbit)
100 {
101 list<Field>::const_iterator fbit, feit;
102 fbit = fieldList.begin(), feit = fieldList.end();
103 for(; fbit != feit; ++fbit)
104 {
105 if(hbit->name() != fbit->first)
106 break;
107 // case insensitive
108 istring value = hbit->value();
109 if(value.find(fbit->second) != string::npos)
110 matched++;
111 }
112 }
113 if(!matched)
114 return false;
115 }
116
117 return true;
118
119 }
120 istring type, subtype;
121 list<Param> paramList;
122 list<Field> fieldList;
123 bool recursive, justFilename, quiet;
124 };
125
126 void die(bool b, const string& msg)
127 {
128 if(b)
129 {
130 cerr << "Error: " << msg << endl << endl;
131 usage();
132 }
133 }
134
135 void printPart(const MimeEntity& me, const MatchParamRq& mpr, string& fqn)
136 {
137 while(mpr(&me))
138 {
139 ++g_matches;
140 if(mpr.quiet)
141 break;
142 if(mpr.justFilename)
143 {
144 if(fqn.length() == 0)
145 break;
146 cout << fqn << endl;
147 fqn.clear();
148 } else {
149 if(g_matches > 1)
150 cout << endl;
151 cout << me;
152 }
153 break; // never loop
154 }
155 if(!mpr.recursive)
156 return; // just top level entity
157 MimeEntityList::const_iterator mbit, meit;
158 mbit = me.body().parts().begin(), meit = me.body().parts().end();
159 for(; mbit != meit; ++mbit)
160 printPart(**mbit, mpr, fqn);
161 }
162
163 int main(int argc, char** argv)
164 {
165 std::ios_base::sync_with_stdio(false);
166 MatchParamRq mpr;
167 int ignoreMask = 0;
168
169 int p = 1;
170 while(p < argc)
171 {
172 string param = argv[p];
173 if(param == "-h")
174 usage();
175 else if (param == "-r")
176 mpr.recursive = 1;
177 else if (param == "-q")
178 mpr.quiet = 1;
179 else if (param == "-l")
180 mpr.justFilename = 1;
181 else if (param == "-H")
182 ignoreMask += imHeader;
183 else if (param == "-B")
184 ignoreMask += imBody;
185 else if (param == "-C")
186 ignoreMask += imChildParts;
187 else if (param == "-t") {
188 die( ++p == argc, param + " requires an argument");
189 ContentType ct(argv[p]);
190 die(mpr.type.length() != 0, "just one -t allowed");
191 mpr.type = ct.type();
192 mpr.subtype = ct.subtype();
193 } else if (param == "-p") {
194 die( ++p == argc, param + " requires an argument");
195 string switch_param = argv[p];
196 StringTokenizer stok(&switch_param, "=");
197 pair<string,string> item;
198 stok.next(item.first) && stok.next(item.second);
199 mpr.paramList.push_back(item);
200 } else if (param == "-f") {
201 die( ++p == argc, param + " requires an argument");
202 string switch_param = argv[p];
203 StringTokenizer stok(&switch_param, "=");
204 pair<string,string> item;
205 stok.next(item.first) && stok.next(item.second);
206 mpr.fieldList.push_back(item);
207 } else if( param.length() == 2 && param[0] == '-') {
208 usage();
209 } else {
210 // filename list starts here
211 // first filename: argv[p]
212 break;
213 }
214 ++p;
215 }
216
217 string fqn;
218 if(argc == p)
219 { // read from stdin
220 istreambuf_iterator<char> bit(cin), eit;
221 MimeEntity me;
222 me.load(bit, eit, ignoreMask);
223 fqn = "stdin";
224 printPart(me, mpr, fqn);
225 } else
226 for(int fc = p; fc < argc; ++fc)
227 {
228 fqn = argv[fc];
229 File in(fqn);
230 if(!in)
231 {
232 cerr << "ERR: unable to open file " << argv[fc]
233 << endl;
234 continue;
235 }
236 MimeEntity me;
237 me.load(in.begin(), in.end(), ignoreMask);
238 printPart(me, mpr, fqn);
239 }
240 return g_matches;
241 }
242

  ViewVC Help
Powered by ViewVC 1.1.26