Changeset - a556e24d0635
[Not reviewed]
default
0 2 0
Nathan Brink (binki) - 16 years ago 2009-08-16 22:21:41
ohnobinki@ohnopublishing.net
remoteio: partial modularization
2 files changed with 126 insertions and 25 deletions:
0 comments (0 inline, 0 general)
src/common/libremoteio.h
Show inline comments
 
@@ -29,9 +29,10 @@
 

	
 
enum remoteio_method
 
  {
 
    REMOTEIO_METHOD_SSH,
 
    REMOTEIO_METHOD_SSH = 0,
 
    /*    REMOTEIO_METHOD_TCP */ /*< someday, maybe */
 
    /*    REMOETIO_METHOD_XMLRPC */ /*< again, maybe someday */
 
    REMOTEIO_METHOD_MAX = 1 /*< This is a number used to check the consitency of remoteio_server structs */
 
  };
 

	
 
struct remoteio_server
 
@@ -52,10 +53,27 @@ struct remoteio_opts
 

	
 
struct remoteio {
 
  enum remoteio_method method;
 
  struct remoteio_opts *opts;
 
  struct execio *execio;
 
};
 

	
 

	
 
/* lookup table */
 
typedef int remoteio_open_func_t(struct remoteio *rem, struct remoteio_server *server);
 
typedef int remoteio_read_func_t(struct remoteio *rem, void *buf, size_t len, size_t *bytesread);
 
typedef int remoteio_write_func_t(struct remoteio *rem, void *buf, size_t len, size_t *bytesread);
 
typedef int remoteio_close_func_t(struct remoteio *rem);
 

	
 
struct remoteio_method_funcmap
 
{
 
  remoteio_open_func_t *open_func;
 
  remoteio_read_func_t *read_func;
 
  remoteio_write_func_t *write_func;
 
  remoteio_close_func_t *close_func;
 

	
 
  char *name; /*< used for error messages */
 
};
 

	
 
int remoteio_config(cfg_t *cfg, struct remoteio_opts *opts);
 

	
 
#endif
src/common/remoteio.c
Show inline comments
 
@@ -27,12 +27,32 @@
 
#include <string.h>
 

	
 
/* local */
 

	
 
int _remoteio_ssh_open(struct remoteio *rem, struct remoteio_server *server);
 
int _remoteio_ssh_read(struct remoteio *rem, void *buf, size_t len, size_t *bytesread);
 
int _remoteio_ssh_write(struct remoteio *rem, void *buf, size_t len, size_t *bytesread);
 
int _remoteio_ssh_close(struct remoteio *rem);
 

	
 
/**
 
  lookup table for different methods of remoteio:
 
  the enum remoteio_method is the index of the entry to use for that method. 
 
  Regardless, a NULL terminator is required because the configuration function
 
  searches through this table for the method specified in the config file.
 
*/
 
struct remoteio_method_funcmap funcmap[] = 
 
  {
 
    /* [REMOTEIO_METHOD_SSH] */
 
    {&_remoteio_ssh_open, &_remoteio_ssh_read, &_remoteio_ssh_write, &_remoteio_ssh_close, "ssh"},
 
    {NULL, NULL, NULL, NULL, NULL}
 
  };
 

	
 
struct remoteio_server *remoteio_getserver(const struct remoteio_opts *opts, const char *servername);
 

	
 
int remoteio_config(cfg_t *cfg, struct remoteio_opts *opts)
 
{
 
  size_t numservers;
 
  size_t counter;
 
  static int haslisted_methods = 0;
 
  
 
  struct remoteio_server *aserver;
 

	
 
@@ -49,6 +69,7 @@ int remoteio_config(cfg_t *cfg, struct r
 
  for(counter = 0; counter < numservers; counter ++)
 
    {
 
      cfg_t *cfg_aserver;
 
      char *method;
 
      
 
      cfg_aserver = cfg_getnsec(cfg, "server", counter);
 
      
 
@@ -58,10 +79,25 @@ int remoteio_config(cfg_t *cfg, struct r
 
      aserver->name = strdup(cfg_title(cfg_aserver));
 
      aserver->hostname = strdup(cfg_getstr(cfg_aserver, "hostname"));
 
      aserver->username = strdup(cfg_getstr(cfg_aserver, "username"));
 
      if(strcmp(cfg_getstr(cfg_aserver, "method"), "ssh") == 0)
 

	
 
      aserver->method = REMOTEIO_METHOD_MAX;
 
      method = cfg_getstr(cfg_aserver, "method");
 
      for(counter = 0; funcmap[counter].name; counter ++)
 
	if(strcmp(method, funcmap[counter].name) == 0)
 
	aserver->method = REMOTEIO_METHOD_SSH;
 
      else
 
      if(aserver->method == REMOTEIO_METHOD_MAX)
 
	{
 
	  fprintf(stderr, "No such method as %s\n", method);
 
	  if(!haslisted_methods)
 
	    {
 
	      fprintf(stderr, "Available methods:\n");
 
	      for(counter = 0; funcmap[counter].name; counter ++)
 
		fprintf(stderr, "\t%s\n", funcmap[counter].name);
 
	      
 
	      haslisted_methods ++;
 
	    }
 
	abort();
 
	}
 
      
 
      if(counter < numservers - 1)
 
	{
 
@@ -76,14 +112,18 @@ int remoteio_config(cfg_t *cfg, struct r
 

	
 

	
 

	
 
int remoteio_open(struct remoteio **rem, struct remoteio_opts *opts, const char *servername)
 
int remoteio_open(struct remoteio **remoteio, struct remoteio_opts *opts, const char *servername)
 
{
 
  char *userhost;
 
  char *sshargs[] = {opts->ssh_command, NULL /* userhost */, "distrend", "-d", (char *)NULL};
 
  struct remoteio_server *theserver;
 
  struct remoteio *rem;
 

	
 
  int tmp;
 
  
 
  int rtn;
 
  
 
  struct remoteio_server *theserver;
 
  if(!opts)
 
    {
 
      fprintf(stderr, "%s:%d: no null opts!\n\tThis is a bug, please report it (after making sure it isn't already reported)\n", __FILE__, __LINE__);
 
      return 1;
 
    }
 

	
 
  theserver = remoteio_getserver(opts, servername);
 
  if(!theserver)
 
@@ -92,28 +132,31 @@ int remoteio_open(struct remoteio **rem,
 
      return 1;
 
    }
 

	
 
  if(theserver->method != REMOTEIO_METHOD_SSH)
 
  if(theserver->method >= REMOTEIO_METHOD_MAX
 
     || theserver->method < 0)
 
    {
 
      fprintf(stderr, "%s:%d: Unsupported remoteio method %d\n", __FILE__, __LINE__, theserver->method);
 
      fprintf(stderr, "%s:%d: Unsupported remoteio method %d\n\tThis is a bug, probably indicating memory corruption. This is, of course, probably my fault (not your hardware's) ;-)\n", __FILE__, __LINE__, theserver->method);
 
      return 1;
 
    }
 

	
 
  if(theserver->username)
 
    _distren_asprintf(&userhost, "%s@%s", theserver->username, theserver->hostname);
 
  else
 
    userhost = strdup(theserver->hostname);
 
  sshargs[1] = userhost;
 
  rem = malloc(sizeof(struct remoteio));
 
  if(!rem)
 
    {
 
      fprintf(stderr, "OOM\n");
 
      return 2;
 
    }
 
  *remoteio = rem;
 

	
 
  *rem = malloc(sizeof(struct remoteio));
 
  rtn = execio_open( &(*rem)->execio, "ssh", sshargs);
 
  if(rtn)
 
  rem->method = theserver->method;
 
  rem->opts = opts;
 

	
 
  tmp = funcmap[theserver->method].open_func(rem, theserver);
 
  if(tmp)
 
    {
 
      fprintf(stderr, "error opening remoteio channel to server ``%s''" , servername);
 
      free(*rem);
 
      free(userhost);
 
      return 1;
 
      fprintf(stderr, "Error using method %s for server ``%s''", funcmap[theserver->method].name, servername);
 
      free(rem);
 
      *remoteio = NULL;
 
      return tmp;
 
    }
 
  free(userhost);
 
  
 
  return 0;
 
}
 
@@ -153,3 +196,43 @@ struct remoteio_server *remoteio_getserv
 

	
 
  return (struct remoteio_server *)NULL;
 
}
 

	
 

	
 

	
 

	
 
/**
 
   different remoteio methods' implementations:
 
 */
 

	
 
/*
 
  SSH, via execio
 
*/
 

	
 
int _remoteio_ssh_open(struct remoteio *rem, struct remoteio_server *server)
 
{
 
  char *userhost;
 
  char *sshargs[] = {rem->opts->ssh_command, NULL /* userhost */, "distrend", "-d", (char *)NULL};
 

	
 
  int rtn;
 

	
 
  if(server->username)
 
    _distren_asprintf(&userhost, "%s@%s", server->username, server->hostname);
 
  else
 
    userhost = strdup(server->hostname);
 
  sshargs[1] = userhost;
 

	
 
  rtn = execio_open( &rem->execio, "ssh", sshargs);
 
  if(rtn)
 
    {
 
      fprintf(stderr, "error opening remoteio channel to ssh userhost ``%s''\n" , userhost);
 
      free(userhost);
 
      return 1;
 
    }
 
  free(userhost);
 
  
 
  return 0;
 
}
 

	
 
int _remoteio_ssh_read(struct remoteio *rem, void *buf, size_t len, size_t *bytesread);
 
int _remoteio_ssh_write(struct remoteio *rem, void *buf, size_t len, size_t *bytesread);
 
int _remoteio_ssh_close(struct remoteio *rem);
0 comments (0 inline, 0 general)