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