aboutsummaryrefslogtreecommitdiff
path: root/src/arm/gnunet-service-arm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/arm/gnunet-service-arm.c')
-rw-r--r--src/arm/gnunet-service-arm.c2268
1 files changed, 1135 insertions, 1133 deletions
diff --git a/src/arm/gnunet-service-arm.c b/src/arm/gnunet-service-arm.c
index b0f7e07c4..e8c740235 100644
--- a/src/arm/gnunet-service-arm.c
+++ b/src/arm/gnunet-service-arm.c
@@ -16,7 +16,7 @@
16 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
18 SPDX-License-Identifier: AGPL3.0-or-later 18 SPDX-License-Identifier: AGPL3.0-or-later
19*/ 19 */
20 20
21/** 21/**
22 * @file arm/gnunet-service-arm.c 22 * @file 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,8 +65,7 @@ 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{
70 /** 69 /**
71 * This is a linked list. 70 * This is a linked list.
72 */ 71 */
@@ -107,8 +106,7 @@ struct ServiceListeningInfo
107/** 106/**
108 * List of our services. 107 * List of our services.
109 */ 108 */
110struct ServiceList 109struct ServiceList {
111{
112 /** 110 /**
113 * This is a doubly-linked list. 111 * This is a doubly-linked list.
114 */ 112 */
@@ -280,30 +278,30 @@ static struct GNUNET_NotificationContext *notifier;
280 * parameter is ignore on systems other than LINUX 278 * parameter is ignore on systems other than LINUX
281 */ 279 */
282static void 280static void
283add_unixpath (struct sockaddr **saddrs, 281add_unixpath(struct sockaddr **saddrs,
284 socklen_t *saddrlens, 282 socklen_t *saddrlens,
285 const char *unixpath, 283 const char *unixpath,
286 int abstract) 284 int abstract)
287{ 285{
288#ifdef AF_UNIX 286#ifdef AF_UNIX
289 struct sockaddr_un *un; 287 struct sockaddr_un *un;
290 288
291 un = GNUNET_new (struct sockaddr_un); 289 un = GNUNET_new(struct sockaddr_un);
292 un->sun_family = AF_UNIX; 290 un->sun_family = AF_UNIX;
293 GNUNET_strlcpy (un->sun_path, unixpath, sizeof (un->sun_path)); 291 GNUNET_strlcpy(un->sun_path, unixpath, sizeof(un->sun_path));
294#ifdef LINUX 292#ifdef LINUX
295 if (GNUNET_YES == abstract) 293 if (GNUNET_YES == abstract)
296 un->sun_path[0] = '\0'; 294 un->sun_path[0] = '\0';
297#endif 295#endif
298#if HAVE_SOCKADDR_UN_SUN_LEN 296#if HAVE_SOCKADDR_UN_SUN_LEN
299 un->sun_len = (u_char) sizeof (struct sockaddr_un); 297 un->sun_len = (u_char)sizeof(struct sockaddr_un);
300#endif 298#endif
301 *saddrs = (struct sockaddr *) un; 299 *saddrs = (struct sockaddr *)un;
302 *saddrlens = sizeof (struct sockaddr_un); 300 *saddrlens = sizeof(struct sockaddr_un);
303#else 301#else
304 /* this function should never be called 302 /* this function should never be called
305 * unless AF_UNIX is defined! */ 303 * unless AF_UNIX is defined! */
306 GNUNET_assert (0); 304 GNUNET_assert(0);
307#endif 305#endif
308} 306}
309 307
@@ -329,10 +327,10 @@ add_unixpath (struct sockaddr **saddrs,
329 * set to NULL). 327 * set to NULL).
330 */ 328 */
331static int 329static int
332get_server_addresses (const char *service_name, 330get_server_addresses(const char *service_name,
333 const struct GNUNET_CONFIGURATION_Handle *cfg, 331 const struct GNUNET_CONFIGURATION_Handle *cfg,
334 struct sockaddr ***addrs, 332 struct sockaddr ***addrs,
335 socklen_t **addr_lens) 333 socklen_t **addr_lens)
336{ 334{
337 int disablev6; 335 int disablev6;
338 struct GNUNET_NETWORK_Handle *desc; 336 struct GNUNET_NETWORK_Handle *desc;
@@ -353,72 +351,72 @@ get_server_addresses (const char *service_name,
353 *addrs = NULL; 351 *addrs = NULL;
354 *addr_lens = NULL; 352 *addr_lens = NULL;
355 desc = NULL; 353 desc = NULL;
356 if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "DISABLEV6")) 354 if (GNUNET_CONFIGURATION_have_value(cfg, service_name, "DISABLEV6"))
357 {
358 if (GNUNET_SYSERR ==
359 (disablev6 = GNUNET_CONFIGURATION_get_value_yesno (cfg,
360 service_name,
361 "DISABLEV6")))
362 return GNUNET_SYSERR;
363 }
364 else
365 disablev6 = GNUNET_NO;
366
367 if (! disablev6)
368 {
369 /* probe IPv6 support */
370 desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0);
371 if (NULL == desc)
372 { 355 {
373 if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) || 356 if (GNUNET_SYSERR ==
374 (EACCES == errno)) 357 (disablev6 = GNUNET_CONFIGURATION_get_value_yesno(cfg,
375 { 358 service_name,
376 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket"); 359 "DISABLEV6")))
377 return GNUNET_SYSERR; 360 return GNUNET_SYSERR;
378 }
379 LOG (GNUNET_ERROR_TYPE_INFO,
380 _ (
381 "Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"),
382 service_name,
383 strerror (errno));
384 disablev6 = GNUNET_YES;
385 } 361 }
386 else 362 else
363 disablev6 = GNUNET_NO;
364
365 if (!disablev6)
387 { 366 {
388 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc)); 367 /* probe IPv6 support */
389 desc = NULL; 368 desc = GNUNET_NETWORK_socket_create(PF_INET6, SOCK_STREAM, 0);
369 if (NULL == desc)
370 {
371 if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
372 (EACCES == errno))
373 {
374 LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "socket");
375 return GNUNET_SYSERR;
376 }
377 LOG(GNUNET_ERROR_TYPE_INFO,
378 _(
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 }
390 } 389 }
391 }
392 390
393 port = 0; 391 port = 0;
394 if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT")) 392 if (GNUNET_CONFIGURATION_have_value(cfg, service_name, "PORT"))
395 {
396 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg,
397 service_name,
398 "PORT",
399 &port))
400 {
401 LOG (GNUNET_ERROR_TYPE_ERROR,
402 _ ("Require valid port number for service `%s' in configuration!\n"),
403 service_name);
404 }
405 if (port > 65535)
406 { 393 {
407 LOG (GNUNET_ERROR_TYPE_ERROR, 394 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number(cfg,
408 _ ("Require valid port number for service `%s' in configuration!\n"), 395 service_name,
409 service_name); 396 "PORT",
410 return GNUNET_SYSERR; 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 }
411 } 410 }
412 }
413 411
414 if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "BINDTO")) 412 if (GNUNET_CONFIGURATION_have_value(cfg, service_name, "BINDTO"))
415 { 413 {
416 GNUNET_break (GNUNET_OK == 414 GNUNET_break(GNUNET_OK ==
417 GNUNET_CONFIGURATION_get_value_string (cfg, 415 GNUNET_CONFIGURATION_get_value_string(cfg,
418 service_name, 416 service_name,
419 "BINDTO", 417 "BINDTO",
420 &hostname)); 418 &hostname));
421 } 419 }
422 else 420 else
423 hostname = NULL; 421 hostname = NULL;
424 422
@@ -426,235 +424,235 @@ get_server_addresses (const char *service_name,
426 abstract = GNUNET_NO; 424 abstract = GNUNET_NO;
427#ifdef AF_UNIX 425#ifdef AF_UNIX
428 if ((GNUNET_YES == 426 if ((GNUNET_YES ==
429 GNUNET_CONFIGURATION_have_value (cfg, service_name, "UNIXPATH")) && 427 GNUNET_CONFIGURATION_have_value(cfg, service_name, "UNIXPATH")) &&
430 (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename (cfg, 428 (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename(cfg,
431 service_name, 429 service_name,
432 "UNIXPATH", 430 "UNIXPATH",
433 &unixpath)) && 431 &unixpath)) &&
434 (0 < strlen (unixpath))) 432 (0 < strlen(unixpath)))
435 {
436 /* probe UNIX support */
437 struct sockaddr_un s_un;
438
439 if (strlen (unixpath) >= sizeof (s_un.sun_path))
440 { 433 {
441 LOG (GNUNET_ERROR_TYPE_WARNING, 434 /* probe UNIX support */
442 _ ("UNIXPATH `%s' too long, maximum length is %llu\n"), 435 struct sockaddr_un s_un;
443 unixpath, 436
444 (unsigned long long) sizeof (s_un.sun_path)); 437 if (strlen(unixpath) >= sizeof(s_un.sun_path))
445 unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath); 438 {
446 LOG (GNUNET_ERROR_TYPE_INFO, _ ("Using `%s' instead\n"), unixpath); 439 LOG(GNUNET_ERROR_TYPE_WARNING,
447 } 440 _("UNIXPATH `%s' too long, maximum length is %llu\n"),
441 unixpath,
442 (unsigned long long)sizeof(s_un.sun_path));
443 unixpath = GNUNET_NETWORK_shorten_unixpath(unixpath);
444 LOG(GNUNET_ERROR_TYPE_INFO, _("Using `%s' instead\n"), unixpath);
445 }
448#ifdef LINUX 446#ifdef LINUX
449 abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg, 447 abstract = GNUNET_CONFIGURATION_get_value_yesno(cfg,
450 "TESTING", 448 "TESTING",
451 "USE_ABSTRACT_SOCKETS"); 449 "USE_ABSTRACT_SOCKETS");
452 if (GNUNET_SYSERR == abstract) 450 if (GNUNET_SYSERR == abstract)
453 abstract = GNUNET_NO; 451 abstract = GNUNET_NO;
454#endif 452#endif
455 if ((GNUNET_YES != abstract) && 453 if ((GNUNET_YES != abstract) &&
456 (GNUNET_OK != GNUNET_DISK_directory_create_for_file (unixpath))) 454 (GNUNET_OK != GNUNET_DISK_directory_create_for_file(unixpath)))
457 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "mkdir", unixpath); 455 GNUNET_log_strerror_file(GNUNET_ERROR_TYPE_ERROR, "mkdir", unixpath);
458 }
459 if (NULL != unixpath)
460 {
461 desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
462 if (NULL == desc)
463 {
464 if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
465 (EACCES == errno))
466 {
467 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket");
468 GNUNET_free_non_null (hostname);
469 GNUNET_free (unixpath);
470 return GNUNET_SYSERR;
471 }
472 LOG (GNUNET_ERROR_TYPE_INFO,
473 _ (
474 "Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
475 service_name,
476 strerror (errno));
477 GNUNET_free (unixpath);
478 unixpath = NULL;
479 } 456 }
480 else 457 if (NULL != unixpath)
481 { 458 {
482 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc)); 459 desc = GNUNET_NETWORK_socket_create(AF_UNIX, SOCK_STREAM, 0);
483 desc = NULL; 460 if (NULL == desc)
461 {
462 if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
463 (EACCES == errno))
464 {
465 LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "socket");
466 GNUNET_free_non_null(hostname);
467 GNUNET_free(unixpath);
468 return GNUNET_SYSERR;
469 }
470 LOG(GNUNET_ERROR_TYPE_INFO,
471 _(
472 "Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
473 service_name,
474 strerror(errno));
475 GNUNET_free(unixpath);
476 unixpath = NULL;
477 }
478 else
479 {
480 GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(desc));
481 desc = NULL;
482 }
484 } 483 }
485 }
486#endif 484#endif
487 485
488 if ((0 == port) && (NULL == unixpath)) 486 if ((0 == port) && (NULL == unixpath))
489 {
490 if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (cfg,
491 service_name,
492 "START_ON_DEMAND"))
493 LOG (GNUNET_ERROR_TYPE_ERROR,
494 _ (
495 "Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
496 service_name);
497 GNUNET_free_non_null (hostname);
498 return GNUNET_SYSERR;
499 }
500 if (0 == port)
501 {
502 saddrs = GNUNET_new_array (2, struct sockaddr *);
503 saddrlens = GNUNET_new_array (2, socklen_t);
504 add_unixpath (saddrs, saddrlens, unixpath, abstract);
505 GNUNET_free_non_null (unixpath);
506 GNUNET_free_non_null (hostname);
507 *addrs = saddrs;
508 *addr_lens = saddrlens;
509 return 1;
510 }
511
512 if (NULL != hostname)
513 {
514 LOG (GNUNET_ERROR_TYPE_DEBUG,
515 "Resolving `%s' since that is where `%s' will bind to.\n",
516 hostname,
517 service_name);
518 memset (&hints, 0, sizeof (struct addrinfo));
519 if (disablev6)
520 hints.ai_family = AF_INET;
521 hints.ai_protocol = IPPROTO_TCP;
522 if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) ||
523 (NULL == res))
524 { 487 {
525 LOG (GNUNET_ERROR_TYPE_ERROR, 488 if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno(cfg,
526 _ ("Failed to resolve `%s': %s\n"), 489 service_name,
527 hostname, 490 "START_ON_DEMAND"))
528 gai_strerror (ret)); 491 LOG(GNUNET_ERROR_TYPE_ERROR,
529 GNUNET_free (hostname); 492 _(
530 GNUNET_free_non_null (unixpath); 493 "Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
531 return GNUNET_SYSERR; 494 service_name);
532 } 495 GNUNET_free_non_null(hostname);
533 next = res;
534 i = 0;
535 while (NULL != (pos = next))
536 {
537 next = pos->ai_next;
538 if ((disablev6) && (pos->ai_family == AF_INET6))
539 continue;
540 i++;
541 }
542 if (0 == i)
543 {
544 LOG (GNUNET_ERROR_TYPE_ERROR,
545 _ ("Failed to find %saddress for `%s'.\n"),
546 disablev6 ? "IPv4 " : "",
547 hostname);
548 freeaddrinfo (res);
549 GNUNET_free (hostname);
550 GNUNET_free_non_null (unixpath);
551 return GNUNET_SYSERR; 496 return GNUNET_SYSERR;
552 } 497 }
553 resi = i; 498 if (0 == port)
554 if (NULL != unixpath)
555 resi++;
556 saddrs = GNUNET_new_array (resi + 1, struct sockaddr *);
557 saddrlens = GNUNET_new_array (resi + 1, socklen_t);
558 i = 0;
559 if (NULL != unixpath)
560 { 499 {
561 add_unixpath (saddrs, saddrlens, unixpath, abstract); 500 saddrs = GNUNET_new_array(2, struct sockaddr *);
562 i++; 501 saddrlens = GNUNET_new_array(2, socklen_t);
502 add_unixpath(saddrs, saddrlens, unixpath, abstract);
503 GNUNET_free_non_null(unixpath);
504 GNUNET_free_non_null(hostname);
505 *addrs = saddrs;
506 *addr_lens = saddrlens;
507 return 1;
563 } 508 }
564 next = res; 509
565 while (NULL != (pos = next)) 510 if (NULL != hostname)
566 {
567 next = pos->ai_next;
568 if ((disablev6) && (AF_INET6 == pos->ai_family))
569 continue;
570 if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol))
571 continue; /* not TCP */
572 if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype))
573 continue; /* huh? */
574 LOG (GNUNET_ERROR_TYPE_DEBUG,
575 "Service `%s' will bind to `%s'\n",
576 service_name,
577 GNUNET_a2s (pos->ai_addr, pos->ai_addrlen));
578 if (AF_INET == pos->ai_family)
579 {
580 GNUNET_assert (sizeof (struct sockaddr_in) == pos->ai_addrlen);
581 saddrlens[i] = pos->ai_addrlen;
582 saddrs[i] = GNUNET_malloc (saddrlens[i]);
583 GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
584 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
585 }
586 else
587 {
588 GNUNET_assert (AF_INET6 == pos->ai_family);
589 GNUNET_assert (sizeof (struct sockaddr_in6) == pos->ai_addrlen);
590 saddrlens[i] = pos->ai_addrlen;
591 saddrs[i] = GNUNET_malloc (saddrlens[i]);
592 GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
593 ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
594 }
595 i++;
596 }
597 GNUNET_free (hostname);
598 freeaddrinfo (res);
599 resi = i;
600 }
601 else
602 {
603 /* will bind against everything, just set port */
604 if (disablev6)
605 { 511 {
606 /* V4-only */ 512 LOG(GNUNET_ERROR_TYPE_DEBUG,
607 resi = 1; 513 "Resolving `%s' since that is where `%s' will bind to.\n",
514 hostname,
515 service_name);
516 memset(&hints, 0, sizeof(struct addrinfo));
517 if (disablev6)
518 hints.ai_family = AF_INET;
519 hints.ai_protocol = IPPROTO_TCP;
520 if ((0 != (ret = getaddrinfo(hostname, NULL, &hints, &res))) ||
521 (NULL == res))
522 {
523 LOG(GNUNET_ERROR_TYPE_ERROR,
524 _("Failed to resolve `%s': %s\n"),
525 hostname,
526 gai_strerror(ret));
527 GNUNET_free(hostname);
528 GNUNET_free_non_null(unixpath);
529 return GNUNET_SYSERR;
530 }
531 next = res;
532 i = 0;
533 while (NULL != (pos = next))
534 {
535 next = pos->ai_next;
536 if ((disablev6) && (pos->ai_family == AF_INET6))
537 continue;
538 i++;
539 }
540 if (0 == i)
541 {
542 LOG(GNUNET_ERROR_TYPE_ERROR,
543 _("Failed to find %saddress for `%s'.\n"),
544 disablev6 ? "IPv4 " : "",
545 hostname);
546 freeaddrinfo(res);
547 GNUNET_free(hostname);
548 GNUNET_free_non_null(unixpath);
549 return GNUNET_SYSERR;
550 }
551 resi = i;
608 if (NULL != unixpath) 552 if (NULL != unixpath)
609 resi++; 553 resi++;
554 saddrs = GNUNET_new_array(resi + 1, struct sockaddr *);
555 saddrlens = GNUNET_new_array(resi + 1, socklen_t);
610 i = 0; 556 i = 0;
611 saddrs = GNUNET_new_array (resi + 1, struct sockaddr *);
612 saddrlens = GNUNET_new_array (resi + 1, socklen_t);
613 if (NULL != unixpath) 557 if (NULL != unixpath)
614 { 558 {
615 add_unixpath (saddrs, saddrlens, unixpath, abstract); 559 add_unixpath(saddrs, saddrlens, unixpath, abstract);
616 i++; 560 i++;
617 } 561 }
618 saddrlens[i] = sizeof (struct sockaddr_in); 562 next = res;
619 saddrs[i] = GNUNET_malloc (saddrlens[i]); 563 while (NULL != (pos = next))
620#if HAVE_SOCKADDR_IN_SIN_LEN 564 {
621 ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i]; 565 next = pos->ai_next;
622#endif 566 if ((disablev6) && (AF_INET6 == pos->ai_family))
623 ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET; 567 continue;
624 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port); 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;
625 } 598 }
626 else 599 else
627 { 600 {
628 /* dual stack */ 601 /* will bind against everything, just set port */
629 resi = 2; 602 if (disablev6)
630 if (NULL != unixpath) 603 {
631 resi++; 604 /* V4-only */
632 saddrs = GNUNET_new_array (resi + 1, struct sockaddr *); 605 resi = 1;
633 saddrlens = GNUNET_new_array (resi + 1, socklen_t); 606 if (NULL != unixpath)
634 i = 0; 607 resi++;
635 if (NULL != unixpath) 608 i = 0;
636 { 609 saddrs = GNUNET_new_array(resi + 1, struct sockaddr *);
637 add_unixpath (saddrs, saddrlens, unixpath, abstract); 610 saddrlens = GNUNET_new_array(resi + 1, socklen_t);
638 i++; 611 if (NULL != unixpath)
639 } 612 {
640 saddrlens[i] = sizeof (struct sockaddr_in6); 613 add_unixpath(saddrs, saddrlens, unixpath, abstract);
641 saddrs[i] = GNUNET_malloc (saddrlens[i]); 614 i++;
615 }
616 saddrlens[i] = sizeof(struct sockaddr_in);
617 saddrs[i] = GNUNET_malloc(saddrlens[i]);
618#if HAVE_SOCKADDR_IN_SIN_LEN
619 ((struct sockaddr_in *)saddrs[i])->sin_len = saddrlens[i];
620#endif
621 ((struct sockaddr_in *)saddrs[i])->sin_family = AF_INET;
622 ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port);
623 }
624 else
625 {
626 /* dual stack */
627 resi = 2;
628 if (NULL != unixpath)
629 resi++;
630 saddrs = GNUNET_new_array(resi + 1, struct sockaddr *);
631 saddrlens = GNUNET_new_array(resi + 1, socklen_t);
632 i = 0;
633 if (NULL != unixpath)
634 {
635 add_unixpath(saddrs, saddrlens, unixpath, abstract);
636 i++;
637 }
638 saddrlens[i] = sizeof(struct sockaddr_in6);
639 saddrs[i] = GNUNET_malloc(saddrlens[i]);
642#if HAVE_SOCKADDR_IN_SIN_LEN 640#if HAVE_SOCKADDR_IN_SIN_LEN
643 ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0]; 641 ((struct sockaddr_in6 *)saddrs[i])->sin6_len = saddrlens[0];
644#endif 642#endif
645 ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6; 643 ((struct sockaddr_in6 *)saddrs[i])->sin6_family = AF_INET6;
646 ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port); 644 ((struct sockaddr_in6 *)saddrs[i])->sin6_port = htons(port);
647 i++; 645 i++;
648 saddrlens[i] = sizeof (struct sockaddr_in); 646 saddrlens[i] = sizeof(struct sockaddr_in);
649 saddrs[i] = GNUNET_malloc (saddrlens[i]); 647 saddrs[i] = GNUNET_malloc(saddrlens[i]);
650#if HAVE_SOCKADDR_IN_SIN_LEN 648#if HAVE_SOCKADDR_IN_SIN_LEN
651 ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1]; 649 ((struct sockaddr_in *)saddrs[i])->sin_len = saddrlens[1];
652#endif 650#endif
653 ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET; 651 ((struct sockaddr_in *)saddrs[i])->sin_family = AF_INET;
654 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port); 652 ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port);
653 }
655 } 654 }
656 } 655 GNUNET_free_non_null(unixpath);
657 GNUNET_free_non_null (unixpath);
658 *addrs = saddrs; 656 *addrs = saddrs;
659 *addr_lens = saddrlens; 657 *addr_lens = saddrlens;
660 return resi; 658 return resi;
@@ -672,19 +670,19 @@ get_server_addresses (const char *service_name,
672 * @return NULL if it was not found 670 * @return NULL if it was not found
673 */ 671 */
674static void 672static void
675signal_result (struct GNUNET_SERVICE_Client *client, 673signal_result(struct GNUNET_SERVICE_Client *client,
676 const char *name, 674 const char *name,
677 uint64_t request_id, 675 uint64_t request_id,
678 enum GNUNET_ARM_Result result) 676 enum GNUNET_ARM_Result result)
679{ 677{
680 struct GNUNET_MQ_Envelope *env; 678 struct GNUNET_MQ_Envelope *env;
681 struct GNUNET_ARM_ResultMessage *msg; 679 struct GNUNET_ARM_ResultMessage *msg;
682 680
683 (void) name; 681 (void)name;
684 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_ARM_RESULT); 682 env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_ARM_RESULT);
685 msg->result = htonl (result); 683 msg->result = htonl(result);
686 msg->arm_msg.request_id = GNUNET_htonll (request_id); 684 msg->arm_msg.request_id = GNUNET_htonll(request_id);
687 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env); 685 GNUNET_MQ_send(GNUNET_SERVICE_client_get_mq(client), env);
688} 686}
689 687
690 688
@@ -697,34 +695,34 @@ signal_result (struct GNUNET_SERVICE_Client *client,
697 * otherwise, send to all clients in the notifier 695 * otherwise, send to all clients in the notifier
698 */ 696 */
699static void 697static void
700broadcast_status (const char *name, 698broadcast_status(const char *name,
701 enum GNUNET_ARM_ServiceStatus status, 699 enum GNUNET_ARM_ServiceStatus status,
702 struct GNUNET_SERVICE_Client *unicast) 700 struct GNUNET_SERVICE_Client *unicast)
703{ 701{
704 struct GNUNET_MQ_Envelope *env; 702 struct GNUNET_MQ_Envelope *env;
705 struct GNUNET_ARM_StatusMessage *msg; 703 struct GNUNET_ARM_StatusMessage *msg;
706 size_t namelen; 704 size_t namelen;
707 705
708 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 706 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
709 "Sending status %u of service `%s' to client\n", 707 "Sending status %u of service `%s' to client\n",
710 (unsigned int) status, 708 (unsigned int)status,
711 name); 709 name);
712 namelen = strlen (name) + 1; 710 namelen = strlen(name) + 1;
713 env = GNUNET_MQ_msg_extra (msg, namelen, GNUNET_MESSAGE_TYPE_ARM_STATUS); 711 env = GNUNET_MQ_msg_extra(msg, namelen, GNUNET_MESSAGE_TYPE_ARM_STATUS);
714 msg->status = htonl ((uint32_t) (status)); 712 msg->status = htonl((uint32_t)(status));
715 GNUNET_memcpy ((char *) &msg[1], name, namelen); 713 GNUNET_memcpy((char *)&msg[1], name, namelen);
716 if (NULL == unicast) 714 if (NULL == unicast)
717 { 715 {
718 if (NULL != notifier) 716 if (NULL != notifier)
719 GNUNET_notification_context_broadcast (notifier, 717 GNUNET_notification_context_broadcast(notifier,
720 &msg->header, 718 &msg->header,
721 GNUNET_YES); 719 GNUNET_YES);
722 GNUNET_MQ_discard (env); 720 GNUNET_MQ_discard(env);
723 } 721 }
724 else 722 else
725 { 723 {
726 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (unicast), env); 724 GNUNET_MQ_send(GNUNET_SERVICE_client_get_mq(unicast), env);
727 } 725 }
728} 726}
729 727
730 728
@@ -737,9 +735,9 @@ broadcast_status (const char *name,
737 * being started. 0 if starting was not requested. 735 * being started. 0 if starting was not requested.
738 */ 736 */
739static void 737static void
740start_process (struct ServiceList *sl, 738start_process(struct ServiceList *sl,
741 struct GNUNET_SERVICE_Client *client, 739 struct GNUNET_SERVICE_Client *client,
742 uint64_t request_id) 740 uint64_t request_id)
743{ 741{
744 char *loprefix; 742 char *loprefix;
745 char *options; 743 char *options;
@@ -755,194 +753,194 @@ start_process (struct ServiceList *sl,
755 lsocks = NULL; 753 lsocks = NULL;
756 ls = 0; 754 ls = 0;
757 for (sli = sl->listen_head; NULL != sli; sli = sli->next) 755 for (sli = sl->listen_head; NULL != sli; sli = sli->next)
758 {
759 GNUNET_array_append (lsocks,
760 ls,
761 GNUNET_NETWORK_get_fd (sli->listen_socket));
762 if (NULL != sli->accept_task)
763 { 756 {
764 GNUNET_SCHEDULER_cancel (sli->accept_task); 757 GNUNET_array_append(lsocks,
765 sli->accept_task = NULL; 758 ls,
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 }
766 } 765 }
767 }
768#if WINDOWS 766#if WINDOWS
769 GNUNET_array_append (lsocks, ls, INVALID_SOCKET); 767 GNUNET_array_append(lsocks, ls, INVALID_SOCKET);
770#else 768#else
771 GNUNET_array_append (lsocks, ls, -1); 769 GNUNET_array_append(lsocks, ls, -1);
772#endif 770#endif
773 771
774 /* obtain configuration */ 772 /* obtain configuration */
775 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, 773 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg,
776 sl->name, 774 sl->name,
777 "PREFIX", 775 "PREFIX",
778 &loprefix)) 776 &loprefix))
779 loprefix = GNUNET_strdup (prefix_command); 777 loprefix = GNUNET_strdup(prefix_command);
780 else 778 else
781 loprefix = GNUNET_CONFIGURATION_expand_dollar (cfg, loprefix); 779 loprefix = GNUNET_CONFIGURATION_expand_dollar(cfg, loprefix);
782 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, 780 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg,
783 sl->name, 781 sl->name,
784 "OPTIONS", 782 "OPTIONS",
785 &options)) 783 &options))
786 options = NULL; 784 options = NULL;
787 else 785 else
788 options = GNUNET_CONFIGURATION_expand_dollar (cfg, options); 786 options = GNUNET_CONFIGURATION_expand_dollar(cfg, options);
789 { 787 {
790 char *new_options; 788 char *new_options;
791 char *optpos; 789 char *optpos;
792 char *fin_options; 790 char *fin_options;
793 791
794 fin_options = GNUNET_strdup (final_option); 792 fin_options = GNUNET_strdup(final_option);
795 /* replace '{}' with service name */ 793 /* replace '{}' with service name */
796 while (NULL != (optpos = strstr (fin_options, "{}"))) 794 while (NULL != (optpos = strstr(fin_options, "{}")))
797 { 795 {
798 /* terminate string at opening parenthesis */ 796 /* terminate string at opening parenthesis */
799 *optpos = 0; 797 *optpos = 0;
800 GNUNET_asprintf (&new_options, 798 GNUNET_asprintf(&new_options,
801 "%s%s%s", 799 "%s%s%s",
802 fin_options, 800 fin_options,
803 sl->name, 801 sl->name,
804 optpos + 2); 802 optpos + 2);
805 GNUNET_free (fin_options); 803 GNUNET_free(fin_options);
806 fin_options = new_options; 804 fin_options = new_options;
807 } 805 }
808 if (NULL != options) 806 if (NULL != options)
809 { 807 {
810 /* combine "fin_options" with "options" */ 808 /* combine "fin_options" with "options" */
811 optpos = options; 809 optpos = options;
812 GNUNET_asprintf (&options, "%s %s", fin_options, optpos); 810 GNUNET_asprintf(&options, "%s %s", fin_options, optpos);
813 GNUNET_free (fin_options); 811 GNUNET_free(fin_options);
814 GNUNET_free (optpos); 812 GNUNET_free(optpos);
815 } 813 }
816 else 814 else
817 { 815 {
818 /* only have "fin_options", use that */ 816 /* only have "fin_options", use that */
819 options = fin_options; 817 options = fin_options;
820 } 818 }
821 } 819 }
822 options = GNUNET_CONFIGURATION_expand_dollar (cfg, options); 820 options = GNUNET_CONFIGURATION_expand_dollar(cfg, options);
823 use_debug = GNUNET_CONFIGURATION_get_value_yesno (cfg, sl->name, "DEBUG"); 821 use_debug = GNUNET_CONFIGURATION_get_value_yesno(cfg, sl->name, "DEBUG");
824 { 822 {
825 const char *service_type = NULL; 823 const char *service_type = NULL;
826 const char *choices[] = {"GNUNET", "SIMPLE", NULL}; 824 const char *choices[] = { "GNUNET", "SIMPLE", NULL };
827 825
828 is_simple_service = GNUNET_NO; 826 is_simple_service = GNUNET_NO;
829 if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_choice (cfg, 827 if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_choice(cfg,
830 sl->name, 828 sl->name,
831 "TYPE", 829 "TYPE",
832 choices, 830 choices,
833 &service_type)) && 831 &service_type)) &&
834 (0 == strcasecmp (service_type, "SIMPLE"))) 832 (0 == strcasecmp(service_type, "SIMPLE")))
835 is_simple_service = GNUNET_YES; 833 is_simple_service = GNUNET_YES;
836 } 834 }
837 835
838 GNUNET_assert (NULL == sl->proc); 836 GNUNET_assert(NULL == sl->proc);
839 if (GNUNET_YES == is_simple_service) 837 if (GNUNET_YES == is_simple_service)
840 {
841 /* A simple service will receive no GNUnet specific
842 command line options. */
843 binary = GNUNET_strdup (sl->binary);
844 binary = GNUNET_CONFIGURATION_expand_dollar (cfg, binary);
845 GNUNET_asprintf (&quotedbinary, "\"%s\"", sl->binary);
846 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
847 "Starting simple service `%s' using binary `%s'\n",
848 sl->name,
849 sl->binary);
850 /* FIXME: dollar expansion should only be done outside
851 * of ''-quoted strings, escaping should be considered. */
852 if (NULL != options)
853 options = GNUNET_CONFIGURATION_expand_dollar (cfg, options);
854 sl->proc = GNUNET_OS_start_process_s (sl->pipe_control,
855 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
856 lsocks,
857 loprefix,
858 quotedbinary,
859 options,
860 NULL);
861 }
862 else
863 {
864 /* actually start process */
865 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
866 "Starting service `%s' using binary `%s' and configuration `%s'\n",
867 sl->name,
868 sl->binary,
869 sl->config);
870 binary = GNUNET_OS_get_libexec_binary_path (sl->binary);
871 GNUNET_asprintf (&quotedbinary, "\"%s\"", binary);
872
873 if (GNUNET_YES == use_debug)
874 { 838 {
875 if (NULL == sl->config) 839 /* A simple service will receive no GNUnet specific
876 sl->proc = GNUNET_OS_start_process_s (sl->pipe_control, 840 command line options. */
877 GNUNET_OS_INHERIT_STD_OUT_AND_ERR, 841 binary = GNUNET_strdup(sl->binary);
878 lsocks, 842 binary = GNUNET_CONFIGURATION_expand_dollar(cfg, binary);
879 loprefix, 843 GNUNET_asprintf(&quotedbinary, "\"%s\"", sl->binary);
880 quotedbinary, 844 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
881 "-L", 845 "Starting simple service `%s' using binary `%s'\n",
882 "DEBUG", 846 sl->name,
883 options, 847 sl->binary);
884 NULL); 848 /* FIXME: dollar expansion should only be done outside
885 else 849 * of ''-quoted strings, escaping should be considered. */
886 sl->proc = GNUNET_OS_start_process_s (sl->pipe_control, 850 if (NULL != options)
887 GNUNET_OS_INHERIT_STD_OUT_AND_ERR, 851 options = GNUNET_CONFIGURATION_expand_dollar(cfg, options);
888 lsocks, 852 sl->proc = GNUNET_OS_start_process_s(sl->pipe_control,
889 loprefix, 853 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
890 quotedbinary, 854 lsocks,
891 "-c", 855 loprefix,
892 sl->config, 856 quotedbinary,
893 "-L", 857 options,
894 "DEBUG", 858 NULL);
895 options,
896 NULL);
897 } 859 }
898 else 860 else
899 { 861 {
900 if (NULL == sl->config) 862 /* actually start process */
901 sl->proc = GNUNET_OS_start_process_s (sl->pipe_control, 863 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
902 GNUNET_OS_INHERIT_STD_OUT_AND_ERR, 864 "Starting service `%s' using binary `%s' and configuration `%s'\n",
903 lsocks, 865 sl->name,
904 loprefix, 866 sl->binary,
905 quotedbinary, 867 sl->config);
906 options, 868 binary = GNUNET_OS_get_libexec_binary_path(sl->binary);
907 NULL); 869 GNUNET_asprintf(&quotedbinary, "\"%s\"", binary);
870
871 if (GNUNET_YES == use_debug)
872 {
873 if (NULL == sl->config)
874 sl->proc = GNUNET_OS_start_process_s(sl->pipe_control,
875 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
876 lsocks,
877 loprefix,
878 quotedbinary,
879 "-L",
880 "DEBUG",
881 options,
882 NULL);
883 else
884 sl->proc = GNUNET_OS_start_process_s(sl->pipe_control,
885 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
886 lsocks,
887 loprefix,
888 quotedbinary,
889 "-c",
890 sl->config,
891 "-L",
892 "DEBUG",
893 options,
894 NULL);
895 }
908 else 896 else
909 sl->proc = GNUNET_OS_start_process_s (sl->pipe_control, 897 {
910 GNUNET_OS_INHERIT_STD_OUT_AND_ERR, 898 if (NULL == sl->config)
911 lsocks, 899 sl->proc = GNUNET_OS_start_process_s(sl->pipe_control,
912 loprefix, 900 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
913 quotedbinary, 901 lsocks,
914 "-c", 902 loprefix,
915 sl->config, 903 quotedbinary,
916 options, 904 options,
917 NULL); 905 NULL);
906 else
907 sl->proc = GNUNET_OS_start_process_s(sl->pipe_control,
908 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
909 lsocks,
910 loprefix,
911 quotedbinary,
912 "-c",
913 sl->config,
914 options,
915 NULL);
916 }
918 } 917 }
919 } 918 GNUNET_free(binary);
920 GNUNET_free (binary); 919 GNUNET_free(quotedbinary);
921 GNUNET_free (quotedbinary);
922 if (NULL == sl->proc) 920 if (NULL == sl->proc)
923 { 921 {
924 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 922 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
925 _ ("Failed to start service `%s'\n"), 923 _("Failed to start service `%s'\n"),
926 sl->name); 924 sl->name);
927 if (client) 925 if (client)
928 signal_result (client, 926 signal_result(client,
929 sl->name, 927 sl->name,
930 request_id, 928 request_id,
931 GNUNET_ARM_RESULT_START_FAILED); 929 GNUNET_ARM_RESULT_START_FAILED);
932 } 930 }
933 else 931 else
934 { 932 {
935 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 933 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
936 _ ("Starting service `%s'\n"), 934 _("Starting service `%s'\n"),
937 sl->name); 935 sl->name);
938 broadcast_status (sl->name, GNUNET_ARM_SERVICE_STARTING, NULL); 936 broadcast_status(sl->name, GNUNET_ARM_SERVICE_STARTING, NULL);
939 if (client) 937 if (client)
940 signal_result (client, sl->name, request_id, GNUNET_ARM_RESULT_STARTING); 938 signal_result(client, sl->name, request_id, GNUNET_ARM_RESULT_STARTING);
941 } 939 }
942 /* clean up */ 940 /* clean up */
943 GNUNET_free (loprefix); 941 GNUNET_free(loprefix);
944 GNUNET_free (options); 942 GNUNET_free(options);
945 GNUNET_array_grow (lsocks, ls, 0); 943 GNUNET_array_grow(lsocks, ls, 0);
946} 944}
947 945
948 946
@@ -954,17 +952,17 @@ start_process (struct ServiceList *sl,
954 * @return NULL if it was not found 952 * @return NULL if it was not found
955 */ 953 */
956static struct ServiceList * 954static struct ServiceList *
957find_service (const char *name) 955find_service(const char *name)
958{ 956{
959 struct ServiceList *sl; 957 struct ServiceList *sl;
960 958
961 sl = running_head; 959 sl = running_head;
962 while (sl != NULL) 960 while (sl != NULL)
963 { 961 {
964 if (0 == strcasecmp (sl->name, name)) 962 if (0 == strcasecmp(sl->name, name))
965 return sl; 963 return sl;
966 sl = sl->next; 964 sl = sl->next;
967 } 965 }
968 return NULL; 966 return NULL;
969} 967}
970 968
@@ -976,14 +974,14 @@ find_service (const char *name)
976 * @param cls callback data, `struct ServiceListeningInfo` describing a listen socket 974 * @param cls callback data, `struct ServiceListeningInfo` describing a listen socket
977 */ 975 */
978static void 976static void
979accept_connection (void *cls) 977accept_connection(void *cls)
980{ 978{
981 struct ServiceListeningInfo *sli = cls; 979 struct ServiceListeningInfo *sli = cls;
982 struct ServiceList *sl = sli->sl; 980 struct ServiceList *sl = sli->sl;
983 981
984 sli->accept_task = NULL; 982 sli->accept_task = NULL;
985 GNUNET_assert (GNUNET_NO == in_shutdown); 983 GNUNET_assert(GNUNET_NO == in_shutdown);
986 start_process (sl, NULL, 0); 984 start_process(sl, NULL, 0);
987} 985}
988 986
989 987
@@ -996,121 +994,125 @@ accept_connection (void *cls)
996 * @param sl service entry for the service in question 994 * @param sl service entry for the service in question
997 */ 995 */
998static void 996static void
999create_listen_socket (struct sockaddr *sa, 997create_listen_socket(struct sockaddr *sa,
1000 socklen_t addr_len, 998 socklen_t addr_len,
1001 struct ServiceList *sl) 999 struct ServiceList *sl)
1002{ 1000{
1003 static int on = 1; 1001 static int on = 1;
1004 struct GNUNET_NETWORK_Handle *sock; 1002 struct GNUNET_NETWORK_Handle *sock;
1005 struct ServiceListeningInfo *sli; 1003 struct ServiceListeningInfo *sli;
1004
1006#ifndef WINDOWS 1005#ifndef WINDOWS
1007 int match_uid; 1006 int match_uid;
1008 int match_gid; 1007 int match_gid;
1009#endif 1008#endif
1010 1009
1011 switch (sa->sa_family) 1010 switch (sa->sa_family)
1012 { 1011 {
1013 case AF_INET: 1012 case AF_INET:
1014 sock = GNUNET_NETWORK_socket_create (PF_INET, SOCK_STREAM, 0); 1013 sock = GNUNET_NETWORK_socket_create(PF_INET, SOCK_STREAM, 0);
1015 break; 1014 break;
1016 case AF_INET6: 1015
1017 sock = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0); 1016 case AF_INET6:
1018 break; 1017 sock = GNUNET_NETWORK_socket_create(PF_INET6, SOCK_STREAM, 0);
1019 case AF_UNIX: 1018 break;
1020 if (0 == strcmp (GNUNET_a2s (sa, addr_len), 1019
1021 "@")) /* Do not bind to blank UNIX path! */ 1020 case AF_UNIX:
1022 return; 1021 if (0 == strcmp(GNUNET_a2s(sa, addr_len),
1023 sock = GNUNET_NETWORK_socket_create (PF_UNIX, SOCK_STREAM, 0); 1022 "@")) /* Do not bind to blank UNIX path! */
1024 break; 1023 return;
1025 default: 1024 sock = GNUNET_NETWORK_socket_create(PF_UNIX, SOCK_STREAM, 0);
1026 GNUNET_break (0); 1025 break;
1027 sock = NULL; 1026
1028 errno = EAFNOSUPPORT; 1027 default:
1029 break; 1028 GNUNET_break(0);
1030 } 1029 sock = NULL;
1030 errno = EAFNOSUPPORT;
1031 break;
1032 }
1031 if (NULL == sock) 1033 if (NULL == sock)
1032 { 1034 {
1033 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1035 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
1034 _ ("Unable to create socket for service `%s': %s\n"), 1036 _("Unable to create socket for service `%s': %s\n"),
1035 sl->name, 1037 sl->name,
1036 strerror (errno)); 1038 strerror(errno));
1037 GNUNET_free (sa); 1039 GNUNET_free(sa);
1038 return; 1040 return;
1039 } 1041 }
1040 if (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt (sock, 1042 if (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt(sock,
1041 SOL_SOCKET, 1043 SOL_SOCKET,
1042 SO_REUSEADDR, 1044 SO_REUSEADDR,
1043 &on, 1045 &on,
1044 sizeof (on))) 1046 sizeof(on)))
1045 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 1047 GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1046 "setsockopt"); 1048 "setsockopt");
1047#ifdef IPV6_V6ONLY 1049#ifdef IPV6_V6ONLY
1048 if ((sa->sa_family == AF_INET6) && 1050 if ((sa->sa_family == AF_INET6) &&
1049 (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt (sock, 1051 (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt(sock,
1050 IPPROTO_IPV6, 1052 IPPROTO_IPV6,
1051 IPV6_V6ONLY, 1053 IPV6_V6ONLY,
1052 &on, 1054 &on,
1053 sizeof (on)))) 1055 sizeof(on))))
1054 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 1056 GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1055 "setsockopt"); 1057 "setsockopt");
1056#endif 1058#endif
1057#ifndef WINDOWS 1059#ifndef WINDOWS
1058 if (AF_UNIX == sa->sa_family) 1060 if (AF_UNIX == sa->sa_family)
1059 GNUNET_NETWORK_unix_precheck ((struct sockaddr_un *) sa); 1061 GNUNET_NETWORK_unix_precheck((struct sockaddr_un *)sa);
1060#endif 1062#endif
1061 if (GNUNET_OK != 1063 if (GNUNET_OK !=
1062 GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) sa, addr_len)) 1064 GNUNET_NETWORK_socket_bind(sock, (const struct sockaddr *)sa, addr_len))
1063 { 1065 {
1064 GNUNET_log ( 1066 GNUNET_log(
1065 GNUNET_ERROR_TYPE_WARNING, 1067 GNUNET_ERROR_TYPE_WARNING,
1066 _ ( 1068 _(
1067 "Unable to bind listening socket for service `%s' to address `%s': %s\n"), 1069 "Unable to bind listening socket for service `%s' to address `%s': %s\n"),
1068 sl->name, 1070 sl->name,
1069 GNUNET_a2s (sa, addr_len), 1071 GNUNET_a2s(sa, addr_len),
1070 strerror (errno)); 1072 strerror(errno));
1071 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); 1073 GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(sock));
1072 GNUNET_free (sa); 1074 GNUNET_free(sa);
1073 return; 1075 return;
1074 } 1076 }
1075#ifndef WINDOWS 1077#ifndef WINDOWS
1076 if ((AF_UNIX == sa->sa_family) 1078 if ((AF_UNIX == sa->sa_family)
1077#ifdef LINUX 1079#ifdef LINUX
1078 /* Permission settings are not required when abstract sockets are used */ 1080 /* Permission settings are not required when abstract sockets are used */
1079 && ('\0' != ((const struct sockaddr_un *) sa)->sun_path[0]) 1081 && ('\0' != ((const struct sockaddr_un *)sa)->sun_path[0])
1080#endif 1082#endif
1081 ) 1083 )
1082 { 1084 {
1083 match_uid = 1085 match_uid =
1084 GNUNET_CONFIGURATION_get_value_yesno (cfg, sl->name, "UNIX_MATCH_UID"); 1086 GNUNET_CONFIGURATION_get_value_yesno(cfg, sl->name, "UNIX_MATCH_UID");
1085 match_gid = 1087 match_gid =
1086 GNUNET_CONFIGURATION_get_value_yesno (cfg, sl->name, "UNIX_MATCH_GID"); 1088 GNUNET_CONFIGURATION_get_value_yesno(cfg, sl->name, "UNIX_MATCH_GID");
1087 GNUNET_DISK_fix_permissions (((const struct sockaddr_un *) sa)->sun_path, 1089 GNUNET_DISK_fix_permissions(((const struct sockaddr_un *)sa)->sun_path,
1088 match_uid, 1090 match_uid,
1089 match_gid); 1091 match_gid);
1090 } 1092 }
1091#endif 1093#endif
1092 if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5)) 1094 if (GNUNET_OK != GNUNET_NETWORK_socket_listen(sock, 5))
1093 { 1095 {
1094 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "listen"); 1096 GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, "listen");
1095 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); 1097 GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(sock));
1096 GNUNET_free (sa); 1098 GNUNET_free(sa);
1097 return; 1099 return;
1098 } 1100 }
1099 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1101 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1100 _ ("ARM now monitors connections to service `%s' at `%s'\n"), 1102 _("ARM now monitors connections to service `%s' at `%s'\n"),
1101 sl->name, 1103 sl->name,
1102 GNUNET_a2s (sa, addr_len)); 1104 GNUNET_a2s(sa, addr_len));
1103 sli = GNUNET_new (struct ServiceListeningInfo); 1105 sli = GNUNET_new(struct ServiceListeningInfo);
1104 sli->service_addr = sa; 1106 sli->service_addr = sa;
1105 sli->service_addr_len = addr_len; 1107 sli->service_addr_len = addr_len;
1106 sli->listen_socket = sock; 1108 sli->listen_socket = sock;
1107 sli->sl = sl; 1109 sli->sl = sl;
1108 sli->accept_task = 1110 sli->accept_task =
1109 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 1111 GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL,
1110 sock, 1112 sock,
1111 &accept_connection, 1113 &accept_connection,
1112 sli); 1114 sli);
1113 GNUNET_CONTAINER_DLL_insert (sl->listen_head, sl->listen_tail, sli); 1115 GNUNET_CONTAINER_DLL_insert(sl->listen_head, sl->listen_tail, sli);
1114} 1116}
1115 1117
1116 1118
@@ -1121,15 +1123,15 @@ create_listen_socket (struct sockaddr *sa,
1121 * @param sl entry to free 1123 * @param sl entry to free
1122 */ 1124 */
1123static void 1125static void
1124free_service (struct ServiceList *sl) 1126free_service(struct ServiceList *sl)
1125{ 1127{
1126 GNUNET_assert (GNUNET_YES == in_shutdown); 1128 GNUNET_assert(GNUNET_YES == in_shutdown);
1127 GNUNET_CONTAINER_DLL_remove (running_head, running_tail, sl); 1129 GNUNET_CONTAINER_DLL_remove(running_head, running_tail, sl);
1128 GNUNET_assert (NULL == sl->listen_head); 1130 GNUNET_assert(NULL == sl->listen_head);
1129 GNUNET_free_non_null (sl->config); 1131 GNUNET_free_non_null(sl->config);
1130 GNUNET_free_non_null (sl->binary); 1132 GNUNET_free_non_null(sl->binary);
1131 GNUNET_free (sl->name); 1133 GNUNET_free(sl->name);
1132 GNUNET_free (sl); 1134 GNUNET_free(sl);
1133} 1135}
1134 1136
1135 1137
@@ -1142,10 +1144,10 @@ free_service (struct ServiceList *sl)
1142 * #GNUNET_SYSERR to close it (signal serious error) 1144 * #GNUNET_SYSERR to close it (signal serious error)
1143 */ 1145 */
1144static int 1146static int
1145check_start (void *cls, const struct GNUNET_ARM_Message *amsg) 1147check_start(void *cls, const struct GNUNET_ARM_Message *amsg)
1146{ 1148{
1147 (void) cls; 1149 (void)cls;
1148 GNUNET_MQ_check_zero_termination (amsg); 1150 GNUNET_MQ_check_zero_termination(amsg);
1149 return GNUNET_OK; 1151 return GNUNET_OK;
1150} 1152}
1151 1153
@@ -1157,43 +1159,43 @@ check_start (void *cls, const struct GNUNET_ARM_Message *amsg)
1157 * @param amsg the actual message 1159 * @param amsg the actual message
1158 */ 1160 */
1159static void 1161static void
1160handle_start (void *cls, const struct GNUNET_ARM_Message *amsg) 1162handle_start(void *cls, const struct GNUNET_ARM_Message *amsg)
1161{ 1163{
1162 struct GNUNET_SERVICE_Client *client = cls; 1164 struct GNUNET_SERVICE_Client *client = cls;
1163 const char *servicename; 1165 const char *servicename;
1164 struct ServiceList *sl; 1166 struct ServiceList *sl;
1165 uint64_t request_id; 1167 uint64_t request_id;
1166 1168
1167 request_id = GNUNET_ntohll (amsg->request_id); 1169 request_id = GNUNET_ntohll(amsg->request_id);
1168 servicename = (const char *) &amsg[1]; 1170 servicename = (const char *)&amsg[1];
1169 GNUNET_SERVICE_client_continue (client); 1171 GNUNET_SERVICE_client_continue(client);
1170 if (GNUNET_YES == in_shutdown) 1172 if (GNUNET_YES == in_shutdown)
1171 { 1173 {
1172 signal_result (client, 1174 signal_result(client,
1173 servicename, 1175 servicename,
1174 request_id, 1176 request_id,
1175 GNUNET_ARM_RESULT_IN_SHUTDOWN); 1177 GNUNET_ARM_RESULT_IN_SHUTDOWN);
1176 return; 1178 return;
1177 } 1179 }
1178 sl = find_service (servicename); 1180 sl = find_service(servicename);
1179 if (NULL == sl) 1181 if (NULL == sl)
1180 { 1182 {
1181 signal_result (client, 1183 signal_result(client,
1182 servicename, 1184 servicename,
1183 request_id, 1185 request_id,
1184 GNUNET_ARM_RESULT_IS_NOT_KNOWN); 1186 GNUNET_ARM_RESULT_IS_NOT_KNOWN);
1185 return; 1187 return;
1186 } 1188 }
1187 sl->force_start = GNUNET_YES; 1189 sl->force_start = GNUNET_YES;
1188 if (NULL != sl->proc) 1190 if (NULL != sl->proc)
1189 { 1191 {
1190 signal_result (client, 1192 signal_result(client,
1191 servicename, 1193 servicename,
1192 request_id, 1194 request_id,
1193 GNUNET_ARM_RESULT_IS_STARTED_ALREADY); 1195 GNUNET_ARM_RESULT_IS_STARTED_ALREADY);
1194 return; 1196 return;
1195 } 1197 }
1196 start_process (sl, client, request_id); 1198 start_process(sl, client, request_id);
1197} 1199}
1198 1200
1199 1201
@@ -1203,11 +1205,11 @@ handle_start (void *cls, const struct GNUNET_ARM_Message *amsg)
1203 * @param cls closure (refers to service) 1205 * @param cls closure (refers to service)
1204 */ 1206 */
1205static void 1207static void
1206trigger_shutdown (void *cls) 1208trigger_shutdown(void *cls)
1207{ 1209{
1208 (void) cls; 1210 (void)cls;
1209 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Triggering shutdown\n"); 1211 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Triggering shutdown\n");
1210 GNUNET_SCHEDULER_shutdown (); 1212 GNUNET_SCHEDULER_shutdown();
1211} 1213}
1212 1214
1213 1215
@@ -1220,10 +1222,10 @@ trigger_shutdown (void *cls)
1220 * #GNUNET_SYSERR to close it (signal serious error) 1222 * #GNUNET_SYSERR to close it (signal serious error)
1221 */ 1223 */
1222static int 1224static int
1223check_stop (void *cls, const struct GNUNET_ARM_Message *amsg) 1225check_stop(void *cls, const struct GNUNET_ARM_Message *amsg)
1224{ 1226{
1225 (void) cls; 1227 (void)cls;
1226 GNUNET_MQ_check_zero_termination (amsg); 1228 GNUNET_MQ_check_zero_termination(amsg);
1227 return GNUNET_OK; 1229 return GNUNET_OK;
1228} 1230}
1229 1231
@@ -1235,72 +1237,72 @@ check_stop (void *cls, const struct GNUNET_ARM_Message *amsg)
1235 * @param amsg the actual message 1237 * @param amsg the actual message
1236 */ 1238 */
1237static void 1239static void
1238handle_stop (void *cls, const struct GNUNET_ARM_Message *amsg) 1240handle_stop(void *cls, const struct GNUNET_ARM_Message *amsg)
1239{ 1241{
1240 struct GNUNET_SERVICE_Client *client = cls; 1242 struct GNUNET_SERVICE_Client *client = cls;
1241 struct ServiceList *sl; 1243 struct ServiceList *sl;
1242 const char *servicename; 1244 const char *servicename;
1243 uint64_t request_id; 1245 uint64_t request_id;
1244 1246
1245 request_id = GNUNET_ntohll (amsg->request_id); 1247 request_id = GNUNET_ntohll(amsg->request_id);
1246 servicename = (const char *) &amsg[1]; 1248 servicename = (const char *)&amsg[1];
1247 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1249 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1248 _ ("Preparing to stop `%s'\n"), 1250 _("Preparing to stop `%s'\n"),
1249 servicename); 1251 servicename);
1250 GNUNET_SERVICE_client_continue (client); 1252 GNUNET_SERVICE_client_continue(client);
1251 if (0 == strcasecmp (servicename, "arm")) 1253 if (0 == strcasecmp(servicename, "arm"))
1252 { 1254 {
1253 broadcast_status (servicename, GNUNET_ARM_SERVICE_STOPPING, NULL); 1255 broadcast_status(servicename, GNUNET_ARM_SERVICE_STOPPING, NULL);
1254 signal_result (client, servicename, request_id, GNUNET_ARM_RESULT_STOPPING); 1256 signal_result(client, servicename, request_id, GNUNET_ARM_RESULT_STOPPING);
1255 GNUNET_SERVICE_client_persist (client); 1257 GNUNET_SERVICE_client_persist(client);
1256 GNUNET_SCHEDULER_add_now (&trigger_shutdown, NULL); 1258 GNUNET_SCHEDULER_add_now(&trigger_shutdown, NULL);
1257 return; 1259 return;
1258 } 1260 }
1259 sl = find_service (servicename); 1261 sl = find_service(servicename);
1260 if (NULL == sl) 1262 if (NULL == sl)
1261 { 1263 {
1262 signal_result (client, 1264 signal_result(client,
1263 servicename, 1265 servicename,
1264 request_id, 1266 request_id,
1265 GNUNET_ARM_RESULT_IS_NOT_KNOWN); 1267 GNUNET_ARM_RESULT_IS_NOT_KNOWN);
1266 return; 1268 return;
1267 } 1269 }
1268 sl->force_start = GNUNET_NO; 1270 sl->force_start = GNUNET_NO;
1269 if (GNUNET_YES == in_shutdown) 1271 if (GNUNET_YES == in_shutdown)
1270 { 1272 {
1271 /* shutdown in progress */ 1273 /* shutdown in progress */
1272 signal_result (client, 1274 signal_result(client,
1273 servicename, 1275 servicename,
1274 request_id, 1276 request_id,
1275 GNUNET_ARM_RESULT_IN_SHUTDOWN); 1277 GNUNET_ARM_RESULT_IN_SHUTDOWN);
1276 return; 1278 return;
1277 } 1279 }
1278 if (NULL != sl->killing_client) 1280 if (NULL != sl->killing_client)
1279 { 1281 {
1280 /* killing already in progress */ 1282 /* killing already in progress */
1281 signal_result (client, 1283 signal_result(client,
1282 servicename, 1284 servicename,
1283 request_id, 1285 request_id,
1284 GNUNET_ARM_RESULT_IS_STOPPING_ALREADY); 1286 GNUNET_ARM_RESULT_IS_STOPPING_ALREADY);
1285 return; 1287 return;
1286 } 1288 }
1287 if (NULL == sl->proc) 1289 if (NULL == sl->proc)
1288 { 1290 {
1289 /* process is down */ 1291 /* process is down */
1290 signal_result (client, 1292 signal_result(client,
1291 servicename, 1293 servicename,
1292 request_id, 1294 request_id,
1293 GNUNET_ARM_RESULT_IS_STOPPED_ALREADY); 1295 GNUNET_ARM_RESULT_IS_STOPPED_ALREADY);
1294 return; 1296 return;
1295 } 1297 }
1296 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1298 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1297 "Sending kill signal to service `%s', waiting for process to die.\n", 1299 "Sending kill signal to service `%s', waiting for process to die.\n",
1298 servicename); 1300 servicename);
1299 broadcast_status (servicename, GNUNET_ARM_SERVICE_STOPPING, NULL); 1301 broadcast_status(servicename, GNUNET_ARM_SERVICE_STOPPING, NULL);
1300 /* no signal_start - only when it's STOPPED */ 1302 /* no signal_start - only when it's STOPPED */
1301 sl->killed_at = GNUNET_TIME_absolute_get (); 1303 sl->killed_at = GNUNET_TIME_absolute_get();
1302 if (0 != GNUNET_OS_process_kill (sl->proc, GNUNET_TERM_SIG)) 1304 if (0 != GNUNET_OS_process_kill(sl->proc, GNUNET_TERM_SIG))
1303 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); 1305 GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING, "kill");
1304 sl->killing_client = client; 1306 sl->killing_client = client;
1305 sl->killing_client_request_id = request_id; 1307 sl->killing_client_request_id = request_id;
1306} 1308}
@@ -1313,7 +1315,7 @@ handle_stop (void *cls, const struct GNUNET_ARM_Message *amsg)
1313 * @param message the actual message 1315 * @param message the actual message
1314 */ 1316 */
1315static void 1317static void
1316handle_list (void *cls, const struct GNUNET_ARM_Message *request) 1318handle_list(void *cls, const struct GNUNET_ARM_Message *request)
1317{ 1319{
1318 struct GNUNET_SERVICE_Client *client = cls; 1320 struct GNUNET_SERVICE_Client *client = cls;
1319 struct GNUNET_MQ_Envelope *env; 1321 struct GNUNET_MQ_Envelope *env;
@@ -1323,40 +1325,40 @@ handle_list (void *cls, const struct GNUNET_ARM_Message *request)
1323 uint16_t count; 1325 uint16_t count;
1324 char *pos; 1326 char *pos;
1325 1327
1326 GNUNET_break (0 == ntohl (request->reserved)); 1328 GNUNET_break(0 == ntohl(request->reserved));
1327 count = 0; 1329 count = 0;
1328 string_list_size = 0; 1330 string_list_size = 0;
1329 1331
1330 /* first count the running processes get their name's size */ 1332 /* first count the running processes get their name's size */
1331 for (sl = running_head; NULL != sl; sl = sl->next) 1333 for (sl = running_head; NULL != sl; sl = sl->next)
1332 {
1333 if (NULL != sl->proc)
1334 { 1334 {
1335 string_list_size += strlen (sl->name); 1335 if (NULL != sl->proc)
1336 string_list_size += strlen (sl->binary); 1336 {
1337 string_list_size += 4; 1337 string_list_size += strlen(sl->name);
1338 count++; 1338 string_list_size += strlen(sl->binary);
1339 string_list_size += 4;
1340 count++;
1341 }
1339 } 1342 }
1340 }
1341 1343
1342 env = GNUNET_MQ_msg_extra (msg, 1344 env = GNUNET_MQ_msg_extra(msg,
1343 string_list_size, 1345 string_list_size,
1344 GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT); 1346 GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT);
1345 msg->arm_msg.request_id = request->request_id; 1347 msg->arm_msg.request_id = request->request_id;
1346 msg->count = htons (count); 1348 msg->count = htons(count);
1347 1349
1348 pos = (char *) &msg[1]; 1350 pos = (char *)&msg[1];
1349 for (sl = running_head; NULL != sl; sl = sl->next) 1351 for (sl = running_head; NULL != sl; sl = sl->next)
1350 {
1351 if (NULL != sl->proc)
1352 { 1352 {
1353 size_t s = strlen (sl->name) + strlen (sl->binary) + 4; 1353 if (NULL != sl->proc)
1354 GNUNET_snprintf (pos, s, "%s (%s)", sl->name, sl->binary); 1354 {
1355 pos += s; 1355 size_t s = strlen(sl->name) + strlen(sl->binary) + 4;
1356 GNUNET_snprintf(pos, s, "%s (%s)", sl->name, sl->binary);
1357 pos += s;
1358 }
1356 } 1359 }
1357 } 1360 GNUNET_MQ_send(GNUNET_SERVICE_client_get_mq(client), env);
1358 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env); 1361 GNUNET_SERVICE_client_continue(client);
1359 GNUNET_SERVICE_client_continue (client);
1360} 1362}
1361 1363
1362 1364
@@ -1367,16 +1369,16 @@ handle_list (void *cls, const struct GNUNET_ARM_Message *request)
1367 * @param message the actual message 1369 * @param message the actual message
1368 */ 1370 */
1369static void 1371static void
1370handle_test (void *cls, const struct GNUNET_MessageHeader *message) 1372handle_test(void *cls, const struct GNUNET_MessageHeader *message)
1371{ 1373{
1372 struct GNUNET_SERVICE_Client *client = cls; 1374 struct GNUNET_SERVICE_Client *client = cls;
1373 struct GNUNET_MQ_Envelope *env; 1375 struct GNUNET_MQ_Envelope *env;
1374 struct GNUNET_MessageHeader *msg; 1376 struct GNUNET_MessageHeader *msg;
1375 1377
1376 (void) message; 1378 (void)message;
1377 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_ARM_TEST); 1379 env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_ARM_TEST);
1378 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env); 1380 GNUNET_MQ_send(GNUNET_SERVICE_client_get_mq(client), env);
1379 GNUNET_SERVICE_client_continue (client); 1381 GNUNET_SERVICE_client_continue(client);
1380} 1382}
1381 1383
1382 1384
@@ -1385,24 +1387,24 @@ handle_test (void *cls, const struct GNUNET_MessageHeader *message)
1385 * tasks, signal handler and the server. 1387 * tasks, signal handler and the server.
1386 */ 1388 */
1387static void 1389static void
1388do_shutdown () 1390do_shutdown()
1389{ 1391{
1390 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Last shutdown phase\n"); 1392 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Last shutdown phase\n");
1391 if (NULL != notifier) 1393 if (NULL != notifier)
1392 { 1394 {
1393 GNUNET_notification_context_destroy (notifier); 1395 GNUNET_notification_context_destroy(notifier);
1394 notifier = NULL; 1396 notifier = NULL;
1395 } 1397 }
1396 if (NULL != service) 1398 if (NULL != service)
1397 { 1399 {
1398 GNUNET_SERVICE_shutdown (service); 1400 GNUNET_SERVICE_shutdown(service);
1399 service = NULL; 1401 service = NULL;
1400 } 1402 }
1401 if (NULL != child_death_task) 1403 if (NULL != child_death_task)
1402 { 1404 {
1403 GNUNET_SCHEDULER_cancel (child_death_task); 1405 GNUNET_SCHEDULER_cancel(child_death_task);
1404 child_death_task = NULL; 1406 child_death_task = NULL;
1405 } 1407 }
1406} 1408}
1407 1409
1408 1410
@@ -1413,13 +1415,13 @@ do_shutdown ()
1413 * @return number of active services found 1415 * @return number of active services found
1414 */ 1416 */
1415static unsigned int 1417static unsigned int
1416list_count (struct ServiceList *running_head) 1418list_count(struct ServiceList *running_head)
1417{ 1419{
1418 struct ServiceList *i; 1420 struct ServiceList *i;
1419 unsigned int res; 1421 unsigned int res;
1420 1422
1421 for (res = 0, i = running_head; NULL != i; i = i->next, res++) 1423 for (res = 0, i = running_head; NULL != i; i = i->next, res++)
1422 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%s\n", i->name); 1424 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s\n", i->name);
1423 return res; 1425 return res;
1424} 1426}
1425 1427
@@ -1430,61 +1432,61 @@ list_count (struct ServiceList *running_head)
1430 * @param cls closure, NULL if we need to self-restart 1432 * @param cls closure, NULL if we need to self-restart
1431 */ 1433 */
1432static void 1434static void
1433shutdown_task (void *cls) 1435shutdown_task(void *cls)
1434{ 1436{
1435 struct ServiceList *pos; 1437 struct ServiceList *pos;
1436 struct ServiceList *nxt; 1438 struct ServiceList *nxt;
1437 struct ServiceListeningInfo *sli; 1439 struct ServiceListeningInfo *sli;
1438 1440
1439 (void) cls; 1441 (void)cls;
1440 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "First shutdown phase\n"); 1442 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "First shutdown phase\n");
1441 if (NULL != child_restart_task) 1443 if (NULL != child_restart_task)
1442 { 1444 {
1443 GNUNET_SCHEDULER_cancel (child_restart_task); 1445 GNUNET_SCHEDULER_cancel(child_restart_task);
1444 child_restart_task = NULL; 1446 child_restart_task = NULL;
1445 } 1447 }
1446 in_shutdown = GNUNET_YES; 1448 in_shutdown = GNUNET_YES;
1447 /* first, stop listening */ 1449 /* first, stop listening */
1448 for (pos = running_head; NULL != pos; pos = pos->next) 1450 for (pos = running_head; NULL != pos; pos = pos->next)
1449 {
1450 while (NULL != (sli = pos->listen_head))
1451 { 1451 {
1452 GNUNET_CONTAINER_DLL_remove (pos->listen_head, pos->listen_tail, sli); 1452 while (NULL != (sli = pos->listen_head))
1453 if (NULL != sli->accept_task) 1453 {
1454 { 1454 GNUNET_CONTAINER_DLL_remove(pos->listen_head, pos->listen_tail, sli);
1455 GNUNET_SCHEDULER_cancel (sli->accept_task); 1455 if (NULL != sli->accept_task)
1456 sli->accept_task = NULL; 1456 {
1457 } 1457 GNUNET_SCHEDULER_cancel(sli->accept_task);
1458 GNUNET_break (GNUNET_OK == 1458 sli->accept_task = NULL;
1459 GNUNET_NETWORK_socket_close (sli->listen_socket)); 1459 }
1460 GNUNET_free (sli->service_addr); 1460 GNUNET_break(GNUNET_OK ==
1461 GNUNET_free (sli); 1461 GNUNET_NETWORK_socket_close(sli->listen_socket));
1462 GNUNET_free(sli->service_addr);
1463 GNUNET_free(sli);
1464 }
1462 } 1465 }
1463 }
1464 /* then, shutdown all existing service processes */ 1466 /* then, shutdown all existing service processes */
1465 nxt = running_head; 1467 nxt = running_head;
1466 while (NULL != (pos = nxt)) 1468 while (NULL != (pos = nxt))
1467 {
1468 nxt = pos->next;
1469 if (NULL != pos->proc)
1470 {
1471 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stopping service `%s'\n", pos->name);
1472 pos->killed_at = GNUNET_TIME_absolute_get ();
1473 if (0 != GNUNET_OS_process_kill (pos->proc, GNUNET_TERM_SIG))
1474 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
1475 }
1476 else
1477 { 1469 {
1478 free_service (pos); 1470 nxt = pos->next;
1471 if (NULL != pos->proc)
1472 {
1473 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Stopping service `%s'\n", pos->name);
1474 pos->killed_at = GNUNET_TIME_absolute_get();
1475 if (0 != GNUNET_OS_process_kill(pos->proc, GNUNET_TERM_SIG))
1476 GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING, "kill");
1477 }
1478 else
1479 {
1480 free_service(pos);
1481 }
1479 } 1482 }
1480 }
1481 /* finally, should all service processes be already gone, terminate for real */ 1483 /* finally, should all service processes be already gone, terminate for real */
1482 if (NULL == running_head) 1484 if (NULL == running_head)
1483 do_shutdown (); 1485 do_shutdown();
1484 else 1486 else
1485 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1487 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1486 "Delaying shutdown, have %u childs still running\n", 1488 "Delaying shutdown, have %u childs still running\n",
1487 list_count (running_head)); 1489 list_count(running_head));
1488} 1490}
1489 1491
1490 1492
@@ -1494,73 +1496,73 @@ shutdown_task (void *cls)
1494 * @param cls closure, always NULL 1496 * @param cls closure, always NULL
1495 */ 1497 */
1496static void 1498static void
1497delayed_restart_task (void *cls) 1499delayed_restart_task(void *cls)
1498 1500
1499{ 1501{
1500 struct ServiceList *sl; 1502 struct ServiceList *sl;
1501 struct GNUNET_TIME_Relative lowestRestartDelay; 1503 struct GNUNET_TIME_Relative lowestRestartDelay;
1502 struct ServiceListeningInfo *sli; 1504 struct ServiceListeningInfo *sli;
1503 1505
1504 (void) cls; 1506 (void)cls;
1505 child_restart_task = NULL; 1507 child_restart_task = NULL;
1506 GNUNET_assert (GNUNET_NO == in_shutdown); 1508 GNUNET_assert(GNUNET_NO == in_shutdown);
1507 lowestRestartDelay = GNUNET_TIME_UNIT_FOREVER_REL; 1509 lowestRestartDelay = GNUNET_TIME_UNIT_FOREVER_REL;
1508 1510
1509 /* check for services that need to be restarted due to 1511 /* check for services that need to be restarted due to
1510 * configuration changes or because the last restart failed */ 1512 * configuration changes or because the last restart failed */
1511 for (sl = running_head; NULL != sl; sl = sl->next) 1513 for (sl = running_head; NULL != sl; sl = sl->next)
1512 {
1513 if (NULL != sl->proc)
1514 continue;
1515 /* service is currently not running */
1516 if (0 == GNUNET_TIME_absolute_get_remaining (sl->restart_at).rel_value_us)
1517 { 1514 {
1518 /* restart is now allowed */ 1515 if (NULL != sl->proc)
1519 if (sl->force_start) 1516 continue;
1520 { 1517 /* service is currently not running */
1521 /* process should run by default, start immediately */ 1518 if (0 == GNUNET_TIME_absolute_get_remaining(sl->restart_at).rel_value_us)
1522 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1519 {
1523 _ ("Restarting service `%s'.\n"), 1520 /* restart is now allowed */
1524 sl->name); 1521 if (sl->force_start)
1525 start_process (sl, NULL, 0); 1522 {
1526 } 1523 /* process should run by default, start immediately */
1524 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1525 _("Restarting service `%s'.\n"),
1526 sl->name);
1527 start_process(sl, NULL, 0);
1528 }
1529 else
1530 {
1531 /* process is run on-demand, ensure it is re-started if there is demand */
1532 for (sli = sl->listen_head; NULL != sli; sli = sli->next)
1533 if (NULL == sli->accept_task)
1534 {
1535 /* accept was actually paused, so start it again */
1536 sli->accept_task =
1537 GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL,
1538 sli->listen_socket,
1539 &accept_connection,
1540 sli);
1541 }
1542 }
1543 }
1527 else 1544 else
1528 { 1545 {
1529 /* process is run on-demand, ensure it is re-started if there is demand */ 1546 /* update calculation for earliest time to reactivate a service */
1530 for (sli = sl->listen_head; NULL != sli; sli = sli->next) 1547 lowestRestartDelay =
1531 if (NULL == sli->accept_task) 1548 GNUNET_TIME_relative_min(lowestRestartDelay,
1532 { 1549 GNUNET_TIME_absolute_get_remaining(
1533 /* accept was actually paused, so start it again */ 1550 sl->restart_at));
1534 sli->accept_task = 1551 }
1535 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
1536 sli->listen_socket,
1537 &accept_connection,
1538 sli);
1539 }
1540 }
1541 }
1542 else
1543 {
1544 /* update calculation for earliest time to reactivate a service */
1545 lowestRestartDelay =
1546 GNUNET_TIME_relative_min (lowestRestartDelay,
1547 GNUNET_TIME_absolute_get_remaining (
1548 sl->restart_at));
1549 } 1552 }
1550 }
1551 if (lowestRestartDelay.rel_value_us != 1553 if (lowestRestartDelay.rel_value_us !=
1552 GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) 1554 GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1553 { 1555 {
1554 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1556 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1555 "Will restart process in %s\n", 1557 "Will restart process in %s\n",
1556 GNUNET_STRINGS_relative_time_to_string (lowestRestartDelay, 1558 GNUNET_STRINGS_relative_time_to_string(lowestRestartDelay,
1557 GNUNET_YES)); 1559 GNUNET_YES));
1558 child_restart_task = 1560 child_restart_task =
1559 GNUNET_SCHEDULER_add_delayed_with_priority (lowestRestartDelay, 1561 GNUNET_SCHEDULER_add_delayed_with_priority(lowestRestartDelay,
1560 GNUNET_SCHEDULER_PRIORITY_IDLE, 1562 GNUNET_SCHEDULER_PRIORITY_IDLE,
1561 &delayed_restart_task, 1563 &delayed_restart_task,
1562 NULL); 1564 NULL);
1563 } 1565 }
1564} 1566}
1565 1567
1566 1568
@@ -1571,7 +1573,7 @@ delayed_restart_task (void *cls)
1571 * @param cls closure, NULL 1573 * @param cls closure, NULL
1572 */ 1574 */
1573static void 1575static void
1574maint_child_death (void *cls) 1576maint_child_death(void *cls)
1575{ 1577{
1576 struct ServiceList *pos; 1578 struct ServiceList *pos;
1577 struct ServiceList *next; 1579 struct ServiceList *next;
@@ -1584,199 +1586,199 @@ maint_child_death (void *cls)
1584 unsigned long statusCode; 1586 unsigned long statusCode;
1585 const struct GNUNET_DISK_FileHandle *pr; 1587 const struct GNUNET_DISK_FileHandle *pr;
1586 1588
1587 (void) cls; 1589 (void)cls;
1588 pr = GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ); 1590 pr = GNUNET_DISK_pipe_handle(sigpipe, GNUNET_DISK_PIPE_END_READ);
1589 child_death_task = NULL; 1591 child_death_task = NULL;
1590 /* consume the signal */ 1592 /* consume the signal */
1591 GNUNET_break (0 < GNUNET_DISK_file_read (pr, &c, sizeof (c))); 1593 GNUNET_break(0 < GNUNET_DISK_file_read(pr, &c, sizeof(c)));
1592 1594
1593 /* check for services that died (WAITPID) */ 1595 /* check for services that died (WAITPID) */
1594 next = running_head; 1596 next = running_head;
1595 while (NULL != (pos = next)) 1597 while (NULL != (pos = next))
1596 {
1597 next = pos->next;
1598
1599 if (NULL == pos->proc)
1600 { 1598 {
1601 if (GNUNET_YES == in_shutdown) 1599 next = pos->next;
1602 free_service (pos); 1600
1603 continue; 1601 if (NULL == pos->proc)
1604 } 1602 {
1603 if (GNUNET_YES == in_shutdown)
1604 free_service(pos);
1605 continue;
1606 }
1605#if HAVE_WAIT4 1607#if HAVE_WAIT4
1606 if (NULL != wait_file) 1608 if (NULL != wait_file)
1607 { 1609 {
1608 /* need to use 'wait4()' to obtain and log performance data */ 1610 /* need to use 'wait4()' to obtain and log performance data */
1609 struct rusage ru; 1611 struct rusage ru;
1610 int status; 1612 int status;
1611 pid_t pid; 1613 pid_t pid;
1612 1614
1613 pid = GNUNET_OS_process_get_pid (pos->proc); 1615 pid = GNUNET_OS_process_get_pid(pos->proc);
1614 ret = wait4 (pid, &status, WNOHANG, &ru); 1616 ret = wait4(pid, &status, WNOHANG, &ru);
1615 if (ret <= 0) 1617 if (ret <= 0)
1616 continue; /* no process done */ 1618 continue; /* no process done */
1617 if (WIFEXITED (status)) 1619 if (WIFEXITED(status))
1618 { 1620 {
1619 statusType = GNUNET_OS_PROCESS_EXITED; 1621 statusType = GNUNET_OS_PROCESS_EXITED;
1620 statusCode = WEXITSTATUS (status); 1622 statusCode = WEXITSTATUS(status);
1621 } 1623 }
1622 else if (WIFSIGNALED (status)) 1624 else if (WIFSIGNALED(status))
1623 { 1625 {
1624 statusType = GNUNET_OS_PROCESS_SIGNALED; 1626 statusType = GNUNET_OS_PROCESS_SIGNALED;
1625 statusCode = WTERMSIG (status); 1627 statusCode = WTERMSIG(status);
1626 } 1628 }
1627 else if (WIFSTOPPED (status)) 1629 else if (WIFSTOPPED(status))
1628 { 1630 {
1629 statusType = GNUNET_OS_PROCESS_SIGNALED; 1631 statusType = GNUNET_OS_PROCESS_SIGNALED;
1630 statusCode = WSTOPSIG (status); 1632 statusCode = WSTOPSIG(status);
1631 } 1633 }
1632#ifdef WIFCONTINUED 1634#ifdef WIFCONTINUED
1633 else if (WIFCONTINUED (status)) 1635 else if (WIFCONTINUED(status))
1634 { 1636 {
1635 statusType = GNUNET_OS_PROCESS_RUNNING; 1637 statusType = GNUNET_OS_PROCESS_RUNNING;
1636 statusCode = 0; 1638 statusCode = 0;
1637 } 1639 }
1638#endif 1640#endif
1639 else 1641 else
1640 { 1642 {
1641 statusType = GNUNET_OS_PROCESS_UNKNOWN; 1643 statusType = GNUNET_OS_PROCESS_UNKNOWN;
1642 statusCode = 0; 1644 statusCode = 0;
1643 } 1645 }
1644 if ((GNUNET_OS_PROCESS_EXITED == statusType) || 1646 if ((GNUNET_OS_PROCESS_EXITED == statusType) ||
1645 (GNUNET_OS_PROCESS_SIGNALED == statusType)) 1647 (GNUNET_OS_PROCESS_SIGNALED == statusType))
1646 { 1648 {
1647 double utime = ru.ru_utime.tv_sec + (ru.ru_utime.tv_usec / 10e6); 1649 double utime = ru.ru_utime.tv_sec + (ru.ru_utime.tv_usec / 10e6);
1648 double stime = ru.ru_stime.tv_sec + (ru.ru_stime.tv_usec / 10e6); 1650 double stime = ru.ru_stime.tv_sec + (ru.ru_stime.tv_usec / 10e6);
1649 fprintf (wait_file, 1651 fprintf(wait_file,
1650 "%s(%u) %.3f %.3f %llu %llu %llu %llu %llu\n", 1652 "%s(%u) %.3f %.3f %llu %llu %llu %llu %llu\n",
1651 pos->binary, 1653 pos->binary,
1652 (unsigned int) pid, 1654 (unsigned int)pid,
1653 utime, 1655 utime,
1654 stime, 1656 stime,
1655 (unsigned long long) ru.ru_maxrss, 1657 (unsigned long long)ru.ru_maxrss,
1656 (unsigned long long) ru.ru_inblock, 1658 (unsigned long long)ru.ru_inblock,
1657 (unsigned long long) ru.ru_oublock, 1659 (unsigned long long)ru.ru_oublock,
1658 (unsigned long long) ru.ru_nvcsw, 1660 (unsigned long long)ru.ru_nvcsw,
1659 (unsigned long long) ru.ru_nivcsw); 1661 (unsigned long long)ru.ru_nivcsw);
1660 } 1662 }
1661 } 1663 }
1662 else /* continue with JUST this "if" as "else" (intentionally no brackets!) */ 1664 else /* continue with JUST this "if" as "else" (intentionally no brackets!) */
1663#endif 1665#endif
1664 if ((GNUNET_SYSERR == (ret = GNUNET_OS_process_status (pos->proc, 1666 if ((GNUNET_SYSERR == (ret = GNUNET_OS_process_status(pos->proc,
1665 &statusType, 1667 &statusType,
1666 &statusCode))) || 1668 &statusCode))) ||
1667 (ret == GNUNET_NO) || (statusType == GNUNET_OS_PROCESS_STOPPED) || 1669 (ret == GNUNET_NO) || (statusType == GNUNET_OS_PROCESS_STOPPED) ||
1668 (statusType == GNUNET_OS_PROCESS_UNKNOWN) || 1670 (statusType == GNUNET_OS_PROCESS_UNKNOWN) ||
1669 (statusType == GNUNET_OS_PROCESS_RUNNING)) 1671 (statusType == GNUNET_OS_PROCESS_RUNNING))
1670 continue; 1672 continue;
1671 1673
1672 if (statusType == GNUNET_OS_PROCESS_EXITED) 1674 if (statusType == GNUNET_OS_PROCESS_EXITED)
1673 {
1674 statstr = _ (/* process termination method */ "exit");
1675 statcode = statusCode;
1676 }
1677 else if (statusType == GNUNET_OS_PROCESS_SIGNALED)
1678 {
1679 statstr = _ (/* process termination method */ "signal");
1680 statcode = statusCode;
1681 }
1682 else
1683 {
1684 statstr = _ (/* process termination method */ "unknown");
1685 statcode = 0;
1686 }
1687 if (0 != pos->killed_at.abs_value_us)
1688 {
1689 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1690 _ ("Service `%s' took %s to terminate\n"),
1691 pos->name,
1692 GNUNET_STRINGS_relative_time_to_string (
1693 GNUNET_TIME_absolute_get_duration (pos->killed_at),
1694 GNUNET_YES));
1695 }
1696 GNUNET_OS_process_destroy (pos->proc);
1697 pos->proc = NULL;
1698 broadcast_status (pos->name, GNUNET_ARM_SERVICE_STOPPED, NULL);
1699 if (NULL != pos->killing_client)
1700 {
1701 signal_result (pos->killing_client,
1702 pos->name,
1703 pos->killing_client_request_id,
1704 GNUNET_ARM_RESULT_STOPPED);
1705 pos->killing_client = NULL;
1706 pos->killing_client_request_id = 0;
1707 }
1708 if (GNUNET_YES != in_shutdown)
1709 {
1710 if ((statusType == GNUNET_OS_PROCESS_EXITED) && (statcode == 0))
1711 {
1712 /* process terminated normally, allow restart at any time */
1713 pos->restart_at.abs_value_us = 0;
1714 GNUNET_log (
1715 GNUNET_ERROR_TYPE_INFO,
1716 _ ("Service `%s' terminated normally, will restart at any time\n"),
1717 pos->name);
1718 /* process can still be re-started on-demand, ensure it is re-started if there is demand */
1719 for (sli = pos->listen_head; NULL != sli; sli = sli->next)
1720 { 1675 {
1721 GNUNET_break (NULL == sli->accept_task); 1676 statstr = _(/* process termination method */ "exit");
1722 sli->accept_task = 1677 statcode = statusCode;
1723 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 1678 }
1724 sli->listen_socket, 1679 else if (statusType == GNUNET_OS_PROCESS_SIGNALED)
1725 &accept_connection, 1680 {
1726 sli); 1681 statstr = _(/* process termination method */ "signal");
1682 statcode = statusCode;
1727 } 1683 }
1728 }
1729 else 1684 else
1730 {
1731 GNUNET_log (
1732 GNUNET_ERROR_TYPE_INFO,
1733 _ ("Service `%s' terminated with status %s/%d, will restart in %s\n"),
1734 pos->name,
1735 statstr,
1736 statcode,
1737 GNUNET_STRINGS_relative_time_to_string (pos->backoff, GNUNET_YES));
1738 { 1685 {
1739 /* Reduce backoff based on runtime of the process, 1686 statstr = _(/* process termination method */ "unknown");
1740 so that there is a cool-down if a process actually 1687 statcode = 0;
1741 runs for a while. */ 1688 }
1742 struct GNUNET_TIME_Relative runtime; 1689 if (0 != pos->killed_at.abs_value_us)
1743 unsigned int minutes; 1690 {
1744 1691 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1745 runtime = GNUNET_TIME_absolute_get_duration (pos->restart_at); 1692 _("Service `%s' took %s to terminate\n"),
1746 minutes = 1693 pos->name,
1747 runtime.rel_value_us / GNUNET_TIME_UNIT_MINUTES.rel_value_us; 1694 GNUNET_STRINGS_relative_time_to_string(
1748 if (minutes > 31) 1695 GNUNET_TIME_absolute_get_duration(pos->killed_at),
1749 pos->backoff = GNUNET_TIME_UNIT_ZERO; 1696 GNUNET_YES));
1697 }
1698 GNUNET_OS_process_destroy(pos->proc);
1699 pos->proc = NULL;
1700 broadcast_status(pos->name, GNUNET_ARM_SERVICE_STOPPED, NULL);
1701 if (NULL != pos->killing_client)
1702 {
1703 signal_result(pos->killing_client,
1704 pos->name,
1705 pos->killing_client_request_id,
1706 GNUNET_ARM_RESULT_STOPPED);
1707 pos->killing_client = NULL;
1708 pos->killing_client_request_id = 0;
1709 }
1710 if (GNUNET_YES != in_shutdown)
1711 {
1712 if ((statusType == GNUNET_OS_PROCESS_EXITED) && (statcode == 0))
1713 {
1714 /* process terminated normally, allow restart at any time */
1715 pos->restart_at.abs_value_us = 0;
1716 GNUNET_log(
1717 GNUNET_ERROR_TYPE_INFO,
1718 _("Service `%s' terminated normally, will restart at any time\n"),
1719 pos->name);
1720 /* process can still be re-started on-demand, ensure it is re-started if there is demand */
1721 for (sli = pos->listen_head; NULL != sli; sli = sli->next)
1722 {
1723 GNUNET_break(NULL == sli->accept_task);
1724 sli->accept_task =
1725 GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL,
1726 sli->listen_socket,
1727 &accept_connection,
1728 sli);
1729 }
1730 }
1750 else 1731 else
1751 pos->backoff.rel_value_us <<= minutes; 1732 {
1733 GNUNET_log(
1734 GNUNET_ERROR_TYPE_INFO,
1735 _("Service `%s' terminated with status %s/%d, will restart in %s\n"),
1736 pos->name,
1737 statstr,
1738 statcode,
1739 GNUNET_STRINGS_relative_time_to_string(pos->backoff, GNUNET_YES));
1740 {
1741 /* Reduce backoff based on runtime of the process,
1742 so that there is a cool-down if a process actually
1743 runs for a while. */
1744 struct GNUNET_TIME_Relative runtime;
1745 unsigned int minutes;
1746
1747 runtime = GNUNET_TIME_absolute_get_duration(pos->restart_at);
1748 minutes =
1749 runtime.rel_value_us / GNUNET_TIME_UNIT_MINUTES.rel_value_us;
1750 if (minutes > 31)
1751 pos->backoff = GNUNET_TIME_UNIT_ZERO;
1752 else
1753 pos->backoff.rel_value_us <<= minutes;
1754 }
1755 /* schedule restart */
1756 pos->restart_at = GNUNET_TIME_relative_to_absolute(pos->backoff);
1757 pos->backoff = GNUNET_TIME_STD_BACKOFF(pos->backoff);
1758 if (NULL != child_restart_task)
1759 GNUNET_SCHEDULER_cancel(child_restart_task);
1760 child_restart_task =
1761 GNUNET_SCHEDULER_add_with_priority(GNUNET_SCHEDULER_PRIORITY_IDLE,
1762 &delayed_restart_task,
1763 NULL);
1764 }
1765 }
1766 else
1767 {
1768 free_service(pos);
1752 } 1769 }
1753 /* schedule restart */
1754 pos->restart_at = GNUNET_TIME_relative_to_absolute (pos->backoff);
1755 pos->backoff = GNUNET_TIME_STD_BACKOFF (pos->backoff);
1756 if (NULL != child_restart_task)
1757 GNUNET_SCHEDULER_cancel (child_restart_task);
1758 child_restart_task =
1759 GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE,
1760 &delayed_restart_task,
1761 NULL);
1762 }
1763 }
1764 else
1765 {
1766 free_service (pos);
1767 } 1770 }
1768 }
1769 child_death_task = 1771 child_death_task =
1770 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 1772 GNUNET_SCHEDULER_add_read_file(GNUNET_TIME_UNIT_FOREVER_REL,
1771 pr, 1773 pr,
1772 &maint_child_death, 1774 &maint_child_death,
1773 NULL); 1775 NULL);
1774 if ((NULL == running_head) && (GNUNET_YES == in_shutdown)) 1776 if ((NULL == running_head) && (GNUNET_YES == in_shutdown))
1775 do_shutdown (); 1777 do_shutdown();
1776 else if (GNUNET_YES == in_shutdown) 1778 else if (GNUNET_YES == in_shutdown)
1777 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1779 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1778 "Delaying shutdown after child's death, still have %u children\n", 1780 "Delaying shutdown after child's death, still have %u children\n",
1779 list_count (running_head)); 1781 list_count(running_head));
1780} 1782}
1781 1783
1782 1784
@@ -1785,17 +1787,17 @@ maint_child_death (void *cls)
1785 * respective handler by writing to the trigger pipe. 1787 * respective handler by writing to the trigger pipe.
1786 */ 1788 */
1787static void 1789static void
1788sighandler_child_death () 1790sighandler_child_death()
1789{ 1791{
1790 static char c; 1792 static char c;
1791 int old_errno = errno; /* back-up errno */ 1793 int old_errno = errno; /* back-up errno */
1792 1794
1793 GNUNET_break ( 1795 GNUNET_break(
1794 1 == 1796 1 ==
1795 GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle (sigpipe, 1797 GNUNET_DISK_file_write(GNUNET_DISK_pipe_handle(sigpipe,
1796 GNUNET_DISK_PIPE_END_WRITE), 1798 GNUNET_DISK_PIPE_END_WRITE),
1797 &c, 1799 &c,
1798 sizeof (c))); 1800 sizeof(c)));
1799 errno = old_errno; /* restore errno */ 1801 errno = old_errno; /* restore errno */
1800} 1802}
1801 1803
@@ -1809,7 +1811,7 @@ sighandler_child_death ()
1809 * @return #GNUNET_OK (continue) 1811 * @return #GNUNET_OK (continue)
1810 */ 1812 */
1811static void 1813static void
1812setup_service (void *cls, const char *section) 1814setup_service(void *cls, const char *section)
1813{ 1815{
1814 struct ServiceList *sl; 1816 struct ServiceList *sl;
1815 char *binary; 1817 char *binary;
@@ -1819,65 +1821,65 @@ setup_service (void *cls, const char *section)
1819 socklen_t *addr_lens; 1821 socklen_t *addr_lens;
1820 int ret; 1822 int ret;
1821 1823
1822 (void) cls; 1824 (void)cls;
1823 if (0 == strcasecmp (section, "arm")) 1825 if (0 == strcasecmp(section, "arm"))
1824 return; 1826 return;
1825 if (GNUNET_OK != 1827 if (GNUNET_OK !=
1826 GNUNET_CONFIGURATION_get_value_string (cfg, section, "BINARY", &binary)) 1828 GNUNET_CONFIGURATION_get_value_string(cfg, section, "BINARY", &binary))
1827 { 1829 {
1828 /* not a service section */ 1830 /* not a service section */
1829 return; 1831 return;
1830 } 1832 }
1831 if ((GNUNET_YES == 1833 if ((GNUNET_YES ==
1832 GNUNET_CONFIGURATION_have_value (cfg, section, "RUN_PER_USER")) && 1834 GNUNET_CONFIGURATION_have_value(cfg, section, "RUN_PER_USER")) &&
1833 (GNUNET_YES == 1835 (GNUNET_YES ==
1834 GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "RUN_PER_USER"))) 1836 GNUNET_CONFIGURATION_get_value_yesno(cfg, section, "RUN_PER_USER")))
1835 {
1836 if (GNUNET_NO == start_user)
1837 { 1837 {
1838 GNUNET_free (binary); 1838 if (GNUNET_NO == start_user)
1839 return; /* user service, and we don't deal with those */ 1839 {
1840 GNUNET_free(binary);
1841 return; /* user service, and we don't deal with those */
1842 }
1840 } 1843 }
1841 }
1842 else 1844 else
1843 {
1844 if (GNUNET_NO == start_system)
1845 { 1845 {
1846 GNUNET_free (binary); 1846 if (GNUNET_NO == start_system)
1847 return; /* system service, and we don't deal with those */ 1847 {
1848 GNUNET_free(binary);
1849 return; /* system service, and we don't deal with those */
1850 }
1848 } 1851 }
1849 } 1852 sl = find_service(section);
1850 sl = find_service (section);
1851 if (NULL != sl) 1853 if (NULL != sl)
1852 { 1854 {
1853 /* got the same section twice!? */ 1855 /* got the same section twice!? */
1854 GNUNET_break (0); 1856 GNUNET_break(0);
1855 GNUNET_free (binary); 1857 GNUNET_free(binary);
1856 return; 1858 return;
1857 } 1859 }
1858 config = NULL; 1860 config = NULL;
1859 if (((GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, 1861 if (((GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename(cfg,
1860 section, 1862 section,
1861 "CONFIG", 1863 "CONFIG",
1862 &config)) && 1864 &config)) &&
1863 (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, 1865 (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename(cfg,
1864 "PATHS", 1866 "PATHS",
1865 "DEFAULTCONFIG", 1867 "DEFAULTCONFIG",
1866 &config))) || 1868 &config))) ||
1867 (0 != stat (config, &sbuf))) 1869 (0 != stat(config, &sbuf)))
1868 {
1869 if (NULL != config)
1870 { 1870 {
1871 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING, 1871 if (NULL != config)
1872 section, 1872 {
1873 "CONFIG", 1873 GNUNET_log_config_invalid(GNUNET_ERROR_TYPE_WARNING,
1874 strerror (errno)); 1874 section,
1875 GNUNET_free (config); 1875 "CONFIG",
1876 config = NULL; 1876 strerror(errno));
1877 GNUNET_free(config);
1878 config = NULL;
1879 }
1877 } 1880 }
1878 } 1881 sl = GNUNET_new(struct ServiceList);
1879 sl = GNUNET_new (struct ServiceList); 1882 sl->name = GNUNET_strdup(section);
1880 sl->name = GNUNET_strdup (section);
1881 sl->binary = binary; 1883 sl->binary = binary;
1882 sl->config = config; 1884 sl->config = config;
1883 sl->backoff = GNUNET_TIME_UNIT_MILLISECONDS; 1885 sl->backoff = GNUNET_TIME_UNIT_MILLISECONDS;
@@ -1885,32 +1887,32 @@ setup_service (void *cls, const char *section)
1885#if WINDOWS 1887#if WINDOWS
1886 sl->pipe_control = GNUNET_YES; 1888 sl->pipe_control = GNUNET_YES;
1887#else 1889#else
1888 if (GNUNET_CONFIGURATION_have_value (cfg, section, "PIPECONTROL")) 1890 if (GNUNET_CONFIGURATION_have_value(cfg, section, "PIPECONTROL"))
1889 sl->pipe_control = 1891 sl->pipe_control =
1890 GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "PIPECONTROL"); 1892 GNUNET_CONFIGURATION_get_value_yesno(cfg, section, "PIPECONTROL");
1891#endif 1893#endif
1892 GNUNET_CONTAINER_DLL_insert (running_head, running_tail, sl); 1894 GNUNET_CONTAINER_DLL_insert(running_head, running_tail, sl);
1893 if (GNUNET_YES == 1895 if (GNUNET_YES ==
1894 GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "IMMEDIATE_START")) 1896 GNUNET_CONFIGURATION_get_value_yesno(cfg, section, "IMMEDIATE_START"))
1895 { 1897 {
1896 sl->force_start = GNUNET_YES; 1898 sl->force_start = GNUNET_YES;
1897 if (GNUNET_YES == 1899 if (GNUNET_YES ==
1898 GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "NOARMBIND")) 1900 GNUNET_CONFIGURATION_get_value_yesno(cfg, section, "NOARMBIND"))
1899 return; 1901 return;
1900 } 1902 }
1901 else 1903 else
1902 { 1904 {
1903 if (GNUNET_YES != 1905 if (GNUNET_YES !=
1904 GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "START_ON_DEMAND")) 1906 GNUNET_CONFIGURATION_get_value_yesno(cfg, section, "START_ON_DEMAND"))
1905 return; 1907 return;
1906 } 1908 }
1907 if (0 >= (ret = get_server_addresses (section, cfg, &addrs, &addr_lens))) 1909 if (0 >= (ret = get_server_addresses(section, cfg, &addrs, &addr_lens)))
1908 return; 1910 return;
1909 /* this will free (or capture) addrs[i] */ 1911 /* this will free (or capture) addrs[i] */
1910 for (unsigned int i = 0; i < (unsigned int) ret; i++) 1912 for (unsigned int i = 0; i < (unsigned int)ret; i++)
1911 create_listen_socket (addrs[i], addr_lens[i], sl); 1913 create_listen_socket(addrs[i], addr_lens[i], sl);
1912 GNUNET_free (addrs); 1914 GNUNET_free(addrs);
1913 GNUNET_free (addr_lens); 1915 GNUNET_free(addr_lens);
1914} 1916}
1915 1917
1916 1918
@@ -1923,16 +1925,16 @@ setup_service (void *cls, const char *section)
1923 * @return @a client 1925 * @return @a client
1924 */ 1926 */
1925static void * 1927static void *
1926client_connect_cb (void *cls, 1928client_connect_cb(void *cls,
1927 struct GNUNET_SERVICE_Client *client, 1929 struct GNUNET_SERVICE_Client *client,
1928 struct GNUNET_MQ_Handle *mq) 1930 struct GNUNET_MQ_Handle *mq)
1929{ 1931{
1930 /* All clients are considered to be of the "monitor" kind 1932 /* All clients are considered to be of the "monitor" kind
1931 * (that is, they don't affect ARM shutdown). 1933 * (that is, they don't affect ARM shutdown).
1932 */ 1934 */
1933 (void) cls; 1935 (void)cls;
1934 (void) mq; 1936 (void)mq;
1935 GNUNET_SERVICE_client_mark_monitor (client); 1937 GNUNET_SERVICE_client_mark_monitor(client);
1936 return client; 1938 return client;
1937} 1939}
1938 1940
@@ -1945,12 +1947,12 @@ client_connect_cb (void *cls,
1945 * @param app_ctx must match @a client 1947 * @param app_ctx must match @a client
1946 */ 1948 */
1947static void 1949static void
1948client_disconnect_cb (void *cls, 1950client_disconnect_cb(void *cls,
1949 struct GNUNET_SERVICE_Client *client, 1951 struct GNUNET_SERVICE_Client *client,
1950 void *app_ctx) 1952 void *app_ctx)
1951{ 1953{
1952 (void) cls; 1954 (void)cls;
1953 GNUNET_assert (client == app_ctx); 1955 GNUNET_assert(client == app_ctx);
1954 for (struct ServiceList *sl = running_head; NULL != sl; sl = sl->next) 1956 for (struct ServiceList *sl = running_head; NULL != sl; sl = sl->next)
1955 if (sl->killing_client == client) 1957 if (sl->killing_client == client)
1956 sl->killing_client = NULL; 1958 sl->killing_client = NULL;
@@ -1966,18 +1968,18 @@ client_disconnect_cb (void *cls,
1966 * #GNUNET_SYSERR to close it (signal serious error) 1968 * #GNUNET_SYSERR to close it (signal serious error)
1967 */ 1969 */
1968static void 1970static void
1969handle_monitor (void *cls, const struct GNUNET_MessageHeader *message) 1971handle_monitor(void *cls, const struct GNUNET_MessageHeader *message)
1970{ 1972{
1971 struct GNUNET_SERVICE_Client *client = cls; 1973 struct GNUNET_SERVICE_Client *client = cls;
1972 1974
1973 (void) message; 1975 (void)message;
1974 /* FIXME: might want to start by letting monitor know about 1976 /* FIXME: might want to start by letting monitor know about
1975 services that are already running */ 1977 services that are already running */
1976 /* Removal is handled by the server implementation, internally. */ 1978 /* Removal is handled by the server implementation, internally. */
1977 GNUNET_notification_context_add (notifier, 1979 GNUNET_notification_context_add(notifier,
1978 GNUNET_SERVICE_client_get_mq (client)); 1980 GNUNET_SERVICE_client_get_mq(client));
1979 broadcast_status ("arm", GNUNET_ARM_SERVICE_MONITORING_STARTED, client); 1981 broadcast_status("arm", GNUNET_ARM_SERVICE_MONITORING_STARTED, client);
1980 GNUNET_SERVICE_client_continue (client); 1982 GNUNET_SERVICE_client_continue(client);
1981} 1983}
1982 1984
1983 1985
@@ -1989,71 +1991,71 @@ handle_monitor (void *cls, const struct GNUNET_MessageHeader *message)
1989 * @param c configuration to use 1991 * @param c configuration to use
1990 */ 1992 */
1991static void 1993static void
1992run (void *cls, 1994run(void *cls,
1993 const struct GNUNET_CONFIGURATION_Handle *c, 1995 const struct GNUNET_CONFIGURATION_Handle *c,
1994 struct GNUNET_SERVICE_Handle *serv) 1996 struct GNUNET_SERVICE_Handle *serv)
1995{ 1997{
1996 struct ServiceList *sl; 1998 struct ServiceList *sl;
1997 1999
1998 (void) cls; 2000 (void)cls;
1999 cfg = c; 2001 cfg = c;
2000 service = serv; 2002 service = serv;
2001 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); 2003 GNUNET_SCHEDULER_add_shutdown(&shutdown_task, NULL);
2002 child_death_task = GNUNET_SCHEDULER_add_read_file ( 2004 child_death_task = GNUNET_SCHEDULER_add_read_file(
2003 GNUNET_TIME_UNIT_FOREVER_REL, 2005 GNUNET_TIME_UNIT_FOREVER_REL,
2004 GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ), 2006 GNUNET_DISK_pipe_handle(sigpipe, GNUNET_DISK_PIPE_END_READ),
2005 &maint_child_death, 2007 &maint_child_death,
2006 NULL); 2008 NULL);
2007#if HAVE_WAIT4 2009#if HAVE_WAIT4
2008 if (GNUNET_OK == 2010 if (GNUNET_OK ==
2009 GNUNET_CONFIGURATION_get_value_filename (cfg, 2011 GNUNET_CONFIGURATION_get_value_filename(cfg,
2010 "ARM", 2012 "ARM",
2011 "RESOURCE_DIAGNOSTICS", 2013 "RESOURCE_DIAGNOSTICS",
2012 &wait_filename)) 2014 &wait_filename))
2013 {
2014 wait_file = fopen (wait_filename, "w");
2015 if (NULL == wait_file)
2016 { 2015 {
2017 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, 2016 wait_file = fopen(wait_filename, "w");
2018 "fopen", 2017 if (NULL == wait_file)
2019 wait_filename); 2018 {
2019 GNUNET_log_strerror_file(GNUNET_ERROR_TYPE_ERROR,
2020 "fopen",
2021 wait_filename);
2022 }
2020 } 2023 }
2021 }
2022#endif 2024#endif
2023 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, 2025 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg,
2024 "ARM", 2026 "ARM",
2025 "GLOBAL_PREFIX", 2027 "GLOBAL_PREFIX",
2026 &prefix_command)) 2028 &prefix_command))
2027 prefix_command = GNUNET_strdup (""); 2029 prefix_command = GNUNET_strdup("");
2028 else 2030 else
2029 prefix_command = GNUNET_CONFIGURATION_expand_dollar (cfg, prefix_command); 2031 prefix_command = GNUNET_CONFIGURATION_expand_dollar(cfg, prefix_command);
2030 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, 2032 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg,
2031 "ARM", 2033 "ARM",
2032 "GLOBAL_POSTFIX", 2034 "GLOBAL_POSTFIX",
2033 &final_option)) 2035 &final_option))
2034 final_option = GNUNET_strdup (""); 2036 final_option = GNUNET_strdup("");
2035 else 2037 else
2036 final_option = GNUNET_CONFIGURATION_expand_dollar (cfg, final_option); 2038 final_option = GNUNET_CONFIGURATION_expand_dollar(cfg, final_option);
2037 start_user = 2039 start_user =
2038 GNUNET_CONFIGURATION_get_value_yesno (cfg, "ARM", "START_USER_SERVICES"); 2040 GNUNET_CONFIGURATION_get_value_yesno(cfg, "ARM", "START_USER_SERVICES");
2039 start_system = 2041 start_system =
2040 GNUNET_CONFIGURATION_get_value_yesno (cfg, "ARM", "START_SYSTEM_SERVICES"); 2042 GNUNET_CONFIGURATION_get_value_yesno(cfg, "ARM", "START_SYSTEM_SERVICES");
2041 if ((GNUNET_NO == start_user) && (GNUNET_NO == start_system)) 2043 if ((GNUNET_NO == start_user) && (GNUNET_NO == start_system))
2042 { 2044 {
2043 GNUNET_log ( 2045 GNUNET_log(
2044 GNUNET_ERROR_TYPE_ERROR, 2046 GNUNET_ERROR_TYPE_ERROR,
2045 "Please configure either START_USER_SERVICES or START_SYSTEM_SERVICES or both.\n"); 2047 "Please configure either START_USER_SERVICES or START_SYSTEM_SERVICES or both.\n");
2046 GNUNET_SCHEDULER_shutdown (); 2048 GNUNET_SCHEDULER_shutdown();
2047 global_ret = 1; 2049 global_ret = 1;
2048 return; 2050 return;
2049 } 2051 }
2050 GNUNET_CONFIGURATION_iterate_sections (cfg, &setup_service, NULL); 2052 GNUNET_CONFIGURATION_iterate_sections(cfg, &setup_service, NULL);
2051 2053
2052 /* start default services... */ 2054 /* start default services... */
2053 for (sl = running_head; NULL != sl; sl = sl->next) 2055 for (sl = running_head; NULL != sl; sl = sl->next)
2054 if (GNUNET_YES == sl->force_start) 2056 if (GNUNET_YES == sl->force_start)
2055 start_process (sl, NULL, 0); 2057 start_process(sl, NULL, 0);
2056 notifier = GNUNET_notification_context_create (MAX_NOTIFY_QUEUE); 2058 notifier = GNUNET_notification_context_create(MAX_NOTIFY_QUEUE);
2057} 2059}
2058 2060
2059 2061
@@ -2065,61 +2067,61 @@ run (void *cls,
2065 * @return 0 ok, 1 on error 2067 * @return 0 ok, 1 on error
2066 */ 2068 */
2067int 2069int
2068main (int argc, char *const *argv) 2070main(int argc, char *const *argv)
2069{ 2071{
2070 struct GNUNET_SIGNAL_Context *shc_chld; 2072 struct GNUNET_SIGNAL_Context *shc_chld;
2071 struct GNUNET_MQ_MessageHandler handlers[] = 2073 struct GNUNET_MQ_MessageHandler handlers[] =
2072 {GNUNET_MQ_hd_var_size (start, 2074 { GNUNET_MQ_hd_var_size(start,
2073 GNUNET_MESSAGE_TYPE_ARM_START, 2075 GNUNET_MESSAGE_TYPE_ARM_START,
2074 struct GNUNET_ARM_Message, 2076 struct GNUNET_ARM_Message,
2077 NULL),
2078 GNUNET_MQ_hd_var_size(stop,
2079 GNUNET_MESSAGE_TYPE_ARM_STOP,
2080 struct GNUNET_ARM_Message,
2081 NULL),
2082 GNUNET_MQ_hd_fixed_size(monitor,
2083 GNUNET_MESSAGE_TYPE_ARM_MONITOR,
2084 struct GNUNET_MessageHeader,
2075 NULL), 2085 NULL),
2076 GNUNET_MQ_hd_var_size (stop, 2086 GNUNET_MQ_hd_fixed_size(list,
2077 GNUNET_MESSAGE_TYPE_ARM_STOP, 2087 GNUNET_MESSAGE_TYPE_ARM_LIST,
2078 struct GNUNET_ARM_Message, 2088 struct GNUNET_ARM_Message,
2079 NULL), 2089 NULL),
2080 GNUNET_MQ_hd_fixed_size (monitor, 2090 GNUNET_MQ_hd_fixed_size(test,
2081 GNUNET_MESSAGE_TYPE_ARM_MONITOR, 2091 GNUNET_MESSAGE_TYPE_ARM_TEST,
2082 struct GNUNET_MessageHeader, 2092 struct GNUNET_MessageHeader,
2083 NULL), 2093 NULL),
2084 GNUNET_MQ_hd_fixed_size (list, 2094 GNUNET_MQ_handler_end() };
2085 GNUNET_MESSAGE_TYPE_ARM_LIST, 2095
2086 struct GNUNET_ARM_Message, 2096 sigpipe = GNUNET_DISK_pipe(GNUNET_NO, GNUNET_NO, GNUNET_NO, GNUNET_NO);
2087 NULL), 2097 GNUNET_assert(NULL != sigpipe);
2088 GNUNET_MQ_hd_fixed_size (test,
2089 GNUNET_MESSAGE_TYPE_ARM_TEST,
2090 struct GNUNET_MessageHeader,
2091 NULL),
2092 GNUNET_MQ_handler_end ()};
2093
2094 sigpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO, GNUNET_NO);
2095 GNUNET_assert (NULL != sigpipe);
2096 shc_chld = 2098 shc_chld =
2097 GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, &sighandler_child_death); 2099 GNUNET_SIGNAL_handler_install(GNUNET_SIGCHLD, &sighandler_child_death);
2098 if (0 != GNUNET_SERVICE_run_ (argc, 2100 if (0 != GNUNET_SERVICE_run_(argc,
2099 argv, 2101 argv,
2100 "arm", 2102 "arm",
2101 GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN, 2103 GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN,
2102 &run, 2104 &run,
2103 &client_connect_cb, 2105 &client_connect_cb,
2104 &client_disconnect_cb, 2106 &client_disconnect_cb,
2105 NULL, 2107 NULL,
2106 handlers)) 2108 handlers))
2107 global_ret = 2; 2109 global_ret = 2;
2108#if HAVE_WAIT4 2110#if HAVE_WAIT4
2109 if (NULL != wait_file) 2111 if (NULL != wait_file)
2110 { 2112 {
2111 fclose (wait_file); 2113 fclose(wait_file);
2112 wait_file = NULL; 2114 wait_file = NULL;
2113 } 2115 }
2114 if (NULL != wait_filename) 2116 if (NULL != wait_filename)
2115 { 2117 {
2116 GNUNET_free (wait_filename); 2118 GNUNET_free(wait_filename);
2117 wait_filename = NULL; 2119 wait_filename = NULL;
2118 } 2120 }
2119#endif 2121#endif
2120 GNUNET_SIGNAL_handler_uninstall (shc_chld); 2122 GNUNET_SIGNAL_handler_uninstall(shc_chld);
2121 shc_chld = NULL; 2123 shc_chld = NULL;
2122 GNUNET_DISK_pipe_close (sigpipe); 2124 GNUNET_DISK_pipe_close(sigpipe);
2123 sigpipe = NULL; 2125 sigpipe = NULL;
2124 return global_ret; 2126 return global_ret;
2125} 2127}
@@ -2131,11 +2133,11 @@ main (int argc, char *const *argv)
2131/** 2133/**
2132 * MINIMIZE heap size (way below 128k) since this process doesn't need much. 2134 * MINIMIZE heap size (way below 128k) since this process doesn't need much.
2133 */ 2135 */
2134void __attribute__ ((constructor)) GNUNET_ARM_memory_init () 2136void __attribute__ ((constructor)) GNUNET_ARM_memory_init()
2135{ 2137{
2136 mallopt (M_TRIM_THRESHOLD, 4 * 1024); 2138 mallopt(M_TRIM_THRESHOLD, 4 * 1024);
2137 mallopt (M_TOP_PAD, 1 * 1024); 2139 mallopt(M_TOP_PAD, 1 * 1024);
2138 malloc_trim (0); 2140 malloc_trim(0);
2139} 2141}
2140#endif 2142#endif
2141 2143