aboutsummaryrefslogtreecommitdiff
path: root/src/daemon.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon.c')
-rw-r--r--src/daemon.c315
1 files changed, 315 insertions, 0 deletions
diff --git a/src/daemon.c b/src/daemon.c
new file mode 100644
index 00000000..f3949276
--- /dev/null
+++ b/src/daemon.c
@@ -0,0 +1,315 @@
1/*
2 This file is part of GNUnet.
3 (C) 2005 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file src/daemon.c
23 * @brief code for gnunet-gtk gnunetd interaction
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "daemon.h"
29#include "main.h"
30#include "helper.h"
31#ifndef MINGW
32 #include <sys/wait.h>
33#endif
34#include <GNUnet/gnunet_util.h>
35#include <GNUnet/gnunet_protocols.h>
36
37/**
38 * Checks if gnunetd is running
39 *
40 * NOTE: Uses CS_PROTO_CLIENT_COUNT query to determine if
41 * gnunetd is running
42 */
43static int checkDaemonRunning(void) {
44 GNUNET_TCP_SOCKET * sock;
45 CS_HEADER csHdr;
46 int ret;
47
48 sock = getClientSocket();
49 if(sock == NULL) {
50 BREAK();
51 return SYSERR;
52 }
53
54 csHdr.size
55 = htons(sizeof(CS_HEADER));
56 csHdr.type
57 = htons(CS_PROTO_CLIENT_COUNT);
58 if (SYSERR == writeToSocket(sock,
59 &csHdr)) {
60 LOG(LOG_DEBUG,
61 _("gnunetd is NOT running.\n"));
62 releaseClientSocket(sock);
63 return SYSERR;
64 }
65 if (SYSERR == readTCPResult(sock,
66 &ret)) {
67 releaseClientSocket(sock);
68 return SYSERR;
69 }
70 releaseClientSocket(sock);
71
72 return OK;
73}
74
75
76
77#if LINUX || OSX || SOLARIS || SOMEBSD
78static int launchWithExec() {
79 pid_t pid;
80
81 pid = fork();
82 if (pid == 0) {
83 char * args[4];
84 char * path;
85 char * cp;
86
87 path = NULL;
88 cp = getConfigurationString("MAIN",
89 "ARGV[0]");
90 if (cp != NULL) {
91 int i = strlen(cp);
92 while ( (i >= 0) &&
93 (cp[i] != DIR_SEPARATOR) )
94 i--;
95 if ( i != -1 ) {
96 cp[i+1] = '\0';
97 path = MALLOC(i+1+strlen("gnunetd"));
98 strcpy(path, cp);
99 strcat(path, "gnunetd");
100 args[0] = path;
101 FREE(cp);
102 } else {
103 args[0] = "gnunetd";
104 }
105 }
106 cp = getConfigurationString("GNUNET-GTK",
107 "GNUNETD-CONFIG");
108 if (cp != NULL) {
109 args[1] = "-c";
110 args[2] = cp;
111 } else {
112 args[1] = NULL;
113 }
114 args[3] = NULL;
115 errno = 0;
116 nice(10); /* return value is not well-defined */
117 if (errno != 0)
118 LOG_STRERROR(LOG_WARNING, "nice");
119 if (path != NULL)
120 execv(path,
121 args);
122 else
123 execvp("gnunetd",
124 args);
125 LOG_STRERROR(LOG_FAILURE, "exec");
126 LOG(LOG_FAILURE,
127 _("Attempted path to '%s' was '%s'.\n"),
128 "gnunetd",
129 (path == NULL) ? "gnunetd" : path);
130 FREENONNULL(path); /* yeah, right, like we're likely to get
131 here... */
132 FREENONNULL(args[1]);
133 _exit(-1);
134 } else {
135 pid_t ret;
136 int status;
137
138 ret = waitpid(pid, &status, 0);
139 if (ret == -1) {
140 LOG_STRERROR(LOG_ERROR, "waitpid");
141 return SYSERR;
142 }
143 if ( (WIFEXITED(status) &&
144 (0 != WEXITSTATUS(status)) ) ) {
145 guiMessage(_("Starting gnunetd failed, error code: %d"),
146 WEXITSTATUS(status));
147 return SYSERR;
148 }
149#ifdef WCOREDUMP
150 if (WCOREDUMP(status)) {
151 guiMessage(_("Starting gnunetd failed (core dumped)."));
152 return SYSERR;
153 }
154#endif
155 if (WIFSIGNALED(status) ||
156 WTERMSIG(status) ) {
157 guiMessage(_("Starting gnunetd failed (aborted by signal)."));
158 return SYSERR;
159 }
160 return OK;
161 }
162}
163#endif
164
165static int doLaunch() {
166
167#if LINUX || OSX || SOLARIS || SOMEBSD
168 return launchWithExec();
169#elif MINGW
170 char szCall[_MAX_PATH + 1], szWd[_MAX_PATH + 1], szCWd[_MAX_PATH + 1];
171 char *args[1];
172
173 conv_to_win_path("/bin/gnunetd.exe", szCall);
174 conv_to_win_path("/bin", szWd);
175 _getcwd(szCWd, _MAX_PATH);
176
177 chdir(szWd);
178 args[0] = NULL;
179 spawnvp(_P_NOWAIT, szCall, (const char *const *) args);
180 chdir(szCWd);
181
182 return OK;
183#else
184 /* any system out there that does not support THIS!? */
185 system("gnunetd"); /* we may not have nice,
186 so let's be minimalistic here. */
187 return OK;
188#endif
189}
190
191/**
192 * Launch gnunetd w/ checks
193 */
194void on_startDaemon_clicked(GtkWidget * widget,
195 gpointer data) {
196 if (OK == checkDaemonRunning() ) {
197 cronCheckDaemon(NULL);
198 return;
199 } else {
200 addLogEntry(_("Launching gnunetd..."));
201 doLaunch();
202 }
203}
204
205/**
206 * Kill gnunetd
207 */
208void on_stopDaemon_clicked(GtkWidget * widget,
209 gpointer data) {
210 if (OK == checkDaemonRunning() ) {
211 GNUNET_TCP_SOCKET * sock;
212 CS_HEADER csHdr;
213 int ret;
214
215 sock = getClientSocket();
216 if (sock == NULL) {
217 cronCheckDaemon(NULL);
218 /* well, probably already dead */
219 return;
220 }
221 csHdr.size
222 = htons(sizeof(CS_HEADER));
223 csHdr.type
224 = htons(CS_PROTO_SHUTDOWN_REQUEST);
225 if (SYSERR == writeToSocket(sock,
226 &csHdr)) {
227 guiMessage(_("Error sending shutdown request to gnunetd."));
228 releaseClientSocket(sock);
229 cronCheckDaemon(NULL);
230 return;
231 }
232 if (SYSERR == readTCPResult(sock,
233 &ret)) {
234 guiMessage(_("Error reading shutdown confirmation from gnunetd."));
235 releaseClientSocket(sock);
236 cronCheckDaemon(NULL);
237 return;
238 }
239 if (ret == OK) {
240 static GtkWidget * killEntry;
241 killEntry
242 = glade_xml_get_widget(mainXML,
243 "stopDaemon");
244 gtk_widget_set_sensitive(killEntry, FALSE);
245 addLogEntry(_("Terminating gnunetd..."));
246 } else {
247 guiMessage(_("gnunetd refused to shut down (error code '%d')."),
248 ret);
249 }
250 releaseClientSocket(sock);
251 }
252 cronCheckDaemon(NULL);
253}
254
255static gint doUpdateMenus(SaveCall * call) {
256 static GtkWidget * killEntry = NULL;
257 static GtkWidget * launchEntry = NULL;
258 static GtkWidget * statsEntryYes = NULL;
259 static GtkWidget * statsEntryNo = NULL;
260 static int once = 1;
261 static int isLocal;
262 char * host;
263 int ret;
264
265 ret = * (int*) call->args;
266 if (once) {
267 once = 0;
268 killEntry
269 = glade_xml_get_widget(mainXML,
270 "stopDaemon");
271 launchEntry
272 = glade_xml_get_widget(mainXML,
273 "startDaemon");
274 statsEntryYes
275 = glade_xml_get_widget(mainXML,
276 "statusPixmapYes");
277 statsEntryNo
278 = glade_xml_get_widget(mainXML,
279 "statusPixmapNo");
280 host = getConfigurationString("NETWORK",
281 "HOST");
282 if ( (host == NULL) ||
283 (strcmp(host, "localhost")==0) )
284 isLocal = TRUE;
285 else
286 isLocal = FALSE;
287 FREENONNULL(host);
288 }
289 if (ret == SYSERR) {
290 gtk_widget_hide(statsEntryYes);
291 gtk_widget_show_all(statsEntryNo);
292 gtk_widget_set_sensitive(killEntry, FALSE);
293 gtk_widget_set_sensitive(launchEntry, (TRUE & isLocal) );
294 } else {
295 gtk_widget_hide(statsEntryNo);
296 gtk_widget_show_all(statsEntryYes);
297 gtk_widget_set_sensitive(killEntry, TRUE);
298 gtk_widget_set_sensitive(launchEntry, FALSE);
299 }
300 gtkSaveCallDone(call->sem);
301 return FALSE;
302}
303
304void cronCheckDaemon(void * dummy) {
305 static int last = 42;
306 int ret;
307
308 ret = checkDaemonRunning();
309 if (ret != last) {
310 last = ret;
311 gtkSaveCall((GtkFunction) doUpdateMenus, &ret);
312 }
313}
314
315/* end of daemon.c */