1 /*
2 * Copyright © 2004-2010 Jens Oknelid, paskharen@gmail.com
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * In addition, as a special exception, compiling, linking, and/or
19 * using OpenSSL with this program is allowed.
20 */
21
22 #include <gtk/gtk.h>
23 #include <glib/gi18n.h>
24 #include <dcpp/stdinc.h>
25 #include <dcpp/DCPlusPlus.h>
26 #include "bacon-message-connection.h"
27 #include "settingsmanager.hh"
28 #include "wulformanager.hh"
29 #include "WulforUtil.hh"
30 #include <iostream>
31 #include <signal.h>
32
33 #define GUI_LOCALE_DIR LOCALE_DIR
34
35 #define GUI_PACKAGE "eiskaltdcpp-gtk"
36
37 #include "VersionGlobal.h"
38
39 #ifdef ENABLE_STACKTRACE
40 #include "extra/stacktrace.h"
41 #endif // ENABLE_STACKTRACE
42
printHelp()43 void printHelp()
44 {
45 printf(_(
46 "Using:\n"
47 " eiskaltdcpp-gtk <magnet link> <dchub://link> <adc(s)://link>\n"
48 " eiskaltdcpp-gtk <Key>\n"
49 "EiskaltDC++ is a cross-platform program that uses the Direct Connect and ADC protocol.\n"
50 "\n"
51 "Keys:\n"
52 " -h, --help\t Show this message\n"
53 " -V, --version\t Show version string\n"
54 )
55 );
56 }
57
printVersion()58 void printVersion()
59 {
60 printf("%s version: %s (%s)\n", APPNAME, EISKALTDCPP_VERSION, EISKALTDCPP_VERSION_SFX);
61 printf("GTK+ version: %d.%d.%d\n", gtk_major_version, gtk_minor_version, gtk_micro_version);
62 printf("Glib version: %d.%d.%d\n", glib_major_version, glib_minor_version, glib_micro_version);
63 }
64
65 BaconMessageConnection *connection = NULL;
66
receiver(const char * link,gpointer data)67 void receiver(const char *link, gpointer data)
68 {
69 g_return_if_fail(link != NULL);
70 WulforManager::get()->onReceived_gui(link);
71 }
72
callBack(void * x,const std::string & a)73 void callBack(void* x, const std::string& a)
74 {
75 std::cout << _("Loading: ") << a << std::endl;
76 }
77
catchSIG(int sigNum)78 void catchSIG(int sigNum) {
79 psignal(sigNum, _("Catching signal "));
80
81 #ifdef ENABLE_STACKTRACE
82 printBacktrace(sigNum);
83 #endif // ENABLE_STACKTRACE
84
85 raise(SIGINT);
86
87 std::abort();
88 }
89
90 template <int sigNum = 0, int ... Params>
catchSignals()91 void catchSignals() {
92 if (!sigNum)
93 return;
94
95 psignal(sigNum, _("Installing handler for"));
96
97 signal(sigNum, catchSIG);
98
99 catchSignals<Params ... >();
100 }
101
installHandlers()102 void installHandlers(){
103 struct sigaction sa;
104 memset(&sa, 0, sizeof(sa));
105 sa.sa_handler = SIG_IGN;
106
107 if (sigaction(SIGPIPE, &sa, NULL) == -1)
108 printf(_("Cannot handle SIGPIPE\n"));
109 else {
110 sigset_t set;
111 sigemptyset (&set);
112 sigaddset (&set, SIGPIPE);
113 pthread_sigmask(SIG_BLOCK, &set, NULL);
114 }
115
116 catchSignals<SIGSEGV, SIGABRT, SIGBUS, SIGTERM>();
117
118 printf(_("Signal handlers installed.\n"));
119 }
120
main(int argc,char * argv[])121 int main(int argc, char *argv[])
122 {
123
124 for (int i = 0; i < argc; i++){
125 if (!strcmp(argv[i],"--help") || !strcmp(argv[i],"-h")){
126 printHelp();
127 exit(0);
128 }
129 else if (!strcmp(argv[i],"--version") || !strcmp(argv[i],"-V")){
130 printVersion();
131 exit(0);
132 }
133 }
134
135 // Initialize i18n support
136 bindtextdomain(GUI_PACKAGE, GUI_LOCALE_DIR);
137 textdomain(GUI_PACKAGE);
138 bind_textdomain_codeset(GUI_PACKAGE, "UTF-8");
139
140 connection = bacon_message_connection_new(GUI_PACKAGE);
141
142 dcdebug(connection ? "eiskaltdcpp-gtk: connection yes...\n" : "eiskaltdcpp-gtk: connection no...\n");
143
144 // Check if profile is locked
145 if (WulforUtil::profileIsLocked())
146 {
147 if (!bacon_message_connection_get_is_server(connection))
148 {
149 dcdebug("eiskaltdcpp-gtk: is client...\n");
150
151 if (argc > 1)
152 {
153 dcdebug("eiskaltdcpp-gtk: send %s\n", argv[1]);
154 bacon_message_connection_send(connection, argv[1]);
155 }
156 }
157
158 bacon_message_connection_free(connection);
159
160 return 0;
161 }
162
163 if (bacon_message_connection_get_is_server(connection))
164 {
165 dcdebug("eiskaltdcpp-gtk: is server...\n");
166 bacon_message_connection_set_callback(connection, receiver, NULL);
167 }
168
169 // Start the DC++ client core
170 dcpp::startup(callBack, NULL);
171
172 dcpp::TimerManager::getInstance()->start();
173
174 #if !GLIB_CHECK_VERSION(2,32,0)
175 g_thread_init(NULL);
176 #endif
177 gdk_threads_init();
178 gtk_init(&argc, &argv);
179 g_set_application_name("EiskaltDC++ Gtk");
180
181 installHandlers();
182
183 WulforSettingsManager::newInstance();
184 WulforManager::start(argc, argv);
185 gdk_threads_enter();
186 gtk_main();
187 bacon_message_connection_free(connection);
188 gdk_threads_leave();
189 WulforManager::stop();
190 WulforSettingsManager::deleteInstance();
191
192 std::cout << _("Shutting down libdcpp...") << std::endl;
193 dcpp::shutdown();
194 std::cout << _("Quit...") << std::endl;
195 return 0;
196 }
197