← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~linuxdcpp-team/linuxdcpp/trunk] Rev 359: Moved argument parsing & handling to wulfor.cc

 

Merge authors:
  Razzloss (razzloss)
------------------------------------------------------------
revno: 359 [merge]
committer: Razzloss <razzloss@xxxxxxxxx>
branch nick: master
timestamp: Mon 2010-03-22 21:26:53 +0200
message:
  Moved argument parsing & handling to wulfor.cc
modified:
  .bzrignore
  data/linuxdcpp.1
  linux/WulforUtil.cc
  linux/WulforUtil.hh
  linux/hub.cc
  linux/mainwindow.cc
  linux/mainwindow.hh
  linux/wulfor.cc


--
lp:linuxdcpp
https://code.launchpad.net/~linuxdcpp-team/linuxdcpp/trunk

Your team LinuxDC++ Team is subscribed to branch lp:linuxdcpp.
To unsubscribe from this branch go to https://code.launchpad.net/~linuxdcpp-team/linuxdcpp/trunk/+edit-subscription.
=== modified file '.bzrignore'
--- .bzrignore	2010-03-15 20:46:38 +0000
+++ .bzrignore	2010-03-22 16:53:52 +0000
@@ -2,3 +2,4 @@
 tags
 core
 linuxdcpp
+config.h

=== modified file 'data/linuxdcpp.1'
--- data/linuxdcpp.1	2009-10-22 03:11:11 +0000
+++ data/linuxdcpp.1	2010-03-22 16:52:49 +0000
@@ -12,7 +12,23 @@
  Direct Connect (DC) is a peer-to-peer (P2P) file-sharing protocol. Clients connect to a central hub where they can chat or share files with one another. Users can view other users' list of shared files or search the hub for files.
 
 .SH OPTIONS
-None
+LinuxDC++ specific options are described below.
+.IP "\-m or \-\-magnet=Magnet-link"
+Search for a given magnet link from connected hubs.
+.IP "\-c or \-\-connect=URI"
+Connect to a given hub. 
+.IP "\-s or \-\-show"
+Show the running instance. If no other arguments are given and LinuxDC++ is already running, this is the default.
+.IP "\-e or \-\-existing"
+Direct commands to already running instance. If running instance is not found, do nothing.
+.IP "\-r or \-\-refresh" 
+Initiate filelist refresh.
+.IP "\-V or \-\-version"
+Show version information and exit
+.IP "\-h or \-\-help" 
+Display summary of accepted LinuxDC++ specific options.
+.IP "\-\-help\-all"
+Display summary of all accepted options.
 
 .SH SEE ALSO
 .B Homepage: 

=== modified file 'linux/WulforUtil.cc'
--- linux/WulforUtil.cc	2010-03-15 12:30:41 +0000
+++ linux/WulforUtil.cc	2010-03-22 16:53:52 +0000
@@ -42,7 +42,6 @@
 std::vector<std::string> WulforUtil::charsets;
 const std::string WulforUtil::magnetSignature = "magnet:?xt=urn:tree:tiger:";
 GtkIconFactory* WulforUtil::iconFactory = NULL;
-CommandLineArgs WulforUtil::startArguments;
 
 vector<int> WulforUtil::splitString(const string &str, const string &delimiter)
 {
@@ -63,62 +62,6 @@
 	return array;
 }
 
-bool WulforUtil::parseArguments(int *argc, char **argv[])
-{
-	gchar* magnet = NULL, *address = NULL;
-	gboolean show = FALSE, refresh = FALSE, version = FALSE;
-
-	GOptionEntry entries[] = {
-		{ "magnet", 'm', 0, G_OPTION_ARG_STRING, &magnet, "Search magnet from connected hubs.", NULL },
-		{ "connect", 'c', 0, G_OPTION_ARG_STRING, &address, "Connect to given hub", NULL },
-		{ "show", 's', 0, G_OPTION_ARG_NONE, &show, "Show running instance (or start a new one)", NULL },
-		{ "refresh", 'r', 0, G_OPTION_ARG_NONE, &refresh, "Refresh filelist. LinuxDC++ has to be running for this to have an effect.", NULL },
-		{ "version", 'V', 0, G_OPTION_ARG_NONE, &version, "Print version information and exit.", NULL },
-		{ NULL }
-	};
-
-	GOptionContext *context;
-	GError* error = NULL;
-	context = g_option_context_new("");
-	g_option_context_add_main_entries(context, entries, NULL);
-	g_option_context_add_group(context, gtk_get_option_group(TRUE));
-	if (!g_option_context_parse(context, argc, argv, &error))
-	{
-		g_print(_("Option parsing failed: %s\n"), error->message);
-		return FALSE;
-	}
-	else
-	{
-		if (show)
-			startArguments.show = TRUE;
-		if (refresh)
-			startArguments.refresh = TRUE;
-		if (magnet)
-			startArguments.magnets.push_back(std::string(magnet));
-		if (address)
-			startArguments.urls.push_back(std::string(address));
-		if (version)
-			startArguments.version = TRUE;
-
-		// Handle extra 'file' arguments passed to commandline
-		parseExtraArguments(*argc, *argv);
-	}
-
-	return TRUE;
-}
-
-void WulforUtil::parseExtraArguments(int argc, char* argv[])
-{
-	for (int i = 1; i < argc; i++)	// i = 1 since argv[0] is prgname
-	{
-		string arg(argv[i]);
-		if (isHubURL(arg))
-			startArguments.urls.push_back(arg);
-		else if (isMagnet(arg))
-			startArguments.magnets.push_back(arg);
-	}
-}
-
 string WulforUtil::linuxSeparator(const string &ps)
 {
 	string str = ps;

=== modified file 'linux/WulforUtil.hh'
--- linux/WulforUtil.hh	2010-03-15 12:30:41 +0000
+++ linux/WulforUtil.hh	2010-03-22 16:53:52 +0000
@@ -28,14 +28,6 @@
 #include <dcpp/CID.h>
 #include <dcpp/User.h>
 
-struct CommandLineArgs {
-	std::vector<std::string> magnets;
-	std::vector<std::string> urls;
-	bool show;
-	bool refresh;
-	bool version;
-};
-
 class WulforUtil
 {
 	public:
@@ -73,9 +65,6 @@
 
 		static const std::string ENCODING_LOCALE;
 		
-		static bool parseArguments(int *argc, char **argv[]);
-		static void parseExtraArguments(int argc, char* argv[]);
-		static CommandLineArgs startArguments;
 	private:
 		static std::vector<std::string> charsets;
 		static const std::string magnetSignature;

=== modified file 'linux/hub.cc'
--- linux/hub.cc	2010-03-22 15:47:40 +0000
+++ linux/hub.cc	2010-03-22 19:26:53 +0000
@@ -1179,16 +1179,8 @@
 
 void Hub::onSearchMagnetClicked_gui(GtkMenuItem *item, gpointer data)
 {
-	Hub *hub = (Hub *)data;
-	string name;
-	int64_t size;
-	string tth;
-
-	if (WulforUtil::splitMagnet(hub->selectedTagStr, name, size, tth))
-	{
-		Search *s = WulforManager::get()->getMainWindow()->addSearch_gui();
-		s->putValue_gui(tth, 0, SearchManager::SIZE_DONTCARE, SearchManager::TYPE_TTH);
-	}
+	Hub *hub = (Hub*)data;
+	WulforManager::get()->getMainWindow()->addMagnetSearch_gui(hub->selectedTagStr);
 }
 
 void Hub::onMagnetPropertiesClicked_gui(GtkMenuItem *item, gpointer data)

=== modified file 'linux/mainwindow.cc'
--- linux/mainwindow.cc	2010-03-15 12:30:41 +0000
+++ linux/mainwindow.cc	2010-03-22 19:18:07 +0000
@@ -166,30 +166,7 @@
 	showTransfersPane_gui();
 
 	// Set up our IPC 
-	const string pipepath = WulforUtil::getPipePath();
-	dcdebug("MainWindow::MainWindow: Pipepath %s\n", pipepath.c_str());
-	int status = mkfifo(pipepath.c_str(), S_IRWXU); 
-	if (status == -1 && errno == EEXIST)
-	{
-		dcdebug("Stale pipe detected. Unlinking...\n");
-		unlink(pipepath.c_str());
-	}
-
-	if (status == 0 || mkfifo(pipepath.c_str(), S_IRWXU) == 0)
-	{
-		int fd = open(pipepath.c_str(), O_NONBLOCK | O_RDWR);
-		if (fd >= 0) 
-		{
-			IPC = g_io_channel_unix_new(fd);	// Eh, can this fail?
-			g_io_add_watch(IPC, G_IO_IN, onExternalData, this);
-			g_io_add_watch(IPC, G_IO_PRI, onExternalData, this);
-		}
-	} 
-	else
-	{
-		dcdebug("MainWindow::MainWindow, mkfifo FAILED!\n");
-		IPC = NULL;
-	}
+	createIPCPipe();
 
 	// Putting this after all the resizing and moving makes the window appear
 	// in the correct position instantly, looking slightly more cool 
@@ -266,7 +243,6 @@
 	WulforManager::get()->dispatchClientFunc(f0);
 
 	autoOpen_gui();
-	handleCommandlineArguments_gui();
 }
 
 void MainWindow::setTitle(const string& text)
@@ -661,6 +637,21 @@
 	return entry;
 }
 
+Search *MainWindow::addMagnetSearch_gui(const string& magnet)
+{
+	string name;
+	int64_t size;
+	string tth;
+
+	if (WulforUtil::splitMagnet(magnet, name, size, tth))
+	{
+		Search *s = addSearch_gui();
+		s->putValue_gui(tth, 0, SearchManager::SIZE_DONTCARE, SearchManager::TYPE_TTH);
+		return s;
+	}
+	return NULL;
+}
+
 void MainWindow::setTabPosition_gui(int position)
 {
 	GtkPositionType tabPosition;
@@ -1293,26 +1284,33 @@
 	return filename;
 }
 
-void MainWindow::handleCommandlineArguments_gui()
+void MainWindow::createIPCPipe()
 {
-	std::vector<std::string>::iterator it = WulforUtil::startArguments.magnets.begin();
-	for (; it != WulforUtil::startArguments.magnets.end(); ++it)
-	{
-		string name;
-		int64_t size;
-		string tth;
-
-		if (WulforUtil::splitMagnet(*it, name, size, tth))
+	const string pipepath = WulforUtil::getPipePath();
+	dcdebug("MainWindow::MainWindow: Pipepath %s\n", pipepath.c_str());
+
+	int status = mkfifo(pipepath.c_str(), S_IRWXU); 
+
+	if (status == -1 && errno == EEXIST)
+	{
+		dcdebug("Stale pipe detected. Unlinking...\n");
+		unlink(pipepath.c_str());
+	}
+
+	if (status == 0 || mkfifo(pipepath.c_str(), S_IRWXU) == 0)
+	{
+		int fd = open(pipepath.c_str(), O_NONBLOCK | O_RDWR);
+		if (fd >= 0) 
 		{
-			Search *s = addSearch_gui();
-			s->putValue_gui(tth, 0, SearchManager::SIZE_DONTCARE, SearchManager::TYPE_TTH);
+			IPC = g_io_channel_unix_new(fd);	// Eh, can this fail?
+			g_io_add_watch(IPC, G_IO_IN, onExternalData, this);
+			g_io_add_watch(IPC, G_IO_PRI, onExternalData, this);
 		}
-	}
-
-	for (it = WulforUtil::startArguments.urls.begin(); it != WulforUtil::startArguments.urls.end(); ++it)
+	} 
+	else
 	{
-
-		showHub_gui(*it);
+		dcdebug("MainWindow::MainWindow, mkfifo FAILED!\n");
+		IPC = NULL;
 	}
 }
 
@@ -1367,15 +1365,7 @@
 		} 
 		else if (cmd == "magnet")
 		{
-			string name;
-			int64_t size;
-			string tth;
-
-			if (WulforUtil::splitMagnet(arg, name, size, tth))
-			{
-				Search *s = mw->addSearch_gui();
-				s->putValue_gui(tth, 0, SearchManager::SIZE_DONTCARE, SearchManager::TYPE_TTH);
-			}
+			mw->addMagnetSearch_gui(arg);
 		}
 		else if (cmd == "connect")
 		{

=== modified file 'linux/mainwindow.hh'
--- linux/mainwindow.hh	2010-03-10 20:22:21 +0000
+++ linux/mainwindow.hh	2010-03-22 19:18:07 +0000
@@ -74,9 +74,9 @@
 		void showPublicHubs_gui();
 		void showShareBrowser_gui(dcpp::UserPtr user, std::string file, std::string dir, bool useSetting);
 		Search *addSearch_gui();
+		Search *addMagnetSearch_gui(const std::string& magnet);
 		void setMainStatus_gui(std::string text, time_t t = time(NULL));
 		void showNotification_gui(std::string title, std::string body);
-		void handleCommandlineArguments_gui();
 
 		// Client functions
 		void openOwnList_client(bool useSetting);
@@ -98,6 +98,7 @@
 			std::string downloaded, std::string uploadSpeed, std::string uploaded);
 		void setTabPosition_gui(int position);
 		void setToolbarStyle_gui(int style);
+		void createIPCPipe();
 
 		// GUI Callbacks
 		static gboolean onWindowState_gui(GtkWidget *widget, GdkEventWindowState *event, gpointer data);

=== modified file 'linux/wulfor.cc'
--- linux/wulfor.cc	2010-03-16 09:46:02 +0000
+++ linux/wulfor.cc	2010-03-22 19:18:07 +0000
@@ -34,6 +34,17 @@
 #include <iostream>
 #include <signal.h>
 
+struct CommandlineArgs {
+	std::vector<std::string> magnets;
+	std::vector<std::string> urls;
+	bool show;
+	bool refresh;
+	bool version;
+	bool existing;
+	CommandlineArgs() : show(FALSE), refresh(FALSE), version(FALSE), existing(FALSE) { }
+};
+
+
 void callBack(void* x, const std::string& a)
 {
 	std::cout << "Loading: " << a << std::endl;
@@ -54,59 +65,138 @@
 		<< gtk_minor_version << "." << gtk_micro_version << std::endl;
 }
 
+void parseExtraArguments(int argc, char* argv[], CommandlineArgs* args)
+{
+	for (int i = 1; i < argc; i++)	// i = 1 since argv[0] is prgname
+	{
+		std::string arg(argv[i]);
+		if (WulforUtil::isHubURL(arg))
+			args->urls.push_back(arg);
+		else if (WulforUtil::isMagnet(arg))
+			args->magnets.push_back(arg);
+	}
+}
+
+bool parseArguments(int *argc, char **argv[], CommandlineArgs* args)
+{
+	gchar **magnet = NULL, **address = NULL;
+	gboolean show = FALSE, refresh = FALSE, version = FALSE, existing = FALSE;
+
+	GOptionEntry entries[] = {
+		{ "magnet", 'm', 0, G_OPTION_ARG_STRING_ARRAY, &magnet, N_("Search magnet from connected hubs."), N_("Magnet-link") },
+		{ "connect", 'c', 0, G_OPTION_ARG_STRING_ARRAY, &address, N_("Connect to given hub."), N_("URI") },
+		{ "show", 's', 0, G_OPTION_ARG_NONE, &show, N_("Show running instance (this is a default in case no other command was given)"), NULL },
+		{ "existing", 'e', 0, G_OPTION_ARG_NONE, &existing, N_("Send command to already running instance (do nothing if running instance is not found)."), NULL },
+		{ "refresh", 'r', 0, G_OPTION_ARG_NONE, &refresh, N_("Refresh filelist. LinuxDC++ has to be running for this to have an effect."), NULL },
+		{ "version", 'V', 0, G_OPTION_ARG_NONE, &version, N_("Print version information and exit."), NULL },
+		{ NULL }
+	};
+
+	GOptionContext *context;
+	GError* error = NULL;
+	context = g_option_context_new(_("[URI] [MAGNET-LINK]..."));
+	g_option_context_add_main_entries(context, entries, NULL);
+	// with gtk_get_option_group(TRUE) we don't need to call gtk_init with argc & argv in main.
+	g_option_context_add_group(context, gtk_get_option_group(TRUE));
+	if (!g_option_context_parse(context, argc, argv, &error))
+	{
+		g_print(_("Option parsing failed: %s\n"), error->message);
+		return FALSE;
+	}
+	else
+	{
+		if (show)
+			args->show = TRUE;
+		if (refresh)
+			args->refresh = TRUE;
+		if (version)
+			args->version = TRUE;
+		if (existing)
+			args->existing = TRUE;
+		if (magnet)
+		{
+			int i = 0;
+			for (gchar* it = magnet[0]; it != NULL; it = magnet[++i])
+				args->magnets.push_back(std::string(it));
+			g_strfreev(magnet);
+		}
+		if (address)
+		{
+			int i = 0;
+			for (gchar* it = address[0]; it != NULL; it = address[++i])
+				args->urls.push_back(std::string(it));
+			g_strfreev(address);
+		}
+
+		// Handle extra 'file' arguments passed to commandline
+		parseExtraArguments(*argc, *argv, args);
+	}
+	g_option_context_free(context);
+
+	return TRUE;
+}
+
+int handleArguments(const CommandlineArgs &args) 
+{
+
+	int retval = 1;
+	if (args.refresh)
+		retval = WulforUtil::writeIPCCommand("refresh");
+	for (std::vector<std::string>::const_iterator it = args.magnets.begin();
+			retval > 0 && it != args.magnets.end(); ++it)
+	{
+		retval = WulforUtil::writeIPCCommand(std::string("magnet ") + *it);
+	}
+	for (std::vector<std::string>::const_iterator it = args.urls.begin();
+			retval > 0 && it != args.urls.end(); ++it)
+	{
+		retval = WulforUtil::writeIPCCommand(std::string("connect ") + *it);
+	}
+
+	if (retval > 0 && args.show) 
+	{
+		retval = WulforUtil::writeIPCCommand("show");
+	}
+
+	return retval;
+}
+
 int main(int argc, char *argv[])
 {
+	CommandlineArgs args;
 	// Initialize i18n support
 	bindtextdomain("linuxdcpp", _DATADIR "/locale");
 	textdomain("linuxdcpp");
 	bind_textdomain_codeset("linuxdcpp", "UTF-8");
 
-	printVersionInfo();
 
-	if (!WulforUtil::parseArguments(&argc, &argv))
+	if (!parseArguments(&argc, &argv, &args))
 	{
 		return -1;
 	}
 
-	if (WulforUtil::startArguments.version)
+	if (args.version)
 	{
+		printVersionInfo();
 		return 0;
 	}
 
 	// Check if profile is locked
 	if (WulforUtil::profileIsLocked())
 	{
-		bool commandGiven = WulforUtil::startArguments.refresh;
-		int retval = 1;
-		if (WulforUtil::startArguments.refresh)
-			retval = WulforUtil::writeIPCCommand("refresh");
-		for (std::vector<std::string>::iterator it = WulforUtil::startArguments.magnets.begin();
-			retval > 0 && it != WulforUtil::startArguments.magnets.end(); ++it)
-		{
-			retval = WulforUtil::writeIPCCommand(std::string("magnet ") + *it);
-			commandGiven = TRUE;
-		}
-		for (std::vector<std::string>::iterator it = WulforUtil::startArguments.urls.begin();
-			retval > 0 && it != WulforUtil::startArguments.urls.end(); ++it)
-		{
-			retval = WulforUtil::writeIPCCommand(std::string("connect ") + *it);
-			commandGiven = TRUE;
-		}
-
-		if (retval > 0 && WulforUtil::startArguments.show) 
-		{
-			return WulforUtil::writeIPCCommand("show");
-		}
+		int retval = handleArguments(args);
 
 		if (retval < 0) 
 		{
-			std::cout << _("Failed to talk to running LinuxDC++:") <<  dcpp::Util::translateError(retval) << std::endl;
+			std::cout << _("Failed to talk to running LinuxDC++: ") <<  dcpp::Util::translateError(retval) << std::endl;
+			return -1;
 		}
 
-		if (!commandGiven) 	// If no arguments were given show the profile lock error. Should we make show the default and remove the lock error message?
-		{			
-			gtk_init(&argc, &argv);
-			std::string message = _("Only one instance of LinuxDC++ is allowed per profile");
+		if (retval == 1 && WulforUtil::writeIPCCommand("show") <= 0)	
+		{
+			// Show profile lock error only if profile is locked and talking to running instance
+			// fails for some reason
+			std::string message = _("Only one instance of LinuxDC++ is allowed per profile. Also failed to talk to already running instance for some reason");
 
 			GtkWidget *dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", message.c_str());
 			gtk_dialog_run(GTK_DIALOG(dialog));
@@ -118,6 +208,14 @@
 		return 0;
 	}
 
+	if (args.existing) // If we're still here and --existing was given, bail out since no running instance was found
+	{
+		std::cout << _("No running instance found") << std::endl;
+		return 0;
+	}
+
+	printVersionInfo();
+
 	// Start the DC++ client core
 	dcpp::startup(callBack, NULL);
 
@@ -125,7 +223,6 @@
 
 	g_thread_init(NULL);
 	gdk_threads_init();
-	gtk_init(&argc, &argv);
 	glade_init();
 	g_set_application_name(_("LinuxDC++"));
 
@@ -133,6 +230,7 @@
 
 	WulforSettingsManager::newInstance();
 	WulforManager::start();
+	handleArguments(args);
 	gdk_threads_enter();
 	gtk_main();
 	gdk_threads_leave();