static enum ParsingStates {atParseKey, atParseValue} KvPairState_; ///< Parsing state while parsing kv-pair tokens
};
-int parseConfigFile(const char *file_name);
+namespace Configuration {
+/// interprets (and partially applies) squid.conf or equivalent configuration
+void Parse();
+}
#endif /* SQUID_SRC_CONFIGPARSER_H */
} else {
try {
if (!parse_line(tmp_line)) {
- debugs(3, DBG_CRITICAL, ConfigParser::CurrentLocation() << ": unrecognized: '" << tmp_line << "'");
+ debugs(3, DBG_CRITICAL, "ERROR: unrecognized directive near '" << tmp_line << "'" <<
+ Debug::Extra << "directive location: " << ConfigParser::CurrentLocation());
++err_count;
}
} catch (...) {
return err_count;
}
-static
-int
-parseConfigFileOrThrow(const char *file_name)
+void
+Configuration::Parse()
{
- int err_count = 0;
-
debugs(5, 4, MYNAME);
configFreeMemory();
ACLMethodData::ThePurgeCount = 0;
default_all();
- err_count = parseOneConfigFile(file_name, 0);
+ const auto unrecognizedDirectives = parseOneConfigFile(ConfigFile, 0);
defaults_if_none();
*/
configDoConfigure();
+ // TODO: Throw before configDoConfigure(). Doing that would reduce the set
+ // of configuration errors Squid can detect in one execution, but we should
+ // not apply a clearly broken configuration, especially when we are going to
+ // quit anyway. While some legacy parse_foo() functions apply significant
+ // changes before configDoConfigure(), we cannot easily stop them. We can
+ // easily stop configDoConfigure().
+ if (unrecognizedDirectives)
+ throw TextException(ToSBuf("Found ", unrecognizedDirectives, " unrecognized directive(s)"), Here());
+
if (opt_send_signal == -1) {
Mgr::RegisterAction("config",
"Current Squid Configuration",
dump_config,
1, 1);
}
-
- return err_count;
-}
-
-// TODO: Refactor main.cc to centrally handle (and report) all exceptions.
-int
-parseConfigFile(const char *file_name)
-{
- try {
- return parseConfigFileOrThrow(file_name);
- }
- catch (const std::exception &ex) {
- debugs(3, DBG_CRITICAL, "FATAL: bad configuration: " << ex.what());
- self_destruct();
- return 1; // not reached
- }
}
/*
false);
}
+/// error message to log when Configuration::Parse() fails
+static SBuf
+ConfigurationFailureMessage()
+{
+ SBufStream out;
+ out << (reconfiguring ? "re" : "");
+ out << "configuration failure: " << CurrentException;
+ if (!opt_parse_cfg_only)
+ out << Debug::Extra << "advice: Run 'squid -k parse' and check for ERRORs.";
+ return out.buf();
+}
+
static void
mainReconfigureFinish(void *)
{
if (Config2.onoff.enable_purge)
Config2.onoff.enable_purge = 2;
- // parse the config returns a count of errors encountered.
const int oldWorkers = Config.workers;
+
try {
- if (parseConfigFile(ConfigFile) != 0) {
- // for now any errors are a fatal condition...
- self_destruct();
- }
+ Configuration::Parse();
} catch (...) {
// for now any errors are a fatal condition...
- debugs(1, DBG_CRITICAL, "FATAL: Unhandled exception parsing config file. " <<
- " Run squid -k parse and check for errors.");
- self_destruct();
+ fatal(ConfigurationFailureMessage().c_str());
}
if (oldWorkers != Config.workers) {
/* parse configuration file
* note: in "normal" case this used to be called from mainInitialize() */
{
- int parse_err;
-
if (!ConfigFile)
ConfigFile = xstrdup(DEFAULT_CONFIG_FILE);
RunRegisteredHere(RegisteredRunner::bootstrapConfig);
try {
- parse_err = parseConfigFile(ConfigFile);
+ Configuration::Parse();
} catch (...) {
- // for now any errors are a fatal condition...
- debugs(1, DBG_CRITICAL, "FATAL: Unhandled exception parsing config file." <<
- (opt_parse_cfg_only ? " Run squid -k parse and check for errors." : ""));
- parse_err = 1;
+ auto msg = ConfigurationFailureMessage();
+ if (opt_parse_cfg_only) {
+ debugs(3, DBG_CRITICAL, "FATAL: " << msg);
+ return EXIT_FAILURE;
+ } else {
+ fatal(msg.c_str());
+ return EXIT_FAILURE; // unreachable
+ }
}
- if (opt_parse_cfg_only || parse_err > 0)
- return parse_err;
+ if (opt_parse_cfg_only)
+ return EXIT_SUCCESS;
}
setUmask(Config.umask);