aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxrs <xrs@mail36.net>2019-09-28 19:11:33 +0200
committerxrs <xrs@mail36.net>2019-09-28 19:11:33 +0200
commitf5759dbc478ddf83b8a1d31d1580c845b9480633 (patch)
tree2087591b5f0f010df1c6b74e4d3874ac7ee2c9e7
parent3df1c58ee5e23f59f71b3e495e6b863cda27ed5f (diff)
parent31aee41701fa2cd92ec566bd459e3425ee1f0b7d (diff)
downloadgnunet-f5759dbc478ddf83b8a1d31d1580c845b9480633.tar.gz
gnunet-f5759dbc478ddf83b8a1d31d1580c845b9480633.zip
Merge branch 'master' of ssh://git.gnunet.org/gnunet
-rw-r--r--README2
-rw-r--r--src/arm/arm.h45
-rw-r--r--src/arm/arm_api.c933
-rw-r--r--src/arm/arm_monitor_api.c8
-rw-r--r--src/arm/gnunet-arm.c1044
-rw-r--r--src/arm/gnunet-service-arm.c2359
-rw-r--r--src/arm/test_exponential_backoff.c2
-rw-r--r--src/arm/test_gnunet_service_arm.c10
-rw-r--r--src/datastore/plugin_datastore_mysql.c2
-rw-r--r--src/dns/gnunet-helper-dns.c4
-rw-r--r--src/gns/gnunet-gns.c266
-rw-r--r--src/include/gnunet_arm_service.h84
-rw-r--r--src/include/gnunet_client_lib.h27
-rw-r--r--src/include/gnunet_disk_lib.h189
-rw-r--r--src/include/gnunet_os_lib.h134
-rw-r--r--src/include/gnunet_scheduler_lib.h195
-rw-r--r--src/include/gnunet_service_lib.h92
-rw-r--r--src/util/client.c1000
-rw-r--r--src/util/service.c2181
19 files changed, 4707 insertions, 3870 deletions
diff --git a/README b/README
index e15cd9c26..e23d006b5 100644
--- a/README
+++ b/README
@@ -326,7 +326,7 @@ You can avoid running 'make install' as root if you run configure
326with the "--with-sudo=yes" option and have extensive sudo rights 326with the "--with-sudo=yes" option and have extensive sudo rights
327(can run "chmod +s" and "chown" via 'sudo'). If you run 'make install' 327(can run "chmod +s" and "chown" via 'sudo'). If you run 'make install'
328as a normal user without sudo rights (or the configure option), 328as a normal user without sudo rights (or the configure option),
329certain binaries that require additional priviledges will not be 329certain binaries that require additional privileges will not be
330installed properly (and autonomous NAT traversal, WLAN, DNS/GNS and 330installed properly (and autonomous NAT traversal, WLAN, DNS/GNS and
331the VPN will then not work). 331the VPN will then not work).
332 332
diff --git a/src/arm/arm.h b/src/arm/arm.h
index 983586060..bddcd7cf3 100644
--- a/src/arm/arm.h
+++ b/src/arm/arm.h
@@ -93,6 +93,44 @@ struct GNUNET_ARM_ResultMessage {
93 uint32_t result; 93 uint32_t result;
94}; 94};
95 95
96struct GNUNET_ARM_ServiceInfoMessage {
97 /**
98 * String pool index for the service's name.
99 */
100 uint16_t name_index;
101
102 /**
103 * String pool index for the service's binary.
104 */
105 uint16_t binary_index;
106
107 /**
108 * Last process exit status.
109 */
110 int16_t last_exit_status;
111
112 /**
113 * Padding.
114 */
115 uint16_t padding;
116
117 /**
118 * Status from the 'enum GNUNET_ARM_ServiceStatus'
119 */
120 uint32_t status;
121
122 /**
123 * Time when the sevice will be restarted, if applicable
124 * to the current status.
125 */
126 struct GNUNET_TIME_AbsoluteNBO restart_at;
127
128 /**
129 * Time when the sevice was first started, if applicable.
130 */
131 struct GNUNET_TIME_AbsoluteNBO last_started_at;
132};
133
96/** 134/**
97 * Reply from ARM to client for the 135 * Reply from ARM to client for the
98 * #GNUNET_MESSAGE_TYPE_ARM_LIST request followed by count 136 * #GNUNET_MESSAGE_TYPE_ARM_LIST request followed by count
@@ -107,10 +145,13 @@ struct GNUNET_ARM_ListResultMessage {
107 struct GNUNET_ARM_Message arm_msg; 145 struct GNUNET_ARM_Message arm_msg;
108 146
109 /** 147 /**
110 * Number of '\0' terminated strings that follow 148 * Number of 'struct GNUNET_ARM_ServiceInfoMessage' that
111 * this message. 149 * are at the end of this message.
112 */ 150 */
113 uint16_t count; 151 uint16_t count;
152
153 /* struct GNUNET_ARM_ServiceInfoMessage[count]; */
154 /* pool of 0-terminated strings */
114}; 155};
115 156
116GNUNET_NETWORK_STRUCT_END 157GNUNET_NETWORK_STRUCT_END
diff --git a/src/arm/arm_api.c b/src/arm/arm_api.c
index b42c95dc0..da7268f67 100644
--- a/src/arm/arm_api.c
+++ b/src/arm/arm_api.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2009, 2010, 2012, 2013, 2016 GNUnet e.V. 3 Copyright (C) 2009, 2010, 2012, 2013, 2016, 2019 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -30,14 +30,15 @@
30#include "gnunet_protocols.h" 30#include "gnunet_protocols.h"
31#include "arm.h" 31#include "arm.h"
32 32
33#define LOG(kind, ...) GNUNET_log_from(kind, "arm-api", __VA_ARGS__) 33#define LOG(kind, ...) GNUNET_log_from (kind, "arm-api", __VA_ARGS__)
34 34
35 35
36/** 36/**
37 * Entry in a doubly-linked list of operations awaiting for replies 37 * Entry in a doubly-linked list of operations awaiting for replies
38 * (in-order) from the ARM service. 38 * (in-order) from the ARM service.
39 */ 39 */
40struct GNUNET_ARM_Operation { 40struct GNUNET_ARM_Operation
41{
41 /** 42 /**
42 * This is a doubly-linked list. 43 * This is a doubly-linked list.
43 */ 44 */
@@ -84,6 +85,11 @@ struct GNUNET_ARM_Operation {
84 enum GNUNET_ARM_Result starting_ret; 85 enum GNUNET_ARM_Result starting_ret;
85 86
86 /** 87 /**
88 * File descriptor to close on operation stop, if not NULL.
89 */
90 struct GNUNET_DISK_FileHandle *rfd;
91
92 /**
87 * Is this an operation to stop the ARM service? 93 * Is this an operation to stop the ARM service?
88 */ 94 */
89 int is_arm_stop; 95 int is_arm_stop;
@@ -93,7 +99,8 @@ struct GNUNET_ARM_Operation {
93/** 99/**
94 * Handle for interacting with ARM. 100 * Handle for interacting with ARM.
95 */ 101 */
96struct GNUNET_ARM_Handle { 102struct GNUNET_ARM_Handle
103{
97 /** 104 /**
98 * Our connection to the ARM service. 105 * Our connection to the ARM service.
99 */ 106 */
@@ -164,7 +171,7 @@ struct GNUNET_ARM_Handle {
164 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure 171 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
165 */ 172 */
166static int 173static int
167reconnect_arm(struct GNUNET_ARM_Handle *h); 174reconnect_arm (struct GNUNET_ARM_Handle *h);
168 175
169 176
170/** 177/**
@@ -173,12 +180,12 @@ reconnect_arm(struct GNUNET_ARM_Handle *h);
173 * @param cls the `struct GNUNET_ARM_Handle` 180 * @param cls the `struct GNUNET_ARM_Handle`
174 */ 181 */
175static void 182static void
176reconnect_arm_task(void *cls) 183reconnect_arm_task (void *cls)
177{ 184{
178 struct GNUNET_ARM_Handle *h = cls; 185 struct GNUNET_ARM_Handle *h = cls;
179 186
180 h->reconnect_task = NULL; 187 h->reconnect_task = NULL;
181 reconnect_arm(h); 188 reconnect_arm (h);
182} 189}
183 190
184 191
@@ -189,31 +196,39 @@ reconnect_arm_task(void *cls)
189 * @param h our handle 196 * @param h our handle
190 */ 197 */
191static void 198static void
192reconnect_arm_later(struct GNUNET_ARM_Handle *h) 199reconnect_arm_later (struct GNUNET_ARM_Handle *h)
193{ 200{
194 struct GNUNET_ARM_Operation *op; 201 struct GNUNET_ARM_Operation *op;
195 202
196 if (NULL != h->mq) 203 if (NULL != h->mq)
197 { 204 {
198 GNUNET_MQ_destroy(h->mq); 205 GNUNET_MQ_destroy (h->mq);
199 h->mq = NULL; 206 h->mq = NULL;
200 } 207 }
201 h->currently_up = GNUNET_NO; 208 h->currently_up = GNUNET_NO;
202 GNUNET_assert(NULL == h->reconnect_task); 209 GNUNET_assert (NULL == h->reconnect_task);
203 h->reconnect_task = 210 h->reconnect_task =
204 GNUNET_SCHEDULER_add_delayed(h->retry_backoff, &reconnect_arm_task, h); 211 GNUNET_SCHEDULER_add_delayed (h->retry_backoff,
212 &reconnect_arm_task,
213 h);
205 while (NULL != (op = h->operation_pending_head)) 214 while (NULL != (op = h->operation_pending_head))
206 { 215 {
207 if (NULL != op->result_cont) 216 if (NULL != op->result_cont)
208 op->result_cont(op->cont_cls, GNUNET_ARM_REQUEST_DISCONNECTED, 0); 217 op->result_cont (op->cont_cls,
209 if (NULL != op->list_cont) 218 GNUNET_ARM_REQUEST_DISCONNECTED,
210 op->list_cont(op->cont_cls, GNUNET_ARM_REQUEST_DISCONNECTED, 0, NULL); 219 0);
211 GNUNET_ARM_operation_cancel(op); 220 if (NULL != op->list_cont)
212 } 221 op->list_cont (op->cont_cls,
213 GNUNET_assert(NULL == h->operation_pending_head); 222 GNUNET_ARM_REQUEST_DISCONNECTED,
214 h->retry_backoff = GNUNET_TIME_STD_BACKOFF(h->retry_backoff); 223 0,
224 NULL);
225 GNUNET_ARM_operation_cancel (op);
226 }
227 GNUNET_assert (NULL == h->operation_pending_head);
228 h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff);
215 if (NULL != h->conn_status) 229 if (NULL != h->conn_status)
216 h->conn_status(h->conn_status_cls, GNUNET_NO); 230 h->conn_status (h->conn_status_cls,
231 GNUNET_NO);
217} 232}
218 233
219 234
@@ -225,11 +240,11 @@ reconnect_arm_later(struct GNUNET_ARM_Handle *h)
225 * @return NULL if not found 240 * @return NULL if not found
226 */ 241 */
227static struct GNUNET_ARM_Operation * 242static struct GNUNET_ARM_Operation *
228find_op_by_id(struct GNUNET_ARM_Handle *h, uint64_t id) 243find_op_by_id (struct GNUNET_ARM_Handle *h,
244 uint64_t id)
229{ 245{
230 struct GNUNET_ARM_Operation *result; 246 for (struct GNUNET_ARM_Operation *result = h->operation_pending_head;
231 247 NULL != result;
232 for (result = h->operation_pending_head; NULL != result;
233 result = result->next) 248 result = result->next)
234 if (id == result->id) 249 if (id == result->id)
235 return result; 250 return result;
@@ -244,7 +259,8 @@ find_op_by_id(struct GNUNET_ARM_Handle *h, uint64_t id)
244 * @param res the message received from the arm service 259 * @param res the message received from the arm service
245 */ 260 */
246static void 261static void
247handle_arm_result(void *cls, const struct GNUNET_ARM_ResultMessage *res) 262handle_arm_result (void *cls,
263 const struct GNUNET_ARM_ResultMessage *res)
248{ 264{
249 struct GNUNET_ARM_Handle *h = cls; 265 struct GNUNET_ARM_Handle *h = cls;
250 struct GNUNET_ARM_Operation *op; 266 struct GNUNET_ARM_Operation *op;
@@ -253,75 +269,123 @@ handle_arm_result(void *cls, const struct GNUNET_ARM_ResultMessage *res)
253 GNUNET_ARM_ResultCallback result_cont; 269 GNUNET_ARM_ResultCallback result_cont;
254 void *result_cont_cls; 270 void *result_cont_cls;
255 271
256 id = GNUNET_ntohll(res->arm_msg.request_id); 272 id = GNUNET_ntohll (res->arm_msg.request_id);
257 op = find_op_by_id(h, id); 273 op = find_op_by_id (h,
274 id);
258 if (NULL == op) 275 if (NULL == op)
276 {
277 LOG (GNUNET_ERROR_TYPE_DEBUG,
278 "Message with unknown id %llu\n",
279 (unsigned long long) id);
280 return;
281 }
282
283 result = (enum GNUNET_ARM_Result) ntohl (res->result);
284 if ( (GNUNET_YES == op->is_arm_stop) &&
285 (GNUNET_ARM_RESULT_STOPPING == result) )
286 {
287 /* special case: if we are stopping 'gnunet-service-arm', we do not just
288 wait for the result message, but also wait for the service to close
289 the connection (and then we have to close our client handle as well);
290 this is done by installing a different receive handler, waiting for
291 the connection to go down */
292 if (NULL != h->thm)
259 { 293 {
260 LOG(GNUNET_ERROR_TYPE_DEBUG, 294 GNUNET_break (0);
261 "Message with unknown id %llu\n", 295 op->result_cont (h->thm->cont_cls,
262 (unsigned long long)id); 296 GNUNET_ARM_REQUEST_SENT_OK,
263 return; 297 GNUNET_ARM_RESULT_IS_NOT_KNOWN);
264 } 298 GNUNET_free (h->thm);
265
266 result = (enum GNUNET_ARM_Result)ntohl(res->result);
267 if ((GNUNET_YES == op->is_arm_stop) && (GNUNET_ARM_RESULT_STOPPING == result))
268 {
269 /* special case: if we are stopping 'gnunet-service-arm', we do not just
270 wait for the result message, but also wait for the service to close
271 the connection (and then we have to close our client handle as well);
272 this is done by installing a different receive handler, waiting for
273 the connection to go down */
274 if (NULL != h->thm)
275 {
276 GNUNET_break(0);
277 op->result_cont(h->thm->cont_cls,
278 GNUNET_ARM_REQUEST_SENT_OK,
279 GNUNET_ARM_RESULT_IS_NOT_KNOWN);
280 GNUNET_free(h->thm);
281 }
282 GNUNET_CONTAINER_DLL_remove(h->operation_pending_head,
283 h->operation_pending_tail,
284 op);
285 h->thm = op;
286 return;
287 } 299 }
300 GNUNET_CONTAINER_DLL_remove (h->operation_pending_head,
301 h->operation_pending_tail,
302 op);
303 h->thm = op;
304 return;
305 }
288 result_cont = op->result_cont; 306 result_cont = op->result_cont;
289 result_cont_cls = op->cont_cls; 307 result_cont_cls = op->cont_cls;
290 GNUNET_ARM_operation_cancel(op); 308 GNUNET_ARM_operation_cancel (op);
291 if (NULL != result_cont) 309 if (NULL != result_cont)
292 result_cont(result_cont_cls, GNUNET_ARM_REQUEST_SENT_OK, result); 310 result_cont (result_cont_cls,
311 GNUNET_ARM_REQUEST_SENT_OK,
312 result);
293} 313}
294 314
295 315
296/** 316/**
297 * Checked that list result message is well-formed. 317 * Read from a string pool.
318 *
319 * @param pool_start start of the string pool
320 * @param pool_size size of the string pool
321 * @param str_index index into the string pool
322 * @returns an index into the string pool, or
323 * NULL if the index is out of bounds
324 */
325static const char *
326pool_get (const char *pool_start,
327 size_t pool_size,
328 size_t str_index)
329{
330 const char *str_start;
331 const char *end;
332
333 if (str_index >= pool_size)
334 return NULL;
335 str_start = pool_start + str_index;
336 end = memchr (str_start, 0, pool_size - str_index);
337 if (NULL == end)
338 return NULL;
339 return str_start;
340}
341
342
343/**
344 * Check that list result message is well-formed.
298 * 345 *
299 * @param cls our `struct GNUNET_ARM_Handle` 346 * @param cls our `struct GNUNET_ARM_Handle`
300 * @param lres the message received from the arm service 347 * @param lres the message received from the arm service
301 * @return #GNUNET_OK if message is well-formed 348 * @return #GNUNET_OK if message is well-formed
302 */ 349 */
303static int 350static int
304check_arm_list_result(void *cls, 351check_arm_list_result (void *cls,
305 const struct GNUNET_ARM_ListResultMessage *lres) 352 const struct GNUNET_ARM_ListResultMessage *lres)
306{ 353{
307 const char *pos = (const char *)&lres[1]; 354 uint16_t rcount = ntohs (lres->count);
308 uint16_t rcount = ntohs(lres->count); 355 uint16_t msize = ntohs (lres->arm_msg.header.size) - sizeof(*lres);
309 uint16_t msize = ntohs(lres->arm_msg.header.size) - sizeof(*lres); 356 struct GNUNET_ARM_ServiceInfoMessage *ssm;
310 uint16_t size_check; 357 size_t pool_size;
311 358 char *pool_start;
312 (void)cls; 359
313 size_check = 0; 360 (void) cls;
361 if ((rcount * sizeof (struct GNUNET_ARM_ServiceInfoMessage) > msize))
362 {
363 GNUNET_break_op (0);
364 return GNUNET_NO;
365 }
366 ssm = (struct GNUNET_ARM_ServiceInfoMessage *) &lres[1];
367 pool_start = (char *) (ssm + rcount);
368 pool_size = msize - (rcount * sizeof (struct GNUNET_ARM_ServiceInfoMessage));
314 for (unsigned int i = 0; i < rcount; i++) 369 for (unsigned int i = 0; i < rcount; i++)
370 {
371 uint16_t name_index = ntohs (ssm->name_index);
372 uint16_t binary_index = ntohs (ssm->binary_index);
373 if (NULL == pool_get (pool_start,
374 pool_size,
375 name_index))
315 { 376 {
316 const char *end = memchr(pos, 0, msize - size_check); 377 GNUNET_break_op (0);
317 if (NULL == end) 378 return GNUNET_NO;
318 {
319 GNUNET_break(0);
320 return GNUNET_SYSERR;
321 }
322 size_check += (end - pos) + 1;
323 pos = end + 1;
324 } 379 }
380 if (NULL == pool_get (pool_start,
381 pool_size,
382 binary_index))
383 {
384 GNUNET_break_op (0);
385 return GNUNET_NO;
386 }
387 ssm++;
388 }
325 return GNUNET_OK; 389 return GNUNET_OK;
326} 390}
327 391
@@ -333,41 +397,65 @@ check_arm_list_result(void *cls,
333 * @param lres the message received from the arm service 397 * @param lres the message received from the arm service
334 */ 398 */
335static void 399static void
336handle_arm_list_result(void *cls, 400handle_arm_list_result (void *cls,
337 const struct GNUNET_ARM_ListResultMessage *lres) 401 const struct GNUNET_ARM_ListResultMessage *lres)
338{ 402{
339 struct GNUNET_ARM_Handle *h = cls; 403 struct GNUNET_ARM_Handle *h = cls;
340 uint16_t rcount = ntohs(lres->count); 404 uint16_t rcount = ntohs (lres->count);
341 const char *list[rcount]; 405 uint16_t msize = ntohs (lres->arm_msg.header.size) - sizeof(*lres);
342 const char *pos = (const char *)&lres[1]; 406 struct GNUNET_ARM_ServiceInfo list[rcount];
343 uint16_t msize = ntohs(lres->arm_msg.header.size) - sizeof(*lres); 407 struct GNUNET_ARM_ServiceInfoMessage *ssm;
344 struct GNUNET_ARM_Operation *op; 408 struct GNUNET_ARM_Operation *op;
345 uint16_t size_check;
346 uint64_t id; 409 uint64_t id;
410 size_t pool_size;
411 char *pool_start;
347 412
348 id = GNUNET_ntohll(lres->arm_msg.request_id); 413 id = GNUNET_ntohll (lres->arm_msg.request_id);
349 op = find_op_by_id(h, id); 414 op = find_op_by_id (h, id);
350 if (NULL == op) 415 if (NULL == op)
351 { 416 {
352 LOG(GNUNET_ERROR_TYPE_DEBUG, 417 LOG (GNUNET_ERROR_TYPE_DEBUG,
353 "Message with unknown id %llu\n", 418 "Message with unknown id %llu\n",
354 (unsigned long long)id); 419 (unsigned long long) id);
355 return; 420 return;
356 } 421 }
357 size_check = 0;
358 for (unsigned int i = 0; i < rcount; i++)
359 {
360 const char *end = memchr(pos, 0, msize - size_check);
361 422
362 /* Assert, as this was already checked in #check_arm_list_result() */ 423 GNUNET_assert ((rcount * sizeof (struct GNUNET_ARM_ServiceInfoMessage) <=
363 GNUNET_assert(NULL != end); 424 msize));
364 list[i] = pos; 425
365 size_check += (end - pos) + 1; 426 ssm = (struct GNUNET_ARM_ServiceInfoMessage *) &lres[1];
366 pos = end + 1; 427 pool_start = (char *) (ssm + rcount);
367 } 428 pool_size = msize - (rcount * sizeof (struct GNUNET_ARM_ServiceInfoMessage));
429
430 for (unsigned int i = 0; i < rcount; i++)
431 {
432 uint16_t name_index = ntohs (ssm->name_index);
433 uint16_t binary_index = ntohs (ssm->binary_index);
434 const char *name;
435 const char *binary;
436
437 GNUNET_assert (NULL != (name = pool_get (pool_start,
438 pool_size,
439 name_index)));
440 GNUNET_assert (NULL != (binary = pool_get (pool_start,
441 pool_size,
442 binary_index)));
443 list[i] = (struct GNUNET_ARM_ServiceInfo) {
444 .name = name,
445 .binary = binary,
446 .status = ntohl (ssm->status),
447 .last_started_at = GNUNET_TIME_absolute_ntoh (ssm->last_started_at),
448 .restart_at = GNUNET_TIME_absolute_ntoh (ssm->restart_at),
449 .last_exit_status = ntohs (ssm->last_exit_status),
450 };
451 ssm++;
452 }
368 if (NULL != op->list_cont) 453 if (NULL != op->list_cont)
369 op->list_cont(op->cont_cls, GNUNET_ARM_REQUEST_SENT_OK, rcount, list); 454 op->list_cont (op->cont_cls,
370 GNUNET_ARM_operation_cancel(op); 455 GNUNET_ARM_REQUEST_SENT_OK,
456 rcount,
457 list);
458 GNUNET_ARM_operation_cancel (op);
371} 459}
372 460
373 461
@@ -378,18 +466,20 @@ handle_arm_list_result(void *cls,
378 * @param msg message received 466 * @param msg message received
379 */ 467 */
380static void 468static void
381handle_confirm(void *cls, const struct GNUNET_MessageHeader *msg) 469handle_confirm (void *cls,
470 const struct GNUNET_MessageHeader *msg)
382{ 471{
383 struct GNUNET_ARM_Handle *h = cls; 472 struct GNUNET_ARM_Handle *h = cls;
384 473
385 (void)msg; 474 (void) msg;
386 LOG(GNUNET_ERROR_TYPE_DEBUG, "Got confirmation from ARM that we are up!\n"); 475 LOG (GNUNET_ERROR_TYPE_DEBUG,
476 "Got confirmation from ARM that we are up!\n");
387 if (GNUNET_NO == h->currently_up) 477 if (GNUNET_NO == h->currently_up)
388 { 478 {
389 h->currently_up = GNUNET_YES; 479 h->currently_up = GNUNET_YES;
390 if (NULL != h->conn_status) 480 if (NULL != h->conn_status)
391 h->conn_status(h->conn_status_cls, GNUNET_YES); 481 h->conn_status (h->conn_status_cls, GNUNET_YES);
392 } 482 }
393} 483}
394 484
395 485
@@ -402,22 +492,23 @@ handle_confirm(void *cls, const struct GNUNET_MessageHeader *msg)
402 * @param error error code 492 * @param error error code
403 */ 493 */
404static void 494static void
405mq_error_handler(void *cls, enum GNUNET_MQ_Error error) 495mq_error_handler (void *cls,
496 enum GNUNET_MQ_Error error)
406{ 497{
407 struct GNUNET_ARM_Handle *h = cls; 498 struct GNUNET_ARM_Handle *h = cls;
408 struct GNUNET_ARM_Operation *op; 499 struct GNUNET_ARM_Operation *op;
409 500
410 (void)error; 501 (void) error;
411 h->currently_up = GNUNET_NO; 502 h->currently_up = GNUNET_NO;
412 if (NULL != (op = h->thm)) 503 if (NULL != (op = h->thm))
413 { 504 {
414 h->thm = NULL; 505 h->thm = NULL;
415 op->result_cont(op->cont_cls, 506 op->result_cont (op->cont_cls,
416 GNUNET_ARM_REQUEST_SENT_OK, 507 GNUNET_ARM_REQUEST_SENT_OK,
417 GNUNET_ARM_RESULT_STOPPED); 508 GNUNET_ARM_RESULT_STOPPED);
418 GNUNET_free(op); 509 GNUNET_free (op);
419 } 510 }
420 reconnect_arm_later(h); 511 reconnect_arm_later (h);
421} 512}
422 513
423 514
@@ -428,39 +519,48 @@ mq_error_handler(void *cls, enum GNUNET_MQ_Error error)
428 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure 519 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
429 */ 520 */
430static int 521static int
431reconnect_arm(struct GNUNET_ARM_Handle *h) 522reconnect_arm (struct GNUNET_ARM_Handle *h)
432{ 523{
433 struct GNUNET_MQ_MessageHandler handlers[] = 524 struct GNUNET_MQ_MessageHandler handlers[] = {
434 { GNUNET_MQ_hd_fixed_size(arm_result, 525 GNUNET_MQ_hd_fixed_size (arm_result,
435 GNUNET_MESSAGE_TYPE_ARM_RESULT, 526 GNUNET_MESSAGE_TYPE_ARM_RESULT,
436 struct GNUNET_ARM_ResultMessage, 527 struct GNUNET_ARM_ResultMessage,
437 h), 528 h),
438 GNUNET_MQ_hd_var_size(arm_list_result, 529 GNUNET_MQ_hd_var_size (arm_list_result,
439 GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT, 530 GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT,
440 struct GNUNET_ARM_ListResultMessage, 531 struct GNUNET_ARM_ListResultMessage,
441 h), 532 h),
442 GNUNET_MQ_hd_fixed_size(confirm, 533 GNUNET_MQ_hd_fixed_size (confirm,
443 GNUNET_MESSAGE_TYPE_ARM_TEST, 534 GNUNET_MESSAGE_TYPE_ARM_TEST,
444 struct GNUNET_MessageHeader, 535 struct GNUNET_MessageHeader,
445 h), 536 h),
446 GNUNET_MQ_handler_end() }; 537 GNUNET_MQ_handler_end ()
538 };
447 struct GNUNET_MessageHeader *test; 539 struct GNUNET_MessageHeader *test;
448 struct GNUNET_MQ_Envelope *env; 540 struct GNUNET_MQ_Envelope *env;
449 541
450 if (NULL != h->mq) 542 if (NULL != h->mq)
451 return GNUNET_OK; 543 return GNUNET_OK;
452 GNUNET_assert(GNUNET_NO == h->currently_up); 544 GNUNET_assert (GNUNET_NO == h->currently_up);
453 h->mq = GNUNET_CLIENT_connect(h->cfg, "arm", handlers, &mq_error_handler, h); 545 h->mq = GNUNET_CLIENT_connect (h->cfg,
546 "arm",
547 handlers,
548 &mq_error_handler,
549 h);
454 if (NULL == h->mq) 550 if (NULL == h->mq)
455 { 551 {
456 LOG(GNUNET_ERROR_TYPE_DEBUG, "GNUNET_CLIENT_connect returned NULL\n"); 552 LOG (GNUNET_ERROR_TYPE_DEBUG,
457 if (NULL != h->conn_status) 553 "GNUNET_CLIENT_connect returned NULL\n");
458 h->conn_status(h->conn_status_cls, GNUNET_SYSERR); 554 if (NULL != h->conn_status)
459 return GNUNET_SYSERR; 555 h->conn_status (h->conn_status_cls,
460 } 556 GNUNET_SYSERR);
461 LOG(GNUNET_ERROR_TYPE_DEBUG, "Sending TEST message to ARM\n"); 557 return GNUNET_SYSERR;
462 env = GNUNET_MQ_msg(test, GNUNET_MESSAGE_TYPE_ARM_TEST); 558 }
463 GNUNET_MQ_send(h->mq, env); 559 LOG (GNUNET_ERROR_TYPE_DEBUG,
560 "Sending TEST message to ARM\n");
561 env = GNUNET_MQ_msg (test,
562 GNUNET_MESSAGE_TYPE_ARM_TEST);
563 GNUNET_MQ_send (h->mq, env);
464 return GNUNET_OK; 564 return GNUNET_OK;
465} 565}
466 566
@@ -477,21 +577,21 @@ reconnect_arm(struct GNUNET_ARM_Handle *h)
477 * @return context to use for further ARM operations, NULL on error. 577 * @return context to use for further ARM operations, NULL on error.
478 */ 578 */
479struct GNUNET_ARM_Handle * 579struct GNUNET_ARM_Handle *
480GNUNET_ARM_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, 580GNUNET_ARM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
481 GNUNET_ARM_ConnectionStatusCallback conn_status, 581 GNUNET_ARM_ConnectionStatusCallback conn_status,
482 void *conn_status_cls) 582 void *conn_status_cls)
483{ 583{
484 struct GNUNET_ARM_Handle *h; 584 struct GNUNET_ARM_Handle *h;
485 585
486 h = GNUNET_new(struct GNUNET_ARM_Handle); 586 h = GNUNET_new (struct GNUNET_ARM_Handle);
487 h->cfg = cfg; 587 h->cfg = cfg;
488 h->conn_status = conn_status; 588 h->conn_status = conn_status;
489 h->conn_status_cls = conn_status_cls; 589 h->conn_status_cls = conn_status_cls;
490 if (GNUNET_OK != reconnect_arm(h)) 590 if (GNUNET_OK != reconnect_arm (h))
491 { 591 {
492 GNUNET_free(h); 592 GNUNET_free (h);
493 return NULL; 593 return NULL;
494 } 594 }
495 return h; 595 return h;
496} 596}
497 597
@@ -502,38 +602,43 @@ GNUNET_ARM_connect(const struct GNUNET_CONFIGURATION_Handle *cfg,
502 * @param h the handle that was being used 602 * @param h the handle that was being used
503 */ 603 */
504void 604void
505GNUNET_ARM_disconnect(struct GNUNET_ARM_Handle *h) 605GNUNET_ARM_disconnect (struct GNUNET_ARM_Handle *h)
506{ 606{
507 struct GNUNET_ARM_Operation *op; 607 struct GNUNET_ARM_Operation *op;
508 608
509 LOG(GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from ARM service\n"); 609 LOG (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from ARM service\n");
510 while (NULL != (op = h->operation_pending_head)) 610 while (NULL != (op = h->operation_pending_head))
611 {
612 GNUNET_CONTAINER_DLL_remove (h->operation_pending_head,
613 h->operation_pending_tail,
614 op);
615 if (NULL != op->result_cont)
616 op->result_cont (op->cont_cls,
617 GNUNET_ARM_REQUEST_DISCONNECTED,
618 0);
619 if (NULL != op->list_cont)
620 op->list_cont (op->cont_cls,
621 GNUNET_ARM_REQUEST_DISCONNECTED,
622 0,
623 NULL);
624 if (NULL != op->async)
511 { 625 {
512 GNUNET_CONTAINER_DLL_remove(h->operation_pending_head, 626 GNUNET_SCHEDULER_cancel (op->async);
513 h->operation_pending_tail, 627 op->async = NULL;
514 op);
515 if (NULL != op->result_cont)
516 op->result_cont(op->cont_cls, GNUNET_ARM_REQUEST_DISCONNECTED, 0);
517 if (NULL != op->list_cont)
518 op->list_cont(op->cont_cls, GNUNET_ARM_REQUEST_DISCONNECTED, 0, NULL);
519 if (NULL != op->async)
520 {
521 GNUNET_SCHEDULER_cancel(op->async);
522 op->async = NULL;
523 }
524 GNUNET_free(op);
525 } 628 }
629 GNUNET_free (op);
630 }
526 if (NULL != h->mq) 631 if (NULL != h->mq)
527 { 632 {
528 GNUNET_MQ_destroy(h->mq); 633 GNUNET_MQ_destroy (h->mq);
529 h->mq = NULL; 634 h->mq = NULL;
530 } 635 }
531 if (NULL != h->reconnect_task) 636 if (NULL != h->reconnect_task)
532 { 637 {
533 GNUNET_SCHEDULER_cancel(h->reconnect_task); 638 GNUNET_SCHEDULER_cancel (h->reconnect_task);
534 h->reconnect_task = NULL; 639 h->reconnect_task = NULL;
535 } 640 }
536 GNUNET_free(h); 641 GNUNET_free (h);
537} 642}
538 643
539 644
@@ -543,11 +648,13 @@ GNUNET_ARM_disconnect(struct GNUNET_ARM_Handle *h)
543 * 648 *
544 * @param h the handle with configuration details 649 * @param h the handle with configuration details
545 * @param std_inheritance inheritance of std streams 650 * @param std_inheritance inheritance of std streams
651 * @param sigfd socket to pass to ARM for signalling
546 * @return operation status code 652 * @return operation status code
547 */ 653 */
548static enum GNUNET_ARM_Result 654static enum GNUNET_ARM_Result
549start_arm_service(struct GNUNET_ARM_Handle *h, 655start_arm_service (struct GNUNET_ARM_Handle *h,
550 enum GNUNET_OS_InheritStdioFlags std_inheritance) 656 enum GNUNET_OS_InheritStdioFlags std_inheritance,
657 struct GNUNET_DISK_FileHandle *sigfd)
551{ 658{
552 struct GNUNET_OS_Process *proc; 659 struct GNUNET_OS_Process *proc;
553 char *cbinary; 660 char *cbinary;
@@ -556,99 +663,124 @@ start_arm_service(struct GNUNET_ARM_Handle *h,
556 char *config; 663 char *config;
557 char *loprefix; 664 char *loprefix;
558 char *lopostfix; 665 char *lopostfix;
666 SOCKTYPE ld[2];
667 SOCKTYPE *lsocks;
559 668
560 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(h->cfg, 669 if (NULL == sigfd)
561 "arm", 670 {
562 "PREFIX", 671 lsocks = NULL;
563 &loprefix)) 672 }
564 loprefix = GNUNET_strdup("");
565 else 673 else
566 loprefix = GNUNET_CONFIGURATION_expand_dollar(h->cfg, loprefix); 674 {
567 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(h->cfg, 675 ld[0] = sigfd->fd;
568 "arm", 676 ld[1] = -1;
569 "OPTIONS", 677 lsocks = ld;
570 &lopostfix)) 678 }
571 lopostfix = GNUNET_strdup(""); 679 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (h->cfg,
680 "arm",
681 "PREFIX",
682 &loprefix))
683 loprefix = GNUNET_strdup ("");
572 else 684 else
573 lopostfix = GNUNET_CONFIGURATION_expand_dollar(h->cfg, lopostfix); 685 loprefix = GNUNET_CONFIGURATION_expand_dollar (h->cfg, loprefix);
686 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (h->cfg,
687 "arm",
688 "OPTIONS",
689 &lopostfix))
690 lopostfix = GNUNET_strdup ("");
691 else
692 lopostfix = GNUNET_CONFIGURATION_expand_dollar (h->cfg,
693 lopostfix);
574 if (GNUNET_OK != 694 if (GNUNET_OK !=
575 GNUNET_CONFIGURATION_get_value_string(h->cfg, "arm", "BINARY", &cbinary)) 695 GNUNET_CONFIGURATION_get_value_string (h->cfg,
576 { 696 "arm",
577 GNUNET_log_config_missing(GNUNET_ERROR_TYPE_WARNING, "arm", "BINARY"); 697 "BINARY",
578 GNUNET_free(loprefix); 698 &cbinary))
579 GNUNET_free(lopostfix); 699 {
580 return GNUNET_ARM_RESULT_IS_NOT_KNOWN; 700 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
581 } 701 "arm",
582 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename(h->cfg, 702 "BINARY");
583 "arm", 703 GNUNET_free (loprefix);
584 "CONFIG", 704 GNUNET_free (lopostfix);
585 &config)) 705 return GNUNET_ARM_RESULT_IS_NOT_KNOWN;
706 }
707 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (h->cfg,
708 "arm",
709 "CONFIG",
710 &config))
586 config = NULL; 711 config = NULL;
587 binary = GNUNET_OS_get_libexec_binary_path(cbinary); 712 binary = GNUNET_OS_get_libexec_binary_path (cbinary);
588 GNUNET_asprintf(&quotedbinary, "\"%s\"", binary); 713 GNUNET_asprintf (&quotedbinary,
589 GNUNET_free(cbinary); 714 "\"%s\"",
590 if ((GNUNET_YES == 715 binary);
591 GNUNET_CONFIGURATION_have_value(h->cfg, "TESTING", "WEAKRANDOM")) && 716 GNUNET_free (cbinary);
592 (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno(h->cfg, 717 if ( (GNUNET_YES ==
593 "TESTING", 718 GNUNET_CONFIGURATION_have_value (h->cfg,
594 "WEAKRANDOM")) && 719 "TESTING",
595 (GNUNET_NO == 720 "WEAKRANDOM")) &&
596 GNUNET_CONFIGURATION_have_value(h->cfg, "TESTING", "HOSTFILE"))) 721 (GNUNET_YES ==
597 { 722 GNUNET_CONFIGURATION_get_value_yesno (h->cfg,
598 /* Means we are ONLY running locally */ 723 "TESTING",
599 /* we're clearly running a test, don't daemonize */ 724 "WEAKRANDOM")) &&
600 if (NULL == config) 725 (GNUNET_NO ==
601 proc = GNUNET_OS_start_process_s(GNUNET_NO, 726 GNUNET_CONFIGURATION_have_value (h->cfg,
602 std_inheritance, 727 "TESTING",
603 NULL, 728 "HOSTFILE")) )
604 loprefix, 729 {
605 quotedbinary, 730 /* Means we are ONLY running locally */
606 /* no daemonization! */ 731 /* we're clearly running a test, don't daemonize */
607 lopostfix, 732 if (NULL == config)
608 NULL); 733 proc = GNUNET_OS_start_process_s (GNUNET_NO,
609 else 734 std_inheritance,
610 proc = GNUNET_OS_start_process_s(GNUNET_NO, 735 lsocks,
611 std_inheritance, 736 loprefix,
612 NULL, 737 quotedbinary,
613 loprefix, 738 /* no daemonization! */
614 quotedbinary, 739 lopostfix,
615 "-c", 740 NULL);
616 config, 741 else
617 /* no daemonization! */ 742 proc = GNUNET_OS_start_process_s (GNUNET_NO,
618 lopostfix, 743 std_inheritance,
619 NULL); 744 lsocks,
620 } 745 loprefix,
746 quotedbinary,
747 "-c",
748 config,
749 /* no daemonization! */
750 lopostfix,
751 NULL);
752 }
621 else 753 else
622 { 754 {
623 if (NULL == config) 755 if (NULL == config)
624 proc = GNUNET_OS_start_process_s(GNUNET_NO, 756 proc = GNUNET_OS_start_process_s (GNUNET_NO,
625 std_inheritance, 757 std_inheritance,
626 NULL, 758 lsocks,
627 loprefix, 759 loprefix,
628 quotedbinary, 760 quotedbinary,
629 "-d", /* do daemonize */ 761 "-d", /* do daemonize */
630 lopostfix, 762 lopostfix,
631 NULL); 763 NULL);
632 else 764 else
633 proc = GNUNET_OS_start_process_s(GNUNET_NO, 765 proc = GNUNET_OS_start_process_s (GNUNET_NO,
634 std_inheritance, 766 std_inheritance,
635 NULL, 767 lsocks,
636 loprefix, 768 loprefix,
637 quotedbinary, 769 quotedbinary,
638 "-c", 770 "-c",
639 config, 771 config,
640 "-d", /* do daemonize */ 772 "-d", /* do daemonize */
641 lopostfix, 773 lopostfix,
642 NULL); 774 NULL);
643 } 775 }
644 GNUNET_free(binary); 776 GNUNET_free (binary);
645 GNUNET_free(quotedbinary); 777 GNUNET_free (quotedbinary);
646 GNUNET_free_non_null(config); 778 GNUNET_free_non_null (config);
647 GNUNET_free(loprefix); 779 GNUNET_free (loprefix);
648 GNUNET_free(lopostfix); 780 GNUNET_free (lopostfix);
649 if (NULL == proc) 781 if (NULL == proc)
650 return GNUNET_ARM_RESULT_START_FAILED; 782 return GNUNET_ARM_RESULT_START_FAILED;
651 GNUNET_OS_process_destroy(proc); 783 GNUNET_OS_process_destroy (proc);
652 return GNUNET_ARM_RESULT_STARTING; 784 return GNUNET_ARM_RESULT_STARTING;
653} 785}
654 786
@@ -660,19 +792,29 @@ start_arm_service(struct GNUNET_ARM_Handle *h,
660 * @param op operation to cancel 792 * @param op operation to cancel
661 */ 793 */
662void 794void
663GNUNET_ARM_operation_cancel(struct GNUNET_ARM_Operation *op) 795GNUNET_ARM_operation_cancel (struct GNUNET_ARM_Operation *op)
664{ 796{
665 struct GNUNET_ARM_Handle *h = op->h; 797 struct GNUNET_ARM_Handle *h = op->h;
666 798
799 if (NULL != op->async)
800 {
801 GNUNET_SCHEDULER_cancel (op->async);
802 op->async = NULL;
803 }
804 if (NULL != op->rfd)
805 {
806 GNUNET_DISK_file_close (op->rfd);
807 op->rfd = NULL;
808 }
667 if (h->thm == op) 809 if (h->thm == op)
668 { 810 {
669 op->result_cont = NULL; 811 op->result_cont = NULL;
670 return; 812 return;
671 } 813 }
672 GNUNET_CONTAINER_DLL_remove(h->operation_pending_head, 814 GNUNET_CONTAINER_DLL_remove (h->operation_pending_head,
673 h->operation_pending_tail, 815 h->operation_pending_tail,
674 op); 816 op);
675 GNUNET_free(op); 817 GNUNET_free (op);
676} 818}
677 819
678 820
@@ -687,38 +829,38 @@ GNUNET_ARM_operation_cancel(struct GNUNET_ARM_Operation *op)
687 * @return handle to queue, NULL on error 829 * @return handle to queue, NULL on error
688 */ 830 */
689static struct GNUNET_ARM_Operation * 831static struct GNUNET_ARM_Operation *
690change_service(struct GNUNET_ARM_Handle *h, 832change_service (struct GNUNET_ARM_Handle *h,
691 const char *service_name, 833 const char *service_name,
692 GNUNET_ARM_ResultCallback cb, 834 GNUNET_ARM_ResultCallback cb,
693 void *cb_cls, 835 void *cb_cls,
694 uint16_t type) 836 uint16_t type)
695{ 837{
696 struct GNUNET_ARM_Operation *op; 838 struct GNUNET_ARM_Operation *op;
697 size_t slen; 839 size_t slen;
698 struct GNUNET_MQ_Envelope *env; 840 struct GNUNET_MQ_Envelope *env;
699 struct GNUNET_ARM_Message *msg; 841 struct GNUNET_ARM_Message *msg;
700 842
701 slen = strlen(service_name) + 1; 843 slen = strlen (service_name) + 1;
702 if (slen + sizeof(struct GNUNET_ARM_Message) >= GNUNET_MAX_MESSAGE_SIZE) 844 if (slen + sizeof(struct GNUNET_ARM_Message) >= GNUNET_MAX_MESSAGE_SIZE)
703 { 845 {
704 GNUNET_break(0); 846 GNUNET_break (0);
705 return NULL; 847 return NULL;
706 } 848 }
707 if (0 == h->request_id_counter) 849 if (0 == h->request_id_counter)
708 h->request_id_counter++; 850 h->request_id_counter++;
709 op = GNUNET_new(struct GNUNET_ARM_Operation); 851 op = GNUNET_new (struct GNUNET_ARM_Operation);
710 op->h = h; 852 op->h = h;
711 op->result_cont = cb; 853 op->result_cont = cb;
712 op->cont_cls = cb_cls; 854 op->cont_cls = cb_cls;
713 op->id = h->request_id_counter++; 855 op->id = h->request_id_counter++;
714 GNUNET_CONTAINER_DLL_insert_tail(h->operation_pending_head, 856 GNUNET_CONTAINER_DLL_insert_tail (h->operation_pending_head,
715 h->operation_pending_tail, 857 h->operation_pending_tail,
716 op); 858 op);
717 env = GNUNET_MQ_msg_extra(msg, slen, type); 859 env = GNUNET_MQ_msg_extra (msg, slen, type);
718 msg->reserved = htonl(0); 860 msg->reserved = htonl (0);
719 msg->request_id = GNUNET_htonll(op->id); 861 msg->request_id = GNUNET_htonll (op->id);
720 GNUNET_memcpy(&msg[1], service_name, slen); 862 GNUNET_memcpy (&msg[1], service_name, slen);
721 GNUNET_MQ_send(h->mq, env); 863 GNUNET_MQ_send (h->mq, env);
722 return op; 864 return op;
723} 865}
724 866
@@ -729,22 +871,24 @@ change_service(struct GNUNET_ARM_Handle *h,
729 * @param cls the operation that asked ARM to be started 871 * @param cls the operation that asked ARM to be started
730 */ 872 */
731static void 873static void
732notify_running(void *cls) 874notify_running (void *cls)
733{ 875{
734 struct GNUNET_ARM_Operation *op = cls; 876 struct GNUNET_ARM_Operation *op = cls;
735 struct GNUNET_ARM_Handle *h = op->h; 877 struct GNUNET_ARM_Handle *h = op->h;
736 878
737 op->async = NULL; 879 op->async = NULL;
738 GNUNET_CONTAINER_DLL_remove(h->operation_pending_head, 880 GNUNET_CONTAINER_DLL_remove (h->operation_pending_head,
739 h->operation_pending_tail, 881 h->operation_pending_tail,
740 op); 882 op);
741 if (NULL != op->result_cont) 883 if (NULL != op->result_cont)
742 op->result_cont(op->cont_cls, 884 op->result_cont (op->cont_cls,
743 GNUNET_ARM_REQUEST_SENT_OK, 885 GNUNET_ARM_REQUEST_SENT_OK,
744 GNUNET_ARM_RESULT_IS_STARTED_ALREADY); 886 GNUNET_ARM_RESULT_IS_STARTED_ALREADY);
745 if ((GNUNET_YES == h->currently_up) && (NULL != h->conn_status)) 887 if ( (GNUNET_YES == h->currently_up) &&
746 h->conn_status(h->conn_status_cls, GNUNET_YES); 888 (NULL != h->conn_status) )
747 GNUNET_free(op); 889 h->conn_status (h->conn_status_cls,
890 GNUNET_YES);
891 GNUNET_free (op);
748} 892}
749 893
750 894
@@ -754,22 +898,22 @@ notify_running(void *cls)
754 * @param cls the operation that asked ARM to be started 898 * @param cls the operation that asked ARM to be started
755 */ 899 */
756static void 900static void
757notify_starting(void *cls) 901notify_starting (void *cls)
758{ 902{
759 struct GNUNET_ARM_Operation *op = cls; 903 struct GNUNET_ARM_Operation *op = cls;
760 struct GNUNET_ARM_Handle *h = op->h; 904 struct GNUNET_ARM_Handle *h = op->h;
761 905
762 op->async = NULL; 906 op->async = NULL;
763 LOG(GNUNET_ERROR_TYPE_DEBUG, 907 LOG (GNUNET_ERROR_TYPE_DEBUG,
764 "Notifying client that we started the ARM service\n"); 908 "Notifying client that we started the ARM service\n");
765 GNUNET_CONTAINER_DLL_remove(h->operation_pending_head, 909 GNUNET_CONTAINER_DLL_remove (h->operation_pending_head,
766 h->operation_pending_tail, 910 h->operation_pending_tail,
767 op); 911 op);
768 if (NULL != op->result_cont) 912 if (NULL != op->result_cont)
769 op->result_cont(op->cont_cls, 913 op->result_cont (op->cont_cls,
770 GNUNET_ARM_REQUEST_SENT_OK, 914 GNUNET_ARM_REQUEST_SENT_OK,
771 op->starting_ret); 915 op->starting_ret);
772 GNUNET_free(op); 916 GNUNET_free (op);
773} 917}
774 918
775 919
@@ -784,23 +928,28 @@ notify_starting(void *cls)
784 * @return handle for the operation, NULL on error 928 * @return handle for the operation, NULL on error
785 */ 929 */
786struct GNUNET_ARM_Operation * 930struct GNUNET_ARM_Operation *
787GNUNET_ARM_request_service_start( 931GNUNET_ARM_request_service_start (struct GNUNET_ARM_Handle *h,
788 struct GNUNET_ARM_Handle *h, 932 const char *service_name,
789 const char *service_name, 933 enum GNUNET_OS_InheritStdioFlags
790 enum GNUNET_OS_InheritStdioFlags std_inheritance, 934 std_inheritance,
791 GNUNET_ARM_ResultCallback cont, 935 GNUNET_ARM_ResultCallback cont,
792 void *cont_cls) 936 void *cont_cls)
793{ 937{
794 struct GNUNET_ARM_Operation *op; 938 struct GNUNET_ARM_Operation *op;
795 enum GNUNET_ARM_Result ret; 939 enum GNUNET_ARM_Result ret;
796 940 struct GNUNET_DISK_PipeHandle *sig;
797 LOG(GNUNET_ERROR_TYPE_DEBUG, "Starting service `%s'\n", service_name); 941 struct GNUNET_DISK_FileHandle *wsig;
798 if (0 != strcasecmp("arm", service_name)) 942
799 return change_service(h, 943 LOG (GNUNET_ERROR_TYPE_DEBUG,
800 service_name, 944 "Starting service `%s'\n",
801 cont, 945 service_name);
802 cont_cls, 946 if (0 != strcasecmp ("arm",
803 GNUNET_MESSAGE_TYPE_ARM_START); 947 service_name))
948 return change_service (h,
949 service_name,
950 cont,
951 cont_cls,
952 GNUNET_MESSAGE_TYPE_ARM_START);
804 953
805 /* Possible cases: 954 /* Possible cases:
806 * 1) We're connected to ARM already. Invoke the callback immediately. 955 * 1) We're connected to ARM already. Invoke the callback immediately.
@@ -809,37 +958,68 @@ GNUNET_ARM_request_service_start(
809 * a service test. 958 * a service test.
810 */ 959 */
811 if (GNUNET_YES == h->currently_up) 960 if (GNUNET_YES == h->currently_up)
812 { 961 {
813 LOG(GNUNET_ERROR_TYPE_DEBUG, "ARM is already running\n"); 962 LOG (GNUNET_ERROR_TYPE_DEBUG,
814 op = GNUNET_new(struct GNUNET_ARM_Operation); 963 "ARM is already running\n");
815 op->h = h; 964 op = GNUNET_new (struct GNUNET_ARM_Operation);
816 op->result_cont = cont; 965 op->h = h;
817 op->cont_cls = cont_cls; 966 op->result_cont = cont;
818 GNUNET_CONTAINER_DLL_insert_tail(h->operation_pending_head, 967 op->cont_cls = cont_cls;
819 h->operation_pending_tail, 968 GNUNET_CONTAINER_DLL_insert_tail (h->operation_pending_head,
820 op); 969 h->operation_pending_tail,
821 op->async = GNUNET_SCHEDULER_add_now(&notify_running, op); 970 op);
822 return op; 971 op->async = GNUNET_SCHEDULER_add_now (&notify_running, op);
823 } 972 return op;
973 }
824 /* This is an inherently uncertain choice, as it is of course 974 /* This is an inherently uncertain choice, as it is of course
825 theoretically possible that ARM is up and we just did not 975 theoretically possible that ARM is up and we just did not
826 yet complete the MQ handshake. However, given that users 976 yet complete the MQ handshake. However, given that users
827 are unlikely to hammer 'gnunet-arm -s' on a busy system, 977 are unlikely to hammer 'gnunet-arm -s' on a busy system,
828 the above check should catch 99.99% of the cases where ARM 978 the above check should catch 99.99% of the cases where ARM
829 is already running. */ 979 is already running. */
830 LOG(GNUNET_ERROR_TYPE_DEBUG, "Starting ARM service\n"); 980 LOG (GNUNET_ERROR_TYPE_DEBUG,
831 ret = start_arm_service(h, std_inheritance); 981 "Starting ARM service\n");
982 if (NULL == (sig = GNUNET_DISK_pipe (GNUNET_NO,
983 GNUNET_NO,
984 GNUNET_NO,
985 GNUNET_YES)))
986 {
987 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
988 "pipe");
989 }
990 wsig = GNUNET_DISK_pipe_detach_end (sig,
991 GNUNET_DISK_PIPE_END_WRITE);
992 ret = start_arm_service (h,
993 std_inheritance,
994 wsig);
995 GNUNET_DISK_file_close (wsig);
832 if (GNUNET_ARM_RESULT_STARTING == ret) 996 if (GNUNET_ARM_RESULT_STARTING == ret)
833 reconnect_arm(h); 997 reconnect_arm (h);
834 op = GNUNET_new(struct GNUNET_ARM_Operation); 998 op = GNUNET_new (struct GNUNET_ARM_Operation);
835 op->h = h; 999 op->h = h;
836 op->result_cont = cont; 1000 op->result_cont = cont;
837 op->cont_cls = cont_cls; 1001 op->cont_cls = cont_cls;
838 GNUNET_CONTAINER_DLL_insert_tail(h->operation_pending_head, 1002 GNUNET_CONTAINER_DLL_insert_tail (h->operation_pending_head,
839 h->operation_pending_tail, 1003 h->operation_pending_tail,
840 op); 1004 op);
841 op->starting_ret = ret; 1005 op->starting_ret = ret;
842 op->async = GNUNET_SCHEDULER_add_now(&notify_starting, op); 1006 if (NULL != sig)
1007 {
1008 op->rfd = GNUNET_DISK_pipe_detach_end (sig,
1009 GNUNET_DISK_PIPE_END_READ);
1010 /* Wait at most a minute for gnunet-service-arm to be up, as beyond
1011 that something clearly just went wrong */
1012 op->async = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_MINUTES,
1013 op->rfd,
1014 &notify_starting,
1015 op);
1016 }
1017 else
1018 {
1019 op->async = GNUNET_SCHEDULER_add_now (&notify_starting,
1020 op);
1021 }
1022 GNUNET_DISK_pipe_close (sig);
843 return op; 1023 return op;
844} 1024}
845 1025
@@ -859,24 +1039,27 @@ GNUNET_ARM_request_service_start(
859 * @return handle for the operation, NULL on error 1039 * @return handle for the operation, NULL on error
860 */ 1040 */
861struct GNUNET_ARM_Operation * 1041struct GNUNET_ARM_Operation *
862GNUNET_ARM_request_service_stop(struct GNUNET_ARM_Handle *h, 1042GNUNET_ARM_request_service_stop (struct GNUNET_ARM_Handle *h,
863 const char *service_name, 1043 const char *service_name,
864 GNUNET_ARM_ResultCallback cont, 1044 GNUNET_ARM_ResultCallback cont,
865 void *cont_cls) 1045 void *cont_cls)
866{ 1046{
867 struct GNUNET_ARM_Operation *op; 1047 struct GNUNET_ARM_Operation *op;
868 1048
869 LOG(GNUNET_ERROR_TYPE_DEBUG, "Stopping service `%s'\n", service_name); 1049 LOG (GNUNET_ERROR_TYPE_DEBUG,
870 op = change_service(h, 1050 "Stopping service `%s'\n",
871 service_name, 1051 service_name);
872 cont, 1052 op = change_service (h,
873 cont_cls, 1053 service_name,
874 GNUNET_MESSAGE_TYPE_ARM_STOP); 1054 cont,
1055 cont_cls,
1056 GNUNET_MESSAGE_TYPE_ARM_STOP);
875 if (NULL == op) 1057 if (NULL == op)
876 return NULL; 1058 return NULL;
877 /* If the service is ARM, set a flag as we will use MQ errors 1059 /* If the service is ARM, set a flag as we will use MQ errors
878 to detect that the process is really gone. */ 1060 to detect that the process is really gone. */
879 if (0 == strcasecmp(service_name, "arm")) 1061 if (0 == strcasecmp (service_name,
1062 "arm"))
880 op->is_arm_stop = GNUNET_YES; 1063 op->is_arm_stop = GNUNET_YES;
881 return op; 1064 return op;
882} 1065}
@@ -891,29 +1074,31 @@ GNUNET_ARM_request_service_stop(struct GNUNET_ARM_Handle *h,
891 * @return handle for the operation, NULL on error 1074 * @return handle for the operation, NULL on error
892 */ 1075 */
893struct GNUNET_ARM_Operation * 1076struct GNUNET_ARM_Operation *
894GNUNET_ARM_request_service_list(struct GNUNET_ARM_Handle *h, 1077GNUNET_ARM_request_service_list (struct GNUNET_ARM_Handle *h,
895 GNUNET_ARM_ServiceListCallback cont, 1078 GNUNET_ARM_ServiceListCallback cont,
896 void *cont_cls) 1079 void *cont_cls)
897{ 1080{
898 struct GNUNET_ARM_Operation *op; 1081 struct GNUNET_ARM_Operation *op;
899 struct GNUNET_MQ_Envelope *env; 1082 struct GNUNET_MQ_Envelope *env;
900 struct GNUNET_ARM_Message *msg; 1083 struct GNUNET_ARM_Message *msg;
901 1084
902 LOG(GNUNET_ERROR_TYPE_DEBUG, "Requesting LIST from ARM service\n"); 1085 LOG (GNUNET_ERROR_TYPE_DEBUG,
1086 "Requesting LIST from ARM service\n");
903 if (0 == h->request_id_counter) 1087 if (0 == h->request_id_counter)
904 h->request_id_counter++; 1088 h->request_id_counter++;
905 op = GNUNET_new(struct GNUNET_ARM_Operation); 1089 op = GNUNET_new (struct GNUNET_ARM_Operation);
906 op->h = h; 1090 op->h = h;
907 op->list_cont = cont; 1091 op->list_cont = cont;
908 op->cont_cls = cont_cls; 1092 op->cont_cls = cont_cls;
909 op->id = h->request_id_counter++; 1093 op->id = h->request_id_counter++;
910 GNUNET_CONTAINER_DLL_insert_tail(h->operation_pending_head, 1094 GNUNET_CONTAINER_DLL_insert_tail (h->operation_pending_head,
911 h->operation_pending_tail, 1095 h->operation_pending_tail,
912 op); 1096 op);
913 env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_ARM_LIST); 1097 env = GNUNET_MQ_msg (msg,
914 msg->reserved = htonl(0); 1098 GNUNET_MESSAGE_TYPE_ARM_LIST);
915 msg->request_id = GNUNET_htonll(op->id); 1099 msg->reserved = htonl (0);
916 GNUNET_MQ_send(h->mq, env); 1100 msg->request_id = GNUNET_htonll (op->id);
1101 GNUNET_MQ_send (h->mq, env);
917 return op; 1102 return op;
918} 1103}
919 1104
diff --git a/src/arm/arm_monitor_api.c b/src/arm/arm_monitor_api.c
index c6e1e2683..00faaaef1 100644
--- a/src/arm/arm_monitor_api.c
+++ b/src/arm/arm_monitor_api.c
@@ -61,7 +61,7 @@ struct GNUNET_ARM_MonitorHandle {
61 /** 61 /**
62 * Callback to invoke on status updates. 62 * Callback to invoke on status updates.
63 */ 63 */
64 GNUNET_ARM_ServiceStatusCallback service_status; 64 GNUNET_ARM_ServiceMonitorCallback service_status;
65 65
66 /** 66 /**
67 * Closure for @e service_status. 67 * Closure for @e service_status.
@@ -153,9 +153,9 @@ static void
153handle_monitor_notify(void *cls, const struct GNUNET_ARM_StatusMessage *res) 153handle_monitor_notify(void *cls, const struct GNUNET_ARM_StatusMessage *res)
154{ 154{
155 struct GNUNET_ARM_MonitorHandle *h = cls; 155 struct GNUNET_ARM_MonitorHandle *h = cls;
156 enum GNUNET_ARM_ServiceStatus status; 156 enum GNUNET_ARM_ServiceMonitorStatus status;
157 157
158 status = (enum GNUNET_ARM_ServiceStatus)ntohl(res->status); 158 status = (enum GNUNET_ARM_ServiceMonitorStatus)ntohl(res->status);
159 LOG(GNUNET_ERROR_TYPE_DEBUG, 159 LOG(GNUNET_ERROR_TYPE_DEBUG,
160 "Received notification from ARM for service `%s' with status %d\n", 160 "Received notification from ARM for service `%s' with status %d\n",
161 (const char *)&res[1], 161 (const char *)&res[1],
@@ -230,7 +230,7 @@ reconnect_arm_monitor(struct GNUNET_ARM_MonitorHandle *h)
230 */ 230 */
231struct GNUNET_ARM_MonitorHandle * 231struct GNUNET_ARM_MonitorHandle *
232GNUNET_ARM_monitor_start(const struct GNUNET_CONFIGURATION_Handle *cfg, 232GNUNET_ARM_monitor_start(const struct GNUNET_CONFIGURATION_Handle *cfg,
233 GNUNET_ARM_ServiceStatusCallback cont, 233 GNUNET_ARM_ServiceMonitorCallback cont,
234 void *cont_cls) 234 void *cont_cls)
235{ 235{
236 struct GNUNET_ARM_MonitorHandle *h; 236 struct GNUNET_ARM_MonitorHandle *h;
diff --git a/src/arm/gnunet-arm.c b/src/arm/gnunet-arm.c
index 3396a4dbe..0fdb66fa0 100644
--- a/src/arm/gnunet-arm.c
+++ b/src/arm/gnunet-arm.c
@@ -54,6 +54,11 @@ static int delete;
54static int quiet; 54static int quiet;
55 55
56/** 56/**
57 * Set if we should print all services, including stopped ones.
58 */
59static int show_all;
60
61/**
57 * Monitor ARM activity. 62 * Monitor ARM activity.
58 */ 63 */
59static int monitor; 64static int monitor;
@@ -144,25 +149,25 @@ static struct GNUNET_ARM_Operation *op;
144 * were specified when gnunet-arm was run. 149 * were specified when gnunet-arm was run.
145 */ 150 */
146static void 151static void
147delete_files() 152delete_files ()
148{ 153{
149 GNUNET_log( 154 GNUNET_log (
150 GNUNET_ERROR_TYPE_DEBUG, 155 GNUNET_ERROR_TYPE_DEBUG,
151 "Will attempt to remove configuration file %s and service directory %s\n", 156 "Will attempt to remove configuration file %s and service directory %s\n",
152 config_file, 157 config_file,
153 dir); 158 dir);
154 if (0 != unlink(config_file)) 159 if (0 != unlink (config_file))
155 { 160 {
156 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, 161 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
157 _("Failed to remove configuration file %s\n"), 162 _ ("Failed to remove configuration file %s\n"),
158 config_file); 163 config_file);
159 } 164 }
160 if (GNUNET_OK != GNUNET_DISK_directory_remove(dir)) 165 if (GNUNET_OK != GNUNET_DISK_directory_remove (dir))
161 { 166 {
162 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, 167 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
163 _("Failed to remove servicehome directory %s\n"), 168 _ ("Failed to remove servicehome directory %s\n"),
164 dir); 169 dir);
165 } 170 }
166} 171}
167 172
168 173
@@ -173,37 +178,38 @@ delete_files()
173 * @param cls closure, unused 178 * @param cls closure, unused
174 */ 179 */
175static void 180static void
176shutdown_task(void *cls) 181shutdown_task (void *cls)
177{ 182{
178 (void)cls; 183 (void) cls;
179 if (NULL != al_task) 184 if (NULL != al_task)
180 { 185 {
181 GNUNET_SCHEDULER_cancel(al_task); 186 GNUNET_SCHEDULER_cancel (al_task);
182 al_task = NULL; 187 al_task = NULL;
183 } 188 }
184 if (NULL != op) 189 if (NULL != op)
185 { 190 {
186 GNUNET_ARM_operation_cancel(op); 191 GNUNET_ARM_operation_cancel (op);
187 op = NULL; 192 op = NULL;
188 } 193 }
189 if (NULL != h) 194 if (NULL != h)
190 { 195 {
191 GNUNET_ARM_disconnect(h); 196 GNUNET_ARM_disconnect (h);
192 h = NULL; 197 h = NULL;
193 } 198 }
194 if (NULL != m) 199 if (NULL != m)
195 { 200 {
196 GNUNET_ARM_monitor_stop(m); 201 GNUNET_ARM_monitor_stop (m);
197 m = NULL; 202 m = NULL;
198 } 203 }
199 if (NULL != timeout_task) 204 if (NULL != timeout_task)
200 { 205 {
201 GNUNET_SCHEDULER_cancel(timeout_task); 206 GNUNET_SCHEDULER_cancel (timeout_task);
202 timeout_task = NULL; 207 timeout_task = NULL;
203 } 208 }
204 if ((GNUNET_YES == end) && (GNUNET_YES == delete)) 209 if ( (GNUNET_YES == end) &&
205 delete_files(); 210 (GNUNET_YES == delete) )
206 GNUNET_CONFIGURATION_destroy(cfg); 211 delete_files ();
212 GNUNET_CONFIGURATION_destroy (cfg);
207 cfg = NULL; 213 cfg = NULL;
208} 214}
209 215
@@ -215,17 +221,17 @@ shutdown_task(void *cls)
215 * @return a string interpretation of the request status 221 * @return a string interpretation of the request status
216 */ 222 */
217static const char * 223static const char *
218req_string(enum GNUNET_ARM_RequestStatus rs) 224req_string (enum GNUNET_ARM_RequestStatus rs)
219{ 225{
220 switch (rs) 226 switch (rs)
221 { 227 {
222 case GNUNET_ARM_REQUEST_SENT_OK: 228 case GNUNET_ARM_REQUEST_SENT_OK:
223 return _("Message was sent successfully"); 229 return _ ("Message was sent successfully");
224 230
225 case GNUNET_ARM_REQUEST_DISCONNECTED: 231 case GNUNET_ARM_REQUEST_DISCONNECTED:
226 return _("We disconnected from ARM before we could send a request"); 232 return _ ("We disconnected from ARM before we could send a request");
227 } 233 }
228 return _("Unknown request status"); 234 return _ ("Unknown request status");
229} 235}
230 236
231 237
@@ -236,41 +242,41 @@ req_string(enum GNUNET_ARM_RequestStatus rs)
236 * @return a string interpretation 242 * @return a string interpretation
237 */ 243 */
238static const char * 244static const char *
239ret_string(enum GNUNET_ARM_Result result) 245ret_string (enum GNUNET_ARM_Result result)
240{ 246{
241 switch (result) 247 switch (result)
242 { 248 {
243 case GNUNET_ARM_RESULT_STOPPED: 249 case GNUNET_ARM_RESULT_STOPPED:
244 return _("is stopped"); 250 return _ ("is stopped");
245 251
246 case GNUNET_ARM_RESULT_STARTING: 252 case GNUNET_ARM_RESULT_STARTING:
247 return _("is starting"); 253 return _ ("is starting");
248 254
249 case GNUNET_ARM_RESULT_STOPPING: 255 case GNUNET_ARM_RESULT_STOPPING:
250 return _("is stopping"); 256 return _ ("is stopping");
251 257
252 case GNUNET_ARM_RESULT_IS_STARTING_ALREADY: 258 case GNUNET_ARM_RESULT_IS_STARTING_ALREADY:
253 return _("is starting already"); 259 return _ ("is starting already");
254 260
255 case GNUNET_ARM_RESULT_IS_STOPPING_ALREADY: 261 case GNUNET_ARM_RESULT_IS_STOPPING_ALREADY:
256 return _("is stopping already"); 262 return _ ("is stopping already");
257 263
258 case GNUNET_ARM_RESULT_IS_STARTED_ALREADY: 264 case GNUNET_ARM_RESULT_IS_STARTED_ALREADY:
259 return _("is started already"); 265 return _ ("is started already");
260 266
261 case GNUNET_ARM_RESULT_IS_STOPPED_ALREADY: 267 case GNUNET_ARM_RESULT_IS_STOPPED_ALREADY:
262 return _("is stopped already"); 268 return _ ("is stopped already");
263 269
264 case GNUNET_ARM_RESULT_IS_NOT_KNOWN: 270 case GNUNET_ARM_RESULT_IS_NOT_KNOWN:
265 return _("service is not known to ARM"); 271 return _ ("service is not known to ARM");
266 272
267 case GNUNET_ARM_RESULT_START_FAILED: 273 case GNUNET_ARM_RESULT_START_FAILED:
268 return _("service failed to start"); 274 return _ ("service failed to start");
269 275
270 case GNUNET_ARM_RESULT_IN_SHUTDOWN: 276 case GNUNET_ARM_RESULT_IN_SHUTDOWN:
271 return _("service cannot be manipulated because ARM is shutting down"); 277 return _ ("service cannot be manipulated because ARM is shutting down");
272 } 278 }
273 return _("Unknown result code."); 279 return _ ("Unknown result code.");
274} 280}
275 281
276 282
@@ -280,7 +286,7 @@ ret_string(enum GNUNET_ARM_Result result)
280 * @param cls closure 286 * @param cls closure
281 */ 287 */
282static void 288static void
283action_loop(void *cls); 289action_loop (void *cls);
284 290
285 291
286/** 292/**
@@ -293,18 +299,20 @@ action_loop(void *cls);
293 * #GNUNET_SYSERR on error. 299 * #GNUNET_SYSERR on error.
294 */ 300 */
295static void 301static void
296conn_status(void *cls, int connected) 302conn_status (void *cls,
303 int connected)
297{ 304{
298 static int once; 305 static int once;
299 306
300 (void)cls; 307 (void) cls;
301 if ((GNUNET_SYSERR == connected) && (0 == once)) 308 if ( (GNUNET_SYSERR == connected) &&
302 { 309 (0 == once) )
303 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 310 {
304 _("Fatal error initializing ARM API.\n")); 311 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
305 GNUNET_SCHEDULER_shutdown(); 312 _ ("Fatal error initializing ARM API.\n"));
306 return; 313 GNUNET_SCHEDULER_shutdown ();
307 } 314 return;
315 }
308 once = 1; 316 once = 1;
309} 317}
310 318
@@ -321,32 +329,34 @@ conn_status(void *cls, int connected)
321 * according to ARM 329 * according to ARM
322 */ 330 */
323static void 331static void
324start_callback(void *cls, 332start_callback (void *cls,
325 enum GNUNET_ARM_RequestStatus rs, 333 enum GNUNET_ARM_RequestStatus rs,
326 enum GNUNET_ARM_Result result) 334 enum GNUNET_ARM_Result result)
327{ 335{
328 (void)cls; 336 (void) cls;
329 op = NULL; 337 op = NULL;
330 if (GNUNET_ARM_REQUEST_SENT_OK != rs) 338 if (GNUNET_ARM_REQUEST_SENT_OK != rs)
331 { 339 {
332 fprintf(stdout, 340 fprintf (stdout,
333 _("Failed to start the ARM service: %s\n"), 341 _ ("Failed to start the ARM service: %s\n"),
334 req_string(rs)); 342 req_string (rs));
335 GNUNET_SCHEDULER_shutdown(); 343 GNUNET_SCHEDULER_shutdown ();
336 return; 344 return;
337 } 345 }
338 if ((GNUNET_ARM_RESULT_STARTING != result) && 346 if ((GNUNET_ARM_RESULT_STARTING != result) &&
339 (GNUNET_ARM_RESULT_IS_STARTED_ALREADY != result)) 347 (GNUNET_ARM_RESULT_IS_STARTED_ALREADY != result))
340 { 348 {
341 fprintf(stdout, 349 fprintf (stdout,
342 _("Failed to start the ARM service: %s\n"), 350 _ ("Failed to start the ARM service: %s\n"),
343 ret_string(result)); 351 ret_string (result));
344 GNUNET_SCHEDULER_shutdown(); 352 GNUNET_SCHEDULER_shutdown ();
345 return; 353 return;
346 } 354 }
347 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "ARM service [re]start successful\n"); 355 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
356 "ARM service [re]start successful\n");
348 start = 0; 357 start = 0;
349 al_task = GNUNET_SCHEDULER_add_now(&action_loop, NULL); 358 al_task = GNUNET_SCHEDULER_add_now (&action_loop,
359 NULL);
350} 360}
351 361
352 362
@@ -362,44 +372,47 @@ start_callback(void *cls,
362 * according to ARM 372 * according to ARM
363 */ 373 */
364static void 374static void
365stop_callback(void *cls, 375stop_callback (void *cls,
366 enum GNUNET_ARM_RequestStatus rs, 376 enum GNUNET_ARM_RequestStatus rs,
367 enum GNUNET_ARM_Result result) 377 enum GNUNET_ARM_Result result)
368{ 378{
369 char *msg; 379 char *msg;
370 380
371 (void)cls; 381 (void) cls;
372 op = NULL; 382 op = NULL;
373 if (GNUNET_ARM_REQUEST_SENT_OK != rs) 383 if (GNUNET_ARM_REQUEST_SENT_OK != rs)
374 { 384 {
375 GNUNET_asprintf(&msg, 385 GNUNET_asprintf (&msg,
376 "%s", 386 "%s",
377 _( 387 _ (
378 "Failed to send a stop request to the ARM service: %s\n")); 388 "Failed to send a stop request to the ARM service: %s\n"));
379 fprintf(stdout, msg, req_string(rs)); 389 fprintf (stdout, msg, req_string (rs));
380 GNUNET_free(msg); 390 GNUNET_free (msg);
381 GNUNET_SCHEDULER_shutdown(); 391 GNUNET_SCHEDULER_shutdown ();
382 return; 392 return;
383 } 393 }
384 if ((GNUNET_ARM_RESULT_STOPPING != result) && 394 if ( (GNUNET_ARM_RESULT_STOPPING != result) &&
385 (GNUNET_ARM_RESULT_STOPPED != result) && 395 (GNUNET_ARM_RESULT_STOPPED != result) &&
386 (GNUNET_ARM_RESULT_IS_STOPPED_ALREADY != result)) 396 (GNUNET_ARM_RESULT_IS_STOPPED_ALREADY != result) )
387 { 397 {
388 fprintf(stdout, 398 fprintf (stdout,
389 _("Failed to stop the ARM service: %s\n"), 399 _ ("Failed to stop the ARM service: %s\n"),
390 ret_string(result)); 400 ret_string (result));
391 GNUNET_SCHEDULER_shutdown(); 401 GNUNET_SCHEDULER_shutdown ();
392 return; 402 return;
393 } 403 }
394 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "ARM service shutdown successful\n"); 404 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
405 "ARM service shutdown successful\n");
395 end = 0; 406 end = 0;
396 if (restart) 407 if (restart)
397 { 408 {
398 restart = 0; 409 restart = 0;
399 start = 1; 410 start = 1;
400 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Initiating an ARM restart\n"); 411 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
401 } 412 "Initiating an ARM restart\n");
402 al_task = GNUNET_SCHEDULER_add_now(&action_loop, NULL); 413 }
414 al_task = GNUNET_SCHEDULER_add_now (&action_loop,
415 NULL);
403} 416}
404 417
405 418
@@ -415,37 +428,38 @@ stop_callback(void *cls,
415 * according to ARM 428 * according to ARM
416 */ 429 */
417static void 430static void
418init_callback(void *cls, 431init_callback (void *cls,
419 enum GNUNET_ARM_RequestStatus rs, 432 enum GNUNET_ARM_RequestStatus rs,
420 enum GNUNET_ARM_Result result) 433 enum GNUNET_ARM_Result result)
421{ 434{
422 (void)cls; 435 (void) cls;
423 op = NULL; 436 op = NULL;
424 if (GNUNET_ARM_REQUEST_SENT_OK != rs) 437 if (GNUNET_ARM_REQUEST_SENT_OK != rs)
425 { 438 {
426 fprintf(stdout, 439 fprintf (stdout,
427 _("Failed to send a request to start the `%s' service: %s\n"), 440 _ ("Failed to send a request to start the `%s' service: %s\n"),
428 init, 441 init,
429 req_string(rs)); 442 req_string (rs));
430 GNUNET_SCHEDULER_shutdown(); 443 GNUNET_SCHEDULER_shutdown ();
431 return; 444 return;
432 } 445 }
433 if ((GNUNET_ARM_RESULT_STARTING != result) && 446 if ((GNUNET_ARM_RESULT_STARTING != result) &&
434 (GNUNET_ARM_RESULT_IS_STARTED_ALREADY != result)) 447 (GNUNET_ARM_RESULT_IS_STARTED_ALREADY != result))
435 { 448 {
436 fprintf(stdout, 449 fprintf (stdout,
437 _("Failed to start the `%s' service: %s\n"), 450 _ ("Failed to start the `%s' service: %s\n"),
438 init, 451 init,
439 ret_string(result)); 452 ret_string (result));
440 GNUNET_SCHEDULER_shutdown(); 453 GNUNET_SCHEDULER_shutdown ();
441 return; 454 return;
442 } 455 }
443 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 456 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
444 "Service %s [re]started successfully\n", 457 "Service %s [re]started successfully\n",
445 init); 458 init);
446 GNUNET_free(init); 459 GNUNET_free (init);
447 init = NULL; 460 init = NULL;
448 al_task = GNUNET_SCHEDULER_add_now(&action_loop, NULL); 461 al_task = GNUNET_SCHEDULER_add_now (&action_loop,
462 NULL);
449} 463}
450 464
451 465
@@ -461,42 +475,45 @@ init_callback(void *cls,
461 * according to ARM 475 * according to ARM
462 */ 476 */
463static void 477static void
464term_callback(void *cls, 478term_callback (void *cls,
465 enum GNUNET_ARM_RequestStatus rs, 479 enum GNUNET_ARM_RequestStatus rs,
466 enum GNUNET_ARM_Result result) 480 enum GNUNET_ARM_Result result)
467{ 481{
468 char *msg; 482 char *msg;
469 483
470 (void)cls; 484 (void) cls;
471 op = NULL; 485 op = NULL;
472 if (GNUNET_ARM_REQUEST_SENT_OK != rs) 486 if (GNUNET_ARM_REQUEST_SENT_OK != rs)
473 { 487 {
474 GNUNET_asprintf(&msg, 488 GNUNET_asprintf (&msg,
475 _( 489 _ (
476 "Failed to send a request to kill the `%s' service: %%s\n"), 490 "Failed to send a request to kill the `%s' service: %%s\n"),
477 term); 491 term);
478 fprintf(stdout, msg, req_string(rs)); 492 fprintf (stdout,
479 GNUNET_free(msg); 493 msg,
480 GNUNET_SCHEDULER_shutdown(); 494 req_string (rs));
481 return; 495 GNUNET_free (msg);
482 } 496 GNUNET_SCHEDULER_shutdown ();
483 if ((GNUNET_ARM_RESULT_STOPPED != result) && 497 return;
484 (GNUNET_ARM_RESULT_IS_STOPPED_ALREADY != result)) 498 }
485 { 499 if ( (GNUNET_ARM_RESULT_STOPPED != result) &&
486 fprintf(stdout, 500 (GNUNET_ARM_RESULT_IS_STOPPED_ALREADY != result) )
487 _("Failed to kill the `%s' service: %s\n"), 501 {
488 term, 502 fprintf (stdout,
489 ret_string(result)); 503 _ ("Failed to kill the `%s' service: %s\n"),
490 GNUNET_SCHEDULER_shutdown(); 504 term,
491 return; 505 ret_string (result));
492 } 506 GNUNET_SCHEDULER_shutdown ();
507 return;
508 }
493 509
494 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 510 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
495 "Service %s stopped successfully\n", 511 "Service %s stopped successfully\n",
496 term); 512 term);
497 GNUNET_free(term); 513 GNUNET_free (term);
498 term = NULL; 514 term = NULL;
499 al_task = GNUNET_SCHEDULER_add_now(&action_loop, NULL); 515 al_task = GNUNET_SCHEDULER_add_now (&action_loop,
516 NULL);
500} 517}
501 518
502 519
@@ -508,42 +525,196 @@ term_callback(void *cls,
508 * @param cls closure (unused) 525 * @param cls closure (unused)
509 * @param rs request status (success, failure, etc.) 526 * @param rs request status (success, failure, etc.)
510 * @param count number of services in the list 527 * @param count number of services in the list
511 * @param list list of services that are running 528 * @param list list of services managed by arm
512 */ 529 */
513static void 530static void
514list_callback(void *cls, 531list_callback (void *cls,
515 enum GNUNET_ARM_RequestStatus rs, 532 enum GNUNET_ARM_RequestStatus rs,
516 unsigned int count, 533 unsigned int count,
517 const char *const *list) 534 const struct GNUNET_ARM_ServiceInfo *list)
518{ 535{
519 (void)cls; 536 unsigned int num_stopped = 0;
537 unsigned int num_started = 0;
538 unsigned int num_stopping = 0;
539 unsigned int num_failed = 0;
540 unsigned int num_finished = 0;
541 (void) cls;
520 op = NULL; 542 op = NULL;
521 if (GNUNET_ARM_REQUEST_SENT_OK != rs) 543 if (GNUNET_ARM_REQUEST_SENT_OK != rs)
544 {
545 char *msg;
546
547 GNUNET_asprintf (&msg,
548 "%s",
549 _ ("Failed to request a list of services: %s\n"));
550 fprintf (stdout,
551 msg,
552 req_string (rs));
553 GNUNET_free (msg);
554 ret = 3;
555 GNUNET_SCHEDULER_shutdown ();
556 }
557 if (NULL == list)
558 {
559 fprintf (stderr,
560 "%s",
561 _ ("Error communicating with ARM. ARM not running?\n"));
562 GNUNET_SCHEDULER_shutdown ();
563 ret = 3;
564 return;
565 }
566 for (unsigned int i = 0; i < count; i++)
567 {
568 switch (list[i].status)
522 { 569 {
523 char *msg; 570 case GNUNET_ARM_SERVICE_STATUS_STOPPED:
524 571 num_stopped++;
525 GNUNET_asprintf(&msg, 572 break;
526 "%s", 573 case GNUNET_ARM_SERVICE_STATUS_FAILED:
527 _("Failed to request a list of services: %s\n")); 574 num_failed++;
528 fprintf(stdout, msg, req_string(rs)); 575 break;
529 GNUNET_free(msg); 576 case GNUNET_ARM_SERVICE_STATUS_FINISHED:
530 ret = 3; 577 num_finished++;
531 GNUNET_SCHEDULER_shutdown(); 578 break;
579 case GNUNET_ARM_SERVICE_STATUS_STARTED:
580 num_started++;
581 break;
582 case GNUNET_ARM_SERVICE_STATUS_STOPPING:
583 num_stopping++;
584 fprintf (stdout,
585 "%s (binary='%s', status=stopping)\n",
586 list[i].name,
587 list[i].binary);
588 break;
589 default:
590 GNUNET_break_op (0);
591 fprintf (stdout,
592 "%s (binary='%s', status=unknown)\n",
593 list[i].name,
594 list[i].binary);
595 break;
532 } 596 }
533 if (NULL == list) 597 }
598 if (! quiet)
599 {
600 if (show_all)
601 fprintf (stdout,
602 "%s",
603 _ ("All services:\n"));
604 else
605 fprintf (stdout,
606 "%s",
607 _ ("Services (excluding stopped services):\n"));
608 if (num_stopped || num_failed || num_finished || num_stopping ||
609 num_started)
534 { 610 {
535 fprintf(stderr, 611 int sep = 0;
536 "%s", 612 fprintf (stdout, "(");
537 _("Error communicating with ARM. ARM not running?\n")); 613 if (0 != num_started)
538 GNUNET_SCHEDULER_shutdown(); 614 {
539 ret = 3; 615 if (sep)
540 return; 616 fprintf (stdout, " / ");
617 fprintf (stdout,
618 "started: %u",
619 num_started);
620 sep = 1;
621 }
622 if (0 != num_failed)
623 {
624 if (sep)
625 fprintf (stdout, " / ");
626 fprintf (stdout,
627 "failed: %u",
628 num_failed);
629 sep = 1;
630 }
631 if (0 != num_stopping)
632 {
633 if (sep)
634 fprintf (stdout, " / ");
635 fprintf (stdout,
636 "stopping: %u",
637 num_stopping);
638 sep = 1;
639 }
640 if (0 != num_stopped)
641 {
642 if (sep)
643 fprintf (stdout, " / ");
644 fprintf (stdout,
645 "stopped: %u",
646 num_stopped);
647 sep = 1;
648 }
649 if (0 != num_finished)
650 {
651 if (sep)
652 fprintf (stdout, " / ");
653 fprintf (stdout,
654 "finished: %u",
655 num_finished);
656 sep = 1;
657 }
658 fprintf (stdout, ")\n");
541 } 659 }
542 if (!quiet) 660 else
543 fprintf(stdout, "%s", _("Running services:\n")); 661 {
662 fprintf (stdout,
663 "%s",
664 _ ("(No services configured.)\n"));
665 }
666 }
544 for (unsigned int i = 0; i < count; i++) 667 for (unsigned int i = 0; i < count; i++)
545 fprintf(stdout, "%s\n", list[i]); 668 {
546 al_task = GNUNET_SCHEDULER_add_now(&action_loop, NULL); 669 struct GNUNET_TIME_Relative restart_in;
670 switch (list[i].status)
671 {
672 case GNUNET_ARM_SERVICE_STATUS_STOPPED:
673 if (show_all)
674 fprintf (stdout,
675 "%s (binary='%s', status=stopped)\n",
676 list[i].name,
677 list[i].binary);
678 break;
679 case GNUNET_ARM_SERVICE_STATUS_FAILED:
680 restart_in = GNUNET_TIME_absolute_get_remaining (list[i].restart_at);
681 fprintf (stdout,
682 "%s (binary='%s', status=failed, exit_status=%d, restart_delay='%s')\n",
683 list[i].name,
684 list[i].binary,
685 list[i].last_exit_status,
686 GNUNET_STRINGS_relative_time_to_string (restart_in,
687 GNUNET_YES));
688 break;
689 case GNUNET_ARM_SERVICE_STATUS_FINISHED:
690 fprintf (stdout,
691 "%s (binary='%s', status=finished)\n",
692 list[i].name,
693 list[i].binary);
694 break;
695 case GNUNET_ARM_SERVICE_STATUS_STARTED:
696 fprintf (stdout,
697 "%s (binary='%s', status=started)\n",
698 list[i].name,
699 list[i].binary);
700 break;
701 case GNUNET_ARM_SERVICE_STATUS_STOPPING:
702 fprintf (stdout,
703 "%s (binary='%s', status=stopping)\n",
704 list[i].name,
705 list[i].binary);
706 break;
707 default:
708 GNUNET_break_op (0);
709 fprintf (stdout,
710 "%s (binary='%s', status=unknown)\n",
711 list[i].name,
712 list[i].binary);
713 break;
714 }
715 }
716 al_task = GNUNET_SCHEDULER_add_now (&action_loop,
717 NULL);
547} 718}
548 719
549 720
@@ -554,91 +725,115 @@ list_callback(void *cls,
554 * @param cls closure, unused 725 * @param cls closure, unused
555 */ 726 */
556static void 727static void
557action_loop(void *cls) 728action_loop (void *cls)
558{ 729{
559 (void)cls; 730 (void) cls;
560 al_task = NULL; 731 al_task = NULL;
561 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Running requested actions\n"); 732 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
733 "Running requested actions\n");
562 while (1) 734 while (1)
735 {
736 switch (phase++)
563 { 737 {
564 switch (phase++) 738 case 0:
739 if (NULL != term)
740 {
741 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
742 "Termination action\n");
743 op = GNUNET_ARM_request_service_stop (h,
744 term,
745 &term_callback,
746 NULL);
747 return;
748 }
749 break;
750
751 case 1:
752 if (end || restart)
753 {
754 if (GNUNET_YES !=
755 GNUNET_CLIENT_test (cfg,
756 "arm"))
757 {
758 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
759 "GNUnet not running, cannot stop the peer\n");
760 }
761 else
565 { 762 {
566 case 0: 763 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
567 if (NULL != term) 764 "End action\n");
568 { 765 op = GNUNET_ARM_request_service_stop (h,
569 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Termination action\n"); 766 "arm",
570 op = GNUNET_ARM_request_service_stop(h, term, &term_callback, NULL); 767 &stop_callback,
571 return; 768 NULL);
572 }
573 break;
574
575 case 1:
576 if (end || restart)
577 {
578 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "End action\n");
579 op = GNUNET_ARM_request_service_stop(h, "arm", &stop_callback, NULL);
580 return;
581 }
582 break;
583
584 case 2:
585 if (start)
586 {
587 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Start action\n");
588 op =
589 GNUNET_ARM_request_service_start(h,
590 "arm",
591 (no_stdout
592 ? 0
593 : GNUNET_OS_INHERIT_STD_OUT) |
594 (no_stderr
595 ? 0
596 : GNUNET_OS_INHERIT_STD_ERR),
597 &start_callback,
598 NULL);
599 return;
600 }
601 break;
602
603 case 3:
604 if (NULL != init)
605 {
606 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Initialization action\n");
607 op = GNUNET_ARM_request_service_start(h,
608 init,
609 GNUNET_OS_INHERIT_STD_NONE,
610 &init_callback,
611 NULL);
612 return;
613 }
614 break;
615
616 case 4:
617 if (list)
618 {
619 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
620 "Going to list all running services controlled by ARM.\n");
621 op = GNUNET_ARM_request_service_list(h, &list_callback, &list);
622 return;
623 }
624 break;
625
626 case 5:
627 if (monitor)
628 {
629 if (!quiet)
630 fprintf(stderr, _("Now only monitoring, press CTRL-C to stop.\n"));
631 quiet =
632 0; /* does not make sense to stay quiet in monitor mode at this time */
633 return; /* done with tasks, just monitor */
634 }
635 break;
636
637 default: /* last phase */
638 GNUNET_SCHEDULER_shutdown();
639 return; 769 return;
640 } 770 }
771 }
772 break;
773
774 case 2:
775 if (start)
776 {
777 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
778 "Start action\n");
779 op =
780 GNUNET_ARM_request_service_start (h,
781 "arm",
782 (no_stdout
783 ? 0
784 : GNUNET_OS_INHERIT_STD_OUT)
785 | (no_stderr
786 ? 0
787 : GNUNET_OS_INHERIT_STD_ERR),
788 &start_callback,
789 NULL);
790 return;
791 }
792 break;
793
794 case 3:
795 if (NULL != init)
796 {
797 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
798 "Initialization action\n");
799 op = GNUNET_ARM_request_service_start (h,
800 init,
801 GNUNET_OS_INHERIT_STD_NONE,
802 &init_callback,
803 NULL);
804 return;
805 }
806 break;
807
808 case 4:
809 if (list)
810 {
811 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
812 "Going to list all running services controlled by ARM.\n");
813 op = GNUNET_ARM_request_service_list (h,
814 &list_callback,
815 &list);
816 return;
817 }
818 break;
819
820 case 5:
821 if (monitor)
822 {
823 if (! quiet)
824 fprintf (stderr,
825 _ ("Now only monitoring, press CTRL-C to stop.\n"));
826 quiet =
827 0; /* does not make sense to stay quiet in monitor mode at this time */
828 return; /* done with tasks, just monitor */
829 }
830 break;
831
832 default: /* last phase */
833 GNUNET_SCHEDULER_shutdown ();
834 return;
641 } 835 }
836 }
642} 837}
643 838
644 839
@@ -650,48 +845,50 @@ action_loop(void *cls)
650 * @param status status of the service 845 * @param status status of the service
651 */ 846 */
652static void 847static void
653srv_status(void *cls, 848srv_status (void *cls,
654 const char *service, 849 const char *service,
655 enum GNUNET_ARM_ServiceStatus status) 850 enum GNUNET_ARM_ServiceMonitorStatus status)
656{ 851{
657 const char *msg; 852 const char *msg;
658 853
659 (void)cls; 854 (void) cls;
660 switch (status) 855 switch (status)
661 { 856 {
662 case GNUNET_ARM_SERVICE_MONITORING_STARTED: 857 case GNUNET_ARM_SERVICE_MONITORING_STARTED:
663 return; /* this should be done silently */ 858 return; /* this should be done silently */
664 859
665 case GNUNET_ARM_SERVICE_STOPPED: 860 case GNUNET_ARM_SERVICE_STOPPED:
666 msg = _("Stopped %s.\n"); 861 msg = _ ("Stopped %s.\n");
667 break; 862 break;
668 863
669 case GNUNET_ARM_SERVICE_STARTING: 864 case GNUNET_ARM_SERVICE_STARTING:
670 msg = _("Starting %s...\n"); 865 msg = _ ("Starting %s...\n");
671 break; 866 break;
672 867
673 case GNUNET_ARM_SERVICE_STOPPING: 868 case GNUNET_ARM_SERVICE_STOPPING:
674 msg = _("Stopping %s...\n"); 869 msg = _ ("Stopping %s...\n");
675 break; 870 break;
676 871
677 default: 872 default:
678 msg = NULL; 873 msg = NULL;
679 break; 874 break;
680 } 875 }
681 if (!quiet) 876 if (! quiet)
682 { 877 {
683 if (NULL != msg) 878 if (NULL != msg)
684 fprintf(stderr, msg, service); 879 fprintf (stderr,
685 else 880 msg,
686 fprintf(stderr, 881 service);
687 _("Unknown status %u for service %s.\n"), 882 else
688 status, 883 fprintf (stderr,
689 service); 884 _ ("Unknown status %u for service %s.\n"),
690 } 885 status,
691 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 886 service);
692 "Got service %s status %d\n", 887 }
693 service, 888 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
694 (int)status); 889 "Got service %s status %d\n",
890 service,
891 (int) status);
695} 892}
696 893
697 894
@@ -699,12 +896,12 @@ srv_status(void *cls,
699 * Task run on timeout (if -T is given). 896 * Task run on timeout (if -T is given).
700 */ 897 */
701static void 898static void
702timeout_task_cb(void *cls) 899timeout_task_cb (void *cls)
703{ 900{
704 (void)cls; 901 (void) cls;
705 timeout_task = NULL; 902 timeout_task = NULL;
706 ret = 2; 903 ret = 2;
707 GNUNET_SCHEDULER_shutdown(); 904 GNUNET_SCHEDULER_shutdown ();
708} 905}
709 906
710 907
@@ -717,34 +914,47 @@ timeout_task_cb(void *cls)
717 * @param c configuration 914 * @param c configuration
718 */ 915 */
719static void 916static void
720run(void *cls, 917run (void *cls,
721 char *const *args, 918 char *const *args,
722 const char *cfgfile, 919 const char *cfgfile,
723 const struct GNUNET_CONFIGURATION_Handle *c) 920 const struct GNUNET_CONFIGURATION_Handle *c)
724{ 921{
725 (void)cls; 922 (void) cls;
726 (void)args; 923 (void) args;
727 (void)cfgfile; 924 (void) cfgfile;
728 cfg = GNUNET_CONFIGURATION_dup(c); 925 cfg = GNUNET_CONFIGURATION_dup (c);
729 if (GNUNET_OK != 926 if (GNUNET_OK !=
730 GNUNET_CONFIGURATION_get_value_string(cfg, "PATHS", "GNUNET_HOME", &dir)) 927 GNUNET_CONFIGURATION_get_value_string (cfg,
731 { 928 "PATHS",
732 GNUNET_log_config_missing(GNUNET_ERROR_TYPE_ERROR, "PATHS", "GNUNET_HOME"); 929 "GNUNET_HOME",
733 return; 930 &dir))
734 } 931 {
735 (void)GNUNET_CONFIGURATION_get_value_filename(cfg, 932 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
736 "arm", 933 "PATHS",
737 "CONFIG", 934 "GNUNET_HOME");
738 &config_file); 935 return;
739 if (NULL == (h = GNUNET_ARM_connect(cfg, &conn_status, NULL))) 936 }
937 (void) GNUNET_CONFIGURATION_get_value_filename (cfg,
938 "arm",
939 "CONFIG",
940 &config_file);
941 if (NULL == (h = GNUNET_ARM_connect (cfg,
942 &conn_status,
943 NULL)))
740 return; 944 return;
741 if (monitor) 945 if (monitor)
742 m = GNUNET_ARM_monitor_start(cfg, &srv_status, NULL); 946 m = GNUNET_ARM_monitor_start (cfg,
743 al_task = GNUNET_SCHEDULER_add_now(&action_loop, NULL); 947 &srv_status,
744 GNUNET_SCHEDULER_add_shutdown(&shutdown_task, NULL); 948 NULL);
949 al_task = GNUNET_SCHEDULER_add_now (&action_loop,
950 NULL);
951 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
952 NULL);
745 if (0 != timeout.rel_value_us) 953 if (0 != timeout.rel_value_us)
746 timeout_task = 954 timeout_task =
747 GNUNET_SCHEDULER_add_delayed(timeout, &timeout_task_cb, NULL); 955 GNUNET_SCHEDULER_add_delayed (timeout,
956 &timeout_task_cb,
957 NULL);
748} 958}
749 959
750 960
@@ -756,88 +966,98 @@ run(void *cls,
756 * @return 0 ok, 1 on error, 2 on timeout 966 * @return 0 ok, 1 on error, 2 on timeout
757 */ 967 */
758int 968int
759main(int argc, char *const *argv) 969main (int argc, char *const *argv)
760{ 970{
761 struct GNUNET_GETOPT_CommandLineOption options[] = 971 struct GNUNET_GETOPT_CommandLineOption options[] = {
762 { GNUNET_GETOPT_option_flag('e', 972 GNUNET_GETOPT_option_flag ('e',
763 "end", 973 "end",
764 gettext_noop("stop all GNUnet services"), 974 gettext_noop ("stop all GNUnet services"),
765 &end), 975 &end),
766 GNUNET_GETOPT_option_string('i', 976 GNUNET_GETOPT_option_string ('i',
767 "init", 977 "init",
768 "SERVICE", 978 "SERVICE",
769 gettext_noop("start a particular service"), 979 gettext_noop ("start a particular service"),
770 &init), 980 &init),
771 GNUNET_GETOPT_option_string('k', 981 GNUNET_GETOPT_option_string ('k',
772 "kill", 982 "kill",
773 "SERVICE", 983 "SERVICE",
774 gettext_noop("stop a particular service"), 984 gettext_noop ("stop a particular service"),
775 &term), 985 &term),
776 GNUNET_GETOPT_option_flag('s', 986 GNUNET_GETOPT_option_flag ('a',
777 "start", 987 "all",
778 gettext_noop( 988 gettext_noop (
779 "start all GNUnet default services"), 989 "also show stopped services (used with -I)"),
780 &start), 990 &show_all),
781 GNUNET_GETOPT_option_flag('r', 991 GNUNET_GETOPT_option_flag ('s',
782 "restart", 992 "start",
783 gettext_noop( 993 gettext_noop (
784 "stop and start all GNUnet default services"), 994 "start all GNUnet default services"),
785 &restart), 995 &start),
786 GNUNET_GETOPT_option_flag('d', 996 GNUNET_GETOPT_option_flag ('r',
787 "delete", 997 "restart",
788 gettext_noop( 998 gettext_noop (
789 "delete config file and directory on exit"), 999 "stop and start all GNUnet default services"),
790 &delete), 1000 &restart),
791 GNUNET_GETOPT_option_flag('m', 1001 GNUNET_GETOPT_option_flag ('d',
792 "monitor", 1002 "delete",
793 gettext_noop("monitor ARM activities"), 1003 gettext_noop (
794 &monitor), 1004 "delete config file and directory on exit"),
795 GNUNET_GETOPT_option_flag('q', 1005 &delete),
796 "quiet", 1006 GNUNET_GETOPT_option_flag ('m',
797 gettext_noop("don't print status messages"), 1007 "monitor",
798 &quiet), 1008 gettext_noop ("monitor ARM activities"),
799 GNUNET_GETOPT_option_relative_time( 1009 &monitor),
1010 GNUNET_GETOPT_option_flag ('q',
1011 "quiet",
1012 gettext_noop ("don't print status messages"),
1013 &quiet),
1014 GNUNET_GETOPT_option_relative_time (
800 'T', 1015 'T',
801 "timeout", 1016 "timeout",
802 "DELAY", 1017 "DELAY",
803 gettext_noop( 1018 gettext_noop (
804 "exit with error status if operation does not finish after DELAY"), 1019 "exit with error status if operation does not finish after DELAY"),
805 &timeout), 1020 &timeout),
806 GNUNET_GETOPT_option_flag('I', 1021 GNUNET_GETOPT_option_flag ('I',
807 "info", 1022 "info",
808 gettext_noop( 1023 gettext_noop (
809 "list currently running services"), 1024 "list currently running services"),
810 &list), 1025 &list),
811 GNUNET_GETOPT_option_flag( 1026 GNUNET_GETOPT_option_flag (
812 'O', 1027 'O',
813 "no-stdout", 1028 "no-stdout",
814 gettext_noop("don't let gnunet-service-arm inherit standard output"), 1029 gettext_noop ("don't let gnunet-service-arm inherit standard output"),
815 &no_stdout), 1030 &no_stdout),
816 GNUNET_GETOPT_option_flag( 1031 GNUNET_GETOPT_option_flag (
817 'E', 1032 'E',
818 "no-stderr", 1033 "no-stderr",
819 gettext_noop("don't let gnunet-service-arm inherit standard error"), 1034 gettext_noop ("don't let gnunet-service-arm inherit standard error"),
820 &no_stderr), 1035 &no_stderr),
821 GNUNET_GETOPT_OPTION_END }; 1036 GNUNET_GETOPT_OPTION_END
1037 };
822 int lret; 1038 int lret;
823 1039
824 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args(argc, argv, &argc, &argv)) 1040 if (GNUNET_OK !=
1041 GNUNET_STRINGS_get_utf8_args (argc,
1042 argv,
1043 &argc,
1044 &argv))
825 return 2; 1045 return 2;
826 if (GNUNET_OK == 1046 if (GNUNET_OK ==
827 (lret = GNUNET_PROGRAM_run( 1047 (lret = GNUNET_PROGRAM_run (
828 argc, 1048 argc,
829 argv, 1049 argv,
830 "gnunet-arm", 1050 "gnunet-arm",
831 gettext_noop( 1051 gettext_noop (
832 "Control services and the Automated Restart Manager (ARM)"), 1052 "Control services and the Automated Restart Manager (ARM)"),
833 options, 1053 options,
834 &run, 1054 &run,
835 NULL))) 1055 NULL)))
836 { 1056 {
837 GNUNET_free((void *)argv); 1057 GNUNET_free ((void *) argv);
838 return ret; 1058 return ret;
839 } 1059 }
840 GNUNET_free((void *)argv); 1060 GNUNET_free ((void *) argv);
841 return lret; 1061 return lret;
842} 1062}
843 1063
diff --git a/src/arm/gnunet-service-arm.c b/src/arm/gnunet-service-arm.c
index e02314b91..d13be6eb1 100644
--- a/src/arm/gnunet-service-arm.c
+++ b/src/arm/gnunet-service-arm.c
@@ -29,10 +29,10 @@
29#include "gnunet_protocols.h" 29#include "gnunet_protocols.h"
30#include "arm.h" 30#include "arm.h"
31 31
32#define LOG(kind, ...) GNUNET_log_from(kind, "util", __VA_ARGS__) 32#define LOG(kind, ...) GNUNET_log_from (kind, "util", __VA_ARGS__)
33 33
34#define LOG_STRERROR(kind, syscall) \ 34#define LOG_STRERROR(kind, syscall) \
35 GNUNET_log_from_strerror(kind, "util", syscall) 35 GNUNET_log_from_strerror (kind, "util", syscall)
36 36
37 37
38#if HAVE_WAIT4 38#if HAVE_WAIT4
@@ -65,7 +65,8 @@ struct ServiceList;
65/** 65/**
66 * Record with information about a listen socket we have open. 66 * Record with information about a listen socket we have open.
67 */ 67 */
68struct ServiceListeningInfo { 68struct ServiceListeningInfo
69{
69 /** 70 /**
70 * This is a linked list. 71 * This is a linked list.
71 */ 72 */
@@ -106,7 +107,8 @@ struct ServiceListeningInfo {
106/** 107/**
107 * List of our services. 108 * List of our services.
108 */ 109 */
109struct ServiceList { 110struct ServiceList
111{
110 /** 112 /**
111 * This is a doubly-linked list. 113 * This is a doubly-linked list.
112 */ 114 */
@@ -164,6 +166,11 @@ struct ServiceList {
164 struct GNUNET_TIME_Relative backoff; 166 struct GNUNET_TIME_Relative backoff;
165 167
166 /** 168 /**
169 * Absolute time at which the process was (re-)started last.
170 */
171 struct GNUNET_TIME_Absolute last_started_at;
172
173 /**
167 * Absolute time at which the process is scheduled to restart in case of death 174 * Absolute time at which the process is scheduled to restart in case of death
168 */ 175 */
169 struct GNUNET_TIME_Absolute restart_at; 176 struct GNUNET_TIME_Absolute restart_at;
@@ -186,6 +193,11 @@ struct ServiceList {
186 * are on Windoze). 193 * are on Windoze).
187 */ 194 */
188 int pipe_control; 195 int pipe_control;
196
197 /**
198 * Last exit status of the process.
199 */
200 int last_exit_status;
189}; 201};
190 202
191/** 203/**
@@ -278,30 +290,30 @@ static struct GNUNET_NotificationContext *notifier;
278 * parameter is ignore on systems other than LINUX 290 * parameter is ignore on systems other than LINUX
279 */ 291 */
280static void 292static void
281add_unixpath(struct sockaddr **saddrs, 293add_unixpath (struct sockaddr **saddrs,
282 socklen_t *saddrlens, 294 socklen_t *saddrlens,
283 const char *unixpath, 295 const char *unixpath,
284 int abstract) 296 int abstract)
285{ 297{
286#ifdef AF_UNIX 298#ifdef AF_UNIX
287 struct sockaddr_un *un; 299 struct sockaddr_un *un;
288 300
289 un = GNUNET_new(struct sockaddr_un); 301 un = GNUNET_new (struct sockaddr_un);
290 un->sun_family = AF_UNIX; 302 un->sun_family = AF_UNIX;
291 GNUNET_strlcpy(un->sun_path, unixpath, sizeof(un->sun_path)); 303 GNUNET_strlcpy (un->sun_path, unixpath, sizeof(un->sun_path));
292#ifdef LINUX 304#ifdef LINUX
293 if (GNUNET_YES == abstract) 305 if (GNUNET_YES == abstract)
294 un->sun_path[0] = '\0'; 306 un->sun_path[0] = '\0';
295#endif 307#endif
296#if HAVE_SOCKADDR_UN_SUN_LEN 308#if HAVE_SOCKADDR_UN_SUN_LEN
297 un->sun_len = (u_char)sizeof(struct sockaddr_un); 309 un->sun_len = (u_char) sizeof(struct sockaddr_un);
298#endif 310#endif
299 *saddrs = (struct sockaddr *)un; 311 *saddrs = (struct sockaddr *) un;
300 *saddrlens = sizeof(struct sockaddr_un); 312 *saddrlens = sizeof(struct sockaddr_un);
301#else 313#else
302 /* this function should never be called 314 /* this function should never be called
303 * unless AF_UNIX is defined! */ 315 * unless AF_UNIX is defined! */
304 GNUNET_assert(0); 316 GNUNET_assert (0);
305#endif 317#endif
306} 318}
307 319
@@ -327,10 +339,10 @@ add_unixpath(struct sockaddr **saddrs,
327 * set to NULL). 339 * set to NULL).
328 */ 340 */
329static int 341static int
330get_server_addresses(const char *service_name, 342get_server_addresses (const char *service_name,
331 const struct GNUNET_CONFIGURATION_Handle *cfg, 343 const struct GNUNET_CONFIGURATION_Handle *cfg,
332 struct sockaddr ***addrs, 344 struct sockaddr ***addrs,
333 socklen_t **addr_lens) 345 socklen_t **addr_lens)
334{ 346{
335 int disablev6; 347 int disablev6;
336 struct GNUNET_NETWORK_Handle *desc; 348 struct GNUNET_NETWORK_Handle *desc;
@@ -351,72 +363,72 @@ get_server_addresses(const char *service_name,
351 *addrs = NULL; 363 *addrs = NULL;
352 *addr_lens = NULL; 364 *addr_lens = NULL;
353 desc = NULL; 365 desc = NULL;
354 if (GNUNET_CONFIGURATION_have_value(cfg, service_name, "DISABLEV6")) 366 if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "DISABLEV6"))
355 { 367 {
356 if (GNUNET_SYSERR == 368 if (GNUNET_SYSERR ==
357 (disablev6 = GNUNET_CONFIGURATION_get_value_yesno(cfg, 369 (disablev6 = GNUNET_CONFIGURATION_get_value_yesno (cfg,
358 service_name, 370 service_name,
359 "DISABLEV6"))) 371 "DISABLEV6")))
360 return GNUNET_SYSERR; 372 return GNUNET_SYSERR;
361 } 373 }
362 else 374 else
363 disablev6 = GNUNET_NO; 375 disablev6 = GNUNET_NO;
364 376
365 if (!disablev6) 377 if (! disablev6)
378 {
379 /* probe IPv6 support */
380 desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0);
381 if (NULL == desc)
366 { 382 {
367 /* probe IPv6 support */ 383 if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
368 desc = GNUNET_NETWORK_socket_create(PF_INET6, SOCK_STREAM, 0); 384 (EACCES == errno))
369 if (NULL == desc) 385 {
370 { 386 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket");
371 if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) || 387 return GNUNET_SYSERR;
372 (EACCES == errno)) 388 }
373 { 389 LOG (GNUNET_ERROR_TYPE_INFO,
374 LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "socket"); 390 _ (
375 return GNUNET_SYSERR; 391 "Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"),
376 } 392 service_name,
377 LOG(GNUNET_ERROR_TYPE_INFO, 393 strerror (errno));
378 _( 394 disablev6 = GNUNET_YES;
379 "Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"),
380 service_name,
381 strerror(errno));
382 disablev6 = GNUNET_YES;
383 }
384 else
385 {
386 GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(desc));
387 desc = NULL;
388 }
389 } 395 }
396 else
397 {
398 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc));
399 desc = NULL;
400 }
401 }
390 402
391 port = 0; 403 port = 0;
392 if (GNUNET_CONFIGURATION_have_value(cfg, service_name, "PORT")) 404 if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT"))
405 {
406 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg,
407 service_name,
408 "PORT",
409 &port))
393 { 410 {
394 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number(cfg, 411 LOG (GNUNET_ERROR_TYPE_ERROR,
395 service_name, 412 _ ("Require valid port number for service `%s' in configuration!\n"),
396 "PORT", 413 service_name);
397 &port))
398 {
399 LOG(GNUNET_ERROR_TYPE_ERROR,
400 _("Require valid port number for service `%s' in configuration!\n"),
401 service_name);
402 }
403 if (port > 65535)
404 {
405 LOG(GNUNET_ERROR_TYPE_ERROR,
406 _("Require valid port number for service `%s' in configuration!\n"),
407 service_name);
408 return GNUNET_SYSERR;
409 }
410 } 414 }
411 415 if (port > 65535)
412 if (GNUNET_CONFIGURATION_have_value(cfg, service_name, "BINDTO"))
413 { 416 {
414 GNUNET_break(GNUNET_OK == 417 LOG (GNUNET_ERROR_TYPE_ERROR,
415 GNUNET_CONFIGURATION_get_value_string(cfg, 418 _ ("Require valid port number for service `%s' in configuration!\n"),
419 service_name);
420 return GNUNET_SYSERR;
421 }
422 }
423
424 if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "BINDTO"))
425 {
426 GNUNET_break (GNUNET_OK ==
427 GNUNET_CONFIGURATION_get_value_string (cfg,
416 service_name, 428 service_name,
417 "BINDTO", 429 "BINDTO",
418 &hostname)); 430 &hostname));
419 } 431 }
420 else 432 else
421 hostname = NULL; 433 hostname = NULL;
422 434
@@ -424,235 +436,235 @@ get_server_addresses(const char *service_name,
424 abstract = GNUNET_NO; 436 abstract = GNUNET_NO;
425#ifdef AF_UNIX 437#ifdef AF_UNIX
426 if ((GNUNET_YES == 438 if ((GNUNET_YES ==
427 GNUNET_CONFIGURATION_have_value(cfg, service_name, "UNIXPATH")) && 439 GNUNET_CONFIGURATION_have_value (cfg, service_name, "UNIXPATH")) &&
428 (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename(cfg, 440 (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename (cfg,
429 service_name, 441 service_name,
430 "UNIXPATH", 442 "UNIXPATH",
431 &unixpath)) && 443 &unixpath)) &&
432 (0 < strlen(unixpath))) 444 (0 < strlen (unixpath)))
433 { 445 {
434 /* probe UNIX support */ 446 /* probe UNIX support */
435 struct sockaddr_un s_un; 447 struct sockaddr_un s_un;
436 448
437 if (strlen(unixpath) >= sizeof(s_un.sun_path)) 449 if (strlen (unixpath) >= sizeof(s_un.sun_path))
438 { 450 {
439 LOG(GNUNET_ERROR_TYPE_WARNING, 451 LOG (GNUNET_ERROR_TYPE_WARNING,
440 _("UNIXPATH `%s' too long, maximum length is %llu\n"), 452 _ ("UNIXPATH `%s' too long, maximum length is %llu\n"),
441 unixpath, 453 unixpath,
442 (unsigned long long)sizeof(s_un.sun_path)); 454 (unsigned long long) sizeof(s_un.sun_path));
443 unixpath = GNUNET_NETWORK_shorten_unixpath(unixpath); 455 unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath);
444 LOG(GNUNET_ERROR_TYPE_INFO, _("Using `%s' instead\n"), unixpath); 456 LOG (GNUNET_ERROR_TYPE_INFO, _ ("Using `%s' instead\n"), unixpath);
445 } 457 }
446#ifdef LINUX 458#ifdef LINUX
447 abstract = GNUNET_CONFIGURATION_get_value_yesno(cfg, 459 abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg,
448 "TESTING", 460 "TESTING",
449 "USE_ABSTRACT_SOCKETS"); 461 "USE_ABSTRACT_SOCKETS");
450 if (GNUNET_SYSERR == abstract) 462 if (GNUNET_SYSERR == abstract)
451 abstract = GNUNET_NO; 463 abstract = GNUNET_NO;
452#endif 464#endif
453 if ((GNUNET_YES != abstract) && 465 if ((GNUNET_YES != abstract) &&
454 (GNUNET_OK != GNUNET_DISK_directory_create_for_file(unixpath))) 466 (GNUNET_OK != GNUNET_DISK_directory_create_for_file (unixpath)))
455 GNUNET_log_strerror_file(GNUNET_ERROR_TYPE_ERROR, "mkdir", unixpath); 467 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "mkdir", unixpath);
456 } 468 }
457 if (NULL != unixpath) 469 if (NULL != unixpath)
470 {
471 desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
472 if (NULL == desc)
458 { 473 {
459 desc = GNUNET_NETWORK_socket_create(AF_UNIX, SOCK_STREAM, 0); 474 if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
460 if (NULL == desc) 475 (EACCES == errno))
461 { 476 {
462 if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) || 477 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket");
463 (EACCES == errno)) 478 GNUNET_free_non_null (hostname);
464 { 479 GNUNET_free (unixpath);
465 LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "socket"); 480 return GNUNET_SYSERR;
466 GNUNET_free_non_null(hostname); 481 }
467 GNUNET_free(unixpath); 482 LOG (GNUNET_ERROR_TYPE_INFO,
468 return GNUNET_SYSERR; 483 _ (
469 } 484 "Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
470 LOG(GNUNET_ERROR_TYPE_INFO, 485 service_name,
471 _( 486 strerror (errno));
472 "Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"), 487 GNUNET_free (unixpath);
473 service_name, 488 unixpath = NULL;
474 strerror(errno)); 489 }
475 GNUNET_free(unixpath); 490 else
476 unixpath = NULL; 491 {
477 } 492 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc));
478 else 493 desc = NULL;
479 {
480 GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(desc));
481 desc = NULL;
482 }
483 } 494 }
495 }
484#endif 496#endif
485 497
486 if ((0 == port) && (NULL == unixpath)) 498 if ((0 == port) && (NULL == unixpath))
499 {
500 if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (cfg,
501 service_name,
502 "START_ON_DEMAND"))
503 LOG (GNUNET_ERROR_TYPE_ERROR,
504 _ (
505 "Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
506 service_name);
507 GNUNET_free_non_null (hostname);
508 return GNUNET_SYSERR;
509 }
510 if (0 == port)
511 {
512 saddrs = GNUNET_new_array (2, struct sockaddr *);
513 saddrlens = GNUNET_new_array (2, socklen_t);
514 add_unixpath (saddrs, saddrlens, unixpath, abstract);
515 GNUNET_free_non_null (unixpath);
516 GNUNET_free_non_null (hostname);
517 *addrs = saddrs;
518 *addr_lens = saddrlens;
519 return 1;
520 }
521
522 if (NULL != hostname)
523 {
524 LOG (GNUNET_ERROR_TYPE_DEBUG,
525 "Resolving `%s' since that is where `%s' will bind to.\n",
526 hostname,
527 service_name);
528 memset (&hints, 0, sizeof(struct addrinfo));
529 if (disablev6)
530 hints.ai_family = AF_INET;
531 hints.ai_protocol = IPPROTO_TCP;
532 if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) ||
533 (NULL == res))
487 { 534 {
488 if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno(cfg, 535 LOG (GNUNET_ERROR_TYPE_ERROR,
489 service_name, 536 _ ("Failed to resolve `%s': %s\n"),
490 "START_ON_DEMAND")) 537 hostname,
491 LOG(GNUNET_ERROR_TYPE_ERROR, 538 gai_strerror (ret));
492 _( 539 GNUNET_free (hostname);
493 "Have neither PORT nor UNIXPATH for service `%s', but one is required\n"), 540 GNUNET_free_non_null (unixpath);
494 service_name);
495 GNUNET_free_non_null(hostname);
496 return GNUNET_SYSERR; 541 return GNUNET_SYSERR;
497 } 542 }
498 if (0 == port) 543 next = res;
544 i = 0;
545 while (NULL != (pos = next))
499 { 546 {
500 saddrs = GNUNET_new_array(2, struct sockaddr *); 547 next = pos->ai_next;
501 saddrlens = GNUNET_new_array(2, socklen_t); 548 if ((disablev6) && (pos->ai_family == AF_INET6))
502 add_unixpath(saddrs, saddrlens, unixpath, abstract); 549 continue;
503 GNUNET_free_non_null(unixpath); 550 i++;
504 GNUNET_free_non_null(hostname);
505 *addrs = saddrs;
506 *addr_lens = saddrlens;
507 return 1;
508 } 551 }
509 552 if (0 == i)
510 if (NULL != hostname)
511 { 553 {
512 LOG(GNUNET_ERROR_TYPE_DEBUG, 554 LOG (GNUNET_ERROR_TYPE_ERROR,
513 "Resolving `%s' since that is where `%s' will bind to.\n", 555 _ ("Failed to find %saddress for `%s'.\n"),
514 hostname, 556 disablev6 ? "IPv4 " : "",
515 service_name); 557 hostname);
516 memset(&hints, 0, sizeof(struct addrinfo)); 558 freeaddrinfo (res);
517 if (disablev6) 559 GNUNET_free (hostname);
518 hints.ai_family = AF_INET; 560 GNUNET_free_non_null (unixpath);
519 hints.ai_protocol = IPPROTO_TCP; 561 return GNUNET_SYSERR;
520 if ((0 != (ret = getaddrinfo(hostname, NULL, &hints, &res))) || 562 }
521 (NULL == res)) 563 resi = i;
522 { 564 if (NULL != unixpath)
523 LOG(GNUNET_ERROR_TYPE_ERROR, 565 resi++;
524 _("Failed to resolve `%s': %s\n"), 566 saddrs = GNUNET_new_array (resi + 1, struct sockaddr *);
525 hostname, 567 saddrlens = GNUNET_new_array (resi + 1, socklen_t);
526 gai_strerror(ret)); 568 i = 0;
527 GNUNET_free(hostname); 569 if (NULL != unixpath)
528 GNUNET_free_non_null(unixpath); 570 {
529 return GNUNET_SYSERR; 571 add_unixpath (saddrs, saddrlens, unixpath, abstract);
530 } 572 i++;
531 next = res; 573 }
532 i = 0; 574 next = res;
533 while (NULL != (pos = next)) 575 while (NULL != (pos = next))
534 { 576 {
535 next = pos->ai_next; 577 next = pos->ai_next;
536 if ((disablev6) && (pos->ai_family == AF_INET6)) 578 if ((disablev6) && (AF_INET6 == pos->ai_family))
537 continue; 579 continue;
538 i++; 580 if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol))
539 } 581 continue; /* not TCP */
540 if (0 == i) 582 if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype))
541 { 583 continue; /* huh? */
542 LOG(GNUNET_ERROR_TYPE_ERROR, 584 LOG (GNUNET_ERROR_TYPE_DEBUG,
543 _("Failed to find %saddress for `%s'.\n"), 585 "Service `%s' will bind to `%s'\n",
544 disablev6 ? "IPv4 " : "", 586 service_name,
545 hostname); 587 GNUNET_a2s (pos->ai_addr, pos->ai_addrlen));
546 freeaddrinfo(res); 588 if (AF_INET == pos->ai_family)
547 GNUNET_free(hostname); 589 {
548 GNUNET_free_non_null(unixpath); 590 GNUNET_assert (sizeof(struct sockaddr_in) == pos->ai_addrlen);
549 return GNUNET_SYSERR; 591 saddrlens[i] = pos->ai_addrlen;
550 } 592 saddrs[i] = GNUNET_malloc (saddrlens[i]);
551 resi = i; 593 GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
594 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
595 }
596 else
597 {
598 GNUNET_assert (AF_INET6 == pos->ai_family);
599 GNUNET_assert (sizeof(struct sockaddr_in6) == pos->ai_addrlen);
600 saddrlens[i] = pos->ai_addrlen;
601 saddrs[i] = GNUNET_malloc (saddrlens[i]);
602 GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
603 ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
604 }
605 i++;
606 }
607 GNUNET_free (hostname);
608 freeaddrinfo (res);
609 resi = i;
610 }
611 else
612 {
613 /* will bind against everything, just set port */
614 if (disablev6)
615 {
616 /* V4-only */
617 resi = 1;
552 if (NULL != unixpath) 618 if (NULL != unixpath)
553 resi++; 619 resi++;
554 saddrs = GNUNET_new_array(resi + 1, struct sockaddr *);
555 saddrlens = GNUNET_new_array(resi + 1, socklen_t);
556 i = 0; 620 i = 0;
621 saddrs = GNUNET_new_array (resi + 1, struct sockaddr *);
622 saddrlens = GNUNET_new_array (resi + 1, socklen_t);
557 if (NULL != unixpath) 623 if (NULL != unixpath)
558 { 624 {
559 add_unixpath(saddrs, saddrlens, unixpath, abstract); 625 add_unixpath (saddrs, saddrlens, unixpath, abstract);
560 i++; 626 i++;
561 } 627 }
562 next = res; 628 saddrlens[i] = sizeof(struct sockaddr_in);
563 while (NULL != (pos = next)) 629 saddrs[i] = GNUNET_malloc (saddrlens[i]);
564 {
565 next = pos->ai_next;
566 if ((disablev6) && (AF_INET6 == pos->ai_family))
567 continue;
568 if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol))
569 continue; /* not TCP */
570 if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype))
571 continue; /* huh? */
572 LOG(GNUNET_ERROR_TYPE_DEBUG,
573 "Service `%s' will bind to `%s'\n",
574 service_name,
575 GNUNET_a2s(pos->ai_addr, pos->ai_addrlen));
576 if (AF_INET == pos->ai_family)
577 {
578 GNUNET_assert(sizeof(struct sockaddr_in) == pos->ai_addrlen);
579 saddrlens[i] = pos->ai_addrlen;
580 saddrs[i] = GNUNET_malloc(saddrlens[i]);
581 GNUNET_memcpy(saddrs[i], pos->ai_addr, saddrlens[i]);
582 ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port);
583 }
584 else
585 {
586 GNUNET_assert(AF_INET6 == pos->ai_family);
587 GNUNET_assert(sizeof(struct sockaddr_in6) == pos->ai_addrlen);
588 saddrlens[i] = pos->ai_addrlen;
589 saddrs[i] = GNUNET_malloc(saddrlens[i]);
590 GNUNET_memcpy(saddrs[i], pos->ai_addr, saddrlens[i]);
591 ((struct sockaddr_in6 *)saddrs[i])->sin6_port = htons(port);
592 }
593 i++;
594 }
595 GNUNET_free(hostname);
596 freeaddrinfo(res);
597 resi = i;
598 }
599 else
600 {
601 /* will bind against everything, just set port */
602 if (disablev6)
603 {
604 /* V4-only */
605 resi = 1;
606 if (NULL != unixpath)
607 resi++;
608 i = 0;
609 saddrs = GNUNET_new_array(resi + 1, struct sockaddr *);
610 saddrlens = GNUNET_new_array(resi + 1, socklen_t);
611 if (NULL != unixpath)
612 {
613 add_unixpath(saddrs, saddrlens, unixpath, abstract);
614 i++;
615 }
616 saddrlens[i] = sizeof(struct sockaddr_in);
617 saddrs[i] = GNUNET_malloc(saddrlens[i]);
618#if HAVE_SOCKADDR_IN_SIN_LEN 630#if HAVE_SOCKADDR_IN_SIN_LEN
619 ((struct sockaddr_in *)saddrs[i])->sin_len = saddrlens[i]; 631 ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i];
620#endif 632#endif
621 ((struct sockaddr_in *)saddrs[i])->sin_family = AF_INET; 633 ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
622 ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port); 634 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
623 } 635 }
624 else 636 else
625 { 637 {
626 /* dual stack */ 638 /* dual stack */
627 resi = 2; 639 resi = 2;
628 if (NULL != unixpath) 640 if (NULL != unixpath)
629 resi++; 641 resi++;
630 saddrs = GNUNET_new_array(resi + 1, struct sockaddr *); 642 saddrs = GNUNET_new_array (resi + 1, struct sockaddr *);
631 saddrlens = GNUNET_new_array(resi + 1, socklen_t); 643 saddrlens = GNUNET_new_array (resi + 1, socklen_t);
632 i = 0; 644 i = 0;
633 if (NULL != unixpath) 645 if (NULL != unixpath)
634 { 646 {
635 add_unixpath(saddrs, saddrlens, unixpath, abstract); 647 add_unixpath (saddrs, saddrlens, unixpath, abstract);
636 i++; 648 i++;
637 } 649 }
638 saddrlens[i] = sizeof(struct sockaddr_in6); 650 saddrlens[i] = sizeof(struct sockaddr_in6);
639 saddrs[i] = GNUNET_malloc(saddrlens[i]); 651 saddrs[i] = GNUNET_malloc (saddrlens[i]);
640#if HAVE_SOCKADDR_IN_SIN_LEN 652#if HAVE_SOCKADDR_IN_SIN_LEN
641 ((struct sockaddr_in6 *)saddrs[i])->sin6_len = saddrlens[0]; 653 ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0];
642#endif 654#endif
643 ((struct sockaddr_in6 *)saddrs[i])->sin6_family = AF_INET6; 655 ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6;
644 ((struct sockaddr_in6 *)saddrs[i])->sin6_port = htons(port); 656 ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
645 i++; 657 i++;
646 saddrlens[i] = sizeof(struct sockaddr_in); 658 saddrlens[i] = sizeof(struct sockaddr_in);
647 saddrs[i] = GNUNET_malloc(saddrlens[i]); 659 saddrs[i] = GNUNET_malloc (saddrlens[i]);
648#if HAVE_SOCKADDR_IN_SIN_LEN 660#if HAVE_SOCKADDR_IN_SIN_LEN
649 ((struct sockaddr_in *)saddrs[i])->sin_len = saddrlens[1]; 661 ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1];
650#endif 662#endif
651 ((struct sockaddr_in *)saddrs[i])->sin_family = AF_INET; 663 ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
652 ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port); 664 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
653 }
654 } 665 }
655 GNUNET_free_non_null(unixpath); 666 }
667 GNUNET_free_non_null (unixpath);
656 *addrs = saddrs; 668 *addrs = saddrs;
657 *addr_lens = saddrlens; 669 *addr_lens = saddrlens;
658 return resi; 670 return resi;
@@ -670,19 +682,19 @@ get_server_addresses(const char *service_name,
670 * @return NULL if it was not found 682 * @return NULL if it was not found
671 */ 683 */
672static void 684static void
673signal_result(struct GNUNET_SERVICE_Client *client, 685signal_result (struct GNUNET_SERVICE_Client *client,
674 const char *name, 686 const char *name,
675 uint64_t request_id, 687 uint64_t request_id,
676 enum GNUNET_ARM_Result result) 688 enum GNUNET_ARM_Result result)
677{ 689{
678 struct GNUNET_MQ_Envelope *env; 690 struct GNUNET_MQ_Envelope *env;
679 struct GNUNET_ARM_ResultMessage *msg; 691 struct GNUNET_ARM_ResultMessage *msg;
680 692
681 (void)name; 693 (void) name;
682 env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_ARM_RESULT); 694 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_ARM_RESULT);
683 msg->result = htonl(result); 695 msg->result = htonl (result);
684 msg->arm_msg.request_id = GNUNET_htonll(request_id); 696 msg->arm_msg.request_id = GNUNET_htonll (request_id);
685 GNUNET_MQ_send(GNUNET_SERVICE_client_get_mq(client), env); 697 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env);
686} 698}
687 699
688 700
@@ -695,34 +707,34 @@ signal_result(struct GNUNET_SERVICE_Client *client,
695 * otherwise, send to all clients in the notifier 707 * otherwise, send to all clients in the notifier
696 */ 708 */
697static void 709static void
698broadcast_status(const char *name, 710broadcast_status (const char *name,
699 enum GNUNET_ARM_ServiceStatus status, 711 enum GNUNET_ARM_ServiceMonitorStatus status,
700 struct GNUNET_SERVICE_Client *unicast) 712 struct GNUNET_SERVICE_Client *unicast)
701{ 713{
702 struct GNUNET_MQ_Envelope *env; 714 struct GNUNET_MQ_Envelope *env;
703 struct GNUNET_ARM_StatusMessage *msg; 715 struct GNUNET_ARM_StatusMessage *msg;
704 size_t namelen; 716 size_t namelen;
705 717
706 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 718 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
707 "Sending status %u of service `%s' to client\n", 719 "Sending status %u of service `%s' to client\n",
708 (unsigned int)status, 720 (unsigned int) status,
709 name); 721 name);
710 namelen = strlen(name) + 1; 722 namelen = strlen (name) + 1;
711 env = GNUNET_MQ_msg_extra(msg, namelen, GNUNET_MESSAGE_TYPE_ARM_STATUS); 723 env = GNUNET_MQ_msg_extra (msg, namelen, GNUNET_MESSAGE_TYPE_ARM_STATUS);
712 msg->status = htonl((uint32_t)(status)); 724 msg->status = htonl ((uint32_t) (status));
713 GNUNET_memcpy((char *)&msg[1], name, namelen); 725 GNUNET_memcpy ((char *) &msg[1], name, namelen);
714 if (NULL == unicast) 726 if (NULL == unicast)
715 { 727 {
716 if (NULL != notifier) 728 if (NULL != notifier)
717 GNUNET_notification_context_broadcast(notifier, 729 GNUNET_notification_context_broadcast (notifier,
718 &msg->header, 730 &msg->header,
719 GNUNET_YES); 731 GNUNET_YES);
720 GNUNET_MQ_discard(env); 732 GNUNET_MQ_discard (env);
721 } 733 }
722 else 734 else
723 { 735 {
724 GNUNET_MQ_send(GNUNET_SERVICE_client_get_mq(unicast), env); 736 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (unicast), env);
725 } 737 }
726} 738}
727 739
728 740
@@ -735,9 +747,9 @@ broadcast_status(const char *name,
735 * being started. 0 if starting was not requested. 747 * being started. 0 if starting was not requested.
736 */ 748 */
737static void 749static void
738start_process(struct ServiceList *sl, 750start_process (struct ServiceList *sl,
739 struct GNUNET_SERVICE_Client *client, 751 struct GNUNET_SERVICE_Client *client,
740 uint64_t request_id) 752 uint64_t request_id)
741{ 753{
742 char *loprefix; 754 char *loprefix;
743 char *options; 755 char *options;
@@ -753,191 +765,192 @@ start_process(struct ServiceList *sl,
753 lsocks = NULL; 765 lsocks = NULL;
754 ls = 0; 766 ls = 0;
755 for (sli = sl->listen_head; NULL != sli; sli = sli->next) 767 for (sli = sl->listen_head; NULL != sli; sli = sli->next)
768 {
769 GNUNET_array_append (lsocks,
770 ls,
771 GNUNET_NETWORK_get_fd (sli->listen_socket));
772 if (NULL != sli->accept_task)
756 { 773 {
757 GNUNET_array_append(lsocks, 774 GNUNET_SCHEDULER_cancel (sli->accept_task);
758 ls, 775 sli->accept_task = NULL;
759 GNUNET_NETWORK_get_fd(sli->listen_socket));
760 if (NULL != sli->accept_task)
761 {
762 GNUNET_SCHEDULER_cancel(sli->accept_task);
763 sli->accept_task = NULL;
764 }
765 } 776 }
777 }
766 778
767 GNUNET_array_append(lsocks, ls, -1); 779 GNUNET_array_append (lsocks, ls, -1);
768 780
769 /* obtain configuration */ 781 /* obtain configuration */
770 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, 782 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg,
771 sl->name, 783 sl->name,
772 "PREFIX", 784 "PREFIX",
773 &loprefix)) 785 &loprefix))
774 loprefix = GNUNET_strdup(prefix_command); 786 loprefix = GNUNET_strdup (prefix_command);
775 else 787 else
776 loprefix = GNUNET_CONFIGURATION_expand_dollar(cfg, loprefix); 788 loprefix = GNUNET_CONFIGURATION_expand_dollar (cfg, loprefix);
777 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, 789 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg,
778 sl->name, 790 sl->name,
779 "OPTIONS", 791 "OPTIONS",
780 &options)) 792 &options))
781 options = NULL; 793 options = NULL;
782 else 794 else
783 options = GNUNET_CONFIGURATION_expand_dollar(cfg, options); 795 options = GNUNET_CONFIGURATION_expand_dollar (cfg, options);
784 { 796 {
785 char *new_options; 797 char *new_options;
786 char *optpos; 798 char *optpos;
787 char *fin_options; 799 char *fin_options;
788 800
789 fin_options = GNUNET_strdup(final_option); 801 fin_options = GNUNET_strdup (final_option);
790 /* replace '{}' with service name */ 802 /* replace '{}' with service name */
791 while (NULL != (optpos = strstr(fin_options, "{}"))) 803 while (NULL != (optpos = strstr (fin_options, "{}")))
792 { 804 {
793 /* terminate string at opening parenthesis */ 805 /* terminate string at opening parenthesis */
794 *optpos = 0; 806 *optpos = 0;
795 GNUNET_asprintf(&new_options, 807 GNUNET_asprintf (&new_options,
796 "%s%s%s", 808 "%s%s%s",
797 fin_options, 809 fin_options,
798 sl->name, 810 sl->name,
799 optpos + 2); 811 optpos + 2);
800 GNUNET_free(fin_options); 812 GNUNET_free (fin_options);
801 fin_options = new_options; 813 fin_options = new_options;
802 } 814 }
803 if (NULL != options) 815 if (NULL != options)
804 { 816 {
805 /* combine "fin_options" with "options" */ 817 /* combine "fin_options" with "options" */
806 optpos = options; 818 optpos = options;
807 GNUNET_asprintf(&options, "%s %s", fin_options, optpos); 819 GNUNET_asprintf (&options, "%s %s", fin_options, optpos);
808 GNUNET_free(fin_options); 820 GNUNET_free (fin_options);
809 GNUNET_free(optpos); 821 GNUNET_free (optpos);
810 } 822 }
811 else 823 else
812 { 824 {
813 /* only have "fin_options", use that */ 825 /* only have "fin_options", use that */
814 options = fin_options; 826 options = fin_options;
815 } 827 }
816 } 828 }
817 options = GNUNET_CONFIGURATION_expand_dollar(cfg, options); 829 options = GNUNET_CONFIGURATION_expand_dollar (cfg, options);
818 use_debug = GNUNET_CONFIGURATION_get_value_yesno(cfg, sl->name, "DEBUG"); 830 use_debug = GNUNET_CONFIGURATION_get_value_yesno (cfg, sl->name, "DEBUG");
819 { 831 {
820 const char *service_type = NULL; 832 const char *service_type = NULL;
821 const char *choices[] = { "GNUNET", "SIMPLE", NULL }; 833 const char *choices[] = { "GNUNET", "SIMPLE", NULL };
822 834
823 is_simple_service = GNUNET_NO; 835 is_simple_service = GNUNET_NO;
824 if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_choice(cfg, 836 if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_choice (cfg,
825 sl->name, 837 sl->name,
826 "TYPE", 838 "TYPE",
827 choices, 839 choices,
828 &service_type)) && 840 &service_type)) &&
829 (0 == strcasecmp(service_type, "SIMPLE"))) 841 (0 == strcasecmp (service_type, "SIMPLE")))
830 is_simple_service = GNUNET_YES; 842 is_simple_service = GNUNET_YES;
831 } 843 }
832 844
833 GNUNET_assert(NULL == sl->proc); 845 GNUNET_assert (NULL == sl->proc);
834 if (GNUNET_YES == is_simple_service) 846 if (GNUNET_YES == is_simple_service)
835 { 847 {
836 /* A simple service will receive no GNUnet specific 848 /* A simple service will receive no GNUnet specific
837 command line options. */ 849 command line options. */
838 binary = GNUNET_strdup(sl->binary); 850 binary = GNUNET_strdup (sl->binary);
839 binary = GNUNET_CONFIGURATION_expand_dollar(cfg, binary); 851 binary = GNUNET_CONFIGURATION_expand_dollar (cfg, binary);
840 GNUNET_asprintf(&quotedbinary, "\"%s\"", sl->binary); 852 GNUNET_asprintf (&quotedbinary, "\"%s\"", sl->binary);
841 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 853 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
842 "Starting simple service `%s' using binary `%s'\n", 854 "Starting simple service `%s' using binary `%s'\n",
843 sl->name, 855 sl->name,
844 sl->binary); 856 sl->binary);
845 /* FIXME: dollar expansion should only be done outside 857 /* FIXME: dollar expansion should only be done outside
846 * of ''-quoted strings, escaping should be considered. */ 858 * of ''-quoted strings, escaping should be considered. */
847 if (NULL != options) 859 if (NULL != options)
848 options = GNUNET_CONFIGURATION_expand_dollar(cfg, options); 860 options = GNUNET_CONFIGURATION_expand_dollar (cfg, options);
849 sl->proc = GNUNET_OS_start_process_s(sl->pipe_control, 861 sl->proc = GNUNET_OS_start_process_s (sl->pipe_control,
850 GNUNET_OS_INHERIT_STD_OUT_AND_ERR, 862 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
851 lsocks, 863 lsocks,
852 loprefix, 864 loprefix,
853 quotedbinary, 865 quotedbinary,
854 options, 866 options,
855 NULL); 867 NULL);
856 } 868 }
857 else 869 else
870 {
871 /* actually start process */
872 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
873 "Starting service `%s' using binary `%s' and configuration `%s'\n",
874 sl->name,
875 sl->binary,
876 sl->config);
877 binary = GNUNET_OS_get_libexec_binary_path (sl->binary);
878 GNUNET_asprintf (&quotedbinary, "\"%s\"", binary);
879
880 if (GNUNET_YES == use_debug)
858 { 881 {
859 /* actually start process */ 882 if (NULL == sl->config)
860 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 883 sl->proc = GNUNET_OS_start_process_s (sl->pipe_control,
861 "Starting service `%s' using binary `%s' and configuration `%s'\n", 884 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
862 sl->name, 885 lsocks,
863 sl->binary, 886 loprefix,
864 sl->config); 887 quotedbinary,
865 binary = GNUNET_OS_get_libexec_binary_path(sl->binary); 888 "-L",
866 GNUNET_asprintf(&quotedbinary, "\"%s\"", binary); 889 "DEBUG",
867 890 options,
868 if (GNUNET_YES == use_debug) 891 NULL);
869 {
870 if (NULL == sl->config)
871 sl->proc = GNUNET_OS_start_process_s(sl->pipe_control,
872 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
873 lsocks,
874 loprefix,
875 quotedbinary,
876 "-L",
877 "DEBUG",
878 options,
879 NULL);
880 else
881 sl->proc = GNUNET_OS_start_process_s(sl->pipe_control,
882 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
883 lsocks,
884 loprefix,
885 quotedbinary,
886 "-c",
887 sl->config,
888 "-L",
889 "DEBUG",
890 options,
891 NULL);
892 }
893 else 892 else
894 { 893 sl->proc = GNUNET_OS_start_process_s (sl->pipe_control,
895 if (NULL == sl->config) 894 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
896 sl->proc = GNUNET_OS_start_process_s(sl->pipe_control, 895 lsocks,
897 GNUNET_OS_INHERIT_STD_OUT_AND_ERR, 896 loprefix,
898 lsocks, 897 quotedbinary,
899 loprefix, 898 "-c",
900 quotedbinary, 899 sl->config,
901 options, 900 "-L",
902 NULL); 901 "DEBUG",
903 else 902 options,
904 sl->proc = GNUNET_OS_start_process_s(sl->pipe_control, 903 NULL);
905 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
906 lsocks,
907 loprefix,
908 quotedbinary,
909 "-c",
910 sl->config,
911 options,
912 NULL);
913 }
914 } 904 }
915 GNUNET_free(binary); 905 else
916 GNUNET_free(quotedbinary);
917 if (NULL == sl->proc)
918 { 906 {
919 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 907 if (NULL == sl->config)
920 _("Failed to start service `%s'\n"), 908 sl->proc = GNUNET_OS_start_process_s (sl->pipe_control,
921 sl->name); 909 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
922 if (client) 910 lsocks,
923 signal_result(client, 911 loprefix,
924 sl->name, 912 quotedbinary,
925 request_id, 913 options,
926 GNUNET_ARM_RESULT_START_FAILED); 914 NULL);
915 else
916 sl->proc = GNUNET_OS_start_process_s (sl->pipe_control,
917 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
918 lsocks,
919 loprefix,
920 quotedbinary,
921 "-c",
922 sl->config,
923 options,
924 NULL);
927 } 925 }
926 }
927 GNUNET_free (binary);
928 GNUNET_free (quotedbinary);
929 sl->last_started_at = GNUNET_TIME_absolute_get ();
930 if (NULL == sl->proc)
931 {
932 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
933 _ ("Failed to start service `%s'\n"),
934 sl->name);
935 if (client)
936 signal_result (client,
937 sl->name,
938 request_id,
939 GNUNET_ARM_RESULT_START_FAILED);
940 }
928 else 941 else
929 { 942 {
930 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 943 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
931 _("Starting service `%s'\n"), 944 _ ("Starting service `%s'\n"),
932 sl->name); 945 sl->name);
933 broadcast_status(sl->name, GNUNET_ARM_SERVICE_STARTING, NULL); 946 broadcast_status (sl->name, GNUNET_ARM_SERVICE_STARTING, NULL);
934 if (client) 947 if (client)
935 signal_result(client, sl->name, request_id, GNUNET_ARM_RESULT_STARTING); 948 signal_result (client, sl->name, request_id, GNUNET_ARM_RESULT_STARTING);
936 } 949 }
937 /* clean up */ 950 /* clean up */
938 GNUNET_free(loprefix); 951 GNUNET_free (loprefix);
939 GNUNET_free(options); 952 GNUNET_free (options);
940 GNUNET_array_grow(lsocks, ls, 0); 953 GNUNET_array_grow (lsocks, ls, 0);
941} 954}
942 955
943 956
@@ -949,17 +962,17 @@ start_process(struct ServiceList *sl,
949 * @return NULL if it was not found 962 * @return NULL if it was not found
950 */ 963 */
951static struct ServiceList * 964static struct ServiceList *
952find_service(const char *name) 965find_service (const char *name)
953{ 966{
954 struct ServiceList *sl; 967 struct ServiceList *sl;
955 968
956 sl = running_head; 969 sl = running_head;
957 while (sl != NULL) 970 while (sl != NULL)
958 { 971 {
959 if (0 == strcasecmp(sl->name, name)) 972 if (0 == strcasecmp (sl->name, name))
960 return sl; 973 return sl;
961 sl = sl->next; 974 sl = sl->next;
962 } 975 }
963 return NULL; 976 return NULL;
964} 977}
965 978
@@ -971,14 +984,14 @@ find_service(const char *name)
971 * @param cls callback data, `struct ServiceListeningInfo` describing a listen socket 984 * @param cls callback data, `struct ServiceListeningInfo` describing a listen socket
972 */ 985 */
973static void 986static void
974accept_connection(void *cls) 987accept_connection (void *cls)
975{ 988{
976 struct ServiceListeningInfo *sli = cls; 989 struct ServiceListeningInfo *sli = cls;
977 struct ServiceList *sl = sli->sl; 990 struct ServiceList *sl = sli->sl;
978 991
979 sli->accept_task = NULL; 992 sli->accept_task = NULL;
980 GNUNET_assert(GNUNET_NO == in_shutdown); 993 GNUNET_assert (GNUNET_NO == in_shutdown);
981 start_process(sl, NULL, 0); 994 start_process (sl, NULL, 0);
982} 995}
983 996
984 997
@@ -991,9 +1004,9 @@ accept_connection(void *cls)
991 * @param sl service entry for the service in question 1004 * @param sl service entry for the service in question
992 */ 1005 */
993static void 1006static void
994create_listen_socket(struct sockaddr *sa, 1007create_listen_socket (struct sockaddr *sa,
995 socklen_t addr_len, 1008 socklen_t addr_len,
996 struct ServiceList *sl) 1009 struct ServiceList *sl)
997{ 1010{
998 static int on = 1; 1011 static int on = 1;
999 struct GNUNET_NETWORK_Handle *sock; 1012 struct GNUNET_NETWORK_Handle *sock;
@@ -1003,107 +1016,107 @@ create_listen_socket(struct sockaddr *sa,
1003 int match_gid; 1016 int match_gid;
1004 1017
1005 switch (sa->sa_family) 1018 switch (sa->sa_family)
1006 { 1019 {
1007 case AF_INET: 1020 case AF_INET:
1008 sock = GNUNET_NETWORK_socket_create(PF_INET, SOCK_STREAM, 0); 1021 sock = GNUNET_NETWORK_socket_create (PF_INET, SOCK_STREAM, 0);
1009 break; 1022 break;
1010 1023
1011 case AF_INET6: 1024 case AF_INET6:
1012 sock = GNUNET_NETWORK_socket_create(PF_INET6, SOCK_STREAM, 0); 1025 sock = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0);
1013 break; 1026 break;
1014 1027
1015 case AF_UNIX: 1028 case AF_UNIX:
1016 if (0 == strcmp(GNUNET_a2s(sa, addr_len), 1029 if (0 == strcmp (GNUNET_a2s (sa, addr_len),
1017 "@")) /* Do not bind to blank UNIX path! */ 1030 "@")) /* Do not bind to blank UNIX path! */
1018 return;
1019 sock = GNUNET_NETWORK_socket_create(PF_UNIX, SOCK_STREAM, 0);
1020 break;
1021
1022 default:
1023 GNUNET_break(0);
1024 sock = NULL;
1025 errno = EAFNOSUPPORT;
1026 break;
1027 }
1028 if (NULL == sock)
1029 {
1030 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
1031 _("Unable to create socket for service `%s': %s\n"),
1032 sl->name,
1033 strerror(errno));
1034 GNUNET_free(sa);
1035 return; 1031 return;
1036 } 1032 sock = GNUNET_NETWORK_socket_create (PF_UNIX, SOCK_STREAM, 0);
1037 if (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt(sock, 1033 break;
1038 SOL_SOCKET, 1034
1039 SO_REUSEADDR, 1035 default:
1040 &on, 1036 GNUNET_break (0);
1041 sizeof(on))) 1037 sock = NULL;
1042 GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 1038 errno = EAFNOSUPPORT;
1043 "setsockopt"); 1039 break;
1040 }
1041 if (NULL == sock)
1042 {
1043 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1044 _ ("Unable to create socket for service `%s': %s\n"),
1045 sl->name,
1046 strerror (errno));
1047 GNUNET_free (sa);
1048 return;
1049 }
1050 if (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt (sock,
1051 SOL_SOCKET,
1052 SO_REUSEADDR,
1053 &on,
1054 sizeof(on)))
1055 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1056 "setsockopt");
1044#ifdef IPV6_V6ONLY 1057#ifdef IPV6_V6ONLY
1045 if ((sa->sa_family == AF_INET6) && 1058 if ((sa->sa_family == AF_INET6) &&
1046 (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt(sock, 1059 (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt (sock,
1047 IPPROTO_IPV6, 1060 IPPROTO_IPV6,
1048 IPV6_V6ONLY, 1061 IPV6_V6ONLY,
1049 &on, 1062 &on,
1050 sizeof(on)))) 1063 sizeof(on))))
1051 GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 1064 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1052 "setsockopt"); 1065 "setsockopt");
1053#endif 1066#endif
1054 if (AF_UNIX == sa->sa_family) 1067 if (AF_UNIX == sa->sa_family)
1055 GNUNET_NETWORK_unix_precheck((struct sockaddr_un *)sa); 1068 GNUNET_NETWORK_unix_precheck ((struct sockaddr_un *) sa);
1056 if (GNUNET_OK != 1069 if (GNUNET_OK !=
1057 GNUNET_NETWORK_socket_bind(sock, (const struct sockaddr *)sa, addr_len)) 1070 GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) sa, addr_len))
1058 { 1071 {
1059 GNUNET_log( 1072 GNUNET_log (
1060 GNUNET_ERROR_TYPE_WARNING, 1073 GNUNET_ERROR_TYPE_WARNING,
1061 _( 1074 _ (
1062 "Unable to bind listening socket for service `%s' to address `%s': %s\n"), 1075 "Unable to bind listening socket for service `%s' to address `%s': %s\n"),
1063 sl->name, 1076 sl->name,
1064 GNUNET_a2s(sa, addr_len), 1077 GNUNET_a2s (sa, addr_len),
1065 strerror(errno)); 1078 strerror (errno));
1066 GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(sock)); 1079 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
1067 GNUNET_free(sa); 1080 GNUNET_free (sa);
1068 return; 1081 return;
1069 } 1082 }
1070 if ((AF_UNIX == sa->sa_family) 1083 if ((AF_UNIX == sa->sa_family)
1071#ifdef LINUX 1084#ifdef LINUX
1072 /* Permission settings are not required when abstract sockets are used */ 1085 /* Permission settings are not required when abstract sockets are used */
1073 && ('\0' != ((const struct sockaddr_un *)sa)->sun_path[0]) 1086 && ('\0' != ((const struct sockaddr_un *) sa)->sun_path[0])
1074#endif 1087#endif
1075 ) 1088 )
1076 { 1089 {
1077 match_uid = 1090 match_uid =
1078 GNUNET_CONFIGURATION_get_value_yesno(cfg, sl->name, "UNIX_MATCH_UID"); 1091 GNUNET_CONFIGURATION_get_value_yesno (cfg, sl->name, "UNIX_MATCH_UID");
1079 match_gid = 1092 match_gid =
1080 GNUNET_CONFIGURATION_get_value_yesno(cfg, sl->name, "UNIX_MATCH_GID"); 1093 GNUNET_CONFIGURATION_get_value_yesno (cfg, sl->name, "UNIX_MATCH_GID");
1081 GNUNET_DISK_fix_permissions(((const struct sockaddr_un *)sa)->sun_path, 1094 GNUNET_DISK_fix_permissions (((const struct sockaddr_un *) sa)->sun_path,
1082 match_uid, 1095 match_uid,
1083 match_gid); 1096 match_gid);
1084 } 1097 }
1085 if (GNUNET_OK != GNUNET_NETWORK_socket_listen(sock, 5)) 1098 if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5))
1086 { 1099 {
1087 GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, "listen"); 1100 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "listen");
1088 GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(sock)); 1101 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
1089 GNUNET_free(sa); 1102 GNUNET_free (sa);
1090 return; 1103 return;
1091 } 1104 }
1092 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 1105 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1093 _("ARM now monitors connections to service `%s' at `%s'\n"), 1106 _ ("ARM now monitors connections to service `%s' at `%s'\n"),
1094 sl->name, 1107 sl->name,
1095 GNUNET_a2s(sa, addr_len)); 1108 GNUNET_a2s (sa, addr_len));
1096 sli = GNUNET_new(struct ServiceListeningInfo); 1109 sli = GNUNET_new (struct ServiceListeningInfo);
1097 sli->service_addr = sa; 1110 sli->service_addr = sa;
1098 sli->service_addr_len = addr_len; 1111 sli->service_addr_len = addr_len;
1099 sli->listen_socket = sock; 1112 sli->listen_socket = sock;
1100 sli->sl = sl; 1113 sli->sl = sl;
1101 sli->accept_task = 1114 sli->accept_task =
1102 GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, 1115 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
1103 sock, 1116 sock,
1104 &accept_connection, 1117 &accept_connection,
1105 sli); 1118 sli);
1106 GNUNET_CONTAINER_DLL_insert(sl->listen_head, sl->listen_tail, sli); 1119 GNUNET_CONTAINER_DLL_insert (sl->listen_head, sl->listen_tail, sli);
1107} 1120}
1108 1121
1109 1122
@@ -1114,15 +1127,15 @@ create_listen_socket(struct sockaddr *sa,
1114 * @param sl entry to free 1127 * @param sl entry to free
1115 */ 1128 */
1116static void 1129static void
1117free_service(struct ServiceList *sl) 1130free_service (struct ServiceList *sl)
1118{ 1131{
1119 GNUNET_assert(GNUNET_YES == in_shutdown); 1132 GNUNET_assert (GNUNET_YES == in_shutdown);
1120 GNUNET_CONTAINER_DLL_remove(running_head, running_tail, sl); 1133 GNUNET_CONTAINER_DLL_remove (running_head, running_tail, sl);
1121 GNUNET_assert(NULL == sl->listen_head); 1134 GNUNET_assert (NULL == sl->listen_head);
1122 GNUNET_free_non_null(sl->config); 1135 GNUNET_free_non_null (sl->config);
1123 GNUNET_free_non_null(sl->binary); 1136 GNUNET_free_non_null (sl->binary);
1124 GNUNET_free(sl->name); 1137 GNUNET_free (sl->name);
1125 GNUNET_free(sl); 1138 GNUNET_free (sl);
1126} 1139}
1127 1140
1128 1141
@@ -1135,10 +1148,10 @@ free_service(struct ServiceList *sl)
1135 * #GNUNET_SYSERR to close it (signal serious error) 1148 * #GNUNET_SYSERR to close it (signal serious error)
1136 */ 1149 */
1137static int 1150static int
1138check_start(void *cls, const struct GNUNET_ARM_Message *amsg) 1151check_start (void *cls, const struct GNUNET_ARM_Message *amsg)
1139{ 1152{
1140 (void)cls; 1153 (void) cls;
1141 GNUNET_MQ_check_zero_termination(amsg); 1154 GNUNET_MQ_check_zero_termination (amsg);
1142 return GNUNET_OK; 1155 return GNUNET_OK;
1143} 1156}
1144 1157
@@ -1150,43 +1163,43 @@ check_start(void *cls, const struct GNUNET_ARM_Message *amsg)
1150 * @param amsg the actual message 1163 * @param amsg the actual message
1151 */ 1164 */
1152static void 1165static void
1153handle_start(void *cls, const struct GNUNET_ARM_Message *amsg) 1166handle_start (void *cls, const struct GNUNET_ARM_Message *amsg)
1154{ 1167{
1155 struct GNUNET_SERVICE_Client *client = cls; 1168 struct GNUNET_SERVICE_Client *client = cls;
1156 const char *servicename; 1169 const char *servicename;
1157 struct ServiceList *sl; 1170 struct ServiceList *sl;
1158 uint64_t request_id; 1171 uint64_t request_id;
1159 1172
1160 request_id = GNUNET_ntohll(amsg->request_id); 1173 request_id = GNUNET_ntohll (amsg->request_id);
1161 servicename = (const char *)&amsg[1]; 1174 servicename = (const char *) &amsg[1];
1162 GNUNET_SERVICE_client_continue(client); 1175 GNUNET_SERVICE_client_continue (client);
1163 if (GNUNET_YES == in_shutdown) 1176 if (GNUNET_YES == in_shutdown)
1164 { 1177 {
1165 signal_result(client, 1178 signal_result (client,
1166 servicename, 1179 servicename,
1167 request_id, 1180 request_id,
1168 GNUNET_ARM_RESULT_IN_SHUTDOWN); 1181 GNUNET_ARM_RESULT_IN_SHUTDOWN);
1169 return; 1182 return;
1170 } 1183 }
1171 sl = find_service(servicename); 1184 sl = find_service (servicename);
1172 if (NULL == sl) 1185 if (NULL == sl)
1173 { 1186 {
1174 signal_result(client, 1187 signal_result (client,
1175 servicename, 1188 servicename,
1176 request_id, 1189 request_id,
1177 GNUNET_ARM_RESULT_IS_NOT_KNOWN); 1190 GNUNET_ARM_RESULT_IS_NOT_KNOWN);
1178 return; 1191 return;
1179 } 1192 }
1180 sl->force_start = GNUNET_YES; 1193 sl->force_start = GNUNET_YES;
1181 if (NULL != sl->proc) 1194 if (NULL != sl->proc)
1182 { 1195 {
1183 signal_result(client, 1196 signal_result (client,
1184 servicename, 1197 servicename,
1185 request_id, 1198 request_id,
1186 GNUNET_ARM_RESULT_IS_STARTED_ALREADY); 1199 GNUNET_ARM_RESULT_IS_STARTED_ALREADY);
1187 return; 1200 return;
1188 } 1201 }
1189 start_process(sl, client, request_id); 1202 start_process (sl, client, request_id);
1190} 1203}
1191 1204
1192 1205
@@ -1196,11 +1209,11 @@ handle_start(void *cls, const struct GNUNET_ARM_Message *amsg)
1196 * @param cls closure (refers to service) 1209 * @param cls closure (refers to service)
1197 */ 1210 */
1198static void 1211static void
1199trigger_shutdown(void *cls) 1212trigger_shutdown (void *cls)
1200{ 1213{
1201 (void)cls; 1214 (void) cls;
1202 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Triggering shutdown\n"); 1215 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Triggering shutdown\n");
1203 GNUNET_SCHEDULER_shutdown(); 1216 GNUNET_SCHEDULER_shutdown ();
1204} 1217}
1205 1218
1206 1219
@@ -1213,10 +1226,10 @@ trigger_shutdown(void *cls)
1213 * #GNUNET_SYSERR to close it (signal serious error) 1226 * #GNUNET_SYSERR to close it (signal serious error)
1214 */ 1227 */
1215static int 1228static int
1216check_stop(void *cls, const struct GNUNET_ARM_Message *amsg) 1229check_stop (void *cls, const struct GNUNET_ARM_Message *amsg)
1217{ 1230{
1218 (void)cls; 1231 (void) cls;
1219 GNUNET_MQ_check_zero_termination(amsg); 1232 GNUNET_MQ_check_zero_termination (amsg);
1220 return GNUNET_OK; 1233 return GNUNET_OK;
1221} 1234}
1222 1235
@@ -1228,128 +1241,184 @@ check_stop(void *cls, const struct GNUNET_ARM_Message *amsg)
1228 * @param amsg the actual message 1241 * @param amsg the actual message
1229 */ 1242 */
1230static void 1243static void
1231handle_stop(void *cls, const struct GNUNET_ARM_Message *amsg) 1244handle_stop (void *cls, const struct GNUNET_ARM_Message *amsg)
1232{ 1245{
1233 struct GNUNET_SERVICE_Client *client = cls; 1246 struct GNUNET_SERVICE_Client *client = cls;
1234 struct ServiceList *sl; 1247 struct ServiceList *sl;
1235 const char *servicename; 1248 const char *servicename;
1236 uint64_t request_id; 1249 uint64_t request_id;
1237 1250
1238 request_id = GNUNET_ntohll(amsg->request_id); 1251 request_id = GNUNET_ntohll (amsg->request_id);
1239 servicename = (const char *)&amsg[1]; 1252 servicename = (const char *) &amsg[1];
1240 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 1253 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1241 _("Preparing to stop `%s'\n"), 1254 _ ("Preparing to stop `%s'\n"),
1242 servicename); 1255 servicename);
1243 GNUNET_SERVICE_client_continue(client); 1256 GNUNET_SERVICE_client_continue (client);
1244 if (0 == strcasecmp(servicename, "arm")) 1257 if (0 == strcasecmp (servicename, "arm"))
1245 { 1258 {
1246 broadcast_status(servicename, GNUNET_ARM_SERVICE_STOPPING, NULL); 1259 broadcast_status (servicename, GNUNET_ARM_SERVICE_STOPPING, NULL);
1247 signal_result(client, servicename, request_id, GNUNET_ARM_RESULT_STOPPING); 1260 signal_result (client, servicename, request_id, GNUNET_ARM_RESULT_STOPPING);
1248 GNUNET_SERVICE_client_persist(client); 1261 GNUNET_SERVICE_client_persist (client);
1249 GNUNET_SCHEDULER_add_now(&trigger_shutdown, NULL); 1262 GNUNET_SCHEDULER_add_now (&trigger_shutdown, NULL);
1250 return; 1263 return;
1251 } 1264 }
1252 sl = find_service(servicename); 1265 sl = find_service (servicename);
1253 if (NULL == sl) 1266 if (NULL == sl)
1254 { 1267 {
1255 signal_result(client, 1268 signal_result (client,
1256 servicename, 1269 servicename,
1257 request_id, 1270 request_id,
1258 GNUNET_ARM_RESULT_IS_NOT_KNOWN); 1271 GNUNET_ARM_RESULT_IS_NOT_KNOWN);
1259 return; 1272 return;
1260 } 1273 }
1261 sl->force_start = GNUNET_NO; 1274 sl->force_start = GNUNET_NO;
1262 if (GNUNET_YES == in_shutdown) 1275 if (GNUNET_YES == in_shutdown)
1263 { 1276 {
1264 /* shutdown in progress */ 1277 /* shutdown in progress */
1265 signal_result(client, 1278 signal_result (client,
1266 servicename, 1279 servicename,
1267 request_id, 1280 request_id,
1268 GNUNET_ARM_RESULT_IN_SHUTDOWN); 1281 GNUNET_ARM_RESULT_IN_SHUTDOWN);
1269 return; 1282 return;
1270 } 1283 }
1271 if (NULL != sl->killing_client) 1284 if (NULL != sl->killing_client)
1272 { 1285 {
1273 /* killing already in progress */ 1286 /* killing already in progress */
1274 signal_result(client, 1287 signal_result (client,
1275 servicename, 1288 servicename,
1276 request_id, 1289 request_id,
1277 GNUNET_ARM_RESULT_IS_STOPPING_ALREADY); 1290 GNUNET_ARM_RESULT_IS_STOPPING_ALREADY);
1278 return; 1291 return;
1279 } 1292 }
1280 if (NULL == sl->proc) 1293 if (NULL == sl->proc)
1281 { 1294 {
1282 /* process is down */ 1295 /* process is down */
1283 signal_result(client, 1296 signal_result (client,
1284 servicename, 1297 servicename,
1285 request_id, 1298 request_id,
1286 GNUNET_ARM_RESULT_IS_STOPPED_ALREADY); 1299 GNUNET_ARM_RESULT_IS_STOPPED_ALREADY);
1287 return; 1300 return;
1288 } 1301 }
1289 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1302 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1290 "Sending kill signal to service `%s', waiting for process to die.\n", 1303 "Sending kill signal to service `%s', waiting for process to die.\n",
1291 servicename); 1304 servicename);
1292 broadcast_status(servicename, GNUNET_ARM_SERVICE_STOPPING, NULL); 1305 broadcast_status (servicename, GNUNET_ARM_SERVICE_STOPPING, NULL);
1293 /* no signal_start - only when it's STOPPED */ 1306 /* no signal_start - only when it's STOPPED */
1294 sl->killed_at = GNUNET_TIME_absolute_get(); 1307 sl->killed_at = GNUNET_TIME_absolute_get ();
1295 if (0 != GNUNET_OS_process_kill(sl->proc, GNUNET_TERM_SIG)) 1308 if (0 != GNUNET_OS_process_kill (sl->proc, GNUNET_TERM_SIG))
1296 GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING, "kill"); 1309 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
1297 sl->killing_client = client; 1310 sl->killing_client = client;
1298 sl->killing_client_request_id = request_id; 1311 sl->killing_client_request_id = request_id;
1299} 1312}
1300 1313
1301 1314
1302/** 1315/**
1316 * Write a string to a string pool.
1317 *
1318 * @param pool_start pointer to the start of the string pool
1319 * @param pool_size size of the string pool
1320 * @param[in,out] pool_pos current position index in the string pool,
1321 * will be updated
1322 * @param str string to write to the string pool
1323 * @returns GNUNET_OK if the string fits into the pool,
1324 * GNUNET_SYSERR otherwise
1325 */
1326static int
1327pool_write (char *pool_start, size_t pool_size, size_t *pool_pos, char *str)
1328{
1329 size_t next_pos = (*pool_pos) + strlen (str) + 1;
1330
1331 if (next_pos > pool_size)
1332 return GNUNET_SYSERR;
1333 memcpy (pool_start + *pool_pos, str, strlen (str) + 1);
1334 *pool_pos = next_pos;
1335 return GNUNET_OK;
1336}
1337
1338/**
1303 * Handle LIST-message. 1339 * Handle LIST-message.
1304 * 1340 *
1305 * @param cls identification of the client 1341 * @param cls identification of the client
1306 * @param message the actual message 1342 * @param message the actual message
1307 */ 1343 */
1308static void 1344static void
1309handle_list(void *cls, const struct GNUNET_ARM_Message *request) 1345handle_list (void *cls, const struct GNUNET_ARM_Message *request)
1310{ 1346{
1311 struct GNUNET_SERVICE_Client *client = cls; 1347 struct GNUNET_SERVICE_Client *client = cls;
1312 struct GNUNET_MQ_Envelope *env; 1348 struct GNUNET_MQ_Envelope *env;
1313 struct GNUNET_ARM_ListResultMessage *msg; 1349 struct GNUNET_ARM_ListResultMessage *msg;
1314 size_t string_list_size; 1350 size_t extra_size;
1315 struct ServiceList *sl; 1351 struct ServiceList *sl;
1316 uint16_t count; 1352 uint16_t count;
1317 char *pos; 1353 size_t pool_size;
1354 size_t pool_pos;
1355 char *pool_start;
1356 struct GNUNET_ARM_ServiceInfoMessage *ssm;
1318 1357
1319 GNUNET_break(0 == ntohl(request->reserved)); 1358 GNUNET_break_op (0 == ntohl (request->reserved));
1320 count = 0; 1359 count = 0;
1321 string_list_size = 0; 1360 pool_size = 0;
1322 1361
1323 /* first count the running processes get their name's size */ 1362 /* Do one pass over the list to compute the number of services
1363 * and the string pool size */
1324 for (sl = running_head; NULL != sl; sl = sl->next) 1364 for (sl = running_head; NULL != sl; sl = sl->next)
1325 { 1365 {
1326 if (NULL != sl->proc) 1366 pool_size += strlen (sl->name) + 1;
1327 { 1367 pool_size += strlen (sl->binary) + 1;
1328 string_list_size += strlen(sl->name); 1368 count++;
1329 string_list_size += strlen(sl->binary); 1369 }
1330 string_list_size += 4;
1331 count++;
1332 }
1333 }
1334 1370
1335 env = GNUNET_MQ_msg_extra(msg, 1371 extra_size = pool_size + (count * sizeof (struct
1336 string_list_size, 1372 GNUNET_ARM_ServiceInfoMessage));
1337 GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT); 1373 env = GNUNET_MQ_msg_extra (msg,
1374 extra_size,
1375 GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT);
1338 msg->arm_msg.request_id = request->request_id; 1376 msg->arm_msg.request_id = request->request_id;
1339 msg->count = htons(count); 1377 msg->count = htons (count);
1378
1379 ssm = (struct GNUNET_ARM_ServiceInfoMessage *) &msg[1];
1380 pool_start = (char *) (ssm + count);
1381 pool_pos = 0;
1340 1382
1341 pos = (char *)&msg[1];
1342 for (sl = running_head; NULL != sl; sl = sl->next) 1383 for (sl = running_head; NULL != sl; sl = sl->next)
1384 {
1385 ssm->name_index = htons ((uint16_t) pool_pos);
1386 GNUNET_assert (GNUNET_OK == pool_write (pool_start, pool_size, &pool_pos,
1387 sl->name));
1388 ssm->binary_index = htons ((uint16_t) pool_pos);
1389 GNUNET_assert (GNUNET_OK == pool_write (pool_start, pool_size, &pool_pos,
1390 sl->binary));
1391 if (NULL == sl->proc)
1343 { 1392 {
1344 if (NULL != sl->proc) 1393 if (0 == sl->last_started_at.abs_value_us)
1345 { 1394 {
1346 size_t s = strlen(sl->name) + strlen(sl->binary) + 4; 1395 /* Process never started */
1347 GNUNET_snprintf(pos, s, "%s (%s)", sl->name, sl->binary); 1396 ssm->status = htonl (GNUNET_ARM_SERVICE_STATUS_STOPPED);
1348 pos += s; 1397 }
1349 } 1398 else if (0 == sl->last_exit_status)
1399 {
1400 ssm->status = htonl (GNUNET_ARM_SERVICE_STATUS_FINISHED);
1401 }
1402 else
1403 {
1404 ssm->status = htonl (GNUNET_ARM_SERVICE_STATUS_FAILED);
1405 ssm->last_exit_status = htons (sl->last_exit_status);
1406 }
1407 }
1408 else if ((NULL != sl->killing_client) || (GNUNET_YES == in_shutdown))
1409 {
1410 ssm->status = htonl (GNUNET_ARM_SERVICE_STATUS_STOPPING);
1411 }
1412 else
1413 {
1414 ssm->status = htonl (GNUNET_ARM_SERVICE_STATUS_STARTED);
1350 } 1415 }
1351 GNUNET_MQ_send(GNUNET_SERVICE_client_get_mq(client), env); 1416 ssm->last_started_at = GNUNET_TIME_absolute_hton (sl->last_started_at);
1352 GNUNET_SERVICE_client_continue(client); 1417 ssm->restart_at = GNUNET_TIME_absolute_hton (sl->restart_at);
1418 ssm++;
1419 }
1420 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env);
1421 GNUNET_SERVICE_client_continue (client);
1353} 1422}
1354 1423
1355 1424
@@ -1360,16 +1429,16 @@ handle_list(void *cls, const struct GNUNET_ARM_Message *request)
1360 * @param message the actual message 1429 * @param message the actual message
1361 */ 1430 */
1362static void 1431static void
1363handle_test(void *cls, const struct GNUNET_MessageHeader *message) 1432handle_test (void *cls, const struct GNUNET_MessageHeader *message)
1364{ 1433{
1365 struct GNUNET_SERVICE_Client *client = cls; 1434 struct GNUNET_SERVICE_Client *client = cls;
1366 struct GNUNET_MQ_Envelope *env; 1435 struct GNUNET_MQ_Envelope *env;
1367 struct GNUNET_MessageHeader *msg; 1436 struct GNUNET_MessageHeader *msg;
1368 1437
1369 (void)message; 1438 (void) message;
1370 env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_ARM_TEST); 1439 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_ARM_TEST);
1371 GNUNET_MQ_send(GNUNET_SERVICE_client_get_mq(client), env); 1440 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env);
1372 GNUNET_SERVICE_client_continue(client); 1441 GNUNET_SERVICE_client_continue (client);
1373} 1442}
1374 1443
1375 1444
@@ -1378,24 +1447,24 @@ handle_test(void *cls, const struct GNUNET_MessageHeader *message)
1378 * tasks, signal handler and the server. 1447 * tasks, signal handler and the server.
1379 */ 1448 */
1380static void 1449static void
1381do_shutdown() 1450do_shutdown ()
1382{ 1451{
1383 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Last shutdown phase\n"); 1452 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Last shutdown phase\n");
1384 if (NULL != notifier) 1453 if (NULL != notifier)
1385 { 1454 {
1386 GNUNET_notification_context_destroy(notifier); 1455 GNUNET_notification_context_destroy (notifier);
1387 notifier = NULL; 1456 notifier = NULL;
1388 } 1457 }
1389 if (NULL != service) 1458 if (NULL != service)
1390 { 1459 {
1391 GNUNET_SERVICE_shutdown(service); 1460 GNUNET_SERVICE_shutdown (service);
1392 service = NULL; 1461 service = NULL;
1393 } 1462 }
1394 if (NULL != child_death_task) 1463 if (NULL != child_death_task)
1395 { 1464 {
1396 GNUNET_SCHEDULER_cancel(child_death_task); 1465 GNUNET_SCHEDULER_cancel (child_death_task);
1397 child_death_task = NULL; 1466 child_death_task = NULL;
1398 } 1467 }
1399} 1468}
1400 1469
1401 1470
@@ -1406,13 +1475,13 @@ do_shutdown()
1406 * @return number of active services found 1475 * @return number of active services found
1407 */ 1476 */
1408static unsigned int 1477static unsigned int
1409list_count(struct ServiceList *running_head) 1478list_count (struct ServiceList *running_head)
1410{ 1479{
1411 struct ServiceList *i; 1480 struct ServiceList *i;
1412 unsigned int res; 1481 unsigned int res;
1413 1482
1414 for (res = 0, i = running_head; NULL != i; i = i->next, res++) 1483 for (res = 0, i = running_head; NULL != i; i = i->next, res++)
1415 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s\n", i->name); 1484 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%s\n", i->name);
1416 return res; 1485 return res;
1417} 1486}
1418 1487
@@ -1423,61 +1492,61 @@ list_count(struct ServiceList *running_head)
1423 * @param cls closure, NULL if we need to self-restart 1492 * @param cls closure, NULL if we need to self-restart
1424 */ 1493 */
1425static void 1494static void
1426shutdown_task(void *cls) 1495shutdown_task (void *cls)
1427{ 1496{
1428 struct ServiceList *pos; 1497 struct ServiceList *pos;
1429 struct ServiceList *nxt; 1498 struct ServiceList *nxt;
1430 struct ServiceListeningInfo *sli; 1499 struct ServiceListeningInfo *sli;
1431 1500
1432 (void)cls; 1501 (void) cls;
1433 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "First shutdown phase\n"); 1502 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "First shutdown phase\n");
1434 if (NULL != child_restart_task) 1503 if (NULL != child_restart_task)
1435 { 1504 {
1436 GNUNET_SCHEDULER_cancel(child_restart_task); 1505 GNUNET_SCHEDULER_cancel (child_restart_task);
1437 child_restart_task = NULL; 1506 child_restart_task = NULL;
1438 } 1507 }
1439 in_shutdown = GNUNET_YES; 1508 in_shutdown = GNUNET_YES;
1440 /* first, stop listening */ 1509 /* first, stop listening */
1441 for (pos = running_head; NULL != pos; pos = pos->next) 1510 for (pos = running_head; NULL != pos; pos = pos->next)
1511 {
1512 while (NULL != (sli = pos->listen_head))
1442 { 1513 {
1443 while (NULL != (sli = pos->listen_head)) 1514 GNUNET_CONTAINER_DLL_remove (pos->listen_head, pos->listen_tail, sli);
1444 { 1515 if (NULL != sli->accept_task)
1445 GNUNET_CONTAINER_DLL_remove(pos->listen_head, pos->listen_tail, sli); 1516 {
1446 if (NULL != sli->accept_task) 1517 GNUNET_SCHEDULER_cancel (sli->accept_task);
1447 { 1518 sli->accept_task = NULL;
1448 GNUNET_SCHEDULER_cancel(sli->accept_task); 1519 }
1449 sli->accept_task = NULL; 1520 GNUNET_break (GNUNET_OK ==
1450 } 1521 GNUNET_NETWORK_socket_close (sli->listen_socket));
1451 GNUNET_break(GNUNET_OK == 1522 GNUNET_free (sli->service_addr);
1452 GNUNET_NETWORK_socket_close(sli->listen_socket)); 1523 GNUNET_free (sli);
1453 GNUNET_free(sli->service_addr);
1454 GNUNET_free(sli);
1455 }
1456 } 1524 }
1525 }
1457 /* then, shutdown all existing service processes */ 1526 /* then, shutdown all existing service processes */
1458 nxt = running_head; 1527 nxt = running_head;
1459 while (NULL != (pos = nxt)) 1528 while (NULL != (pos = nxt))
1529 {
1530 nxt = pos->next;
1531 if (NULL != pos->proc)
1460 { 1532 {
1461 nxt = pos->next; 1533 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stopping service `%s'\n", pos->name);
1462 if (NULL != pos->proc) 1534 pos->killed_at = GNUNET_TIME_absolute_get ();
1463 { 1535 if (0 != GNUNET_OS_process_kill (pos->proc, GNUNET_TERM_SIG))
1464 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Stopping service `%s'\n", pos->name); 1536 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
1465 pos->killed_at = GNUNET_TIME_absolute_get();
1466 if (0 != GNUNET_OS_process_kill(pos->proc, GNUNET_TERM_SIG))
1467 GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING, "kill");
1468 }
1469 else
1470 {
1471 free_service(pos);
1472 }
1473 } 1537 }
1538 else
1539 {
1540 free_service (pos);
1541 }
1542 }
1474 /* finally, should all service processes be already gone, terminate for real */ 1543 /* finally, should all service processes be already gone, terminate for real */
1475 if (NULL == running_head) 1544 if (NULL == running_head)
1476 do_shutdown(); 1545 do_shutdown ();
1477 else 1546 else
1478 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1547 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1479 "Delaying shutdown, have %u childs still running\n", 1548 "Delaying shutdown, have %u childs still running\n",
1480 list_count(running_head)); 1549 list_count (running_head));
1481} 1550}
1482 1551
1483 1552
@@ -1487,73 +1556,73 @@ shutdown_task(void *cls)
1487 * @param cls closure, always NULL 1556 * @param cls closure, always NULL
1488 */ 1557 */
1489static void 1558static void
1490delayed_restart_task(void *cls) 1559delayed_restart_task (void *cls)
1491 1560
1492{ 1561{
1493 struct ServiceList *sl; 1562 struct ServiceList *sl;
1494 struct GNUNET_TIME_Relative lowestRestartDelay; 1563 struct GNUNET_TIME_Relative lowestRestartDelay;
1495 struct ServiceListeningInfo *sli; 1564 struct ServiceListeningInfo *sli;
1496 1565
1497 (void)cls; 1566 (void) cls;
1498 child_restart_task = NULL; 1567 child_restart_task = NULL;
1499 GNUNET_assert(GNUNET_NO == in_shutdown); 1568 GNUNET_assert (GNUNET_NO == in_shutdown);
1500 lowestRestartDelay = GNUNET_TIME_UNIT_FOREVER_REL; 1569 lowestRestartDelay = GNUNET_TIME_UNIT_FOREVER_REL;
1501 1570
1502 /* check for services that need to be restarted due to 1571 /* check for services that need to be restarted due to
1503 * configuration changes or because the last restart failed */ 1572 * configuration changes or because the last restart failed */
1504 for (sl = running_head; NULL != sl; sl = sl->next) 1573 for (sl = running_head; NULL != sl; sl = sl->next)
1574 {
1575 if (NULL != sl->proc)
1576 continue;
1577 /* service is currently not running */
1578 if (0 == GNUNET_TIME_absolute_get_remaining (sl->restart_at).rel_value_us)
1505 { 1579 {
1506 if (NULL != sl->proc) 1580 /* restart is now allowed */
1507 continue; 1581 if (sl->force_start)
1508 /* service is currently not running */ 1582 {
1509 if (0 == GNUNET_TIME_absolute_get_remaining(sl->restart_at).rel_value_us) 1583 /* process should run by default, start immediately */
1510 { 1584 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1511 /* restart is now allowed */ 1585 _ ("Restarting service `%s'.\n"),
1512 if (sl->force_start) 1586 sl->name);
1513 { 1587 start_process (sl, NULL, 0);
1514 /* process should run by default, start immediately */ 1588 }
1515 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1516 _("Restarting service `%s'.\n"),
1517 sl->name);
1518 start_process(sl, NULL, 0);
1519 }
1520 else
1521 {
1522 /* process is run on-demand, ensure it is re-started if there is demand */
1523 for (sli = sl->listen_head; NULL != sli; sli = sli->next)
1524 if (NULL == sli->accept_task)
1525 {
1526 /* accept was actually paused, so start it again */
1527 sli->accept_task =
1528 GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL,
1529 sli->listen_socket,
1530 &accept_connection,
1531 sli);
1532 }
1533 }
1534 }
1535 else 1589 else
1536 { 1590 {
1537 /* update calculation for earliest time to reactivate a service */ 1591 /* process is run on-demand, ensure it is re-started if there is demand */
1538 lowestRestartDelay = 1592 for (sli = sl->listen_head; NULL != sli; sli = sli->next)
1539 GNUNET_TIME_relative_min(lowestRestartDelay, 1593 if (NULL == sli->accept_task)
1540 GNUNET_TIME_absolute_get_remaining( 1594 {
1541 sl->restart_at)); 1595 /* accept was actually paused, so start it again */
1542 } 1596 sli->accept_task =
1597 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
1598 sli->listen_socket,
1599 &accept_connection,
1600 sli);
1601 }
1602 }
1603 }
1604 else
1605 {
1606 /* update calculation for earliest time to reactivate a service */
1607 lowestRestartDelay =
1608 GNUNET_TIME_relative_min (lowestRestartDelay,
1609 GNUNET_TIME_absolute_get_remaining (
1610 sl->restart_at));
1543 } 1611 }
1612 }
1544 if (lowestRestartDelay.rel_value_us != 1613 if (lowestRestartDelay.rel_value_us !=
1545 GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) 1614 GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1546 { 1615 {
1547 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1616 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1548 "Will restart process in %s\n", 1617 "Will restart process in %s\n",
1549 GNUNET_STRINGS_relative_time_to_string(lowestRestartDelay, 1618 GNUNET_STRINGS_relative_time_to_string (lowestRestartDelay,
1550 GNUNET_YES)); 1619 GNUNET_YES));
1551 child_restart_task = 1620 child_restart_task =
1552 GNUNET_SCHEDULER_add_delayed_with_priority(lowestRestartDelay, 1621 GNUNET_SCHEDULER_add_delayed_with_priority (lowestRestartDelay,
1553 GNUNET_SCHEDULER_PRIORITY_IDLE, 1622 GNUNET_SCHEDULER_PRIORITY_IDLE,
1554 &delayed_restart_task, 1623 &delayed_restart_task,
1555 NULL); 1624 NULL);
1556 } 1625 }
1557} 1626}
1558 1627
1559 1628
@@ -1564,7 +1633,7 @@ delayed_restart_task(void *cls)
1564 * @param cls closure, NULL 1633 * @param cls closure, NULL
1565 */ 1634 */
1566static void 1635static void
1567maint_child_death(void *cls) 1636maint_child_death (void *cls)
1568{ 1637{
1569 struct ServiceList *pos; 1638 struct ServiceList *pos;
1570 struct ServiceList *next; 1639 struct ServiceList *next;
@@ -1577,199 +1646,200 @@ maint_child_death(void *cls)
1577 unsigned long statusCode; 1646 unsigned long statusCode;
1578 const struct GNUNET_DISK_FileHandle *pr; 1647 const struct GNUNET_DISK_FileHandle *pr;
1579 1648
1580 (void)cls; 1649 (void) cls;
1581 pr = GNUNET_DISK_pipe_handle(sigpipe, GNUNET_DISK_PIPE_END_READ); 1650 pr = GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ);
1582 child_death_task = NULL; 1651 child_death_task = NULL;
1583 /* consume the signal */ 1652 /* consume the signal */
1584 GNUNET_break(0 < GNUNET_DISK_file_read(pr, &c, sizeof(c))); 1653 GNUNET_break (0 < GNUNET_DISK_file_read (pr, &c, sizeof(c)));
1585 1654
1586 /* check for services that died (WAITPID) */ 1655 /* check for services that died (WAITPID) */
1587 next = running_head; 1656 next = running_head;
1588 while (NULL != (pos = next)) 1657 while (NULL != (pos = next))
1589 { 1658 {
1590 next = pos->next; 1659 next = pos->next;
1591 1660
1592 if (NULL == pos->proc) 1661 if (NULL == pos->proc)
1593 { 1662 {
1594 if (GNUNET_YES == in_shutdown) 1663 if (GNUNET_YES == in_shutdown)
1595 free_service(pos); 1664 free_service (pos);
1596 continue; 1665 continue;
1597 } 1666 }
1598#if HAVE_WAIT4 1667#if HAVE_WAIT4
1599 if (NULL != wait_file) 1668 if (NULL != wait_file)
1600 { 1669 {
1601 /* need to use 'wait4()' to obtain and log performance data */ 1670 /* need to use 'wait4()' to obtain and log performance data */
1602 struct rusage ru; 1671 struct rusage ru;
1603 int status; 1672 int status;
1604 pid_t pid; 1673 pid_t pid;
1605 1674
1606 pid = GNUNET_OS_process_get_pid(pos->proc); 1675 pid = GNUNET_OS_process_get_pid (pos->proc);
1607 ret = wait4(pid, &status, WNOHANG, &ru); 1676 ret = wait4 (pid, &status, WNOHANG, &ru);
1608 if (ret <= 0) 1677 if (ret <= 0)
1609 continue; /* no process done */ 1678 continue; /* no process done */
1610 if (WIFEXITED(status)) 1679 if (WIFEXITED (status))
1611 { 1680 {
1612 statusType = GNUNET_OS_PROCESS_EXITED; 1681 statusType = GNUNET_OS_PROCESS_EXITED;
1613 statusCode = WEXITSTATUS(status); 1682 statusCode = WEXITSTATUS (status);
1614 } 1683 }
1615 else if (WIFSIGNALED(status)) 1684 else if (WIFSIGNALED (status))
1616 { 1685 {
1617 statusType = GNUNET_OS_PROCESS_SIGNALED; 1686 statusType = GNUNET_OS_PROCESS_SIGNALED;
1618 statusCode = WTERMSIG(status); 1687 statusCode = WTERMSIG (status);
1619 } 1688 }
1620 else if (WIFSTOPPED(status)) 1689 else if (WIFSTOPPED (status))
1621 { 1690 {
1622 statusType = GNUNET_OS_PROCESS_SIGNALED; 1691 statusType = GNUNET_OS_PROCESS_SIGNALED;
1623 statusCode = WSTOPSIG(status); 1692 statusCode = WSTOPSIG (status);
1624 } 1693 }
1625#ifdef WIFCONTINUED 1694#ifdef WIFCONTINUED
1626 else if (WIFCONTINUED(status)) 1695 else if (WIFCONTINUED (status))
1627 { 1696 {
1628 statusType = GNUNET_OS_PROCESS_RUNNING; 1697 statusType = GNUNET_OS_PROCESS_RUNNING;
1629 statusCode = 0; 1698 statusCode = 0;
1630 } 1699 }
1631#endif
1632 else
1633 {
1634 statusType = GNUNET_OS_PROCESS_UNKNOWN;
1635 statusCode = 0;
1636 }
1637 if ((GNUNET_OS_PROCESS_EXITED == statusType) ||
1638 (GNUNET_OS_PROCESS_SIGNALED == statusType))
1639 {
1640 double utime = ru.ru_utime.tv_sec + (ru.ru_utime.tv_usec / 10e6);
1641 double stime = ru.ru_stime.tv_sec + (ru.ru_stime.tv_usec / 10e6);
1642 fprintf(wait_file,
1643 "%s(%u) %.3f %.3f %llu %llu %llu %llu %llu\n",
1644 pos->binary,
1645 (unsigned int)pid,
1646 utime,
1647 stime,
1648 (unsigned long long)ru.ru_maxrss,
1649 (unsigned long long)ru.ru_inblock,
1650 (unsigned long long)ru.ru_oublock,
1651 (unsigned long long)ru.ru_nvcsw,
1652 (unsigned long long)ru.ru_nivcsw);
1653 }
1654 }
1655 else /* continue with JUST this "if" as "else" (intentionally no brackets!) */
1656#endif 1700#endif
1657 if ((GNUNET_SYSERR == (ret = GNUNET_OS_process_status(pos->proc,
1658 &statusType,
1659 &statusCode))) ||
1660 (ret == GNUNET_NO) || (statusType == GNUNET_OS_PROCESS_STOPPED) ||
1661 (statusType == GNUNET_OS_PROCESS_UNKNOWN) ||
1662 (statusType == GNUNET_OS_PROCESS_RUNNING))
1663 continue;
1664
1665 if (statusType == GNUNET_OS_PROCESS_EXITED)
1666 {
1667 statstr = _(/* process termination method */ "exit");
1668 statcode = statusCode;
1669 }
1670 else if (statusType == GNUNET_OS_PROCESS_SIGNALED)
1671 {
1672 statstr = _(/* process termination method */ "signal");
1673 statcode = statusCode;
1674 }
1675 else 1701 else
1676 { 1702 {
1677 statstr = _(/* process termination method */ "unknown"); 1703 statusType = GNUNET_OS_PROCESS_UNKNOWN;
1678 statcode = 0; 1704 statusCode = 0;
1679 } 1705 }
1680 if (0 != pos->killed_at.abs_value_us) 1706 if ((GNUNET_OS_PROCESS_EXITED == statusType) ||
1681 { 1707 (GNUNET_OS_PROCESS_SIGNALED == statusType))
1682 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 1708 {
1683 _("Service `%s' took %s to terminate\n"), 1709 double utime = ru.ru_utime.tv_sec + (ru.ru_utime.tv_usec / 10e6);
1710 double stime = ru.ru_stime.tv_sec + (ru.ru_stime.tv_usec / 10e6);
1711 fprintf (wait_file,
1712 "%s(%u) %.3f %.3f %llu %llu %llu %llu %llu\n",
1713 pos->binary,
1714 (unsigned int) pid,
1715 utime,
1716 stime,
1717 (unsigned long long) ru.ru_maxrss,
1718 (unsigned long long) ru.ru_inblock,
1719 (unsigned long long) ru.ru_oublock,
1720 (unsigned long long) ru.ru_nvcsw,
1721 (unsigned long long) ru.ru_nivcsw);
1722 }
1723 }
1724 else /* continue with JUST this "if" as "else" (intentionally no brackets!) */
1725#endif
1726 if ((GNUNET_SYSERR == (ret = GNUNET_OS_process_status (pos->proc,
1727 &statusType,
1728 &statusCode))) ||
1729 (ret == GNUNET_NO) || (statusType == GNUNET_OS_PROCESS_STOPPED) ||
1730 (statusType == GNUNET_OS_PROCESS_UNKNOWN) ||
1731 (statusType == GNUNET_OS_PROCESS_RUNNING))
1732 continue;
1733
1734 if (statusType == GNUNET_OS_PROCESS_EXITED)
1735 {
1736 statstr = _ (/* process termination method */ "exit");
1737 statcode = statusCode;
1738 }
1739 else if (statusType == GNUNET_OS_PROCESS_SIGNALED)
1740 {
1741 statstr = _ (/* process termination method */ "signal");
1742 statcode = statusCode;
1743 }
1744 else
1745 {
1746 statstr = _ (/* process termination method */ "unknown");
1747 statcode = 0;
1748 }
1749 if (0 != pos->killed_at.abs_value_us)
1750 {
1751 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1752 _ ("Service `%s' took %s to terminate\n"),
1753 pos->name,
1754 GNUNET_STRINGS_relative_time_to_string (
1755 GNUNET_TIME_absolute_get_duration (pos->killed_at),
1756 GNUNET_YES));
1757 }
1758 GNUNET_OS_process_destroy (pos->proc);
1759 pos->proc = NULL;
1760 broadcast_status (pos->name, GNUNET_ARM_SERVICE_STOPPED, NULL);
1761 if (NULL != pos->killing_client)
1762 {
1763 signal_result (pos->killing_client,
1684 pos->name, 1764 pos->name,
1685 GNUNET_STRINGS_relative_time_to_string( 1765 pos->killing_client_request_id,
1686 GNUNET_TIME_absolute_get_duration(pos->killed_at), 1766 GNUNET_ARM_RESULT_STOPPED);
1687 GNUNET_YES)); 1767 pos->killing_client = NULL;
1688 } 1768 pos->killing_client_request_id = 0;
1689 GNUNET_OS_process_destroy(pos->proc); 1769 }
1690 pos->proc = NULL; 1770 if (GNUNET_YES != in_shutdown)
1691 broadcast_status(pos->name, GNUNET_ARM_SERVICE_STOPPED, NULL); 1771 {
1692 if (NULL != pos->killing_client) 1772 pos->last_exit_status = statcode;
1693 { 1773 if ((statusType == GNUNET_OS_PROCESS_EXITED) && (statcode == 0))
1694 signal_result(pos->killing_client, 1774 {
1695 pos->name, 1775 /* process terminated normally, allow restart at any time */
1696 pos->killing_client_request_id, 1776 pos->restart_at.abs_value_us = 0;
1697 GNUNET_ARM_RESULT_STOPPED); 1777 GNUNET_log (
1698 pos->killing_client = NULL; 1778 GNUNET_ERROR_TYPE_INFO,
1699 pos->killing_client_request_id = 0; 1779 _ ("Service `%s' terminated normally, will restart at any time\n"),
1700 } 1780 pos->name);
1701 if (GNUNET_YES != in_shutdown) 1781 /* process can still be re-started on-demand, ensure it is re-started if there is demand */
1782 for (sli = pos->listen_head; NULL != sli; sli = sli->next)
1702 { 1783 {
1703 if ((statusType == GNUNET_OS_PROCESS_EXITED) && (statcode == 0)) 1784 GNUNET_break (NULL == sli->accept_task);
1704 { 1785 sli->accept_task =
1705 /* process terminated normally, allow restart at any time */ 1786 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
1706 pos->restart_at.abs_value_us = 0; 1787 sli->listen_socket,
1707 GNUNET_log( 1788 &accept_connection,
1708 GNUNET_ERROR_TYPE_INFO, 1789 sli);
1709 _("Service `%s' terminated normally, will restart at any time\n"),
1710 pos->name);
1711 /* process can still be re-started on-demand, ensure it is re-started if there is demand */
1712 for (sli = pos->listen_head; NULL != sli; sli = sli->next)
1713 {
1714 GNUNET_break(NULL == sli->accept_task);
1715 sli->accept_task =
1716 GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL,
1717 sli->listen_socket,
1718 &accept_connection,
1719 sli);
1720 }
1721 }
1722 else
1723 {
1724 GNUNET_log(
1725 GNUNET_ERROR_TYPE_INFO,
1726 _("Service `%s' terminated with status %s/%d, will restart in %s\n"),
1727 pos->name,
1728 statstr,
1729 statcode,
1730 GNUNET_STRINGS_relative_time_to_string(pos->backoff, GNUNET_YES));
1731 {
1732 /* Reduce backoff based on runtime of the process,
1733 so that there is a cool-down if a process actually
1734 runs for a while. */
1735 struct GNUNET_TIME_Relative runtime;
1736 unsigned int minutes;
1737
1738 runtime = GNUNET_TIME_absolute_get_duration(pos->restart_at);
1739 minutes =
1740 runtime.rel_value_us / GNUNET_TIME_UNIT_MINUTES.rel_value_us;
1741 if (minutes > 31)
1742 pos->backoff = GNUNET_TIME_UNIT_ZERO;
1743 else
1744 pos->backoff.rel_value_us <<= minutes;
1745 }
1746 /* schedule restart */
1747 pos->restart_at = GNUNET_TIME_relative_to_absolute(pos->backoff);
1748 pos->backoff = GNUNET_TIME_STD_BACKOFF(pos->backoff);
1749 if (NULL != child_restart_task)
1750 GNUNET_SCHEDULER_cancel(child_restart_task);
1751 child_restart_task =
1752 GNUNET_SCHEDULER_add_with_priority(GNUNET_SCHEDULER_PRIORITY_IDLE,
1753 &delayed_restart_task,
1754 NULL);
1755 }
1756 } 1790 }
1791 }
1757 else 1792 else
1793 {
1794 GNUNET_log (
1795 GNUNET_ERROR_TYPE_WARNING,
1796 _ ("Service `%s' terminated with status %s/%d, will restart in %s\n"),
1797 pos->name,
1798 statstr,
1799 statcode,
1800 GNUNET_STRINGS_relative_time_to_string (pos->backoff, GNUNET_YES));
1758 { 1801 {
1759 free_service(pos); 1802 /* Reduce backoff based on runtime of the process,
1803 so that there is a cool-down if a process actually
1804 runs for a while. */
1805 struct GNUNET_TIME_Relative runtime;
1806 unsigned int minutes;
1807
1808 runtime = GNUNET_TIME_absolute_get_duration (pos->restart_at);
1809 minutes =
1810 runtime.rel_value_us / GNUNET_TIME_UNIT_MINUTES.rel_value_us;
1811 if (minutes > 31)
1812 pos->backoff = GNUNET_TIME_UNIT_ZERO;
1813 else
1814 pos->backoff.rel_value_us <<= minutes;
1760 } 1815 }
1816 /* schedule restart */
1817 pos->restart_at = GNUNET_TIME_relative_to_absolute (pos->backoff);
1818 pos->backoff = GNUNET_TIME_STD_BACKOFF (pos->backoff);
1819 if (NULL != child_restart_task)
1820 GNUNET_SCHEDULER_cancel (child_restart_task);
1821 child_restart_task =
1822 GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE,
1823 &delayed_restart_task,
1824 NULL);
1825 }
1761 } 1826 }
1827 else
1828 {
1829 free_service (pos);
1830 }
1831 }
1762 child_death_task = 1832 child_death_task =
1763 GNUNET_SCHEDULER_add_read_file(GNUNET_TIME_UNIT_FOREVER_REL, 1833 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
1764 pr, 1834 pr,
1765 &maint_child_death, 1835 &maint_child_death,
1766 NULL); 1836 NULL);
1767 if ((NULL == running_head) && (GNUNET_YES == in_shutdown)) 1837 if ((NULL == running_head) && (GNUNET_YES == in_shutdown))
1768 do_shutdown(); 1838 do_shutdown ();
1769 else if (GNUNET_YES == in_shutdown) 1839 else if (GNUNET_YES == in_shutdown)
1770 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1840 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1771 "Delaying shutdown after child's death, still have %u children\n", 1841 "Delaying shutdown after child's death, still have %u children\n",
1772 list_count(running_head)); 1842 list_count (running_head));
1773} 1843}
1774 1844
1775 1845
@@ -1778,17 +1848,17 @@ maint_child_death(void *cls)
1778 * respective handler by writing to the trigger pipe. 1848 * respective handler by writing to the trigger pipe.
1779 */ 1849 */
1780static void 1850static void
1781sighandler_child_death() 1851sighandler_child_death ()
1782{ 1852{
1783 static char c; 1853 static char c;
1784 int old_errno = errno; /* back-up errno */ 1854 int old_errno = errno; /* back-up errno */
1785 1855
1786 GNUNET_break( 1856 GNUNET_break (
1787 1 == 1857 1 ==
1788 GNUNET_DISK_file_write(GNUNET_DISK_pipe_handle(sigpipe, 1858 GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle (sigpipe,
1789 GNUNET_DISK_PIPE_END_WRITE), 1859 GNUNET_DISK_PIPE_END_WRITE),
1790 &c, 1860 &c,
1791 sizeof(c))); 1861 sizeof(c)));
1792 errno = old_errno; /* restore errno */ 1862 errno = old_errno; /* restore errno */
1793} 1863}
1794 1864
@@ -1802,7 +1872,7 @@ sighandler_child_death()
1802 * @return #GNUNET_OK (continue) 1872 * @return #GNUNET_OK (continue)
1803 */ 1873 */
1804static void 1874static void
1805setup_service(void *cls, const char *section) 1875setup_service (void *cls, const char *section)
1806{ 1876{
1807 struct ServiceList *sl; 1877 struct ServiceList *sl;
1808 char *binary; 1878 char *binary;
@@ -1812,94 +1882,94 @@ setup_service(void *cls, const char *section)
1812 socklen_t *addr_lens; 1882 socklen_t *addr_lens;
1813 int ret; 1883 int ret;
1814 1884
1815 (void)cls; 1885 (void) cls;
1816 if (0 == strcasecmp(section, "arm")) 1886 if (0 == strcasecmp (section, "arm"))
1817 return; 1887 return;
1818 if (GNUNET_OK != 1888 if (GNUNET_OK !=
1819 GNUNET_CONFIGURATION_get_value_string(cfg, section, "BINARY", &binary)) 1889 GNUNET_CONFIGURATION_get_value_string (cfg, section, "BINARY", &binary))
1820 { 1890 {
1821 /* not a service section */ 1891 /* not a service section */
1822 return; 1892 return;
1823 } 1893 }
1824 if ((GNUNET_YES == 1894 if ((GNUNET_YES ==
1825 GNUNET_CONFIGURATION_have_value(cfg, section, "RUN_PER_USER")) && 1895 GNUNET_CONFIGURATION_have_value (cfg, section, "RUN_PER_USER")) &&
1826 (GNUNET_YES == 1896 (GNUNET_YES ==
1827 GNUNET_CONFIGURATION_get_value_yesno(cfg, section, "RUN_PER_USER"))) 1897 GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "RUN_PER_USER")))
1898 {
1899 if (GNUNET_NO == start_user)
1828 { 1900 {
1829 if (GNUNET_NO == start_user) 1901 GNUNET_free (binary);
1830 { 1902 return; /* user service, and we don't deal with those */
1831 GNUNET_free(binary);
1832 return; /* user service, and we don't deal with those */
1833 }
1834 } 1903 }
1904 }
1835 else 1905 else
1906 {
1907 if (GNUNET_NO == start_system)
1836 { 1908 {
1837 if (GNUNET_NO == start_system) 1909 GNUNET_free (binary);
1838 { 1910 return; /* system service, and we don't deal with those */
1839 GNUNET_free(binary);
1840 return; /* system service, and we don't deal with those */
1841 }
1842 } 1911 }
1843 sl = find_service(section); 1912 }
1913 sl = find_service (section);
1844 if (NULL != sl) 1914 if (NULL != sl)
1845 { 1915 {
1846 /* got the same section twice!? */ 1916 /* got the same section twice!? */
1847 GNUNET_break(0); 1917 GNUNET_break (0);
1848 GNUNET_free(binary); 1918 GNUNET_free (binary);
1849 return; 1919 return;
1850 } 1920 }
1851 config = NULL; 1921 config = NULL;
1852 if (((GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename(cfg, 1922 if (((GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg,
1853 section, 1923 section,
1854 "CONFIG", 1924 "CONFIG",
1855 &config)) && 1925 &config)) &&
1856 (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename(cfg, 1926 (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg,
1857 "PATHS", 1927 "PATHS",
1858 "DEFAULTCONFIG", 1928 "DEFAULTCONFIG",
1859 &config))) || 1929 &config))) ||
1860 (0 != stat(config, &sbuf))) 1930 (0 != stat (config, &sbuf)))
1931 {
1932 if (NULL != config)
1861 { 1933 {
1862 if (NULL != config) 1934 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
1863 { 1935 section,
1864 GNUNET_log_config_invalid(GNUNET_ERROR_TYPE_WARNING, 1936 "CONFIG",
1865 section, 1937 strerror (errno));
1866 "CONFIG", 1938 GNUNET_free (config);
1867 strerror(errno)); 1939 config = NULL;
1868 GNUNET_free(config);
1869 config = NULL;
1870 }
1871 } 1940 }
1872 sl = GNUNET_new(struct ServiceList); 1941 }
1873 sl->name = GNUNET_strdup(section); 1942 sl = GNUNET_new (struct ServiceList);
1943 sl->name = GNUNET_strdup (section);
1874 sl->binary = binary; 1944 sl->binary = binary;
1875 sl->config = config; 1945 sl->config = config;
1876 sl->backoff = GNUNET_TIME_UNIT_MILLISECONDS; 1946 sl->backoff = GNUNET_TIME_UNIT_MILLISECONDS;
1877 sl->restart_at = GNUNET_TIME_UNIT_FOREVER_ABS; 1947 sl->restart_at = GNUNET_TIME_UNIT_FOREVER_ABS;
1878 if (GNUNET_CONFIGURATION_have_value(cfg, section, "PIPECONTROL")) 1948 if (GNUNET_CONFIGURATION_have_value (cfg, section, "PIPECONTROL"))
1879 sl->pipe_control = 1949 sl->pipe_control =
1880 GNUNET_CONFIGURATION_get_value_yesno(cfg, section, "PIPECONTROL"); 1950 GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "PIPECONTROL");
1881 GNUNET_CONTAINER_DLL_insert(running_head, running_tail, sl); 1951 GNUNET_CONTAINER_DLL_insert (running_head, running_tail, sl);
1882 if (GNUNET_YES == 1952 if (GNUNET_YES ==
1883 GNUNET_CONFIGURATION_get_value_yesno(cfg, section, "IMMEDIATE_START")) 1953 GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "IMMEDIATE_START"))
1884 { 1954 {
1885 sl->force_start = GNUNET_YES; 1955 sl->force_start = GNUNET_YES;
1886 if (GNUNET_YES == 1956 if (GNUNET_YES ==
1887 GNUNET_CONFIGURATION_get_value_yesno(cfg, section, "NOARMBIND")) 1957 GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "NOARMBIND"))
1888 return; 1958 return;
1889 } 1959 }
1890 else 1960 else
1891 { 1961 {
1892 if (GNUNET_YES != 1962 if (GNUNET_YES !=
1893 GNUNET_CONFIGURATION_get_value_yesno(cfg, section, "START_ON_DEMAND")) 1963 GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "START_ON_DEMAND"))
1894 return; 1964 return;
1895 } 1965 }
1896 if (0 >= (ret = get_server_addresses(section, cfg, &addrs, &addr_lens))) 1966 if (0 >= (ret = get_server_addresses (section, cfg, &addrs, &addr_lens)))
1897 return; 1967 return;
1898 /* this will free (or capture) addrs[i] */ 1968 /* this will free (or capture) addrs[i] */
1899 for (unsigned int i = 0; i < (unsigned int)ret; i++) 1969 for (unsigned int i = 0; i < (unsigned int) ret; i++)
1900 create_listen_socket(addrs[i], addr_lens[i], sl); 1970 create_listen_socket (addrs[i], addr_lens[i], sl);
1901 GNUNET_free(addrs); 1971 GNUNET_free (addrs);
1902 GNUNET_free(addr_lens); 1972 GNUNET_free (addr_lens);
1903} 1973}
1904 1974
1905 1975
@@ -1912,16 +1982,16 @@ setup_service(void *cls, const char *section)
1912 * @return @a client 1982 * @return @a client
1913 */ 1983 */
1914static void * 1984static void *
1915client_connect_cb(void *cls, 1985client_connect_cb (void *cls,
1916 struct GNUNET_SERVICE_Client *client, 1986 struct GNUNET_SERVICE_Client *client,
1917 struct GNUNET_MQ_Handle *mq) 1987 struct GNUNET_MQ_Handle *mq)
1918{ 1988{
1919 /* All clients are considered to be of the "monitor" kind 1989 /* All clients are considered to be of the "monitor" kind
1920 * (that is, they don't affect ARM shutdown). 1990 * (that is, they don't affect ARM shutdown).
1921 */ 1991 */
1922 (void)cls; 1992 (void) cls;
1923 (void)mq; 1993 (void) mq;
1924 GNUNET_SERVICE_client_mark_monitor(client); 1994 GNUNET_SERVICE_client_mark_monitor (client);
1925 return client; 1995 return client;
1926} 1996}
1927 1997
@@ -1934,12 +2004,12 @@ client_connect_cb(void *cls,
1934 * @param app_ctx must match @a client 2004 * @param app_ctx must match @a client
1935 */ 2005 */
1936static void 2006static void
1937client_disconnect_cb(void *cls, 2007client_disconnect_cb (void *cls,
1938 struct GNUNET_SERVICE_Client *client, 2008 struct GNUNET_SERVICE_Client *client,
1939 void *app_ctx) 2009 void *app_ctx)
1940{ 2010{
1941 (void)cls; 2011 (void) cls;
1942 GNUNET_assert(client == app_ctx); 2012 GNUNET_assert (client == app_ctx);
1943 for (struct ServiceList *sl = running_head; NULL != sl; sl = sl->next) 2013 for (struct ServiceList *sl = running_head; NULL != sl; sl = sl->next)
1944 if (sl->killing_client == client) 2014 if (sl->killing_client == client)
1945 sl->killing_client = NULL; 2015 sl->killing_client = NULL;
@@ -1955,18 +2025,18 @@ client_disconnect_cb(void *cls,
1955 * #GNUNET_SYSERR to close it (signal serious error) 2025 * #GNUNET_SYSERR to close it (signal serious error)
1956 */ 2026 */
1957static void 2027static void
1958handle_monitor(void *cls, const struct GNUNET_MessageHeader *message) 2028handle_monitor (void *cls, const struct GNUNET_MessageHeader *message)
1959{ 2029{
1960 struct GNUNET_SERVICE_Client *client = cls; 2030 struct GNUNET_SERVICE_Client *client = cls;
1961 2031
1962 (void)message; 2032 (void) message;
1963 /* FIXME: might want to start by letting monitor know about 2033 /* FIXME: might want to start by letting monitor know about
1964 services that are already running */ 2034 services that are already running */
1965 /* Removal is handled by the server implementation, internally. */ 2035 /* Removal is handled by the server implementation, internally. */
1966 GNUNET_notification_context_add(notifier, 2036 GNUNET_notification_context_add (notifier,
1967 GNUNET_SERVICE_client_get_mq(client)); 2037 GNUNET_SERVICE_client_get_mq (client));
1968 broadcast_status("arm", GNUNET_ARM_SERVICE_MONITORING_STARTED, client); 2038 broadcast_status ("arm", GNUNET_ARM_SERVICE_MONITORING_STARTED, client);
1969 GNUNET_SERVICE_client_continue(client); 2039 GNUNET_SERVICE_client_continue (client);
1970} 2040}
1971 2041
1972 2042
@@ -1978,71 +2048,71 @@ handle_monitor(void *cls, const struct GNUNET_MessageHeader *message)
1978 * @param c configuration to use 2048 * @param c configuration to use
1979 */ 2049 */
1980static void 2050static void
1981run(void *cls, 2051run (void *cls,
1982 const struct GNUNET_CONFIGURATION_Handle *c, 2052 const struct GNUNET_CONFIGURATION_Handle *c,
1983 struct GNUNET_SERVICE_Handle *serv) 2053 struct GNUNET_SERVICE_Handle *serv)
1984{ 2054{
1985 struct ServiceList *sl; 2055 struct ServiceList *sl;
1986 2056
1987 (void)cls; 2057 (void) cls;
1988 cfg = c; 2058 cfg = c;
1989 service = serv; 2059 service = serv;
1990 GNUNET_SCHEDULER_add_shutdown(&shutdown_task, NULL); 2060 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
1991 child_death_task = GNUNET_SCHEDULER_add_read_file( 2061 child_death_task = GNUNET_SCHEDULER_add_read_file (
1992 GNUNET_TIME_UNIT_FOREVER_REL, 2062 GNUNET_TIME_UNIT_FOREVER_REL,
1993 GNUNET_DISK_pipe_handle(sigpipe, GNUNET_DISK_PIPE_END_READ), 2063 GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ),
1994 &maint_child_death, 2064 &maint_child_death,
1995 NULL); 2065 NULL);
1996#if HAVE_WAIT4 2066#if HAVE_WAIT4
1997 if (GNUNET_OK == 2067 if (GNUNET_OK ==
1998 GNUNET_CONFIGURATION_get_value_filename(cfg, 2068 GNUNET_CONFIGURATION_get_value_filename (cfg,
1999 "ARM", 2069 "ARM",
2000 "RESOURCE_DIAGNOSTICS", 2070 "RESOURCE_DIAGNOSTICS",
2001 &wait_filename)) 2071 &wait_filename))
2072 {
2073 wait_file = fopen (wait_filename, "w");
2074 if (NULL == wait_file)
2002 { 2075 {
2003 wait_file = fopen(wait_filename, "w"); 2076 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
2004 if (NULL == wait_file) 2077 "fopen",
2005 { 2078 wait_filename);
2006 GNUNET_log_strerror_file(GNUNET_ERROR_TYPE_ERROR,
2007 "fopen",
2008 wait_filename);
2009 }
2010 } 2079 }
2080 }
2011#endif 2081#endif
2012 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, 2082 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg,
2013 "ARM", 2083 "ARM",
2014 "GLOBAL_PREFIX", 2084 "GLOBAL_PREFIX",
2015 &prefix_command)) 2085 &prefix_command))
2016 prefix_command = GNUNET_strdup(""); 2086 prefix_command = GNUNET_strdup ("");
2017 else 2087 else
2018 prefix_command = GNUNET_CONFIGURATION_expand_dollar(cfg, prefix_command); 2088 prefix_command = GNUNET_CONFIGURATION_expand_dollar (cfg, prefix_command);
2019 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, 2089 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg,
2020 "ARM", 2090 "ARM",
2021 "GLOBAL_POSTFIX", 2091 "GLOBAL_POSTFIX",
2022 &final_option)) 2092 &final_option))
2023 final_option = GNUNET_strdup(""); 2093 final_option = GNUNET_strdup ("");
2024 else 2094 else
2025 final_option = GNUNET_CONFIGURATION_expand_dollar(cfg, final_option); 2095 final_option = GNUNET_CONFIGURATION_expand_dollar (cfg, final_option);
2026 start_user = 2096 start_user =
2027 GNUNET_CONFIGURATION_get_value_yesno(cfg, "ARM", "START_USER_SERVICES"); 2097 GNUNET_CONFIGURATION_get_value_yesno (cfg, "ARM", "START_USER_SERVICES");
2028 start_system = 2098 start_system =
2029 GNUNET_CONFIGURATION_get_value_yesno(cfg, "ARM", "START_SYSTEM_SERVICES"); 2099 GNUNET_CONFIGURATION_get_value_yesno (cfg, "ARM", "START_SYSTEM_SERVICES");
2030 if ((GNUNET_NO == start_user) && (GNUNET_NO == start_system)) 2100 if ((GNUNET_NO == start_user) && (GNUNET_NO == start_system))
2031 { 2101 {
2032 GNUNET_log( 2102 GNUNET_log (
2033 GNUNET_ERROR_TYPE_ERROR, 2103 GNUNET_ERROR_TYPE_ERROR,
2034 "Please configure either START_USER_SERVICES or START_SYSTEM_SERVICES or both.\n"); 2104 "Please configure either START_USER_SERVICES or START_SYSTEM_SERVICES or both.\n");
2035 GNUNET_SCHEDULER_shutdown(); 2105 GNUNET_SCHEDULER_shutdown ();
2036 global_ret = 1; 2106 global_ret = 1;
2037 return; 2107 return;
2038 } 2108 }
2039 GNUNET_CONFIGURATION_iterate_sections(cfg, &setup_service, NULL); 2109 GNUNET_CONFIGURATION_iterate_sections (cfg, &setup_service, NULL);
2040 2110
2041 /* start default services... */ 2111 /* start default services... */
2042 for (sl = running_head; NULL != sl; sl = sl->next) 2112 for (sl = running_head; NULL != sl; sl = sl->next)
2043 if (GNUNET_YES == sl->force_start) 2113 if (GNUNET_YES == sl->force_start)
2044 start_process(sl, NULL, 0); 2114 start_process (sl, NULL, 0);
2045 notifier = GNUNET_notification_context_create(MAX_NOTIFY_QUEUE); 2115 notifier = GNUNET_notification_context_create (MAX_NOTIFY_QUEUE);
2046} 2116}
2047 2117
2048 2118
@@ -2054,61 +2124,64 @@ run(void *cls,
2054 * @return 0 ok, 1 on error 2124 * @return 0 ok, 1 on error
2055 */ 2125 */
2056int 2126int
2057main(int argc, char *const *argv) 2127main (int argc, char *const *argv)
2058{ 2128{
2059 struct GNUNET_SIGNAL_Context *shc_chld; 2129 struct GNUNET_SIGNAL_Context *shc_chld;
2060 struct GNUNET_MQ_MessageHandler handlers[] = 2130 struct GNUNET_MQ_MessageHandler handlers[] = {
2061 { GNUNET_MQ_hd_var_size(start, 2131 GNUNET_MQ_hd_var_size (start,
2062 GNUNET_MESSAGE_TYPE_ARM_START, 2132 GNUNET_MESSAGE_TYPE_ARM_START,
2063 struct GNUNET_ARM_Message, 2133 struct GNUNET_ARM_Message,
2064 NULL), 2134 NULL),
2065 GNUNET_MQ_hd_var_size(stop, 2135 GNUNET_MQ_hd_var_size (stop,
2066 GNUNET_MESSAGE_TYPE_ARM_STOP, 2136 GNUNET_MESSAGE_TYPE_ARM_STOP,
2067 struct GNUNET_ARM_Message, 2137 struct GNUNET_ARM_Message,
2068 NULL), 2138 NULL),
2069 GNUNET_MQ_hd_fixed_size(monitor, 2139 GNUNET_MQ_hd_fixed_size (monitor,
2070 GNUNET_MESSAGE_TYPE_ARM_MONITOR, 2140 GNUNET_MESSAGE_TYPE_ARM_MONITOR,
2071 struct GNUNET_MessageHeader, 2141 struct GNUNET_MessageHeader,
2072 NULL), 2142 NULL),
2073 GNUNET_MQ_hd_fixed_size(list, 2143 GNUNET_MQ_hd_fixed_size (list,
2074 GNUNET_MESSAGE_TYPE_ARM_LIST, 2144 GNUNET_MESSAGE_TYPE_ARM_LIST,
2075 struct GNUNET_ARM_Message, 2145 struct GNUNET_ARM_Message,
2076 NULL), 2146 NULL),
2077 GNUNET_MQ_hd_fixed_size(test, 2147 GNUNET_MQ_hd_fixed_size (test,
2078 GNUNET_MESSAGE_TYPE_ARM_TEST, 2148 GNUNET_MESSAGE_TYPE_ARM_TEST,
2079 struct GNUNET_MessageHeader, 2149 struct GNUNET_MessageHeader,
2080 NULL), 2150 NULL),
2081 GNUNET_MQ_handler_end() }; 2151 GNUNET_MQ_handler_end ()
2082 2152 };
2083 sigpipe = GNUNET_DISK_pipe(GNUNET_NO, GNUNET_NO, GNUNET_NO, GNUNET_NO); 2153
2084 GNUNET_assert(NULL != sigpipe); 2154 sigpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO, GNUNET_NO);
2155 GNUNET_assert (NULL != sigpipe);
2085 shc_chld = 2156 shc_chld =
2086 GNUNET_SIGNAL_handler_install(GNUNET_SIGCHLD, &sighandler_child_death); 2157 GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD,
2087 if (0 != GNUNET_SERVICE_run_(argc, 2158 &sighandler_child_death);
2088 argv, 2159 if (0 != GNUNET_SERVICE_run_ (argc,
2089 "arm", 2160 argv,
2090 GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN, 2161 "arm",
2091 &run, 2162 GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN
2092 &client_connect_cb, 2163 | GNUNET_SERVICE_OPTION_CLOSE_LSOCKS,
2093 &client_disconnect_cb, 2164 &run,
2094 NULL, 2165 &client_connect_cb,
2095 handlers)) 2166 &client_disconnect_cb,
2167 NULL,
2168 handlers))
2096 global_ret = 2; 2169 global_ret = 2;
2097#if HAVE_WAIT4 2170#if HAVE_WAIT4
2098 if (NULL != wait_file) 2171 if (NULL != wait_file)
2099 { 2172 {
2100 fclose(wait_file); 2173 fclose (wait_file);
2101 wait_file = NULL; 2174 wait_file = NULL;
2102 } 2175 }
2103 if (NULL != wait_filename) 2176 if (NULL != wait_filename)
2104 { 2177 {
2105 GNUNET_free(wait_filename); 2178 GNUNET_free (wait_filename);
2106 wait_filename = NULL; 2179 wait_filename = NULL;
2107 } 2180 }
2108#endif 2181#endif
2109 GNUNET_SIGNAL_handler_uninstall(shc_chld); 2182 GNUNET_SIGNAL_handler_uninstall (shc_chld);
2110 shc_chld = NULL; 2183 shc_chld = NULL;
2111 GNUNET_DISK_pipe_close(sigpipe); 2184 GNUNET_DISK_pipe_close (sigpipe);
2112 sigpipe = NULL; 2185 sigpipe = NULL;
2113 return global_ret; 2186 return global_ret;
2114} 2187}
@@ -2120,11 +2193,11 @@ main(int argc, char *const *argv)
2120/** 2193/**
2121 * MINIMIZE heap size (way below 128k) since this process doesn't need much. 2194 * MINIMIZE heap size (way below 128k) since this process doesn't need much.
2122 */ 2195 */
2123void __attribute__ ((constructor)) GNUNET_ARM_memory_init() 2196void __attribute__ ((constructor)) GNUNET_ARM_memory_init ()
2124{ 2197{
2125 mallopt(M_TRIM_THRESHOLD, 4 * 1024); 2198 mallopt (M_TRIM_THRESHOLD, 4 * 1024);
2126 mallopt(M_TOP_PAD, 1 * 1024); 2199 mallopt (M_TOP_PAD, 1 * 1024);
2127 malloc_trim(0); 2200 malloc_trim (0);
2128} 2201}
2129#endif 2202#endif
2130 2203
diff --git a/src/arm/test_exponential_backoff.c b/src/arm/test_exponential_backoff.c
index 8190d29c2..b13ab1cb8 100644
--- a/src/arm/test_exponential_backoff.c
+++ b/src/arm/test_exponential_backoff.c
@@ -196,7 +196,7 @@ arm_stop_cb(void *cls,
196static void 196static void
197srv_status(void *cls, 197srv_status(void *cls,
198 const char *service, 198 const char *service,
199 enum GNUNET_ARM_ServiceStatus status) 199 enum GNUNET_ARM_ServiceMonitorStatus status)
200{ 200{
201 if (status == GNUNET_ARM_SERVICE_MONITORING_STARTED) 201 if (status == GNUNET_ARM_SERVICE_MONITORING_STARTED)
202 { 202 {
diff --git a/src/arm/test_gnunet_service_arm.c b/src/arm/test_gnunet_service_arm.c
index 8c8c664f9..cb2c14438 100644
--- a/src/arm/test_gnunet_service_arm.c
+++ b/src/arm/test_gnunet_service_arm.c
@@ -78,7 +78,7 @@ static void
78service_list(void *cls, 78service_list(void *cls,
79 enum GNUNET_ARM_RequestStatus rs, 79 enum GNUNET_ARM_RequestStatus rs,
80 unsigned int count, 80 unsigned int count,
81 const char *const*list) 81 const struct GNUNET_ARM_ServiceInfo *list)
82{ 82{
83 unsigned int i; 83 unsigned int i;
84 84
@@ -89,13 +89,13 @@ service_list(void *cls,
89 goto stop_arm; 89 goto stop_arm;
90 for (i = 0; i < count; i++) 90 for (i = 0; i < count; i++)
91 { 91 {
92 if (0 == strcasecmp(list[i], 92 if ((0 == strcasecmp(list[i].name, "resolver")) &&
93 "resolver (gnunet-service-resolver)")) 93 (0 == strcasecmp(list[i].binary, "gnunet-service-resolver")))
94 { 94 {
95 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 95 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
96 "Got service list, now stopping arm\n"); 96 "Got service list, now stopping arm\n");
97 ret = 0; 97 ret = 0;
98 } 98 }
99 } 99 }
100 100
101stop_arm: 101stop_arm:
diff --git a/src/datastore/plugin_datastore_mysql.c b/src/datastore/plugin_datastore_mysql.c
index c670a6d99..cc5b558ee 100644
--- a/src/datastore/plugin_datastore_mysql.c
+++ b/src/datastore/plugin_datastore_mysql.c
@@ -77,7 +77,7 @@
77 * Thats it. Note that .my.cnf file is a security risk unless its on 77 * Thats it. Note that .my.cnf file is a security risk unless its on
78 * a safe partition etc. The $HOME/.my.cnf can of course be a symbolic 78 * a safe partition etc. The $HOME/.my.cnf can of course be a symbolic
79 * link. Even greater security risk can be achieved by setting no 79 * link. Even greater security risk can be achieved by setting no
80 * password for $USER. Luckily $USER has only priviledges to mess 80 * password for $USER. Luckily $USER has only privileges to mess
81 * up GNUnet's tables, nothing else (unless you give them more, 81 * up GNUnet's tables, nothing else (unless you give them more,
82 * of course).<p> 82 * of course).<p>
83 * 83 *
diff --git a/src/dns/gnunet-helper-dns.c b/src/dns/gnunet-helper-dns.c
index 85c72579d..e837d81c6 100644
--- a/src/dns/gnunet-helper-dns.c
+++ b/src/dns/gnunet-helper-dns.c
@@ -499,7 +499,7 @@ set_address4(const char *dev, const char *address, const char *mask)
499 499
500/** 500/**
501 * Start forwarding to and from the tunnel. This function runs with 501 * Start forwarding to and from the tunnel. This function runs with
502 * "reduced" priviledges (saved UID is still 0, but effective UID is 502 * "reduced" privileges (saved UID is still 0, but effective UID is
503 * the real user ID). 503 * the real user ID).
504 * 504 *
505 * @param fd_tun tunnel FD 505 * @param fd_tun tunnel FD
@@ -728,7 +728,7 @@ PROCESS_BUFFER:
728 * 25-39 failed to drop privs and then failed to undo some changes to routing table 728 * 25-39 failed to drop privs and then failed to undo some changes to routing table
729 * 40 failed to regain privs 729 * 40 failed to regain privs
730 * 41-55 failed to regain prisv and then failed to undo some changes to routing table 730 * 41-55 failed to regain prisv and then failed to undo some changes to routing table
731 * 254 insufficient priviledges 731 * 254 insufficient privileges
732 * 255 failed to handle kill signal properly 732 * 255 failed to handle kill signal properly
733 */ 733 */
734int 734int
diff --git a/src/gns/gnunet-gns.c b/src/gns/gnunet-gns.c
index 352ccce04..5f4061f7d 100644
--- a/src/gns/gnunet-gns.c
+++ b/src/gns/gnunet-gns.c
@@ -90,24 +90,24 @@ static int global_ret;
90 * @param cls unused 90 * @param cls unused
91 */ 91 */
92static void 92static void
93do_shutdown(void *cls) 93do_shutdown (void *cls)
94{ 94{
95 (void)cls; 95 (void) cls;
96 if (NULL != to_task) 96 if (NULL != to_task)
97 { 97 {
98 GNUNET_SCHEDULER_cancel(to_task); 98 GNUNET_SCHEDULER_cancel (to_task);
99 to_task = NULL; 99 to_task = NULL;
100 } 100 }
101 if (NULL != lr) 101 if (NULL != lr)
102 { 102 {
103 GNUNET_GNS_lookup_with_tld_cancel(lr); 103 GNUNET_GNS_lookup_with_tld_cancel (lr);
104 lr = NULL; 104 lr = NULL;
105 } 105 }
106 if (NULL != gns) 106 if (NULL != gns)
107 { 107 {
108 GNUNET_GNS_disconnect(gns); 108 GNUNET_GNS_disconnect (gns);
109 gns = NULL; 109 gns = NULL;
110 } 110 }
111} 111}
112 112
113/** 113/**
@@ -116,11 +116,11 @@ do_shutdown(void *cls)
116 * @param cls unused 116 * @param cls unused
117 */ 117 */
118static void 118static void
119do_timeout(void* cls) 119do_timeout (void*cls)
120{ 120{
121 to_task = NULL; 121 to_task = NULL;
122 global_ret = 3; //Timeout 122 global_ret = 3; // Timeout
123 GNUNET_SCHEDULER_shutdown(); 123 GNUNET_SCHEDULER_shutdown ();
124} 124}
125 125
126/** 126/**
@@ -132,10 +132,10 @@ do_timeout(void* cls)
132 * @param rd array of @a rd_count records with the results 132 * @param rd array of @a rd_count records with the results
133 */ 133 */
134static void 134static void
135process_lookup_result(void *cls, 135process_lookup_result (void *cls,
136 int was_gns, 136 int was_gns,
137 uint32_t rd_count, 137 uint32_t rd_count,
138 const struct GNUNET_GNSRECORD_Data *rd) 138 const struct GNUNET_GNSRECORD_Data *rd)
139{ 139{
140 const char *name = cls; 140 const char *name = cls;
141 const char *typename; 141 const char *typename;
@@ -143,41 +143,41 @@ process_lookup_result(void *cls,
143 143
144 lr = NULL; 144 lr = NULL;
145 if (GNUNET_NO == was_gns) 145 if (GNUNET_NO == was_gns)
146 { 146 {
147 global_ret = 4; /* not for GNS */ 147 global_ret = 4; /* not for GNS */
148 GNUNET_SCHEDULER_shutdown(); 148 GNUNET_SCHEDULER_shutdown ();
149 return; 149 return;
150 } 150 }
151 if (!raw) 151 if (! raw)
152 { 152 {
153 if (0 == rd_count) 153 if (0 == rd_count)
154 printf("No results.\n"); 154 printf ("No results.\n");
155 else 155 else
156 printf("%s:\n", name); 156 printf ("%s:\n", name);
157 } 157 }
158 for (uint32_t i = 0; i < rd_count; i++) 158 for (uint32_t i = 0; i < rd_count; i++)
159 {
160 if ((rd[i].record_type != rtype) && (GNUNET_GNSRECORD_TYPE_ANY != rtype))
161 continue;
162 typename = GNUNET_GNSRECORD_number_to_typename (rd[i].record_type);
163 string_val = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
164 rd[i].data,
165 rd[i].data_size);
166 if (NULL == string_val)
159 { 167 {
160 if ((rd[i].record_type != rtype) && (GNUNET_GNSRECORD_TYPE_ANY != rtype)) 168 fprintf (stderr,
161 continue; 169 "Record %u of type %d malformed, skipping\n",
162 typename = GNUNET_GNSRECORD_number_to_typename(rd[i].record_type); 170 (unsigned int) i,
163 string_val = GNUNET_GNSRECORD_value_to_string(rd[i].record_type, 171 (int) rd[i].record_type);
164 rd[i].data, 172 continue;
165 rd[i].data_size);
166 if (NULL == string_val)
167 {
168 fprintf(stderr,
169 "Record %u of type %d malformed, skipping\n",
170 (unsigned int)i,
171 (int)rd[i].record_type);
172 continue;
173 }
174 if (raw)
175 printf("%s\n", string_val);
176 else
177 printf("Got `%s' record: %s\n", typename, string_val);
178 GNUNET_free(string_val);
179 } 173 }
180 GNUNET_SCHEDULER_shutdown(); 174 if (raw)
175 printf ("%s\n", string_val);
176 else
177 printf ("Got `%s' record: %s\n", typename, string_val);
178 GNUNET_free (string_val);
179 }
180 GNUNET_SCHEDULER_shutdown ();
181} 181}
182 182
183 183
@@ -190,53 +190,69 @@ process_lookup_result(void *cls,
190 * @param c configuration 190 * @param c configuration
191 */ 191 */
192static void 192static void
193run(void *cls, 193run (void *cls,
194 char *const *args, 194 char *const *args,
195 const char *cfgfile, 195 const char *cfgfile,
196 const struct GNUNET_CONFIGURATION_Handle *c) 196 const struct GNUNET_CONFIGURATION_Handle *c)
197{ 197{
198 (void)cls; 198 (void) cls;
199 (void)args; 199 (void) args;
200 (void)cfgfile; 200 (void) cfgfile;
201 201
202 cfg = c; 202 cfg = c;
203 to_task = NULL; 203 to_task = NULL;
204 if (GNUNET_OK != GNUNET_DNSPARSER_check_name(lookup_name)) 204 if (GNUNET_OK != GNUNET_DNSPARSER_check_name (lookup_name))
205 { 205 {
206 fprintf(stderr, _("`%s' is not a valid domain name\n"), lookup_name); 206 fprintf (stderr,
207 global_ret = 3; 207 _ ("`%s' is not a valid domain name\n"),
208 return; 208 lookup_name);
209 } 209 global_ret = 3;
210 to_task = GNUNET_SCHEDULER_add_delayed(timeout, &do_timeout, NULL); 210 return;
211 gns = GNUNET_GNS_connect(cfg); 211 }
212 if (GNUNET_YES !=
213 GNUNET_CLIENT_test (cfg,
214 "arm"))
215 {
216 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
217 _ ("Cannot resolve using GNS: GNUnet peer not running\n"));
218 global_ret = 2;
219 return;
220 }
221 to_task = GNUNET_SCHEDULER_add_delayed (timeout,
222 &do_timeout,
223 NULL);
224 gns = GNUNET_GNS_connect (cfg);
212 if (NULL == gns) 225 if (NULL == gns)
213 { 226 {
214 fprintf(stderr, _("Failed to connect to GNS\n")); 227 fprintf (stderr,
215 global_ret = 2; 228 _ ("Failed to connect to GNS\n"));
216 return; 229 global_ret = 2;
217 } 230 return;
218 GNUNET_SCHEDULER_add_shutdown(&do_shutdown, NULL); 231 }
232 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
233 NULL);
219 if (NULL != lookup_type) 234 if (NULL != lookup_type)
220 rtype = GNUNET_GNSRECORD_typename_to_number(lookup_type); 235 rtype = GNUNET_GNSRECORD_typename_to_number (lookup_type);
221 else 236 else
222 rtype = GNUNET_DNSPARSER_TYPE_A; 237 rtype = GNUNET_DNSPARSER_TYPE_A;
223 if (UINT32_MAX == rtype) 238 if (UINT32_MAX == rtype)
224 { 239 {
225 fprintf(stderr, _("Invalid typename specified, assuming `ANY'\n")); 240 fprintf (stderr,
226 rtype = GNUNET_GNSRECORD_TYPE_ANY; 241 _ ("Invalid typename specified, assuming `ANY'\n"));
227 } 242 rtype = GNUNET_GNSRECORD_TYPE_ANY;
228 lr = GNUNET_GNS_lookup_with_tld(gns, 243 }
229 lookup_name, 244 lr = GNUNET_GNS_lookup_with_tld (gns,
230 rtype, 245 lookup_name,
231 GNUNET_GNS_LO_DEFAULT, 246 rtype,
232 &process_lookup_result, 247 GNUNET_GNS_LO_DEFAULT,
233 lookup_name); 248 &process_lookup_result,
249 lookup_name);
234 if (NULL == lr) 250 if (NULL == lr)
235 { 251 {
236 global_ret = 2; 252 global_ret = 2;
237 GNUNET_SCHEDULER_shutdown(); 253 GNUNET_SCHEDULER_shutdown ();
238 return; 254 return;
239 } 255 }
240} 256}
241 257
242 258
@@ -248,48 +264,50 @@ run(void *cls,
248 * @return 0 ok, 1 on error 264 * @return 0 ok, 1 on error
249 */ 265 */
250int 266int
251main(int argc, char *const *argv) 267main (int argc, char *const *argv)
252{ 268{
253 timeout = GNUNET_TIME_UNIT_FOREVER_REL; 269 timeout = GNUNET_TIME_UNIT_FOREVER_REL;
254 struct GNUNET_GETOPT_CommandLineOption options[] = 270 struct GNUNET_GETOPT_CommandLineOption options[] =
255 { GNUNET_GETOPT_option_mandatory( 271 { GNUNET_GETOPT_option_mandatory (
256 GNUNET_GETOPT_option_string('u', 272 GNUNET_GETOPT_option_string ('u',
257 "lookup", 273 "lookup",
258 "NAME", 274 "NAME",
259 gettext_noop( 275 gettext_noop (
260 "Lookup a record for the given name"), 276 "Lookup a record for the given name"),
261 &lookup_name)), 277 &lookup_name)),
262 GNUNET_GETOPT_option_string('t', 278 GNUNET_GETOPT_option_string ('t',
263 "type", 279 "type",
264 "TYPE", 280 "TYPE",
265 gettext_noop( 281 gettext_noop (
266 "Specify the type of the record to lookup"), 282 "Specify the type of the record to lookup"),
267 &lookup_type), 283 &lookup_type),
268 GNUNET_GETOPT_option_relative_time('T', 284 GNUNET_GETOPT_option_relative_time ('T',
269 "timeout", 285 "timeout",
270 "TIMEOUT", 286 "TIMEOUT",
271 gettext_noop( 287 gettext_noop (
272 "Specify a timeout for the lookup"), 288 "Specify a timeout for the lookup"),
273 &timeout), 289 &timeout),
274 GNUNET_GETOPT_option_flag('r', 290 GNUNET_GETOPT_option_flag ('r',
275 "raw", 291 "raw",
276 gettext_noop("No unneeded output"), 292 gettext_noop ("No unneeded output"),
277 &raw), 293 &raw),
278 GNUNET_GETOPT_OPTION_END }; 294 GNUNET_GETOPT_OPTION_END };
279 int ret; 295 int ret;
280 296
281 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args(argc, argv, &argc, &argv)) 297 if (GNUNET_OK !=
298 GNUNET_STRINGS_get_utf8_args (argc, argv,
299 &argc, &argv))
282 return 2; 300 return 2;
283 301
284 GNUNET_log_setup("gnunet-gns", "WARNING", NULL); 302 GNUNET_log_setup ("gnunet-gns", "WARNING", NULL);
285 ret = GNUNET_PROGRAM_run(argc, 303 ret = GNUNET_PROGRAM_run (argc,
286 argv, 304 argv,
287 "gnunet-gns", 305 "gnunet-gns",
288 _("GNUnet GNS resolver tool"), 306 _ ("GNUnet GNS resolver tool"),
289 options, 307 options,
290 &run, 308 &run,
291 NULL); 309 NULL);
292 GNUNET_free((void *)argv); 310 GNUNET_free ((void *) argv);
293 if (GNUNET_OK != ret) 311 if (GNUNET_OK != ret)
294 return 1; 312 return 1;
295 return global_ret; 313 return global_ret;
diff --git a/src/include/gnunet_arm_service.h b/src/include/gnunet_arm_service.h
index faf89128f..32355a3e5 100644
--- a/src/include/gnunet_arm_service.h
+++ b/src/include/gnunet_arm_service.h
@@ -70,7 +70,7 @@ enum GNUNET_ARM_RequestStatus {
70/** 70/**
71 * Statuses of services. 71 * Statuses of services.
72 */ 72 */
73enum GNUNET_ARM_ServiceStatus { 73enum GNUNET_ARM_ServiceMonitorStatus {
74 /** 74 /**
75 * Dummy message. 75 * Dummy message.
76 */ 76 */
@@ -150,6 +150,78 @@ enum GNUNET_ARM_Result {
150 150
151 151
152/** 152/**
153 * Status of a service managed by ARM.
154 */
155enum GNUNET_ARM_ServiceStatus
156{
157 /**
158 * Service is stopped.
159 */
160 GNUNET_ARM_SERVICE_STATUS_STOPPED = 0,
161
162 /**
163 * Service has been started and is currently running.
164 */
165 GNUNET_ARM_SERVICE_STATUS_STARTED = 1,
166
167 /**
168 * The service has previously failed, and
169 * will be restarted.
170 */
171 GNUNET_ARM_SERVICE_STATUS_FAILED = 2,
172
173 /**
174 * The service was started, but then exited normally.
175 */
176 GNUNET_ARM_SERVICE_STATUS_FINISHED = 3,
177
178 /**
179 * The service was started, and we're currently waiting
180 * for it to be stopped.
181 */
182 GNUNET_ARM_SERVICE_STATUS_STOPPING = 4,
183};
184
185
186/**
187 * Information about a service managed by ARM.
188 */
189struct GNUNET_ARM_ServiceInfo
190{
191 /**
192 * The current status of the service.
193 */
194 enum GNUNET_ARM_ServiceStatus status;
195
196 /**
197 * The name of the service.
198 */
199 const char *name;
200
201 /**
202 * The binary used to execute the service.
203 */
204 const char *binary;
205
206 /**
207 * Time when the sevice will be restarted, if applicable
208 * to the current status.
209 */
210 struct GNUNET_TIME_Absolute restart_at;
211
212 /**
213 * Time when the sevice was first started, if applicable.
214 */
215 struct GNUNET_TIME_Absolute last_started_at;
216
217 /**
218 * Last process exit status.
219 */
220 int last_exit_status;
221};
222
223
224/**
153 * Handle for interacting with ARM. 225 * Handle for interacting with ARM.
154 */ 226 */
155struct GNUNET_ARM_Handle; 227struct GNUNET_ARM_Handle;
@@ -197,13 +269,13 @@ typedef void
197 * @param cls closure 269 * @param cls closure
198 * @param rs status of the request 270 * @param rs status of the request
199 * @param count number of strings in the list 271 * @param count number of strings in the list
200 * @param list list of running services 272 * @param list list of services managed by arm
201 */ 273 */
202typedef void 274typedef void
203(*GNUNET_ARM_ServiceListCallback) (void *cls, 275(*GNUNET_ARM_ServiceListCallback) (void *cls,
204 enum GNUNET_ARM_RequestStatus rs, 276 enum GNUNET_ARM_RequestStatus rs,
205 unsigned int count, 277 unsigned int count,
206 const char *const*list); 278 const struct GNUNET_ARM_ServiceInfo *list);
207 279
208 280
209/** 281/**
@@ -309,9 +381,9 @@ struct GNUNET_ARM_MonitorHandle;
309 * @param status status of the service 381 * @param status status of the service
310 */ 382 */
311typedef void 383typedef void
312(*GNUNET_ARM_ServiceStatusCallback) (void *cls, 384(*GNUNET_ARM_ServiceMonitorCallback) (void *cls,
313 const char *service, 385 const char *service,
314 enum GNUNET_ARM_ServiceStatus status); 386 enum GNUNET_ARM_ServiceMonitorStatus status);
315 387
316 388
317/** 389/**
@@ -327,7 +399,7 @@ typedef void
327 */ 399 */
328struct GNUNET_ARM_MonitorHandle * 400struct GNUNET_ARM_MonitorHandle *
329GNUNET_ARM_monitor_start(const struct GNUNET_CONFIGURATION_Handle *cfg, 401GNUNET_ARM_monitor_start(const struct GNUNET_CONFIGURATION_Handle *cfg,
330 GNUNET_ARM_ServiceStatusCallback cont, 402 GNUNET_ARM_ServiceMonitorCallback cont,
331 void *cont_cls); 403 void *cont_cls);
332 404
333 405
diff --git a/src/include/gnunet_client_lib.h b/src/include/gnunet_client_lib.h
index 8e4984124..9fc52724c 100644
--- a/src/include/gnunet_client_lib.h
+++ b/src/include/gnunet_client_lib.h
@@ -47,6 +47,23 @@ extern "C"
47 47
48 48
49/** 49/**
50 * Test if the port or UNIXPATH of the given @a service_name
51 * is in use and thus (most likely) the respective service is up.
52 *
53 * @param cfg our configuration
54 * @param service_name name of the service to connect to
55 * @return #GNUNET_YES if the service is (likely) up (or running remotely),
56 * #GNUNET_NO if the service is (definitively) down,
57 * #GNUNET_SYSERR if the configuration does not give us
58 * the necessary information about the service, or if
59 * we could not check (i.e. socket() failed)
60 */
61int
62GNUNET_CLIENT_test (const struct GNUNET_CONFIGURATION_Handle *cfg,
63 const char *service_name);
64
65
66/**
50 * Create a message queue to connect to a GNUnet service. 67 * Create a message queue to connect to a GNUnet service.
51 * If handlers are specfied, receive messages from the connection. 68 * If handlers are specfied, receive messages from the connection.
52 * 69 *
@@ -57,11 +74,11 @@ extern "C"
57 * @return the message queue, NULL on error 74 * @return the message queue, NULL on error
58 */ 75 */
59struct GNUNET_MQ_Handle * 76struct GNUNET_MQ_Handle *
60GNUNET_CLIENT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, 77GNUNET_CLIENT_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
61 const char *service_name, 78 const char *service_name,
62 const struct GNUNET_MQ_MessageHandler *handlers, 79 const struct GNUNET_MQ_MessageHandler *handlers,
63 GNUNET_MQ_ErrorHandler error_handler, 80 GNUNET_MQ_ErrorHandler error_handler,
64 void *error_handler_cls); 81 void *error_handler_cls);
65 82
66 83
67#if 0 /* keep Emacsens' auto-indent happy */ 84#if 0 /* keep Emacsens' auto-indent happy */
diff --git a/src/include/gnunet_disk_lib.h b/src/include/gnunet_disk_lib.h
index d1e1e0333..9376a1059 100644
--- a/src/include/gnunet_disk_lib.h
+++ b/src/include/gnunet_disk_lib.h
@@ -38,7 +38,8 @@ struct GNUNET_DISK_PipeHandle;
38/** 38/**
39 * Type of a handle. 39 * Type of a handle.
40 */ 40 */
41enum GNUNET_FILE_Type { 41enum GNUNET_FILE_Type
42{
42 /** 43 /**
43 * Handle represents an event. 44 * Handle represents an event.
44 */ 45 */
@@ -58,7 +59,8 @@ enum GNUNET_FILE_Type {
58/** 59/**
59 * Handle used to access files (and pipes). 60 * Handle used to access files (and pipes).
60 */ 61 */
61struct GNUNET_DISK_FileHandle { 62struct GNUNET_DISK_FileHandle
63{
62 /** 64 /**
63 * File handle on Unix-like systems. 65 * File handle on Unix-like systems.
64 */ 66 */
@@ -86,7 +88,8 @@ extern "C"
86/** 88/**
87 * Specifies how a file should be opened. 89 * Specifies how a file should be opened.
88 */ 90 */
89enum GNUNET_DISK_OpenFlags { 91enum GNUNET_DISK_OpenFlags
92{
90 /** 93 /**
91 * Open the file for reading 94 * Open the file for reading
92 */ 95 */
@@ -126,7 +129,8 @@ enum GNUNET_DISK_OpenFlags {
126/** 129/**
127 * Specifies what type of memory map is desired. 130 * Specifies what type of memory map is desired.
128 */ 131 */
129enum GNUNET_DISK_MapType { 132enum GNUNET_DISK_MapType
133{
130 /** 134 /**
131 * Read-only memory map. 135 * Read-only memory map.
132 */ 136 */
@@ -147,7 +151,8 @@ enum GNUNET_DISK_MapType {
147/** 151/**
148 * File access permissions, UNIX-style. 152 * File access permissions, UNIX-style.
149 */ 153 */
150enum GNUNET_DISK_AccessPermissions { 154enum GNUNET_DISK_AccessPermissions
155{
151 /** 156 /**
152 * Nobody is allowed to do anything to the file. 157 * Nobody is allowed to do anything to the file.
153 */ 158 */
@@ -204,7 +209,8 @@ enum GNUNET_DISK_AccessPermissions {
204 * Constants for specifying how to seek. Do not change values or order, 209 * Constants for specifying how to seek. Do not change values or order,
205 * some of the code depends on the specific numeric values! 210 * some of the code depends on the specific numeric values!
206 */ 211 */
207enum GNUNET_DISK_Seek { 212enum GNUNET_DISK_Seek
213{
208 /** 214 /**
209 * Seek an absolute position (from the start of the file). 215 * Seek an absolute position (from the start of the file).
210 */ 216 */
@@ -225,7 +231,8 @@ enum GNUNET_DISK_Seek {
225/** 231/**
226 * Enumeration identifying the two ends of a pipe. 232 * Enumeration identifying the two ends of a pipe.
227 */ 233 */
228enum GNUNET_DISK_PipeEnd { 234enum GNUNET_DISK_PipeEnd
235{
229 /** 236 /**
230 * The reading-end of a pipe. 237 * The reading-end of a pipe.
231 */ 238 */
@@ -245,7 +252,7 @@ enum GNUNET_DISK_PipeEnd {
245 * @return #GNUNET_YES if invalid, #GNUNET_NO if valid 252 * @return #GNUNET_YES if invalid, #GNUNET_NO if valid
246 */ 253 */
247int 254int
248GNUNET_DISK_handle_invalid(const struct GNUNET_DISK_FileHandle *h); 255GNUNET_DISK_handle_invalid (const struct GNUNET_DISK_FileHandle *h);
249 256
250 257
251/** 258/**
@@ -257,7 +264,7 @@ GNUNET_DISK_handle_invalid(const struct GNUNET_DISK_FileHandle *h);
257 * else (will print an error message in that case, too). 264 * else (will print an error message in that case, too).
258 */ 265 */
259int 266int
260GNUNET_DISK_file_test(const char *fil); 267GNUNET_DISK_file_test (const char *fil);
261 268
262 269
263/** 270/**
@@ -268,7 +275,7 @@ GNUNET_DISK_file_test(const char *fil);
268 * @param fil name of the file to back up 275 * @param fil name of the file to back up
269 */ 276 */
270void 277void
271GNUNET_DISK_file_backup(const char *fil); 278GNUNET_DISK_file_backup (const char *fil);
272 279
273 280
274/** 281/**
@@ -279,8 +286,8 @@ GNUNET_DISK_file_backup(const char *fil);
279 * @return the new position on success, GNUNET_SYSERR otherwise 286 * @return the new position on success, GNUNET_SYSERR otherwise
280 */ 287 */
281off_t 288off_t
282GNUNET_DISK_file_seek(const struct GNUNET_DISK_FileHandle *h, off_t offset, 289GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle *h, off_t offset,
283 enum GNUNET_DISK_Seek whence); 290 enum GNUNET_DISK_Seek whence);
284 291
285 292
286/** 293/**
@@ -298,10 +305,10 @@ GNUNET_DISK_file_seek(const struct GNUNET_DISK_FileHandle *h, off_t offset,
298 * @return #GNUNET_SYSERR on error, #GNUNET_OK on success 305 * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
299 */ 306 */
300int 307int
301GNUNET_DISK_file_size(const char *filename, 308GNUNET_DISK_file_size (const char *filename,
302 uint64_t *size, 309 uint64_t *size,
303 int include_symbolic_links, 310 int include_symbolic_links,
304 int single_file_mode); 311 int single_file_mode);
305 312
306 313
307/** 314/**
@@ -320,9 +327,9 @@ GNUNET_DISK_file_size(const char *filename,
320 * @return #GNUNET_OK on success 327 * @return #GNUNET_OK on success
321 */ 328 */
322int 329int
323GNUNET_DISK_file_get_identifiers(const char *filename, 330GNUNET_DISK_file_get_identifiers (const char *filename,
324 uint64_t *dev, 331 uint64_t *dev,
325 uint64_t *ino); 332 uint64_t *ino);
326 333
327 334
328/** 335/**
@@ -337,7 +344,7 @@ GNUNET_DISK_file_get_identifiers(const char *filename,
337 * file on disk in directory for temporary files 344 * file on disk in directory for temporary files
338 */ 345 */
339char * 346char *
340GNUNET_DISK_mktemp(const char *t); 347GNUNET_DISK_mktemp (const char *t);
341 348
342 349
343/** 350/**
@@ -350,7 +357,7 @@ GNUNET_DISK_mktemp(const char *t);
350 * @return NULL on error, otherwise name of freshly created directory 357 * @return NULL on error, otherwise name of freshly created directory
351 */ 358 */
352char * 359char *
353GNUNET_DISK_mkdtemp(const char *t); 360GNUNET_DISK_mkdtemp (const char *t);
354 361
355 362
356/** 363/**
@@ -366,9 +373,9 @@ GNUNET_DISK_mkdtemp(const char *t);
366 * @return IO handle on success, NULL on error 373 * @return IO handle on success, NULL on error
367 */ 374 */
368struct GNUNET_DISK_FileHandle * 375struct GNUNET_DISK_FileHandle *
369GNUNET_DISK_file_open(const char *fn, 376GNUNET_DISK_file_open (const char *fn,
370 enum GNUNET_DISK_OpenFlags flags, 377 enum GNUNET_DISK_OpenFlags flags,
371 enum GNUNET_DISK_AccessPermissions perm); 378 enum GNUNET_DISK_AccessPermissions perm);
372 379
373 380
374/** 381/**
@@ -379,8 +386,8 @@ GNUNET_DISK_file_open(const char *fn,
379 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 386 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
380 */ 387 */
381int 388int
382GNUNET_DISK_file_handle_size(struct GNUNET_DISK_FileHandle *fh, 389GNUNET_DISK_file_handle_size (struct GNUNET_DISK_FileHandle *fh,
383 off_t *size); 390 off_t *size);
384 391
385 392
386/** 393/**
@@ -393,10 +400,10 @@ GNUNET_DISK_file_handle_size(struct GNUNET_DISK_FileHandle *fh,
393 * @return handle to the new pipe, NULL on error 400 * @return handle to the new pipe, NULL on error
394 */ 401 */
395struct GNUNET_DISK_PipeHandle * 402struct GNUNET_DISK_PipeHandle *
396GNUNET_DISK_pipe(int blocking_read, 403GNUNET_DISK_pipe (int blocking_read,
397 int blocking_write, 404 int blocking_write,
398 int inherit_read, 405 int inherit_read,
399 int inherit_write); 406 int inherit_write);
400 407
401 408
402/** 409/**
@@ -410,9 +417,9 @@ GNUNET_DISK_pipe(int blocking_read,
410 * @return handle to the new pipe, NULL on error 417 * @return handle to the new pipe, NULL on error
411 */ 418 */
412struct GNUNET_DISK_PipeHandle * 419struct GNUNET_DISK_PipeHandle *
413GNUNET_DISK_pipe_from_fd(int blocking_read, 420GNUNET_DISK_pipe_from_fd (int blocking_read,
414 int blocking_write, 421 int blocking_write,
415 int fd[2]); 422 int fd[2]);
416 423
417 424
418/** 425/**
@@ -421,7 +428,7 @@ GNUNET_DISK_pipe_from_fd(int blocking_read,
421 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise 428 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
422 */ 429 */
423int 430int
424GNUNET_DISK_pipe_close(struct GNUNET_DISK_PipeHandle *p); 431GNUNET_DISK_pipe_close (struct GNUNET_DISK_PipeHandle *p);
425 432
426 433
427/** 434/**
@@ -432,8 +439,8 @@ GNUNET_DISK_pipe_close(struct GNUNET_DISK_PipeHandle *p);
432 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise 439 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
433 */ 440 */
434int 441int
435GNUNET_DISK_pipe_close_end(struct GNUNET_DISK_PipeHandle *p, 442GNUNET_DISK_pipe_close_end (struct GNUNET_DISK_PipeHandle *p,
436 enum GNUNET_DISK_PipeEnd end); 443 enum GNUNET_DISK_PipeEnd end);
437 444
438 445
439/** 446/**
@@ -449,8 +456,8 @@ GNUNET_DISK_pipe_close_end(struct GNUNET_DISK_PipeHandle *p,
449 * (or if that end is not present or is closed). 456 * (or if that end is not present or is closed).
450 */ 457 */
451struct GNUNET_DISK_FileHandle * 458struct GNUNET_DISK_FileHandle *
452GNUNET_DISK_pipe_detach_end(struct GNUNET_DISK_PipeHandle *p, 459GNUNET_DISK_pipe_detach_end (struct GNUNET_DISK_PipeHandle *p,
453 enum GNUNET_DISK_PipeEnd end); 460 enum GNUNET_DISK_PipeEnd end);
454 461
455/** 462/**
456 * Close an open file. 463 * Close an open file.
@@ -459,7 +466,7 @@ GNUNET_DISK_pipe_detach_end(struct GNUNET_DISK_PipeHandle *p,
459 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise 466 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
460 */ 467 */
461int 468int
462GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h); 469GNUNET_DISK_file_close (struct GNUNET_DISK_FileHandle *h);
463 470
464 471
465/** 472/**
@@ -470,8 +477,8 @@ GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h);
470 * @return handle for the respective end 477 * @return handle for the respective end
471 */ 478 */
472const struct GNUNET_DISK_FileHandle * 479const struct GNUNET_DISK_FileHandle *
473GNUNET_DISK_pipe_handle(const struct GNUNET_DISK_PipeHandle *p, 480GNUNET_DISK_pipe_handle (const struct GNUNET_DISK_PipeHandle *p,
474 enum GNUNET_DISK_PipeEnd n); 481 enum GNUNET_DISK_PipeEnd n);
475 482
476/** 483/**
477 * Update POSIX permissions mask of a file on disk. If both argumets 484 * Update POSIX permissions mask of a file on disk. If both argumets
@@ -483,9 +490,9 @@ GNUNET_DISK_pipe_handle(const struct GNUNET_DISK_PipeHandle *p,
483 * @param require_gid_match #GNUNET_YES means 770 unless @a require_uid_match is set 490 * @param require_gid_match #GNUNET_YES means 770 unless @a require_uid_match is set
484 */ 491 */
485void 492void
486GNUNET_DISK_fix_permissions(const char *fn, 493GNUNET_DISK_fix_permissions (const char *fn,
487 int require_uid_match, 494 int require_uid_match,
488 int require_gid_match); 495 int require_gid_match);
489 496
490 497
491/** 498/**
@@ -495,7 +502,7 @@ GNUNET_DISK_fix_permissions(const char *fn,
495 * @return file handle corresponding to the descriptor 502 * @return file handle corresponding to the descriptor
496 */ 503 */
497struct GNUNET_DISK_FileHandle * 504struct GNUNET_DISK_FileHandle *
498GNUNET_DISK_get_handle_from_int_fd(int fno); 505GNUNET_DISK_get_handle_from_int_fd (int fno);
499 506
500 507
501/** 508/**
@@ -505,7 +512,7 @@ GNUNET_DISK_get_handle_from_int_fd(int fno);
505 * @return file handle corresponding to the descriptor 512 * @return file handle corresponding to the descriptor
506 */ 513 */
507struct GNUNET_DISK_FileHandle * 514struct GNUNET_DISK_FileHandle *
508GNUNET_DISK_get_handle_from_native(FILE *fd); 515GNUNET_DISK_get_handle_from_native (FILE *fd);
509 516
510 517
511/** 518/**
@@ -517,9 +524,9 @@ GNUNET_DISK_get_handle_from_native(FILE *fd);
517 * @return the number of bytes read on success, #GNUNET_SYSERR on failure 524 * @return the number of bytes read on success, #GNUNET_SYSERR on failure
518 */ 525 */
519ssize_t 526ssize_t
520GNUNET_DISK_file_read(const struct GNUNET_DISK_FileHandle *h, 527GNUNET_DISK_file_read (const struct GNUNET_DISK_FileHandle *h,
521 void *result, 528 void *result,
522 size_t len); 529 size_t len);
523 530
524 531
525/** 532/**
@@ -533,9 +540,9 @@ GNUNET_DISK_file_read(const struct GNUNET_DISK_FileHandle *h,
533 * @return the number of bytes read on success, #GNUNET_SYSERR on failure 540 * @return the number of bytes read on success, #GNUNET_SYSERR on failure
534 */ 541 */
535ssize_t 542ssize_t
536GNUNET_DISK_file_read_non_blocking(const struct GNUNET_DISK_FileHandle * h, 543GNUNET_DISK_file_read_non_blocking (const struct GNUNET_DISK_FileHandle *h,
537 void *result, 544 void *result,
538 size_t len); 545 size_t len);
539 546
540 547
541/** 548/**
@@ -547,9 +554,9 @@ GNUNET_DISK_file_read_non_blocking(const struct GNUNET_DISK_FileHandle * h,
547 * @return number of bytes read, #GNUNET_SYSERR on failure 554 * @return number of bytes read, #GNUNET_SYSERR on failure
548 */ 555 */
549ssize_t 556ssize_t
550GNUNET_DISK_fn_read(const char *fn, 557GNUNET_DISK_fn_read (const char *fn,
551 void *result, 558 void *result,
552 size_t len); 559 size_t len);
553 560
554 561
555/** 562/**
@@ -561,9 +568,9 @@ GNUNET_DISK_fn_read(const char *fn,
561 * @return number of bytes written on success, #GNUNET_SYSERR on error 568 * @return number of bytes written on success, #GNUNET_SYSERR on error
562 */ 569 */
563ssize_t 570ssize_t
564GNUNET_DISK_file_write(const struct GNUNET_DISK_FileHandle *h, 571GNUNET_DISK_file_write (const struct GNUNET_DISK_FileHandle *h,
565 const void *buffer, 572 const void *buffer,
566 size_t n); 573 size_t n);
567 574
568 575
569/** 576/**
@@ -575,9 +582,9 @@ GNUNET_DISK_file_write(const struct GNUNET_DISK_FileHandle *h,
575 * @return number of bytes written on success, #GNUNET_SYSERR on error 582 * @return number of bytes written on success, #GNUNET_SYSERR on error
576 */ 583 */
577ssize_t 584ssize_t
578GNUNET_DISK_file_write_blocking(const struct GNUNET_DISK_FileHandle *h, 585GNUNET_DISK_file_write_blocking (const struct GNUNET_DISK_FileHandle *h,
579 const void *buffer, 586 const void *buffer,
580 size_t n); 587 size_t n);
581 588
582 589
583/** 590/**
@@ -591,10 +598,10 @@ GNUNET_DISK_file_write_blocking(const struct GNUNET_DISK_FileHandle *h,
591 * @return number of bytes written on success, #GNUNET_SYSERR on error 598 * @return number of bytes written on success, #GNUNET_SYSERR on error
592 */ 599 */
593ssize_t 600ssize_t
594GNUNET_DISK_fn_write(const char *fn, 601GNUNET_DISK_fn_write (const char *fn,
595 const void *buffer, 602 const void *buffer,
596 size_t n, 603 size_t n,
597 enum GNUNET_DISK_AccessPermissions mode); 604 enum GNUNET_DISK_AccessPermissions mode);
598 605
599 606
600/** 607/**
@@ -605,8 +612,8 @@ GNUNET_DISK_fn_write(const char *fn,
605 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 612 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
606 */ 613 */
607int 614int
608GNUNET_DISK_file_copy(const char *src, 615GNUNET_DISK_file_copy (const char *src,
609 const char *dst); 616 const char *dst);
610 617
611 618
612/** 619/**
@@ -618,9 +625,9 @@ GNUNET_DISK_file_copy(const char *src,
618 * @return the number of files found, -1 on error 625 * @return the number of files found, -1 on error
619 */ 626 */
620int 627int
621GNUNET_DISK_directory_scan(const char *dir_name, 628GNUNET_DISK_directory_scan (const char *dir_name,
622 GNUNET_FileNameCallback callback, 629 GNUNET_FileNameCallback callback,
623 void *callback_cls); 630 void *callback_cls);
624 631
625 632
626/** 633/**
@@ -632,7 +639,7 @@ GNUNET_DISK_directory_scan(const char *dir_name,
632 * #GNUNET_NO if directory exists but is not writeable 639 * #GNUNET_NO if directory exists but is not writeable
633 */ 640 */
634int 641int
635GNUNET_DISK_directory_create_for_file(const char *filename); 642GNUNET_DISK_directory_create_for_file (const char *filename);
636 643
637 644
638/** 645/**
@@ -648,7 +655,7 @@ GNUNET_DISK_directory_create_for_file(const char *filename);
648 * does not exist or `stat`ed 655 * does not exist or `stat`ed
649 */ 656 */
650int 657int
651GNUNET_DISK_directory_test(const char *fil, int is_readable); 658GNUNET_DISK_directory_test (const char *fil, int is_readable);
652 659
653 660
654/** 661/**
@@ -659,7 +666,7 @@ GNUNET_DISK_directory_test(const char *fil, int is_readable);
659 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 666 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
660 */ 667 */
661int 668int
662GNUNET_DISK_directory_remove(const char *filename); 669GNUNET_DISK_directory_remove (const char *filename);
663 670
664 671
665/** 672/**
@@ -670,8 +677,8 @@ GNUNET_DISK_directory_remove(const char *filename);
670 * @param option option with the dir name to purge 677 * @param option option with the dir name to purge
671 */ 678 */
672void 679void
673GNUNET_DISK_purge_cfg_dir(const char *cfg_filename, 680GNUNET_DISK_purge_cfg_dir (const char *cfg_filename,
674 const char *option); 681 const char *option);
675 682
676 683
677/** 684/**
@@ -681,7 +688,7 @@ GNUNET_DISK_purge_cfg_dir(const char *cfg_filename,
681 * @returns #GNUNET_SYSERR on failure, #GNUNET_OK otherwise 688 * @returns #GNUNET_SYSERR on failure, #GNUNET_OK otherwise
682 */ 689 */
683int 690int
684GNUNET_DISK_directory_create(const char *dir); 691GNUNET_DISK_directory_create (const char *dir);
685 692
686 693
687/** 694/**
@@ -694,9 +701,9 @@ GNUNET_DISK_directory_create(const char *dir);
694 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 701 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
695 */ 702 */
696int 703int
697GNUNET_DISK_file_lock(struct GNUNET_DISK_FileHandle *fh, 704GNUNET_DISK_file_lock (struct GNUNET_DISK_FileHandle *fh,
698 off_t lock_start, 705 off_t lock_start,
699 off_t lock_end, int excl); 706 off_t lock_end, int excl);
700 707
701 708
702/** 709/**
@@ -708,9 +715,9 @@ GNUNET_DISK_file_lock(struct GNUNET_DISK_FileHandle *fh,
708 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 715 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
709 */ 716 */
710int 717int
711GNUNET_DISK_file_unlock(struct GNUNET_DISK_FileHandle *fh, 718GNUNET_DISK_file_unlock (struct GNUNET_DISK_FileHandle *fh,
712 off_t unlock_start, 719 off_t unlock_start,
713 off_t unlock_end); 720 off_t unlock_end);
714 721
715 722
716/** 723/**
@@ -718,7 +725,7 @@ GNUNET_DISK_file_unlock(struct GNUNET_DISK_FileHandle *fh,
718 * @param fn the filename to canonicalize 725 * @param fn the filename to canonicalize
719 */ 726 */
720void 727void
721GNUNET_DISK_filename_canonicalize(char *fn); 728GNUNET_DISK_filename_canonicalize (char *fn);
722 729
723 730
724/** 731/**
@@ -728,8 +735,8 @@ GNUNET_DISK_filename_canonicalize(char *fn);
728 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure 735 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
729 */ 736 */
730int 737int
731GNUNET_DISK_file_change_owner(const char *filename, 738GNUNET_DISK_file_change_owner (const char *filename,
732 const char *user); 739 const char *user);
733 740
734 741
735/** 742/**
@@ -747,10 +754,10 @@ struct GNUNET_DISK_MapHandle;
747 * @return pointer to the mapped memory region, NULL on failure 754 * @return pointer to the mapped memory region, NULL on failure
748 */ 755 */
749void * 756void *
750GNUNET_DISK_file_map(const struct GNUNET_DISK_FileHandle *h, 757GNUNET_DISK_file_map (const struct GNUNET_DISK_FileHandle *h,
751 struct GNUNET_DISK_MapHandle **m, 758 struct GNUNET_DISK_MapHandle **m,
752 enum GNUNET_DISK_MapType access, 759 enum GNUNET_DISK_MapType access,
753 size_t len); 760 size_t len);
754 761
755 762
756/** 763/**
@@ -760,7 +767,7 @@ GNUNET_DISK_file_map(const struct GNUNET_DISK_FileHandle *h,
760 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise 767 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
761 */ 768 */
762int 769int
763GNUNET_DISK_file_unmap(struct GNUNET_DISK_MapHandle *h); 770GNUNET_DISK_file_unmap (struct GNUNET_DISK_MapHandle *h);
764 771
765 772
766/** 773/**
@@ -770,7 +777,7 @@ GNUNET_DISK_file_unmap(struct GNUNET_DISK_MapHandle *h);
770 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise 777 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
771 */ 778 */
772int 779int
773GNUNET_DISK_file_sync(const struct GNUNET_DISK_FileHandle *h); 780GNUNET_DISK_file_sync (const struct GNUNET_DISK_FileHandle *h);
774 781
775 782
776#if 0 /* keep Emacsens' auto-indent happy */ 783#if 0 /* keep Emacsens' auto-indent happy */
diff --git a/src/include/gnunet_os_lib.h b/src/include/gnunet_os_lib.h
index e5bc7146b..e4c0d6cdb 100644
--- a/src/include/gnunet_os_lib.h
+++ b/src/include/gnunet_os_lib.h
@@ -65,7 +65,8 @@ extern "C"
65 * Flags that determine which of the standard streams 65 * Flags that determine which of the standard streams
66 * should be inherited by the child process. 66 * should be inherited by the child process.
67 */ 67 */
68enum GNUNET_OS_InheritStdioFlags { 68enum GNUNET_OS_InheritStdioFlags
69{
69 /** 70 /**
70 * No standard streams should be inherited. 71 * No standard streams should be inherited.
71 */ 72 */
@@ -112,7 +113,8 @@ struct GNUNET_OS_Process;
112/** 113/**
113 * Possible installation paths to request 114 * Possible installation paths to request
114 */ 115 */
115enum GNUNET_OS_InstallationPathKind { 116enum GNUNET_OS_InstallationPathKind
117{
116 /** 118 /**
117 * Return the "PREFIX" directory given to configure. 119 * Return the "PREFIX" directory given to configure.
118 */ 120 */
@@ -166,7 +168,8 @@ enum GNUNET_OS_InstallationPathKind {
166/** 168/**
167 * Process status types 169 * Process status types
168 */ 170 */
169enum GNUNET_OS_ProcessStatusType { 171enum GNUNET_OS_ProcessStatusType
172{
170 /** 173 /**
171 * The process is not known to the OS (or at 174 * The process is not known to the OS (or at
172 * least not one of our children). 175 * least not one of our children).
@@ -199,7 +202,8 @@ enum GNUNET_OS_ProcessStatusType {
199 * Project-specific data used to help the OS subsystem 202 * Project-specific data used to help the OS subsystem
200 * find installation paths. 203 * find installation paths.
201 */ 204 */
202struct GNUNET_OS_ProjectData { 205struct GNUNET_OS_ProjectData
206{
203 /** 207 /**
204 * Name of a library that is installed in the "lib/" directory of 208 * Name of a library that is installed in the "lib/" directory of
205 * the project, such as "libgnunetutil". Used to locate the 209 * the project, such as "libgnunetutil". Used to locate the
@@ -290,14 +294,14 @@ struct GNUNET_OS_ProjectData {
290 * Return default project data used by 'libgnunetutil' for GNUnet. 294 * Return default project data used by 'libgnunetutil' for GNUnet.
291 */ 295 */
292const struct GNUNET_OS_ProjectData * 296const struct GNUNET_OS_ProjectData *
293GNUNET_OS_project_data_default(void); 297GNUNET_OS_project_data_default (void);
294 298
295 299
296/** 300/**
297 * @return current (actual) project data. 301 * @return current (actual) project data.
298 */ 302 */
299const struct GNUNET_OS_ProjectData * 303const struct GNUNET_OS_ProjectData *
300GNUNET_OS_project_data_get(void); 304GNUNET_OS_project_data_get (void);
301 305
302 306
303/** 307/**
@@ -306,7 +310,7 @@ GNUNET_OS_project_data_get(void);
306 * @param pd project data used to determine paths. 310 * @param pd project data used to determine paths.
307 */ 311 */
308void 312void
309GNUNET_OS_init(const struct GNUNET_OS_ProjectData *pd); 313GNUNET_OS_init (const struct GNUNET_OS_ProjectData *pd);
310 314
311 315
312/** 316/**
@@ -318,7 +322,7 @@ GNUNET_OS_init(const struct GNUNET_OS_ProjectData *pd);
318 * @return a pointer to the dir path (to be freed by the caller) 322 * @return a pointer to the dir path (to be freed by the caller)
319 */ 323 */
320char * 324char *
321GNUNET_OS_installation_get_path(enum GNUNET_OS_InstallationPathKind dirkind); 325GNUNET_OS_installation_get_path (enum GNUNET_OS_InstallationPathKind dirkind);
322 326
323 327
324/** 328/**
@@ -330,7 +334,7 @@ GNUNET_OS_installation_get_path(enum GNUNET_OS_InstallationPathKind dirkind);
330 * @return full path to the binary, if possible, otherwise copy of 'progname' 334 * @return full path to the binary, if possible, otherwise copy of 'progname'
331 */ 335 */
332char * 336char *
333GNUNET_OS_get_libexec_binary_path(const char *progname); 337GNUNET_OS_get_libexec_binary_path (const char *progname);
334 338
335 339
336/** 340/**
@@ -346,8 +350,8 @@ GNUNET_OS_get_libexec_binary_path(const char *progname);
346 * otherwise 350 * otherwise
347 */ 351 */
348char * 352char *
349GNUNET_OS_get_suid_binary_path(const struct GNUNET_CONFIGURATION_Handle *cfg, 353GNUNET_OS_get_suid_binary_path (const struct GNUNET_CONFIGURATION_Handle *cfg,
350 const char *progname); 354 const char *progname);
351 355
352 356
353/** 357/**
@@ -379,14 +383,16 @@ typedef int
379 * @param proc_cls closure for @a proc 383 * @param proc_cls closure for @a proc
380 */ 384 */
381void 385void
382GNUNET_OS_network_interfaces_list(GNUNET_OS_NetworkInterfaceProcessor proc, 386GNUNET_OS_network_interfaces_list (GNUNET_OS_NetworkInterfaceProcessor proc,
383 void *proc_cls); 387 void *proc_cls);
384 388
385/** 389/**
386 * @brief Get maximum string length returned by gethostname() 390 * @brief Get maximum string length returned by gethostname()
387 */ 391 */
388#if HAVE_SYSCONF && defined(_SC_HOST_NAME_MAX) 392#if HAVE_SYSCONF && defined(_SC_HOST_NAME_MAX)
389#define GNUNET_OS_get_hostname_max_length() ({ int __sc_tmp = sysconf(_SC_HOST_NAME_MAX); __sc_tmp <= 0 ? 255 : __sc_tmp; }) 393#define GNUNET_OS_get_hostname_max_length() ({ int __sc_tmp = sysconf ( \
394 _SC_HOST_NAME_MAX); __sc_tmp <= \
395 0 ? 255 : __sc_tmp; })
390#elif defined(HOST_NAME_MAX) 396#elif defined(HOST_NAME_MAX)
391#define GNUNET_OS_get_hostname_max_length() HOST_NAME_MAX 397#define GNUNET_OS_get_hostname_max_length() HOST_NAME_MAX
392#else 398#else
@@ -403,7 +409,7 @@ GNUNET_OS_network_interfaces_list(GNUNET_OS_NetworkInterfaceProcessor proc,
403 * @return pointer to the process sturcutre for this process 409 * @return pointer to the process sturcutre for this process
404 */ 410 */
405struct GNUNET_OS_Process * 411struct GNUNET_OS_Process *
406GNUNET_OS_process_current(void); 412GNUNET_OS_process_current (void);
407 413
408 414
409/** 415/**
@@ -414,8 +420,8 @@ GNUNET_OS_process_current(void);
414 * @return 0 on success, -1 on error 420 * @return 0 on success, -1 on error
415 */ 421 */
416int 422int
417GNUNET_OS_process_kill(struct GNUNET_OS_Process *proc, 423GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc,
418 int sig); 424 int sig);
419 425
420 426
421/** 427/**
@@ -424,7 +430,7 @@ GNUNET_OS_process_kill(struct GNUNET_OS_Process *proc,
424 * @param proc pointer to process structure 430 * @param proc pointer to process structure
425 */ 431 */
426void 432void
427GNUNET_OS_process_destroy(struct GNUNET_OS_Process *proc); 433GNUNET_OS_process_destroy (struct GNUNET_OS_Process *proc);
428 434
429 435
430/** 436/**
@@ -435,7 +441,7 @@ GNUNET_OS_process_destroy(struct GNUNET_OS_Process *proc);
435 * @return the current process id 441 * @return the current process id
436 */ 442 */
437pid_t 443pid_t
438GNUNET_OS_process_get_pid(struct GNUNET_OS_Process *proc); 444GNUNET_OS_process_get_pid (struct GNUNET_OS_Process *proc);
439 445
440 446
441/** 447/**
@@ -451,13 +457,13 @@ GNUNET_OS_process_get_pid(struct GNUNET_OS_Process *proc);
451 * @return pointer to process structure of the new process, NULL on error 457 * @return pointer to process structure of the new process, NULL on error
452 */ 458 */
453struct GNUNET_OS_Process * 459struct GNUNET_OS_Process *
454GNUNET_OS_start_process_vap(int pipe_control, 460GNUNET_OS_start_process_vap (int pipe_control,
455 enum GNUNET_OS_InheritStdioFlags std_inheritance, 461 enum GNUNET_OS_InheritStdioFlags std_inheritance,
456 struct GNUNET_DISK_PipeHandle *pipe_stdin, 462 struct GNUNET_DISK_PipeHandle *pipe_stdin,
457 struct GNUNET_DISK_PipeHandle *pipe_stdout, 463 struct GNUNET_DISK_PipeHandle *pipe_stdout,
458 struct GNUNET_DISK_PipeHandle *pipe_stderr, 464 struct GNUNET_DISK_PipeHandle *pipe_stderr,
459 const char *filename, 465 const char *filename,
460 char *const argv[]); 466 char *const argv[]);
461 467
462 468
463/** 469/**
@@ -473,12 +479,12 @@ GNUNET_OS_start_process_vap(int pipe_control,
473 * @return pointer to process structure of the new process, NULL on error 479 * @return pointer to process structure of the new process, NULL on error
474 */ 480 */
475struct GNUNET_OS_Process * 481struct GNUNET_OS_Process *
476GNUNET_OS_start_process(int pipe_control, 482GNUNET_OS_start_process (int pipe_control,
477 enum GNUNET_OS_InheritStdioFlags std_inheritance, 483 enum GNUNET_OS_InheritStdioFlags std_inheritance,
478 struct GNUNET_DISK_PipeHandle *pipe_stdin, 484 struct GNUNET_DISK_PipeHandle *pipe_stdin,
479 struct GNUNET_DISK_PipeHandle *pipe_stdout, 485 struct GNUNET_DISK_PipeHandle *pipe_stdout,
480 struct GNUNET_DISK_PipeHandle *pipe_stderr, 486 struct GNUNET_DISK_PipeHandle *pipe_stderr,
481 const char *filename, ...); 487 const char *filename, ...);
482 488
483 489
484/** 490/**
@@ -494,12 +500,12 @@ GNUNET_OS_start_process(int pipe_control,
494 * @return pointer to process structure of the new process, NULL on error 500 * @return pointer to process structure of the new process, NULL on error
495 */ 501 */
496struct GNUNET_OS_Process * 502struct GNUNET_OS_Process *
497GNUNET_OS_start_process_va(int pipe_control, 503GNUNET_OS_start_process_va (int pipe_control,
498 enum GNUNET_OS_InheritStdioFlags std_inheritance, 504 enum GNUNET_OS_InheritStdioFlags std_inheritance,
499 struct GNUNET_DISK_PipeHandle *pipe_stdin, 505 struct GNUNET_DISK_PipeHandle *pipe_stdin,
500 struct GNUNET_DISK_PipeHandle *pipe_stdout, 506 struct GNUNET_DISK_PipeHandle *pipe_stdout,
501 struct GNUNET_DISK_PipeHandle *pipe_stderr, 507 struct GNUNET_DISK_PipeHandle *pipe_stderr,
502 const char *filename, va_list va); 508 const char *filename, va_list va);
503 509
504/** 510/**
505 * Start a process. 511 * Start a process.
@@ -514,11 +520,11 @@ GNUNET_OS_start_process_va(int pipe_control,
514 * @return pointer to process structure of the new process, NULL on error 520 * @return pointer to process structure of the new process, NULL on error
515 */ 521 */
516struct GNUNET_OS_Process * 522struct GNUNET_OS_Process *
517GNUNET_OS_start_process_v(int pipe_control, 523GNUNET_OS_start_process_v (int pipe_control,
518 enum GNUNET_OS_InheritStdioFlags std_inheritance, 524 enum GNUNET_OS_InheritStdioFlags std_inheritance,
519 const SOCKTYPE *lsocks, 525 const SOCKTYPE *lsocks,
520 const char *filename, 526 const char *filename,
521 char *const argv[]); 527 char *const argv[]);
522 528
523 529
524/** 530/**
@@ -540,10 +546,10 @@ GNUNET_OS_start_process_v(int pipe_control,
540 * @return pointer to process structure of the new process, NULL on error 546 * @return pointer to process structure of the new process, NULL on error
541 */ 547 */
542struct GNUNET_OS_Process * 548struct GNUNET_OS_Process *
543GNUNET_OS_start_process_s(int pipe_control, 549GNUNET_OS_start_process_s (int pipe_control,
544 unsigned int std_inheritance, 550 unsigned int std_inheritance,
545 const SOCKTYPE * lsocks, 551 const SOCKTYPE *lsocks,
546 const char *filename, ...); 552 const char *filename, ...);
547 553
548 554
549/** 555/**
@@ -568,7 +574,7 @@ typedef void
568 * @param cmd handle to the process 574 * @param cmd handle to the process
569 */ 575 */
570void 576void
571GNUNET_OS_command_stop(struct GNUNET_OS_CommandHandle *cmd); 577GNUNET_OS_command_stop (struct GNUNET_OS_CommandHandle *cmd);
572 578
573 579
574/** 580/**
@@ -583,11 +589,11 @@ GNUNET_OS_command_stop(struct GNUNET_OS_CommandHandle *cmd);
583 * @return NULL on error 589 * @return NULL on error
584 */ 590 */
585struct GNUNET_OS_CommandHandle * 591struct GNUNET_OS_CommandHandle *
586GNUNET_OS_command_run(GNUNET_OS_LineProcessor proc, 592GNUNET_OS_command_run (GNUNET_OS_LineProcessor proc,
587 void *proc_cls, 593 void *proc_cls,
588 struct GNUNET_TIME_Relative timeout, 594 struct GNUNET_TIME_Relative timeout,
589 const char *binary, 595 const char *binary,
590 ...); 596 ...);
591 597
592 598
593/** 599/**
@@ -600,9 +606,9 @@ GNUNET_OS_command_run(GNUNET_OS_LineProcessor proc,
600 * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise 606 * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise
601 */ 607 */
602int 608int
603GNUNET_OS_process_status(struct GNUNET_OS_Process *proc, 609GNUNET_OS_process_status (struct GNUNET_OS_Process *proc,
604 enum GNUNET_OS_ProcessStatusType *type, 610 enum GNUNET_OS_ProcessStatusType *type,
605 unsigned long *code); 611 unsigned long *code);
606 612
607 613
608/** 614/**
@@ -616,7 +622,7 @@ GNUNET_OS_process_status(struct GNUNET_OS_Process *proc,
616 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise 622 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
617 */ 623 */
618int 624int
619GNUNET_OS_process_wait(struct GNUNET_OS_Process *proc); 625GNUNET_OS_process_wait (struct GNUNET_OS_Process *proc);
620 626
621 627
622 628
@@ -630,9 +636,9 @@ GNUNET_OS_process_wait(struct GNUNET_OS_Process *proc);
630 * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise 636 * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise
631 */ 637 */
632int 638int
633GNUNET_OS_process_wait_status(struct GNUNET_OS_Process *proc, 639GNUNET_OS_process_wait_status (struct GNUNET_OS_Process *proc,
634 enum GNUNET_OS_ProcessStatusType *type, 640 enum GNUNET_OS_ProcessStatusType *type,
635 unsigned long *code); 641 unsigned long *code);
636 642
637 643
638/** 644/**
@@ -644,7 +650,7 @@ GNUNET_OS_process_wait_status(struct GNUNET_OS_Process *proc,
644 * @param cls closure (unused) 650 * @param cls closure (unused)
645 */ 651 */
646void 652void
647GNUNET_OS_install_parent_control_handler(void *cls); 653GNUNET_OS_install_parent_control_handler (void *cls);
648 654
649 655
650/** 656/**
@@ -665,9 +671,9 @@ GNUNET_OS_install_parent_control_handler(void *cls);
665 * #GNUNET_SYSERR on error (no such binary or not executable) 671 * #GNUNET_SYSERR on error (no such binary or not executable)
666 */ 672 */
667int 673int
668GNUNET_OS_check_helper_binary(const char *binary, 674GNUNET_OS_check_helper_binary (const char *binary,
669 int check_suid, 675 int check_suid,
670 const char *params); 676 const char *params);
671 677
672 678
673#if 0 /* keep Emacsens' auto-indent happy */ 679#if 0 /* keep Emacsens' auto-indent happy */
diff --git a/src/include/gnunet_scheduler_lib.h b/src/include/gnunet_scheduler_lib.h
index 39b16a1b4..da968737e 100644
--- a/src/include/gnunet_scheduler_lib.h
+++ b/src/include/gnunet_scheduler_lib.h
@@ -52,7 +52,8 @@ struct GNUNET_SCHEDULER_Task;
52 * Reasons why the schedule may have triggered 52 * Reasons why the schedule may have triggered
53 * the task now. 53 * the task now.
54 */ 54 */
55enum GNUNET_SCHEDULER_Reason { 55enum GNUNET_SCHEDULER_Reason
56{
56 /** 57 /**
57 * This task is not ready. 58 * This task is not ready.
58 */ 59 */
@@ -99,7 +100,8 @@ enum GNUNET_SCHEDULER_Reason {
99 * Possible events on FDs, used as a bitmask. 100 * Possible events on FDs, used as a bitmask.
100 * Modelled after GPollFD. 101 * Modelled after GPollFD.
101 */ 102 */
102enum GNUNET_SCHEDULER_EventType { 103enum GNUNET_SCHEDULER_EventType
104{
103 /** 105 /**
104 * No event (useful for timeout). 106 * No event (useful for timeout).
105 */ 107 */
@@ -140,7 +142,8 @@ enum GNUNET_SCHEDULER_EventType {
140/** 142/**
141 * Information about an event relating to a file descriptor/socket. 143 * Information about an event relating to a file descriptor/socket.
142 */ 144 */
143struct GNUNET_SCHEDULER_FdInfo { 145struct GNUNET_SCHEDULER_FdInfo
146{
144 /** 147 /**
145 * GNUnet network socket the event is about, matches @a sock, 148 * GNUnet network socket the event is about, matches @a sock,
146 * NULL if this is about a file handle or if no network 149 * NULL if this is about a file handle or if no network
@@ -170,7 +173,8 @@ struct GNUNET_SCHEDULER_FdInfo {
170/** 173/**
171 * Context information passed to each scheduler task. 174 * Context information passed to each scheduler task.
172 */ 175 */
173struct GNUNET_SCHEDULER_TaskContext { 176struct GNUNET_SCHEDULER_TaskContext
177{
174 /** 178 /**
175 * Reason why the task is run now 179 * Reason why the task is run now
176 */ 180 */
@@ -219,8 +223,8 @@ struct GNUNET_SCHEDULER_TaskContext {
219 * @param fdi information about the related FD 223 * @param fdi information about the related FD
220 */ 224 */
221void 225void
222GNUNET_SCHEDULER_task_ready(struct GNUNET_SCHEDULER_Task *task, 226GNUNET_SCHEDULER_task_ready (struct GNUNET_SCHEDULER_Task *task,
223 struct GNUNET_SCHEDULER_FdInfo *fdi); 227 struct GNUNET_SCHEDULER_FdInfo *fdi);
224 228
225 229
226/** 230/**
@@ -250,14 +254,15 @@ struct GNUNET_SCHEDULER_Handle;
250 * if we are done running tasks (yield to block) 254 * if we are done running tasks (yield to block)
251 */ 255 */
252int 256int
253GNUNET_SCHEDULER_do_work(struct GNUNET_SCHEDULER_Handle *sh); 257GNUNET_SCHEDULER_do_work (struct GNUNET_SCHEDULER_Handle *sh);
254 258
255 259
256/** 260/**
257 * API an external event loop has to implement for 261 * API an external event loop has to implement for
258 * #GNUNET_SCHEDULER_driver_init. 262 * #GNUNET_SCHEDULER_driver_init.
259 */ 263 */
260struct GNUNET_SCHEDULER_Driver { 264struct GNUNET_SCHEDULER_Driver
265{
261 /** 266 /**
262 * Closure to pass to the functions in this struct. 267 * Closure to pass to the functions in this struct.
263 */ 268 */
@@ -348,7 +353,7 @@ typedef void
348 * #GNUNET_SCHEDULER_driver_done 353 * #GNUNET_SCHEDULER_driver_done
349 */ 354 */
350struct GNUNET_SCHEDULER_Handle * 355struct GNUNET_SCHEDULER_Handle *
351GNUNET_SCHEDULER_driver_init(const struct GNUNET_SCHEDULER_Driver *driver); 356GNUNET_SCHEDULER_driver_init (const struct GNUNET_SCHEDULER_Driver *driver);
352 357
353 358
354/** 359/**
@@ -366,7 +371,7 @@ GNUNET_SCHEDULER_driver_init(const struct GNUNET_SCHEDULER_Driver *driver);
366 * @param sh the handle returned by #GNUNET_SCHEDULER_driver_init 371 * @param sh the handle returned by #GNUNET_SCHEDULER_driver_init
367 */ 372 */
368void 373void
369GNUNET_SCHEDULER_driver_done(struct GNUNET_SCHEDULER_Handle *sh); 374GNUNET_SCHEDULER_driver_done (struct GNUNET_SCHEDULER_Handle *sh);
370 375
371 376
372/** 377/**
@@ -375,7 +380,7 @@ GNUNET_SCHEDULER_driver_done(struct GNUNET_SCHEDULER_Handle *sh);
375 * @return NULL on error 380 * @return NULL on error
376 */ 381 */
377struct GNUNET_SCHEDULER_Driver * 382struct GNUNET_SCHEDULER_Driver *
378GNUNET_SCHEDULER_driver_select(void); 383GNUNET_SCHEDULER_driver_select (void);
379 384
380 385
381/** 386/**
@@ -412,8 +417,8 @@ typedef int
412 * @param task_cls closure of @a task 417 * @param task_cls closure of @a task
413 */ 418 */
414void 419void
415GNUNET_SCHEDULER_run(GNUNET_SCHEDULER_TaskCallback task, 420GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_TaskCallback task,
416 void *task_cls); 421 void *task_cls);
417 422
418/** 423/**
419 * Initialize and run scheduler. This function will return when all 424 * Initialize and run scheduler. This function will return when all
@@ -427,9 +432,9 @@ GNUNET_SCHEDULER_run(GNUNET_SCHEDULER_TaskCallback task,
427 * @param task_cls closure of @a task 432 * @param task_cls closure of @a task
428 */ 433 */
429void 434void
430GNUNET_SCHEDULER_run_with_optional_signals(int install_signals, 435GNUNET_SCHEDULER_run_with_optional_signals (int install_signals,
431 GNUNET_SCHEDULER_TaskCallback task, 436 GNUNET_SCHEDULER_TaskCallback task,
432 void *task_cls); 437 void *task_cls);
433 438
434 439
435/** 440/**
@@ -439,7 +444,7 @@ GNUNET_SCHEDULER_run_with_optional_signals(int install_signals,
439 * will be delayed until the next shutdown signal. 444 * will be delayed until the next shutdown signal.
440 */ 445 */
441void 446void
442GNUNET_SCHEDULER_shutdown(void); 447GNUNET_SCHEDULER_shutdown (void);
443 448
444 449
445/** 450/**
@@ -454,7 +459,7 @@ GNUNET_SCHEDULER_shutdown(void);
454 * @return number of tasks pending right now 459 * @return number of tasks pending right now
455 */ 460 */
456unsigned int 461unsigned int
457GNUNET_SCHEDULER_get_load(enum GNUNET_SCHEDULER_Priority p); 462GNUNET_SCHEDULER_get_load (enum GNUNET_SCHEDULER_Priority p);
458 463
459 464
460/** 465/**
@@ -464,7 +469,7 @@ GNUNET_SCHEDULER_get_load(enum GNUNET_SCHEDULER_Priority p);
464 * @return task context with information why the current task is run 469 * @return task context with information why the current task is run
465 */ 470 */
466const struct GNUNET_SCHEDULER_TaskContext * 471const struct GNUNET_SCHEDULER_TaskContext *
467GNUNET_SCHEDULER_get_task_context(void); 472GNUNET_SCHEDULER_get_task_context (void);
468 473
469 474
470/** 475/**
@@ -480,7 +485,7 @@ GNUNET_SCHEDULER_get_task_context(void);
480 * @return original closure of the task 485 * @return original closure of the task
481 */ 486 */
482void * 487void *
483GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task); 488GNUNET_SCHEDULER_cancel (struct GNUNET_SCHEDULER_Task *task);
484 489
485 490
486/** 491/**
@@ -494,10 +499,13 @@ GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task);
494 * @param priority priority to use for the task 499 * @param priority priority to use for the task
495 */ 500 */
496void 501void
497GNUNET_SCHEDULER_add_with_reason_and_priority(GNUNET_SCHEDULER_TaskCallback task, 502GNUNET_SCHEDULER_add_with_reason_and_priority (GNUNET_SCHEDULER_TaskCallback
498 void *task_cls, 503 task,
499 enum GNUNET_SCHEDULER_Reason reason, 504 void *task_cls,
500 enum GNUNET_SCHEDULER_Priority priority); 505 enum GNUNET_SCHEDULER_Reason
506 reason,
507 enum GNUNET_SCHEDULER_Priority
508 priority);
501 509
502 510
503/** 511/**
@@ -510,9 +518,9 @@ GNUNET_SCHEDULER_add_with_reason_and_priority(GNUNET_SCHEDULER_TaskCallback task
510 * only valid until @a task is started! 518 * only valid until @a task is started!
511 */ 519 */
512struct GNUNET_SCHEDULER_Task * 520struct GNUNET_SCHEDULER_Task *
513GNUNET_SCHEDULER_add_with_priority(enum GNUNET_SCHEDULER_Priority prio, 521GNUNET_SCHEDULER_add_with_priority (enum GNUNET_SCHEDULER_Priority prio,
514 GNUNET_SCHEDULER_TaskCallback task, 522 GNUNET_SCHEDULER_TaskCallback task,
515 void *task_cls); 523 void *task_cls);
516 524
517 525
518/** 526/**
@@ -531,8 +539,8 @@ GNUNET_SCHEDULER_add_with_priority(enum GNUNET_SCHEDULER_Priority prio,
531 * only valid until @a task is started! 539 * only valid until @a task is started!
532 */ 540 */
533struct GNUNET_SCHEDULER_Task * 541struct GNUNET_SCHEDULER_Task *
534GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, 542GNUNET_SCHEDULER_add_now (GNUNET_SCHEDULER_TaskCallback task,
535 void *task_cls); 543 void *task_cls);
536 544
537 545
538/** 546/**
@@ -546,8 +554,8 @@ GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task,
546 * only valid until @a task is started! 554 * only valid until @a task is started!
547 */ 555 */
548struct GNUNET_SCHEDULER_Task * 556struct GNUNET_SCHEDULER_Task *
549GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, 557GNUNET_SCHEDULER_add_shutdown (GNUNET_SCHEDULER_TaskCallback task,
550 void *task_cls); 558 void *task_cls);
551 559
552 560
553/** 561/**
@@ -565,9 +573,9 @@ GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task,
565 * only valid until @a task is started! 573 * only valid until @a task is started!
566 */ 574 */
567struct GNUNET_SCHEDULER_Task * 575struct GNUNET_SCHEDULER_Task *
568GNUNET_SCHEDULER_add_now_with_lifeness(int lifeness, 576GNUNET_SCHEDULER_add_now_with_lifeness (int lifeness,
569 GNUNET_SCHEDULER_TaskCallback task, 577 GNUNET_SCHEDULER_TaskCallback task,
570 void *task_cls); 578 void *task_cls);
571 579
572 580
573/** 581/**
@@ -582,9 +590,9 @@ GNUNET_SCHEDULER_add_now_with_lifeness(int lifeness,
582 * only valid until @a task is started! 590 * only valid until @a task is started!
583 */ 591 */
584struct GNUNET_SCHEDULER_Task * 592struct GNUNET_SCHEDULER_Task *
585GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, 593GNUNET_SCHEDULER_add_delayed (struct GNUNET_TIME_Relative delay,
586 GNUNET_SCHEDULER_TaskCallback task, 594 GNUNET_SCHEDULER_TaskCallback task,
587 void *task_cls); 595 void *task_cls);
588 596
589 597
590/** 598/**
@@ -599,9 +607,9 @@ GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay,
599 * only valid until @a task is started! 607 * only valid until @a task is started!
600 */ 608 */
601struct GNUNET_SCHEDULER_Task * 609struct GNUNET_SCHEDULER_Task *
602GNUNET_SCHEDULER_add_at(struct GNUNET_TIME_Absolute at, 610GNUNET_SCHEDULER_add_at (struct GNUNET_TIME_Absolute at,
603 GNUNET_SCHEDULER_TaskCallback task, 611 GNUNET_SCHEDULER_TaskCallback task,
604 void *task_cls); 612 void *task_cls);
605 613
606 614
607/** 615/**
@@ -616,10 +624,11 @@ GNUNET_SCHEDULER_add_at(struct GNUNET_TIME_Absolute at,
616 * only valid until @a task is started! 624 * only valid until @a task is started!
617 */ 625 */
618struct GNUNET_SCHEDULER_Task * 626struct GNUNET_SCHEDULER_Task *
619GNUNET_SCHEDULER_add_delayed_with_priority(struct GNUNET_TIME_Relative delay, 627GNUNET_SCHEDULER_add_delayed_with_priority (struct GNUNET_TIME_Relative delay,
620 enum GNUNET_SCHEDULER_Priority priority, 628 enum GNUNET_SCHEDULER_Priority
621 GNUNET_SCHEDULER_TaskCallback task, 629 priority,
622 void *task_cls); 630 GNUNET_SCHEDULER_TaskCallback task,
631 void *task_cls);
623 632
624 633
625/** 634/**
@@ -634,10 +643,10 @@ GNUNET_SCHEDULER_add_delayed_with_priority(struct GNUNET_TIME_Relative delay,
634 * only valid until @a task is started! 643 * only valid until @a task is started!
635 */ 644 */
636struct GNUNET_SCHEDULER_Task * 645struct GNUNET_SCHEDULER_Task *
637GNUNET_SCHEDULER_add_at_with_priority(struct GNUNET_TIME_Absolute at, 646GNUNET_SCHEDULER_add_at_with_priority (struct GNUNET_TIME_Absolute at,
638 enum GNUNET_SCHEDULER_Priority priority, 647 enum GNUNET_SCHEDULER_Priority priority,
639 GNUNET_SCHEDULER_TaskCallback task, 648 GNUNET_SCHEDULER_TaskCallback task,
640 void *task_cls); 649 void *task_cls);
641 650
642 651
643/** 652/**
@@ -661,10 +670,10 @@ GNUNET_SCHEDULER_add_at_with_priority(struct GNUNET_TIME_Absolute at,
661 * only valid until @a task is started! 670 * only valid until @a task is started!
662 */ 671 */
663struct GNUNET_SCHEDULER_Task * 672struct GNUNET_SCHEDULER_Task *
664GNUNET_SCHEDULER_add_read_net(struct GNUNET_TIME_Relative delay, 673GNUNET_SCHEDULER_add_read_net (struct GNUNET_TIME_Relative delay,
665 struct GNUNET_NETWORK_Handle *rfd, 674 struct GNUNET_NETWORK_Handle *rfd,
666 GNUNET_SCHEDULER_TaskCallback task, 675 GNUNET_SCHEDULER_TaskCallback task,
667 void *task_cls); 676 void *task_cls);
668 677
669 678
670/** 679/**
@@ -690,11 +699,12 @@ GNUNET_SCHEDULER_add_read_net(struct GNUNET_TIME_Relative delay,
690 * only valid until @a task is started! 699 * only valid until @a task is started!
691 */ 700 */
692struct GNUNET_SCHEDULER_Task * 701struct GNUNET_SCHEDULER_Task *
693GNUNET_SCHEDULER_add_read_net_with_priority(struct GNUNET_TIME_Relative delay, 702GNUNET_SCHEDULER_add_read_net_with_priority (struct GNUNET_TIME_Relative delay,
694 enum GNUNET_SCHEDULER_Priority priority, 703 enum GNUNET_SCHEDULER_Priority
695 struct GNUNET_NETWORK_Handle *rfd, 704 priority,
696 GNUNET_SCHEDULER_TaskCallback task, 705 struct GNUNET_NETWORK_Handle *rfd,
697 void *task_cls); 706 GNUNET_SCHEDULER_TaskCallback task,
707 void *task_cls);
698 708
699 709
700/** 710/**
@@ -719,10 +729,10 @@ GNUNET_SCHEDULER_add_read_net_with_priority(struct GNUNET_TIME_Relative delay,
719 * only valid until @a task is started! 729 * only valid until @a task is started!
720 */ 730 */
721struct GNUNET_SCHEDULER_Task * 731struct GNUNET_SCHEDULER_Task *
722GNUNET_SCHEDULER_add_write_net(struct GNUNET_TIME_Relative delay, 732GNUNET_SCHEDULER_add_write_net (struct GNUNET_TIME_Relative delay,
723 struct GNUNET_NETWORK_Handle *wfd, 733 struct GNUNET_NETWORK_Handle *wfd,
724 GNUNET_SCHEDULER_TaskCallback task, 734 GNUNET_SCHEDULER_TaskCallback task,
725 void *task_cls); 735 void *task_cls);
726 736
727 737
728/** 738/**
@@ -749,13 +759,13 @@ GNUNET_SCHEDULER_add_write_net(struct GNUNET_TIME_Relative delay,
749 * only valid until "task" is started! 759 * only valid until "task" is started!
750 */ 760 */
751struct GNUNET_SCHEDULER_Task * 761struct GNUNET_SCHEDULER_Task *
752GNUNET_SCHEDULER_add_net_with_priority(struct GNUNET_TIME_Relative delay, 762GNUNET_SCHEDULER_add_net_with_priority (struct GNUNET_TIME_Relative delay,
753 enum GNUNET_SCHEDULER_Priority priority, 763 enum GNUNET_SCHEDULER_Priority priority,
754 struct GNUNET_NETWORK_Handle *fd, 764 struct GNUNET_NETWORK_Handle *fd,
755 int on_read, 765 int on_read,
756 int on_write, 766 int on_write,
757 GNUNET_SCHEDULER_TaskCallback task, 767 GNUNET_SCHEDULER_TaskCallback task,
758 void *task_cls); 768 void *task_cls);
759 769
760 770
761/** 771/**
@@ -779,10 +789,10 @@ GNUNET_SCHEDULER_add_net_with_priority(struct GNUNET_TIME_Relative delay,
779 * only valid until @a task is started! 789 * only valid until @a task is started!
780 */ 790 */
781struct GNUNET_SCHEDULER_Task * 791struct GNUNET_SCHEDULER_Task *
782GNUNET_SCHEDULER_add_read_file(struct GNUNET_TIME_Relative delay, 792GNUNET_SCHEDULER_add_read_file (struct GNUNET_TIME_Relative delay,
783 const struct GNUNET_DISK_FileHandle *rfd, 793 const struct GNUNET_DISK_FileHandle *rfd,
784 GNUNET_SCHEDULER_TaskCallback task, 794 GNUNET_SCHEDULER_TaskCallback task,
785 void *task_cls); 795 void *task_cls);
786 796
787 797
788/** 798/**
@@ -806,10 +816,10 @@ GNUNET_SCHEDULER_add_read_file(struct GNUNET_TIME_Relative delay,
806 * only valid until @a task is started! 816 * only valid until @a task is started!
807 */ 817 */
808struct GNUNET_SCHEDULER_Task * 818struct GNUNET_SCHEDULER_Task *
809GNUNET_SCHEDULER_add_write_file(struct GNUNET_TIME_Relative delay, 819GNUNET_SCHEDULER_add_write_file (struct GNUNET_TIME_Relative delay,
810 const struct GNUNET_DISK_FileHandle *wfd, 820 const struct GNUNET_DISK_FileHandle *wfd,
811 GNUNET_SCHEDULER_TaskCallback task, 821 GNUNET_SCHEDULER_TaskCallback task,
812 void *task_cls); 822 void *task_cls);
813 823
814 824
815/** 825/**
@@ -836,12 +846,15 @@ GNUNET_SCHEDULER_add_write_file(struct GNUNET_TIME_Relative delay,
836 * only valid until @a task is started! 846 * only valid until @a task is started!
837 */ 847 */
838struct GNUNET_SCHEDULER_Task * 848struct GNUNET_SCHEDULER_Task *
839GNUNET_SCHEDULER_add_file_with_priority(struct GNUNET_TIME_Relative delay, 849GNUNET_SCHEDULER_add_file_with_priority (struct GNUNET_TIME_Relative delay,
840 enum GNUNET_SCHEDULER_Priority priority, 850 enum GNUNET_SCHEDULER_Priority
841 const struct GNUNET_DISK_FileHandle *fd, 851 priority,
842 int on_read, int on_write, 852 const struct
843 GNUNET_SCHEDULER_TaskCallback task, 853 GNUNET_DISK_FileHandle *fd,
844 void *task_cls); 854 int on_read,
855 int on_write,
856 GNUNET_SCHEDULER_TaskCallback task,
857 void *task_cls);
845 858
846 859
847/** 860/**
@@ -876,12 +889,12 @@ GNUNET_SCHEDULER_add_file_with_priority(struct GNUNET_TIME_Relative delay,
876 * only valid until @a task is started! 889 * only valid until @a task is started!
877 */ 890 */
878struct GNUNET_SCHEDULER_Task * 891struct GNUNET_SCHEDULER_Task *
879GNUNET_SCHEDULER_add_select(enum GNUNET_SCHEDULER_Priority prio, 892GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio,
880 struct GNUNET_TIME_Relative delay, 893 struct GNUNET_TIME_Relative delay,
881 const struct GNUNET_NETWORK_FDSet *rs, 894 const struct GNUNET_NETWORK_FDSet *rs,
882 const struct GNUNET_NETWORK_FDSet *ws, 895 const struct GNUNET_NETWORK_FDSet *ws,
883 GNUNET_SCHEDULER_TaskCallback task, 896 GNUNET_SCHEDULER_TaskCallback task,
884 void *task_cls); 897 void *task_cls);
885 898
886/** 899/**
887 * Sets the select function to use in the scheduler (scheduler_select). 900 * Sets the select function to use in the scheduler (scheduler_select).
@@ -890,8 +903,8 @@ GNUNET_SCHEDULER_add_select(enum GNUNET_SCHEDULER_Priority prio,
890 * @param new_select_cls closure for @a new_select 903 * @param new_select_cls closure for @a new_select
891 */ 904 */
892void 905void
893GNUNET_SCHEDULER_set_select(GNUNET_SCHEDULER_select new_select, 906GNUNET_SCHEDULER_set_select (GNUNET_SCHEDULER_select new_select,
894 void *new_select_cls); 907 void *new_select_cls);
895 908
896 909
897 910
@@ -908,7 +921,7 @@ GNUNET_SCHEDULER_set_select(GNUNET_SCHEDULER_select new_select,
908 * @param aid the asynchronous scope id to enter 921 * @param aid the asynchronous scope id to enter
909 */ 922 */
910void 923void
911GNUNET_SCHEDULER_begin_async_scope(struct GNUNET_AsyncScopeId *aid); 924GNUNET_SCHEDULER_begin_async_scope (struct GNUNET_AsyncScopeId *aid);
912 925
913 926
914 927
diff --git a/src/include/gnunet_service_lib.h b/src/include/gnunet_service_lib.h
index 9cdf4d459..19a5fb89b 100644
--- a/src/include/gnunet_service_lib.h
+++ b/src/include/gnunet_service_lib.h
@@ -50,7 +50,8 @@ extern "C"
50/** 50/**
51 * Options for the service (bitmask). 51 * Options for the service (bitmask).
52 */ 52 */
53enum GNUNET_SERVICE_Options { 53enum GNUNET_SERVICE_Options
54{
54 /** 55 /**
55 * Use defaults. Terminates all client connections and the listen 56 * Use defaults. Terminates all client connections and the listen
56 * sockets immediately upon receiving the shutdown signal. 57 * sockets immediately upon receiving the shutdown signal.
@@ -68,7 +69,18 @@ enum GNUNET_SERVICE_Options {
68 * Trigger a SOFT server shutdown on signals, allowing active 69 * Trigger a SOFT server shutdown on signals, allowing active
69 * non-monitor clients to complete their transactions. 70 * non-monitor clients to complete their transactions.
70 */ 71 */
71 GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN = 2 72 GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN = 2,
73
74 /**
75 * Bitmask over the shutdown options.
76 */
77 GNUNET_SERVICE_OPTION_SHUTDOWN_BITMASK = 3,
78
79 /**
80 * Instead of listening on lsocks passed by the parent,
81 * close them *after* opening our own listen socket(s).
82 */
83 GNUNET_SERVICE_OPTION_CLOSE_LSOCKS = 4
72}; 84};
73 85
74 86
@@ -164,12 +176,12 @@ typedef void
164 * @return NULL on error 176 * @return NULL on error
165 */ 177 */
166struct GNUNET_SERVICE_Handle * 178struct GNUNET_SERVICE_Handle *
167GNUNET_SERVICE_start(const char *service_name, 179GNUNET_SERVICE_start (const char *service_name,
168 const struct GNUNET_CONFIGURATION_Handle *cfg, 180 const struct GNUNET_CONFIGURATION_Handle *cfg,
169 GNUNET_SERVICE_ConnectHandler connect_cb, 181 GNUNET_SERVICE_ConnectHandler connect_cb,
170 GNUNET_SERVICE_DisconnectHandler disconnect_cb, 182 GNUNET_SERVICE_DisconnectHandler disconnect_cb,
171 void *cls, 183 void *cls,
172 const struct GNUNET_MQ_MessageHandler *handlers); 184 const struct GNUNET_MQ_MessageHandler *handlers);
173 185
174 186
175/** 187/**
@@ -178,7 +190,7 @@ GNUNET_SERVICE_start(const char *service_name,
178 * @param srv service to stop 190 * @param srv service to stop
179 */ 191 */
180void 192void
181GNUNET_SERVICE_stop(struct GNUNET_SERVICE_Handle *srv); 193GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Handle *srv);
182 194
183 195
184/** 196/**
@@ -223,15 +235,15 @@ GNUNET_SERVICE_stop(struct GNUNET_SERVICE_Handle *srv);
223 * @return 0 on success, non-zero on error 235 * @return 0 on success, non-zero on error
224 */ 236 */
225int 237int
226GNUNET_SERVICE_run_(int argc, 238GNUNET_SERVICE_run_ (int argc,
227 char *const *argv, 239 char *const *argv,
228 const char *service_name, 240 const char *service_name,
229 enum GNUNET_SERVICE_Options options, 241 enum GNUNET_SERVICE_Options options,
230 GNUNET_SERVICE_InitCallback service_init_cb, 242 GNUNET_SERVICE_InitCallback service_init_cb,
231 GNUNET_SERVICE_ConnectHandler connect_cb, 243 GNUNET_SERVICE_ConnectHandler connect_cb,
232 GNUNET_SERVICE_DisconnectHandler disconnect_cb, 244 GNUNET_SERVICE_DisconnectHandler disconnect_cb,
233 void *cls, 245 void *cls,
234 const struct GNUNET_MQ_MessageHandler *handlers); 246 const struct GNUNET_MQ_MessageHandler *handlers);
235 247
236 248
237/** 249/**
@@ -291,23 +303,24 @@ GNUNET_SERVICE_run_(int argc,
291 * GNUNET_MQ_handler_end ()); 303 * GNUNET_MQ_handler_end ());
292 * </code> 304 * </code>
293 */ 305 */
294#define GNUNET_SERVICE_MAIN(service_name, service_options, init_cb, connect_cb, disconnect_cb, cls, ...) \ 306#define GNUNET_SERVICE_MAIN(service_name, service_options, init_cb, connect_cb, \
307 disconnect_cb, cls, ...) \
295 int \ 308 int \
296 main(int argc, \ 309 main (int argc, \
297 char *const *argv) \ 310 char *const *argv) \
298 { \ 311 { \
299 struct GNUNET_MQ_MessageHandler mh[] = { \ 312 struct GNUNET_MQ_MessageHandler mh[] = { \
300 __VA_ARGS__ \ 313 __VA_ARGS__ \
301 }; \ 314 }; \
302 return GNUNET_SERVICE_run_(argc, \ 315 return GNUNET_SERVICE_run_ (argc, \
303 argv, \ 316 argv, \
304 service_name, \ 317 service_name, \
305 service_options, \ 318 service_options, \
306 init_cb, \ 319 init_cb, \
307 connect_cb, \ 320 connect_cb, \
308 disconnect_cb, \ 321 disconnect_cb, \
309 cls, \ 322 cls, \
310 mh); \ 323 mh); \
311 } 324 }
312 325
313 326
@@ -318,7 +331,7 @@ GNUNET_SERVICE_run_(int argc,
318 * @param sh service to stop accepting connections. 331 * @param sh service to stop accepting connections.
319 */ 332 */
320void 333void
321GNUNET_SERVICE_suspend(struct GNUNET_SERVICE_Handle *sh); 334GNUNET_SERVICE_suspend (struct GNUNET_SERVICE_Handle *sh);
322 335
323 336
324/** 337/**
@@ -327,7 +340,7 @@ GNUNET_SERVICE_suspend(struct GNUNET_SERVICE_Handle *sh);
327 * @param sh service to resume accepting connections. 340 * @param sh service to resume accepting connections.
328 */ 341 */
329void 342void
330GNUNET_SERVICE_resume(struct GNUNET_SERVICE_Handle *sh); 343GNUNET_SERVICE_resume (struct GNUNET_SERVICE_Handle *sh);
331 344
332 345
333/** 346/**
@@ -337,7 +350,7 @@ GNUNET_SERVICE_resume(struct GNUNET_SERVICE_Handle *sh);
337 * @param c the client to continue receiving from 350 * @param c the client to continue receiving from
338 */ 351 */
339void 352void
340GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c); 353GNUNET_SERVICE_client_continue (struct GNUNET_SERVICE_Client *c);
341 354
342 355
343/** 356/**
@@ -347,7 +360,7 @@ GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c);
347 * @return the message queue of @a c 360 * @return the message queue of @a c
348 */ 361 */
349struct GNUNET_MQ_Handle * 362struct GNUNET_MQ_Handle *
350GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c); 363GNUNET_SERVICE_client_get_mq (struct GNUNET_SERVICE_Client *c);
351 364
352 365
353/** 366/**
@@ -359,7 +372,8 @@ GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c);
359 * @param c client for which to disable the warning 372 * @param c client for which to disable the warning
360 */ 373 */
361void 374void
362GNUNET_SERVICE_client_disable_continue_warning(struct GNUNET_SERVICE_Client *c); 375GNUNET_SERVICE_client_disable_continue_warning (struct
376 GNUNET_SERVICE_Client *c);
363 377
364 378
365/** 379/**
@@ -378,7 +392,7 @@ GNUNET_SERVICE_client_disable_continue_warning(struct GNUNET_SERVICE_Client *c);
378 * @param c client to disconnect now 392 * @param c client to disconnect now
379 */ 393 */
380void 394void
381GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c); 395GNUNET_SERVICE_client_drop (struct GNUNET_SERVICE_Client *c);
382 396
383 397
384/** 398/**
@@ -387,7 +401,7 @@ GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c);
387 * @param sh server to shutdown 401 * @param sh server to shutdown
388 */ 402 */
389void 403void
390GNUNET_SERVICE_shutdown(struct GNUNET_SERVICE_Handle *sh); 404GNUNET_SERVICE_shutdown (struct GNUNET_SERVICE_Handle *sh);
391 405
392 406
393/** 407/**
@@ -403,7 +417,7 @@ GNUNET_SERVICE_shutdown(struct GNUNET_SERVICE_Handle *sh);
403 * @param c client to mark as a monitor 417 * @param c client to mark as a monitor
404 */ 418 */
405void 419void
406GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c); 420GNUNET_SERVICE_client_mark_monitor (struct GNUNET_SERVICE_Client *c);
407 421
408 422
409/** 423/**
@@ -414,7 +428,7 @@ GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c);
414 * @param c client to persist the socket (never to be closed) 428 * @param c client to persist the socket (never to be closed)
415 */ 429 */
416void 430void
417GNUNET_SERVICE_client_persist(struct GNUNET_SERVICE_Client *c); 431GNUNET_SERVICE_client_persist (struct GNUNET_SERVICE_Client *c);
418 432
419 433
420#if 0 /* keep Emacsens' auto-indent happy */ 434#if 0 /* keep Emacsens' auto-indent happy */
diff --git a/src/util/client.c b/src/util/client.c
index e3585af2e..d431909cf 100644
--- a/src/util/client.c
+++ b/src/util/client.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2001-2016 GNUnet e.V. 3 Copyright (C) 2001-2016, 2019 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -33,7 +33,7 @@
33#include "gnunet_socks.h" 33#include "gnunet_socks.h"
34 34
35 35
36#define LOG(kind, ...) GNUNET_log_from(kind, "util-client", __VA_ARGS__) 36#define LOG(kind, ...) GNUNET_log_from (kind, "util-client", __VA_ARGS__)
37 37
38/** 38/**
39 * Timeout we use on TCP connect before trying another 39 * Timeout we use on TCP connect before trying another
@@ -41,7 +41,8 @@
41 * is this value divided by the number of address families. 41 * is this value divided by the number of address families.
42 * Default is 5s. 42 * Default is 5s.
43 */ 43 */
44#define CONNECT_RETRY_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5) 44#define CONNECT_RETRY_TIMEOUT GNUNET_TIME_relative_multiply ( \
45 GNUNET_TIME_UNIT_SECONDS, 5)
45 46
46 47
47 48
@@ -55,7 +56,8 @@ struct ClientState;
55 * During connect, we try multiple possible IP addresses 56 * During connect, we try multiple possible IP addresses
56 * to find out which one might work. 57 * to find out which one might work.
57 */ 58 */
58struct AddressProbe { 59struct AddressProbe
60{
59 /** 61 /**
60 * This is a linked list. 62 * This is a linked list.
61 */ 63 */
@@ -96,7 +98,8 @@ struct AddressProbe {
96/** 98/**
97 * Internal state for a client connected to a GNUnet service. 99 * Internal state for a client connected to a GNUnet service.
98 */ 100 */
99struct ClientState { 101struct ClientState
102{
100 /** 103 /**
101 * The connection handle, NULL if not live 104 * The connection handle, NULL if not live
102 */ 105 */
@@ -205,7 +208,7 @@ struct ClientState {
205 * @param cls the `struct ClientState` to try to connect to the service 208 * @param cls the `struct ClientState` to try to connect to the service
206 */ 209 */
207static void 210static void
208start_connect(void *cls); 211start_connect (void *cls);
209 212
210 213
211/** 214/**
@@ -215,26 +218,26 @@ start_connect(void *cls);
215 * @param cstate the connection we tried to establish 218 * @param cstate the connection we tried to establish
216 */ 219 */
217static void 220static void
218connect_fail_continuation(struct ClientState *cstate) 221connect_fail_continuation (struct ClientState *cstate)
219{ 222{
220 GNUNET_break(NULL == cstate->ap_head); 223 GNUNET_break (NULL == cstate->ap_head);
221 GNUNET_break(NULL == cstate->ap_tail); 224 GNUNET_break (NULL == cstate->ap_tail);
222 GNUNET_break(NULL == cstate->dns_active); 225 GNUNET_break (NULL == cstate->dns_active);
223 GNUNET_break(NULL == cstate->sock); 226 GNUNET_break (NULL == cstate->sock);
224 GNUNET_assert(NULL == cstate->send_task); 227 GNUNET_assert (NULL == cstate->send_task);
225 GNUNET_assert(NULL == cstate->recv_task); 228 GNUNET_assert (NULL == cstate->recv_task);
226 // GNUNET_assert (NULL == cstate->proxy_handshake); 229 // GNUNET_assert (NULL == cstate->proxy_handshake);
227 230
228 cstate->back_off = GNUNET_TIME_STD_BACKOFF(cstate->back_off); 231 cstate->back_off = GNUNET_TIME_STD_BACKOFF (cstate->back_off);
229 LOG(GNUNET_ERROR_TYPE_DEBUG, 232 LOG (GNUNET_ERROR_TYPE_DEBUG,
230 "Failed to establish connection to `%s', no further addresses to try, will try again in %s.\n", 233 "Failed to establish connection to `%s', no further addresses to try, will try again in %s.\n",
231 cstate->service_name, 234 cstate->service_name,
232 GNUNET_STRINGS_relative_time_to_string(cstate->back_off, 235 GNUNET_STRINGS_relative_time_to_string (cstate->back_off,
233 GNUNET_YES)); 236 GNUNET_YES));
234 cstate->retry_task 237 cstate->retry_task
235 = GNUNET_SCHEDULER_add_delayed(cstate->back_off, 238 = GNUNET_SCHEDULER_add_delayed (cstate->back_off,
236 &start_connect, 239 &start_connect,
237 cstate); 240 cstate);
238} 241}
239 242
240 243
@@ -244,7 +247,7 @@ connect_fail_continuation(struct ClientState *cstate)
244 * @param cls the `struct ClientState` with the `msg` to transmit 247 * @param cls the `struct ClientState` with the `msg` to transmit
245 */ 248 */
246static void 249static void
247transmit_ready(void *cls) 250transmit_ready (void *cls)
248{ 251{
249 struct ClientState *cstate = cls; 252 struct ClientState *cstate = cls;
250 ssize_t ret; 253 ssize_t ret;
@@ -255,56 +258,56 @@ transmit_ready(void *cls)
255 cstate->send_task = NULL; 258 cstate->send_task = NULL;
256 if (GNUNET_YES == cstate->in_destroy) 259 if (GNUNET_YES == cstate->in_destroy)
257 return; 260 return;
258 pos = (const char *)cstate->msg; 261 pos = (const char *) cstate->msg;
259 len = ntohs(cstate->msg->size); 262 len = ntohs (cstate->msg->size);
260 GNUNET_assert(cstate->msg_off < len); 263 GNUNET_assert (cstate->msg_off < len);
261 LOG(GNUNET_ERROR_TYPE_DEBUG, 264 LOG (GNUNET_ERROR_TYPE_DEBUG,
262 "message of type %u trying to send with socket %p (MQ: %p\n", 265 "message of type %u trying to send with socket %p (MQ: %p\n",
263 ntohs(cstate->msg->type), 266 ntohs (cstate->msg->type),
264 cstate->sock, 267 cstate->sock,
265 cstate->mq); 268 cstate->mq);
266 269
267RETRY: 270RETRY:
268 ret = GNUNET_NETWORK_socket_send(cstate->sock, 271 ret = GNUNET_NETWORK_socket_send (cstate->sock,
269 &pos[cstate->msg_off], 272 &pos[cstate->msg_off],
270 len - cstate->msg_off); 273 len - cstate->msg_off);
271 if (-1 == ret) 274 if (-1 == ret)
275 {
276 LOG (GNUNET_ERROR_TYPE_WARNING,
277 "Error during sending message of type %u\n",
278 ntohs (cstate->msg->type));
279 if (EINTR == errno)
272 { 280 {
273 LOG(GNUNET_ERROR_TYPE_WARNING, 281 LOG (GNUNET_ERROR_TYPE_DEBUG,
274 "Error during sending message of type %u\n", 282 "Retrying message of type %u\n",
275 ntohs(cstate->msg->type)); 283 ntohs (cstate->msg->type));
276 if (EINTR == errno) 284 goto RETRY;
277 {
278 LOG(GNUNET_ERROR_TYPE_DEBUG,
279 "Retrying message of type %u\n",
280 ntohs(cstate->msg->type));
281 goto RETRY;
282 }
283 GNUNET_MQ_inject_error(cstate->mq,
284 GNUNET_MQ_ERROR_WRITE);
285 return;
286 } 285 }
286 GNUNET_MQ_inject_error (cstate->mq,
287 GNUNET_MQ_ERROR_WRITE);
288 return;
289 }
287 notify_in_flight = (0 == cstate->msg_off); 290 notify_in_flight = (0 == cstate->msg_off);
288 cstate->msg_off += ret; 291 cstate->msg_off += ret;
289 if (cstate->msg_off < len) 292 if (cstate->msg_off < len)
290 { 293 {
291 LOG(GNUNET_ERROR_TYPE_DEBUG, 294 LOG (GNUNET_ERROR_TYPE_DEBUG,
292 "rescheduling message of type %u\n", 295 "rescheduling message of type %u\n",
293 ntohs(cstate->msg->type)); 296 ntohs (cstate->msg->type));
294 cstate->send_task 297 cstate->send_task
295 = GNUNET_SCHEDULER_add_write_net(GNUNET_TIME_UNIT_FOREVER_REL, 298 = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
296 cstate->sock, 299 cstate->sock,
297 &transmit_ready, 300 &transmit_ready,
298 cstate); 301 cstate);
299 if (notify_in_flight) 302 if (notify_in_flight)
300 GNUNET_MQ_impl_send_in_flight(cstate->mq); 303 GNUNET_MQ_impl_send_in_flight (cstate->mq);
301 return; 304 return;
302 } 305 }
303 LOG(GNUNET_ERROR_TYPE_DEBUG, 306 LOG (GNUNET_ERROR_TYPE_DEBUG,
304 "sending message of type %u successful\n", 307 "sending message of type %u successful\n",
305 ntohs(cstate->msg->type)); 308 ntohs (cstate->msg->type));
306 cstate->msg = NULL; 309 cstate->msg = NULL;
307 GNUNET_MQ_impl_send_continue(cstate->mq); 310 GNUNET_MQ_impl_send_continue (cstate->mq);
308} 311}
309 312
310 313
@@ -319,20 +322,20 @@ RETRY:
319 * #GNUNET_SYSERR to stop further processing due to error 322 * #GNUNET_SYSERR to stop further processing due to error
320 */ 323 */
321static int 324static int
322recv_message(void *cls, 325recv_message (void *cls,
323 const struct GNUNET_MessageHeader *msg) 326 const struct GNUNET_MessageHeader *msg)
324{ 327{
325 struct ClientState *cstate = cls; 328 struct ClientState *cstate = cls;
326 329
327 if (GNUNET_YES == cstate->in_destroy) 330 if (GNUNET_YES == cstate->in_destroy)
328 return GNUNET_NO; 331 return GNUNET_NO;
329 LOG(GNUNET_ERROR_TYPE_DEBUG, 332 LOG (GNUNET_ERROR_TYPE_DEBUG,
330 "Received message of type %u and size %u from %s\n", 333 "Received message of type %u and size %u from %s\n",
331 ntohs(msg->type), 334 ntohs (msg->type),
332 ntohs(msg->size), 335 ntohs (msg->size),
333 cstate->service_name); 336 cstate->service_name);
334 GNUNET_MQ_inject_message(cstate->mq, 337 GNUNET_MQ_inject_message (cstate->mq,
335 msg); 338 msg);
336 if (GNUNET_YES == cstate->in_destroy) 339 if (GNUNET_YES == cstate->in_destroy)
337 return GNUNET_NO; 340 return GNUNET_NO;
338 return GNUNET_OK; 341 return GNUNET_OK;
@@ -345,20 +348,20 @@ recv_message(void *cls,
345 * @param cstate handle of the client state to process 348 * @param cstate handle of the client state to process
346 */ 349 */
347static void 350static void
348cancel_aps(struct ClientState *cstate) 351cancel_aps (struct ClientState *cstate)
349{ 352{
350 struct AddressProbe *pos; 353 struct AddressProbe *pos;
351 354
352 while (NULL != (pos = cstate->ap_head)) 355 while (NULL != (pos = cstate->ap_head))
353 { 356 {
354 GNUNET_break(GNUNET_OK == 357 GNUNET_break (GNUNET_OK ==
355 GNUNET_NETWORK_socket_close(pos->sock)); 358 GNUNET_NETWORK_socket_close (pos->sock));
356 GNUNET_SCHEDULER_cancel(pos->task); 359 GNUNET_SCHEDULER_cancel (pos->task);
357 GNUNET_CONTAINER_DLL_remove(cstate->ap_head, 360 GNUNET_CONTAINER_DLL_remove (cstate->ap_head,
358 cstate->ap_tail, 361 cstate->ap_tail,
359 pos); 362 pos);
360 GNUNET_free(pos); 363 GNUNET_free (pos);
361 } 364 }
362} 365}
363 366
364 367
@@ -370,51 +373,51 @@ cancel_aps(struct ClientState *cstate)
370 * @param impl_state our `struct ClientState` 373 * @param impl_state our `struct ClientState`
371 */ 374 */
372static void 375static void
373connection_client_destroy_impl(struct GNUNET_MQ_Handle *mq, 376connection_client_destroy_impl (struct GNUNET_MQ_Handle *mq,
374 void *impl_state) 377 void *impl_state)
375{ 378{
376 struct ClientState *cstate = impl_state; 379 struct ClientState *cstate = impl_state;
377 380
378 (void)mq; 381 (void) mq;
379 if (NULL != cstate->dns_active) 382 if (NULL != cstate->dns_active)
380 { 383 {
381 GNUNET_RESOLVER_request_cancel(cstate->dns_active); 384 GNUNET_RESOLVER_request_cancel (cstate->dns_active);
382 cstate->dns_active = NULL; 385 cstate->dns_active = NULL;
383 } 386 }
384 if (NULL != cstate->send_task) 387 if (NULL != cstate->send_task)
385 { 388 {
386 GNUNET_SCHEDULER_cancel(cstate->send_task); 389 GNUNET_SCHEDULER_cancel (cstate->send_task);
387 cstate->send_task = NULL; 390 cstate->send_task = NULL;
388 } 391 }
389 if (NULL != cstate->retry_task) 392 if (NULL != cstate->retry_task)
390 { 393 {
391 GNUNET_SCHEDULER_cancel(cstate->retry_task); 394 GNUNET_SCHEDULER_cancel (cstate->retry_task);
392 cstate->retry_task = NULL; 395 cstate->retry_task = NULL;
393 } 396 }
394 if (GNUNET_SYSERR == cstate->in_destroy) 397 if (GNUNET_SYSERR == cstate->in_destroy)
395 { 398 {
396 /* defer destruction */ 399 /* defer destruction */
397 cstate->in_destroy = GNUNET_YES; 400 cstate->in_destroy = GNUNET_YES;
398 cstate->mq = NULL; 401 cstate->mq = NULL;
399 return; 402 return;
400 } 403 }
401 if (NULL != cstate->recv_task) 404 if (NULL != cstate->recv_task)
402 { 405 {
403 GNUNET_SCHEDULER_cancel(cstate->recv_task); 406 GNUNET_SCHEDULER_cancel (cstate->recv_task);
404 cstate->recv_task = NULL; 407 cstate->recv_task = NULL;
405 } 408 }
406 if (NULL != cstate->sock) 409 if (NULL != cstate->sock)
407 { 410 {
408 LOG(GNUNET_ERROR_TYPE_DEBUG, 411 LOG (GNUNET_ERROR_TYPE_DEBUG,
409 "destroying socket: %p\n", 412 "destroying socket: %p\n",
410 cstate->sock); 413 cstate->sock);
411 GNUNET_NETWORK_socket_close(cstate->sock); 414 GNUNET_NETWORK_socket_close (cstate->sock);
412 } 415 }
413 cancel_aps(cstate); 416 cancel_aps (cstate);
414 GNUNET_free(cstate->service_name); 417 GNUNET_free (cstate->service_name);
415 GNUNET_free_non_null(cstate->hostname); 418 GNUNET_free_non_null (cstate->hostname);
416 GNUNET_MST_destroy(cstate->mst); 419 GNUNET_MST_destroy (cstate->mst);
417 GNUNET_free(cstate); 420 GNUNET_free (cstate);
418} 421}
419 422
420 423
@@ -424,39 +427,39 @@ connection_client_destroy_impl(struct GNUNET_MQ_Handle *mq,
424 * @param cls `struct ClientState` with connection to read from 427 * @param cls `struct ClientState` with connection to read from
425 */ 428 */
426static void 429static void
427receive_ready(void *cls) 430receive_ready (void *cls)
428{ 431{
429 struct ClientState *cstate = cls; 432 struct ClientState *cstate = cls;
430 int ret; 433 int ret;
431 434
432 cstate->recv_task = NULL; 435 cstate->recv_task = NULL;
433 cstate->in_destroy = GNUNET_SYSERR; 436 cstate->in_destroy = GNUNET_SYSERR;
434 ret = GNUNET_MST_read(cstate->mst, 437 ret = GNUNET_MST_read (cstate->mst,
435 cstate->sock, 438 cstate->sock,
436 GNUNET_NO, 439 GNUNET_NO,
437 GNUNET_NO); 440 GNUNET_NO);
438 if (GNUNET_SYSERR == ret) 441 if (GNUNET_SYSERR == ret)
439 { 442 {
440 if (NULL != cstate->mq) 443 if (NULL != cstate->mq)
441 GNUNET_MQ_inject_error(cstate->mq, 444 GNUNET_MQ_inject_error (cstate->mq,
442 GNUNET_MQ_ERROR_READ); 445 GNUNET_MQ_ERROR_READ);
443 if (GNUNET_YES == cstate->in_destroy) 446 if (GNUNET_YES == cstate->in_destroy)
444 connection_client_destroy_impl(cstate->mq, 447 connection_client_destroy_impl (cstate->mq,
445 cstate); 448 cstate);
446 return; 449 return;
447 } 450 }
448 if (GNUNET_YES == cstate->in_destroy) 451 if (GNUNET_YES == cstate->in_destroy)
449 { 452 {
450 connection_client_destroy_impl(cstate->mq, 453 connection_client_destroy_impl (cstate->mq,
451 cstate); 454 cstate);
452 return; 455 return;
453 } 456 }
454 cstate->in_destroy = GNUNET_NO; 457 cstate->in_destroy = GNUNET_NO;
455 cstate->recv_task 458 cstate->recv_task
456 = GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, 459 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
457 cstate->sock, 460 cstate->sock,
458 &receive_ready, 461 &receive_ready,
459 cstate); 462 cstate);
460} 463}
461 464
462 465
@@ -466,23 +469,23 @@ receive_ready(void *cls)
466 * @param cstate the connection we tried to establish 469 * @param cstate the connection we tried to establish
467 */ 470 */
468static void 471static void
469connect_success_continuation(struct ClientState *cstate) 472connect_success_continuation (struct ClientState *cstate)
470{ 473{
471 GNUNET_assert(NULL == cstate->recv_task); 474 GNUNET_assert (NULL == cstate->recv_task);
472 cstate->recv_task 475 cstate->recv_task
473 = GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, 476 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
474 cstate->sock, 477 cstate->sock,
475 &receive_ready, 478 &receive_ready,
476 cstate); 479 cstate);
477 if (NULL != cstate->msg) 480 if (NULL != cstate->msg)
478 { 481 {
479 GNUNET_assert(NULL == cstate->send_task); 482 GNUNET_assert (NULL == cstate->send_task);
480 cstate->send_task 483 cstate->send_task
481 = GNUNET_SCHEDULER_add_write_net(GNUNET_TIME_UNIT_FOREVER_REL, 484 = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
482 cstate->sock, 485 cstate->sock,
483 &transmit_ready, 486 &transmit_ready,
484 cstate); 487 cstate);
485 } 488 }
486} 489}
487 490
488 491
@@ -494,8 +497,8 @@ connect_success_continuation(struct ClientState *cstate)
494 * @return NULL on error, socket connected to UNIX otherwise 497 * @return NULL on error, socket connected to UNIX otherwise
495 */ 498 */
496static struct GNUNET_NETWORK_Handle * 499static struct GNUNET_NETWORK_Handle *
497try_unixpath(const char *service_name, 500try_unixpath (const char *service_name,
498 const struct GNUNET_CONFIGURATION_Handle *cfg) 501 const struct GNUNET_CONFIGURATION_Handle *cfg)
499{ 502{
500#if AF_UNIX 503#if AF_UNIX
501 struct GNUNET_NETWORK_Handle *sock; 504 struct GNUNET_NETWORK_Handle *sock;
@@ -504,67 +507,56 @@ try_unixpath(const char *service_name,
504 507
505 unixpath = NULL; 508 unixpath = NULL;
506 if ((GNUNET_OK == 509 if ((GNUNET_OK ==
507 GNUNET_CONFIGURATION_get_value_filename(cfg, 510 GNUNET_CONFIGURATION_get_value_filename (cfg,
508 service_name, 511 service_name,
509 "UNIXPATH", 512 "UNIXPATH",
510 &unixpath)) && 513 &unixpath)) &&
511 (0 < strlen(unixpath))) 514 (0 < strlen (unixpath)))
515 {
516 /* We have a non-NULL unixpath, need to validate it */
517 if (strlen (unixpath) >= sizeof(s_un.sun_path))
512 { 518 {
513 /* We have a non-NULL unixpath, need to validate it */ 519 LOG (GNUNET_ERROR_TYPE_WARNING,
514 if (strlen(unixpath) >= sizeof(s_un.sun_path)) 520 _ ("UNIXPATH `%s' too long, maximum length is %llu\n"),
515 { 521 unixpath,
516 LOG(GNUNET_ERROR_TYPE_WARNING, 522 (unsigned long long) sizeof(s_un.sun_path));
517 _("UNIXPATH `%s' too long, maximum length is %llu\n"), 523 unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath);
518 unixpath, 524 LOG (GNUNET_ERROR_TYPE_INFO,
519 (unsigned long long)sizeof(s_un.sun_path)); 525 _ ("Using `%s' instead\n"),
520 unixpath = GNUNET_NETWORK_shorten_unixpath(unixpath); 526 unixpath);
521 LOG(GNUNET_ERROR_TYPE_INFO, 527 if (NULL == unixpath)
522 _("Using `%s' instead\n"), 528 return NULL;
523 unixpath); 529 }
524 if (NULL == unixpath) 530 memset (&s_un,
525 return NULL; 531 0,
526 } 532 sizeof(s_un));
527 memset(&s_un, 533 s_un.sun_family = AF_UNIX;
528 0, 534 GNUNET_strlcpy (s_un.sun_path,
529 sizeof(s_un)); 535 unixpath,
530 s_un.sun_family = AF_UNIX; 536 sizeof(s_un.sun_path));
531 GNUNET_strlcpy(s_un.sun_path,
532 unixpath,
533 sizeof(s_un.sun_path));
534#ifdef LINUX
535 {
536 int abstract;
537
538 abstract = GNUNET_CONFIGURATION_get_value_yesno(cfg,
539 "TESTING",
540 "USE_ABSTRACT_SOCKETS");
541 if (GNUNET_YES == abstract)
542 s_un.sun_path[0] = '\0';
543 }
544#endif
545#if HAVE_SOCKADDR_UN_SUN_LEN 537#if HAVE_SOCKADDR_UN_SUN_LEN
546 s_un.sun_len = (u_char)sizeof(struct sockaddr_un); 538 s_un.sun_len = (u_char) sizeof(struct sockaddr_un);
547#endif 539#endif
548 sock = GNUNET_NETWORK_socket_create(AF_UNIX, 540 sock = GNUNET_NETWORK_socket_create (AF_UNIX,
549 SOCK_STREAM, 541 SOCK_STREAM,
550 0); 542 0);
551 if ((NULL != sock) && 543 if ((NULL != sock) &&
552 ((GNUNET_OK == 544 ((GNUNET_OK ==
553 GNUNET_NETWORK_socket_connect(sock, 545 GNUNET_NETWORK_socket_connect (sock,
554 (struct sockaddr *)&s_un, 546 (struct sockaddr *) &s_un,
555 sizeof(s_un))) || 547 sizeof(s_un))) ||
556 (EINPROGRESS == errno))) 548 (EINPROGRESS == errno)))
557 { 549 {
558 LOG(GNUNET_ERROR_TYPE_DEBUG, 550 LOG (GNUNET_ERROR_TYPE_DEBUG,
559 "Successfully connected to unixpath `%s'!\n", 551 "Successfully connected to unixpath `%s'!\n",
560 unixpath); 552 unixpath);
561 GNUNET_free(unixpath); 553 GNUNET_free (unixpath);
562 return sock; 554 return sock;
563 }
564 if (NULL != sock)
565 GNUNET_NETWORK_socket_close(sock);
566 } 555 }
567 GNUNET_free_non_null(unixpath); 556 if (NULL != sock)
557 GNUNET_NETWORK_socket_close (sock);
558 }
559 GNUNET_free_non_null (unixpath);
568#endif 560#endif
569 return NULL; 561 return NULL;
570} 562}
@@ -577,7 +569,7 @@ try_unixpath(const char *service_name,
577 * @param cls the `struct AddressProbe *` with the address that we are probing 569 * @param cls the `struct AddressProbe *` with the address that we are probing
578 */ 570 */
579static void 571static void
580connect_probe_continuation(void *cls) 572connect_probe_continuation (void *cls)
581{ 573{
582 struct AddressProbe *ap = cls; 574 struct AddressProbe *ap = cls;
583 struct ClientState *cstate = ap->cstate; 575 struct ClientState *cstate = ap->cstate;
@@ -586,40 +578,40 @@ connect_probe_continuation(void *cls)
586 socklen_t len; 578 socklen_t len;
587 579
588 ap->task = NULL; 580 ap->task = NULL;
589 GNUNET_assert(NULL != ap->sock); 581 GNUNET_assert (NULL != ap->sock);
590 GNUNET_CONTAINER_DLL_remove(cstate->ap_head, 582 GNUNET_CONTAINER_DLL_remove (cstate->ap_head,
591 cstate->ap_tail, 583 cstate->ap_tail,
592 ap); 584 ap);
593 len = sizeof(error); 585 len = sizeof(error);
594 error = 0; 586 error = 0;
595 tc = GNUNET_SCHEDULER_get_task_context(); 587 tc = GNUNET_SCHEDULER_get_task_context ();
596 if ((0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) || 588 if ((0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) ||
597 (GNUNET_OK != 589 (GNUNET_OK !=
598 GNUNET_NETWORK_socket_getsockopt(ap->sock, 590 GNUNET_NETWORK_socket_getsockopt (ap->sock,
599 SOL_SOCKET, 591 SOL_SOCKET,
600 SO_ERROR, 592 SO_ERROR,
601 &error, 593 &error,
602 &len)) || 594 &len)) ||
603 (0 != error)) 595 (0 != error))
604 { 596 {
605 GNUNET_break(GNUNET_OK == 597 GNUNET_break (GNUNET_OK ==
606 GNUNET_NETWORK_socket_close(ap->sock)); 598 GNUNET_NETWORK_socket_close (ap->sock));
607 GNUNET_free(ap); 599 GNUNET_free (ap);
608 if ((NULL == cstate->ap_head) && 600 if ((NULL == cstate->ap_head) &&
609 // (NULL == cstate->proxy_handshake) && 601 // (NULL == cstate->proxy_handshake) &&
610 (NULL == cstate->dns_active)) 602 (NULL == cstate->dns_active))
611 connect_fail_continuation(cstate); 603 connect_fail_continuation (cstate);
612 return; 604 return;
613 } 605 }
614 LOG(GNUNET_ERROR_TYPE_DEBUG, 606 LOG (GNUNET_ERROR_TYPE_DEBUG,
615 "Connection to `%s' succeeded!\n", 607 "Connection to `%s' succeeded!\n",
616 cstate->service_name); 608 cstate->service_name);
617 /* trigger jobs that waited for the connection */ 609 /* trigger jobs that waited for the connection */
618 GNUNET_assert(NULL == cstate->sock); 610 GNUNET_assert (NULL == cstate->sock);
619 cstate->sock = ap->sock; 611 cstate->sock = ap->sock;
620 GNUNET_free(ap); 612 GNUNET_free (ap);
621 cancel_aps(cstate); 613 cancel_aps (cstate);
622 connect_success_continuation(cstate); 614 connect_success_continuation (cstate);
623} 615}
624 616
625 617
@@ -632,82 +624,82 @@ connect_probe_continuation(void *cls)
632 * @param addrlen length of @a addr 624 * @param addrlen length of @a addr
633 */ 625 */
634static void 626static void
635try_connect_using_address(void *cls, 627try_connect_using_address (void *cls,
636 const struct sockaddr *addr, 628 const struct sockaddr *addr,
637 socklen_t addrlen) 629 socklen_t addrlen)
638{ 630{
639 struct ClientState *cstate = cls; 631 struct ClientState *cstate = cls;
640 struct AddressProbe *ap; 632 struct AddressProbe *ap;
641 633
642 if (NULL == addr) 634 if (NULL == addr)
643 { 635 {
644 cstate->dns_active = NULL; 636 cstate->dns_active = NULL;
645 if ((NULL == cstate->ap_head) && 637 if ((NULL == cstate->ap_head) &&
646 // (NULL == cstate->proxy_handshake) && 638 // (NULL == cstate->proxy_handshake) &&
647 (NULL == cstate->sock)) 639 (NULL == cstate->sock))
648 connect_fail_continuation(cstate); 640 connect_fail_continuation (cstate);
649 return; 641 return;
650 } 642 }
651 if (NULL != cstate->sock) 643 if (NULL != cstate->sock)
652 return; /* already connected */ 644 return; /* already connected */
653 /* try to connect */ 645 /* try to connect */
654 LOG(GNUNET_ERROR_TYPE_DEBUG, 646 LOG (GNUNET_ERROR_TYPE_DEBUG,
655 "Trying to connect using address `%s:%u'\n", 647 "Trying to connect using address `%s:%u'\n",
656 GNUNET_a2s(addr, 648 GNUNET_a2s (addr,
657 addrlen), 649 addrlen),
658 cstate->port); 650 cstate->port);
659 ap = GNUNET_malloc(sizeof(struct AddressProbe) + addrlen); 651 ap = GNUNET_malloc (sizeof(struct AddressProbe) + addrlen);
660 ap->addr = (const struct sockaddr *)&ap[1]; 652 ap->addr = (const struct sockaddr *) &ap[1];
661 GNUNET_memcpy(&ap[1], 653 GNUNET_memcpy (&ap[1],
662 addr, 654 addr,
663 addrlen); 655 addrlen);
664 ap->addrlen = addrlen; 656 ap->addrlen = addrlen;
665 ap->cstate = cstate; 657 ap->cstate = cstate;
666 658
667 switch (ap->addr->sa_family) 659 switch (ap->addr->sa_family)
668 { 660 {
669 case AF_INET: 661 case AF_INET:
670 ((struct sockaddr_in *)ap->addr)->sin_port = htons(cstate->port); 662 ((struct sockaddr_in *) ap->addr)->sin_port = htons (cstate->port);
671 break; 663 break;
672 664
673 case AF_INET6: 665 case AF_INET6:
674 ((struct sockaddr_in6 *)ap->addr)->sin6_port = htons(cstate->port); 666 ((struct sockaddr_in6 *) ap->addr)->sin6_port = htons (cstate->port);
675 break; 667 break;
676 668
677 default: 669 default:
678 GNUNET_break(0); 670 GNUNET_break (0);
679 GNUNET_free(ap); 671 GNUNET_free (ap);
680 return; /* not supported by us */ 672 return; /* not supported by us */
681 } 673 }
682 ap->sock = GNUNET_NETWORK_socket_create(ap->addr->sa_family, 674 ap->sock = GNUNET_NETWORK_socket_create (ap->addr->sa_family,
683 SOCK_STREAM, 675 SOCK_STREAM,
684 0); 676 0);
685 if (NULL == ap->sock) 677 if (NULL == ap->sock)
686 { 678 {
687 GNUNET_free(ap); 679 GNUNET_free (ap);
688 return; /* not supported by OS */ 680 return; /* not supported by OS */
689 } 681 }
690 if ((GNUNET_OK != 682 if ((GNUNET_OK !=
691 GNUNET_NETWORK_socket_connect(ap->sock, 683 GNUNET_NETWORK_socket_connect (ap->sock,
692 ap->addr, 684 ap->addr,
693 ap->addrlen)) && 685 ap->addrlen)) &&
694 (EINPROGRESS != errno)) 686 (EINPROGRESS != errno))
695 { 687 {
696 /* maybe refused / unsupported address, try next */ 688 /* maybe refused / unsupported address, try next */
697 GNUNET_log_strerror(GNUNET_ERROR_TYPE_INFO, 689 GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO,
698 "connect"); 690 "connect");
699 GNUNET_break(GNUNET_OK == 691 GNUNET_break (GNUNET_OK ==
700 GNUNET_NETWORK_socket_close(ap->sock)); 692 GNUNET_NETWORK_socket_close (ap->sock));
701 GNUNET_free(ap); 693 GNUNET_free (ap);
702 return; 694 return;
703 } 695 }
704 GNUNET_CONTAINER_DLL_insert(cstate->ap_head, 696 GNUNET_CONTAINER_DLL_insert (cstate->ap_head,
705 cstate->ap_tail, 697 cstate->ap_tail,
706 ap); 698 ap);
707 ap->task = GNUNET_SCHEDULER_add_write_net(CONNECT_RETRY_TIMEOUT, 699 ap->task = GNUNET_SCHEDULER_add_write_net (CONNECT_RETRY_TIMEOUT,
708 ap->sock, 700 ap->sock,
709 &connect_probe_continuation, 701 &connect_probe_continuation,
710 ap); 702 ap);
711} 703}
712 704
713 705
@@ -720,8 +712,8 @@ try_connect_using_address(void *cls,
720 * @return #GNUNET_OK if the configuration is valid, #GNUNET_SYSERR if not 712 * @return #GNUNET_OK if the configuration is valid, #GNUNET_SYSERR if not
721 */ 713 */
722static int 714static int
723test_service_configuration(const char *service_name, 715test_service_configuration (const char *service_name,
724 const struct GNUNET_CONFIGURATION_Handle *cfg) 716 const struct GNUNET_CONFIGURATION_Handle *cfg)
725{ 717{
726 int ret = GNUNET_SYSERR; 718 int ret = GNUNET_SYSERR;
727 char *hostname = NULL; 719 char *hostname = NULL;
@@ -731,45 +723,45 @@ test_service_configuration(const char *service_name,
731 char *unixpath = NULL; 723 char *unixpath = NULL;
732 724
733 if ((GNUNET_OK == 725 if ((GNUNET_OK ==
734 GNUNET_CONFIGURATION_get_value_filename(cfg, 726 GNUNET_CONFIGURATION_get_value_filename (cfg,
735 service_name, 727 service_name,
736 "UNIXPATH", 728 "UNIXPATH",
737 &unixpath)) && 729 &unixpath)) &&
738 (0 < strlen(unixpath))) 730 (0 < strlen (unixpath)))
739 ret = GNUNET_OK; 731 ret = GNUNET_OK;
740 else if ((GNUNET_OK == 732 else if ((GNUNET_OK ==
741 GNUNET_CONFIGURATION_have_value(cfg, 733 GNUNET_CONFIGURATION_have_value (cfg,
742 service_name, 734 service_name,
743 "UNIXPATH"))) 735 "UNIXPATH")))
744 { 736 {
745 GNUNET_log_config_invalid(GNUNET_ERROR_TYPE_ERROR, 737 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
746 service_name, 738 service_name,
747 "UNIXPATH", 739 "UNIXPATH",
748 _("not a valid filename")); 740 _ ("not a valid filename"));
749 return GNUNET_SYSERR; /* UNIXPATH specified but invalid! */ 741 return GNUNET_SYSERR; /* UNIXPATH specified but invalid! */
750 } 742 }
751 GNUNET_free_non_null(unixpath); 743 GNUNET_free_non_null (unixpath);
752#endif 744#endif
753 745
754 if ((GNUNET_YES == 746 if ((GNUNET_YES ==
755 GNUNET_CONFIGURATION_have_value(cfg, 747 GNUNET_CONFIGURATION_have_value (cfg,
756 service_name, 748 service_name,
757 "PORT")) && 749 "PORT")) &&
758 (GNUNET_OK == 750 (GNUNET_OK ==
759 GNUNET_CONFIGURATION_get_value_number(cfg, 751 GNUNET_CONFIGURATION_get_value_number (cfg,
760 service_name, 752 service_name,
761 "PORT", 753 "PORT",
762 &port)) && 754 &port)) &&
763 (port <= 65535) && 755 (port <= 65535) &&
764 (0 != port) && 756 (0 != port) &&
765 (GNUNET_OK == 757 (GNUNET_OK ==
766 GNUNET_CONFIGURATION_get_value_string(cfg, 758 GNUNET_CONFIGURATION_get_value_string (cfg,
767 service_name, 759 service_name,
768 "HOSTNAME", 760 "HOSTNAME",
769 &hostname)) && 761 &hostname)) &&
770 (0 != strlen(hostname))) 762 (0 != strlen (hostname)))
771 ret = GNUNET_OK; 763 ret = GNUNET_OK;
772 GNUNET_free_non_null(hostname); 764 GNUNET_free_non_null (hostname);
773 return ret; 765 return ret;
774} 766}
775 767
@@ -780,7 +772,7 @@ test_service_configuration(const char *service_name,
780 * @param cls the `struct ClientState` to try to connect to the service 772 * @param cls the `struct ClientState` to try to connect to the service
781 */ 773 */
782static void 774static void
783start_connect(void *cls) 775start_connect (void *cls)
784{ 776{
785 struct ClientState *cstate = cls; 777 struct ClientState *cstate = cls;
786 778
@@ -788,41 +780,41 @@ start_connect(void *cls)
788#if 0 780#if 0
789 /* Never use a local source if a proxy is configured */ 781 /* Never use a local source if a proxy is configured */
790 if (GNUNET_YES == 782 if (GNUNET_YES ==
791 GNUNET_SOCKS_check_service(cstate->service_name, 783 GNUNET_SOCKS_check_service (cstate->service_name,
792 cstate->cfg)) 784 cstate->cfg))
793 { 785 {
794 socks_connect(cstate); 786 socks_connect (cstate);
795 return; 787 return;
796 } 788 }
797#endif 789#endif
798 790
799 if ((0 == (cstate->attempts++ % 2)) || 791 if ((0 == (cstate->attempts++ % 2)) ||
800 (0 == cstate->port) || 792 (0 == cstate->port) ||
801 (NULL == cstate->hostname)) 793 (NULL == cstate->hostname))
794 {
795 /* on even rounds, try UNIX first, or always
796 if we do not have a DNS name and TCP port. */
797 cstate->sock = try_unixpath (cstate->service_name,
798 cstate->cfg);
799 if (NULL != cstate->sock)
802 { 800 {
803 /* on even rounds, try UNIX first, or always 801 connect_success_continuation (cstate);
804 if we do not have a DNS name and TCP port. */ 802 return;
805 cstate->sock = try_unixpath(cstate->service_name,
806 cstate->cfg);
807 if (NULL != cstate->sock)
808 {
809 connect_success_continuation(cstate);
810 return;
811 }
812 } 803 }
804 }
813 if ((NULL == cstate->hostname) || 805 if ((NULL == cstate->hostname) ||
814 (0 == cstate->port)) 806 (0 == cstate->port))
815 { 807 {
816 /* All options failed. Boo! */ 808 /* All options failed. Boo! */
817 connect_fail_continuation(cstate); 809 connect_fail_continuation (cstate);
818 return; 810 return;
819 } 811 }
820 cstate->dns_active 812 cstate->dns_active
821 = GNUNET_RESOLVER_ip_get(cstate->hostname, 813 = GNUNET_RESOLVER_ip_get (cstate->hostname,
822 AF_UNSPEC, 814 AF_UNSPEC,
823 CONNECT_RETRY_TIMEOUT, 815 CONNECT_RETRY_TIMEOUT,
824 &try_connect_using_address, 816 &try_connect_using_address,
825 cstate); 817 cstate);
826} 818}
827 819
828 820
@@ -834,30 +826,30 @@ start_connect(void *cls)
834 * @param impl_state our `struct ClientState` 826 * @param impl_state our `struct ClientState`
835 */ 827 */
836static void 828static void
837connection_client_send_impl(struct GNUNET_MQ_Handle *mq, 829connection_client_send_impl (struct GNUNET_MQ_Handle *mq,
838 const struct GNUNET_MessageHeader *msg, 830 const struct GNUNET_MessageHeader *msg,
839 void *impl_state) 831 void *impl_state)
840{ 832{
841 struct ClientState *cstate = impl_state; 833 struct ClientState *cstate = impl_state;
842 834
843 (void)mq; 835 (void) mq;
844 /* only one message at a time allowed */ 836 /* only one message at a time allowed */
845 GNUNET_assert(NULL == cstate->msg); 837 GNUNET_assert (NULL == cstate->msg);
846 GNUNET_assert(NULL == cstate->send_task); 838 GNUNET_assert (NULL == cstate->send_task);
847 cstate->msg = msg; 839 cstate->msg = msg;
848 cstate->msg_off = 0; 840 cstate->msg_off = 0;
849 if (NULL == cstate->sock) 841 if (NULL == cstate->sock)
850 { 842 {
851 LOG(GNUNET_ERROR_TYPE_DEBUG, 843 LOG (GNUNET_ERROR_TYPE_DEBUG,
852 "message of type %u waiting for socket\n", 844 "message of type %u waiting for socket\n",
853 ntohs(msg->type)); 845 ntohs (msg->type));
854 return; /* still waiting for connection */ 846 return; /* still waiting for connection */
855 } 847 }
856 cstate->send_task 848 cstate->send_task
857 = GNUNET_SCHEDULER_add_write_net(GNUNET_TIME_UNIT_FOREVER_REL, 849 = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
858 cstate->sock, 850 cstate->sock,
859 &transmit_ready, 851 &transmit_ready,
860 cstate); 852 cstate);
861} 853}
862 854
863 855
@@ -868,20 +860,186 @@ connection_client_send_impl(struct GNUNET_MQ_Handle *mq,
868 * @param impl_state our `struct ClientState` 860 * @param impl_state our `struct ClientState`
869 */ 861 */
870static void 862static void
871connection_client_cancel_impl(struct GNUNET_MQ_Handle *mq, 863connection_client_cancel_impl (struct GNUNET_MQ_Handle *mq,
872 void *impl_state) 864 void *impl_state)
873{ 865{
874 struct ClientState *cstate = impl_state; 866 struct ClientState *cstate = impl_state;
875 867
876 (void)mq; 868 (void) mq;
877 GNUNET_assert(NULL != cstate->msg); 869 GNUNET_assert (NULL != cstate->msg);
878 GNUNET_assert(0 == cstate->msg_off); 870 GNUNET_assert (0 == cstate->msg_off);
879 cstate->msg = NULL; 871 cstate->msg = NULL;
880 if (NULL != cstate->send_task) 872 if (NULL != cstate->send_task)
873 {
874 GNUNET_SCHEDULER_cancel (cstate->send_task);
875 cstate->send_task = NULL;
876 }
877}
878
879
880/**
881 * Test if the port or UNIXPATH of the given @a service_name
882 * is in use and thus (most likely) the respective service is up.
883 *
884 * @param cfg our configuration
885 * @param service_name name of the service to connect to
886 * @return #GNUNET_YES if the service is (likely) up,
887 * #GNUNET_NO if the service is (definitively) down,
888 * #GNUNET_SYSERR if the configuration does not give us
889 * the necessary information about the service, or if
890 * we could not check (i.e. socket() failed)
891 */
892int
893GNUNET_CLIENT_test (const struct GNUNET_CONFIGURATION_Handle *cfg,
894 const char *service_name)
895{
896 char *hostname = NULL;
897 unsigned long long port;
898 int ret;
899
900#if AF_UNIX
901 {
902 char *unixpath = NULL;
903
904 if (GNUNET_OK ==
905 GNUNET_CONFIGURATION_get_value_filename (cfg,
906 service_name,
907 "UNIXPATH",
908 &unixpath))
881 { 909 {
882 GNUNET_SCHEDULER_cancel(cstate->send_task); 910 if (0 == strlen (unixpath))
883 cstate->send_task = NULL; 911 {
912 GNUNET_free (unixpath);
913 return GNUNET_SYSERR; /* empty string not OK */
914 }
915 if (0 == access (unixpath,
916 F_OK))
917 {
918 GNUNET_free (unixpath);
919 return GNUNET_OK; /* file exists, we assume service is running */
920 }
921 GNUNET_free (unixpath);
922 }
923 else if (GNUNET_OK ==
924 GNUNET_CONFIGURATION_have_value (cfg,
925 service_name,
926 "UNIXPATH"))
927 {
928 /* UNIXPATH specified but not a valid path! */
929 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
930 service_name,
931 "UNIXPATH",
932 _ ("not a valid filename"));
933 return GNUNET_SYSERR;
884 } 934 }
935 }
936#endif
937
938 if ( (GNUNET_OK !=
939 GNUNET_CONFIGURATION_get_value_number (cfg,
940 service_name,
941 "PORT",
942 &port)) ||
943 (port > 65535) ||
944 (0 == port) )
945 {
946 return GNUNET_SYSERR;
947 }
948 if (GNUNET_OK ==
949 GNUNET_CONFIGURATION_get_value_string (cfg,
950 service_name,
951 "HOSTNAME",
952 &hostname))
953 {
954 /* We always assume remotes are up */
955 ret = GNUNET_YES;
956 }
957 else
958 {
959 /* We look for evidence the service is up */
960 ret = GNUNET_NO;
961 }
962 if ( (NULL == hostname) ||
963 (0 == strcasecmp (hostname,
964 "localhost")) ||
965 (0 == strcasecmp (hostname,
966 "ip6-localnet")) )
967 {
968 /* service runs on loopback */
969 struct sockaddr_in v4;
970 struct sockaddr_in6 v6;
971 int sock;
972
973 memset (&v4, 0, sizeof (v4));
974 memset (&v6, 0, sizeof (v6));
975 v4.sin_family = AF_INET;
976 v4.sin_port = htons ((uint16_t) port);
977#if HAVE_SOCKADDR_IN_SUN_LEN
978 v4.sin_len = (u_char) sizeof(struct sockaddr_in);
979#endif
980 inet_pton (AF_INET,
981 "127.0.0.1",
982 &v4.sin_addr);
983 ret = GNUNET_NO;
984 sock = socket (AF_INET,
985 SOCK_STREAM,
986 0);
987 if (-1 != sock)
988 {
989 if (0 != bind (sock,
990 (struct sockaddr *) &v4,
991 sizeof (v4)))
992 {
993 /* bind failed, so someone is listening! */
994 ret = GNUNET_YES;
995 }
996 (void) close (sock);
997 }
998 else
999 {
1000 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
1001 "socket");
1002 if (GNUNET_NO == ret)
1003 ret = GNUNET_SYSERR;
1004 }
1005 v6.sin6_family = AF_INET6;
1006 v6.sin6_port = htons ((uint16_t) port);
1007#if HAVE_SOCKADDR_IN_SUN_LEN
1008 v6.sin6_len = (u_char) sizeof(struct sockaddr_in6);
1009#endif
1010 inet_pton (AF_INET6,
1011 "::1",
1012 &v6.sin6_addr);
1013 sock = socket (AF_INET6,
1014 SOCK_STREAM,
1015 0);
1016 if (-1 != sock)
1017 {
1018 if (0 != bind (sock,
1019 (struct sockaddr *) &v6,
1020 sizeof (v6)))
1021 {
1022 /* bind failed, so someone is listening! */
1023 ret = GNUNET_YES;
1024 }
1025 (void) close (sock);
1026 }
1027 else
1028 {
1029 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
1030 "socket");
1031 /* not changing 'ret' intentionally here, as
1032 v4 succeeding and v6 failing just means we
1033 should use v4 */
1034 }
1035 }
1036 else
1037 {
1038 /* service running remotely */
1039 ret = GNUNET_OK;
1040 }
1041 GNUNET_free_non_null (hostname);
1042 return ret;
885} 1043}
886 1044
887 1045
@@ -897,57 +1055,57 @@ connection_client_cancel_impl(struct GNUNET_MQ_Handle *mq,
897 * @return the message queue, NULL on error 1055 * @return the message queue, NULL on error
898 */ 1056 */
899struct GNUNET_MQ_Handle * 1057struct GNUNET_MQ_Handle *
900GNUNET_CLIENT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, 1058GNUNET_CLIENT_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
901 const char *service_name, 1059 const char *service_name,
902 const struct GNUNET_MQ_MessageHandler *handlers, 1060 const struct GNUNET_MQ_MessageHandler *handlers,
903 GNUNET_MQ_ErrorHandler error_handler, 1061 GNUNET_MQ_ErrorHandler error_handler,
904 void *error_handler_cls) 1062 void *error_handler_cls)
905{ 1063{
906 struct ClientState *cstate; 1064 struct ClientState *cstate;
907 1065
908 if (GNUNET_OK != 1066 if (GNUNET_OK !=
909 test_service_configuration(service_name, 1067 test_service_configuration (service_name,
910 cfg)) 1068 cfg))
911 return NULL; 1069 return NULL;
912 cstate = GNUNET_new(struct ClientState); 1070 cstate = GNUNET_new (struct ClientState);
913 cstate->service_name = GNUNET_strdup(service_name); 1071 cstate->service_name = GNUNET_strdup (service_name);
914 cstate->cfg = cfg; 1072 cstate->cfg = cfg;
915 cstate->retry_task = GNUNET_SCHEDULER_add_now(&start_connect, 1073 cstate->retry_task = GNUNET_SCHEDULER_add_now (&start_connect,
916 cstate); 1074 cstate);
917 cstate->mst = GNUNET_MST_create(&recv_message, 1075 cstate->mst = GNUNET_MST_create (&recv_message,
918 cstate); 1076 cstate);
919 if (GNUNET_YES == 1077 if (GNUNET_YES ==
920 GNUNET_CONFIGURATION_have_value(cfg, 1078 GNUNET_CONFIGURATION_have_value (cfg,
921 service_name, 1079 service_name,
922 "PORT")) 1080 "PORT"))
923 { 1081 {
924 if (!((GNUNET_OK != 1082 if (! ((GNUNET_OK !=
925 GNUNET_CONFIGURATION_get_value_number(cfg, 1083 GNUNET_CONFIGURATION_get_value_number (cfg,
926 service_name, 1084 service_name,
927 "PORT", 1085 "PORT",
928 &cstate->port)) || 1086 &cstate->port)) ||
929 (cstate->port > 65535) || 1087 (cstate->port > 65535) ||
930 (GNUNET_OK != 1088 (GNUNET_OK !=
931 GNUNET_CONFIGURATION_get_value_string(cfg, 1089 GNUNET_CONFIGURATION_get_value_string (cfg,
932 service_name, 1090 service_name,
933 "HOSTNAME", 1091 "HOSTNAME",
934 &cstate->hostname))) && 1092 &cstate->hostname))) &&
935 (0 == strlen(cstate->hostname))) 1093 (0 == strlen (cstate->hostname)))
936 { 1094 {
937 GNUNET_free(cstate->hostname); 1095 GNUNET_free (cstate->hostname);
938 cstate->hostname = NULL; 1096 cstate->hostname = NULL;
939 LOG(GNUNET_ERROR_TYPE_WARNING, 1097 LOG (GNUNET_ERROR_TYPE_WARNING,
940 _("Need a non-empty hostname for service `%s'.\n"), 1098 _ ("Need a non-empty hostname for service `%s'.\n"),
941 service_name); 1099 service_name);
942 }
943 } 1100 }
944 cstate->mq = GNUNET_MQ_queue_for_callbacks(&connection_client_send_impl, 1101 }
945 &connection_client_destroy_impl, 1102 cstate->mq = GNUNET_MQ_queue_for_callbacks (&connection_client_send_impl,
946 &connection_client_cancel_impl, 1103 &connection_client_destroy_impl,
947 cstate, 1104 &connection_client_cancel_impl,
948 handlers, 1105 cstate,
949 error_handler, 1106 handlers,
950 error_handler_cls); 1107 error_handler,
1108 error_handler_cls);
951 return cstate->mq; 1109 return cstate->mq;
952} 1110}
953 1111
diff --git a/src/util/service.c b/src/util/service.c
index b0f4ea289..21b99547c 100644
--- a/src/util/service.c
+++ b/src/util/service.c
@@ -37,19 +37,20 @@
37#endif 37#endif
38 38
39 39
40#define LOG(kind, ...) GNUNET_log_from(kind, "util-service", __VA_ARGS__) 40#define LOG(kind, ...) GNUNET_log_from (kind, "util-service", __VA_ARGS__)
41 41
42#define LOG_STRERROR(kind, syscall) \ 42#define LOG_STRERROR(kind, syscall) \
43 GNUNET_log_from_strerror(kind, "util-service", syscall) 43 GNUNET_log_from_strerror (kind, "util-service", syscall)
44 44
45#define LOG_STRERROR_FILE(kind, syscall, filename) \ 45#define LOG_STRERROR_FILE(kind, syscall, filename) \
46 GNUNET_log_from_strerror_file(kind, "util-service", syscall, filename) 46 GNUNET_log_from_strerror_file (kind, "util-service", syscall, filename)
47 47
48 48
49/** 49/**
50 * Information the service tracks per listen operation. 50 * Information the service tracks per listen operation.
51 */ 51 */
52struct ServiceListenContext { 52struct ServiceListenContext
53{
53 /** 54 /**
54 * Kept in a DLL. 55 * Kept in a DLL.
55 */ 56 */
@@ -80,7 +81,8 @@ struct ServiceListenContext {
80/** 81/**
81 * Reasons why we might be suspended. 82 * Reasons why we might be suspended.
82 */ 83 */
83enum SuspendReason { 84enum SuspendReason
85{
84 /** 86 /**
85 * We are running normally. 87 * We are running normally.
86 */ 88 */
@@ -111,7 +113,8 @@ enum SuspendReason {
111/** 113/**
112 * Handle to a service. 114 * Handle to a service.
113 */ 115 */
114struct GNUNET_SERVICE_Handle { 116struct GNUNET_SERVICE_Handle
117{
115 /** 118 /**
116 * Our configuration. 119 * Our configuration.
117 */ 120 */
@@ -172,6 +175,7 @@ struct GNUNET_SERVICE_Handle {
172 */ 175 */
173 void *task_cls; 176 void *task_cls;
174 177
178
175 /** 179 /**
176 * IPv4 addresses that are not allowed to connect. 180 * IPv4 addresses that are not allowed to connect.
177 */ 181 */
@@ -243,7 +247,8 @@ struct GNUNET_SERVICE_Handle {
243/** 247/**
244 * Handle to a client that is connected to a service. 248 * Handle to a client that is connected to a service.
245 */ 249 */
246struct GNUNET_SERVICE_Client { 250struct GNUNET_SERVICE_Client
251{
247 /** 252 /**
248 * Kept in a DLL. 253 * Kept in a DLL.
249 */ 254 */
@@ -353,15 +358,15 @@ struct GNUNET_SERVICE_Client {
353 * @return #GNUNET_YES if we have non-monitoring clients left 358 * @return #GNUNET_YES if we have non-monitoring clients left
354 */ 359 */
355static int 360static int
356have_non_monitor_clients(struct GNUNET_SERVICE_Handle *sh) 361have_non_monitor_clients (struct GNUNET_SERVICE_Handle *sh)
357{ 362{
358 for (struct GNUNET_SERVICE_Client *client = sh->clients_head; NULL != client; 363 for (struct GNUNET_SERVICE_Client *client = sh->clients_head; NULL != client;
359 client = client->next) 364 client = client->next)
360 { 365 {
361 if (client->is_monitor) 366 if (client->is_monitor)
362 continue; 367 continue;
363 return GNUNET_YES; 368 return GNUNET_YES;
364 } 369 }
365 return GNUNET_NO; 370 return GNUNET_NO;
366} 371}
367 372
@@ -374,20 +379,20 @@ have_non_monitor_clients(struct GNUNET_SERVICE_Handle *sh)
374 * @param sr reason for suspending accepting connections 379 * @param sr reason for suspending accepting connections
375 */ 380 */
376static void 381static void
377do_suspend(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr) 382do_suspend (struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr)
378{ 383{
379 struct ServiceListenContext *slc; 384 struct ServiceListenContext *slc;
380 385
381 GNUNET_assert(0 == (sh->suspend_state & sr)); 386 GNUNET_assert (0 == (sh->suspend_state & sr));
382 sh->suspend_state |= sr; 387 sh->suspend_state |= sr;
383 for (slc = sh->slc_head; NULL != slc; slc = slc->next) 388 for (slc = sh->slc_head; NULL != slc; slc = slc->next)
389 {
390 if (NULL != slc->listen_task)
384 { 391 {
385 if (NULL != slc->listen_task) 392 GNUNET_SCHEDULER_cancel (slc->listen_task);
386 { 393 slc->listen_task = NULL;
387 GNUNET_SCHEDULER_cancel(slc->listen_task);
388 slc->listen_task = NULL;
389 }
390 } 394 }
395 }
391} 396}
392 397
393 398
@@ -400,29 +405,27 @@ do_suspend(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr)
400 * @param cls our `struct GNUNET_SERVICE_Handle` 405 * @param cls our `struct GNUNET_SERVICE_Handle`
401 */ 406 */
402static void 407static void
403service_shutdown(void *cls) 408service_shutdown (void *cls)
404{ 409{
405 struct GNUNET_SERVICE_Handle *sh = cls; 410 struct GNUNET_SERVICE_Handle *sh = cls;
406 411
407 switch (sh->options) 412 switch (sh->options & GNUNET_SERVICE_OPTION_SHUTDOWN_BITMASK)
408 { 413 {
409 case GNUNET_SERVICE_OPTION_NONE: 414 case GNUNET_SERVICE_OPTION_NONE:
410 GNUNET_SERVICE_shutdown(sh); 415 GNUNET_SERVICE_shutdown (sh);
411 break; 416 break;
412 417 case GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN:
413 case GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN: 418 /* This task should never be run if we are using
414 /* This task should never be run if we are using 419 the manual shutdown. */
415 the manual shutdown. */ 420 GNUNET_assert (0);
416 GNUNET_assert(0); 421 break;
417 break; 422 case GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN:
418 423 if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN))
419 case GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN: 424 do_suspend (sh, SUSPEND_STATE_SHUTDOWN);
420 if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN)) 425 if (GNUNET_NO == have_non_monitor_clients (sh))
421 do_suspend(sh, SUSPEND_STATE_SHUTDOWN); 426 GNUNET_SERVICE_shutdown (sh);
422 if (GNUNET_NO == have_non_monitor_clients(sh)) 427 break;
423 GNUNET_SERVICE_shutdown(sh); 428 }
424 break;
425 }
426} 429}
427 430
428 431
@@ -434,8 +437,8 @@ service_shutdown(void *cls)
434 * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is 437 * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is
435 */ 438 */
436static int 439static int
437check_ipv4_listed(const struct GNUNET_STRINGS_IPv4NetworkPolicy *list, 440check_ipv4_listed (const struct GNUNET_STRINGS_IPv4NetworkPolicy *list,
438 const struct in_addr *add) 441 const struct in_addr *add)
439{ 442{
440 unsigned int i; 443 unsigned int i;
441 444
@@ -443,12 +446,12 @@ check_ipv4_listed(const struct GNUNET_STRINGS_IPv4NetworkPolicy *list,
443 return GNUNET_NO; 446 return GNUNET_NO;
444 i = 0; 447 i = 0;
445 while ((0 != list[i].network.s_addr) || (0 != list[i].netmask.s_addr)) 448 while ((0 != list[i].network.s_addr) || (0 != list[i].netmask.s_addr))
446 { 449 {
447 if ((add->s_addr & list[i].netmask.s_addr) == 450 if ((add->s_addr & list[i].netmask.s_addr) ==
448 (list[i].network.s_addr & list[i].netmask.s_addr)) 451 (list[i].network.s_addr & list[i].netmask.s_addr))
449 return GNUNET_YES; 452 return GNUNET_YES;
450 i++; 453 i++;
451 } 454 }
452 return GNUNET_NO; 455 return GNUNET_NO;
453} 456}
454 457
@@ -461,8 +464,8 @@ check_ipv4_listed(const struct GNUNET_STRINGS_IPv4NetworkPolicy *list,
461 * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is 464 * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is
462 */ 465 */
463static int 466static int
464check_ipv6_listed(const struct GNUNET_STRINGS_IPv6NetworkPolicy *list, 467check_ipv6_listed (const struct GNUNET_STRINGS_IPv6NetworkPolicy *list,
465 const struct in6_addr *ip) 468 const struct in6_addr *ip)
466{ 469{
467 unsigned int i; 470 unsigned int i;
468 unsigned int j; 471 unsigned int j;
@@ -471,17 +474,17 @@ check_ipv6_listed(const struct GNUNET_STRINGS_IPv6NetworkPolicy *list,
471 return GNUNET_NO; 474 return GNUNET_NO;
472 i = 0; 475 i = 0;
473NEXT: 476NEXT:
474 while (0 != GNUNET_is_zero(&list[i].network)) 477 while (0 != GNUNET_is_zero (&list[i].network))
475 { 478 {
476 for (j = 0; j < sizeof(struct in6_addr) / sizeof(int); j++) 479 for (j = 0; j < sizeof(struct in6_addr) / sizeof(int); j++)
477 if (((((int *)ip)[j] & ((int *)&list[i].netmask)[j])) != 480 if (((((int *) ip)[j] & ((int *) &list[i].netmask)[j])) !=
478 (((int *)&list[i].network)[j] & ((int *)&list[i].netmask)[j])) 481 (((int *) &list[i].network)[j] & ((int *) &list[i].netmask)[j]))
479 { 482 {
480 i++; 483 i++;
481 goto NEXT; 484 goto NEXT;
482 } 485 }
483 return GNUNET_YES; 486 return GNUNET_YES;
484 } 487 }
485 return GNUNET_NO; 488 return GNUNET_NO;
486} 489}
487 490
@@ -493,63 +496,63 @@ NEXT:
493 * @param cls the `struct GNUNET_SERVICE_Client *` to send to 496 * @param cls the `struct GNUNET_SERVICE_Client *` to send to
494 */ 497 */
495static void 498static void
496do_send(void *cls) 499do_send (void *cls)
497{ 500{
498 struct GNUNET_SERVICE_Client *client = cls; 501 struct GNUNET_SERVICE_Client *client = cls;
499 ssize_t ret; 502 ssize_t ret;
500 size_t left; 503 size_t left;
501 const char *buf; 504 const char *buf;
502 505
503 LOG(GNUNET_ERROR_TYPE_DEBUG, 506 LOG (GNUNET_ERROR_TYPE_DEBUG,
504 "service: sending message with type %u\n", 507 "service: sending message with type %u\n",
505 ntohs(client->msg->type)); 508 ntohs (client->msg->type));
506 509
507 510
508 client->send_task = NULL; 511 client->send_task = NULL;
509 buf = (const char *)client->msg; 512 buf = (const char *) client->msg;
510 left = ntohs(client->msg->size) - client->msg_pos; 513 left = ntohs (client->msg->size) - client->msg_pos;
511 ret = GNUNET_NETWORK_socket_send(client->sock, &buf[client->msg_pos], left); 514 ret = GNUNET_NETWORK_socket_send (client->sock, &buf[client->msg_pos], left);
512 GNUNET_assert(ret <= (ssize_t)left); 515 GNUNET_assert (ret <= (ssize_t) left);
513 if (0 == ret) 516 if (0 == ret)
514 { 517 {
515 LOG(GNUNET_ERROR_TYPE_DEBUG, "no data send"); 518 LOG (GNUNET_ERROR_TYPE_DEBUG, "no data send");
516 GNUNET_MQ_inject_error(client->mq, GNUNET_MQ_ERROR_WRITE); 519 GNUNET_MQ_inject_error (client->mq, GNUNET_MQ_ERROR_WRITE);
517 return; 520 return;
518 } 521 }
519 if (-1 == ret) 522 if (-1 == ret)
523 {
524 if ((EAGAIN == errno) || (EINTR == errno))
520 { 525 {
521 if ((EAGAIN == errno) || (EINTR == errno)) 526 /* ignore */
522 { 527 ret = 0;
523 /* ignore */
524 ret = 0;
525 }
526 else
527 {
528 if (EPIPE != errno)
529 GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING, "send");
530 LOG(GNUNET_ERROR_TYPE_DEBUG,
531 "socket send returned with error code %i",
532 errno);
533 GNUNET_MQ_inject_error(client->mq, GNUNET_MQ_ERROR_WRITE);
534 return;
535 }
536 }
537 if (0 == client->msg_pos)
538 {
539 GNUNET_MQ_impl_send_in_flight(client->mq);
540 } 528 }
541 client->msg_pos += ret; 529 else
542 if (left > (size_t)ret)
543 { 530 {
544 GNUNET_assert(NULL == client->drop_task); 531 if (EPIPE != errno)
545 client->send_task = 532 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "send");
546 GNUNET_SCHEDULER_add_write_net(GNUNET_TIME_UNIT_FOREVER_REL, 533 LOG (GNUNET_ERROR_TYPE_DEBUG,
547 client->sock, 534 "socket send returned with error code %i",
548 &do_send, 535 errno);
549 client); 536 GNUNET_MQ_inject_error (client->mq, GNUNET_MQ_ERROR_WRITE);
550 return; 537 return;
551 } 538 }
552 GNUNET_MQ_impl_send_continue(client->mq); 539 }
540 if (0 == client->msg_pos)
541 {
542 GNUNET_MQ_impl_send_in_flight (client->mq);
543 }
544 client->msg_pos += ret;
545 if (left > (size_t) ret)
546 {
547 GNUNET_assert (NULL == client->drop_task);
548 client->send_task =
549 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
550 client->sock,
551 &do_send,
552 client);
553 return;
554 }
555 GNUNET_MQ_impl_send_continue (client->mq);
553} 556}
554 557
555 558
@@ -562,27 +565,27 @@ do_send(void *cls)
562 * @param impl_state our `struct GNUNET_SERVICE_Client *` 565 * @param impl_state our `struct GNUNET_SERVICE_Client *`
563 */ 566 */
564static void 567static void
565service_mq_send(struct GNUNET_MQ_Handle *mq, 568service_mq_send (struct GNUNET_MQ_Handle *mq,
566 const struct GNUNET_MessageHeader *msg, 569 const struct GNUNET_MessageHeader *msg,
567 void *impl_state) 570 void *impl_state)
568{ 571{
569 struct GNUNET_SERVICE_Client *client = impl_state; 572 struct GNUNET_SERVICE_Client *client = impl_state;
570 573
571 (void)mq; 574 (void) mq;
572 if (NULL != client->drop_task) 575 if (NULL != client->drop_task)
573 return; /* we're going down right now, do not try to send */ 576 return; /* we're going down right now, do not try to send */
574 GNUNET_assert(NULL == client->send_task); 577 GNUNET_assert (NULL == client->send_task);
575 LOG(GNUNET_ERROR_TYPE_DEBUG, 578 LOG (GNUNET_ERROR_TYPE_DEBUG,
576 "Sending message of type %u and size %u to client\n", 579 "Sending message of type %u and size %u to client\n",
577 ntohs(msg->type), 580 ntohs (msg->type),
578 ntohs(msg->size)); 581 ntohs (msg->size));
579 client->msg = msg; 582 client->msg = msg;
580 client->msg_pos = 0; 583 client->msg_pos = 0;
581 client->send_task = 584 client->send_task =
582 GNUNET_SCHEDULER_add_write_net(GNUNET_TIME_UNIT_FOREVER_REL, 585 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
583 client->sock, 586 client->sock,
584 &do_send, 587 &do_send,
585 client); 588 client);
586} 589}
587 590
588 591
@@ -593,14 +596,14 @@ service_mq_send(struct GNUNET_MQ_Handle *mq,
593 * @param impl_state state specific to the implementation 596 * @param impl_state state specific to the implementation
594 */ 597 */
595static void 598static void
596service_mq_cancel(struct GNUNET_MQ_Handle *mq, void *impl_state) 599service_mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
597{ 600{
598 struct GNUNET_SERVICE_Client *client = impl_state; 601 struct GNUNET_SERVICE_Client *client = impl_state;
599 602
600 (void)mq; 603 (void) mq;
601 GNUNET_assert(0 == client->msg_pos); 604 GNUNET_assert (0 == client->msg_pos);
602 client->msg = NULL; 605 client->msg = NULL;
603 GNUNET_SCHEDULER_cancel(client->send_task); 606 GNUNET_SCHEDULER_cancel (client->send_task);
604 client->send_task = NULL; 607 client->send_task = NULL;
605} 608}
606 609
@@ -615,20 +618,20 @@ service_mq_cancel(struct GNUNET_MQ_Handle *mq, void *impl_state)
615 * @param error error code 618 * @param error error code
616 */ 619 */
617static void 620static void
618service_mq_error_handler(void *cls, enum GNUNET_MQ_Error error) 621service_mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
619{ 622{
620 struct GNUNET_SERVICE_Client *client = cls; 623 struct GNUNET_SERVICE_Client *client = cls;
621 struct GNUNET_SERVICE_Handle *sh = client->sh; 624 struct GNUNET_SERVICE_Handle *sh = client->sh;
622 625
623 if ((GNUNET_MQ_ERROR_NO_MATCH == error) && (GNUNET_NO == sh->require_found)) 626 if ((GNUNET_MQ_ERROR_NO_MATCH == error) && (GNUNET_NO == sh->require_found))
624 { 627 {
625 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 628 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
626 "No handler for message of type %u found\n", 629 "No handler for message of type %u found\n",
627 (unsigned int)client->warn_type); 630 (unsigned int) client->warn_type);
628 GNUNET_SERVICE_client_continue(client); 631 GNUNET_SERVICE_client_continue (client);
629 return; /* ignore error */ 632 return; /* ignore error */
630 } 633 }
631 GNUNET_SERVICE_client_drop(client); 634 GNUNET_SERVICE_client_drop (client);
632} 635}
633 636
634 637
@@ -638,24 +641,24 @@ service_mq_error_handler(void *cls, enum GNUNET_MQ_Error error)
638 * @param cls our `struct GNUNET_SERVICE_Client *` to process more requests from 641 * @param cls our `struct GNUNET_SERVICE_Client *` to process more requests from
639 */ 642 */
640static void 643static void
641warn_no_client_continue(void *cls) 644warn_no_client_continue (void *cls)
642{ 645{
643 struct GNUNET_SERVICE_Client *client = cls; 646 struct GNUNET_SERVICE_Client *client = cls;
644 647
645 GNUNET_break( 648 GNUNET_break (
646 0 != 649 0 !=
647 client->warn_type); /* type should never be 0 here, as we don't use 0 */ 650 client->warn_type); /* type should never be 0 here, as we don't use 0 */
648 client->warn_task = GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_UNIT_MINUTES, 651 client->warn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
649 &warn_no_client_continue, 652 &warn_no_client_continue,
650 client); 653 client);
651 LOG( 654 LOG (
652 GNUNET_ERROR_TYPE_WARNING, 655 GNUNET_ERROR_TYPE_WARNING,
653 _( 656 _ (
654 "Processing code for message of type %u did not call `GNUNET_SERVICE_client_continue' after %s\n"), 657 "Processing code for message of type %u did not call `GNUNET_SERVICE_client_continue' after %s\n"),
655 (unsigned int)client->warn_type, 658 (unsigned int) client->warn_type,
656 GNUNET_STRINGS_relative_time_to_string(GNUNET_TIME_absolute_get_duration( 659 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (
657 client->warn_start), 660 client->warn_start),
658 GNUNET_YES)); 661 GNUNET_YES));
659} 662}
660 663
661 664
@@ -671,23 +674,23 @@ warn_no_client_continue(void *cls)
671 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the client was dropped 674 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the client was dropped
672 */ 675 */
673static int 676static int
674service_client_mst_cb(void *cls, const struct GNUNET_MessageHeader *message) 677service_client_mst_cb (void *cls, const struct GNUNET_MessageHeader *message)
675{ 678{
676 struct GNUNET_SERVICE_Client *client = cls; 679 struct GNUNET_SERVICE_Client *client = cls;
677 680
678 LOG(GNUNET_ERROR_TYPE_DEBUG, 681 LOG (GNUNET_ERROR_TYPE_DEBUG,
679 "Received message of type %u and size %u from client\n", 682 "Received message of type %u and size %u from client\n",
680 ntohs(message->type), 683 ntohs (message->type),
681 ntohs(message->size)); 684 ntohs (message->size));
682 GNUNET_assert(GNUNET_NO == client->needs_continue); 685 GNUNET_assert (GNUNET_NO == client->needs_continue);
683 client->needs_continue = GNUNET_YES; 686 client->needs_continue = GNUNET_YES;
684 client->warn_type = ntohs(message->type); 687 client->warn_type = ntohs (message->type);
685 client->warn_start = GNUNET_TIME_absolute_get(); 688 client->warn_start = GNUNET_TIME_absolute_get ();
686 GNUNET_assert(NULL == client->warn_task); 689 GNUNET_assert (NULL == client->warn_task);
687 client->warn_task = GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_UNIT_MINUTES, 690 client->warn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
688 &warn_no_client_continue, 691 &warn_no_client_continue,
689 client); 692 client);
690 GNUNET_MQ_inject_message(client->mq, message); 693 GNUNET_MQ_inject_message (client->mq, message);
691 if (NULL != client->drop_task) 694 if (NULL != client->drop_task)
692 return GNUNET_SYSERR; 695 return GNUNET_SYSERR;
693 return GNUNET_OK; 696 return GNUNET_OK;
@@ -701,37 +704,37 @@ service_client_mst_cb(void *cls, const struct GNUNET_MessageHeader *message)
701 * @param cls the `struct GNUNET_SERVICE_Client` that sent us data. 704 * @param cls the `struct GNUNET_SERVICE_Client` that sent us data.
702 */ 705 */
703static void 706static void
704service_client_recv(void *cls) 707service_client_recv (void *cls)
705{ 708{
706 struct GNUNET_SERVICE_Client *client = cls; 709 struct GNUNET_SERVICE_Client *client = cls;
707 int ret; 710 int ret;
708 711
709 client->recv_task = NULL; 712 client->recv_task = NULL;
710 ret = GNUNET_MST_read(client->mst, client->sock, GNUNET_NO, GNUNET_YES); 713 ret = GNUNET_MST_read (client->mst, client->sock, GNUNET_NO, GNUNET_YES);
711 if (GNUNET_SYSERR == ret) 714 if (GNUNET_SYSERR == ret)
715 {
716 /* client closed connection (or IO error) */
717 if (NULL == client->drop_task)
712 { 718 {
713 /* client closed connection (or IO error) */ 719 GNUNET_assert (GNUNET_NO == client->needs_continue);
714 if (NULL == client->drop_task) 720 GNUNET_SERVICE_client_drop (client);
715 {
716 GNUNET_assert(GNUNET_NO == client->needs_continue);
717 GNUNET_SERVICE_client_drop(client);
718 }
719 return;
720 } 721 }
722 return;
723 }
721 if (GNUNET_NO == ret) 724 if (GNUNET_NO == ret)
722 return; /* more messages in buffer, wait for application 725 return; /* more messages in buffer, wait for application
723 to be done processing */ 726 to be done processing */
724 GNUNET_assert(GNUNET_OK == ret); 727 GNUNET_assert (GNUNET_OK == ret);
725 if (GNUNET_YES == client->needs_continue) 728 if (GNUNET_YES == client->needs_continue)
726 return; 729 return;
727 if (NULL != client->recv_task) 730 if (NULL != client->recv_task)
728 return; 731 return;
729 /* MST needs more data, re-schedule read job */ 732 /* MST needs more data, re-schedule read job */
730 client->recv_task = 733 client->recv_task =
731 GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, 734 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
732 client->sock, 735 client->sock,
733 &service_client_recv, 736 &service_client_recv,
734 client); 737 client);
735} 738}
736 739
737 740
@@ -743,31 +746,31 @@ service_client_recv(void *cls)
743 * @param sock socket associated with the client 746 * @param sock socket associated with the client
744 */ 747 */
745static void 748static void
746start_client(struct GNUNET_SERVICE_Handle *sh, 749start_client (struct GNUNET_SERVICE_Handle *sh,
747 struct GNUNET_NETWORK_Handle *csock) 750 struct GNUNET_NETWORK_Handle *csock)
748{ 751{
749 struct GNUNET_SERVICE_Client *client; 752 struct GNUNET_SERVICE_Client *client;
750 753
751 client = GNUNET_new(struct GNUNET_SERVICE_Client); 754 client = GNUNET_new (struct GNUNET_SERVICE_Client);
752 GNUNET_CONTAINER_DLL_insert(sh->clients_head, sh->clients_tail, client); 755 GNUNET_CONTAINER_DLL_insert (sh->clients_head, sh->clients_tail, client);
753 client->sh = sh; 756 client->sh = sh;
754 client->sock = csock; 757 client->sock = csock;
755 client->mq = GNUNET_MQ_queue_for_callbacks(&service_mq_send, 758 client->mq = GNUNET_MQ_queue_for_callbacks (&service_mq_send,
756 NULL, 759 NULL,
757 &service_mq_cancel, 760 &service_mq_cancel,
758 client, 761 client,
759 sh->handlers, 762 sh->handlers,
760 &service_mq_error_handler, 763 &service_mq_error_handler,
761 client); 764 client);
762 client->mst = GNUNET_MST_create(&service_client_mst_cb, client); 765 client->mst = GNUNET_MST_create (&service_client_mst_cb, client);
763 if (NULL != sh->connect_cb) 766 if (NULL != sh->connect_cb)
764 client->user_context = sh->connect_cb(sh->cb_cls, client, client->mq); 767 client->user_context = sh->connect_cb (sh->cb_cls, client, client->mq);
765 GNUNET_MQ_set_handlers_closure(client->mq, client->user_context); 768 GNUNET_MQ_set_handlers_closure (client->mq, client->user_context);
766 client->recv_task = 769 client->recv_task =
767 GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, 770 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
768 client->sock, 771 client->sock,
769 &service_client_recv, 772 &service_client_recv,
770 client); 773 client);
771} 774}
772 775
773 776
@@ -778,83 +781,83 @@ start_client(struct GNUNET_SERVICE_Handle *sh,
778 * @param cls the `struct ServiceListenContext` of the ready listen socket 781 * @param cls the `struct ServiceListenContext` of the ready listen socket
779 */ 782 */
780static void 783static void
781accept_client(void *cls) 784accept_client (void *cls)
782{ 785{
783 struct ServiceListenContext *slc = cls; 786 struct ServiceListenContext *slc = cls;
784 struct GNUNET_SERVICE_Handle *sh = slc->sh; 787 struct GNUNET_SERVICE_Handle *sh = slc->sh;
785 788
786 slc->listen_task = NULL; 789 slc->listen_task = NULL;
787 while (1) 790 while (1)
791 {
792 struct GNUNET_NETWORK_Handle *sock;
793 const struct sockaddr_in *v4;
794 const struct sockaddr_in6 *v6;
795 struct sockaddr_storage sa;
796 socklen_t addrlen;
797 int ok;
798
799 addrlen = sizeof(sa);
800 sock = GNUNET_NETWORK_socket_accept (slc->listen_socket,
801 (struct sockaddr *) &sa,
802 &addrlen);
803 if (NULL == sock)
804 {
805 if (EMFILE == errno)
806 do_suspend (sh, SUSPEND_STATE_EMFILE);
807 else if (EAGAIN != errno)
808 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "accept");
809 break;
810 }
811 switch (sa.ss_family)
788 { 812 {
789 struct GNUNET_NETWORK_Handle *sock; 813 case AF_INET:
790 const struct sockaddr_in *v4; 814 GNUNET_assert (addrlen == sizeof(struct sockaddr_in));
791 const struct sockaddr_in6 *v6; 815 v4 = (const struct sockaddr_in *) &sa;
792 struct sockaddr_storage sa; 816 ok = (((NULL == sh->v4_allowed) ||
793 socklen_t addrlen; 817 (check_ipv4_listed (sh->v4_allowed, &v4->sin_addr))) &&
794 int ok; 818 ((NULL == sh->v4_denied) ||
795 819 (! check_ipv4_listed (sh->v4_denied, &v4->sin_addr))));
796 addrlen = sizeof(sa); 820 break;
797 sock = GNUNET_NETWORK_socket_accept(slc->listen_socket, 821
798 (struct sockaddr *)&sa, 822 case AF_INET6:
799 &addrlen); 823 GNUNET_assert (addrlen == sizeof(struct sockaddr_in6));
800 if (NULL == sock) 824 v6 = (const struct sockaddr_in6 *) &sa;
801 { 825 ok = (((NULL == sh->v6_allowed) ||
802 if (EMFILE == errno) 826 (check_ipv6_listed (sh->v6_allowed, &v6->sin6_addr))) &&
803 do_suspend(sh, SUSPEND_STATE_EMFILE); 827 ((NULL == sh->v6_denied) ||
804 else if (EAGAIN != errno) 828 (! check_ipv6_listed (sh->v6_denied, &v6->sin6_addr))));
805 GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING, "accept"); 829 break;
806 break; 830
807 } 831 case AF_UNIX:
808 switch (sa.ss_family) 832 ok = GNUNET_OK; /* controlled using file-system ACL now */
809 { 833 break;
810 case AF_INET: 834
811 GNUNET_assert(addrlen == sizeof(struct sockaddr_in)); 835 default:
812 v4 = (const struct sockaddr_in *)&sa; 836 LOG (GNUNET_ERROR_TYPE_WARNING,
813 ok = (((NULL == sh->v4_allowed) || 837 _ ("Unknown address family %d\n"),
814 (check_ipv4_listed(sh->v4_allowed, &v4->sin_addr))) && 838 sa.ss_family);
815 ((NULL == sh->v4_denied) || 839 return;
816 (!check_ipv4_listed(sh->v4_denied, &v4->sin_addr)))); 840 }
817 break; 841 if (! ok)
818 842 {
819 case AF_INET6: 843 LOG (GNUNET_ERROR_TYPE_DEBUG,
820 GNUNET_assert(addrlen == sizeof(struct sockaddr_in6)); 844 "Service rejected incoming connection from %s due to policy.\n",
821 v6 = (const struct sockaddr_in6 *)&sa; 845 GNUNET_a2s ((const struct sockaddr *) &sa, addrlen));
822 ok = (((NULL == sh->v6_allowed) || 846 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
823 (check_ipv6_listed(sh->v6_allowed, &v6->sin6_addr))) && 847 continue;
824 ((NULL == sh->v6_denied) ||
825 (!check_ipv6_listed(sh->v6_denied, &v6->sin6_addr))));
826 break;
827
828 case AF_UNIX:
829 ok = GNUNET_OK; /* controlled using file-system ACL now */
830 break;
831
832 default:
833 LOG(GNUNET_ERROR_TYPE_WARNING,
834 _("Unknown address family %d\n"),
835 sa.ss_family);
836 return;
837 }
838 if (!ok)
839 {
840 LOG(GNUNET_ERROR_TYPE_DEBUG,
841 "Service rejected incoming connection from %s due to policy.\n",
842 GNUNET_a2s((const struct sockaddr *)&sa, addrlen));
843 GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(sock));
844 continue;
845 }
846 LOG(GNUNET_ERROR_TYPE_DEBUG,
847 "Service accepted incoming connection from %s.\n",
848 GNUNET_a2s((const struct sockaddr *)&sa, addrlen));
849 start_client(slc->sh, sock);
850 } 848 }
849 LOG (GNUNET_ERROR_TYPE_DEBUG,
850 "Service accepted incoming connection from %s.\n",
851 GNUNET_a2s ((const struct sockaddr *) &sa, addrlen));
852 start_client (slc->sh, sock);
853 }
851 if (0 != sh->suspend_state) 854 if (0 != sh->suspend_state)
852 return; 855 return;
853 slc->listen_task = 856 slc->listen_task =
854 GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, 857 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
855 slc->listen_socket, 858 slc->listen_socket,
856 &accept_client, 859 &accept_client,
857 slc); 860 slc);
858} 861}
859 862
860 863
@@ -866,23 +869,23 @@ accept_client(void *cls)
866 * or #SUSPEND_STATE_NONE on first startup 869 * or #SUSPEND_STATE_NONE on first startup
867 */ 870 */
868static void 871static void
869do_resume(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr) 872do_resume (struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr)
870{ 873{
871 struct ServiceListenContext *slc; 874 struct ServiceListenContext *slc;
872 875
873 GNUNET_assert((SUSPEND_STATE_NONE == sr) || (0 != (sh->suspend_state & sr))); 876 GNUNET_assert ((SUSPEND_STATE_NONE == sr) || (0 != (sh->suspend_state & sr)));
874 sh->suspend_state -= sr; 877 sh->suspend_state -= sr;
875 if (SUSPEND_STATE_NONE != sh->suspend_state) 878 if (SUSPEND_STATE_NONE != sh->suspend_state)
876 return; 879 return;
877 for (slc = sh->slc_head; NULL != slc; slc = slc->next) 880 for (slc = sh->slc_head; NULL != slc; slc = slc->next)
878 { 881 {
879 GNUNET_assert(NULL == slc->listen_task); 882 GNUNET_assert (NULL == slc->listen_task);
880 slc->listen_task = 883 slc->listen_task =
881 GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, 884 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
882 slc->listen_socket, 885 slc->listen_socket,
883 &accept_client, 886 &accept_client,
884 slc); 887 slc);
885 } 888 }
886} 889}
887 890
888 891
@@ -894,23 +897,24 @@ do_resume(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr)
894 * @param cls our `struct GNUNET_SERVICE_Handle` 897 * @param cls our `struct GNUNET_SERVICE_Handle`
895 */ 898 */
896static void 899static void
897service_main(void *cls) 900service_main (void *cls)
898{ 901{
899 struct GNUNET_SERVICE_Handle *sh = cls; 902 struct GNUNET_SERVICE_Handle *sh = cls;
900 903
901 if (GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN != sh->options) 904 if (GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN !=
902 GNUNET_SCHEDULER_add_shutdown(&service_shutdown, sh); 905 (sh->options & GNUNET_SERVICE_OPTION_SHUTDOWN_BITMASK))
903 do_resume(sh, SUSPEND_STATE_NONE); 906 GNUNET_SCHEDULER_add_shutdown (&service_shutdown, sh);
907 do_resume (sh, SUSPEND_STATE_NONE);
904 908
905 if (-1 != sh->ready_confirm_fd) 909 if (-1 != sh->ready_confirm_fd)
906 { 910 {
907 GNUNET_break(1 == write(sh->ready_confirm_fd, ".", 1)); 911 GNUNET_break (1 == write (sh->ready_confirm_fd, ".", 1));
908 GNUNET_break(0 == close(sh->ready_confirm_fd)); 912 GNUNET_break (0 == close (sh->ready_confirm_fd));
909 sh->ready_confirm_fd = -1; 913 sh->ready_confirm_fd = -1;
910 } 914 }
911 915
912 if (NULL != sh->service_init_cb) 916 if (NULL != sh->service_init_cb)
913 sh->service_init_cb(sh->cb_cls, sh->cfg, sh); 917 sh->service_init_cb (sh->cb_cls, sh->cfg, sh);
914} 918}
915 919
916 920
@@ -924,33 +928,33 @@ service_main(void *cls)
924 * no ACL configured) 928 * no ACL configured)
925 */ 929 */
926static int 930static int
927process_acl4(struct GNUNET_STRINGS_IPv4NetworkPolicy **ret, 931process_acl4 (struct GNUNET_STRINGS_IPv4NetworkPolicy **ret,
928 struct GNUNET_SERVICE_Handle *sh, 932 struct GNUNET_SERVICE_Handle *sh,
929 const char *option) 933 const char *option)
930{ 934{
931 char *opt; 935 char *opt;
932 936
933 if (!GNUNET_CONFIGURATION_have_value(sh->cfg, sh->service_name, option)) 937 if (! GNUNET_CONFIGURATION_have_value (sh->cfg, sh->service_name, option))
934 { 938 {
935 *ret = NULL; 939 *ret = NULL;
936 return GNUNET_OK; 940 return GNUNET_OK;
937 } 941 }
938 GNUNET_break(GNUNET_OK == 942 GNUNET_break (GNUNET_OK ==
939 GNUNET_CONFIGURATION_get_value_string(sh->cfg, 943 GNUNET_CONFIGURATION_get_value_string (sh->cfg,
940 sh->service_name, 944 sh->service_name,
941 option, 945 option,
942 &opt)); 946 &opt));
943 if (NULL == (*ret = GNUNET_STRINGS_parse_ipv4_policy(opt))) 947 if (NULL == (*ret = GNUNET_STRINGS_parse_ipv4_policy (opt)))
944 { 948 {
945 LOG(GNUNET_ERROR_TYPE_WARNING, 949 LOG (GNUNET_ERROR_TYPE_WARNING,
946 _("Could not parse IPv4 network specification `%s' for `%s:%s'\n"), 950 _ ("Could not parse IPv4 network specification `%s' for `%s:%s'\n"),
947 opt, 951 opt,
948 sh->service_name, 952 sh->service_name,
949 option); 953 option);
950 GNUNET_free(opt); 954 GNUNET_free (opt);
951 return GNUNET_SYSERR; 955 return GNUNET_SYSERR;
952 } 956 }
953 GNUNET_free(opt); 957 GNUNET_free (opt);
954 return GNUNET_OK; 958 return GNUNET_OK;
955} 959}
956 960
@@ -965,33 +969,33 @@ process_acl4(struct GNUNET_STRINGS_IPv4NetworkPolicy **ret,
965 * no ACL configured) 969 * no ACL configured)
966 */ 970 */
967static int 971static int
968process_acl6(struct GNUNET_STRINGS_IPv6NetworkPolicy **ret, 972process_acl6 (struct GNUNET_STRINGS_IPv6NetworkPolicy **ret,
969 struct GNUNET_SERVICE_Handle *sh, 973 struct GNUNET_SERVICE_Handle *sh,
970 const char *option) 974 const char *option)
971{ 975{
972 char *opt; 976 char *opt;
973 977
974 if (!GNUNET_CONFIGURATION_have_value(sh->cfg, sh->service_name, option)) 978 if (! GNUNET_CONFIGURATION_have_value (sh->cfg, sh->service_name, option))
975 { 979 {
976 *ret = NULL; 980 *ret = NULL;
977 return GNUNET_OK; 981 return GNUNET_OK;
978 } 982 }
979 GNUNET_break(GNUNET_OK == 983 GNUNET_break (GNUNET_OK ==
980 GNUNET_CONFIGURATION_get_value_string(sh->cfg, 984 GNUNET_CONFIGURATION_get_value_string (sh->cfg,
981 sh->service_name, 985 sh->service_name,
982 option, 986 option,
983 &opt)); 987 &opt));
984 if (NULL == (*ret = GNUNET_STRINGS_parse_ipv6_policy(opt))) 988 if (NULL == (*ret = GNUNET_STRINGS_parse_ipv6_policy (opt)))
985 { 989 {
986 LOG(GNUNET_ERROR_TYPE_WARNING, 990 LOG (GNUNET_ERROR_TYPE_WARNING,
987 _("Could not parse IPv6 network specification `%s' for `%s:%s'\n"), 991 _ ("Could not parse IPv6 network specification `%s' for `%s:%s'\n"),
988 opt, 992 opt,
989 sh->service_name, 993 sh->service_name,
990 option); 994 option);
991 GNUNET_free(opt); 995 GNUNET_free (opt);
992 return GNUNET_SYSERR; 996 return GNUNET_SYSERR;
993 } 997 }
994 GNUNET_free(opt); 998 GNUNET_free (opt);
995 return GNUNET_OK; 999 return GNUNET_OK;
996} 1000}
997 1001
@@ -1003,34 +1007,27 @@ process_acl6(struct GNUNET_STRINGS_IPv6NetworkPolicy **ret,
1003 * @param saddrs array to update 1007 * @param saddrs array to update
1004 * @param saddrlens where to store the address length 1008 * @param saddrlens where to store the address length
1005 * @param unixpath path to add 1009 * @param unixpath path to add
1006 * @param abstract #GNUNET_YES to add an abstract UNIX domain socket. This
1007 * parameter is ignore on systems other than LINUX
1008 */ 1010 */
1009static void 1011static void
1010add_unixpath(struct sockaddr **saddrs, 1012add_unixpath (struct sockaddr **saddrs,
1011 socklen_t *saddrlens, 1013 socklen_t *saddrlens,
1012 const char *unixpath, 1014 const char *unixpath)
1013 int abstract)
1014{ 1015{
1015#ifdef AF_UNIX 1016#ifdef AF_UNIX
1016 struct sockaddr_un *un; 1017 struct sockaddr_un *un;
1017 1018
1018 un = GNUNET_new(struct sockaddr_un); 1019 un = GNUNET_new (struct sockaddr_un);
1019 un->sun_family = AF_UNIX; 1020 un->sun_family = AF_UNIX;
1020 GNUNET_strlcpy(un->sun_path, unixpath, sizeof(un->sun_path)); 1021 GNUNET_strlcpy (un->sun_path, unixpath, sizeof(un->sun_path));
1021#ifdef LINUX
1022 if (GNUNET_YES == abstract)
1023 un->sun_path[0] = '\0';
1024#endif
1025#if HAVE_SOCKADDR_UN_SUN_LEN 1022#if HAVE_SOCKADDR_UN_SUN_LEN
1026 un->sun_len = (u_char)sizeof(struct sockaddr_un); 1023 un->sun_len = (u_char) sizeof(struct sockaddr_un);
1027#endif 1024#endif
1028 *saddrs = (struct sockaddr *)un; 1025 *saddrs = (struct sockaddr *) un;
1029 *saddrlens = sizeof(struct sockaddr_un); 1026 *saddrlens = sizeof(struct sockaddr_un);
1030#else 1027#else
1031 /* this function should never be called 1028 /* this function should never be called
1032 * unless AF_UNIX is defined! */ 1029 * unless AF_UNIX is defined! */
1033 GNUNET_assert(0); 1030 GNUNET_assert (0);
1034#endif 1031#endif
1035} 1032}
1036 1033
@@ -1056,10 +1053,10 @@ add_unixpath(struct sockaddr **saddrs,
1056 * set to NULL). 1053 * set to NULL).
1057 */ 1054 */
1058static int 1055static int
1059get_server_addresses(const char *service_name, 1056get_server_addresses (const char *service_name,
1060 const struct GNUNET_CONFIGURATION_Handle *cfg, 1057 const struct GNUNET_CONFIGURATION_Handle *cfg,
1061 struct sockaddr ***addrs, 1058 struct sockaddr ***addrs,
1062 socklen_t **addr_lens) 1059 socklen_t **addr_lens)
1063{ 1060{
1064 int disablev6; 1061 int disablev6;
1065 struct GNUNET_NETWORK_Handle *desc; 1062 struct GNUNET_NETWORK_Handle *desc;
@@ -1072,7 +1069,6 @@ get_server_addresses(const char *service_name,
1072 unsigned int i; 1069 unsigned int i;
1073 int resi; 1070 int resi;
1074 int ret; 1071 int ret;
1075 int abstract;
1076 struct sockaddr **saddrs; 1072 struct sockaddr **saddrs;
1077 socklen_t *saddrlens; 1073 socklen_t *saddrlens;
1078 char *hostname; 1074 char *hostname;
@@ -1081,273 +1077,264 @@ get_server_addresses(const char *service_name,
1081 *addr_lens = NULL; 1077 *addr_lens = NULL;
1082 desc = NULL; 1078 desc = NULL;
1083 disablev6 = GNUNET_NO; 1079 disablev6 = GNUNET_NO;
1084 if ((GNUNET_NO == GNUNET_NETWORK_test_pf(PF_INET6)) || 1080 if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
1085 (GNUNET_YES == 1081 (GNUNET_YES ==
1086 GNUNET_CONFIGURATION_get_value_yesno(cfg, service_name, "DISABLEV6"))) 1082 GNUNET_CONFIGURATION_get_value_yesno (cfg, service_name, "DISABLEV6")))
1087 disablev6 = GNUNET_YES; 1083 disablev6 = GNUNET_YES;
1088 1084
1089 port = 0; 1085 port = 0;
1090 if (GNUNET_CONFIGURATION_have_value(cfg, service_name, "PORT")) 1086 if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT"))
1087 {
1088 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg,
1089 service_name,
1090 "PORT",
1091 &port))
1091 { 1092 {
1092 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number(cfg, 1093 LOG (GNUNET_ERROR_TYPE_ERROR,
1093 service_name, 1094 _ ("Require valid port number for service `%s' in configuration!\n"),
1094 "PORT", 1095 service_name);
1095 &port))
1096 {
1097 LOG(GNUNET_ERROR_TYPE_ERROR,
1098 _("Require valid port number for service `%s' in configuration!\n"),
1099 service_name);
1100 }
1101 if (port > 65535)
1102 {
1103 LOG(GNUNET_ERROR_TYPE_ERROR,
1104 _("Require valid port number for service `%s' in configuration!\n"),
1105 service_name);
1106 return GNUNET_SYSERR;
1107 }
1108 } 1096 }
1109 1097 if (port > 65535)
1110 if (GNUNET_CONFIGURATION_have_value(cfg, service_name, "BINDTO"))
1111 { 1098 {
1112 GNUNET_break(GNUNET_OK == 1099 LOG (GNUNET_ERROR_TYPE_ERROR,
1113 GNUNET_CONFIGURATION_get_value_string(cfg, 1100 _ ("Require valid port number for service `%s' in configuration!\n"),
1101 service_name);
1102 return GNUNET_SYSERR;
1103 }
1104 }
1105
1106 if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "BINDTO"))
1107 {
1108 GNUNET_break (GNUNET_OK ==
1109 GNUNET_CONFIGURATION_get_value_string (cfg,
1114 service_name, 1110 service_name,
1115 "BINDTO", 1111 "BINDTO",
1116 &hostname)); 1112 &hostname));
1117 } 1113 }
1118 else 1114 else
1119 hostname = NULL; 1115 hostname = NULL;
1120 1116
1121 unixpath = NULL; 1117 unixpath = NULL;
1122 abstract = GNUNET_NO;
1123#ifdef AF_UNIX 1118#ifdef AF_UNIX
1124 if ((GNUNET_YES == 1119 if ((GNUNET_YES ==
1125 GNUNET_CONFIGURATION_have_value(cfg, service_name, "UNIXPATH")) && 1120 GNUNET_CONFIGURATION_have_value (cfg, service_name, "UNIXPATH")) &&
1126 (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename(cfg, 1121 (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename (cfg,
1127 service_name, 1122 service_name,
1128 "UNIXPATH", 1123 "UNIXPATH",
1129 &unixpath)) && 1124 &unixpath)) &&
1130 (0 < strlen(unixpath))) 1125 (0 < strlen (unixpath)))
1126 {
1127 /* probe UNIX support */
1128 struct sockaddr_un s_un;
1129
1130 if (strlen (unixpath) >= sizeof(s_un.sun_path))
1131 { 1131 {
1132 /* probe UNIX support */ 1132 LOG (GNUNET_ERROR_TYPE_WARNING,
1133 struct sockaddr_un s_un; 1133 _ ("UNIXPATH `%s' too long, maximum length is %llu\n"),
1134 1134 unixpath,
1135 if (strlen(unixpath) >= sizeof(s_un.sun_path)) 1135 (unsigned long long) sizeof(s_un.sun_path));
1136 { 1136 unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath);
1137 LOG(GNUNET_ERROR_TYPE_WARNING, 1137 LOG (GNUNET_ERROR_TYPE_INFO, _ ("Using `%s' instead\n"), unixpath);
1138 _("UNIXPATH `%s' too long, maximum length is %llu\n"),
1139 unixpath,
1140 (unsigned long long)sizeof(s_un.sun_path));
1141 unixpath = GNUNET_NETWORK_shorten_unixpath(unixpath);
1142 LOG(GNUNET_ERROR_TYPE_INFO, _("Using `%s' instead\n"), unixpath);
1143 }
1144#ifdef LINUX
1145 abstract = GNUNET_CONFIGURATION_get_value_yesno(cfg,
1146 "TESTING",
1147 "USE_ABSTRACT_SOCKETS");
1148 if (GNUNET_SYSERR == abstract)
1149 abstract = GNUNET_NO;
1150#endif
1151 if ((GNUNET_YES != abstract) &&
1152 (GNUNET_OK != GNUNET_DISK_directory_create_for_file(unixpath)))
1153 GNUNET_log_strerror_file(GNUNET_ERROR_TYPE_ERROR, "mkdir", unixpath);
1154 } 1138 }
1139 if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (unixpath))
1140 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "mkdir", unixpath);
1141 }
1155 if (NULL != unixpath) 1142 if (NULL != unixpath)
1143 {
1144 desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
1145 if (NULL == desc)
1156 { 1146 {
1157 desc = GNUNET_NETWORK_socket_create(AF_UNIX, SOCK_STREAM, 0); 1147 if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
1158 if (NULL == desc) 1148 (EACCES == errno))
1159 { 1149 {
1160 if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) || 1150 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket");
1161 (EACCES == errno)) 1151 GNUNET_free_non_null (hostname);
1162 { 1152 GNUNET_free (unixpath);
1163 LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "socket"); 1153 return GNUNET_SYSERR;
1164 GNUNET_free_non_null(hostname); 1154 }
1165 GNUNET_free(unixpath); 1155 LOG (GNUNET_ERROR_TYPE_INFO,
1166 return GNUNET_SYSERR; 1156 _ (
1167 } 1157 "Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
1168 LOG(GNUNET_ERROR_TYPE_INFO, 1158 service_name,
1169 _( 1159 strerror (errno));
1170 "Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"), 1160 GNUNET_free (unixpath);
1171 service_name, 1161 unixpath = NULL;
1172 strerror(errno));
1173 GNUNET_free(unixpath);
1174 unixpath = NULL;
1175 }
1176 else
1177 {
1178 GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(desc));
1179 desc = NULL;
1180 }
1181 } 1162 }
1163 else
1164 {
1165 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc));
1166 desc = NULL;
1167 }
1168 }
1182#endif 1169#endif
1183 1170
1184 if ((0 == port) && (NULL == unixpath)) 1171 if ((0 == port) && (NULL == unixpath))
1172 {
1173 LOG (GNUNET_ERROR_TYPE_ERROR,
1174 _ (
1175 "Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
1176 service_name);
1177 GNUNET_free_non_null (hostname);
1178 return GNUNET_SYSERR;
1179 }
1180 if (0 == port)
1181 {
1182 saddrs = GNUNET_new_array (2, struct sockaddr *);
1183 saddrlens = GNUNET_new_array (2, socklen_t);
1184 add_unixpath (saddrs, saddrlens, unixpath);
1185 GNUNET_free_non_null (unixpath);
1186 GNUNET_free_non_null (hostname);
1187 *addrs = saddrs;
1188 *addr_lens = saddrlens;
1189 return 1;
1190 }
1191
1192 if (NULL != hostname)
1193 {
1194 LOG (GNUNET_ERROR_TYPE_DEBUG,
1195 "Resolving `%s' since that is where `%s' will bind to.\n",
1196 hostname,
1197 service_name);
1198 memset (&hints, 0, sizeof(struct addrinfo));
1199 if (disablev6)
1200 hints.ai_family = AF_INET;
1201 hints.ai_protocol = IPPROTO_TCP;
1202 if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) ||
1203 (NULL == res))
1185 { 1204 {
1186 LOG(GNUNET_ERROR_TYPE_ERROR, 1205 LOG (GNUNET_ERROR_TYPE_ERROR,
1187 _( 1206 _ ("Failed to resolve `%s': %s\n"),
1188 "Have neither PORT nor UNIXPATH for service `%s', but one is required\n"), 1207 hostname,
1189 service_name); 1208 gai_strerror (ret));
1190 GNUNET_free_non_null(hostname); 1209 GNUNET_free (hostname);
1210 GNUNET_free_non_null (unixpath);
1191 return GNUNET_SYSERR; 1211 return GNUNET_SYSERR;
1192 } 1212 }
1193 if (0 == port) 1213 next = res;
1214 i = 0;
1215 while (NULL != (pos = next))
1194 { 1216 {
1195 saddrs = GNUNET_new_array(2, struct sockaddr *); 1217 next = pos->ai_next;
1196 saddrlens = GNUNET_new_array(2, socklen_t); 1218 if ((disablev6) && (pos->ai_family == AF_INET6))
1197 add_unixpath(saddrs, saddrlens, unixpath, abstract); 1219 continue;
1198 GNUNET_free_non_null(unixpath); 1220 i++;
1199 GNUNET_free_non_null(hostname);
1200 *addrs = saddrs;
1201 *addr_lens = saddrlens;
1202 return 1;
1203 } 1221 }
1204 1222 if (0 == i)
1205 if (NULL != hostname)
1206 { 1223 {
1207 LOG(GNUNET_ERROR_TYPE_DEBUG, 1224 LOG (GNUNET_ERROR_TYPE_ERROR,
1208 "Resolving `%s' since that is where `%s' will bind to.\n", 1225 _ ("Failed to find %saddress for `%s'.\n"),
1209 hostname, 1226 disablev6 ? "IPv4 " : "",
1210 service_name); 1227 hostname);
1211 memset(&hints, 0, sizeof(struct addrinfo)); 1228 freeaddrinfo (res);
1212 if (disablev6) 1229 GNUNET_free (hostname);
1213 hints.ai_family = AF_INET; 1230 GNUNET_free_non_null (unixpath);
1214 hints.ai_protocol = IPPROTO_TCP; 1231 return GNUNET_SYSERR;
1215 if ((0 != (ret = getaddrinfo(hostname, NULL, &hints, &res))) || 1232 }
1216 (NULL == res)) 1233 resi = i;
1217 { 1234 if (NULL != unixpath)
1218 LOG(GNUNET_ERROR_TYPE_ERROR, 1235 resi++;
1219 _("Failed to resolve `%s': %s\n"), 1236 saddrs = GNUNET_new_array (resi + 1, struct sockaddr *);
1220 hostname, 1237 saddrlens = GNUNET_new_array (resi + 1, socklen_t);
1221 gai_strerror(ret)); 1238 i = 0;
1222 GNUNET_free(hostname); 1239 if (NULL != unixpath)
1223 GNUNET_free_non_null(unixpath); 1240 {
1224 return GNUNET_SYSERR; 1241 add_unixpath (saddrs, saddrlens, unixpath);
1225 } 1242 i++;
1226 next = res; 1243 }
1227 i = 0; 1244 next = res;
1228 while (NULL != (pos = next)) 1245 while (NULL != (pos = next))
1229 { 1246 {
1230 next = pos->ai_next; 1247 next = pos->ai_next;
1231 if ((disablev6) && (pos->ai_family == AF_INET6)) 1248 if ((disablev6) && (AF_INET6 == pos->ai_family))
1232 continue; 1249 continue;
1233 i++; 1250 if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol))
1234 } 1251 continue; /* not TCP */
1235 if (0 == i) 1252 if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype))
1236 { 1253 continue; /* huh? */
1237 LOG(GNUNET_ERROR_TYPE_ERROR, 1254 LOG (GNUNET_ERROR_TYPE_DEBUG,
1238 _("Failed to find %saddress for `%s'.\n"), 1255 "Service `%s' will bind to `%s'\n",
1239 disablev6 ? "IPv4 " : "", 1256 service_name,
1240 hostname); 1257 GNUNET_a2s (pos->ai_addr, pos->ai_addrlen));
1241 freeaddrinfo(res); 1258 if (AF_INET == pos->ai_family)
1242 GNUNET_free(hostname); 1259 {
1243 GNUNET_free_non_null(unixpath); 1260 GNUNET_assert (sizeof(struct sockaddr_in) == pos->ai_addrlen);
1244 return GNUNET_SYSERR; 1261 saddrlens[i] = pos->ai_addrlen;
1245 } 1262 saddrs[i] = GNUNET_malloc (saddrlens[i]);
1246 resi = i; 1263 GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
1264 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
1265 }
1266 else
1267 {
1268 GNUNET_assert (AF_INET6 == pos->ai_family);
1269 GNUNET_assert (sizeof(struct sockaddr_in6) == pos->ai_addrlen);
1270 saddrlens[i] = pos->ai_addrlen;
1271 saddrs[i] = GNUNET_malloc (saddrlens[i]);
1272 GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
1273 ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
1274 }
1275 i++;
1276 }
1277 GNUNET_free (hostname);
1278 freeaddrinfo (res);
1279 resi = i;
1280 }
1281 else
1282 {
1283 /* will bind against everything, just set port */
1284 if (disablev6)
1285 {
1286 /* V4-only */
1287 resi = 1;
1247 if (NULL != unixpath) 1288 if (NULL != unixpath)
1248 resi++; 1289 resi++;
1249 saddrs = GNUNET_new_array(resi + 1, struct sockaddr *);
1250 saddrlens = GNUNET_new_array(resi + 1, socklen_t);
1251 i = 0; 1290 i = 0;
1291 saddrs = GNUNET_new_array (resi + 1, struct sockaddr *);
1292 saddrlens = GNUNET_new_array (resi + 1, socklen_t);
1252 if (NULL != unixpath) 1293 if (NULL != unixpath)
1253 { 1294 {
1254 add_unixpath(saddrs, saddrlens, unixpath, abstract); 1295 add_unixpath (saddrs, saddrlens, unixpath);
1255 i++; 1296 i++;
1256 } 1297 }
1257 next = res; 1298 saddrlens[i] = sizeof(struct sockaddr_in);
1258 while (NULL != (pos = next)) 1299 saddrs[i] = GNUNET_malloc (saddrlens[i]);
1259 {
1260 next = pos->ai_next;
1261 if ((disablev6) && (AF_INET6 == pos->ai_family))
1262 continue;
1263 if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol))
1264 continue; /* not TCP */
1265 if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype))
1266 continue; /* huh? */
1267 LOG(GNUNET_ERROR_TYPE_DEBUG,
1268 "Service `%s' will bind to `%s'\n",
1269 service_name,
1270 GNUNET_a2s(pos->ai_addr, pos->ai_addrlen));
1271 if (AF_INET == pos->ai_family)
1272 {
1273 GNUNET_assert(sizeof(struct sockaddr_in) == pos->ai_addrlen);
1274 saddrlens[i] = pos->ai_addrlen;
1275 saddrs[i] = GNUNET_malloc(saddrlens[i]);
1276 GNUNET_memcpy(saddrs[i], pos->ai_addr, saddrlens[i]);
1277 ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port);
1278 }
1279 else
1280 {
1281 GNUNET_assert(AF_INET6 == pos->ai_family);
1282 GNUNET_assert(sizeof(struct sockaddr_in6) == pos->ai_addrlen);
1283 saddrlens[i] = pos->ai_addrlen;
1284 saddrs[i] = GNUNET_malloc(saddrlens[i]);
1285 GNUNET_memcpy(saddrs[i], pos->ai_addr, saddrlens[i]);
1286 ((struct sockaddr_in6 *)saddrs[i])->sin6_port = htons(port);
1287 }
1288 i++;
1289 }
1290 GNUNET_free(hostname);
1291 freeaddrinfo(res);
1292 resi = i;
1293 }
1294 else
1295 {
1296 /* will bind against everything, just set port */
1297 if (disablev6)
1298 {
1299 /* V4-only */
1300 resi = 1;
1301 if (NULL != unixpath)
1302 resi++;
1303 i = 0;
1304 saddrs = GNUNET_new_array(resi + 1, struct sockaddr *);
1305 saddrlens = GNUNET_new_array(resi + 1, socklen_t);
1306 if (NULL != unixpath)
1307 {
1308 add_unixpath(saddrs, saddrlens, unixpath, abstract);
1309 i++;
1310 }
1311 saddrlens[i] = sizeof(struct sockaddr_in);
1312 saddrs[i] = GNUNET_malloc(saddrlens[i]);
1313#if HAVE_SOCKADDR_IN_SIN_LEN 1300#if HAVE_SOCKADDR_IN_SIN_LEN
1314 ((struct sockaddr_in *)saddrs[i])->sin_len = saddrlens[i]; 1301 ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i];
1315#endif 1302#endif
1316 ((struct sockaddr_in *)saddrs[i])->sin_family = AF_INET; 1303 ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
1317 ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port); 1304 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
1318 } 1305 }
1319 else 1306 else
1320 { 1307 {
1321 /* dual stack */ 1308 /* dual stack */
1322 resi = 2; 1309 resi = 2;
1323 if (NULL != unixpath) 1310 if (NULL != unixpath)
1324 resi++; 1311 resi++;
1325 saddrs = GNUNET_new_array(resi + 1, struct sockaddr *); 1312 saddrs = GNUNET_new_array (resi + 1, struct sockaddr *);
1326 saddrlens = GNUNET_new_array(resi + 1, socklen_t); 1313 saddrlens = GNUNET_new_array (resi + 1, socklen_t);
1327 i = 0; 1314 i = 0;
1328 if (NULL != unixpath) 1315 if (NULL != unixpath)
1329 { 1316 {
1330 add_unixpath(saddrs, saddrlens, unixpath, abstract); 1317 add_unixpath (saddrs, saddrlens, unixpath);
1331 i++; 1318 i++;
1332 } 1319 }
1333 saddrlens[i] = sizeof(struct sockaddr_in6); 1320 saddrlens[i] = sizeof(struct sockaddr_in6);
1334 saddrs[i] = GNUNET_malloc(saddrlens[i]); 1321 saddrs[i] = GNUNET_malloc (saddrlens[i]);
1335#if HAVE_SOCKADDR_IN_SIN_LEN 1322#if HAVE_SOCKADDR_IN_SIN_LEN
1336 ((struct sockaddr_in6 *)saddrs[i])->sin6_len = saddrlens[0]; 1323 ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0];
1337#endif 1324#endif
1338 ((struct sockaddr_in6 *)saddrs[i])->sin6_family = AF_INET6; 1325 ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6;
1339 ((struct sockaddr_in6 *)saddrs[i])->sin6_port = htons(port); 1326 ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
1340 i++; 1327 i++;
1341 saddrlens[i] = sizeof(struct sockaddr_in); 1328 saddrlens[i] = sizeof(struct sockaddr_in);
1342 saddrs[i] = GNUNET_malloc(saddrlens[i]); 1329 saddrs[i] = GNUNET_malloc (saddrlens[i]);
1343#if HAVE_SOCKADDR_IN_SIN_LEN 1330#if HAVE_SOCKADDR_IN_SIN_LEN
1344 ((struct sockaddr_in *)saddrs[i])->sin_len = saddrlens[1]; 1331 ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1];
1345#endif 1332#endif
1346 ((struct sockaddr_in *)saddrs[i])->sin_family = AF_INET; 1333 ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
1347 ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port); 1334 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
1348 }
1349 } 1335 }
1350 GNUNET_free_non_null(unixpath); 1336 }
1337 GNUNET_free_non_null (unixpath);
1351 *addrs = saddrs; 1338 *addrs = saddrs;
1352 *addr_lens = saddrlens; 1339 *addr_lens = saddrlens;
1353 return resi; 1340 return resi;
@@ -1362,89 +1349,93 @@ get_server_addresses(const char *service_name,
1362 * @return NULL on error, otherwise the listen socket 1349 * @return NULL on error, otherwise the listen socket
1363 */ 1350 */
1364static struct GNUNET_NETWORK_Handle * 1351static struct GNUNET_NETWORK_Handle *
1365open_listen_socket(const struct sockaddr *server_addr, socklen_t socklen) 1352open_listen_socket (const struct sockaddr *server_addr,
1353 socklen_t socklen)
1366{ 1354{
1367 struct GNUNET_NETWORK_Handle *sock; 1355 struct GNUNET_NETWORK_Handle *sock;
1368 uint16_t port; 1356 uint16_t port;
1369 int eno; 1357 int eno;
1370 1358
1371 switch (server_addr->sa_family) 1359 switch (server_addr->sa_family)
1372 { 1360 {
1373 case AF_INET: 1361 case AF_INET:
1374 port = ntohs(((const struct sockaddr_in *)server_addr)->sin_port); 1362 port = ntohs (((const struct sockaddr_in *) server_addr)->sin_port);
1375 break; 1363 break;
1376 1364 case AF_INET6:
1377 case AF_INET6: 1365 port = ntohs (((const struct sockaddr_in6 *) server_addr)->sin6_port);
1378 port = ntohs(((const struct sockaddr_in6 *)server_addr)->sin6_port); 1366 break;
1379 break; 1367 case AF_UNIX:
1380 1368 port = 0;
1381 case AF_UNIX: 1369 break;
1382 port = 0; 1370 default:
1383 break; 1371 GNUNET_break (0);
1384 1372 port = 0;
1385 default: 1373 break;
1386 GNUNET_break(0); 1374 }
1387 port = 0; 1375 sock = GNUNET_NETWORK_socket_create (server_addr->sa_family,
1388 break; 1376 SOCK_STREAM,
1389 } 1377 0);
1390 sock = GNUNET_NETWORK_socket_create(server_addr->sa_family, SOCK_STREAM, 0);
1391 if (NULL == sock) 1378 if (NULL == sock)
1392 { 1379 {
1393 LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "socket"); 1380 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
1394 errno = 0; 1381 "socket");
1395 return NULL; 1382 errno = 0;
1396 } 1383 return NULL;
1384 }
1397 /* bind the socket */ 1385 /* bind the socket */
1398 if (GNUNET_OK != GNUNET_NETWORK_socket_bind(sock, server_addr, socklen)) 1386 if (GNUNET_OK !=
1387 GNUNET_NETWORK_socket_bind (sock,
1388 server_addr,
1389 socklen))
1390 {
1391 eno = errno;
1392 if (EADDRINUSE != errno)
1399 { 1393 {
1400 eno = errno; 1394 /* we don't log 'EADDRINUSE' here since an IPv4 bind may
1401 if (EADDRINUSE != errno) 1395 * fail if we already took the port on IPv6; if both IPv4 and
1402 { 1396 * IPv6 binds fail, then our caller will log using the
1403 /* we don't log 'EADDRINUSE' here since an IPv4 bind may 1397 * errno preserved in 'eno' */
1404 * fail if we already took the port on IPv6; if both IPv4 and 1398 if (0 != port)
1405 * IPv6 binds fail, then our caller will log using the 1399 LOG (GNUNET_ERROR_TYPE_ERROR,
1406 * errno preserved in 'eno' */ 1400 _ ("`%s' failed for port %d (%s).\n"),
1407 if (0 != port) 1401 "bind",
1408 LOG(GNUNET_ERROR_TYPE_ERROR, 1402 port,
1409 _("`%s' failed for port %d (%s).\n"), 1403 (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
1410 "bind",
1411 port,
1412 (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
1413 else
1414 LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "bind");
1415 eno = 0;
1416 }
1417 else 1404 else
1418 { 1405 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "bind");
1419 if (0 != port) 1406 eno = 0;
1420 LOG(GNUNET_ERROR_TYPE_WARNING,
1421 _("`%s' failed for port %d (%s): address already in use\n"),
1422 "bind",
1423 port,
1424 (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
1425 else if (AF_UNIX == server_addr->sa_family)
1426 {
1427 LOG(GNUNET_ERROR_TYPE_WARNING,
1428 _("`%s' failed for `%s': address already in use\n"),
1429 "bind",
1430 GNUNET_a2s(server_addr, socklen));
1431 }
1432 }
1433 GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(sock));
1434 errno = eno;
1435 return NULL;
1436 } 1407 }
1437 if (GNUNET_OK != GNUNET_NETWORK_socket_listen(sock, 5)) 1408 else
1438 { 1409 {
1439 LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "listen"); 1410 if (0 != port)
1440 GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(sock)); 1411 LOG (GNUNET_ERROR_TYPE_WARNING,
1441 errno = 0; 1412 _ ("`%s' failed for port %d (%s): address already in use\n"),
1442 return NULL; 1413 "bind",
1414 port,
1415 (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
1416 else if (AF_UNIX == server_addr->sa_family)
1417 {
1418 LOG (GNUNET_ERROR_TYPE_WARNING,
1419 _ ("`%s' failed for `%s': address already in use\n"),
1420 "bind",
1421 GNUNET_a2s (server_addr, socklen));
1422 }
1443 } 1423 }
1424 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
1425 errno = eno;
1426 return NULL;
1427 }
1428 if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5))
1429 {
1430 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "listen");
1431 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
1432 errno = 0;
1433 return NULL;
1434 }
1444 if (0 != port) 1435 if (0 != port)
1445 LOG(GNUNET_ERROR_TYPE_DEBUG, 1436 LOG (GNUNET_ERROR_TYPE_DEBUG,
1446 "Server starts to listen on port %u.\n", 1437 "Server starts to listen on port %u.\n",
1447 port); 1438 port);
1448 return sock; 1439 return sock;
1449} 1440}
1450 1441
@@ -1466,128 +1457,141 @@ open_listen_socket(const struct sockaddr *server_addr, socklen_t socklen)
1466 * @return #GNUNET_OK if configuration succeeded 1457 * @return #GNUNET_OK if configuration succeeded
1467 */ 1458 */
1468static int 1459static int
1469setup_service(struct GNUNET_SERVICE_Handle *sh) 1460setup_service (struct GNUNET_SERVICE_Handle *sh)
1470{ 1461{
1471 int tolerant; 1462 int tolerant;
1463 struct GNUNET_NETWORK_Handle **csocks = NULL;
1472 struct GNUNET_NETWORK_Handle **lsocks; 1464 struct GNUNET_NETWORK_Handle **lsocks;
1473 const char *nfds; 1465 const char *nfds;
1474 unsigned int cnt; 1466 unsigned int cnt;
1475 int flags; 1467 int flags;
1476 char dummy[2]; 1468 char dummy[2];
1477 1469
1478 if (GNUNET_CONFIGURATION_have_value(sh->cfg, sh->service_name, "TOLERANT")) 1470 if (GNUNET_CONFIGURATION_have_value (sh->cfg,
1471 sh->service_name,
1472 "TOLERANT"))
1473 {
1474 if (GNUNET_SYSERR ==
1475 (tolerant = GNUNET_CONFIGURATION_get_value_yesno (sh->cfg,
1476 sh->service_name,
1477 "TOLERANT")))
1479 { 1478 {
1480 if (GNUNET_SYSERR == 1479 LOG (GNUNET_ERROR_TYPE_ERROR,
1481 (tolerant = GNUNET_CONFIGURATION_get_value_yesno(sh->cfg, 1480 _ ("Specified value for `%s' of service `%s' is invalid\n"),
1482 sh->service_name, 1481 "TOLERANT",
1483 "TOLERANT"))) 1482 sh->service_name);
1484 { 1483 return GNUNET_SYSERR;
1485 LOG(GNUNET_ERROR_TYPE_ERROR,
1486 _("Specified value for `%s' of service `%s' is invalid\n"),
1487 "TOLERANT",
1488 sh->service_name);
1489 return GNUNET_SYSERR;
1490 }
1491 } 1484 }
1485 }
1492 else 1486 else
1493 tolerant = GNUNET_NO; 1487 tolerant = GNUNET_NO;
1494 1488
1495 lsocks = NULL; 1489 lsocks = NULL;
1496
1497 errno = 0; 1490 errno = 0;
1498 if ((NULL != (nfds = getenv("LISTEN_FDS"))) && 1491 if ((NULL != (nfds = getenv ("LISTEN_FDS"))) &&
1499 (1 == sscanf(nfds, "%u%1s", &cnt, dummy)) && (cnt > 0) && 1492 (1 == sscanf (nfds, "%u%1s", &cnt, dummy)) && (cnt > 0) &&
1500 (cnt < FD_SETSIZE) && (cnt + 4 < FD_SETSIZE)) 1493 (cnt < FD_SETSIZE) && (cnt + 4 < FD_SETSIZE))
1494 {
1495 lsocks = GNUNET_new_array (cnt + 1, struct GNUNET_NETWORK_Handle *);
1496 while (0 < cnt--)
1501 { 1497 {
1502 lsocks = GNUNET_new_array(cnt + 1, struct GNUNET_NETWORK_Handle *); 1498 flags = fcntl (3 + cnt, F_GETFD);
1503 while (0 < cnt--) 1499 if ((flags < 0) || (0 != (flags & FD_CLOEXEC)) ||
1504 { 1500 (NULL == (lsocks[cnt] = GNUNET_NETWORK_socket_box_native (3 + cnt))))
1505 flags = fcntl(3 + cnt, F_GETFD); 1501 {
1506 if ((flags < 0) || (0 != (flags & FD_CLOEXEC)) || 1502 LOG (GNUNET_ERROR_TYPE_ERROR,
1507 (NULL == (lsocks[cnt] = GNUNET_NETWORK_socket_box_native(3 + cnt)))) 1503 _ (
1508 { 1504 "Could not access pre-bound socket %u, will try to bind myself\n"),
1509 LOG(GNUNET_ERROR_TYPE_ERROR, 1505 (unsigned int) 3 + cnt);
1510 _( 1506 cnt++;
1511 "Could not access pre-bound socket %u, will try to bind myself\n"), 1507 while (NULL != lsocks[cnt])
1512 (unsigned int)3 + cnt); 1508 GNUNET_break (GNUNET_OK ==
1513 cnt++; 1509 GNUNET_NETWORK_socket_close (lsocks[cnt++]));
1514 while (NULL != lsocks[cnt]) 1510 GNUNET_free (lsocks);
1515 GNUNET_break(GNUNET_OK == 1511 lsocks = NULL;
1516 GNUNET_NETWORK_socket_close(lsocks[cnt++])); 1512 break;
1517 GNUNET_free(lsocks); 1513 }
1518 lsocks = NULL;
1519 break;
1520 }
1521 }
1522 unsetenv("LISTEN_FDS");
1523 } 1514 }
1515 unsetenv ("LISTEN_FDS");
1516 }
1517 if ( (0 != (GNUNET_SERVICE_OPTION_CLOSE_LSOCKS & sh->options)) &&
1518 (NULL != lsocks) )
1519 {
1520 csocks = lsocks;
1521 lsocks = NULL;
1522 }
1524 1523
1525 if (NULL != lsocks) 1524 if (NULL != lsocks)
1525 {
1526 /* listen only on inherited sockets if we have any */
1527 for (struct GNUNET_NETWORK_Handle **ls = lsocks; NULL != *ls; ls++)
1526 { 1528 {
1527 /* listen only on inherited sockets if we have any */ 1529 struct ServiceListenContext *slc;
1528 struct GNUNET_NETWORK_Handle **ls; 1530
1529 1531 slc = GNUNET_new (struct ServiceListenContext);
1530 for (ls = lsocks; NULL != *ls; ls++) 1532 slc->sh = sh;
1531 { 1533 slc->listen_socket = *ls;
1532 struct ServiceListenContext *slc; 1534 GNUNET_CONTAINER_DLL_insert (sh->slc_head, sh->slc_tail, slc);
1533
1534 slc = GNUNET_new(struct ServiceListenContext);
1535 slc->sh = sh;
1536 slc->listen_socket = *ls;
1537 GNUNET_CONTAINER_DLL_insert(sh->slc_head, sh->slc_tail, slc);
1538 }
1539 GNUNET_free(lsocks);
1540 } 1535 }
1536 GNUNET_free (lsocks);
1537 }
1541 else 1538 else
1542 { 1539 {
1543 struct sockaddr **addrs; 1540 struct sockaddr **addrs;
1544 socklen_t *addrlens; 1541 socklen_t *addrlens;
1545 int num; 1542 int num;
1546 1543
1547 num = get_server_addresses(sh->service_name, sh->cfg, &addrs, &addrlens); 1544 num = get_server_addresses (sh->service_name, sh->cfg, &addrs, &addrlens);
1548 if (GNUNET_SYSERR == num) 1545 if (GNUNET_SYSERR == num)
1549 return GNUNET_SYSERR; 1546 return GNUNET_SYSERR;
1550 1547
1551 for (int i = 0; i < num; i++) 1548 for (int i = 0; i < num; i++)
1552 { 1549 {
1553 struct ServiceListenContext *slc; 1550 struct ServiceListenContext *slc;
1554
1555 slc = GNUNET_new(struct ServiceListenContext);
1556 slc->sh = sh;
1557 slc->listen_socket = open_listen_socket(addrs[i], addrlens[i]);
1558 GNUNET_free(addrs[i]);
1559 if (NULL == slc->listen_socket)
1560 {
1561 GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, "bind");
1562 GNUNET_free(slc);
1563 continue;
1564 }
1565 GNUNET_CONTAINER_DLL_insert(sh->slc_head, sh->slc_tail, slc);
1566 }
1567 GNUNET_free_non_null(addrlens);
1568 GNUNET_free_non_null(addrs);
1569 if ((0 != num) && (NULL == sh->slc_head))
1570 {
1571 /* All attempts to bind failed, hard failure */
1572 GNUNET_log(
1573 GNUNET_ERROR_TYPE_ERROR,
1574 _(
1575 "Could not bind to any of the ports I was supposed to, refusing to run!\n"));
1576 return GNUNET_SYSERR;
1577 }
1578 }
1579 1551
1552 slc = GNUNET_new (struct ServiceListenContext);
1553 slc->sh = sh;
1554 slc->listen_socket = open_listen_socket (addrs[i], addrlens[i]);
1555 GNUNET_free (addrs[i]);
1556 if (NULL == slc->listen_socket)
1557 {
1558 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
1559 GNUNET_free (slc);
1560 continue;
1561 }
1562 GNUNET_CONTAINER_DLL_insert (sh->slc_head, sh->slc_tail, slc);
1563 }
1564 GNUNET_free_non_null (addrlens);
1565 GNUNET_free_non_null (addrs);
1566 if ((0 != num) && (NULL == sh->slc_head))
1567 {
1568 /* All attempts to bind failed, hard failure */
1569 GNUNET_log (
1570 GNUNET_ERROR_TYPE_ERROR,
1571 _ (
1572 "Could not bind to any of the ports I was supposed to, refusing to run!\n"));
1573 GNUNET_free_non_null (csocks);
1574 return GNUNET_SYSERR;
1575 }
1576 }
1577 if (NULL != csocks)
1578 {
1579 /* close inherited sockets to signal parent that we are ready */
1580 for (struct GNUNET_NETWORK_Handle **ls = csocks; NULL != *ls; ls++)
1581 GNUNET_NETWORK_socket_close (*ls);
1582 GNUNET_free (csocks);
1583 }
1580 sh->require_found = tolerant ? GNUNET_NO : GNUNET_YES; 1584 sh->require_found = tolerant ? GNUNET_NO : GNUNET_YES;
1581 sh->match_uid = GNUNET_CONFIGURATION_get_value_yesno(sh->cfg, 1585 sh->match_uid = GNUNET_CONFIGURATION_get_value_yesno (sh->cfg,
1582 sh->service_name, 1586 sh->service_name,
1583 "UNIX_MATCH_UID"); 1587 "UNIX_MATCH_UID");
1584 sh->match_gid = GNUNET_CONFIGURATION_get_value_yesno(sh->cfg, 1588 sh->match_gid = GNUNET_CONFIGURATION_get_value_yesno (sh->cfg,
1585 sh->service_name, 1589 sh->service_name,
1586 "UNIX_MATCH_GID"); 1590 "UNIX_MATCH_GID");
1587 process_acl4(&sh->v4_denied, sh, "REJECT_FROM"); 1591 process_acl4 (&sh->v4_denied, sh, "REJECT_FROM");
1588 process_acl4(&sh->v4_allowed, sh, "ACCEPT_FROM"); 1592 process_acl4 (&sh->v4_allowed, sh, "ACCEPT_FROM");
1589 process_acl6(&sh->v6_denied, sh, "REJECT_FROM6"); 1593 process_acl6 (&sh->v6_denied, sh, "REJECT_FROM6");
1590 process_acl6(&sh->v6_allowed, sh, "ACCEPT_FROM6"); 1594 process_acl6 (&sh->v6_allowed, sh, "ACCEPT_FROM6");
1591 return GNUNET_OK; 1595 return GNUNET_OK;
1592} 1596}
1593 1597
@@ -1600,14 +1604,14 @@ setup_service(struct GNUNET_SERVICE_Handle *sh)
1600 * @return value of the 'USERNAME' option 1604 * @return value of the 'USERNAME' option
1601 */ 1605 */
1602static char * 1606static char *
1603get_user_name(struct GNUNET_SERVICE_Handle *sh) 1607get_user_name (struct GNUNET_SERVICE_Handle *sh)
1604{ 1608{
1605 char *un; 1609 char *un;
1606 1610
1607 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename(sh->cfg, 1611 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (sh->cfg,
1608 sh->service_name, 1612 sh->service_name,
1609 "USERNAME", 1613 "USERNAME",
1610 &un)) 1614 &un))
1611 return NULL; 1615 return NULL;
1612 return un; 1616 return un;
1613} 1617}
@@ -1620,45 +1624,45 @@ get_user_name(struct GNUNET_SERVICE_Handle *sh)
1620 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 1624 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
1621 */ 1625 */
1622static int 1626static int
1623set_user_id(struct GNUNET_SERVICE_Handle *sh) 1627set_user_id (struct GNUNET_SERVICE_Handle *sh)
1624{ 1628{
1625 char *user; 1629 char *user;
1626 1630
1627 if (NULL == (user = get_user_name(sh))) 1631 if (NULL == (user = get_user_name (sh)))
1628 return GNUNET_OK; /* keep */ 1632 return GNUNET_OK; /* keep */
1629 1633
1630 struct passwd *pws; 1634 struct passwd *pws;
1631 1635
1632 errno = 0; 1636 errno = 0;
1633 pws = getpwnam(user); 1637 pws = getpwnam (user);
1634 if (NULL == pws) 1638 if (NULL == pws)
1635 { 1639 {
1636 LOG(GNUNET_ERROR_TYPE_ERROR, 1640 LOG (GNUNET_ERROR_TYPE_ERROR,
1637 _("Cannot obtain information about user `%s': %s\n"), 1641 _ ("Cannot obtain information about user `%s': %s\n"),
1638 user, 1642 user,
1639 errno == 0 ? _("No such user") : strerror(errno)); 1643 errno == 0 ? _ ("No such user") : strerror (errno));
1640 GNUNET_free(user); 1644 GNUNET_free (user);
1641 return GNUNET_SYSERR; 1645 return GNUNET_SYSERR;
1642 } 1646 }
1643 if ((0 != setgid(pws->pw_gid)) || (0 != setegid(pws->pw_gid)) || 1647 if ((0 != setgid (pws->pw_gid)) || (0 != setegid (pws->pw_gid)) ||
1644#if HAVE_INITGROUPS 1648#if HAVE_INITGROUPS
1645 (0 != initgroups(user, pws->pw_gid)) || 1649 (0 != initgroups (user, pws->pw_gid)) ||
1646#endif 1650#endif
1647 (0 != setuid(pws->pw_uid)) || (0 != seteuid(pws->pw_uid))) 1651 (0 != setuid (pws->pw_uid)) || (0 != seteuid (pws->pw_uid)))
1652 {
1653 if ((0 != setregid (pws->pw_gid, pws->pw_gid)) ||
1654 (0 != setreuid (pws->pw_uid, pws->pw_uid)))
1648 { 1655 {
1649 if ((0 != setregid(pws->pw_gid, pws->pw_gid)) || 1656 LOG (GNUNET_ERROR_TYPE_ERROR,
1650 (0 != setreuid(pws->pw_uid, pws->pw_uid))) 1657 _ ("Cannot change user/group to `%s': %s\n"),
1651 { 1658 user,
1652 LOG(GNUNET_ERROR_TYPE_ERROR, 1659 strerror (errno));
1653 _("Cannot change user/group to `%s': %s\n"), 1660 GNUNET_free (user);
1654 user, 1661 return GNUNET_SYSERR;
1655 strerror(errno));
1656 GNUNET_free(user);
1657 return GNUNET_SYSERR;
1658 }
1659 } 1662 }
1663 }
1660 1664
1661 GNUNET_free(user); 1665 GNUNET_free (user);
1662 return GNUNET_OK; 1666 return GNUNET_OK;
1663} 1667}
1664 1668
@@ -1671,14 +1675,14 @@ set_user_id(struct GNUNET_SERVICE_Handle *sh)
1671 * @return name of the file for the process ID 1675 * @return name of the file for the process ID
1672 */ 1676 */
1673static char * 1677static char *
1674get_pid_file_name(struct GNUNET_SERVICE_Handle *sh) 1678get_pid_file_name (struct GNUNET_SERVICE_Handle *sh)
1675{ 1679{
1676 char *pif; 1680 char *pif;
1677 1681
1678 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename(sh->cfg, 1682 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (sh->cfg,
1679 sh->service_name, 1683 sh->service_name,
1680 "PIDFILE", 1684 "PIDFILE",
1681 &pif)) 1685 &pif))
1682 return NULL; 1686 return NULL;
1683 return pif; 1687 return pif;
1684} 1688}
@@ -1690,15 +1694,15 @@ get_pid_file_name(struct GNUNET_SERVICE_Handle *sh)
1690 * @param sh service context 1694 * @param sh service context
1691 */ 1695 */
1692static void 1696static void
1693pid_file_delete(struct GNUNET_SERVICE_Handle *sh) 1697pid_file_delete (struct GNUNET_SERVICE_Handle *sh)
1694{ 1698{
1695 char *pif = get_pid_file_name(sh); 1699 char *pif = get_pid_file_name (sh);
1696 1700
1697 if (NULL == pif) 1701 if (NULL == pif)
1698 return; /* no PID file */ 1702 return; /* no PID file */
1699 if (0 != unlink(pif)) 1703 if (0 != unlink (pif))
1700 LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_WARNING, "unlink", pif); 1704 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", pif);
1701 GNUNET_free(pif); 1705 GNUNET_free (pif);
1702} 1706}
1703 1707
1704 1708
@@ -1709,73 +1713,73 @@ pid_file_delete(struct GNUNET_SERVICE_Handle *sh)
1709 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 1713 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
1710 */ 1714 */
1711static int 1715static int
1712detach_terminal(struct GNUNET_SERVICE_Handle *sh) 1716detach_terminal (struct GNUNET_SERVICE_Handle *sh)
1713{ 1717{
1714 pid_t pid; 1718 pid_t pid;
1715 int nullfd; 1719 int nullfd;
1716 int filedes[2]; 1720 int filedes[2];
1717 1721
1718 if (0 != pipe(filedes)) 1722 if (0 != pipe (filedes))
1719 { 1723 {
1720 LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "pipe"); 1724 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "pipe");
1721 return GNUNET_SYSERR; 1725 return GNUNET_SYSERR;
1722 } 1726 }
1723 pid = fork(); 1727 pid = fork ();
1724 if (pid < 0) 1728 if (pid < 0)
1725 { 1729 {
1726 LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "fork"); 1730 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fork");
1727 return GNUNET_SYSERR; 1731 return GNUNET_SYSERR;
1728 } 1732 }
1729 if (0 != pid) 1733 if (0 != pid)
1734 {
1735 /* Parent */
1736 char c;
1737
1738 GNUNET_break (0 == close (filedes[1]));
1739 c = 'X';
1740 if (1 != read (filedes[0], &c, sizeof(char)))
1741 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "read");
1742 fflush (stdout);
1743 switch (c)
1730 { 1744 {
1731 /* Parent */ 1745 case '.':
1732 char c; 1746 exit (0);
1733 1747
1734 GNUNET_break(0 == close(filedes[1])); 1748 case 'I':
1735 c = 'X'; 1749 LOG (GNUNET_ERROR_TYPE_INFO,
1736 if (1 != read(filedes[0], &c, sizeof(char))) 1750 _ ("Service process failed to initialize\n"));
1737 LOG_STRERROR(GNUNET_ERROR_TYPE_WARNING, "read"); 1751 break;
1738 fflush(stdout); 1752
1739 switch (c) 1753 case 'S':
1740 { 1754 LOG (GNUNET_ERROR_TYPE_INFO,
1741 case '.': 1755 _ ("Service process could not initialize server function\n"));
1742 exit(0); 1756 break;
1743 1757
1744 case 'I': 1758 case 'X':
1745 LOG(GNUNET_ERROR_TYPE_INFO, 1759 LOG (GNUNET_ERROR_TYPE_INFO,
1746 _("Service process failed to initialize\n")); 1760 _ ("Service process failed to report status\n"));
1747 break; 1761 break;
1748
1749 case 'S':
1750 LOG(GNUNET_ERROR_TYPE_INFO,
1751 _("Service process could not initialize server function\n"));
1752 break;
1753
1754 case 'X':
1755 LOG(GNUNET_ERROR_TYPE_INFO,
1756 _("Service process failed to report status\n"));
1757 break;
1758 }
1759 exit(1); /* child reported error */
1760 } 1762 }
1761 GNUNET_break(0 == close(0)); 1763 exit (1); /* child reported error */
1762 GNUNET_break(0 == close(1)); 1764 }
1763 GNUNET_break(0 == close(filedes[0])); 1765 GNUNET_break (0 == close (0));
1764 nullfd = open("/dev/null", O_RDWR | O_APPEND); 1766 GNUNET_break (0 == close (1));
1767 GNUNET_break (0 == close (filedes[0]));
1768 nullfd = open ("/dev/null", O_RDWR | O_APPEND);
1765 if (nullfd < 0) 1769 if (nullfd < 0)
1766 return GNUNET_SYSERR; 1770 return GNUNET_SYSERR;
1767 /* set stdin/stdout to /dev/null */ 1771 /* set stdin/stdout to /dev/null */
1768 if ((dup2(nullfd, 0) < 0) || (dup2(nullfd, 1) < 0)) 1772 if ((dup2 (nullfd, 0) < 0) || (dup2 (nullfd, 1) < 0))
1769 { 1773 {
1770 LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "dup2"); 1774 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "dup2");
1771 (void)close(nullfd); 1775 (void) close (nullfd);
1772 return GNUNET_SYSERR; 1776 return GNUNET_SYSERR;
1773 } 1777 }
1774 (void)close(nullfd); 1778 (void) close (nullfd);
1775 /* Detach from controlling terminal */ 1779 /* Detach from controlling terminal */
1776 pid = setsid(); 1780 pid = setsid ();
1777 if (-1 == pid) 1781 if (-1 == pid)
1778 LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "setsid"); 1782 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "setsid");
1779 sh->ready_confirm_fd = filedes[1]; 1783 sh->ready_confirm_fd = filedes[1];
1780 1784
1781 return GNUNET_OK; 1785 return GNUNET_OK;
@@ -1789,23 +1793,23 @@ detach_terminal(struct GNUNET_SERVICE_Handle *sh)
1789 * @param sh handle to the service to tear down. 1793 * @param sh handle to the service to tear down.
1790 */ 1794 */
1791static void 1795static void
1792teardown_service(struct GNUNET_SERVICE_Handle *sh) 1796teardown_service (struct GNUNET_SERVICE_Handle *sh)
1793{ 1797{
1794 struct ServiceListenContext *slc; 1798 struct ServiceListenContext *slc;
1795 1799
1796 GNUNET_free_non_null(sh->v4_denied); 1800 GNUNET_free_non_null (sh->v4_denied);
1797 GNUNET_free_non_null(sh->v6_denied); 1801 GNUNET_free_non_null (sh->v6_denied);
1798 GNUNET_free_non_null(sh->v4_allowed); 1802 GNUNET_free_non_null (sh->v4_allowed);
1799 GNUNET_free_non_null(sh->v6_allowed); 1803 GNUNET_free_non_null (sh->v6_allowed);
1800 while (NULL != (slc = sh->slc_head)) 1804 while (NULL != (slc = sh->slc_head))
1801 { 1805 {
1802 GNUNET_CONTAINER_DLL_remove(sh->slc_head, sh->slc_tail, slc); 1806 GNUNET_CONTAINER_DLL_remove (sh->slc_head, sh->slc_tail, slc);
1803 if (NULL != slc->listen_task) 1807 if (NULL != slc->listen_task)
1804 GNUNET_SCHEDULER_cancel(slc->listen_task); 1808 GNUNET_SCHEDULER_cancel (slc->listen_task);
1805 GNUNET_break(GNUNET_OK == 1809 GNUNET_break (GNUNET_OK ==
1806 GNUNET_NETWORK_socket_close(slc->listen_socket)); 1810 GNUNET_NETWORK_socket_close (slc->listen_socket));
1807 GNUNET_free(slc); 1811 GNUNET_free (slc);
1808 } 1812 }
1809} 1813}
1810 1814
1811 1815
@@ -1816,7 +1820,7 @@ teardown_service(struct GNUNET_SERVICE_Handle *sh)
1816 * @param msg AGPL request 1820 * @param msg AGPL request
1817 */ 1821 */
1818static void 1822static void
1819return_agpl(void *cls, const struct GNUNET_MessageHeader *msg) 1823return_agpl (void *cls, const struct GNUNET_MessageHeader *msg)
1820{ 1824{
1821 struct GNUNET_SERVICE_Client *client = cls; 1825 struct GNUNET_SERVICE_Client *client = cls;
1822 struct GNUNET_MQ_Handle *mq; 1826 struct GNUNET_MQ_Handle *mq;
@@ -1824,13 +1828,13 @@ return_agpl(void *cls, const struct GNUNET_MessageHeader *msg)
1824 struct GNUNET_MessageHeader *res; 1828 struct GNUNET_MessageHeader *res;
1825 size_t slen; 1829 size_t slen;
1826 1830
1827 (void)msg; 1831 (void) msg;
1828 slen = strlen(GNUNET_AGPL_URL) + 1; 1832 slen = strlen (GNUNET_AGPL_URL) + 1;
1829 env = GNUNET_MQ_msg_extra(res, GNUNET_MESSAGE_TYPE_RESPONSE_AGPL, slen); 1833 env = GNUNET_MQ_msg_extra (res, GNUNET_MESSAGE_TYPE_RESPONSE_AGPL, slen);
1830 memcpy(&res[1], GNUNET_AGPL_URL, slen); 1834 memcpy (&res[1], GNUNET_AGPL_URL, slen);
1831 mq = GNUNET_SERVICE_client_get_mq(client); 1835 mq = GNUNET_SERVICE_client_get_mq (client);
1832 GNUNET_MQ_send(mq, env); 1836 GNUNET_MQ_send (mq, env);
1833 GNUNET_SERVICE_client_continue(client); 1837 GNUNET_SERVICE_client_continue (client);
1834} 1838}
1835 1839
1836 1840
@@ -1871,29 +1875,29 @@ return_agpl(void *cls, const struct GNUNET_MessageHeader *msg)
1871 * @return NULL on error 1875 * @return NULL on error
1872 */ 1876 */
1873struct GNUNET_SERVICE_Handle * 1877struct GNUNET_SERVICE_Handle *
1874GNUNET_SERVICE_start(const char *service_name, 1878GNUNET_SERVICE_start (const char *service_name,
1875 const struct GNUNET_CONFIGURATION_Handle *cfg, 1879 const struct GNUNET_CONFIGURATION_Handle *cfg,
1876 GNUNET_SERVICE_ConnectHandler connect_cb, 1880 GNUNET_SERVICE_ConnectHandler connect_cb,
1877 GNUNET_SERVICE_DisconnectHandler disconnect_cb, 1881 GNUNET_SERVICE_DisconnectHandler disconnect_cb,
1878 void *cls, 1882 void *cls,
1879 const struct GNUNET_MQ_MessageHandler *handlers) 1883 const struct GNUNET_MQ_MessageHandler *handlers)
1880{ 1884{
1881 struct GNUNET_SERVICE_Handle *sh; 1885 struct GNUNET_SERVICE_Handle *sh;
1882 1886
1883 sh = GNUNET_new(struct GNUNET_SERVICE_Handle); 1887 sh = GNUNET_new (struct GNUNET_SERVICE_Handle);
1884 sh->service_name = service_name; 1888 sh->service_name = service_name;
1885 sh->cfg = cfg; 1889 sh->cfg = cfg;
1886 sh->connect_cb = connect_cb; 1890 sh->connect_cb = connect_cb;
1887 sh->disconnect_cb = disconnect_cb; 1891 sh->disconnect_cb = disconnect_cb;
1888 sh->cb_cls = cls; 1892 sh->cb_cls = cls;
1889 sh->handlers = GNUNET_MQ_copy_handlers2(handlers, &return_agpl, NULL); 1893 sh->handlers = GNUNET_MQ_copy_handlers2 (handlers, &return_agpl, NULL);
1890 if (GNUNET_OK != setup_service(sh)) 1894 if (GNUNET_OK != setup_service (sh))
1891 { 1895 {
1892 GNUNET_free_non_null(sh->handlers); 1896 GNUNET_free_non_null (sh->handlers);
1893 GNUNET_free(sh); 1897 GNUNET_free (sh);
1894 return NULL; 1898 return NULL;
1895 } 1899 }
1896 do_resume(sh, SUSPEND_STATE_NONE); 1900 do_resume (sh, SUSPEND_STATE_NONE);
1897 return sh; 1901 return sh;
1898} 1902}
1899 1903
@@ -1904,16 +1908,16 @@ GNUNET_SERVICE_start(const char *service_name,
1904 * @param srv service to stop 1908 * @param srv service to stop
1905 */ 1909 */
1906void 1910void
1907GNUNET_SERVICE_stop(struct GNUNET_SERVICE_Handle *srv) 1911GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Handle *srv)
1908{ 1912{
1909 struct GNUNET_SERVICE_Client *client; 1913 struct GNUNET_SERVICE_Client *client;
1910 1914
1911 GNUNET_SERVICE_suspend(srv); 1915 GNUNET_SERVICE_suspend (srv);
1912 while (NULL != (client = srv->clients_head)) 1916 while (NULL != (client = srv->clients_head))
1913 GNUNET_SERVICE_client_drop(client); 1917 GNUNET_SERVICE_client_drop (client);
1914 teardown_service(srv); 1918 teardown_service (srv);
1915 GNUNET_free_non_null(srv->handlers); 1919 GNUNET_free_non_null (srv->handlers);
1916 GNUNET_free(srv); 1920 GNUNET_free (srv);
1917} 1921}
1918 1922
1919 1923
@@ -1959,15 +1963,15 @@ GNUNET_SERVICE_stop(struct GNUNET_SERVICE_Handle *srv)
1959 * @return 0 on success, non-zero on error 1963 * @return 0 on success, non-zero on error
1960 */ 1964 */
1961int 1965int
1962GNUNET_SERVICE_run_(int argc, 1966GNUNET_SERVICE_run_ (int argc,
1963 char *const *argv, 1967 char *const *argv,
1964 const char *service_name, 1968 const char *service_name,
1965 enum GNUNET_SERVICE_Options options, 1969 enum GNUNET_SERVICE_Options options,
1966 GNUNET_SERVICE_InitCallback service_init_cb, 1970 GNUNET_SERVICE_InitCallback service_init_cb,
1967 GNUNET_SERVICE_ConnectHandler connect_cb, 1971 GNUNET_SERVICE_ConnectHandler connect_cb,
1968 GNUNET_SERVICE_DisconnectHandler disconnect_cb, 1972 GNUNET_SERVICE_DisconnectHandler disconnect_cb,
1969 void *cls, 1973 void *cls,
1970 const struct GNUNET_MQ_MessageHandler *handlers) 1974 const struct GNUNET_MQ_MessageHandler *handlers)
1971{ 1975{
1972 struct GNUNET_SERVICE_Handle sh; 1976 struct GNUNET_SERVICE_Handle sh;
1973 1977
@@ -1986,40 +1990,40 @@ GNUNET_SERVICE_run_(int argc,
1986 struct GNUNET_CONFIGURATION_Handle *cfg; 1990 struct GNUNET_CONFIGURATION_Handle *cfg;
1987 int ret; 1991 int ret;
1988 int err; 1992 int err;
1989 const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get(); 1993 const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get ();
1990 1994 struct GNUNET_GETOPT_CommandLineOption service_options[] = {
1991 struct GNUNET_GETOPT_CommandLineOption service_options[] = 1995 GNUNET_GETOPT_option_cfgfile (&opt_cfg_filename),
1992 { GNUNET_GETOPT_option_cfgfile(&opt_cfg_filename), 1996 GNUNET_GETOPT_option_flag ('d',
1993 GNUNET_GETOPT_option_flag('d', 1997 "daemonize",
1994 "daemonize", 1998 gettext_noop (
1995 gettext_noop( 1999 "do daemonize (detach from terminal)"),
1996 "do daemonize (detach from terminal)"), 2000 &do_daemonize),
1997 &do_daemonize), 2001 GNUNET_GETOPT_option_help (NULL),
1998 GNUNET_GETOPT_option_help(NULL), 2002 GNUNET_GETOPT_option_loglevel (&loglev),
1999 GNUNET_GETOPT_option_loglevel(&loglev), 2003 GNUNET_GETOPT_option_logfile (&logfile),
2000 GNUNET_GETOPT_option_logfile(&logfile), 2004 GNUNET_GETOPT_option_version (pd->version),
2001 GNUNET_GETOPT_option_version(pd->version), 2005 GNUNET_GETOPT_OPTION_END
2002 GNUNET_GETOPT_OPTION_END }; 2006 };
2003 2007
2004 err = 1; 2008 err = 1;
2005 memset(&sh, 0, sizeof(sh)); 2009 memset (&sh, 0, sizeof(sh));
2006 xdg = getenv("XDG_CONFIG_HOME"); 2010 xdg = getenv ("XDG_CONFIG_HOME");
2007 if (NULL != xdg) 2011 if (NULL != xdg)
2008 GNUNET_asprintf(&cfg_filename, 2012 GNUNET_asprintf (&cfg_filename,
2009 "%s%s%s", 2013 "%s%s%s",
2010 xdg, 2014 xdg,
2011 DIR_SEPARATOR_STR, 2015 DIR_SEPARATOR_STR,
2012 pd->config_file); 2016 pd->config_file);
2013 else 2017 else
2014 cfg_filename = GNUNET_strdup(pd->user_config_file); 2018 cfg_filename = GNUNET_strdup (pd->user_config_file);
2015 sh.ready_confirm_fd = -1; 2019 sh.ready_confirm_fd = -1;
2016 sh.options = options; 2020 sh.options = options;
2017 sh.cfg = cfg = GNUNET_CONFIGURATION_create(); 2021 sh.cfg = cfg = GNUNET_CONFIGURATION_create ();
2018 sh.service_init_cb = service_init_cb; 2022 sh.service_init_cb = service_init_cb;
2019 sh.connect_cb = connect_cb; 2023 sh.connect_cb = connect_cb;
2020 sh.disconnect_cb = disconnect_cb; 2024 sh.disconnect_cb = disconnect_cb;
2021 sh.cb_cls = cls; 2025 sh.cb_cls = cls;
2022 sh.handlers = GNUNET_MQ_copy_handlers(handlers); 2026 sh.handlers = GNUNET_MQ_copy_handlers (handlers);
2023 sh.service_name = service_name; 2027 sh.service_name = service_name;
2024 sh.ret = 0; 2028 sh.ret = 0;
2025 /* setup subsystems */ 2029 /* setup subsystems */
@@ -2029,135 +2033,140 @@ GNUNET_SERVICE_run_(int argc,
2029 do_daemonize = 0; 2033 do_daemonize = 0;
2030#if ENABLE_NLS 2034#if ENABLE_NLS
2031 if (NULL != pd->gettext_domain) 2035 if (NULL != pd->gettext_domain)
2036 {
2037 setlocale (LC_ALL, "");
2038 path = (NULL == pd->gettext_path) ?
2039 GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LOCALEDIR) :
2040 GNUNET_strdup (pd->gettext_path);
2041 if (NULL != path)
2032 { 2042 {
2033 setlocale(LC_ALL, ""); 2043 bindtextdomain (pd->gettext_domain, path);
2034 path = (NULL == pd->gettext_path) ? 2044 GNUNET_free (path);
2035 GNUNET_OS_installation_get_path(GNUNET_OS_IPK_LOCALEDIR) :
2036 GNUNET_strdup(pd->gettext_path);
2037 if (NULL != path)
2038 {
2039 bindtextdomain(pd->gettext_domain, path);
2040 GNUNET_free(path);
2041 }
2042 textdomain(pd->gettext_domain);
2043 } 2045 }
2046 textdomain (pd->gettext_domain);
2047 }
2044#endif 2048#endif
2045 ret = GNUNET_GETOPT_run(service_name, service_options, argc, argv); 2049 ret = GNUNET_GETOPT_run (service_name,
2050 service_options,
2051 argc,
2052 argv);
2046 if (GNUNET_SYSERR == ret) 2053 if (GNUNET_SYSERR == ret)
2047 goto shutdown; 2054 goto shutdown;
2048 if (GNUNET_NO == ret) 2055 if (GNUNET_NO == ret)
2049 { 2056 {
2050 err = 0; 2057 err = 0;
2051 goto shutdown; 2058 goto shutdown;
2052 } 2059 }
2053 if (GNUNET_OK != GNUNET_log_setup(service_name, loglev, logfile)) 2060 if (GNUNET_OK != GNUNET_log_setup (service_name,
2054 { 2061 loglev,
2055 GNUNET_break(0); 2062 logfile))
2056 goto shutdown; 2063 {
2057 } 2064 GNUNET_break (0);
2065 goto shutdown;
2066 }
2058 if (NULL != opt_cfg_filename) 2067 if (NULL != opt_cfg_filename)
2068 {
2069 if ((GNUNET_YES != GNUNET_DISK_file_test (opt_cfg_filename)) ||
2070 (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, opt_cfg_filename)))
2059 { 2071 {
2060 if ((GNUNET_YES != GNUNET_DISK_file_test(opt_cfg_filename)) || 2072 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2061 (GNUNET_SYSERR == GNUNET_CONFIGURATION_load(cfg, opt_cfg_filename))) 2073 _ ("Malformed configuration file `%s', exit ...\n"),
2062 { 2074 opt_cfg_filename);
2063 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 2075 goto shutdown;
2064 _("Malformed configuration file `%s', exit ...\n"),
2065 opt_cfg_filename);
2066 goto shutdown;
2067 }
2068 } 2076 }
2077 }
2069 else 2078 else
2079 {
2080 if (GNUNET_YES == GNUNET_DISK_file_test (cfg_filename))
2070 { 2081 {
2071 if (GNUNET_YES == GNUNET_DISK_file_test(cfg_filename)) 2082 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, cfg_filename))
2072 { 2083 {
2073 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load(cfg, cfg_filename)) 2084 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2074 { 2085 _ ("Malformed configuration file `%s', exit ...\n"),
2075 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 2086 cfg_filename);
2076 _("Malformed configuration file `%s', exit ...\n"), 2087 goto shutdown;
2077 cfg_filename); 2088 }
2078 goto shutdown;
2079 }
2080 }
2081 else
2082 {
2083 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load(cfg, NULL))
2084 {
2085 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
2086 _("Malformed configuration, exit ...\n"));
2087 goto shutdown;
2088 }
2089 }
2090 } 2089 }
2091 if (GNUNET_OK != setup_service(&sh)) 2090 else
2092 goto shutdown;
2093 if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal(&sh)))
2094 { 2091 {
2095 GNUNET_break(0); 2092 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, NULL))
2096 goto shutdown; 2093 {
2094 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2095 _ ("Malformed configuration, exit ...\n"));
2096 goto shutdown;
2097 }
2097 } 2098 }
2098 if (GNUNET_OK != set_user_id(&sh)) 2099 }
2100 if (GNUNET_OK != setup_service (&sh))
2099 goto shutdown; 2101 goto shutdown;
2100 LOG(GNUNET_ERROR_TYPE_DEBUG, 2102 if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal (&sh)))
2101 "Service `%s' runs with configuration from `%s'\n", 2103 {
2102 service_name, 2104 GNUNET_break (0);
2103 (NULL != opt_cfg_filename) ? opt_cfg_filename : cfg_filename); 2105 goto shutdown;
2104 if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(sh.cfg, 2106 }
2105 "TESTING", 2107 if (GNUNET_OK != set_user_id (&sh))
2106 "SKEW_OFFSET", 2108 goto shutdown;
2107 &skew_offset)) && 2109 LOG (GNUNET_ERROR_TYPE_DEBUG,
2108 (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(sh.cfg, 2110 "Service `%s' runs with configuration from `%s'\n",
2109 "TESTING", 2111 service_name,
2110 "SKEW_VARIANCE", 2112 (NULL != opt_cfg_filename) ? opt_cfg_filename : cfg_filename);
2111 &skew_variance))) 2113 if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (sh.cfg,
2112 { 2114 "TESTING",
2113 clock_offset = skew_offset - skew_variance; 2115 "SKEW_OFFSET",
2114 GNUNET_TIME_set_offset(clock_offset); 2116 &skew_offset)) &&
2115 LOG(GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll ms\n", clock_offset); 2117 (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (sh.cfg,
2116 } 2118 "TESTING",
2117 GNUNET_RESOLVER_connect(sh.cfg); 2119 "SKEW_VARIANCE",
2120 &skew_variance)))
2121 {
2122 clock_offset = skew_offset - skew_variance;
2123 GNUNET_TIME_set_offset (clock_offset);
2124 LOG (GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll ms\n", clock_offset);
2125 }
2126 GNUNET_RESOLVER_connect (sh.cfg);
2118 2127
2119 /* actually run service */ 2128 /* actually run service */
2120 err = 0; 2129 err = 0;
2121 GNUNET_SCHEDULER_run(&service_main, &sh); 2130 GNUNET_SCHEDULER_run (&service_main, &sh);
2122 /* shutdown */ 2131 /* shutdown */
2123 if (1 == do_daemonize) 2132 if (1 == do_daemonize)
2124 pid_file_delete(&sh); 2133 pid_file_delete (&sh);
2125 2134
2126shutdown: 2135shutdown:
2127 if (-1 != sh.ready_confirm_fd) 2136 if (-1 != sh.ready_confirm_fd)
2128 { 2137 {
2129 if (1 != write(sh.ready_confirm_fd, err ? "I" : "S", 1)) 2138 if (1 != write (sh.ready_confirm_fd, err ? "I" : "S", 1))
2130 LOG_STRERROR(GNUNET_ERROR_TYPE_WARNING, "write"); 2139 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "write");
2131 GNUNET_break(0 == close(sh.ready_confirm_fd)); 2140 GNUNET_break (0 == close (sh.ready_confirm_fd));
2132 } 2141 }
2133#if HAVE_MALLINFO 2142#if HAVE_MALLINFO
2134 { 2143 {
2135 char *counter; 2144 char *counter;
2136 2145
2137 if ((GNUNET_YES == GNUNET_CONFIGURATION_have_value(sh.cfg, 2146 if ((GNUNET_YES == GNUNET_CONFIGURATION_have_value (sh.cfg,
2138 service_name, 2147 service_name,
2139 "GAUGER_HEAP")) && 2148 "GAUGER_HEAP")) &&
2140 (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(sh.cfg, 2149 (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (sh.cfg,
2141 service_name, 2150 service_name,
2142 "GAUGER_HEAP", 2151 "GAUGER_HEAP",
2143 &counter))) 2152 &counter)))
2144 { 2153 {
2145 struct mallinfo mi; 2154 struct mallinfo mi;
2146 2155
2147 mi = mallinfo(); 2156 mi = mallinfo ();
2148 GAUGER(service_name, counter, mi.usmblks, "blocks"); 2157 GAUGER (service_name, counter, mi.usmblks, "blocks");
2149 GNUNET_free(counter); 2158 GNUNET_free (counter);
2150 } 2159 }
2151 } 2160 }
2152#endif 2161#endif
2153 teardown_service(&sh); 2162 teardown_service (&sh);
2154 GNUNET_free_non_null(sh.handlers); 2163 GNUNET_free_non_null (sh.handlers);
2155 GNUNET_SPEEDUP_stop_(); 2164 GNUNET_SPEEDUP_stop_ ();
2156 GNUNET_CONFIGURATION_destroy(cfg); 2165 GNUNET_CONFIGURATION_destroy (cfg);
2157 GNUNET_free_non_null(logfile); 2166 GNUNET_free_non_null (logfile);
2158 GNUNET_free_non_null(loglev); 2167 GNUNET_free_non_null (loglev);
2159 GNUNET_free(cfg_filename); 2168 GNUNET_free (cfg_filename);
2160 GNUNET_free_non_null(opt_cfg_filename); 2169 GNUNET_free_non_null (opt_cfg_filename);
2161 2170
2162 return err ? GNUNET_SYSERR : sh.ret; 2171 return err ? GNUNET_SYSERR : sh.ret;
2163} 2172}
@@ -2170,9 +2179,9 @@ shutdown:
2170 * @param sh service to stop accepting connections. 2179 * @param sh service to stop accepting connections.
2171 */ 2180 */
2172void 2181void
2173GNUNET_SERVICE_suspend(struct GNUNET_SERVICE_Handle *sh) 2182GNUNET_SERVICE_suspend (struct GNUNET_SERVICE_Handle *sh)
2174{ 2183{
2175 do_suspend(sh, SUSPEND_STATE_APP); 2184 do_suspend (sh, SUSPEND_STATE_APP);
2176} 2185}
2177 2186
2178 2187
@@ -2182,9 +2191,9 @@ GNUNET_SERVICE_suspend(struct GNUNET_SERVICE_Handle *sh)
2182 * @param sh service to resume accepting connections. 2191 * @param sh service to resume accepting connections.
2183 */ 2192 */
2184void 2193void
2185GNUNET_SERVICE_resume(struct GNUNET_SERVICE_Handle *sh) 2194GNUNET_SERVICE_resume (struct GNUNET_SERVICE_Handle *sh)
2186{ 2195{
2187 do_resume(sh, SUSPEND_STATE_APP); 2196 do_resume (sh, SUSPEND_STATE_APP);
2188} 2197}
2189 2198
2190 2199
@@ -2195,32 +2204,32 @@ GNUNET_SERVICE_resume(struct GNUNET_SERVICE_Handle *sh)
2195 * @param cls our `struct GNUNET_SERVICE_Client` 2204 * @param cls our `struct GNUNET_SERVICE_Client`
2196 */ 2205 */
2197static void 2206static void
2198resume_client_receive(void *cls) 2207resume_client_receive (void *cls)
2199{ 2208{
2200 struct GNUNET_SERVICE_Client *c = cls; 2209 struct GNUNET_SERVICE_Client *c = cls;
2201 int ret; 2210 int ret;
2202 2211
2203 c->recv_task = NULL; 2212 c->recv_task = NULL;
2204 /* first, check if there is still something in the buffer */ 2213 /* first, check if there is still something in the buffer */
2205 ret = GNUNET_MST_next(c->mst, GNUNET_YES); 2214 ret = GNUNET_MST_next (c->mst, GNUNET_YES);
2206 if (GNUNET_SYSERR == ret) 2215 if (GNUNET_SYSERR == ret)
2207 { 2216 {
2208 if (NULL == c->drop_task) 2217 if (NULL == c->drop_task)
2209 GNUNET_SERVICE_client_drop(c); 2218 GNUNET_SERVICE_client_drop (c);
2210 return; 2219 return;
2211 } 2220 }
2212 if (GNUNET_NO == ret) 2221 if (GNUNET_NO == ret)
2213 return; /* done processing, wait for more later */ 2222 return; /* done processing, wait for more later */
2214 GNUNET_assert(GNUNET_OK == ret); 2223 GNUNET_assert (GNUNET_OK == ret);
2215 if (GNUNET_YES == c->needs_continue) 2224 if (GNUNET_YES == c->needs_continue)
2216 return; /* #GNUNET_MST_next() did give a message to the client */ 2225 return; /* #GNUNET_MST_next() did give a message to the client */
2217 /* need to receive more data from the network first */ 2226 /* need to receive more data from the network first */
2218 if (NULL != c->recv_task) 2227 if (NULL != c->recv_task)
2219 return; 2228 return;
2220 c->recv_task = GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, 2229 c->recv_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
2221 c->sock, 2230 c->sock,
2222 &service_client_recv, 2231 &service_client_recv,
2223 c); 2232 c);
2224} 2233}
2225 2234
2226 2235
@@ -2231,18 +2240,18 @@ resume_client_receive(void *cls)
2231 * @param c the client to continue receiving from 2240 * @param c the client to continue receiving from
2232 */ 2241 */
2233void 2242void
2234GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c) 2243GNUNET_SERVICE_client_continue (struct GNUNET_SERVICE_Client *c)
2235{ 2244{
2236 GNUNET_assert(NULL == c->drop_task); 2245 GNUNET_assert (NULL == c->drop_task);
2237 GNUNET_assert(GNUNET_YES == c->needs_continue); 2246 GNUNET_assert (GNUNET_YES == c->needs_continue);
2238 GNUNET_assert(NULL == c->recv_task); 2247 GNUNET_assert (NULL == c->recv_task);
2239 c->needs_continue = GNUNET_NO; 2248 c->needs_continue = GNUNET_NO;
2240 if (NULL != c->warn_task) 2249 if (NULL != c->warn_task)
2241 { 2250 {
2242 GNUNET_SCHEDULER_cancel(c->warn_task); 2251 GNUNET_SCHEDULER_cancel (c->warn_task);
2243 c->warn_task = NULL; 2252 c->warn_task = NULL;
2244 } 2253 }
2245 c->recv_task = GNUNET_SCHEDULER_add_now(&resume_client_receive, c); 2254 c->recv_task = GNUNET_SCHEDULER_add_now (&resume_client_receive, c);
2246} 2255}
2247 2256
2248 2257
@@ -2255,14 +2264,14 @@ GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
2255 * @param c client for which to disable the warning 2264 * @param c client for which to disable the warning
2256 */ 2265 */
2257void 2266void
2258GNUNET_SERVICE_client_disable_continue_warning(struct GNUNET_SERVICE_Client *c) 2267GNUNET_SERVICE_client_disable_continue_warning (struct GNUNET_SERVICE_Client *c)
2259{ 2268{
2260 GNUNET_break(NULL != c->warn_task); 2269 GNUNET_break (NULL != c->warn_task);
2261 if (NULL != c->warn_task) 2270 if (NULL != c->warn_task)
2262 { 2271 {
2263 GNUNET_SCHEDULER_cancel(c->warn_task); 2272 GNUNET_SCHEDULER_cancel (c->warn_task);
2264 c->warn_task = NULL; 2273 c->warn_task = NULL;
2265 } 2274 }
2266} 2275}
2267 2276
2268 2277
@@ -2272,32 +2281,32 @@ GNUNET_SERVICE_client_disable_continue_warning(struct GNUNET_SERVICE_Client *c)
2272 * @param cls the `struct GNUNET_SERVICE_Client`. 2281 * @param cls the `struct GNUNET_SERVICE_Client`.
2273 */ 2282 */
2274static void 2283static void
2275finish_client_drop(void *cls) 2284finish_client_drop (void *cls)
2276{ 2285{
2277 struct GNUNET_SERVICE_Client *c = cls; 2286 struct GNUNET_SERVICE_Client *c = cls;
2278 struct GNUNET_SERVICE_Handle *sh = c->sh; 2287 struct GNUNET_SERVICE_Handle *sh = c->sh;
2279 2288
2280 c->drop_task = NULL; 2289 c->drop_task = NULL;
2281 GNUNET_assert(NULL == c->send_task); 2290 GNUNET_assert (NULL == c->send_task);
2282 GNUNET_assert(NULL == c->recv_task); 2291 GNUNET_assert (NULL == c->recv_task);
2283 GNUNET_assert(NULL == c->warn_task); 2292 GNUNET_assert (NULL == c->warn_task);
2284 GNUNET_MST_destroy(c->mst); 2293 GNUNET_MST_destroy (c->mst);
2285 GNUNET_MQ_destroy(c->mq); 2294 GNUNET_MQ_destroy (c->mq);
2286 if (GNUNET_NO == c->persist) 2295 if (GNUNET_NO == c->persist)
2287 { 2296 {
2288 GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(c->sock)); 2297 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (c->sock));
2289 if ((0 != (SUSPEND_STATE_EMFILE & sh->suspend_state)) && 2298 if ((0 != (SUSPEND_STATE_EMFILE & sh->suspend_state)) &&
2290 (0 == (SUSPEND_STATE_SHUTDOWN & sh->suspend_state))) 2299 (0 == (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)))
2291 do_resume(sh, SUSPEND_STATE_EMFILE); 2300 do_resume (sh, SUSPEND_STATE_EMFILE);
2292 } 2301 }
2293 else 2302 else
2294 { 2303 {
2295 GNUNET_NETWORK_socket_free_memory_only_(c->sock); 2304 GNUNET_NETWORK_socket_free_memory_only_ (c->sock);
2296 } 2305 }
2297 GNUNET_free(c); 2306 GNUNET_free (c);
2298 if ((0 != (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)) && 2307 if ((0 != (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)) &&
2299 (GNUNET_NO == have_non_monitor_clients(sh))) 2308 (GNUNET_NO == have_non_monitor_clients (sh)))
2300 GNUNET_SERVICE_shutdown(sh); 2309 GNUNET_SERVICE_shutdown (sh);
2301} 2310}
2302 2311
2303 2312
@@ -2312,52 +2321,56 @@ finish_client_drop(void *cls)
2312 * @param c client to disconnect now 2321 * @param c client to disconnect now
2313 */ 2322 */
2314void 2323void
2315GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c) 2324GNUNET_SERVICE_client_drop (struct GNUNET_SERVICE_Client *c)
2316{ 2325{
2317 struct GNUNET_SERVICE_Handle *sh = c->sh; 2326 struct GNUNET_SERVICE_Handle *sh = c->sh;
2318 2327
2319 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 2328 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2320 "Client dropped: %p (MQ: %p)\n", 2329 "Client dropped: %p (MQ: %p)\n",
2321 c, 2330 c,
2322 c->mq); 2331 c->mq);
2323#if EXECINFO 2332#if EXECINFO
2324 { 2333 {
2325 void *backtrace_array[MAX_TRACE_DEPTH]; 2334 void *backtrace_array[MAX_TRACE_DEPTH];
2326 int num_backtrace_strings = backtrace(backtrace_array, MAX_TRACE_DEPTH); 2335 int num_backtrace_strings = backtrace (backtrace_array, MAX_TRACE_DEPTH);
2327 char **backtrace_strings = 2336 char **backtrace_strings =
2328 backtrace_symbols(backtrace_array, t->num_backtrace_strings); 2337 backtrace_symbols (backtrace_array, t->num_backtrace_strings);
2329 for (unsigned int i = 0; i < num_backtrace_strings; i++) 2338 for (unsigned int i = 0; i < num_backtrace_strings; i++)
2330 LOG(GNUNET_ERROR_TYPE_DEBUG, 2339 LOG (GNUNET_ERROR_TYPE_DEBUG,
2331 "client drop trace %u: %s\n", 2340 "client drop trace %u: %s\n",
2332 i, 2341 i,
2333 backtrace_strings[i]); 2342 backtrace_strings[i]);
2334 } 2343 }
2335#endif 2344#endif
2336 if (NULL != c->drop_task) 2345 if (NULL != c->drop_task)
2337 { 2346 {
2338 /* asked to drop twice! */ 2347 /* asked to drop twice! */
2339 GNUNET_assert(0); 2348 GNUNET_assert (0);
2340 return; 2349 return;
2341 } 2350 }
2342 GNUNET_CONTAINER_DLL_remove(sh->clients_head, sh->clients_tail, c); 2351 GNUNET_CONTAINER_DLL_remove (sh->clients_head,
2352 sh->clients_tail,
2353 c);
2343 if (NULL != sh->disconnect_cb) 2354 if (NULL != sh->disconnect_cb)
2344 sh->disconnect_cb(sh->cb_cls, c, c->user_context); 2355 sh->disconnect_cb (sh->cb_cls,
2356 c,
2357 c->user_context);
2345 if (NULL != c->warn_task) 2358 if (NULL != c->warn_task)
2346 { 2359 {
2347 GNUNET_SCHEDULER_cancel(c->warn_task); 2360 GNUNET_SCHEDULER_cancel (c->warn_task);
2348 c->warn_task = NULL; 2361 c->warn_task = NULL;
2349 } 2362 }
2350 if (NULL != c->recv_task) 2363 if (NULL != c->recv_task)
2351 { 2364 {
2352 GNUNET_SCHEDULER_cancel(c->recv_task); 2365 GNUNET_SCHEDULER_cancel (c->recv_task);
2353 c->recv_task = NULL; 2366 c->recv_task = NULL;
2354 } 2367 }
2355 if (NULL != c->send_task) 2368 if (NULL != c->send_task)
2356 { 2369 {
2357 GNUNET_SCHEDULER_cancel(c->send_task); 2370 GNUNET_SCHEDULER_cancel (c->send_task);
2358 c->send_task = NULL; 2371 c->send_task = NULL;
2359 } 2372 }
2360 c->drop_task = GNUNET_SCHEDULER_add_now(&finish_client_drop, c); 2373 c->drop_task = GNUNET_SCHEDULER_add_now (&finish_client_drop, c);
2361} 2374}
2362 2375
2363 2376
@@ -2367,14 +2380,14 @@ GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
2367 * @param sh server to shutdown 2380 * @param sh server to shutdown
2368 */ 2381 */
2369void 2382void
2370GNUNET_SERVICE_shutdown(struct GNUNET_SERVICE_Handle *sh) 2383GNUNET_SERVICE_shutdown (struct GNUNET_SERVICE_Handle *sh)
2371{ 2384{
2372 struct GNUNET_SERVICE_Client *client; 2385 struct GNUNET_SERVICE_Client *client;
2373 2386
2374 if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN)) 2387 if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN))
2375 do_suspend(sh, SUSPEND_STATE_SHUTDOWN); 2388 do_suspend (sh, SUSPEND_STATE_SHUTDOWN);
2376 while (NULL != (client = sh->clients_head)) 2389 while (NULL != (client = sh->clients_head))
2377 GNUNET_SERVICE_client_drop(client); 2390 GNUNET_SERVICE_client_drop (client);
2378} 2391}
2379 2392
2380 2393
@@ -2391,12 +2404,12 @@ GNUNET_SERVICE_shutdown(struct GNUNET_SERVICE_Handle *sh)
2391 * @param c client to mark as a monitor 2404 * @param c client to mark as a monitor
2392 */ 2405 */
2393void 2406void
2394GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c) 2407GNUNET_SERVICE_client_mark_monitor (struct GNUNET_SERVICE_Client *c)
2395{ 2408{
2396 c->is_monitor = GNUNET_YES; 2409 c->is_monitor = GNUNET_YES;
2397 if (((0 != (SUSPEND_STATE_SHUTDOWN & c->sh->suspend_state)) && 2410 if (((0 != (SUSPEND_STATE_SHUTDOWN & c->sh->suspend_state)) &&
2398 (GNUNET_NO == have_non_monitor_clients(c->sh)))) 2411 (GNUNET_NO == have_non_monitor_clients (c->sh))))
2399 GNUNET_SERVICE_shutdown(c->sh); 2412 GNUNET_SERVICE_shutdown (c->sh);
2400} 2413}
2401 2414
2402 2415
@@ -2408,7 +2421,7 @@ GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c)
2408 * @param c client to persist the socket (never to be closed) 2421 * @param c client to persist the socket (never to be closed)
2409 */ 2422 */
2410void 2423void
2411GNUNET_SERVICE_client_persist(struct GNUNET_SERVICE_Client *c) 2424GNUNET_SERVICE_client_persist (struct GNUNET_SERVICE_Client *c)
2412{ 2425{
2413 c->persist = GNUNET_YES; 2426 c->persist = GNUNET_YES;
2414} 2427}
@@ -2421,10 +2434,10 @@ GNUNET_SERVICE_client_persist(struct GNUNET_SERVICE_Client *c)
2421 * @return the message queue of @a c 2434 * @return the message queue of @a c
2422 */ 2435 */
2423struct GNUNET_MQ_Handle * 2436struct GNUNET_MQ_Handle *
2424GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c) 2437GNUNET_SERVICE_client_get_mq (struct GNUNET_SERVICE_Client *c)
2425{ 2438{
2426 return c->mq; 2439 return c->mq;
2427} 2440}
2428 2441
2429 2442
2430/* end of service_new.c */ 2443/* end of service.c */