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