[Debtags-commits] [svn] r1922 - in daemon: . src src/lib
Enrico Zini
enrico at costa.debian.org
Mon Sep 18 15:01:22 UTC 2006
Author: enrico
Date: Mon Sep 18 15:01:21 2006
New Revision: 1922
Added:
daemon/src/cmdline.h
daemon/src/config.cpp
daemon/src/config.h
daemon/src/lib/Pidfile.cpp
daemon/src/lib/Pidfile.h
Modified:
daemon/ (props changed)
daemon/src/CMakeLists.txt
daemon/src/debtagsd.cpp
daemon/src/lib/FullText.cpp
daemon/src/lib/FullText.h
Log:
r3360 at viaza: enrico | 2006-09-18 17:00:46 +0200
Added commandline options
Add daemon functionality
Add logfile support (no syslog yet)
All paths are now configurable
We are a proper daemon!
Modified: daemon/src/CMakeLists.txt
==============================================================================
--- daemon/src/CMakeLists.txt (original)
+++ daemon/src/CMakeLists.txt Mon Sep 18 15:01:21 2006
@@ -3,6 +3,6 @@
INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} )
LINK_LIBRARIES( ept wibble tagcoll xapian z )
-ADD_EXECUTABLE( debtagsd debtagsd.cpp ${libsrc} )
+ADD_EXECUTABLE( debtagsd debtagsd.cpp config.cpp ${libsrc} )
set_target_properties( debtagsd PROPERTIES COMPILE_FLAGS "${TAGCOLL_CFLAGS} ${WIBBLE_CFLAGS} -gstabs+ -Wall -O0 ")
Modified: daemon/src/debtagsd.cpp
==============================================================================
--- daemon/src/debtagsd.cpp (original)
+++ daemon/src/debtagsd.cpp Mon Sep 18 15:01:21 2006
@@ -23,50 +23,10 @@
#include "lib/SignalCatcher.h"
#include "lib/FullText.h"
#include "lib/debdbparser.h"
+#include "lib/Pidfile.h"
-#if 0
-
-#include <Credentials.h>
-
-#include <Pidfile.h>
-
-#include <ChildProcess.h>
-
-#include "ProtocolServer.h"
-
-#ifndef VARDESC_DIR
- #warning Using local default value for VARDESC_DIR
- #define VARDESC_DIR "/etc/stated/vardesc.d"
-#endif
-
-#ifndef DEFAULT_SOCKET
- #warning Using local default value for DEFAULT_SOCKET
- #define DEFAULT_SOCKET PID_DIR "/stated.sock"
-#endif
-
-
-class SigHandler : public SignalCatcher::Handler
-{
-protected:
- SyncQueue<Message>& queue;
-
- void caughtSignal(int sig) throw ()
- {
- switch (sig)
- {
- case SIGTERM:
- case SIGQUIT:
- queue.send(Message(new MessageQuit));
- break;
- default:
- break;
- }
- }
-
-public:
- SigHandler(SyncQueue<Message>& queue) throw () : queue(queue) {}
-};
-#endif
+#include "cmdline.h"
+#include "config.h"
class ListeningSocket
{
@@ -121,6 +81,7 @@
}
#if 0
+ -- Show how to get the peer credentials in a socket
void* ProtocolServer::main() throw ()
{
try {
@@ -152,11 +113,14 @@
using namespace std;
+// True when a signal arrives asking the program to be interrupted
static bool interrupted = false;
+// Signal handlers
void sighandler_interrupted(int sig) { interrupted = true; }
void sighandler_noop(int sig) {}
+/// Manage a socket connection
class Connection
{
int fd;
@@ -199,6 +163,7 @@
}
};
+/// Deserialize a sequence of keywords
std::vector<std::string> parseKeys(const std::string& str)
{
std::vector<std::string> res;
@@ -208,6 +173,7 @@
return res;
}
+/// Deserialize a sequence of tags
std::set<std::string> parseTagset(const std::string& str)
{
std::set<std::string> res;
@@ -233,12 +199,13 @@
return res;
}
+/// Quick access to the short descriptions of every package
class ShortDescs : public std::map<std::string, std::string>
{
public:
- ShortDescs()
+ ShortDescs(Config& cfg)
{
- tagcoll::input::Zlib in("packages.gz");
+ tagcoll::input::Stdio in(cfg.pkgdb);
DebDBParser parser(in);
DebDBParser::Record rec;
while (parser.nextRecord(rec))
@@ -266,23 +233,17 @@
}
};
+/// The debtagsd daemon process
class Debtagsd : public wibble::sys::ChildProcess
{
protected:
-#if 0
- MainState& state;
- string socket;
- bool createPidfile;
-#endif
- bool detach;
-
- ostream& log;
+ Config& cfg;
tagcoll::coll::Fast<std::string, std::string> coll;
-
ShortDescs desc;
FullTextSearch fts;
+ /// Output a package with its tags and description
void outputPackage(const std::string& pkg, Connection& conn)
{
using namespace std;
@@ -300,14 +261,14 @@
conn.write("\n");
}
+ /// Interact with one client
void handleConnection(Connection& conn)
{
using namespace std;
try {
// Read a line from fd
string line = conn.readline();
- log << "Got line " << line << endl;
- //conn.write("Hello " + line + "\n");
+ cfg.log() << "Got line " << line << endl;
// compute output
size_t pos = line.find(" ");
@@ -349,22 +310,18 @@
else
conn.write("Command not recognized: " + cmd + "\n");
} catch (std::exception& e) {
- log << e.what() << endl;
+ cfg.log() << e.what() << endl;
}
}
public:
- Debtagsd(ostream& log, bool detach) : detach(detach), log(log)
+ Debtagsd(Config& cfg) : cfg(cfg), desc(cfg), fts(cfg)
{
- tagcoll::input::Stdio input("/var/lib/debtags/package-tags");
+ tagcoll::input::Stdio input(cfg.tagdb);
tagcoll::textformat::parse(input, tagcoll::coll::inserter(coll));
}
-#if 0
- Stated(MainState& state, const string& socket, bool detach, bool createPidfile) throw ()
- : state(state), socket(socket), detach(detach), createPidfile(createPidfile) {}
- virtual ~Stated() throw () {}
-#endif
+ /// Main loop: wait for connections and dispatch them
virtual int main() throw ()
{
int exitStatus = 0;
@@ -372,27 +329,18 @@
// Change to root directory
chdir("/");
-#if 0
// Setup and create the pidfile
- Pidfile pidfile("debtagsd");
- if (createPidfile)
+ Pidfile pidfile(cfg.pidfile);
+ if (cfg.use_pidfile)
pidfile.takeover();
-#endif
// Detach from tty
- if (detach)
+ if (cfg.detach)
wibble::sys::process::detachFromTTY();
// TODO: if needed, reconfigure logger
// TODO: if needed, change process privileges
-#if 0
- // Install signal catcher thread
- SigHandler handler(queue);
- int handled_signals[] = { SIGTERM, SIGQUIT, SIGHUP, SIGUSR1 };
- SignalCatcher catcher(handler, handled_signals, sizeof(handled_signals)/sizeof(int));
-#endif
-
// Install signal handlers
struct sigaction sa;
sa.sa_handler = sighandler_interrupted;
@@ -408,24 +356,25 @@
SigAction sa2(SIGPIPE, s_noop);
- ListeningSocket lsock("/tmp/prova");
-
-#if 0
- ProtocolServer server(state, queue, socket);
- server.startDetached();
- log_info("Server ready to accept connections from " + socket);
-#endif
+ ListeningSocket lsock(cfg.sockfile);
while (!interrupted)
{
Connection conn(lsock.accept());
- log << "Got connection" << endl;
+ cfg.log() << "Got connection" << endl;
handleConnection(conn);
}
- log << "Interrupted" << endl;
+ cfg.log() << "Interrupted" << endl;
+ } catch (Xapian::Error& xe) {
+ ostream& log = cfg.log();
+ log << "Xapian error " << xe.get_type() << ": " << xe.get_msg();
+ if (xe.get_context().size() > 0)
+ log << " in context " << xe.get_context();
+ log << endl;
+ exitStatus = 1;
} catch (std::exception& e) {
- log << e.what() << endl;
+ cfg.log() << e.what() << endl;
exitStatus = 1;
}
return exitStatus;
@@ -434,67 +383,11 @@
int main(int argc, const char* argv[])
{
-#if 0
- // Initialize command line option parsing
- int op_ver = 0;
- int op_no_pidfile = 0;
- int op_no_detach = 0;
- int op_kill = -1;
- int op_verbose = 0;
- int op_debug = 0;
- char* op_socket = 0;
- char* op_test_lexer = 0;
- char* op_test_state_parser = 0;
- char* op_test_action_parser = 0;
-
- //int op_id = -1;
- //int op_type = -1;
- //const char* op_symbol = 0;
- //const char* op_desc = 0;
- char* help = "Manage a set of variables, running scripts when they change.\n";
- struct poptOption emptyTable[] = { POPT_TABLEEND };
- struct poptOption optionsTable[] = {
- { "kill", 'k', POPT_ARG_INT | POPT_ARGFLAG_OPTIONAL, &op_kill, 0, "kill a running daemon with the specified signal (15 by default)", "signal" },
- { "socket", 0, POPT_ARG_STRING, &op_socket, 0, "location of the server socket (default: " DEFAULT_SOCKET ")", "file" },
- { "test-lexer", 0, POPT_ARG_STRING, &op_test_lexer, 0, "test lexer on input files and exit", "file" },
- { "test-state-parser", 0, POPT_ARG_STRING, &op_test_state_parser, 0, "test the parser of variable descriptions and exit", "file" },
- { "test-action-parser", 0, POPT_ARG_STRING, &op_test_action_parser, 0, "test the parser of action scripts and exit", "file" },
- { "no-pidfile", 0, POPT_ARG_NONE, &op_no_pidfile, 0, "don't create a pidfile", 0 },
- { "no-detach", 'n', POPT_ARG_NONE, &op_no_detach, 0, "don't fork to background (used for debugging)", 0 },
- { "verbose", 'v', POPT_ARG_NONE, &op_verbose, 0, "print and/or log verbose output", 0 },
- { "debug", 0, POPT_ARG_NONE, &op_debug, 0, "print and/or log debug output (includes --verbose output)", 0 },
- { "version", 'V', POPT_ARG_NONE, &op_ver, 0, "print version and exit", 0 },
- POPT_AUTOHELP
- { NULL, 0, POPT_ARG_INCLUDE_TABLE, emptyTable, 0, help, 0 },
- POPT_TABLEEND
- };
- poptContext optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
- poptSetOtherOptionHelp(optCon, "[options]");
-
- set_unexpected(DefaultUnexpected);
-
- if (argc < 1) {
- poptPrintHelp(optCon, stderr, 0);
- return 1;
- }
+ wibble::commandline::DebtagsdOptions opts;
- // Process commandline
- int res = poptGetNextOpt(optCon);
- if (res != -1)
- {
- fprintf(stderr, "%s: %s\n\n",
- poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
- poptStrerror(res));
- poptPrintUsage(optCon, stderr, 0);
- return 1;
- }
-
- if (op_ver)
- {
- printf("%s ver." VERSION "\n", argv[0]);
- return 0;
- }
+ setenv("XAPIAN_PREFER_FLINT", "1", 1);
+#if 0
// Configure logging services
StatedLogEnvironment logEnvironment;
logEnvironment.setLogInfo(op_verbose);
@@ -504,64 +397,85 @@
logEnvironment.setLogDebug(op_debug);
}
logEnvironment.setIsDetached(!op_no_detach);
-
- if (!op_socket)
- op_socket = DEFAULT_SOCKET;
#endif
try {
- setenv("XAPIAN_PREFER_FLINT", "1", 1);
-#if 0
- // Perform op_kill special action
- if (op_kill != -1)
+ // Install the handler for unexpected exceptions
+ wibble::exception::InstallUnexpected installUnexpected;
+
+ // Read commandline options
+ if (opts.parse(argc, argv))
+ return 0;
+ Config cfg;
+ cfg.read(opts);
+
+ if (opts.foundCommand() == opts.start)
+ {
+ // Disable unimportant stderr output early, so that init data is logged
+ // but does not clutter the console
+ //if (!op_no_detach)
+ //set_stderr(Restricted);
+
+ // Check if another stated is already running
+ Pidfile pidfile(cfg.pidfile);
+ if (cfg.use_pidfile && pidfile.is_active())
+ if (!cfg.quiet)
+ {
+ fprintf(stderr, "debtagsd already running as pid %d", pidfile.read());
+ return 1;
+ }
+
+ Debtagsd debtagsd(cfg);
+ if (cfg.detach)
+ debtagsd.fork();
+ else
+ return debtagsd.main();
+ }
+ else if (opts.foundCommand() == opts.stop)
{
- if (op_kill == 0)
- op_kill = 15;
- Pidfile pidfile("stated");
- if (pidfile.kill(op_kill))
- return 0;
- else {
- fprintf(stderr, "stated is not running\n");
+ Pidfile pidfile(cfg.pidfile);
+ if (!pidfile.kill(cfg.kill_signal))
+ {
+ cerr << "debtagsd is not running" << endl;
return 1;
}
}
-
- // Disable unimportant stderr output early, so that init data is logged
- // but does not clutter the console
- //if (!op_no_detach)
- //set_stderr(Restricted);
-
- // Check if another stated is already running
- Pidfile pidfile("stated");
- if (!op_no_pidfile && pidfile.is_active())
+ else if (opts.foundCommand() == opts.restart)
{
- fprintf(stderr, "stated already running as pid %d", pidfile.read());
- exit(1);
- }
-#endif
+ Pidfile pidfile(cfg.pidfile);
+ if (!pidfile.kill(cfg.kill_signal))
+ cerr << "debtagsd was not running" << endl;
- Debtagsd debtagsd(cerr, false);/*state, op_socket, !op_no_detach, !op_no_pidfile*/
- //if (op_no_detach)
- return debtagsd.main();
-#if 0
- else
- {
- ChildProcess daemon(stated);
- daemon.fork();
- return 0;
- }
-#endif
+ if (pidfile.is_active())
+ {
+ fprintf(stderr, "debtagsd is still running as pid %d", pidfile.read());
+ return 1;
+ }
- return 0;
+ Debtagsd debtagsd(cfg);
+ if (cfg.detach)
+ debtagsd.fork();
+ else
+ return debtagsd.main();
+ }
+ else
+ throw wibble::exception::BadOption(string("unhandled command ") +
+ (opts.foundCommand() ? opts.foundCommand()->name() : "(null)"));
} catch (Xapian::Error& xe) {
cerr << "Xapian error " << xe.get_type() << ": " << xe.get_msg();
if (xe.get_context().size() > 0)
cerr << " in context " << xe.get_context();
cerr << endl;
+ return 1;
+ } catch (wibble::exception::BadOption& e) {
+ cerr << e.desc() << endl;
+ opts.outputHelp(cerr);
+ return 1;
} catch (std::exception& e) {
cerr << e.what() << endl;
return 1;
}
+ return 0;
}
#include <tagcoll/coll/fast.tcc>
Modified: daemon/src/lib/FullText.cpp
==============================================================================
--- daemon/src/lib/FullText.cpp (original)
+++ daemon/src/lib/FullText.cpp Mon Sep 18 15:01:21 2006
@@ -11,6 +11,7 @@
#include <iostream>
+#include "../config.h"
static std::string lowercase(const std::string& str)
{
@@ -23,14 +24,15 @@
struct FTSData
{
+ Config& cfg;
Xapian::Database database;
Xapian::Stem stem;
- FTSData() : stem("en")
+ FTSData(Config& cfg) : cfg(cfg), stem("en")
{
- if (!wibble::sys::fs::access("/tmp/prova.db", F_OK))
+ if (!wibble::sys::fs::access(cfg.ftsdb, F_OK))
index();
- database.add_database(Xapian::Database("/tmp/prova.db"));
+ database.add_database(Xapian::Database(cfg.ftsdb));
}
std::string normalise(const std::string& word)
@@ -40,9 +42,9 @@
void index()
{
- Xapian::WritableDatabase database("/tmp/prova.db", Xapian::DB_CREATE_OR_OPEN);
+ Xapian::WritableDatabase database(cfg.ftsdb, Xapian::DB_CREATE_OR_OPEN);
//database.begin_transaction();
- std::cerr << "Indexing..." << std::endl;
+ cfg.log() << "Started indexing package descriptions." << std::endl;
tagcoll::input::Zlib in("packages.gz");
DebDBParser parser(in);
DebDBParser::Record rec;
@@ -64,22 +66,20 @@
}
database.add_document(doc);
}
- std::cerr << "Indexed." << std::endl;
+ cfg.log() << "Finised indexing package descriptions." << std::endl;
//database.commit_transaction();
}
};
-FullTextSearch::FullTextSearch()
- : data(0)
+FullTextSearch::FullTextSearch(Config& cfg)
+ : cfg(cfg), data(new FTSData(cfg))
{
- data = new FTSData;
}
FullTextSearch::~FullTextSearch()
{
- if (data)
- delete data;
+ delete data;
}
std::set<std::string> FullTextSearch::search(const std::vector<std::string>& keys)
@@ -99,7 +99,7 @@
{
// Cut off poor results
if (res.size() > 10 && i.get_percent() < 60) break;
- cerr << i.get_document().get_data() << ": " << i.get_percent() << "%" << endl;
+ //cfg.log() << i.get_document().get_data() << ": " << i.get_percent() << "%" << endl;
res.insert(i.get_document().get_data());
}
return res;
Modified: daemon/src/lib/FullText.h
==============================================================================
--- daemon/src/lib/FullText.h (original)
+++ daemon/src/lib/FullText.h Mon Sep 18 15:01:21 2006
@@ -4,16 +4,18 @@
#include <set>
#include <vector>
#include <string>
+#include "../config.h"
struct FTSData;
/// RAII-style wrapper to sigaction
class FullTextSearch
{
+ Config& cfg;
FTSData* data;
public:
- FullTextSearch();
+ FullTextSearch(Config& cfg);
~FullTextSearch();
std::set<std::string> search(const std::vector<std::string>& keys);
More information about the Debtags-commits
mailing list