removed GNUNET_TESTBED_operation_cancel
[oweals/gnunet.git] / src / testbed / testbed_api_hosts.c
index 91fffc92d57b97ae6d925046c87e97ae9c458522..1663f89624126a8dc27c2f0016959435f6908e47 100644 (file)
  * @author Christian Grothoff
  */
 #include "platform.h"
+#include "gnunet_util_lib.h"
 #include "gnunet_testbed_service.h"
 #include "gnunet_core_service.h"
-#include "gnunet_constants.h"
 #include "gnunet_transport_service.h"
-#include "gnunet_hello_lib.h"
-#include "gnunet_container_lib.h"
 
 #include "testbed_api.h"
 #include "testbed_api_hosts.h"
@@ -191,6 +189,19 @@ GNUNET_TESTBED_host_get_hostname_ (const struct GNUNET_TESTBED_Host *host)
 }
 
 
+/**
+ * Obtain the host's hostname.
+ *
+ * @param host handle to the host, NULL means 'localhost'
+ * @return hostname of the host
+ */
+const char *
+GNUNET_TESTBED_host_get_hostname (const struct GNUNET_TESTBED_Host *host)
+{
+  return GNUNET_TESTBED_host_get_hostname_ (host);
+}
+
+
 /**
  * Obtain the host's username
  *
@@ -288,7 +299,8 @@ GNUNET_TESTBED_host_create (const char *hostname, const char *username,
  * Load a set of hosts from a configuration file.
  *
  * @param filename file with the host specification
- * @param hosts set to the hosts found in the file
+ * @param hosts set to the hosts found in the file; caller must free this if
+ *          number of hosts returned is greater than 0
  * @return number of hosts returned in 'hosts', 0 on error
  */
 unsigned int
@@ -299,14 +311,14 @@ GNUNET_TESTBED_hosts_load_from_file (const char *filename,
   struct GNUNET_TESTBED_Host *starting_host;
   char *data;
   char *buf;
-  char *username;
-  char *hostname;
+  char username[256];
+  char hostname[256];
   uint64_t fs;
   short int port;
   int ret;
   unsigned int offset;
   unsigned int count;
-  
+
 
   GNUNET_assert (NULL != filename);
   if (GNUNET_YES != GNUNET_DISK_file_test (filename))
@@ -314,7 +326,7 @@ GNUNET_TESTBED_hosts_load_from_file (const char *filename,
     LOG (GNUNET_ERROR_TYPE_WARNING, _("Hosts file %s not found\n"), filename);
     return 0;
   }
-  if (GNUNET_OK != 
+  if (GNUNET_OK !=
       GNUNET_DISK_file_size (filename, &fs, GNUNET_YES, GNUNET_YES))
     fs = 0;
   if (0 == fs)
@@ -322,7 +334,7 @@ GNUNET_TESTBED_hosts_load_from_file (const char *filename,
     LOG (GNUNET_ERROR_TYPE_WARNING, _("Hosts file %s has no data\n"), filename);
     return 0;
   }
-  data = GNUNET_malloc (fs);  
+  data = GNUNET_malloc (fs);
   if (fs != GNUNET_DISK_fn_read (filename, data, fs))
   {
     GNUNET_free (data);
@@ -333,29 +345,28 @@ GNUNET_TESTBED_hosts_load_from_file (const char *filename,
   buf = data;
   offset = 0;
   starting_host = NULL;
+  count = 0;
   while (offset < (fs - 1))
   {
     offset++;
     if (((data[offset] == '\n')) && (buf != &data[offset]))
     {
       data[offset] = '\0';
-      ret = SSCANF (buf, "%a[a-zA-Z0-9_]@%a[a-zA-Z0-9.]:%hd",
-                    &username, &hostname, &port);
+      ret = SSCANF (buf, "%255[a-zA-Z0-9_]@%255[a-zA-Z0-9.]:%5hd",
+                    username, hostname, &port);
       if  (3 == ret)
       {
         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                     "Successfully read host %s, port %d and user %s from file\n",
                     hostname, port, username);
         /* We store hosts in a static list; hence we only require the starting
-           host pointer in that list to get the newly created list of hosts */
+           host pointer in that list to access the newly created list of hosts */
         if (NULL == starting_host)
           starting_host = GNUNET_TESTBED_host_create (hostname, username,
                                                       port);
         else
           (void) GNUNET_TESTBED_host_create (hostname, username, port);
         count++;
-        GNUNET_free (hostname);
-        GNUNET_free (username);
       }
       else
         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -363,12 +374,15 @@ GNUNET_TESTBED_hosts_load_from_file (const char *filename,
       buf = &data[offset + 1];
     }
     else if ((data[offset] == '\n') || (data[offset] == '\0'))
-      buf = &data[offset + 1];        
+      buf = &data[offset + 1];
   }
   GNUNET_free (data);
   if (NULL == starting_host)
-    return 0;  
-  *hosts = &host_list[GNUNET_TESTBED_host_get_id_ (starting_host)];
+    return 0;
+  *hosts = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Host *) * count);
+  memcpy (*hosts,
+          &host_list[GNUNET_TESTBED_host_get_id_ (starting_host)],
+          sizeof (struct GNUNET_TESTBED_Host *) * count);
   return count;
 }
 
@@ -384,7 +398,6 @@ GNUNET_TESTBED_host_destroy (struct GNUNET_TESTBED_Host *host)
 {
   struct RegisteredController *rc;
   uint32_t id;
-  uint32_t orig_size;
 
   GNUNET_assert (host->id < host_list_size);
   GNUNET_assert (host_list[host->id] == host);
@@ -398,7 +411,6 @@ GNUNET_TESTBED_host_destroy (struct GNUNET_TESTBED_Host *host)
   GNUNET_free_non_null ((char *) host->username);
   GNUNET_free_non_null ((char *) host->hostname);
   GNUNET_free (host);
-  orig_size = host_list_size;
   while (host_list_size >= HOST_LIST_GROW_STEP)
   {
     for (id = host_list_size - 1; id > host_list_size - HOST_LIST_GROW_STEP;
@@ -411,10 +423,9 @@ GNUNET_TESTBED_host_destroy (struct GNUNET_TESTBED_Host *host)
       break;
     host_list_size -= HOST_LIST_GROW_STEP;
   }
-  if (orig_size != host_list_size)
-    host_list =
-        GNUNET_realloc (host_list,
-                        sizeof (struct GNUNET_TESTBED_Host *) * host_list_size);
+  host_list =
+      GNUNET_realloc (host_list,
+                      sizeof (struct GNUNET_TESTBED_Host *) * host_list_size);
 }
 
 
@@ -441,7 +452,6 @@ GNUNET_TESTBED_mark_host_registered_at_ (struct GNUNET_TESTBED_Host *host,
   }
   rc = GNUNET_malloc (sizeof (struct RegisteredController));
   rc->controller = controller;
-  //host->controller = controller;
   GNUNET_CONTAINER_DLL_insert_tail (host->rc_head, host->rc_tail, rc);
 }
 
@@ -471,4 +481,68 @@ GNUNET_TESTBED_is_host_registered_ (const struct GNUNET_TESTBED_Host *host,
 }
 
 
+/**
+ * Checks whether a host can be used to start testbed service
+ *
+ * @param host the host to check
+ * @return GNUNET_YES if testbed service can be started on the given host
+ *           remotely; GNUNET_NO if not
+ */
+int
+GNUNET_TESTBED_is_host_habitable (const struct GNUNET_TESTBED_Host *host)
+{
+  char *remote_args[11];
+  char *portstr;
+  char *ssh_addr;
+  const char *hostname;
+  struct GNUNET_OS_Process *auxp;
+  unsigned long code;
+  enum GNUNET_OS_ProcessStatusType type;
+  int ret;
+  unsigned int argp;
+
+  portstr = NULL;
+  ssh_addr = NULL;
+  hostname = (NULL == host->hostname) ? "127.0.0.1" : host->hostname;
+  if (NULL == host->username)
+    ssh_addr = GNUNET_strdup (hostname);
+  else
+    GNUNET_asprintf (&ssh_addr, "%s@%s", host->username, hostname);
+  argp = 0;
+  remote_args[argp++] = "ssh";
+  GNUNET_asprintf (&portstr, "%u", host->port);
+  remote_args[argp++] = "-p";
+  remote_args[argp++] = portstr;
+  remote_args[argp++] = "-o";
+  remote_args[argp++] = "BatchMode=yes";
+  remote_args[argp++] = "-o";
+  remote_args[argp++] = "NoHostAuthenticationForLocalhost=yes";
+  remote_args[argp++] = ssh_addr;
+  remote_args[argp++] = "which";
+  remote_args[argp++] = "gnunet-helper-testbed";
+  remote_args[argp++] = NULL;
+  GNUNET_assert (argp == 11);
+  auxp =
+      GNUNET_OS_start_process_vap (GNUNET_NO, GNUNET_OS_INHERIT_STD_ALL, NULL,
+                                   NULL, "ssh", remote_args);
+  if (NULL == auxp)
+  {
+    GNUNET_free (ssh_addr);
+    GNUNET_free (portstr);
+    return GNUNET_NO;
+  }
+  do
+  {
+    ret = GNUNET_OS_process_status (auxp, &type, &code);
+    GNUNET_assert (GNUNET_SYSERR != ret);
+    (void) usleep (300);
+  }
+  while (GNUNET_NO == ret);
+  //(void) GNUNET_OS_process_wait (auxp);
+  GNUNET_OS_process_destroy (auxp);
+  GNUNET_free (ssh_addr);
+  GNUNET_free (portstr);
+  return (0 != code) ? GNUNET_NO : GNUNET_YES;
+}
+
 /* end of testbed_api_hosts.c */