* @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"
}
+/**
+ * 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
*
* 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
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))
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)
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);
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,
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;
}
{
struct RegisteredController *rc;
uint32_t id;
- uint32_t orig_size;
GNUNET_assert (host->id < host_list_size);
GNUNET_assert (host_list[host->id] == 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;
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);
}
}
rc = GNUNET_malloc (sizeof (struct RegisteredController));
rc->controller = controller;
- //host->controller = controller;
GNUNET_CONTAINER_DLL_insert_tail (host->rc_head, host->rc_tail, rc);
}
}
+/**
+ * Checks whether a host can be used to start testbed service
+ *
+ * @param host the host to check
+ * @param config the configuration handle to lookup the path of the testbed helper
+ * @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,
+ const struct GNUNET_CONFIGURATION_Handle *config)
+{
+ char *remote_args[11];
+ char *helper_binary_path;
+ 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);
+ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (config, "testbed",
+ "HELPER_BINARY_PATH",
+ &helper_binary_path))
+ helper_binary_path = GNUNET_OS_get_libexec_binary_path (HELPER_TESTBED_BINARY);
+ 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++] = "stat";
+ remote_args[argp++] = helper_binary_path;
+ remote_args[argp++] = NULL;
+ GNUNET_assert (argp == 11);
+ auxp =
+ GNUNET_OS_start_process_vap (GNUNET_NO, GNUNET_OS_INHERIT_STD_ERR, 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);
+ GNUNET_OS_process_destroy (auxp);
+ GNUNET_free (ssh_addr);
+ GNUNET_free (portstr);
+ GNUNET_free (helper_binary_path);
+ return (0 != code) ? GNUNET_NO : GNUNET_YES;
+}
+
/* end of testbed_api_hosts.c */