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