1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
/*************************************************
* Configuration Reader Source File *
* (C) 1999-2005 The Botan Project *
*************************************************/
#include <botan/conf.h>
#include <botan/lookup.h>
#include <botan/look_add.h>
#include <botan/oids.h>
#include <botan/charset.h>
#include <botan/parsing.h>
#include <fstream>
#include <map>
namespace Botan {
namespace {
/*************************************************
* Strip comments and whitespace from line *
*************************************************/
std::string strip_whitespace(const std::string& line)
{
bool is_escaped = false, in_quote = false, in_string = false;
std::string new_line;
for(std::string::const_iterator j = line.begin(); j != line.end(); j++)
{
const char c = *j;
if(c == '"' && !is_escaped && !in_string)
{ in_quote = !in_quote; continue; }
if(c == '\'' && !is_escaped && !in_quote)
{ in_string = !in_string; continue; }
if(c == '#' && !is_escaped && !in_quote && !in_string)
return new_line;
if(c == '\\' && !is_escaped) { is_escaped = true; continue; }
if(is_space(c) && !in_quote && !in_string && !is_escaped)
continue;
new_line += c;
is_escaped = false;
}
return new_line;
}
/*************************************************
* Do variable interpolation *
*************************************************/
std::string interpolate(const std::string& value,
const std::map<std::string, std::string>& variables)
{
std::string variable, suffix;
if(value.find('.') == std::string::npos)
variable = value;
else
{
variable = value.substr(0, value.find('.'));
suffix = value.substr(value.find('.'), std::string::npos);
}
if(variables.find(variable) != variables.end())
{
const std::string result = variables.find(variable)->second;
if(variable == result)
return value;
return interpolate(result, variables) + suffix;
}
return value;
}
}
namespace Config {
/*************************************************
* Load a configuration file *
*************************************************/
void load(const std::string& fsname)
{
std::ifstream config(fsname.c_str());
if(!config)
throw Config_Error("Could not open config file " + fsname);
u32bit line_no = 0;
std::string line, section;
std::map<std::string, std::string> variables;
while(std::getline(config, line))
{
line_no++;
line = strip_whitespace(line);
if(line == "")
continue;
if(line[0] == '[' && line[line.size()-1] == ']')
{
section = line.substr(1, line.size() - 2);
if(section == "")
throw Config_Error("Empty section name", line_no);
continue;
}
if(section == "")
throw Config_Error("Section must be set before assignment", line_no);
std::vector<std::string> name_and_value;
try {
name_and_value = split_on(line, '=');
}
catch(Format_Error)
{
throw Config_Error("Bad assignment: " + line, line_no);
}
if(name_and_value.size() != 2)
throw Config_Error("Bad line: " + line, line_no);
const std::string name = name_and_value[0];
const std::string value = interpolate(name_and_value[1], variables);
if(variables.find(name) == variables.end())
variables[name] = value;
if(section == "oids")
OIDS::add_oid(OID(value), name);
else if(section == "aliases")
add_alias(name, value);
else
set(section + '/' + name, value);
}
}
}
}
|