Blame src/conf.c

Packit d36e9b
/*
Packit d36e9b
 * libieee1284 - IEEE 1284 library
Packit d36e9b
 * Copyright (C) 2002  Tim Waugh <twaugh@redhat.com>
Packit d36e9b
 *
Packit d36e9b
 * This program is free software; you can redistribute it and/or modify
Packit d36e9b
 * it under the terms of the GNU General Public License as published by
Packit d36e9b
 * the Free Software Foundation; either version 2 of the License, or
Packit d36e9b
 * (at your option) any later version.
Packit d36e9b
 *
Packit d36e9b
 * This program is distributed in the hope that it will be useful,
Packit d36e9b
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit d36e9b
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit d36e9b
 * GNU General Public License for more details.
Packit d36e9b
 *
Packit d36e9b
 * You should have received a copy of the GNU General Public License
Packit d36e9b
 * along with this program; if not, write to the Free Software
Packit d36e9b
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Packit d36e9b
 */
Packit d36e9b
Packit d36e9b
#ifdef HAVE_CONFIG_H
Packit d36e9b
# include "config.h"
Packit d36e9b
#endif /* HAVE_CONFIG_H */
Packit d36e9b
Packit d36e9b
#include <stdlib.h>
Packit d36e9b
#include <stdio.h>
Packit d36e9b
#include <string.h>
Packit d36e9b
Packit d36e9b
#include "conf.h"
Packit d36e9b
#include "debug.h"
Packit d36e9b
Packit d36e9b
struct config_variables conf;
Packit d36e9b
Packit d36e9b
static const char *const ieee1284conf = "ieee1284.conf";
Packit d36e9b
static const size_t max_line_len = 1000;
Packit d36e9b
static const char *ifs = " \t\n";
Packit d36e9b
static const char *tokenchar = "{}=";
Packit d36e9b
Packit d36e9b
/* Get the next token.  Caller frees returned zero-terminated string. */
Packit d36e9b
static char *
Packit d36e9b
get_token (FILE *f)
Packit d36e9b
{
Packit d36e9b
  static char *current_line = NULL;
Packit d36e9b
  static size_t current_line_len = 0;
Packit d36e9b
  static size_t at = 0;
Packit d36e9b
  size_t end, i;
Packit d36e9b
  char *this_token;
Packit d36e9b
Packit d36e9b
  for (;;)
Packit d36e9b
    {
Packit d36e9b
      int quotes = 0;
Packit d36e9b
Packit d36e9b
      if (at == current_line_len)
Packit d36e9b
	{
Packit d36e9b
	  if (current_line)
Packit d36e9b
	    free (current_line);
Packit d36e9b
Packit d36e9b
	  current_line = NULL;
Packit d36e9b
	  current_line_len = 0;
Packit d36e9b
	  at = 0;
Packit d36e9b
	}
Packit d36e9b
Packit d36e9b
      if (!current_line)
Packit d36e9b
	{
Packit d36e9b
	  current_line = malloc (sizeof (char) * max_line_len);
Packit d36e9b
	  if (!current_line)
Packit d36e9b
	    return NULL;
Packit d36e9b
Packit d36e9b
	  /* Ideally we'd use getline here, but that isn't available
Packit d36e9b
	   * everywhere. In fact, *ideally* we'd use wordexp for this
Packit d36e9b
	   * whole function, but that isn't widely available either. */
Packit d36e9b
	  if (!fgets (current_line, max_line_len, f))
Packit d36e9b
	    {
Packit d36e9b
	      free (current_line);
Packit d36e9b
	      current_line = NULL;
Packit d36e9b
	      current_line_len = 0;
Packit d36e9b
	      at = 0;
Packit d36e9b
	      return NULL;
Packit d36e9b
	    }
Packit d36e9b
Packit d36e9b
	  current_line_len = strlen (current_line);
Packit d36e9b
	  at = 0;
Packit d36e9b
	}
Packit d36e9b
Packit d36e9b
      /* Skip whitespace. */
Packit d36e9b
      at += strspn (current_line + at, ifs);
Packit d36e9b
Packit d36e9b
      if (current_line[at] == '#')
Packit d36e9b
	{
Packit d36e9b
	  /* Ignore the rest of the line. */
Packit d36e9b
	  at = current_line_len;
Packit d36e9b
	  continue;
Packit d36e9b
	}
Packit d36e9b
Packit d36e9b
      /* Find the end of the token. */
Packit d36e9b
      for (end = at; end < current_line_len; end++)
Packit d36e9b
	{
Packit d36e9b
	  char ch = current_line[end];
Packit d36e9b
Packit d36e9b
	  if (ch == '\\' && quotes != 1)
Packit d36e9b
	    {
Packit d36e9b
	      end++;
Packit d36e9b
	      continue;
Packit d36e9b
	    }
Packit d36e9b
Packit d36e9b
	  if (ch == '\'')
Packit d36e9b
	    {
Packit d36e9b
	      if (quotes == 0)
Packit d36e9b
		{
Packit d36e9b
		  quotes = 1;
Packit d36e9b
		  continue;
Packit d36e9b
		}
Packit d36e9b
Packit d36e9b
	      if (quotes == 1)
Packit d36e9b
		quotes = 0;
Packit d36e9b
	    }
Packit d36e9b
Packit d36e9b
	  if (ch == '"')
Packit d36e9b
	    {
Packit d36e9b
	      if (quotes == 0)
Packit d36e9b
		{
Packit d36e9b
		  quotes = 2;
Packit d36e9b
		  continue;
Packit d36e9b
		}
Packit d36e9b
Packit d36e9b
	      if (quotes == 2)
Packit d36e9b
		quotes = 0;
Packit d36e9b
	    }
Packit d36e9b
Packit d36e9b
	  if (!quotes && strchr (ifs, ch))
Packit d36e9b
	    break;
Packit d36e9b
Packit d36e9b
	  if (!quotes && strchr (tokenchar, ch))
Packit d36e9b
	    {
Packit d36e9b
	      if (end == at)
Packit d36e9b
		end++;
Packit d36e9b
Packit d36e9b
	      break;
Packit d36e9b
	    }
Packit d36e9b
	}
Packit d36e9b
Packit d36e9b
      if (at == end)
Packit d36e9b
	/* Next line. */
Packit d36e9b
	continue;
Packit d36e9b
Packit d36e9b
      /* Copy this token. */
Packit d36e9b
      this_token = malloc (sizeof (char) * (end - at + 1)); /* worst case */
Packit d36e9b
      if (!this_token)
Packit d36e9b
	return NULL;
Packit d36e9b
Packit d36e9b
      quotes = 0;
Packit d36e9b
      for (i = 0; at < end; at++)
Packit d36e9b
	{
Packit d36e9b
	  char ch = current_line[at];
Packit d36e9b
Packit d36e9b
	  if (ch == '\\' && quotes != 1)
Packit d36e9b
	    {
Packit d36e9b
	      if (at < end - 1)
Packit d36e9b
		this_token[i++] = current_line[++at];
Packit d36e9b
Packit d36e9b
	      continue;
Packit d36e9b
	    }
Packit d36e9b
Packit d36e9b
	  if (ch == '\'')
Packit d36e9b
	    {
Packit d36e9b
	      if (quotes == 0)
Packit d36e9b
		{
Packit d36e9b
		  quotes = 1;
Packit d36e9b
		  continue;
Packit d36e9b
		}
Packit d36e9b
Packit d36e9b
	      if (quotes == 1)
Packit d36e9b
		{
Packit d36e9b
		  quotes = 0;
Packit d36e9b
		  continue;
Packit d36e9b
		}
Packit d36e9b
	    }
Packit d36e9b
Packit d36e9b
	  if (ch == '"')
Packit d36e9b
	    {
Packit d36e9b
	      if (quotes == 0)
Packit d36e9b
		{
Packit d36e9b
		  quotes = 2;
Packit d36e9b
		  continue;
Packit d36e9b
		}
Packit d36e9b
Packit d36e9b
	      if (quotes == 2)
Packit d36e9b
		{
Packit d36e9b
		  quotes = 0;
Packit d36e9b
		  continue;
Packit d36e9b
		}
Packit d36e9b
	    }
Packit d36e9b
Packit d36e9b
	  this_token[i++] = ch;
Packit d36e9b
	}
Packit d36e9b
Packit d36e9b
      this_token[i] = '\0';
Packit d36e9b
      break;
Packit d36e9b
    }
Packit d36e9b
Packit d36e9b
  return this_token;
Packit d36e9b
}
Packit d36e9b
Packit d36e9b
static char *
Packit d36e9b
disallow (FILE *f)
Packit d36e9b
{
Packit d36e9b
  char *token = NULL;
Packit d36e9b
Packit d36e9b
  token = get_token (f);
Packit d36e9b
  if (!token || strcmp (token, "method"))
Packit d36e9b
    {
Packit d36e9b
      debugprintf ("'disallow' requires 'method'\n");
Packit d36e9b
      return token;
Packit d36e9b
    }
Packit d36e9b
Packit d36e9b
  free (token);
Packit d36e9b
  token = get_token (f);
Packit d36e9b
  if (!token || strcmp (token, "ppdev"))
Packit d36e9b
    {
Packit d36e9b
      debugprintf ("'disallow method' requires a method name (e.g. ppdev)\n");
Packit d36e9b
      return token;
Packit d36e9b
    }
Packit d36e9b
Packit d36e9b
  debugprintf ("* Disallowing method: ppdev\n");
Packit d36e9b
  conf.disallow_ppdev = 1;
Packit d36e9b
  free (token);
Packit d36e9b
  return get_token (f);
Packit d36e9b
}
Packit d36e9b
Packit d36e9b
static int
Packit d36e9b
try_read_config_file (const char *path)
Packit d36e9b
{
Packit d36e9b
  FILE *f = fopen (path, "r");
Packit d36e9b
  char *token;
Packit d36e9b
Packit d36e9b
  if (!f)
Packit d36e9b
    return 1;
Packit d36e9b
Packit d36e9b
  debugprintf ("Reading configuration from %s:\n", path);
Packit d36e9b
Packit d36e9b
  token = get_token (f);
Packit d36e9b
  while (token)
Packit d36e9b
    {
Packit d36e9b
      char *next_token;
Packit d36e9b
      if (!strcmp (token, "disallow"))
Packit d36e9b
	{
Packit d36e9b
	  next_token = disallow (f);
Packit d36e9b
	}
Packit d36e9b
      else
Packit d36e9b
	{
Packit d36e9b
	  debugprintf ("Skipping unknown word: %s\n", token);
Packit d36e9b
	  next_token = get_token (f);
Packit d36e9b
	}
Packit d36e9b
Packit d36e9b
      free (token);
Packit d36e9b
      token = next_token;
Packit d36e9b
    }
Packit d36e9b
Packit d36e9b
  fclose (f);
Packit d36e9b
  debugprintf ("End of configuration\n");
Packit d36e9b
  return 0;
Packit d36e9b
}
Packit d36e9b
Packit d36e9b
void
Packit d36e9b
read_config_file (void)
Packit d36e9b
{
Packit d36e9b
  static int config_read = 0;
Packit d36e9b
  size_t rclen;
Packit d36e9b
  char *path;
Packit d36e9b
Packit d36e9b
  if (config_read)
Packit d36e9b
    return;
Packit d36e9b
Packit d36e9b
  conf.disallow_ppdev = 0;
Packit d36e9b
Packit d36e9b
  rclen = strlen (ieee1284conf);
Packit d36e9b
  path = malloc (1 + 5 + rclen);
Packit d36e9b
  if (!path)
Packit d36e9b
    return;
Packit d36e9b
Packit d36e9b
  memcpy (path, "/etc/", 5);
Packit d36e9b
  memcpy (path + 5, ieee1284conf, rclen + 1);
Packit d36e9b
  if (try_read_config_file (path))
Packit d36e9b
    config_read = 1;
Packit d36e9b
Packit d36e9b
  free (path);
Packit d36e9b
  return;
Packit d36e9b
}
Packit d36e9b
Packit d36e9b
/*
Packit d36e9b
 * Local Variables:
Packit d36e9b
 * eval: (c-set-style "gnu")
Packit d36e9b
 * End:
Packit d36e9b
 */