1
/* $Id: search.cpp,v 1.5 2004/08/27 18:11:59 terpstra Exp $
3
* search.cpp - Search for messages in lurker database (optionally delete)
5
* Copyright (C) 2004 - Wesley W. Terpstra
9
* Authors: 'Wesley W. Terpstra' <wesley@terpstra.ca>
11
* This program is free software; you can redistribute it and/or modify
12
* it under the terms of the GNU General Public License as published by
13
* the Free Software Foundation; version 2.
15
* This program is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU General Public License for more details.
20
* You should have received a copy of the GNU General Public License
21
* along with this program; if not, write to the Free Software
22
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
#define _XOPEN_SOURCE 500
26
#define _FILE_OFFSET_BITS 64
37
void help(const char* name)
39
cerr << "Lurker-search (v" << VERSION << ") searches for messages in a lurker database.\n";
41
cerr << "Usage: " << name << " -c <config-file> -k <keyword> [ -d -f -v -q ] <terms>*\n";
43
cerr << "\t-c <config-file> Use this config file for lurker settings\n";
44
cerr << "\t-k <keyword> Add the specified keyword tag to hits\n";
45
cerr << "\t-d Delete matching messages\n";
46
cerr << "\t-f Don't prompt before deleting\n";
47
cerr << "\t-v Output message summaries\n";
48
cerr << "\t-q Don't output message ids or status\n";
50
cerr << "Execute a keyword search to find messages.\n";
51
cerr << "The following search terms are supported (all must match):\n";
52
cerr << " -xxx - select messages which do NOT match this term\n";
53
cerr << " id:xxx - select a message by the Message-ID field\n";
54
cerr << " rt:xxx - select messages which reply to the chosen Message-ID\n";
55
cerr << " th:xxx - select messages included in this thread\n";
56
cerr << " ml:xxx - select messages in this mailing list\n";
57
cerr << " gr:xxx - select messages in this mailing list group\n";
58
cerr << " au:xxx - select messages with this term in the author fields\n";
59
cerr << " sb:xxx - select messages with this word in the subject\n";
60
cerr << " lang:xx - select messages in this language\n";
64
int main(int argc, char** argv)
68
const char* config = 0;
75
while ((c = getopt(argc, (char*const*)argv, "c:k:dvfq?")) != -1)
103
if (!config || optind >= argc)
110
if (cfg.load(config) != 0)
112
cerr << cfg.getError() << flush;
117
auto_ptr<ESort::Reader> dbr;
119
if (erase || keyword != "")
121
if (verbose) cerr << "opening " << cfg.dbdir << "/db read-write" << endl;
122
// Work around g++ 2.95 bug
123
auto_ptr<ESort::Writer> w
124
(ESort::Writer::opendb(cfg.dbdir + "/db"));
130
if (verbose) cerr << "opening " << cfg.dbdir << "/db read-only" << endl;
131
auto_ptr<ESort::Reader> r
132
(ESort::Reader::opendb(cfg.dbdir + "/db"));
138
perror("opening database");
142
Search s(cfg, dbr.get(), ESort::Forward);
144
while (optind < argc) s.keyword(argv[optind++]);
146
vector<Summary> result;
147
vector<Summary>::size_type sz = 0;
148
while (s.pull(1, result) && result.size() == sz+1)
153
cout << "id: " << result.back().id().serialize() << "\n";
157
if ((ok = result.back().load(dbr.get(), cfg)) != "")
159
cerr << "Failed to load: " << ok << "\n";
162
cout << "sb: " << result.back().subject() << "\n";
163
cout << "au: \"" << result.back().author_name() << "\" <"
164
<< result.back().author_email() << ">\n";
168
if (result.empty()) return 0;
173
cerr << "Are you certain you want to delete these messages? (yes/no) [no] " << flush;
175
std::getline(cin, ok);
178
cerr << "aborted!\n";
185
if (!quiet) cerr << "Tagging messages with keyword" << endl;
186
for (vector<Summary>::iterator i = result.begin();
197
cerr << "Tagging with keyword failed; operation aborted.\n";
205
if (!quiet) cerr << "Marking messages as deleted" << endl;
206
for (vector<Summary>::iterator i = result.begin();
212
string(LU_KEYWORD_DELETED) +
217
cerr << "Delete keyword failed; operation aborted.\n";
224
LU_MESSAGE_DELETED) != 0)
227
cerr << "Delete summary failed; operation aborted.\n";
233
if (erase || keyword != "")
235
if (!quiet) cerr << "Committing changes to disk" << endl;
236
if (db->commit() != 0)
239
cerr << "Commit failed; operation aborted.\n";
246
cerr << "Database modified -- cache is now invalid.\n";
247
cerr << "Re-run lurker-prune with the '-p' option.\n";