summaryrefslogtreecommitdiff
path: root/src/arm/gnunet-service-arm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/arm/gnunet-service-arm.c')
-rw-r--r--src/arm/gnunet-service-arm.c1071
1 files changed, 443 insertions, 628 deletions
diff --git a/src/arm/gnunet-service-arm.c b/src/arm/gnunet-service-arm.c
index 4b7cbec20..a05257563 100644
--- a/src/arm/gnunet-service-arm.c
+++ b/src/arm/gnunet-service-arm.c
@@ -29,9 +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) GNUNET_log_from_strerror (kind, "util", syscall) 34#define LOG_strerror(kind, syscall) \
35 GNUNET_log_from_strerror (kind, "util", syscall)
35 36
36 37
37#if HAVE_WAIT4 38#if HAVE_WAIT4
@@ -100,7 +101,6 @@ struct ServiceListeningInfo
100 * Task doing the accepting. 101 * Task doing the accepting.
101 */ 102 */
102 struct GNUNET_SCHEDULER_Task *accept_task; 103 struct GNUNET_SCHEDULER_Task *accept_task;
103
104}; 104};
105 105
106 106
@@ -330,9 +330,9 @@ add_unixpath (struct sockaddr **saddrs,
330 */ 330 */
331static int 331static int
332get_server_addresses (const char *service_name, 332get_server_addresses (const char *service_name,
333 const struct GNUNET_CONFIGURATION_Handle *cfg, 333 const struct GNUNET_CONFIGURATION_Handle *cfg,
334 struct sockaddr ***addrs, 334 struct sockaddr ***addrs,
335 socklen_t ** addr_lens) 335 socklen_t **addr_lens)
336{ 336{
337 int disablev6; 337 int disablev6;
338 struct GNUNET_NETWORK_Handle *desc; 338 struct GNUNET_NETWORK_Handle *desc;
@@ -353,15 +353,12 @@ get_server_addresses (const char *service_name,
353 *addrs = NULL; 353 *addrs = NULL;
354 *addr_lens = NULL; 354 *addr_lens = NULL;
355 desc = NULL; 355 desc = NULL;
356 if (GNUNET_CONFIGURATION_have_value (cfg, 356 if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "DISABLEV6"))
357 service_name,
358 "DISABLEV6"))
359 { 357 {
360 if (GNUNET_SYSERR == 358 if (GNUNET_SYSERR ==
361 (disablev6 = 359 (disablev6 = GNUNET_CONFIGURATION_get_value_yesno (cfg,
362 GNUNET_CONFIGURATION_get_value_yesno (cfg, 360 service_name,
363 service_name, 361 "DISABLEV6")))
364 "DISABLEV6")))
365 return GNUNET_SYSERR; 362 return GNUNET_SYSERR;
366 } 363 }
367 else 364 else
@@ -370,24 +367,20 @@ get_server_addresses (const char *service_name,
370 if (! disablev6) 367 if (! disablev6)
371 { 368 {
372 /* probe IPv6 support */ 369 /* probe IPv6 support */
373 desc = GNUNET_NETWORK_socket_create (PF_INET6, 370 desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0);
374 SOCK_STREAM,
375 0);
376 if (NULL == desc) 371 if (NULL == desc)
377 { 372 {
378 if ( (ENOBUFS == errno) || 373 if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
379 (ENOMEM == errno) || 374 (EACCES == errno))
380 (ENFILE == errno) ||
381 (EACCES == errno) )
382 { 375 {
383 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, 376 LOG_strerror (GNUNET_ERROR_TYPE_ERROR, "socket");
384 "socket");
385 return GNUNET_SYSERR; 377 return GNUNET_SYSERR;
386 } 378 }
387 LOG (GNUNET_ERROR_TYPE_INFO, 379 LOG (GNUNET_ERROR_TYPE_INFO,
388 _("Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"), 380 _ (
381 "Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"),
389 service_name, 382 service_name,
390 STRERROR (errno)); 383 strerror (errno));
391 disablev6 = GNUNET_YES; 384 disablev6 = GNUNET_YES;
392 } 385 }
393 else 386 else
@@ -398,38 +391,33 @@ get_server_addresses (const char *service_name,
398 } 391 }
399 392
400 port = 0; 393 port = 0;
401 if (GNUNET_CONFIGURATION_have_value (cfg, 394 if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT"))
402 service_name,
403 "PORT"))
404 { 395 {
405 if (GNUNET_OK != 396 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg,
406 GNUNET_CONFIGURATION_get_value_number (cfg, 397 service_name,
407 service_name, 398 "PORT",
408 "PORT", 399 &port))
409 &port))
410 { 400 {
411 LOG (GNUNET_ERROR_TYPE_ERROR, 401 LOG (GNUNET_ERROR_TYPE_ERROR,
412 _("Require valid port number for service `%s' in configuration!\n"), 402 _ ("Require valid port number for service `%s' in configuration!\n"),
413 service_name); 403 service_name);
414 } 404 }
415 if (port > 65535) 405 if (port > 65535)
416 { 406 {
417 LOG (GNUNET_ERROR_TYPE_ERROR, 407 LOG (GNUNET_ERROR_TYPE_ERROR,
418 _("Require valid port number for service `%s' in configuration!\n"), 408 _ ("Require valid port number for service `%s' in configuration!\n"),
419 service_name); 409 service_name);
420 return GNUNET_SYSERR; 410 return GNUNET_SYSERR;
421 } 411 }
422 } 412 }
423 413
424 if (GNUNET_CONFIGURATION_have_value (cfg, 414 if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "BINDTO"))
425 service_name,
426 "BINDTO"))
427 { 415 {
428 GNUNET_break (GNUNET_OK == 416 GNUNET_break (GNUNET_OK ==
429 GNUNET_CONFIGURATION_get_value_string (cfg, 417 GNUNET_CONFIGURATION_get_value_string (cfg,
430 service_name, 418 service_name,
431 "BINDTO", 419 "BINDTO",
432 &hostname)); 420 &hostname));
433 } 421 }
434 else 422 else
435 hostname = NULL; 423 hostname = NULL;
@@ -438,14 +426,11 @@ get_server_addresses (const char *service_name,
438 abstract = GNUNET_NO; 426 abstract = GNUNET_NO;
439#ifdef AF_UNIX 427#ifdef AF_UNIX
440 if ((GNUNET_YES == 428 if ((GNUNET_YES ==
441 GNUNET_CONFIGURATION_have_value (cfg, 429 GNUNET_CONFIGURATION_have_value (cfg, service_name, "UNIXPATH")) &&
442 service_name, 430 (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename (cfg,
443 "UNIXPATH")) && 431 service_name,
444 (GNUNET_OK == 432 "UNIXPATH",
445 GNUNET_CONFIGURATION_get_value_filename (cfg, 433 &unixpath)) &&
446 service_name,
447 "UNIXPATH",
448 &unixpath)) &&
449 (0 < strlen (unixpath))) 434 (0 < strlen (unixpath)))
450 { 435 {
451 /* probe UNIX support */ 436 /* probe UNIX support */
@@ -454,13 +439,11 @@ get_server_addresses (const char *service_name,
454 if (strlen (unixpath) >= sizeof (s_un.sun_path)) 439 if (strlen (unixpath) >= sizeof (s_un.sun_path))
455 { 440 {
456 LOG (GNUNET_ERROR_TYPE_WARNING, 441 LOG (GNUNET_ERROR_TYPE_WARNING,
457 _("UNIXPATH `%s' too long, maximum length is %llu\n"), 442 _ ("UNIXPATH `%s' too long, maximum length is %llu\n"),
458 unixpath, 443 unixpath,
459 (unsigned long long) sizeof (s_un.sun_path)); 444 (unsigned long long) sizeof (s_un.sun_path));
460 unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath); 445 unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath);
461 LOG (GNUNET_ERROR_TYPE_INFO, 446 LOG (GNUNET_ERROR_TYPE_INFO, _ ("Using `%s' instead\n"), unixpath);
462 _("Using `%s' instead\n"),
463 unixpath);
464 } 447 }
465#ifdef LINUX 448#ifdef LINUX
466 abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg, 449 abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg,
@@ -469,32 +452,28 @@ get_server_addresses (const char *service_name,
469 if (GNUNET_SYSERR == abstract) 452 if (GNUNET_SYSERR == abstract)
470 abstract = GNUNET_NO; 453 abstract = GNUNET_NO;
471#endif 454#endif
472 if ( (GNUNET_YES != abstract) && 455 if ((GNUNET_YES != abstract) &&
473 (GNUNET_OK != 456 (GNUNET_OK != GNUNET_DISK_directory_create_for_file (unixpath)))
474 GNUNET_DISK_directory_create_for_file (unixpath)) ) 457 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "mkdir", unixpath);
475 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
476 "mkdir",
477 unixpath);
478 } 458 }
479 if (NULL != unixpath) 459 if (NULL != unixpath)
480 { 460 {
481 desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0); 461 desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
482 if (NULL == desc) 462 if (NULL == desc)
483 { 463 {
484 if ( (ENOBUFS == errno) || 464 if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
485 (ENOMEM == errno) || 465 (EACCES == errno))
486 (ENFILE == errno) ||
487 (EACCES == errno) )
488 { 466 {
489 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket"); 467 LOG_strerror (GNUNET_ERROR_TYPE_ERROR, "socket");
490 GNUNET_free_non_null (hostname); 468 GNUNET_free_non_null (hostname);
491 GNUNET_free (unixpath); 469 GNUNET_free (unixpath);
492 return GNUNET_SYSERR; 470 return GNUNET_SYSERR;
493 } 471 }
494 LOG (GNUNET_ERROR_TYPE_INFO, 472 LOG (GNUNET_ERROR_TYPE_INFO,
495 _("Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"), 473 _ (
474 "Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
496 service_name, 475 service_name,
497 STRERROR (errno)); 476 strerror (errno));
498 GNUNET_free (unixpath); 477 GNUNET_free (unixpath);
499 unixpath = NULL; 478 unixpath = NULL;
500 } 479 }
@@ -506,29 +485,23 @@ get_server_addresses (const char *service_name,
506 } 485 }
507#endif 486#endif
508 487
509 if ( (0 == port) && 488 if ((0 == port) && (NULL == unixpath))
510 (NULL == unixpath) )
511 { 489 {
512 if (GNUNET_YES == 490 if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (cfg,
513 GNUNET_CONFIGURATION_get_value_yesno (cfg, 491 service_name,
514 service_name, 492 "START_ON_DEMAND"))
515 "START_ON_DEMAND"))
516 LOG (GNUNET_ERROR_TYPE_ERROR, 493 LOG (GNUNET_ERROR_TYPE_ERROR,
517 _("Have neither PORT nor UNIXPATH for service `%s', but one is required\n"), 494 _ (
518 service_name); 495 "Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
496 service_name);
519 GNUNET_free_non_null (hostname); 497 GNUNET_free_non_null (hostname);
520 return GNUNET_SYSERR; 498 return GNUNET_SYSERR;
521 } 499 }
522 if (0 == port) 500 if (0 == port)
523 { 501 {
524 saddrs = GNUNET_new_array (2, 502 saddrs = GNUNET_new_array (2, struct sockaddr *);
525 struct sockaddr *); 503 saddrlens = GNUNET_new_array (2, socklen_t);
526 saddrlens = GNUNET_new_array (2, 504 add_unixpath (saddrs, saddrlens, unixpath, abstract);
527 socklen_t);
528 add_unixpath (saddrs,
529 saddrlens,
530 unixpath,
531 abstract);
532 GNUNET_free_non_null (unixpath); 505 GNUNET_free_non_null (unixpath);
533 GNUNET_free_non_null (hostname); 506 GNUNET_free_non_null (hostname);
534 *addrs = saddrs; 507 *addrs = saddrs;
@@ -546,14 +519,11 @@ get_server_addresses (const char *service_name,
546 if (disablev6) 519 if (disablev6)
547 hints.ai_family = AF_INET; 520 hints.ai_family = AF_INET;
548 hints.ai_protocol = IPPROTO_TCP; 521 hints.ai_protocol = IPPROTO_TCP;
549 if ((0 != (ret = getaddrinfo (hostname, 522 if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) ||
550 NULL,
551 &hints,
552 &res))) ||
553 (NULL == res)) 523 (NULL == res))
554 { 524 {
555 LOG (GNUNET_ERROR_TYPE_ERROR, 525 LOG (GNUNET_ERROR_TYPE_ERROR,
556 _("Failed to resolve `%s': %s\n"), 526 _ ("Failed to resolve `%s': %s\n"),
557 hostname, 527 hostname,
558 gai_strerror (ret)); 528 gai_strerror (ret));
559 GNUNET_free (hostname); 529 GNUNET_free (hostname);
@@ -572,7 +542,7 @@ get_server_addresses (const char *service_name,
572 if (0 == i) 542 if (0 == i)
573 { 543 {
574 LOG (GNUNET_ERROR_TYPE_ERROR, 544 LOG (GNUNET_ERROR_TYPE_ERROR,
575 _("Failed to find %saddress for `%s'.\n"), 545 _ ("Failed to find %saddress for `%s'.\n"),
576 disablev6 ? "IPv4 " : "", 546 disablev6 ? "IPv4 " : "",
577 hostname); 547 hostname);
578 freeaddrinfo (res); 548 freeaddrinfo (res);
@@ -583,10 +553,8 @@ get_server_addresses (const char *service_name,
583 resi = i; 553 resi = i;
584 if (NULL != unixpath) 554 if (NULL != unixpath)
585 resi++; 555 resi++;
586 saddrs = GNUNET_new_array (resi + 1, 556 saddrs = GNUNET_new_array (resi + 1, struct sockaddr *);
587 struct sockaddr *); 557 saddrlens = GNUNET_new_array (resi + 1, socklen_t);
588 saddrlens = GNUNET_new_array (resi + 1,
589 socklen_t);
590 i = 0; 558 i = 0;
591 if (NULL != unixpath) 559 if (NULL != unixpath)
592 { 560 {
@@ -600,11 +568,13 @@ get_server_addresses (const char *service_name,
600 if ((disablev6) && (AF_INET6 == pos->ai_family)) 568 if ((disablev6) && (AF_INET6 == pos->ai_family))
601 continue; 569 continue;
602 if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol)) 570 if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol))
603 continue; /* not TCP */ 571 continue; /* not TCP */
604 if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype)) 572 if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype))
605 continue; /* huh? */ 573 continue; /* huh? */
606 LOG (GNUNET_ERROR_TYPE_DEBUG, "Service `%s' will bind to `%s'\n", 574 LOG (GNUNET_ERROR_TYPE_DEBUG,
607 service_name, GNUNET_a2s (pos->ai_addr, pos->ai_addrlen)); 575 "Service `%s' will bind to `%s'\n",
576 service_name,
577 GNUNET_a2s (pos->ai_addr, pos->ai_addrlen));
608 if (AF_INET == pos->ai_family) 578 if (AF_INET == pos->ai_family)
609 { 579 {
610 GNUNET_assert (sizeof (struct sockaddr_in) == pos->ai_addrlen); 580 GNUNET_assert (sizeof (struct sockaddr_in) == pos->ai_addrlen);
@@ -638,10 +608,8 @@ get_server_addresses (const char *service_name,
638 if (NULL != unixpath) 608 if (NULL != unixpath)
639 resi++; 609 resi++;
640 i = 0; 610 i = 0;
641 saddrs = GNUNET_new_array (resi + 1, 611 saddrs = GNUNET_new_array (resi + 1, struct sockaddr *);
642 struct sockaddr *); 612 saddrlens = GNUNET_new_array (resi + 1, socklen_t);
643 saddrlens = GNUNET_new_array (resi + 1,
644 socklen_t);
645 if (NULL != unixpath) 613 if (NULL != unixpath)
646 { 614 {
647 add_unixpath (saddrs, saddrlens, unixpath, abstract); 615 add_unixpath (saddrs, saddrlens, unixpath, abstract);
@@ -661,17 +629,12 @@ get_server_addresses (const char *service_name,
661 resi = 2; 629 resi = 2;
662 if (NULL != unixpath) 630 if (NULL != unixpath)
663 resi++; 631 resi++;
664 saddrs = GNUNET_new_array (resi + 1, 632 saddrs = GNUNET_new_array (resi + 1, struct sockaddr *);
665 struct sockaddr *); 633 saddrlens = GNUNET_new_array (resi + 1, socklen_t);
666 saddrlens = GNUNET_new_array (resi + 1,
667 socklen_t);
668 i = 0; 634 i = 0;
669 if (NULL != unixpath) 635 if (NULL != unixpath)
670 { 636 {
671 add_unixpath (saddrs, 637 add_unixpath (saddrs, saddrlens, unixpath, abstract);
672 saddrlens,
673 unixpath,
674 abstract);
675 i++; 638 i++;
676 } 639 }
677 saddrlens[i] = sizeof (struct sockaddr_in6); 640 saddrlens[i] = sizeof (struct sockaddr_in6);
@@ -710,20 +673,18 @@ get_server_addresses (const char *service_name,
710 */ 673 */
711static void 674static void
712signal_result (struct GNUNET_SERVICE_Client *client, 675signal_result (struct GNUNET_SERVICE_Client *client,
713 const char *name, 676 const char *name,
714 uint64_t request_id, 677 uint64_t request_id,
715 enum GNUNET_ARM_Result result) 678 enum GNUNET_ARM_Result result)
716{ 679{
717 struct GNUNET_MQ_Envelope *env; 680 struct GNUNET_MQ_Envelope *env;
718 struct GNUNET_ARM_ResultMessage *msg; 681 struct GNUNET_ARM_ResultMessage *msg;
719 682
720 (void) name; 683 (void) name;
721 env = GNUNET_MQ_msg (msg, 684 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_ARM_RESULT);
722 GNUNET_MESSAGE_TYPE_ARM_RESULT);
723 msg->result = htonl (result); 685 msg->result = htonl (result);
724 msg->arm_msg.request_id = GNUNET_htonll (request_id); 686 msg->arm_msg.request_id = GNUNET_htonll (request_id);
725 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), 687 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env);
726 env);
727} 688}
728 689
729 690
@@ -737,8 +698,8 @@ signal_result (struct GNUNET_SERVICE_Client *client,
737 */ 698 */
738static void 699static void
739broadcast_status (const char *name, 700broadcast_status (const char *name,
740 enum GNUNET_ARM_ServiceStatus status, 701 enum GNUNET_ARM_ServiceStatus status,
741 struct GNUNET_SERVICE_Client *unicast) 702 struct GNUNET_SERVICE_Client *unicast)
742{ 703{
743 struct GNUNET_MQ_Envelope *env; 704 struct GNUNET_MQ_Envelope *env;
744 struct GNUNET_ARM_StatusMessage *msg; 705 struct GNUNET_ARM_StatusMessage *msg;
@@ -749,13 +710,9 @@ broadcast_status (const char *name,
749 (unsigned int) status, 710 (unsigned int) status,
750 name); 711 name);
751 namelen = strlen (name) + 1; 712 namelen = strlen (name) + 1;
752 env = GNUNET_MQ_msg_extra (msg, 713 env = GNUNET_MQ_msg_extra (msg, namelen, GNUNET_MESSAGE_TYPE_ARM_STATUS);
753 namelen,
754 GNUNET_MESSAGE_TYPE_ARM_STATUS);
755 msg->status = htonl ((uint32_t) (status)); 714 msg->status = htonl ((uint32_t) (status));
756 GNUNET_memcpy ((char *) &msg[1], 715 GNUNET_memcpy ((char *) &msg[1], name, namelen);
757 name,
758 namelen);
759 if (NULL == unicast) 716 if (NULL == unicast)
760 { 717 {
761 if (NULL != notifier) 718 if (NULL != notifier)
@@ -766,8 +723,7 @@ broadcast_status (const char *name,
766 } 723 }
767 else 724 else
768 { 725 {
769 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (unicast), 726 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (unicast), env);
770 env);
771 } 727 }
772} 728}
773 729
@@ -799,44 +755,37 @@ start_process (struct ServiceList *sl,
799 lsocks = NULL; 755 lsocks = NULL;
800 ls = 0; 756 ls = 0;
801 for (sli = sl->listen_head; NULL != sli; sli = sli->next) 757 for (sli = sl->listen_head; NULL != sli; sli = sli->next)
758 {
759 GNUNET_array_append (lsocks,
760 ls,
761 GNUNET_NETWORK_get_fd (sli->listen_socket));
762 if (NULL != sli->accept_task)
802 { 763 {
803 GNUNET_array_append (lsocks, ls, 764 GNUNET_SCHEDULER_cancel (sli->accept_task);
804 GNUNET_NETWORK_get_fd (sli->listen_socket)); 765 sli->accept_task = NULL;
805 if (NULL != sli->accept_task)
806 {
807 GNUNET_SCHEDULER_cancel (sli->accept_task);
808 sli->accept_task = NULL;
809 }
810 } 766 }
767 }
811#if WINDOWS 768#if WINDOWS
812 GNUNET_array_append (lsocks, 769 GNUNET_array_append (lsocks, ls, INVALID_SOCKET);
813 ls,
814 INVALID_SOCKET);
815#else 770#else
816 GNUNET_array_append (lsocks, 771 GNUNET_array_append (lsocks, ls, -1);
817 ls,
818 -1);
819#endif 772#endif
820 773
821 /* obtain configuration */ 774 /* obtain configuration */
822 if (GNUNET_OK != 775 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg,
823 GNUNET_CONFIGURATION_get_value_string (cfg, 776 sl->name,
824 sl->name, 777 "PREFIX",
825 "PREFIX", 778 &loprefix))
826 &loprefix))
827 loprefix = GNUNET_strdup (prefix_command); 779 loprefix = GNUNET_strdup (prefix_command);
828 else 780 else
829 loprefix = GNUNET_CONFIGURATION_expand_dollar (cfg, 781 loprefix = GNUNET_CONFIGURATION_expand_dollar (cfg, loprefix);
830 loprefix); 782 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg,
831 if (GNUNET_OK != 783 sl->name,
832 GNUNET_CONFIGURATION_get_value_string (cfg, 784 "OPTIONS",
833 sl->name, 785 &options))
834 "OPTIONS",
835 &options))
836 options = NULL; 786 options = NULL;
837 else 787 else
838 options = GNUNET_CONFIGURATION_expand_dollar (cfg, 788 options = GNUNET_CONFIGURATION_expand_dollar (cfg, options);
839 options);
840 { 789 {
841 char *new_options; 790 char *new_options;
842 char *optpos; 791 char *optpos;
@@ -844,8 +793,7 @@ start_process (struct ServiceList *sl,
844 793
845 fin_options = GNUNET_strdup (final_option); 794 fin_options = GNUNET_strdup (final_option);
846 /* replace '{}' with service name */ 795 /* replace '{}' with service name */
847 while (NULL != (optpos = strstr (fin_options, 796 while (NULL != (optpos = strstr (fin_options, "{}")))
848 "{}")))
849 { 797 {
850 /* terminate string at opening parenthesis */ 798 /* terminate string at opening parenthesis */
851 *optpos = 0; 799 *optpos = 0;
@@ -861,10 +809,7 @@ start_process (struct ServiceList *sl,
861 { 809 {
862 /* combine "fin_options" with "options" */ 810 /* combine "fin_options" with "options" */
863 optpos = options; 811 optpos = options;
864 GNUNET_asprintf (&options, 812 GNUNET_asprintf (&options, "%s %s", fin_options, optpos);
865 "%s %s",
866 fin_options,
867 optpos);
868 GNUNET_free (fin_options); 813 GNUNET_free (fin_options);
869 GNUNET_free (optpos); 814 GNUNET_free (optpos);
870 } 815 }
@@ -874,23 +819,19 @@ start_process (struct ServiceList *sl,
874 options = fin_options; 819 options = fin_options;
875 } 820 }
876 } 821 }
877 options = GNUNET_CONFIGURATION_expand_dollar (cfg, 822 options = GNUNET_CONFIGURATION_expand_dollar (cfg, options);
878 options); 823 use_debug = GNUNET_CONFIGURATION_get_value_yesno (cfg, sl->name, "DEBUG");
879 use_debug = GNUNET_CONFIGURATION_get_value_yesno (cfg,
880 sl->name,
881 "DEBUG");
882 { 824 {
883 const char *service_type = NULL; 825 const char *service_type = NULL;
884 const char *choices[] = { "GNUNET", "SIMPLE", NULL }; 826 const char *choices[] = {"GNUNET", "SIMPLE", NULL};
885 827
886 is_simple_service = GNUNET_NO; 828 is_simple_service = GNUNET_NO;
887 if ( (GNUNET_OK == 829 if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_choice (cfg,
888 GNUNET_CONFIGURATION_get_value_choice (cfg, 830 sl->name,
889 sl->name, 831 "TYPE",
890 "TYPE", 832 choices,
891 choices, 833 &service_type)) &&
892 &service_type)) && 834 (0 == strcasecmp (service_type, "SIMPLE")))
893 (0 == strcasecmp (service_type, "SIMPLE")) )
894 is_simple_service = GNUNET_YES; 835 is_simple_service = GNUNET_YES;
895 } 836 }
896 837
@@ -901,81 +842,79 @@ start_process (struct ServiceList *sl,
901 command line options. */ 842 command line options. */
902 binary = GNUNET_strdup (sl->binary); 843 binary = GNUNET_strdup (sl->binary);
903 binary = GNUNET_CONFIGURATION_expand_dollar (cfg, binary); 844 binary = GNUNET_CONFIGURATION_expand_dollar (cfg, binary);
904 GNUNET_asprintf (&quotedbinary, 845 GNUNET_asprintf (&quotedbinary, "\"%s\"", sl->binary);
905 "\"%s\"",
906 sl->binary);
907 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 846 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
908 "Starting simple service `%s' using binary `%s'\n", 847 "Starting simple service `%s' using binary `%s'\n",
909 sl->name, sl->binary); 848 sl->name,
849 sl->binary);
910 /* FIXME: dollar expansion should only be done outside 850 /* FIXME: dollar expansion should only be done outside
911 * of ''-quoted strings, escaping should be considered. */ 851 * of ''-quoted strings, escaping should be considered. */
912 if (NULL != options) 852 if (NULL != options)
913 options = GNUNET_CONFIGURATION_expand_dollar (cfg, options); 853 options = GNUNET_CONFIGURATION_expand_dollar (cfg, options);
914 sl->proc = 854 sl->proc = GNUNET_OS_start_process_s (sl->pipe_control,
915 GNUNET_OS_start_process_s (sl->pipe_control, 855 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
916 GNUNET_OS_INHERIT_STD_OUT_AND_ERR, 856 lsocks,
917 lsocks, 857 loprefix,
918 loprefix, 858 quotedbinary,
919 quotedbinary, 859 options,
920 options, 860 NULL);
921 NULL);
922 } 861 }
923 else 862 else
924 { 863 {
925 /* actually start process */ 864 /* actually start process */
926 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 865 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
927 "Starting service `%s' using binary `%s' and configuration `%s'\n", 866 "Starting service `%s' using binary `%s' and configuration `%s'\n",
928 sl->name, sl->binary, sl->config); 867 sl->name,
868 sl->binary,
869 sl->config);
929 binary = GNUNET_OS_get_libexec_binary_path (sl->binary); 870 binary = GNUNET_OS_get_libexec_binary_path (sl->binary);
930 GNUNET_asprintf (&quotedbinary, 871 GNUNET_asprintf (&quotedbinary, "\"%s\"", binary);
931 "\"%s\"",
932 binary);
933 872
934 if (GNUNET_YES == use_debug) 873 if (GNUNET_YES == use_debug)
935 { 874 {
936 if (NULL == sl->config) 875 if (NULL == sl->config)
937 sl->proc = 876 sl->proc = GNUNET_OS_start_process_s (sl->pipe_control,
938 GNUNET_OS_start_process_s (sl->pipe_control, 877 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
939 GNUNET_OS_INHERIT_STD_OUT_AND_ERR, 878 lsocks,
940 lsocks, 879 loprefix,
941 loprefix, 880 quotedbinary,
942 quotedbinary, 881 "-L",
943 "-L", "DEBUG", 882 "DEBUG",
944 options, 883 options,
945 NULL); 884 NULL);
946 else 885 else
947 sl->proc = 886 sl->proc = GNUNET_OS_start_process_s (sl->pipe_control,
948 GNUNET_OS_start_process_s (sl->pipe_control, 887 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
949 GNUNET_OS_INHERIT_STD_OUT_AND_ERR, 888 lsocks,
950 lsocks, 889 loprefix,
951 loprefix, 890 quotedbinary,
952 quotedbinary, 891 "-c",
953 "-c", sl->config, 892 sl->config,
954 "-L", "DEBUG", 893 "-L",
955 options, 894 "DEBUG",
956 NULL); 895 options,
896 NULL);
957 } 897 }
958 else 898 else
959 { 899 {
960 if (NULL == sl->config) 900 if (NULL == sl->config)
961 sl->proc = 901 sl->proc = GNUNET_OS_start_process_s (sl->pipe_control,
962 GNUNET_OS_start_process_s (sl->pipe_control, 902 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
963 GNUNET_OS_INHERIT_STD_OUT_AND_ERR, 903 lsocks,
964 lsocks, 904 loprefix,
965 loprefix, 905 quotedbinary,
966 quotedbinary, 906 options,
967 options, 907 NULL);
968 NULL);
969 else 908 else
970 sl->proc = 909 sl->proc = GNUNET_OS_start_process_s (sl->pipe_control,
971 GNUNET_OS_start_process_s (sl->pipe_control, 910 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
972 GNUNET_OS_INHERIT_STD_OUT_AND_ERR, 911 lsocks,
973 lsocks, 912 loprefix,
974 loprefix, 913 quotedbinary,
975 quotedbinary, 914 "-c",
976 "-c", sl->config, 915 sl->config,
977 options, 916 options,
978 NULL); 917 NULL);
979 } 918 }
980 } 919 }
981 GNUNET_free (binary); 920 GNUNET_free (binary);
@@ -983,8 +922,8 @@ start_process (struct ServiceList *sl,
983 if (NULL == sl->proc) 922 if (NULL == sl->proc)
984 { 923 {
985 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 924 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
986 _("Failed to start service `%s'\n"), 925 _ ("Failed to start service `%s'\n"),
987 sl->name); 926 sl->name);
988 if (client) 927 if (client)
989 signal_result (client, 928 signal_result (client,
990 sl->name, 929 sl->name,
@@ -994,23 +933,16 @@ start_process (struct ServiceList *sl,
994 else 933 else
995 { 934 {
996 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 935 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
997 _("Starting service `%s'\n"), 936 _ ("Starting service `%s'\n"),
998 sl->name); 937 sl->name);
999 broadcast_status (sl->name, 938 broadcast_status (sl->name, GNUNET_ARM_SERVICE_STARTING, NULL);
1000 GNUNET_ARM_SERVICE_STARTING,
1001 NULL);
1002 if (client) 939 if (client)
1003 signal_result (client, 940 signal_result (client, sl->name, request_id, GNUNET_ARM_RESULT_STARTING);
1004 sl->name,
1005 request_id,
1006 GNUNET_ARM_RESULT_STARTING);
1007 } 941 }
1008 /* clean up */ 942 /* clean up */
1009 GNUNET_free (loprefix); 943 GNUNET_free (loprefix);
1010 GNUNET_free (options); 944 GNUNET_free (options);
1011 GNUNET_array_grow (lsocks, 945 GNUNET_array_grow (lsocks, ls, 0);
1012 ls,
1013 0);
1014} 946}
1015 947
1016 948
@@ -1028,11 +960,11 @@ find_service (const char *name)
1028 960
1029 sl = running_head; 961 sl = running_head;
1030 while (sl != NULL) 962 while (sl != NULL)
1031 { 963 {
1032 if (0 == strcasecmp (sl->name, name)) 964 if (0 == strcasecmp (sl->name, name))
1033 return sl; 965 return sl;
1034 sl = sl->next; 966 sl = sl->next;
1035 } 967 }
1036 return NULL; 968 return NULL;
1037} 969}
1038 970
@@ -1066,7 +998,7 @@ accept_connection (void *cls)
1066static void 998static void
1067create_listen_socket (struct sockaddr *sa, 999create_listen_socket (struct sockaddr *sa,
1068 socklen_t addr_len, 1000 socklen_t addr_len,
1069 struct ServiceList *sl) 1001 struct ServiceList *sl)
1070{ 1002{
1071 static int on = 1; 1003 static int on = 1;
1072 struct GNUNET_NETWORK_Handle *sock; 1004 struct GNUNET_NETWORK_Handle *sock;
@@ -1079,23 +1011,16 @@ create_listen_socket (struct sockaddr *sa,
1079 switch (sa->sa_family) 1011 switch (sa->sa_family)
1080 { 1012 {
1081 case AF_INET: 1013 case AF_INET:
1082 sock = GNUNET_NETWORK_socket_create (PF_INET, 1014 sock = GNUNET_NETWORK_socket_create (PF_INET, SOCK_STREAM, 0);
1083 SOCK_STREAM,
1084 0);
1085 break; 1015 break;
1086 case AF_INET6: 1016 case AF_INET6:
1087 sock = GNUNET_NETWORK_socket_create (PF_INET6, 1017 sock = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0);
1088 SOCK_STREAM,
1089 0);
1090 break; 1018 break;
1091 case AF_UNIX: 1019 case AF_UNIX:
1092 if (0 == strcmp (GNUNET_a2s (sa, 1020 if (0 == strcmp (GNUNET_a2s (sa, addr_len),
1093 addr_len), 1021 "@")) /* Do not bind to blank UNIX path! */
1094 "@")) /* Do not bind to blank UNIX path! */
1095 return; 1022 return;
1096 sock = GNUNET_NETWORK_socket_create (PF_UNIX, 1023 sock = GNUNET_NETWORK_socket_create (PF_UNIX, SOCK_STREAM, 0);
1097 SOCK_STREAM,
1098 0);
1099 break; 1024 break;
1100 default: 1025 default:
1101 GNUNET_break (0); 1026 GNUNET_break (0);
@@ -1106,48 +1031,44 @@ create_listen_socket (struct sockaddr *sa,
1106 if (NULL == sock) 1031 if (NULL == sock)
1107 { 1032 {
1108 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1033 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1109 _("Unable to create socket for service `%s': %s\n"), 1034 _ ("Unable to create socket for service `%s': %s\n"),
1110 sl->name, 1035 sl->name,
1111 STRERROR (errno)); 1036 strerror (errno));
1112 GNUNET_free (sa); 1037 GNUNET_free (sa);
1113 return; 1038 return;
1114 } 1039 }
1115 if (GNUNET_OK != 1040 if (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt (sock,
1116 GNUNET_NETWORK_socket_setsockopt (sock, 1041 SOL_SOCKET,
1117 SOL_SOCKET, 1042 SO_REUSEADDR,
1118 SO_REUSEADDR, 1043 &on,
1119 &on, 1044 sizeof (on)))
1120 sizeof (on)))
1121 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 1045 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1122 "setsockopt"); 1046 "setsockopt");
1123#ifdef IPV6_V6ONLY 1047#ifdef IPV6_V6ONLY
1124 if ( (sa->sa_family == AF_INET6) && 1048 if ((sa->sa_family == AF_INET6) &&
1125 (GNUNET_OK != 1049 (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt (sock,
1126 GNUNET_NETWORK_socket_setsockopt (sock, 1050 IPPROTO_IPV6,
1127 IPPROTO_IPV6, 1051 IPV6_V6ONLY,
1128 IPV6_V6ONLY, 1052 &on,
1129 &on, 1053 sizeof (on))))
1130 sizeof (on))) )
1131 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 1054 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1132 "setsockopt"); 1055 "setsockopt");
1133#endif 1056#endif
1134#ifndef WINDOWS 1057#ifndef WINDOWS
1135 if (AF_UNIX == sa->sa_family) 1058 if (AF_UNIX == sa->sa_family)
1136 GNUNET_NETWORK_unix_precheck ((struct sockaddr_un *) sa); 1059 GNUNET_NETWORK_unix_precheck ((struct sockaddr_un *) sa);
1137#endif 1060#endif
1138 if (GNUNET_OK != 1061 if (GNUNET_OK !=
1139 GNUNET_NETWORK_socket_bind (sock, 1062 GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) sa, addr_len))
1140 (const struct sockaddr *) sa,
1141 addr_len))
1142 { 1063 {
1143 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1064 GNUNET_log (
1144 _("Unable to bind listening socket for service `%s' to address `%s': %s\n"), 1065 GNUNET_ERROR_TYPE_WARNING,
1145 sl->name, 1066 _ (
1146 GNUNET_a2s (sa, 1067 "Unable to bind listening socket for service `%s' to address `%s': %s\n"),
1147 addr_len), 1068 sl->name,
1148 STRERROR (errno)); 1069 GNUNET_a2s (sa, addr_len),
1149 GNUNET_break (GNUNET_OK == 1070 strerror (errno));
1150 GNUNET_NETWORK_socket_close (sock)); 1071 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
1151 GNUNET_free (sa); 1072 GNUNET_free (sa);
1152 return; 1073 return;
1153 } 1074 }
@@ -1155,51 +1076,41 @@ create_listen_socket (struct sockaddr *sa,
1155 if ((AF_UNIX == sa->sa_family) 1076 if ((AF_UNIX == sa->sa_family)
1156#ifdef LINUX 1077#ifdef LINUX
1157 /* Permission settings are not required when abstract sockets are used */ 1078 /* Permission settings are not required when abstract sockets are used */
1158 && ('\0' != ((const struct sockaddr_un *)sa)->sun_path[0]) 1079 && ('\0' != ((const struct sockaddr_un *) sa)->sun_path[0])
1159#endif 1080#endif
1160 ) 1081 )
1161 { 1082 {
1162 match_uid = 1083 match_uid =
1163 GNUNET_CONFIGURATION_get_value_yesno (cfg, 1084 GNUNET_CONFIGURATION_get_value_yesno (cfg, sl->name, "UNIX_MATCH_UID");
1164 sl->name,
1165 "UNIX_MATCH_UID");
1166 match_gid = 1085 match_gid =
1167 GNUNET_CONFIGURATION_get_value_yesno (cfg, 1086 GNUNET_CONFIGURATION_get_value_yesno (cfg, sl->name, "UNIX_MATCH_GID");
1168 sl->name, 1087 GNUNET_DISK_fix_permissions (((const struct sockaddr_un *) sa)->sun_path,
1169 "UNIX_MATCH_GID");
1170 GNUNET_DISK_fix_permissions (((const struct sockaddr_un *)sa)->sun_path,
1171 match_uid, 1088 match_uid,
1172 match_gid); 1089 match_gid);
1173
1174 } 1090 }
1175#endif 1091#endif
1176 if (GNUNET_OK != 1092 if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5))
1177 GNUNET_NETWORK_socket_listen (sock, 5))
1178 { 1093 {
1179 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, 1094 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "listen");
1180 "listen"); 1095 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
1181 GNUNET_break (GNUNET_OK ==
1182 GNUNET_NETWORK_socket_close (sock));
1183 GNUNET_free (sa); 1096 GNUNET_free (sa);
1184 return; 1097 return;
1185 } 1098 }
1186 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1099 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1187 _("ARM now monitors connections to service `%s' at `%s'\n"), 1100 _ ("ARM now monitors connections to service `%s' at `%s'\n"),
1188 sl->name, 1101 sl->name,
1189 GNUNET_a2s (sa, 1102 GNUNET_a2s (sa, addr_len));
1190 addr_len));
1191 sli = GNUNET_new (struct ServiceListeningInfo); 1103 sli = GNUNET_new (struct ServiceListeningInfo);
1192 sli->service_addr = sa; 1104 sli->service_addr = sa;
1193 sli->service_addr_len = addr_len; 1105 sli->service_addr_len = addr_len;
1194 sli->listen_socket = sock; 1106 sli->listen_socket = sock;
1195 sli->sl = sl; 1107 sli->sl = sl;
1196 sli->accept_task 1108 sli->accept_task =
1197 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 1109 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
1198 sock, 1110 sock,
1199 &accept_connection, sli); 1111 &accept_connection,
1200 GNUNET_CONTAINER_DLL_insert (sl->listen_head, 1112 sli);
1201 sl->listen_tail, 1113 GNUNET_CONTAINER_DLL_insert (sl->listen_head, sl->listen_tail, sli);
1202 sli);
1203} 1114}
1204 1115
1205 1116
@@ -1213,9 +1124,7 @@ static void
1213free_service (struct ServiceList *sl) 1124free_service (struct ServiceList *sl)
1214{ 1125{
1215 GNUNET_assert (GNUNET_YES == in_shutdown); 1126 GNUNET_assert (GNUNET_YES == in_shutdown);
1216 GNUNET_CONTAINER_DLL_remove (running_head, 1127 GNUNET_CONTAINER_DLL_remove (running_head, running_tail, sl);
1217 running_tail,
1218 sl);
1219 GNUNET_assert (NULL == sl->listen_head); 1128 GNUNET_assert (NULL == sl->listen_head);
1220 GNUNET_free_non_null (sl->config); 1129 GNUNET_free_non_null (sl->config);
1221 GNUNET_free_non_null (sl->binary); 1130 GNUNET_free_non_null (sl->binary);
@@ -1233,8 +1142,7 @@ free_service (struct ServiceList *sl)
1233 * #GNUNET_SYSERR to close it (signal serious error) 1142 * #GNUNET_SYSERR to close it (signal serious error)
1234 */ 1143 */
1235static int 1144static int
1236check_start (void *cls, 1145check_start (void *cls, const struct GNUNET_ARM_Message *amsg)
1237 const struct GNUNET_ARM_Message *amsg)
1238{ 1146{
1239 (void) cls; 1147 (void) cls;
1240 GNUNET_MQ_check_zero_termination (amsg); 1148 GNUNET_MQ_check_zero_termination (amsg);
@@ -1249,8 +1157,7 @@ check_start (void *cls,
1249 * @param amsg the actual message 1157 * @param amsg the actual message
1250 */ 1158 */
1251static void 1159static void
1252handle_start (void *cls, 1160handle_start (void *cls, const struct GNUNET_ARM_Message *amsg)
1253 const struct GNUNET_ARM_Message *amsg)
1254{ 1161{
1255 struct GNUNET_SERVICE_Client *client = cls; 1162 struct GNUNET_SERVICE_Client *client = cls;
1256 const char *servicename; 1163 const char *servicename;
@@ -1265,7 +1172,7 @@ handle_start (void *cls,
1265 signal_result (client, 1172 signal_result (client,
1266 servicename, 1173 servicename,
1267 request_id, 1174 request_id,
1268 GNUNET_ARM_RESULT_IN_SHUTDOWN); 1175 GNUNET_ARM_RESULT_IN_SHUTDOWN);
1269 return; 1176 return;
1270 } 1177 }
1271 sl = find_service (servicename); 1178 sl = find_service (servicename);
@@ -1274,7 +1181,7 @@ handle_start (void *cls,
1274 signal_result (client, 1181 signal_result (client,
1275 servicename, 1182 servicename,
1276 request_id, 1183 request_id,
1277 GNUNET_ARM_RESULT_IS_NOT_KNOWN); 1184 GNUNET_ARM_RESULT_IS_NOT_KNOWN);
1278 return; 1185 return;
1279 } 1186 }
1280 sl->force_start = GNUNET_YES; 1187 sl->force_start = GNUNET_YES;
@@ -1283,12 +1190,10 @@ handle_start (void *cls,
1283 signal_result (client, 1190 signal_result (client,
1284 servicename, 1191 servicename,
1285 request_id, 1192 request_id,
1286 GNUNET_ARM_RESULT_IS_STARTED_ALREADY); 1193 GNUNET_ARM_RESULT_IS_STARTED_ALREADY);
1287 return; 1194 return;
1288 } 1195 }
1289 start_process (sl, 1196 start_process (sl, client, request_id);
1290 client,
1291 request_id);
1292} 1197}
1293 1198
1294 1199
@@ -1301,8 +1206,7 @@ static void
1301trigger_shutdown (void *cls) 1206trigger_shutdown (void *cls)
1302{ 1207{
1303 (void) cls; 1208 (void) cls;
1304 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1209 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Triggering shutdown\n");
1305 "Triggering shutdown\n");
1306 GNUNET_SCHEDULER_shutdown (); 1210 GNUNET_SCHEDULER_shutdown ();
1307} 1211}
1308 1212
@@ -1316,8 +1220,7 @@ trigger_shutdown (void *cls)
1316 * #GNUNET_SYSERR to close it (signal serious error) 1220 * #GNUNET_SYSERR to close it (signal serious error)
1317 */ 1221 */
1318static int 1222static int
1319check_stop (void *cls, 1223check_stop (void *cls, const struct GNUNET_ARM_Message *amsg)
1320 const struct GNUNET_ARM_Message *amsg)
1321{ 1224{
1322 (void) cls; 1225 (void) cls;
1323 GNUNET_MQ_check_zero_termination (amsg); 1226 GNUNET_MQ_check_zero_termination (amsg);
@@ -1332,8 +1235,7 @@ check_stop (void *cls,
1332 * @param amsg the actual message 1235 * @param amsg the actual message
1333 */ 1236 */
1334static void 1237static void
1335handle_stop (void *cls, 1238handle_stop (void *cls, const struct GNUNET_ARM_Message *amsg)
1336 const struct GNUNET_ARM_Message *amsg)
1337{ 1239{
1338 struct GNUNET_SERVICE_Client *client = cls; 1240 struct GNUNET_SERVICE_Client *client = cls;
1339 struct ServiceList *sl; 1241 struct ServiceList *sl;
@@ -1343,22 +1245,15 @@ handle_stop (void *cls,
1343 request_id = GNUNET_ntohll (amsg->request_id); 1245 request_id = GNUNET_ntohll (amsg->request_id);
1344 servicename = (const char *) &amsg[1]; 1246 servicename = (const char *) &amsg[1];
1345 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1247 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1346 _("Preparing to stop `%s'\n"), 1248 _ ("Preparing to stop `%s'\n"),
1347 servicename); 1249 servicename);
1348 GNUNET_SERVICE_client_continue (client); 1250 GNUNET_SERVICE_client_continue (client);
1349 if (0 == strcasecmp (servicename, 1251 if (0 == strcasecmp (servicename, "arm"))
1350 "arm"))
1351 { 1252 {
1352 broadcast_status (servicename, 1253 broadcast_status (servicename, GNUNET_ARM_SERVICE_STOPPING, NULL);
1353 GNUNET_ARM_SERVICE_STOPPING, 1254 signal_result (client, servicename, request_id, GNUNET_ARM_RESULT_STOPPING);
1354 NULL);
1355 signal_result (client,
1356 servicename,
1357 request_id,
1358 GNUNET_ARM_RESULT_STOPPING);
1359 GNUNET_SERVICE_client_persist (client); 1255 GNUNET_SERVICE_client_persist (client);
1360 GNUNET_SCHEDULER_add_now (&trigger_shutdown, 1256 GNUNET_SCHEDULER_add_now (&trigger_shutdown, NULL);
1361 NULL);
1362 return; 1257 return;
1363 } 1258 }
1364 sl = find_service (servicename); 1259 sl = find_service (servicename);
@@ -1384,32 +1279,28 @@ handle_stop (void *cls,
1384 { 1279 {
1385 /* killing already in progress */ 1280 /* killing already in progress */
1386 signal_result (client, 1281 signal_result (client,
1387 servicename, 1282 servicename,
1388 request_id, 1283 request_id,
1389 GNUNET_ARM_RESULT_IS_STOPPING_ALREADY); 1284 GNUNET_ARM_RESULT_IS_STOPPING_ALREADY);
1390 return; 1285 return;
1391 } 1286 }
1392 if (NULL == sl->proc) 1287 if (NULL == sl->proc)
1393 { 1288 {
1394 /* process is down */ 1289 /* process is down */
1395 signal_result (client, 1290 signal_result (client,
1396 servicename, 1291 servicename,
1397 request_id, 1292 request_id,
1398 GNUNET_ARM_RESULT_IS_STOPPED_ALREADY); 1293 GNUNET_ARM_RESULT_IS_STOPPED_ALREADY);
1399 return; 1294 return;
1400 } 1295 }
1401 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1296 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1402 "Sending kill signal to service `%s', waiting for process to die.\n", 1297 "Sending kill signal to service `%s', waiting for process to die.\n",
1403 servicename); 1298 servicename);
1404 broadcast_status (servicename, 1299 broadcast_status (servicename, GNUNET_ARM_SERVICE_STOPPING, NULL);
1405 GNUNET_ARM_SERVICE_STOPPING,
1406 NULL);
1407 /* no signal_start - only when it's STOPPED */ 1300 /* no signal_start - only when it's STOPPED */
1408 sl->killed_at = GNUNET_TIME_absolute_get (); 1301 sl->killed_at = GNUNET_TIME_absolute_get ();
1409 if (0 != GNUNET_OS_process_kill (sl->proc, 1302 if (0 != GNUNET_OS_process_kill (sl->proc, GNUNET_TERM_SIG))
1410 GNUNET_TERM_SIG)) 1303 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
1411 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
1412 "kill");
1413 sl->killing_client = client; 1304 sl->killing_client = client;
1414 sl->killing_client_request_id = request_id; 1305 sl->killing_client_request_id = request_id;
1415} 1306}
@@ -1422,8 +1313,7 @@ handle_stop (void *cls,
1422 * @param message the actual message 1313 * @param message the actual message
1423 */ 1314 */
1424static void 1315static void
1425handle_list (void *cls, 1316handle_list (void *cls, const struct GNUNET_ARM_Message *request)
1426 const struct GNUNET_ARM_Message *request)
1427{ 1317{
1428 struct GNUNET_SERVICE_Client *client = cls; 1318 struct GNUNET_SERVICE_Client *client = cls;
1429 struct GNUNET_MQ_Envelope *env; 1319 struct GNUNET_MQ_Envelope *env;
@@ -1461,16 +1351,11 @@ handle_list (void *cls,
1461 if (NULL != sl->proc) 1351 if (NULL != sl->proc)
1462 { 1352 {
1463 size_t s = strlen (sl->name) + strlen (sl->binary) + 4; 1353 size_t s = strlen (sl->name) + strlen (sl->binary) + 4;
1464 GNUNET_snprintf (pos, 1354 GNUNET_snprintf (pos, s, "%s (%s)", sl->name, sl->binary);
1465 s,
1466 "%s (%s)",
1467 sl->name,
1468 sl->binary);
1469 pos += s; 1355 pos += s;
1470 } 1356 }
1471 } 1357 }
1472 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), 1358 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env);
1473 env);
1474 GNUNET_SERVICE_client_continue (client); 1359 GNUNET_SERVICE_client_continue (client);
1475} 1360}
1476 1361
@@ -1482,18 +1367,15 @@ handle_list (void *cls,
1482 * @param message the actual message 1367 * @param message the actual message
1483 */ 1368 */
1484static void 1369static void
1485handle_test (void *cls, 1370handle_test (void *cls, const struct GNUNET_MessageHeader *message)
1486 const struct GNUNET_MessageHeader *message)
1487{ 1371{
1488 struct GNUNET_SERVICE_Client *client = cls; 1372 struct GNUNET_SERVICE_Client *client = cls;
1489 struct GNUNET_MQ_Envelope *env; 1373 struct GNUNET_MQ_Envelope *env;
1490 struct GNUNET_MessageHeader *msg; 1374 struct GNUNET_MessageHeader *msg;
1491 1375
1492 (void) message; 1376 (void) message;
1493 env = GNUNET_MQ_msg (msg, 1377 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_ARM_TEST);
1494 GNUNET_MESSAGE_TYPE_ARM_TEST); 1378 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env);
1495 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
1496 env);
1497 GNUNET_SERVICE_client_continue (client); 1379 GNUNET_SERVICE_client_continue (client);
1498} 1380}
1499 1381
@@ -1505,8 +1387,7 @@ handle_test (void *cls,
1505static void 1387static void
1506do_shutdown () 1388do_shutdown ()
1507{ 1389{
1508 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1390 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Last shutdown phase\n");
1509 "Last shutdown phase\n");
1510 if (NULL != notifier) 1391 if (NULL != notifier)
1511 { 1392 {
1512 GNUNET_notification_context_destroy (notifier); 1393 GNUNET_notification_context_destroy (notifier);
@@ -1538,9 +1419,7 @@ list_count (struct ServiceList *running_head)
1538 unsigned int res; 1419 unsigned int res;
1539 1420
1540 for (res = 0, i = running_head; NULL != i; i = i->next, res++) 1421 for (res = 0, i = running_head; NULL != i; i = i->next, res++)
1541 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1422 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%s\n", i->name);
1542 "%s\n",
1543 i->name);
1544 return res; 1423 return res;
1545} 1424}
1546 1425
@@ -1558,8 +1437,7 @@ shutdown_task (void *cls)
1558 struct ServiceListeningInfo *sli; 1437 struct ServiceListeningInfo *sli;
1559 1438
1560 (void) cls; 1439 (void) cls;
1561 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1440 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "First shutdown phase\n");
1562 "First shutdown phase\n");
1563 if (NULL != child_restart_task) 1441 if (NULL != child_restart_task)
1564 { 1442 {
1565 GNUNET_SCHEDULER_cancel (child_restart_task); 1443 GNUNET_SCHEDULER_cancel (child_restart_task);
@@ -1571,9 +1449,7 @@ shutdown_task (void *cls)
1571 { 1449 {
1572 while (NULL != (sli = pos->listen_head)) 1450 while (NULL != (sli = pos->listen_head))
1573 { 1451 {
1574 GNUNET_CONTAINER_DLL_remove (pos->listen_head, 1452 GNUNET_CONTAINER_DLL_remove (pos->listen_head, pos->listen_tail, sli);
1575 pos->listen_tail,
1576 sli);
1577 if (NULL != sli->accept_task) 1453 if (NULL != sli->accept_task)
1578 { 1454 {
1579 GNUNET_SCHEDULER_cancel (sli->accept_task); 1455 GNUNET_SCHEDULER_cancel (sli->accept_task);
@@ -1592,14 +1468,10 @@ shutdown_task (void *cls)
1592 nxt = pos->next; 1468 nxt = pos->next;
1593 if (NULL != pos->proc) 1469 if (NULL != pos->proc)
1594 { 1470 {
1595 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1471 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stopping service `%s'\n", pos->name);
1596 "Stopping service `%s'\n",
1597 pos->name);
1598 pos->killed_at = GNUNET_TIME_absolute_get (); 1472 pos->killed_at = GNUNET_TIME_absolute_get ();
1599 if (0 != GNUNET_OS_process_kill (pos->proc, 1473 if (0 != GNUNET_OS_process_kill (pos->proc, GNUNET_TERM_SIG))
1600 GNUNET_TERM_SIG)) 1474 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
1601 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
1602 "kill");
1603 } 1475 }
1604 else 1476 else
1605 { 1477 {
@@ -1611,8 +1483,8 @@ shutdown_task (void *cls)
1611 do_shutdown (); 1483 do_shutdown ();
1612 else 1484 else
1613 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1485 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1614 "Delaying shutdown, have %u childs still running\n", 1486 "Delaying shutdown, have %u childs still running\n",
1615 list_count (running_head)); 1487 list_count (running_head));
1616} 1488}
1617 1489
1618 1490
@@ -1646,48 +1518,47 @@ delayed_restart_task (void *cls)
1646 /* restart is now allowed */ 1518 /* restart is now allowed */
1647 if (sl->force_start) 1519 if (sl->force_start)
1648 { 1520 {
1649 /* process should run by default, start immediately */ 1521 /* process should run by default, start immediately */
1650 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1522 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1651 _("Restarting service `%s'.\n"), 1523 _ ("Restarting service `%s'.\n"),
1652 sl->name); 1524 sl->name);
1653 start_process (sl, 1525 start_process (sl, NULL, 0);
1654 NULL,
1655 0);
1656 } 1526 }
1657 else 1527 else
1658 { 1528 {
1659 /* process is run on-demand, ensure it is re-started if there is demand */ 1529 /* process is run on-demand, ensure it is re-started if there is demand */
1660 for (sli = sl->listen_head; NULL != sli; sli = sli->next) 1530 for (sli = sl->listen_head; NULL != sli; sli = sli->next)
1661 if (NULL == sli->accept_task) 1531 if (NULL == sli->accept_task)
1662 { 1532 {
1663 /* accept was actually paused, so start it again */ 1533 /* accept was actually paused, so start it again */
1664 sli->accept_task 1534 sli->accept_task =
1665 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 1535 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
1666 sli->listen_socket, 1536 sli->listen_socket,
1667 &accept_connection, 1537 &accept_connection,
1668 sli); 1538 sli);
1669 } 1539 }
1670 } 1540 }
1671 } 1541 }
1672 else 1542 else
1673 { 1543 {
1674 /* update calculation for earliest time to reactivate a service */ 1544 /* update calculation for earliest time to reactivate a service */
1675 lowestRestartDelay = 1545 lowestRestartDelay =
1676 GNUNET_TIME_relative_min (lowestRestartDelay, 1546 GNUNET_TIME_relative_min (lowestRestartDelay,
1677 GNUNET_TIME_absolute_get_remaining 1547 GNUNET_TIME_absolute_get_remaining (
1678 (sl->restart_at)); 1548 sl->restart_at));
1679 } 1549 }
1680 } 1550 }
1681 if (lowestRestartDelay.rel_value_us != GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) 1551 if (lowestRestartDelay.rel_value_us !=
1552 GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1682 { 1553 {
1683 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1554 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1684 "Will restart process in %s\n", 1555 "Will restart process in %s\n",
1685 GNUNET_STRINGS_relative_time_to_string (lowestRestartDelay, 1556 GNUNET_STRINGS_relative_time_to_string (lowestRestartDelay,
1686 GNUNET_YES)); 1557 GNUNET_YES));
1687 child_restart_task = 1558 child_restart_task =
1688 GNUNET_SCHEDULER_add_delayed_with_priority (lowestRestartDelay, 1559 GNUNET_SCHEDULER_add_delayed_with_priority (lowestRestartDelay,
1689 GNUNET_SCHEDULER_PRIORITY_IDLE, 1560 GNUNET_SCHEDULER_PRIORITY_IDLE,
1690 &delayed_restart_task, 1561 &delayed_restart_task,
1691 NULL); 1562 NULL);
1692 } 1563 }
1693} 1564}
@@ -1714,13 +1585,10 @@ maint_child_death (void *cls)
1714 const struct GNUNET_DISK_FileHandle *pr; 1585 const struct GNUNET_DISK_FileHandle *pr;
1715 1586
1716 (void) cls; 1587 (void) cls;
1717 pr = GNUNET_DISK_pipe_handle (sigpipe, 1588 pr = GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ);
1718 GNUNET_DISK_PIPE_END_READ);
1719 child_death_task = NULL; 1589 child_death_task = NULL;
1720 /* consume the signal */ 1590 /* consume the signal */
1721 GNUNET_break (0 < GNUNET_DISK_file_read (pr, 1591 GNUNET_break (0 < GNUNET_DISK_file_read (pr, &c, sizeof (c)));
1722 &c,
1723 sizeof (c)));
1724 1592
1725 /* check for services that died (WAITPID) */ 1593 /* check for services that died (WAITPID) */
1726 next = running_head; 1594 next = running_head;
@@ -1743,10 +1611,7 @@ maint_child_death (void *cls)
1743 pid_t pid; 1611 pid_t pid;
1744 1612
1745 pid = GNUNET_OS_process_get_pid (pos->proc); 1613 pid = GNUNET_OS_process_get_pid (pos->proc);
1746 ret = wait4 (pid, 1614 ret = wait4 (pid, &status, WNOHANG, &ru);
1747 &status,
1748 WNOHANG,
1749 &ru);
1750 if (ret <= 0) 1615 if (ret <= 0)
1751 continue; /* no process done */ 1616 continue; /* no process done */
1752 if (WIFEXITED (status)) 1617 if (WIFEXITED (status))
@@ -1776,8 +1641,8 @@ maint_child_death (void *cls)
1776 statusType = GNUNET_OS_PROCESS_UNKNOWN; 1641 statusType = GNUNET_OS_PROCESS_UNKNOWN;
1777 statusCode = 0; 1642 statusCode = 0;
1778 } 1643 }
1779 if ( (GNUNET_OS_PROCESS_EXITED == statusType) || 1644 if ((GNUNET_OS_PROCESS_EXITED == statusType) ||
1780 (GNUNET_OS_PROCESS_SIGNALED == statusType) ) 1645 (GNUNET_OS_PROCESS_SIGNALED == statusType))
1781 { 1646 {
1782 double utime = ru.ru_utime.tv_sec + (ru.ru_utime.tv_usec / 10e6); 1647 double utime = ru.ru_utime.tv_sec + (ru.ru_utime.tv_usec / 10e6);
1783 double stime = ru.ru_stime.tv_sec + (ru.ru_stime.tv_usec / 10e6); 1648 double stime = ru.ru_stime.tv_sec + (ru.ru_stime.tv_usec / 10e6);
@@ -1796,48 +1661,45 @@ maint_child_death (void *cls)
1796 } 1661 }
1797 else /* continue with JUST this "if" as "else" (intentionally no brackets!) */ 1662 else /* continue with JUST this "if" as "else" (intentionally no brackets!) */
1798#endif 1663#endif
1799 if ( (GNUNET_SYSERR == 1664 if ((GNUNET_SYSERR == (ret = GNUNET_OS_process_status (pos->proc,
1800 (ret = 1665 &statusType,
1801 GNUNET_OS_process_status (pos->proc, 1666 &statusCode))) ||
1802 &statusType, 1667 (ret == GNUNET_NO) || (statusType == GNUNET_OS_PROCESS_STOPPED) ||
1803 &statusCode))) || 1668 (statusType == GNUNET_OS_PROCESS_UNKNOWN) ||
1804 (ret == GNUNET_NO) || 1669 (statusType == GNUNET_OS_PROCESS_RUNNING))
1805 (statusType == GNUNET_OS_PROCESS_STOPPED) ||
1806 (statusType == GNUNET_OS_PROCESS_UNKNOWN) ||
1807 (statusType == GNUNET_OS_PROCESS_RUNNING) )
1808 continue; 1670 continue;
1809 1671
1810 if (statusType == GNUNET_OS_PROCESS_EXITED) 1672 if (statusType == GNUNET_OS_PROCESS_EXITED)
1811 { 1673 {
1812 statstr = _( /* process termination method */ "exit"); 1674 statstr = _ (/* process termination method */ "exit");
1813 statcode = statusCode; 1675 statcode = statusCode;
1814 } 1676 }
1815 else if (statusType == GNUNET_OS_PROCESS_SIGNALED) 1677 else if (statusType == GNUNET_OS_PROCESS_SIGNALED)
1816 { 1678 {
1817 statstr = _( /* process termination method */ "signal"); 1679 statstr = _ (/* process termination method */ "signal");
1818 statcode = statusCode; 1680 statcode = statusCode;
1819 } 1681 }
1820 else 1682 else
1821 { 1683 {
1822 statstr = _( /* process termination method */ "unknown"); 1684 statstr = _ (/* process termination method */ "unknown");
1823 statcode = 0; 1685 statcode = 0;
1824 } 1686 }
1825 if (0 != pos->killed_at.abs_value_us) 1687 if (0 != pos->killed_at.abs_value_us)
1826 { 1688 {
1827 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1689 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1828 _("Service `%s' took %s to terminate\n"), 1690 _ ("Service `%s' took %s to terminate\n"),
1829 pos->name, 1691 pos->name,
1830 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (pos->killed_at), 1692 GNUNET_STRINGS_relative_time_to_string (
1831 GNUNET_YES)); 1693 GNUNET_TIME_absolute_get_duration (pos->killed_at),
1694 GNUNET_YES));
1832 } 1695 }
1833 GNUNET_OS_process_destroy (pos->proc); 1696 GNUNET_OS_process_destroy (pos->proc);
1834 pos->proc = NULL; 1697 pos->proc = NULL;
1835 broadcast_status (pos->name, 1698 broadcast_status (pos->name, GNUNET_ARM_SERVICE_STOPPED, NULL);
1836 GNUNET_ARM_SERVICE_STOPPED,
1837 NULL);
1838 if (NULL != pos->killing_client) 1699 if (NULL != pos->killing_client)
1839 { 1700 {
1840 signal_result (pos->killing_client, pos->name, 1701 signal_result (pos->killing_client,
1702 pos->name,
1841 pos->killing_client_request_id, 1703 pos->killing_client_request_id,
1842 GNUNET_ARM_RESULT_STOPPED); 1704 GNUNET_ARM_RESULT_STOPPED);
1843 pos->killing_client = NULL; 1705 pos->killing_client = NULL;
@@ -1845,14 +1707,14 @@ maint_child_death (void *cls)
1845 } 1707 }
1846 if (GNUNET_YES != in_shutdown) 1708 if (GNUNET_YES != in_shutdown)
1847 { 1709 {
1848 if ( (statusType == GNUNET_OS_PROCESS_EXITED) && 1710 if ((statusType == GNUNET_OS_PROCESS_EXITED) && (statcode == 0))
1849 (statcode == 0) )
1850 { 1711 {
1851 /* process terminated normally, allow restart at any time */ 1712 /* process terminated normally, allow restart at any time */
1852 pos->restart_at.abs_value_us = 0; 1713 pos->restart_at.abs_value_us = 0;
1853 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1714 GNUNET_log (
1854 _("Service `%s' terminated normally, will restart at any time\n"), 1715 GNUNET_ERROR_TYPE_INFO,
1855 pos->name); 1716 _ ("Service `%s' terminated normally, will restart at any time\n"),
1717 pos->name);
1856 /* process can still be re-started on-demand, ensure it is re-started if there is demand */ 1718 /* process can still be re-started on-demand, ensure it is re-started if there is demand */
1857 for (sli = pos->listen_head; NULL != sli; sli = sli->next) 1719 for (sli = pos->listen_head; NULL != sli; sli = sli->next)
1858 { 1720 {
@@ -1866,36 +1728,37 @@ maint_child_death (void *cls)
1866 } 1728 }
1867 else 1729 else
1868 { 1730 {
1869 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1731 GNUNET_log (
1870 _("Service `%s' terminated with status %s/%d, will restart in %s\n"), 1732 GNUNET_ERROR_TYPE_INFO,
1871 pos->name, 1733 _ ("Service `%s' terminated with status %s/%d, will restart in %s\n"),
1872 statstr, 1734 pos->name,
1873 statcode, 1735 statstr,
1874 GNUNET_STRINGS_relative_time_to_string (pos->backoff, 1736 statcode,
1875 GNUNET_YES)); 1737 GNUNET_STRINGS_relative_time_to_string (pos->backoff, GNUNET_YES));
1876 { 1738 {
1877 /* Reduce backoff based on runtime of the process, 1739 /* Reduce backoff based on runtime of the process,
1878 so that there is a cool-down if a process actually 1740 so that there is a cool-down if a process actually
1879 runs for a while. */ 1741 runs for a while. */
1880 struct GNUNET_TIME_Relative runtime; 1742 struct GNUNET_TIME_Relative runtime;
1881 unsigned int minutes; 1743 unsigned int minutes;
1882 1744
1883 runtime = GNUNET_TIME_absolute_get_duration (pos->restart_at); 1745 runtime = GNUNET_TIME_absolute_get_duration (pos->restart_at);
1884 minutes = runtime.rel_value_us / GNUNET_TIME_UNIT_MINUTES.rel_value_us; 1746 minutes =
1885 if (minutes > 31) 1747 runtime.rel_value_us / GNUNET_TIME_UNIT_MINUTES.rel_value_us;
1886 pos->backoff = GNUNET_TIME_UNIT_ZERO; 1748 if (minutes > 31)
1887 else 1749 pos->backoff = GNUNET_TIME_UNIT_ZERO;
1888 pos->backoff.rel_value_us <<= minutes; 1750 else
1889 } 1751 pos->backoff.rel_value_us <<= minutes;
1890 /* schedule restart */ 1752 }
1753 /* schedule restart */
1891 pos->restart_at = GNUNET_TIME_relative_to_absolute (pos->backoff); 1754 pos->restart_at = GNUNET_TIME_relative_to_absolute (pos->backoff);
1892 pos->backoff = GNUNET_TIME_STD_BACKOFF (pos->backoff); 1755 pos->backoff = GNUNET_TIME_STD_BACKOFF (pos->backoff);
1893 if (NULL != child_restart_task) 1756 if (NULL != child_restart_task)
1894 GNUNET_SCHEDULER_cancel (child_restart_task); 1757 GNUNET_SCHEDULER_cancel (child_restart_task);
1895 child_restart_task 1758 child_restart_task =
1896 = GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE, 1759 GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE,
1897 &delayed_restart_task, 1760 &delayed_restart_task,
1898 NULL); 1761 NULL);
1899 } 1762 }
1900 } 1763 }
1901 else 1764 else
@@ -1903,17 +1766,17 @@ maint_child_death (void *cls)
1903 free_service (pos); 1766 free_service (pos);
1904 } 1767 }
1905 } 1768 }
1906 child_death_task = GNUNET_SCHEDULER_add_read_file ( 1769 child_death_task =
1907 GNUNET_TIME_UNIT_FOREVER_REL, 1770 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
1908 pr, 1771 pr,
1909 &maint_child_death, NULL); 1772 &maint_child_death,
1773 NULL);
1910 if ((NULL == running_head) && (GNUNET_YES == in_shutdown)) 1774 if ((NULL == running_head) && (GNUNET_YES == in_shutdown))
1911 do_shutdown (); 1775 do_shutdown ();
1912 else if (GNUNET_YES == in_shutdown) 1776 else if (GNUNET_YES == in_shutdown)
1913 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1777 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1914 "Delaying shutdown after child's death, still have %u children\n", 1778 "Delaying shutdown after child's death, still have %u children\n",
1915 list_count (running_head)); 1779 list_count (running_head));
1916
1917} 1780}
1918 1781
1919 1782
@@ -1925,14 +1788,15 @@ static void
1925sighandler_child_death () 1788sighandler_child_death ()
1926{ 1789{
1927 static char c; 1790 static char c;
1928 int old_errno = errno; /* back-up errno */ 1791 int old_errno = errno; /* back-up errno */
1929 1792
1930 GNUNET_break (1 == 1793 GNUNET_break (
1931 GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle (sigpipe, 1794 1 ==
1932 GNUNET_DISK_PIPE_END_WRITE), 1795 GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle (sigpipe,
1933 &c, 1796 GNUNET_DISK_PIPE_END_WRITE),
1934 sizeof (c))); 1797 &c,
1935 errno = old_errno; /* restore errno */ 1798 sizeof (c)));
1799 errno = old_errno; /* restore errno */
1936} 1800}
1937 1801
1938 1802
@@ -1945,8 +1809,7 @@ sighandler_child_death ()
1945 * @return #GNUNET_OK (continue) 1809 * @return #GNUNET_OK (continue)
1946 */ 1810 */
1947static void 1811static void
1948setup_service (void *cls, 1812setup_service (void *cls, const char *section)
1949 const char *section)
1950{ 1813{
1951 struct ServiceList *sl; 1814 struct ServiceList *sl;
1952 char *binary; 1815 char *binary;
@@ -1957,26 +1820,18 @@ setup_service (void *cls,
1957 int ret; 1820 int ret;
1958 1821
1959 (void) cls; 1822 (void) cls;
1960 if (0 == strcasecmp (section, 1823 if (0 == strcasecmp (section, "arm"))
1961 "arm"))
1962 return; 1824 return;
1963 if (GNUNET_OK != 1825 if (GNUNET_OK !=
1964 GNUNET_CONFIGURATION_get_value_string (cfg, 1826 GNUNET_CONFIGURATION_get_value_string (cfg, section, "BINARY", &binary))
1965 section,
1966 "BINARY",
1967 &binary))
1968 { 1827 {
1969 /* not a service section */ 1828 /* not a service section */
1970 return; 1829 return;
1971 } 1830 }
1972 if ((GNUNET_YES == 1831 if ((GNUNET_YES ==
1973 GNUNET_CONFIGURATION_have_value (cfg, 1832 GNUNET_CONFIGURATION_have_value (cfg, section, "RUN_PER_USER")) &&
1974 section,
1975 "RUN_PER_USER")) &&
1976 (GNUNET_YES == 1833 (GNUNET_YES ==
1977 GNUNET_CONFIGURATION_get_value_yesno (cfg, 1834 GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "RUN_PER_USER")))
1978 section,
1979 "RUN_PER_USER")))
1980 { 1835 {
1981 if (GNUNET_NO == start_user) 1836 if (GNUNET_NO == start_user)
1982 { 1837 {
@@ -2001,23 +1856,22 @@ setup_service (void *cls,
2001 return; 1856 return;
2002 } 1857 }
2003 config = NULL; 1858 config = NULL;
2004 if (( (GNUNET_OK != 1859 if (((GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg,
2005 GNUNET_CONFIGURATION_get_value_filename (cfg, 1860 section,
2006 section, 1861 "CONFIG",
2007 "CONFIG", 1862 &config)) &&
2008 &config)) && 1863 (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg,
2009 (GNUNET_OK != 1864 "PATHS",
2010 GNUNET_CONFIGURATION_get_value_filename (cfg, 1865 "DEFAULTCONFIG",
2011 "PATHS", 1866 &config))) ||
2012 "DEFAULTCONFIG", 1867 (0 != stat (config, &sbuf)))
2013 &config)) ) ||
2014 (0 != STAT (config, &sbuf)))
2015 { 1868 {
2016 if (NULL != config) 1869 if (NULL != config)
2017 { 1870 {
2018 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING, 1871 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
2019 section, "CONFIG", 1872 section,
2020 STRERROR (errno)); 1873 "CONFIG",
1874 strerror (errno));
2021 GNUNET_free (config); 1875 GNUNET_free (config);
2022 config = NULL; 1876 config = NULL;
2023 } 1877 }
@@ -2031,46 +1885,30 @@ setup_service (void *cls,
2031#if WINDOWS 1885#if WINDOWS
2032 sl->pipe_control = GNUNET_YES; 1886 sl->pipe_control = GNUNET_YES;
2033#else 1887#else
2034 if (GNUNET_CONFIGURATION_have_value (cfg, 1888 if (GNUNET_CONFIGURATION_have_value (cfg, section, "PIPECONTROL"))
2035 section, 1889 sl->pipe_control =
2036 "PIPECONTROL")) 1890 GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "PIPECONTROL");
2037 sl->pipe_control = GNUNET_CONFIGURATION_get_value_yesno (cfg,
2038 section,
2039 "PIPECONTROL");
2040#endif 1891#endif
2041 GNUNET_CONTAINER_DLL_insert (running_head, 1892 GNUNET_CONTAINER_DLL_insert (running_head, running_tail, sl);
2042 running_tail,
2043 sl);
2044 if (GNUNET_YES == 1893 if (GNUNET_YES ==
2045 GNUNET_CONFIGURATION_get_value_yesno (cfg, 1894 GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "IMMEDIATE_START"))
2046 section,
2047 "IMMEDIATE_START"))
2048 { 1895 {
2049 sl->force_start = GNUNET_YES; 1896 sl->force_start = GNUNET_YES;
2050 if (GNUNET_YES == 1897 if (GNUNET_YES ==
2051 GNUNET_CONFIGURATION_get_value_yesno (cfg, 1898 GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "NOARMBIND"))
2052 section,
2053 "NOARMBIND"))
2054 return; 1899 return;
2055 } 1900 }
2056 else 1901 else
2057 { 1902 {
2058 if (GNUNET_YES != 1903 if (GNUNET_YES !=
2059 GNUNET_CONFIGURATION_get_value_yesno (cfg, 1904 GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "START_ON_DEMAND"))
2060 section,
2061 "START_ON_DEMAND"))
2062 return; 1905 return;
2063 } 1906 }
2064 if (0 >= (ret = get_server_addresses (section, 1907 if (0 >= (ret = get_server_addresses (section, cfg, &addrs, &addr_lens)))
2065 cfg,
2066 &addrs,
2067 &addr_lens)))
2068 return; 1908 return;
2069 /* this will free (or capture) addrs[i] */ 1909 /* this will free (or capture) addrs[i] */
2070 for (unsigned int i = 0; i < (unsigned int) ret; i++) 1910 for (unsigned int i = 0; i < (unsigned int) ret; i++)
2071 create_listen_socket (addrs[i], 1911 create_listen_socket (addrs[i], addr_lens[i], sl);
2072 addr_lens[i],
2073 sl);
2074 GNUNET_free (addrs); 1912 GNUNET_free (addrs);
2075 GNUNET_free (addr_lens); 1913 GNUNET_free (addr_lens);
2076} 1914}
@@ -2128,8 +1966,7 @@ client_disconnect_cb (void *cls,
2128 * #GNUNET_SYSERR to close it (signal serious error) 1966 * #GNUNET_SYSERR to close it (signal serious error)
2129 */ 1967 */
2130static void 1968static void
2131handle_monitor (void *cls, 1969handle_monitor (void *cls, const struct GNUNET_MessageHeader *message)
2132 const struct GNUNET_MessageHeader *message)
2133{ 1970{
2134 struct GNUNET_SERVICE_Client *client = cls; 1971 struct GNUNET_SERVICE_Client *client = cls;
2135 1972
@@ -2139,9 +1976,7 @@ handle_monitor (void *cls,
2139 /* Removal is handled by the server implementation, internally. */ 1976 /* Removal is handled by the server implementation, internally. */
2140 GNUNET_notification_context_add (notifier, 1977 GNUNET_notification_context_add (notifier,
2141 GNUNET_SERVICE_client_get_mq (client)); 1978 GNUNET_SERVICE_client_get_mq (client));
2142 broadcast_status ("arm", 1979 broadcast_status ("arm", GNUNET_ARM_SERVICE_MONITORING_STARTED, client);
2143 GNUNET_ARM_SERVICE_MONITORING_STARTED,
2144 client);
2145 GNUNET_SERVICE_client_continue (client); 1980 GNUNET_SERVICE_client_continue (client);
2146} 1981}
2147 1982
@@ -2163,14 +1998,12 @@ run (void *cls,
2163 (void) cls; 1998 (void) cls;
2164 cfg = c; 1999 cfg = c;
2165 service = serv; 2000 service = serv;
2166 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, 2001 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
2167 NULL); 2002 child_death_task = GNUNET_SCHEDULER_add_read_file (
2168 child_death_task = 2003 GNUNET_TIME_UNIT_FOREVER_REL,
2169 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 2004 GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ),
2170 GNUNET_DISK_pipe_handle (sigpipe, 2005 &maint_child_death,
2171 GNUNET_DISK_PIPE_END_READ), 2006 NULL);
2172 &maint_child_death,
2173 NULL);
2174#if HAVE_WAIT4 2007#if HAVE_WAIT4
2175 if (GNUNET_OK == 2008 if (GNUNET_OK ==
2176 GNUNET_CONFIGURATION_get_value_filename (cfg, 2009 GNUNET_CONFIGURATION_get_value_filename (cfg,
@@ -2178,8 +2011,7 @@ run (void *cls,
2178 "RESOURCE_DIAGNOSTICS", 2011 "RESOURCE_DIAGNOSTICS",
2179 &wait_filename)) 2012 &wait_filename))
2180 { 2013 {
2181 wait_file = fopen (wait_filename, 2014 wait_file = fopen (wait_filename, "w");
2182 "w");
2183 if (NULL == wait_file) 2015 if (NULL == wait_file)
2184 { 2016 {
2185 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, 2017 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
@@ -2188,49 +2020,39 @@ run (void *cls,
2188 } 2020 }
2189 } 2021 }
2190#endif 2022#endif
2191 if (GNUNET_OK != 2023 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg,
2192 GNUNET_CONFIGURATION_get_value_string (cfg, 2024 "ARM",
2193 "ARM", 2025 "GLOBAL_PREFIX",
2194 "GLOBAL_PREFIX", 2026 &prefix_command))
2195 &prefix_command))
2196 prefix_command = GNUNET_strdup (""); 2027 prefix_command = GNUNET_strdup ("");
2197 else 2028 else
2198 prefix_command = GNUNET_CONFIGURATION_expand_dollar (cfg, 2029 prefix_command = GNUNET_CONFIGURATION_expand_dollar (cfg, prefix_command);
2199 prefix_command); 2030 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg,
2200 if (GNUNET_OK != 2031 "ARM",
2201 GNUNET_CONFIGURATION_get_value_string (cfg, 2032 "GLOBAL_POSTFIX",
2202 "ARM", 2033 &final_option))
2203 "GLOBAL_POSTFIX",
2204 &final_option))
2205 final_option = GNUNET_strdup (""); 2034 final_option = GNUNET_strdup ("");
2206 else 2035 else
2207 final_option = GNUNET_CONFIGURATION_expand_dollar (cfg, 2036 final_option = GNUNET_CONFIGURATION_expand_dollar (cfg, final_option);
2208 final_option); 2037 start_user =
2209 start_user = GNUNET_CONFIGURATION_get_value_yesno (cfg, 2038 GNUNET_CONFIGURATION_get_value_yesno (cfg, "ARM", "START_USER_SERVICES");
2210 "ARM", 2039 start_system =
2211 "START_USER_SERVICES"); 2040 GNUNET_CONFIGURATION_get_value_yesno (cfg, "ARM", "START_SYSTEM_SERVICES");
2212 start_system = GNUNET_CONFIGURATION_get_value_yesno (cfg, 2041 if ((GNUNET_NO == start_user) && (GNUNET_NO == start_system))
2213 "ARM",
2214 "START_SYSTEM_SERVICES");
2215 if ( (GNUNET_NO == start_user) &&
2216 (GNUNET_NO == start_system) )
2217 { 2042 {
2218 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2043 GNUNET_log (
2219 "Please configure either START_USER_SERVICES or START_SYSTEM_SERVICES or both.\n"); 2044 GNUNET_ERROR_TYPE_ERROR,
2045 "Please configure either START_USER_SERVICES or START_SYSTEM_SERVICES or both.\n");
2220 GNUNET_SCHEDULER_shutdown (); 2046 GNUNET_SCHEDULER_shutdown ();
2221 global_ret = 1; 2047 global_ret = 1;
2222 return; 2048 return;
2223 } 2049 }
2224 GNUNET_CONFIGURATION_iterate_sections (cfg, 2050 GNUNET_CONFIGURATION_iterate_sections (cfg, &setup_service, NULL);
2225 &setup_service,
2226 NULL);
2227 2051
2228 /* start default services... */ 2052 /* start default services... */
2229 for (sl = running_head; NULL != sl; sl = sl->next) 2053 for (sl = running_head; NULL != sl; sl = sl->next)
2230 if (GNUNET_YES == sl->force_start) 2054 if (GNUNET_YES == sl->force_start)
2231 start_process (sl, 2055 start_process (sl, NULL, 0);
2232 NULL,
2233 0);
2234 notifier = GNUNET_notification_context_create (MAX_NOTIFY_QUEUE); 2056 notifier = GNUNET_notification_context_create (MAX_NOTIFY_QUEUE);
2235} 2057}
2236 2058
@@ -2243,52 +2065,45 @@ run (void *cls,
2243 * @return 0 ok, 1 on error 2065 * @return 0 ok, 1 on error
2244 */ 2066 */
2245int 2067int
2246main (int argc, 2068main (int argc, char *const *argv)
2247 char *const *argv)
2248{ 2069{
2249 struct GNUNET_SIGNAL_Context *shc_chld; 2070 struct GNUNET_SIGNAL_Context *shc_chld;
2250 struct GNUNET_MQ_MessageHandler handlers[] = { 2071 struct GNUNET_MQ_MessageHandler handlers[] =
2251 GNUNET_MQ_hd_var_size (start, 2072 {GNUNET_MQ_hd_var_size (start,
2252 GNUNET_MESSAGE_TYPE_ARM_START, 2073 GNUNET_MESSAGE_TYPE_ARM_START,
2253 struct GNUNET_ARM_Message, 2074 struct GNUNET_ARM_Message,
2254 NULL), 2075 NULL),
2255 GNUNET_MQ_hd_var_size (stop, 2076 GNUNET_MQ_hd_var_size (stop,
2256 GNUNET_MESSAGE_TYPE_ARM_STOP, 2077 GNUNET_MESSAGE_TYPE_ARM_STOP,
2257 struct GNUNET_ARM_Message, 2078 struct GNUNET_ARM_Message,
2258 NULL), 2079 NULL),
2259 GNUNET_MQ_hd_fixed_size (monitor, 2080 GNUNET_MQ_hd_fixed_size (monitor,
2260 GNUNET_MESSAGE_TYPE_ARM_MONITOR, 2081 GNUNET_MESSAGE_TYPE_ARM_MONITOR,
2261 struct GNUNET_MessageHeader, 2082 struct GNUNET_MessageHeader,
2262 NULL), 2083 NULL),
2263 GNUNET_MQ_hd_fixed_size (list, 2084 GNUNET_MQ_hd_fixed_size (list,
2264 GNUNET_MESSAGE_TYPE_ARM_LIST, 2085 GNUNET_MESSAGE_TYPE_ARM_LIST,
2265 struct GNUNET_ARM_Message, 2086 struct GNUNET_ARM_Message,
2266 NULL), 2087 NULL),
2267 GNUNET_MQ_hd_fixed_size (test, 2088 GNUNET_MQ_hd_fixed_size (test,
2268 GNUNET_MESSAGE_TYPE_ARM_TEST, 2089 GNUNET_MESSAGE_TYPE_ARM_TEST,
2269 struct GNUNET_MessageHeader, 2090 struct GNUNET_MessageHeader,
2270 NULL), 2091 NULL),
2271 GNUNET_MQ_handler_end () 2092 GNUNET_MQ_handler_end ()};
2272 }; 2093
2273 2094 sigpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO, GNUNET_NO);
2274 sigpipe = GNUNET_DISK_pipe (GNUNET_NO,
2275 GNUNET_NO,
2276 GNUNET_NO,
2277 GNUNET_NO);
2278 GNUNET_assert (NULL != sigpipe); 2095 GNUNET_assert (NULL != sigpipe);
2279 shc_chld = 2096 shc_chld =
2280 GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, 2097 GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, &sighandler_child_death);
2281 &sighandler_child_death); 2098 if (0 != GNUNET_SERVICE_run_ (argc,
2282 if (0 != 2099 argv,
2283 GNUNET_SERVICE_run_ (argc, 2100 "arm",
2284 argv, 2101 GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN,
2285 "arm", 2102 &run,
2286 GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN, 2103 &client_connect_cb,
2287 &run, 2104 &client_disconnect_cb,
2288 &client_connect_cb, 2105 NULL,
2289 &client_disconnect_cb, 2106 handlers))
2290 NULL,
2291 handlers))
2292 global_ret = 2; 2107 global_ret = 2;
2293#if HAVE_WAIT4 2108#if HAVE_WAIT4
2294 if (NULL != wait_file) 2109 if (NULL != wait_file)