[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