summaryrefslogtreecommitdiffstats
path: root/debian/htdig/htdig-3.2.0b6/htlib/Configuration.cc
diff options
context:
space:
mode:
Diffstat (limited to 'debian/htdig/htdig-3.2.0b6/htlib/Configuration.cc')
-rw-r--r--debian/htdig/htdig-3.2.0b6/htlib/Configuration.cc390
1 files changed, 390 insertions, 0 deletions
diff --git a/debian/htdig/htdig-3.2.0b6/htlib/Configuration.cc b/debian/htdig/htdig-3.2.0b6/htlib/Configuration.cc
new file mode 100644
index 00000000..56912736
--- /dev/null
+++ b/debian/htdig/htdig-3.2.0b6/htlib/Configuration.cc
@@ -0,0 +1,390 @@
+//
+// Configuration.cc
+//
+// Configuration: This class provides an object lookup table. Each object
+// in the Configuration is indexed with a string. The objects
+// can be returned by mentioning their string index. Values may
+// include files with `/path/to/file` or other configuration
+// variables with ${variable}
+//
+// Part of the ht://Dig package <http://www.htdig.org/>
+// Copyright (c) 1999-2004 The ht://Dig Group
+// For copyright details, see the file COPYING in your distribution
+// or the GNU Library General Public License (LGPL) version 2 or later
+// <http://www.gnu.org/copyleft/lgpl.html>
+//
+// $Id: Configuration.cc,v 1.20 2004/05/28 13:15:20 lha Exp $
+//
+
+#ifdef HAVE_CONFIG_H
+#include "htconfig.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include "Configuration.h"
+#include "htString.h"
+#include "ParsedString.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <locale.h>
+
+
+//*********************************************************************
+// Configuration::Configuration()
+//
+Configuration::Configuration() : separators("=:"), allow_multiple(0)
+{
+}
+
+
+//*********************************************************************
+// void Configuration::NameValueSeparators(char *s)
+//
+void Configuration::NameValueSeparators(const String& s)
+{
+ separators = s;
+}
+
+
+//*********************************************************************
+// Add an entry to the configuration table.
+//
+void Configuration::Add(const String& str_arg)
+{
+ const char* str = str_arg;
+ String name, value;
+
+ while (str && *str)
+ {
+ while (isspace(*str))
+ str++;
+ name = 0;
+ if (!isalpha(*str))
+ break;
+ // Some isalnum() implementations don't allow all the letters that
+ // isalpha() does, e.g. accented ones. They're not POSIX.2 compliant
+ // but we won't punish them with an infinite loop...
+ if (!isalnum(*str))
+ break;
+ while (isalnum(*str) || *str == '-' || *str == '_')
+ name << *str++;
+
+ name.lowercase();
+
+ //
+ // We have the name. Let's see if we will get a value
+ //
+ while (isspace(*str))
+ str++;
+ if (!*str)
+ {
+ //
+ // End of string. We need to store the name as a boolean TRUE
+ //
+ Add(name, "true");
+ return;
+ }
+
+ if (!strchr((char*)separators, *str))
+ {
+ //
+ // We are now at a new name. The previous one needs to be set
+ // to boolean TRUE
+ //
+ Add(name, "true");
+ continue;
+ }
+
+ //
+ // We now need to deal with the value
+ //
+ str++; // Skip the separator
+ while (isspace(*str))
+ str++;
+ if (!*str)
+ {
+ //
+ // End of string reached. The value must be blank
+ //
+ Add(name, "");
+ break;
+ }
+ value = 0;
+ if (*str == '"')
+ {
+ //
+ // Ah! A quoted value. This should be easy to deal with...
+ // (Just kidding!)
+ //
+ str++;
+ while (*str && *str != '"')
+ {
+ value << *str++;
+ }
+ Add(name, value);
+ if (*str == '"')
+ str++;
+ continue;
+ }
+ else if (*str == '\'')
+ {
+ // A single quoted value.
+ str++;
+ while (*str && *str != '\'')
+ {
+ value << *str++;
+ }
+ Add(name, value);
+ if (*str == '\'')
+ str++;
+ continue;
+ }
+ else
+ {
+ //
+ // A non-quoted string. This string will terminate at the
+ // next blank
+ //
+ while (*str && !isspace(*str))
+ {
+ value << *str++;
+ }
+ Add(name, value);
+ continue;
+ }
+ }
+}
+
+
+//*********************************************************************
+// Add an entry to the configuration table, without allowing variable
+// or file expansion of the value.
+//
+void Configuration::Add(const String& name, const String& value)
+{
+ String escaped;
+ const char *s = value.get();
+ while (*s)
+ {
+ if (strchr("$`\\", *s))
+ escaped << '\\';
+ escaped << *s++;
+ }
+ ParsedString *ps = new ParsedString(escaped);
+ dcGlobalVars.Add(name, ps);
+}
+
+
+//*********************************************************************
+// Add an entry to the configuration table, allowing parsing for variable
+// or file expansion of the value.
+//
+void Configuration::AddParsed(const String& name, const String& value)
+{
+ ParsedString *ps = new ParsedString(value);
+ if (mystrcasecmp(name, "locale") == 0)
+ {
+ String str(setlocale(LC_ALL, ps->get(dcGlobalVars)));
+ ps->set(str);
+
+ //
+ // Set time format to standard to avoid sending If-Modified-Since
+ // http headers in native format which http servers can't
+ // understand
+ //
+ setlocale(LC_TIME, "C");
+ }
+ dcGlobalVars.Add(name, ps);
+}
+
+
+//*********************************************************************
+// Remove an entry from both the hash table and from the list of keys.
+//
+int Configuration::Remove(const String& name)
+{
+ return dcGlobalVars.Remove(name);
+}
+
+
+//*********************************************************************
+// char *Configuration::Find(const char *name) const
+// Retrieve a variable from the configuration database. This variable
+// will be parsed and a new String object will be returned.
+//
+const String Configuration::Find(const String& name) const
+{
+ ParsedString *ps = (ParsedString *) dcGlobalVars[name];
+ if (ps)
+ {
+ return ps->get(dcGlobalVars);
+ }
+ else
+ {
+#ifdef DEBUG
+ fprintf (stderr, "Could not find configuration option %s\n", (const char*)name);
+#endif
+ return 0;
+ }
+}
+
+//-
+// Return 1 if the value of configuration attribute <b>name</b> has
+// been set, 0 otherwise
+int Configuration::Exists(const String& name) const
+{
+ return dcGlobalVars.Exists(name);
+}
+
+//*********************************************************************
+Object *Configuration::Get_Object(char *name) {
+return dcGlobalVars[name];
+}
+
+
+//*********************************************************************
+//
+int Configuration::Value(const String& name, int default_value) const
+{
+ return Find(name).as_integer(default_value);
+}
+
+
+//*********************************************************************
+//
+double Configuration::Double(const String& name, double default_value) const
+{
+ return Find(name).as_double(default_value);
+}
+
+
+//*********************************************************************
+// int Configuration::Boolean(char *name, int default_value)
+//
+int Configuration::Boolean(const String& name, int default_value) const
+{
+ int value = default_value;
+ const String s = Find(name);
+ if (s[0])
+ {
+ if (s.nocase_compare("true") == 0 ||
+ s.nocase_compare("yes") == 0 ||
+ s.nocase_compare("1") == 0)
+ value = 1;
+ else if (s.nocase_compare("false") == 0 ||
+ s.nocase_compare("no") == 0 ||
+ s.nocase_compare("0") == 0)
+ value = 0;
+ }
+
+ return value;
+}
+
+
+//*********************************************************************
+//
+const String Configuration::operator[](const String& name) const
+{
+ return Find(name);
+}
+
+
+//*********************************************************************
+//
+int Configuration::Read(const String& filename)
+{
+ FILE* in = fopen((const char*)filename, "r");
+
+ if(!in) {
+ fprintf(stderr, "Configuration::Read: cannot open %s for reading : ", (const char*)filename);
+ perror("");
+ return NOTOK;
+ }
+
+#define CONFIG_BUFFER_SIZE (50*1024)
+ //
+ // Make the line buffer large so that we can read long lists of start
+ // URLs.
+ //
+ char buffer[CONFIG_BUFFER_SIZE + 1];
+ char *current;
+ String line;
+ String name;
+ char *value;
+ int len;
+ while (fgets(buffer, CONFIG_BUFFER_SIZE, in))
+ {
+ line << buffer;
+ line.chop("\r\n");
+ if (line.last() == '\\')
+ {
+ line.chop(1);
+ continue; // Append the next line to this one
+ }
+
+ current = line.get();
+ if (*current == '#' || *current == '\0')
+ {
+ line = 0;
+ continue; // Comments and blank lines are skipped
+ }
+
+ name = strtok(current, ": =\t");
+ value = strtok(0, "\r\n");
+ if (!value)
+ value = ""; // Blank value
+
+ //
+ // Skip any whitespace before the actual text
+ //
+ while (*value == ' ' || *value == '\t')
+ value++;
+ len = strlen(value) - 1;
+ //
+ // Skip any whitespace after the actual text
+ //
+ while (len >= 0 && (value[len] == ' ' || value[len] == '\t'))
+ {
+ value[len] = '\0';
+ len--;
+ }
+
+ if (mystrcasecmp((char*)name, "include") == 0)
+ {
+ ParsedString ps(value);
+ String str(ps.get(dcGlobalVars));
+ if (str[0] != '/') // Given file name not fully qualified
+ {
+ str = filename; // so strip dir. name from current one
+ len = str.lastIndexOf('/') + 1;
+ if (len > 0)
+ str.chop(str.length() - len);
+ else
+ str = ""; // No slash in current filename
+ str << ps.get(dcGlobalVars);
+ }
+ Read(str);
+ line = 0;
+ continue;
+ }
+
+ AddParsed(name, value);
+ line = 0;
+ }
+ fclose(in);
+ return OK;
+}
+
+
+//*********************************************************************
+// void Configuration::Defaults(ConfigDefaults *array)
+//
+void Configuration::Defaults(const ConfigDefaults *array)
+{
+ for (int i = 0; array[i].name; i++)
+ {
+ AddParsed(array[i].name, array[i].value);
+ }
+}
+