move gnunet-timeout to src/util/, fix issues related to #5375
authorChristian Grothoff <christian@grothoff.org>
Sun, 1 Jul 2018 17:38:06 +0000 (19:38 +0200)
committerChristian Grothoff <christian@grothoff.org>
Sun, 1 Jul 2018 17:38:06 +0000 (19:38 +0200)
15 files changed:
contrib/Makefile.am
contrib/timeout_watchdog.c [deleted file]
contrib/timeout_watchdog_w32.c [deleted file]
doc/man/Makefile.am
doc/man/gnunet-gns.1
src/gns/gns_api.c
src/gns/gnunet-gns.c
src/gns/nss/nss_gns.c
src/gns/nss/nss_gns_query.c
src/gns/nss/nss_gns_query.h
src/identity/identity_api_lookup.c
src/util/Makefile.am
src/util/client.c
src/util/gnunet-timeout-w32.c [new file with mode: 0644]
src/util/gnunet-timeout.c [new file with mode: 0644]

index 158e439982ec0dc3b4309466a8f0f8714f9f0d64..eec3300b9bb58ddbea3bdd245ff138c10b914436 100644 (file)
@@ -5,17 +5,6 @@ tap32dir = $(pkgdatadir)/openvpn-tap32/tapw32/
 
 tap64dir = $(pkgdatadir)/openvpn-tap32/tapw64/
 
-noinst_PROGRAMS = \
- timeout_watchdog
-
-if !MINGW
-timeout_watchdog_SOURCES = \
- timeout_watchdog.c
-else
-timeout_watchdog_SOURCES = \
- timeout_watchdog_w32.c
-endif
-
 noinst_SCRIPTS = \
  scripts/terminate.py \
  scripts/pydiffer.py \
diff --git a/contrib/timeout_watchdog.c b/contrib/timeout_watchdog.c
deleted file mode 100644 (file)
index 70e840d..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
-     This file is part of GNUnet
-     Copyright (C) 2010 GNUnet e.V.
-
-     GNUnet is free software: you can redistribute it and/or modify it
-     under the terms of the GNU Affero General Public License as published
-     by the Free Software Foundation, either version 3 of the License, or
-     (at your option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     Affero General Public License for more details.
-    
-     You should have received a copy of the GNU Affero General Public License
-     along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/**
- * @file contrib/timeout_watchdog.c
- * @brief small tool starting a child process, waiting that it terminates or killing it after a given timeout period
- * @author Matthias Wachs
- */
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-static pid_t child;
-
-
-static void
-sigchld_handler (int val)
-{
-  int status = 0;
-  int ret = 0;
-
-  (void) val;
-  waitpid (child, &status, 0);
-  if (WIFEXITED (status) != 0)
-    {
-      ret = WEXITSTATUS (status);
-      printf ("Test process exited with result %u\n", ret);
-    }
-  if (WIFSIGNALED (status) != 0)
-    {
-      ret = WTERMSIG (status);
-      printf ("Test process was signaled %u\n", ret);
-    }
-  exit (ret);
-}
-
-
-static void
-sigint_handler (int val)
-{
-  kill (0, val);
-  exit (val);
-}
-
-
-int
-main (int argc,
-      char *argv[])
-{
-  int timeout = 0;
-  pid_t gpid = 0;
-
-  if (argc < 3)
-    {
-      printf
-       ("arg 1: timeout in sec., arg 2: executable, arg<n> arguments\n");
-      exit (1);
-    }
-
-  timeout = atoi (argv[1]);
-
-  if (timeout == 0)
-    timeout = 600;
-
-/* with getpgid() it does not compile, but getpgrp is the BSD version and working */
-  gpid = getpgrp ();
-
-  signal (SIGCHLD, sigchld_handler);
-  signal (SIGABRT, sigint_handler);
-  signal (SIGFPE, sigint_handler);
-  signal (SIGILL, sigint_handler);
-  signal (SIGINT, sigint_handler);
-  signal (SIGSEGV, sigint_handler);
-  signal (SIGTERM, sigint_handler);
-
-  child = fork ();
-  if (child == 0)
-    {
-      /*  int setpgrp(pid_t pid, pid_t pgid); is not working on this machine */
-      //setpgrp (0, pid_t gpid);
-      if (-1 != gpid)
-       setpgid (0, gpid);
-      execvp (argv[2], &argv[2]);
-      exit (1);
-    }
-  if (child > 0)
-    {
-      sleep (timeout);
-      printf ("Child processes were killed after timeout of %u seconds\n",
-             timeout);
-      kill (0, SIGTERM);
-      exit (1);
-    }
-  exit (1);
-}
-
-/* end of timeout_watchdog.c */
diff --git a/contrib/timeout_watchdog_w32.c b/contrib/timeout_watchdog_w32.c
deleted file mode 100644 (file)
index 901eb62..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
-     This file is part of GNUnet
-     Copyright (C) 2010 GNUnet e.V.
-
-     GNUnet is free software: you can redistribute it and/or modify it
-     under the terms of the GNU Affero General Public License as published
-     by the Free Software Foundation, either version 3 of the License, or
-     (at your option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     Affero General Public License for more details.
-    
-     You should have received a copy of the GNU Affero General Public License
-     along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/**
- * @file contrib/timeout_watchdog_w32.c
- * @brief small tool starting a child process, waiting that it terminates or killing it after a given timeout period
- * @author LRN
- */
-
-#include <windows.h>
-#include <sys/types.h>
-#include <stdio.h>
-
-int
-main (int argc, char *argv[])
-{
-  int i;
-  DWORD wait_result;
-  wchar_t *commandline;
-  wchar_t **wargv;
-  wchar_t *arg;
-  unsigned int cmdlen;
-  STARTUPINFOW start;
-  PROCESS_INFORMATION proc;
-
-  wchar_t wpath[MAX_PATH + 1];
-
-  wchar_t *pathbuf;
-  DWORD pathbuf_len, alloc_len;
-  wchar_t *ptr;
-  wchar_t *non_const_filename;
-  wchar_t *wcmd;
-  int wargc;
-  int timeout = 0;
-  ssize_t wrote;
-
-  HANDLE job;
-
-  if (argc < 3)
-    {
-      printf
-       ("arg 1: timeout in sec., arg 2: executable, arg<n> arguments\n");
-      exit (1);
-    }
-
-  timeout = atoi (argv[1]);
-
-  if (timeout == 0)
-    timeout = 600;
-
-  commandline =  GetCommandLineW ();
-  if (commandline == NULL)
-  {
-    printf ("Failed to get commandline: %lu\n", GetLastError ());
-    exit (2);
-  }
-
-  wargv = CommandLineToArgvW (commandline, &wargc);
-  if (wargv == NULL || wargc <= 1)
-  {
-    printf ("Failed to get parse commandline: %lu\n", GetLastError ());
-    exit (3);
-  }
-
-  job = CreateJobObject (NULL, NULL);
-  if (job == NULL)
-  {
-    printf ("Failed to create a job: %lu\n", GetLastError ());
-    exit (4);
-  }
-
-  pathbuf_len = GetEnvironmentVariableW (L"PATH", (wchar_t *) &pathbuf, 0);
-
-  alloc_len = pathbuf_len + 1;
-
-  pathbuf = malloc (alloc_len * sizeof (wchar_t));
-
-  ptr = pathbuf;
-
-  alloc_len = GetEnvironmentVariableW (L"PATH", ptr, pathbuf_len);
-
-  cmdlen = wcslen (wargv[2]);
-  if (cmdlen < 5 || wcscmp (&wargv[2][cmdlen - 4], L".exe") != 0)
-  {
-    non_const_filename = malloc (sizeof (wchar_t) * (cmdlen + 5));
-    swprintf (non_const_filename, cmdlen + 5, L"%S.exe", wargv[2]);
-  }
-  else
-  {
-    non_const_filename = wcsdup (wargv[2]);
-  }
-
-  /* Check that this is the full path. If it isn't, search. */
-  if (non_const_filename[1] == L':')
-    swprintf (wpath, sizeof (wpath) / sizeof (wchar_t), L"%S", non_const_filename);
-  else if (!SearchPathW
-           (pathbuf, non_const_filename, NULL, sizeof (wpath) / sizeof (wchar_t),
-            wpath, NULL))
-  {
-    printf ("Failed to get find executable: %lu\n", GetLastError ());
-    exit (5);
-  }
-  free (pathbuf);
-  free (non_const_filename);
-
-  cmdlen = wcslen (wpath) + 4;
-  i = 3;
-  while (NULL != (arg = wargv[i++]))
-    cmdlen += wcslen (arg) + 4;
-
-  wcmd = malloc (sizeof (wchar_t) * (cmdlen + 1));
-  wrote = 0;
-  i = 2;
-  while (NULL != (arg = wargv[i++]))
-  {
-    /* This is to escape trailing slash */
-    wchar_t arg_lastchar = arg[wcslen (arg) - 1];
-    if (wrote == 0)
-    {
-      wrote += swprintf (&wcmd[wrote], cmdlen + 1 - wrote, L"\"%S%S\" ", wpath,
-          arg_lastchar == L'\\' ? L"\\" : L"");
-    }
-    else
-    {
-      if (wcschr (arg, L' ') != NULL)
-        wrote += swprintf (&wcmd[wrote], cmdlen + 1 - wrote, L"\"%S%S\"%S", arg,
-            arg_lastchar == L'\\' ? L"\\" : L"", i == wargc ? L"" : L" ");
-      else
-        wrote += swprintf (&wcmd[wrote], cmdlen + 1 - wrote, L"%S%S%S", arg,
-            arg_lastchar == L'\\' ? L"\\" : L"", i == wargc ? L"" : L" ");
-    }
-  }
-
-  LocalFree (wargv);
-
-  memset (&start, 0, sizeof (start));
-  start.cb = sizeof (start);
-
-  if (!CreateProcessW (wpath, wcmd, NULL, NULL, TRUE, CREATE_SUSPENDED,
-       NULL, NULL, &start, &proc))
-  {
-    wprintf (L"Failed to get spawn process `%S' with arguments `%S': %lu\n", wpath, wcmd, GetLastError ());
-    exit (6);
-  }
-
-  AssignProcessToJobObject (job, proc.hProcess);
-
-  ResumeThread (proc.hThread);
-  CloseHandle (proc.hThread);
-
-  free (wcmd);
-
-  wait_result = WaitForSingleObject (proc.hProcess, timeout * 1000);
-  if (wait_result == WAIT_OBJECT_0)
-  {
-    DWORD status;
-    wait_result = GetExitCodeProcess (proc.hProcess, &status);
-    CloseHandle (proc.hProcess);
-    if (wait_result != 0)
-    {
-      printf ("Test process exited with result %lu\n", status);
-      TerminateJobObject (job, status);
-      exit (status);
-    }
-    printf ("Test process exited (failed to obtain exit status)\n");
-    TerminateJobObject (job, 0);
-    exit (0);
-  }
-  printf ("Child processes were killed after timeout of %u seconds\n",
-             timeout);
-  TerminateJobObject (job, 1);
-  CloseHandle (proc.hProcess);
-  exit (1);
-}
-
-/* end of timeout_watchdog_w32.c */
index a6a116dcac2d05f1844d32ea88ae45534e75417d..37f881d6038fdf3ae1cb7246eda670d70baa0150 100644 (file)
@@ -37,6 +37,7 @@ man_MANS = \
   gnunet-statistics.1 \
   gnunet-testbed-profiler.1 \
   gnunet-testing-run-service.1 \
+  gnunet-timeout.1 \
   gnunet-transport.1 \
   gnunet-transport-certificate-creation.1 \
   gnunet-unindex.1 \
index 9466dae0384428a5d85d4998c78c7fb61068f63f..9e448265345b9e0e9270d8902f0b8e6bbd69e61a 100644 (file)
@@ -46,7 +46,7 @@ Print GNUnet version number.
 .SH RETURN VALUE
 
 gnunet\-gns will return 0 on success, 1 on internal failures, 2 on
-launch failures, 3 if the given name is not configured to use GNS.
+launch failures, 4 if the given name is not configured to use GNS.
 
 
 .SH BUGS
index 0ec9209da80907e907545c0093663935218d5c9a..3b658da921805f1fdaafde66f4c7ead65b21d125 100644 (file)
@@ -11,7 +11,7 @@
      WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      Affero General Public License for more details.
-    
+
      You should have received a copy of the GNU Affero General Public License
      along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
@@ -232,7 +232,6 @@ reconnect (struct GNUNET_GNS_Handle *handle)
                            handle),
     GNUNET_MQ_handler_end ()
   };
-  struct GNUNET_GNS_LookupRequest *lh;
 
   GNUNET_assert (NULL == handle->mq);
   LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -244,7 +243,9 @@ reconnect (struct GNUNET_GNS_Handle *handle)
                                       handle);
   if (NULL == handle->mq)
     return;
-  for (lh = handle->lookup_head; NULL != lh; lh = lh->next)
+  for (struct GNUNET_GNS_LookupRequest *lh = handle->lookup_head;
+       NULL != lh;
+       lh = lh->next)
     GNUNET_MQ_send_copy (handle->mq,
                          lh->env);
 }
index 149c8a7bb0e94ef9b80832de93204c74415fa552..463348ed38bd7e9f63f6d1c179018ec727441cb2 100644 (file)
@@ -11,7 +11,7 @@
      WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      Affero General Public License for more details.
-    
+
      You should have received a copy of the GNU Affero General Public License
      along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
@@ -65,8 +65,9 @@ static struct GNUNET_GNS_LookupWithTldRequest *lr;
 /**
  * Global return value.
  * 0 on success (default),
- * 1 on internal failures, 2 on launch failure,
- * 3 if the name is not a GNS-supported TLD,
+ * 1 on internal failures
+ * 2 on launch failure,
+ * 4 if the name is not a GNS-supported TLD,
  */
 static int global_ret;
 
@@ -114,7 +115,7 @@ process_lookup_result (void *cls,
   lr = NULL;
   if (GNUNET_NO == was_gns)
   {
-    global_ret = 3;
+    global_ret = 4; /* not for GNS */
     GNUNET_SCHEDULER_shutdown ();
     return;
   }
@@ -183,7 +184,6 @@ run (void *cls,
     global_ret = 2;
     return;
   }
-
   GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
                                  NULL);
 
index 9c9233d35d86a03b32180da386fe39269fa9c6c3..58aab47fd5e7139a4047b80ff5f0ff16fde2076c 100644 (file)
  * @return a nss_status code
  */
 enum nss_status
-_nss_gns_gethostbyname2_r(
-    const char *name,
-    int af,
-    struct hostent * result,
-    char *buffer,
-    size_t buflen,
-    int *errnop,
-    int *h_errnop) {
-
-    struct userdata u;
-    enum nss_status status = NSS_STATUS_UNAVAIL;
-    int i;
-    size_t address_length, l, idx, astart;
-
-    if (af == AF_UNSPEC)
+_nss_gns_gethostbyname2_r(const char *name,
+                          int af,
+                          struct hostent *result,
+                          char *buffer,
+                          size_t buflen,
+                          int *errnop,
+                          int *h_errnop)
+{
+  struct userdata u;
+  enum nss_status status = NSS_STATUS_UNAVAIL;
+  int i;
+  size_t address_length;
+  size_t l;
+  size_t idx;
+  size_t astart;
+
+  if (af == AF_UNSPEC)
 #ifdef NSS_IPV6_ONLY
-        af = AF_INET6;
+    af = AF_INET6;
 #else
-        af = AF_INET;
+  af = AF_INET;
 #endif
 
 #ifdef NSS_IPV4_ONLY
-    if (af != AF_INET)
+  if (af != AF_INET)
 #elif NSS_IPV6_ONLY
-    if (af != AF_INET6)
+  if (af != AF_INET6)
 #else
-    if (af != AF_INET && af != AF_INET6)
+  if ( (af != AF_INET) &&
+       (af != AF_INET6) )
 #endif
-    {
-        *errnop = EINVAL;
-        *h_errnop = NO_RECOVERY;
-
-        goto finish;
-    }
-
-    address_length = af == AF_INET ? sizeof(ipv4_address_t) : sizeof(ipv6_address_t);
-    if (buflen <
-        sizeof(char*)+    /* alias names */
-        strlen(name)+1)  {   /* official name */
-
-        *errnop = ERANGE;
-        *h_errnop = NO_RECOVERY;
-        status = NSS_STATUS_TRYAGAIN;
-
-        goto finish;
-    }
-
-    u.count = 0;
-    u.data_len = 0;
-
-    i = gns_resolve_name(af, name, &u);
-    if (-3 == i)
-      {
-        status = NSS_STATUS_NOTFOUND;
-        goto finish;
-      }
-    if (-2 == i)
-      {
-        status = NSS_STATUS_UNAVAIL;
-        goto finish;
-      }
-    if ( (-1 == i) ||
-         (u.count == 0) )
-      {
-        *errnop = ETIMEDOUT;
-        *h_errnop = HOST_NOT_FOUND;
-        status = NSS_STATUS_NOTFOUND;
-        goto finish;
-      }
-
-
-    /* Alias names */
-    *((char**) buffer) = NULL;
-    result->h_aliases = (char**) buffer;
-    idx = sizeof(char*);
-
-    /* Official name */
-    strcpy(buffer+idx, name);
-    result->h_name = buffer+idx;
-    idx += strlen(name)+1;
-
-    ALIGN(idx);
-
-    result->h_addrtype = af;
-    result->h_length = address_length;
-
-    /* Check if there's enough space for the addresses */
-    if (buflen < idx+u.data_len+sizeof(char*)*(u.count+1)) {
-        *errnop = ERANGE;
-        *h_errnop = NO_RECOVERY;
-        status = NSS_STATUS_TRYAGAIN;
-        goto finish;
-    }
+  {
+    *errnop = EINVAL;
+    *h_errnop = NO_RECOVERY;
+
+    goto finish;
+  }
 
+  address_length = (af == AF_INET) ? sizeof(ipv4_address_t) : sizeof(ipv6_address_t);
+  if (buflen <
+      sizeof(char*)+    /* alias names */
+      strlen(name)+1)
+  {   /* official name */
+    *errnop = ERANGE;
+    *h_errnop = NO_RECOVERY;
+    status = NSS_STATUS_TRYAGAIN;
+
+    goto finish;
+  }
+  u.count = 0;
+  u.data_len = 0;
+  i = gns_resolve_name (af,
+                        name,
+                        &u);
+  if (-3 == i)
+  {
+    status = NSS_STATUS_NOTFOUND;
+    goto finish;
+  }
+  if (-2 == i)
+  {
+    status = NSS_STATUS_UNAVAIL;
+    goto finish;
+  }
+  if ( (-1 == i) ||
+       (u.count == 0) )
+  {
+    *errnop = ETIMEDOUT;
+    *h_errnop = HOST_NOT_FOUND;
+    status = NSS_STATUS_NOTFOUND;
+    goto finish;
+  }
+  /* Alias names */
+  *((char**) buffer) = NULL;
+  result->h_aliases = (char**) buffer;
+  idx = sizeof(char*);
+
+  /* Official name */
+  strcpy (buffer+idx,
+          name);
+  result->h_name = buffer+idx;
+  idx += strlen (name)+1;
+
+  ALIGN(idx);
+
+  result->h_addrtype = af;
+  result->h_length = address_length;
+
+  /* Check if there's enough space for the addresses */
+  if (buflen < idx+u.data_len+sizeof(char*)*(u.count+1))
+  {
+    *errnop = ERANGE;
+    *h_errnop = NO_RECOVERY;
+    status = NSS_STATUS_TRYAGAIN;
+    goto finish;
+  }
     /* Addresses */
-    astart = idx;
-    l = u.count*address_length;
-    if (0 != l)
-      memcpy(buffer+astart, &u.data, l);
-    /* address_length is a multiple of 32bits, so idx is still aligned
-     * correctly */
-    idx += l;
-
-    /* Address array address_length is always a multiple of 32bits */
-    for (i = 0; i < u.count; i++)
-        ((char**) (buffer+idx))[i] = buffer+astart+address_length*i;
-    ((char**) (buffer+idx))[i] = NULL;
-    result->h_addr_list = (char**) (buffer+idx);
-
-    status = NSS_STATUS_SUCCESS;
+  astart = idx;
+  l = u.count*address_length;
+  if (0 != l)
+    memcpy (buffer+astart,
+            &u.data,
+            l);
+  /* address_length is a multiple of 32bits, so idx is still aligned
+   * correctly */
+  idx += l;
+
+  /* Address array address_length is always a multiple of 32bits */
+  for (i = 0; i < u.count; i++)
+    ((char**) (buffer+idx))[i] = buffer+astart+address_length*i;
+  ((char**) (buffer+idx))[i] = NULL;
+  result->h_addr_list = (char**) (buffer+idx);
+
+  status = NSS_STATUS_SUCCESS;
 
 finish:
-    return status;
+  return status;
 }
 
+
 /**
  * The gethostbyname hook executed by nsswitch
  *
@@ -176,29 +181,28 @@ finish:
  * @param result the result hostent
  * @param buffer the result buffer
  * @param buflen length of the buffer
- * @param errnop idk
+ * @param errnop[out] the low-level error code to return to the application
  * @param h_errnop idk
  * @return a nss_status code
  */
 enum nss_status
-_nss_gns_gethostbyname_r (
-    const char *name,
-    struct hostent *result,
-    char *buffer,
-    size_t buflen,
-    int *errnop,
-    int *h_errnop) {
-
-    return _nss_gns_gethostbyname2_r(
-        name,
-        AF_UNSPEC,
-        result,
-        buffer,
-        buflen,
-        errnop,
-        h_errnop);
+_nss_gns_gethostbyname_r (const char *name,
+                          struct hostent *result,
+                          char *buffer,
+                          size_t buflen,
+                          int *errnop,
+                          int *h_errnop)
+{
+  return _nss_gns_gethostbyname2_r (name,
+                                    AF_UNSPEC,
+                                    result,
+                                    buffer,
+                                    buflen,
+                                    errnop,
+                                    h_errnop);
 }
 
+
 /**
  * The gethostbyaddr hook executed by nsswitch
  * We can't do this so we always return NSS_STATUS_UNAVAIL
@@ -209,23 +213,22 @@ _nss_gns_gethostbyname_r (
  * @param result the result hostent
  * @param buffer the result buffer
  * @param buflen length of the buffer
- * @param errnop idk
+ * @param errnop[out] the low-level error code to return to the application
  * @param h_errnop idk
  * @return NSS_STATUS_UNAVAIL
  */
 enum nss_status
-_nss_gns_gethostbyaddr_r(
-    const void* addr,
-    int len,
-    int af,
-    struct hostent *result,
-    char *buffer,
-    size_t buflen,
-    int *errnop,
-    int *h_errnop) {
-
-    *errnop = EINVAL;
-    *h_errnop = NO_RECOVERY;
-    //NOTE we allow to leak this into DNS so no NOTFOUND
-    return NSS_STATUS_UNAVAIL;
+_nss_gns_gethostbyaddr_r (const void* addr,
+                          int len,
+                          int af,
+                          struct hostent *result,
+                          char *buffer,
+                          size_t buflen,
+                          int *errnop,
+                          int *h_errnop)
+{
+  *errnop = EINVAL;
+  *h_errnop = NO_RECOVERY;
+  //NOTE we allow to leak this into DNS so no NOTFOUND
+  return NSS_STATUS_UNAVAIL;
 }
index 094e25ed53f4331c2f220d553b313fde7aea8e45..867ead6247b6be9da5101c60ee886cee853e4331 100644 (file)
@@ -11,7 +11,7 @@
      WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      Affero General Public License for more details.
-    
+
      You should have received a copy of the GNU Affero General Public License
      along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
@@ -48,14 +48,16 @@ gns_resolve_name (int af,
   {
     if (-1 == asprintf (&cmd,
                        "%s -t AAAA -u %s\n",
-                       "gnunet-gns -r", name))
+                       "gnunet-gns -r",
+                        name))
       return -1;
   }
   else
   {
     if (-1 == asprintf (&cmd,
                        "%s %s\n",
-                       "gnunet-gns -r -u", name))
+                       "gnunet-gns -r -u",
+                        name))
       return -1;
   }
   if (NULL == (p = popen (cmd, "r")))
@@ -63,7 +65,9 @@ gns_resolve_name (int af,
     free (cmd);
     return -1;
   }
-  while (NULL != fgets (line, sizeof(line), p))
+  while (NULL != fgets (line,
+                        sizeof(line),
+                        p))
   {
     if (u->count >= MAX_ENTRIES)
       break;
@@ -72,7 +76,9 @@ gns_resolve_name (int af,
       line[strlen(line)-1] = '\0';
       if (AF_INET == af)
       {
-       if (inet_pton(af, line, &(u->data.ipv4[u->count])))
+       if (inet_pton(af,
+                      line,
+                      &u->data.ipv4[u->count]))
         {
          u->count++;
          u->data_len += sizeof(ipv4_address_t);
@@ -86,7 +92,9 @@ gns_resolve_name (int af,
       }
       else if (AF_INET6 == af)
       {
-       if (inet_pton(af, line, &(u->data.ipv6[u->count])))
+       if (inet_pton(af,
+                      line,
+                      &u->data.ipv6[u->count]))
         {
          u->count++;
          u->data_len += sizeof(ipv6_address_t);
@@ -105,7 +113,10 @@ gns_resolve_name (int af,
   if (4 == ret)
     return -2; /* not for GNS */
   if (3 == ret)
-    return -3; /* timeout */
+    return -3; /* timeout -> not found */
+  if ( (2 == ret) || (1 == ret) )
+    return -2; /* launch failure -> service unavailable */
   return 0;
 }
+
 /* end of nss_gns_query.c */
index bb04f900499171bd66fc85aa37d2617f36f22469..48cab4b224ac55b69df9144223fe3bd1abb0b0ae 100644 (file)
@@ -11,7 +11,7 @@
      WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      Affero General Public License for more details.
-    
+
      You should have received a copy of the GNU Affero General Public License
      along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 /* Maximum number of entries to return */
 #define MAX_ENTRIES 16
 
-typedef struct {
-    uint32_t address;
+typedef struct
+{
+  uint32_t address;
 } ipv4_address_t;
 
-typedef struct {
-    uint8_t address[16];
+
+typedef struct
+{
+  uint8_t address[16];
 } ipv6_address_t;
 
 
-struct userdata {
+struct userdata
+{
   int count;
   int data_len; /* only valid when doing reverse lookup */
   union  {
-      ipv4_address_t ipv4[MAX_ENTRIES];
-      ipv6_address_t ipv6[MAX_ENTRIES];
-      char *name[MAX_ENTRIES];
+    ipv4_address_t ipv4[MAX_ENTRIES];
+    ipv6_address_t ipv6[MAX_ENTRIES];
+    char *name[MAX_ENTRIES];
   } data;
 };
 
+
 /**
  * Wrapper function that uses gnunet-gns cli tool to resolve
  * an IPv4/6 address.
@@ -54,8 +59,9 @@ struct userdata {
  * @param u the userdata (result struct)
  * @return -1 on error else 0
  */
-int gns_resolve_name(int af,
-               const char *name,
-               struct userdata *userdata);
+int
+gns_resolve_name(int af,
+                 const char *name,
+                 struct userdata *userdata);
 
 #endif
index 593a5dbb06963dbbb9216debd420c9296e415bf9..25aec8edebec6540445ddedf2a54a2adbbf9d7c3 100644 (file)
@@ -11,7 +11,7 @@
      WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      Affero General Public License for more details.
-    
+
      You should have received a copy of the GNU Affero General Public License
      along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
@@ -131,6 +131,12 @@ GNUNET_IDENTITY_ego_lookup (const struct GNUNET_CONFIGURATION_Handle *cfg,
   el->identity = GNUNET_IDENTITY_connect (cfg,
                                          &identity_cb,
                                          el);
+  if (NULL == el->identity)
+  {
+    GNUNET_free (el->name);
+    GNUNET_free (el);
+    return NULL;
+  }
   return el;
 }
 
index ec7bcb016facbd2b4c44b85a3685db99be33f72c..4ae073c2ccb5210a07a1348dea6a9883955d492a 100644 (file)
@@ -166,6 +166,7 @@ lib_LTLIBRARIES = libgnunetutil.la
 
 libexec_PROGRAMS = \
  gnunet-service-resolver \
+ gnunet-timeout \
  $(W32CONSOLEHELPER)
 
 bin_SCRIPTS =\
@@ -192,6 +193,15 @@ endif
 endif
 
 
+if !MINGW
+gnunet_timeout_SOURCES = \
+ gnunet-timeout.c
+else
+gnunet_timeout_SOURCES = \
+ gnunet-timeout-w32.c
+endif
+
+
 do_subst = $(SED) -e 's,[@]PYTHON[@],$(PYTHON),g'
 
 gnunet-qr: gnunet-qr.py.in Makefile
@@ -334,12 +344,12 @@ test_hexcoder_LDADD = \
 test_tun_SOURCES = \
  test_tun.c
 test_tun_LDADD = \
- libgnunetutil.la 
+ libgnunetutil.la
 
 test_regex_SOURCES = \
  test_regex.c
 test_regex_LDADD = \
- libgnunetutil.la 
+ libgnunetutil.la
 
 test_os_start_process_SOURCES = \
  test_os_start_process.c
@@ -622,4 +632,4 @@ EXTRA_DIST = \
   test_resolver_api_data.conf \
   test_service_data.conf \
   test_speedup_data.conf \
-  gnunet-qr.py.in 
+  gnunet-qr.py.in
index 44e326eab39a2dfef39f52e7be71170aeeb49047..1f569255a6a91617d938ad13ab76264a378eac95 100644 (file)
@@ -11,7 +11,7 @@
      WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      Affero General Public License for more details.
-    
+
      You should have received a copy of the GNU Affero General Public License
      along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
@@ -721,6 +721,17 @@ test_service_configuration (const char *service_name,
                                                 &unixpath)) &&
       (0 < strlen (unixpath)))
     ret = GNUNET_OK;
+  else if ((GNUNET_OK ==
+            GNUNET_CONFIGURATION_have_value (cfg,
+                                             service_name,
+                                             "UNIXPATH")))
+  {
+    GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
+                               service_name,
+                               "UNIXPATH",
+                               _("not a valid filename"));
+    return GNUNET_SYSERR; /* UNIXPATH specified but invalid! */
+  }
   GNUNET_free_non_null (unixpath);
 #endif
 
diff --git a/src/util/gnunet-timeout-w32.c b/src/util/gnunet-timeout-w32.c
new file mode 100644 (file)
index 0000000..78b268f
--- /dev/null
@@ -0,0 +1,191 @@
+/*
+     This file is part of GNUnet
+     Copyright (C) 2010 GNUnet e.V.
+
+     GNUnet is free software: you can redistribute it and/or modify it
+     under the terms of the GNU Affero General Public License as published
+     by the Free Software Foundation, either version 3 of the License, or
+     (at your option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Affero General Public License for more details.
+
+     You should have received a copy of the GNU Affero General Public License
+     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file src/util/gnunet-timeout-w32.c
+ * @brief small tool starting a child process, waiting that it terminates or killing it after a given timeout period
+ * @author LRN
+ */
+
+#include <windows.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int
+main (int argc, char *argv[])
+{
+  int i;
+  DWORD wait_result;
+  wchar_t *commandline;
+  wchar_t **wargv;
+  wchar_t *arg;
+  unsigned int cmdlen;
+  STARTUPINFOW start;
+  PROCESS_INFORMATION proc;
+
+  wchar_t wpath[MAX_PATH + 1];
+
+  wchar_t *pathbuf;
+  DWORD pathbuf_len, alloc_len;
+  wchar_t *ptr;
+  wchar_t *non_const_filename;
+  wchar_t *wcmd;
+  int wargc;
+  int timeout = 0;
+  ssize_t wrote;
+
+  HANDLE job;
+
+  if (argc < 3)
+    {
+      printf
+       ("arg 1: timeout in sec., arg 2: executable, arg<n> arguments\n");
+      exit (1);
+    }
+
+  timeout = atoi (argv[1]);
+
+  if (timeout == 0)
+    timeout = 600;
+
+  commandline =  GetCommandLineW ();
+  if (commandline == NULL)
+  {
+    printf ("Failed to get commandline: %lu\n", GetLastError ());
+    exit (2);
+  }
+
+  wargv = CommandLineToArgvW (commandline, &wargc);
+  if (wargv == NULL || wargc <= 1)
+  {
+    printf ("Failed to get parse commandline: %lu\n", GetLastError ());
+    exit (3);
+  }
+
+  job = CreateJobObject (NULL, NULL);
+  if (job == NULL)
+  {
+    printf ("Failed to create a job: %lu\n", GetLastError ());
+    exit (4);
+  }
+
+  pathbuf_len = GetEnvironmentVariableW (L"PATH", (wchar_t *) &pathbuf, 0);
+
+  alloc_len = pathbuf_len + 1;
+
+  pathbuf = malloc (alloc_len * sizeof (wchar_t));
+
+  ptr = pathbuf;
+
+  alloc_len = GetEnvironmentVariableW (L"PATH", ptr, pathbuf_len);
+
+  cmdlen = wcslen (wargv[2]);
+  if (cmdlen < 5 || wcscmp (&wargv[2][cmdlen - 4], L".exe") != 0)
+  {
+    non_const_filename = malloc (sizeof (wchar_t) * (cmdlen + 5));
+    swprintf (non_const_filename, cmdlen + 5, L"%S.exe", wargv[2]);
+  }
+  else
+  {
+    non_const_filename = wcsdup (wargv[2]);
+  }
+
+  /* Check that this is the full path. If it isn't, search. */
+  if (non_const_filename[1] == L':')
+    swprintf (wpath, sizeof (wpath) / sizeof (wchar_t), L"%S", non_const_filename);
+  else if (!SearchPathW
+           (pathbuf, non_const_filename, NULL, sizeof (wpath) / sizeof (wchar_t),
+            wpath, NULL))
+  {
+    printf ("Failed to get find executable: %lu\n", GetLastError ());
+    exit (5);
+  }
+  free (pathbuf);
+  free (non_const_filename);
+
+  cmdlen = wcslen (wpath) + 4;
+  i = 3;
+  while (NULL != (arg = wargv[i++]))
+    cmdlen += wcslen (arg) + 4;
+
+  wcmd = malloc (sizeof (wchar_t) * (cmdlen + 1));
+  wrote = 0;
+  i = 2;
+  while (NULL != (arg = wargv[i++]))
+  {
+    /* This is to escape trailing slash */
+    wchar_t arg_lastchar = arg[wcslen (arg) - 1];
+    if (wrote == 0)
+    {
+      wrote += swprintf (&wcmd[wrote], cmdlen + 1 - wrote, L"\"%S%S\" ", wpath,
+          arg_lastchar == L'\\' ? L"\\" : L"");
+    }
+    else
+    {
+      if (wcschr (arg, L' ') != NULL)
+        wrote += swprintf (&wcmd[wrote], cmdlen + 1 - wrote, L"\"%S%S\"%S", arg,
+            arg_lastchar == L'\\' ? L"\\" : L"", i == wargc ? L"" : L" ");
+      else
+        wrote += swprintf (&wcmd[wrote], cmdlen + 1 - wrote, L"%S%S%S", arg,
+            arg_lastchar == L'\\' ? L"\\" : L"", i == wargc ? L"" : L" ");
+    }
+  }
+
+  LocalFree (wargv);
+
+  memset (&start, 0, sizeof (start));
+  start.cb = sizeof (start);
+
+  if (!CreateProcessW (wpath, wcmd, NULL, NULL, TRUE, CREATE_SUSPENDED,
+       NULL, NULL, &start, &proc))
+  {
+    wprintf (L"Failed to get spawn process `%S' with arguments `%S': %lu\n", wpath, wcmd, GetLastError ());
+    exit (6);
+  }
+
+  AssignProcessToJobObject (job, proc.hProcess);
+
+  ResumeThread (proc.hThread);
+  CloseHandle (proc.hThread);
+
+  free (wcmd);
+
+  wait_result = WaitForSingleObject (proc.hProcess, timeout * 1000);
+  if (wait_result == WAIT_OBJECT_0)
+  {
+    DWORD status;
+    wait_result = GetExitCodeProcess (proc.hProcess, &status);
+    CloseHandle (proc.hProcess);
+    if (wait_result != 0)
+    {
+      printf ("Test process exited with result %lu\n", status);
+      TerminateJobObject (job, status);
+      exit (status);
+    }
+    printf ("Test process exited (failed to obtain exit status)\n");
+    TerminateJobObject (job, 0);
+    exit (0);
+  }
+  printf ("Child processes were killed after timeout of %u seconds\n",
+          timeout);
+  TerminateJobObject (job, 1);
+  CloseHandle (proc.hProcess);
+  exit (1);
+}
+
+/* end of timeout_watchdog_w32.c */
diff --git a/src/util/gnunet-timeout.c b/src/util/gnunet-timeout.c
new file mode 100644 (file)
index 0000000..8dfb6ad
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+     This file is part of GNUnet
+     Copyright (C) 2010 GNUnet e.V.
+
+     GNUnet is free software: you can redistribute it and/or modify it
+     under the terms of the GNU Affero General Public License as published
+     by the Free Software Foundation, either version 3 of the License, or
+     (at your option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Affero General Public License for more details.
+
+     You should have received a copy of the GNU Affero General Public License
+     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file src/util/gnunet-timeout.c
+ * @brief small tool starting a child process, waiting that it terminates or killing it after a given timeout period
+ * @author Matthias Wachs
+ */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static pid_t child;
+
+
+static void
+sigchld_handler (int val)
+{
+  int status = 0;
+  int ret = 0;
+
+  (void) val;
+  waitpid (child,
+           &status,
+           0);
+  if (WIFEXITED (status) != 0)
+  {
+    ret = WEXITSTATUS (status);
+    fprintf (stderr,
+             "Process exited with result %u\n",
+             ret);
+    exit (ret); /* return same status code */
+  }
+  if (WIFSIGNALED (status) != 0)
+  {
+    ret = WTERMSIG (status);
+    fprintf (stderr,
+             "Process received signal %u\n",
+             ret);
+    kill (getpid (),
+          ret); /* kill self with the same signal */
+  }
+  exit (-1);
+}
+
+
+static void
+sigint_handler (int val)
+{
+  kill (0,
+        val);
+  exit (val);
+}
+
+
+int
+main (int argc,
+      char *argv[])
+{
+  int timeout = 0;
+  pid_t gpid = 0;
+
+  if (argc < 3)
+  {
+    fprintf (stderr,
+             "arg 1: timeout in sec., arg 2: executable, arg<n> arguments\n");
+    exit (-1);
+  }
+
+  timeout = atoi (argv[1]);
+
+  if (timeout == 0)
+    timeout = 600;
+
+  /* with getpgid() it does not compile, but getpgrp is the BSD version and working */
+  gpid = getpgrp ();
+
+  signal (SIGCHLD, sigchld_handler);
+  signal (SIGABRT, sigint_handler);
+  signal (SIGFPE, sigint_handler);
+  signal (SIGILL, sigint_handler);
+  signal (SIGINT, sigint_handler);
+  signal (SIGSEGV, sigint_handler);
+  signal (SIGTERM, sigint_handler);
+
+  child = fork ();
+  if (child == 0)
+  {
+    /*  int setpgrp(pid_t pid, pid_t pgid); is not working on this machine */
+    //setpgrp (0, pid_t gpid);
+    if (-1 != gpid)
+      setpgid (0, gpid);
+    execvp (argv[2],
+            &argv[2]);
+    exit (-1);
+  }
+  if (child > 0)
+  {
+    sleep (timeout);
+    printf ("Child processes were killed after timeout of %u seconds\n",
+            timeout);
+    kill (0,
+          SIGTERM);
+    exit (3);
+  }
+  exit (-1);
+}
+
+/* end of timeout_watchdog.c */