* @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
GNUNET_TESTBED_hosts_load_from_file (const char *filename,
struct GNUNET_TESTBED_Host ***hosts)
{
-#if 0
- struct GNUNET_TESTBED_Host **host_array;
-
- host_array = GNUNET_malloc (num_hosts * sizeof (struct GNUNET_TESTBED_Host *));
- host_array[foo] = GNUNET_TESTBED_host_create (...);
- *hosts = host_array;
-
- return num_hosts;
-#endif
- // see testing_group.c, GNUNET_TESTING_hosts_load
- GNUNET_break (0);
- return 0;
+ //struct GNUNET_TESTBED_Host **host_array;
+ struct GNUNET_TESTBED_Host *starting_host;
+ char *data;
+ char *buf;
+ 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 !=
+ 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);
+ if (fs != GNUNET_DISK_fn_read (filename, data, fs))
+ {
+ GNUNET_free (data);
+ LOG (GNUNET_ERROR_TYPE_WARNING, _("Hosts file %s cannot be read\n"),
+ filename);
+ return 0;
+ }
+ 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, "%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 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++;
+ }
+ else
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Error reading line `%s' in hostfile\n", buf);
+ buf = &data[offset + 1];
+ }
+ else if ((data[offset] == '\n') || (data[offset] == '\0'))
+ buf = &data[offset + 1];
+ }
+ GNUNET_free (data);
+ if (NULL == 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;
}
}
host_list =
GNUNET_realloc (host_list,
- sizeof (struct GNUNET_TESTBED_Host) * host_list_size);
+ 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 */