Logo Search packages:      
Sourcecode: sbrsh version File versions  Download package

config.c

/*
 * Copyright (c) 2003, 2004 Nokia
 * Author: Timo Savola <tsavola@movial.fi>
 *
 * This program is licensed under GPL (see COPYING for details)
 */

#define _GNU_SOURCE

#include "types.h"
#include "config.h"
#include "common.h"
#include "client.h"

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

/**
 * Compares the beginning of BUF to TGT. Comparison ends at first whitespace.
 */
static char *is_target(char *tgt, char *buf)
{
      int a, b;

      while (1) {
            a = *tgt++;
            b = *buf++;

            if (!a || !b || isspace(b))
                  return (!a && isspace(b)) ? buf : NULL;

            if (a != b)
                  return NULL;
      }
}

/**
 * Parses BUF into CFG.
 */
static bool_t read_params(char *buf, config_t *cfg)
{
      char *host, *port;

      host = skip_spaces(buf);
      if (!host) {
            errno = 0;
            error("Invalid parameter string");
            return FALSE;
      }

      port = strchr(host, ':');
      if (port) {
            *port++ = '\0';
            buf = port;
      } else {
            port = NULL;
            buf = host;
      }

      buf = find_space(buf);
      if (!buf) {
            errno = 0;
            error("Invalid parameter string");
            return FALSE;
      }
      *buf++ = '\0';

      cfg->host = strdup(host);
      if (!cfg->host) {
            oom_error();
            return FALSE;
      }

      if (port) {
            cfg->port = strdup(port);
            if (!cfg->port) {
                  oom_error();
                  return FALSE;
            }
      }

      return TRUE;
}

static bool_t read_opts(FILE *file, char *buf, size_t size, config_t *cfg)
{
      long pos;
      size_t cnt = 0;
      char **p;

      pos = ftell(file);

      while (1) {
            bool_t blank;
            ssize_t len;

            len = read_line_blank(file, buf, size, &blank);
            if (len < 0)
                  break;
            if (blank)
                  break;
            if (len > 0 && !isspace(buf[0]))
                  break;

            buf = skip_spaces(buf);
            if (strlen(buf) == 0)
                  continue;

            cnt++;
      }

      fseek(file, pos, SEEK_SET);

      cfg->opts = calloc(cnt + 1, sizeof (char *));
      if (!cfg->opts) {
            oom_error();
            return FALSE;
      }

      for (p = cfg->opts; cnt > 0; ) {
            if (read_line(file, buf, size) < 0)
                  break;

            buf = skip_spaces(buf);
            if (strlen(buf) == 0)
                  continue;

            *p++ = strdup(buf);
            cnt--;
      }

      return TRUE;
}

bool_t config_read(config_t *cfg, const char *filename, const char *target)
{
      FILE *file;
      char buf[1024], *bufp;
      ssize_t len;
      bool_t ok = FALSE;

      file = fopen(filename, "r");
      if (!file) {
            error("Can't open %s", filename);
            return FALSE;
      }

      while (1) {
            len = read_line(file, buf, sizeof (buf));
            if (len < 0) {
                  errno = 0;
                  error("Target %s is not listed in %s", target, filename);
                  break;
            }

            if (len == 0 || isspace(buf[0]))
                  continue;
            
            if (target) {
                  /* Compare target name */

                  bufp = is_target((char *) target, buf);
                  if (!bufp)
                        continue;

                  cfg->target = strdup(target);

            } else {
                  /* Take the first one (default) */

                  bufp = find_space(buf);
                  cfg->target = strndup(buf, bufp - buf);
            }

            ok = (read_params(bufp, cfg) && read_opts(file, buf, sizeof (buf), cfg));
            break;
      }

      fclose(file);

      return ok;
}

config_t *config_alloc(void)
{
      return calloc(1, sizeof (config_t));
}

void config_free(config_t *cfg)
{
      if (cfg->target)
            free(cfg->target);

      if (cfg->host)
            free(cfg->host);

      if (cfg->port)
            free(cfg->port);

      if (cfg->opts)
            free_vec((void **) cfg->opts, NULL);

      free(cfg);
}

char **get_targets(const char *filename)
{
      FILE *file;
      char buf[1024];
      ssize_t len;
      size_t cnt;
      char **targets, **p;

      file = fopen(filename, "r");
      if (!file)
            return NULL;

      for (cnt = 0; TRUE; ) {
            len = read_line(file, buf, sizeof (buf));
            if (len < 0)
                  break;

            if (len > 0 && !isspace(*buf))
                  ++cnt;
      }

      rewind(file);

      targets = calloc(cnt + 1, sizeof (char *));
      if (!targets) {
            oom_error();
            return NULL;
      }

      for (p = targets; TRUE; ) {
            len = read_line(file, buf, sizeof (buf));
            if (len < 0)
                  break;

            if (len > 0 && !isspace(*buf)) {
                  *find_space(buf) = '\0';
                  *p++ = strdup(buf);
            }
      }

      return targets;
}


Generated by  Doxygen 1.6.0   Back to index