Files @ 0be4e8427de5
Branch filter:

Location: DistRen/src/common/options.c

binki
started fixing server's main()
/*
  Copyright 2008 Nathan Phillip Brink, Ethan Zonca

  This file is a part of DistRen.

  DistRen 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.

  DistRen 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 DistRen.  If not, see <http://www.gnu.org/licenses/>.
*/

/* The purpose of this file is to... */

#include "options.h"

/* privat-ish files for components we need to config */
#include "libremoteio.h"

#include <confuse.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

struct options_common_data
{
  cfg_t *cfg;
};


int options_init(int argc, char *argv[], cfg_t **mycfg, cfg_opt_t *myopts, char *myname, struct options_common **allopts)
{
  char *configfileprefix;
  char *configfile;

  size_t i;

  char *optstring = "hc:";
  char curopt;

  configfileprefix = NULL;
  while((curopt = getopt(argc, argv, optstring)) != -1)
    switch(curopt)
      {
      case 'h':
	fprintf(stderr, "libdistren common options\n\
\n\
\t-h\tShow this help.\n\
\t-c <path>\tBasename for configuration files. For instance, if distrencommon.conf is located at /etc/distren/distrencommon.conf, set this option /etc/distren/distren . Default value: %s\n\
\n", SYSCONFDIR "/distren");
	return 2;
	break;
      case 'c':
	configfileprefix = strdup(optarg);
	if(!configfileprefix)
	  /* return is unnecessary here */
	  fprintf(stderr, "OOM\n");
	break;
      case ':':
	fprintf(stderr, "Option -%c requires an argument\n", optopt);
	return 1;
      }
  /* restore optind for other people who use getopt */
  optind = 1;
  
  if(!configfileprefix)
    configfileprefix = strdup(SYSCONFDIR "/distren");
  if(!configfileprefix)
    {
    fprintf(stderr, "OOM\n");
    return 1;
    }
  /* For those of you who don't know, the following is an example of concatenation of constant strings by the C compiler. Now, that doesn't mean you can do run-time string concatenation ;-)
   strdup is because someday configfile will be customizable via argv[]
   */

  i = strlen(SYSCONFDIR "/distren.conf") + strlen(myname) + 1;
  configfile = malloc(i);
  if(!configfile)
    {
      perror("malloc");
      return 1;
    }
  strncpy(configfile, SYSCONFDIR "/distren", strlen(SYSCONFDIR "/distren") + 1);
  strcat(configfile, myname);
  strcat(configfile, ".conf");

  *allopts = malloc(sizeof(struct options_common));
  if(!*allopts)
    {
      perror("malloc");
      free(configfile);
      return 1;
    }
  memset(*allopts, '\0', sizeof(struct options_common));

  (*allopts)->data = malloc(sizeof(struct options_common_data));
  if(!(*allopts)->data)
    {
      perror("malloc");
      free(configfile);
      free(*allopts);
      return 1;
    }
  memset((*allopts)->data, '\0', sizeof(struct options_common_data));

  (*allopts)->remoteio = malloc(sizeof(struct remoteio_opts));
  if(!(*allopts)->data)
    {
      perror("malloc");
      free(configfile);
      free((*allopts)->data);
      free(*allopts);
      return 1;
    }
  memset((*allopts)->remoteio, '\0', sizeof(struct remoteio_opts));
  (*allopts)->remoteio->ssh_command = strdup("ssh");
  /** @TODO: check for NULL return above */

  cfg_opt_t common_opts[] =
    {
      CFG_SIMPLE_STR("ssh-command", &(*allopts)->remoteio->ssh_command),
      CFG_END()
    };

  /*
    In these arrays, I should replace NULL with a pointer to a string in the struct which should hold the result of confuse processing an option. This is partially because confuse will not free the values it parses.
   */
  cfg_opt_t server_opts[] =
    {
      CFG_STR("username", NULL, CFGF_NONE),
      CFG_STR("hostname", NULL, CFGF_NONE),
      CFG_STR("method", "ssh", CFGF_NONE),
      CFG_STR_LIST("types", NULL, CFGF_NONE),
      CFG_END()
    };

  cfg_opt_t opts[] =
    {
      CFG_SEC("common",
	      common_opts,
	      CFGF_NONE),
      CFG_SEC("server",
	      server_opts,
	      CFGF_MULTI | CFGF_TITLE),
      CFG_SEC(myname,
	      myopts,
	      0),
      CFG_FUNC("include",
	       &cfg_include),
      CFG_END()
    };



  (*allopts)->data->cfg = cfg_init(opts, 0);
  switch(cfg_parse((*allopts)->data->cfg, configfile))
    {
    default:
      fprintf(stderr, "cfg_parse returned an unknown error code\n");
    case CFG_FILE_ERROR:
      cfg_error((*allopts)->data->cfg, "Couldn't open file ``%s''\n", configfile);
      /* no break; on purpose */

    case CFG_PARSE_ERROR:

      free((*allopts)->data);
      free(*allopts);
      free(configfile);

      return 1;

    case CFG_SUCCESS:
      break;
    }

  free(configfile);

  *mycfg = cfg_getsec((*allopts)->data->cfg, myname);

  return 0;
}

int options_free(struct options_common *opts)
{
  /* free the other common_options struct's members */

  cfg_free(opts->data->cfg);

  free(opts->remoteio);
  free(opts->data);
  free(opts);

  return 0;
}