void ServerConfig::Apply(ServerConfig* old, const std::string &useruid) { valid = true; if (old) { /* * These values can only be set on boot. Keep their old values. Do it before we send messages so we actually have a servername. */ this->ServerName = old->ServerName; this->sid = old->sid; this->cmdline = old->cmdline; } /* The stuff in here may throw CoreException, be sure we're in a position to catch it. */ try { for (int index = 0; index * sizeof(DeprecatedConfig) < sizeof(ChangedConfig); index++) { std::string value; ConfigTagList tags = ConfTags(ChangedConfig[index].tag); for(ConfigIter i = tags.first; i != tags.second; ++i) { if (i->second->readString(ChangedConfig[index].key, value, true) && (ChangedConfig[index].value.empty() || value == ChangedConfig[index].value)) { errstr << "Your configuration contains a deprecated value: <" << ChangedConfig[index].tag; if (ChangedConfig[index].value.empty()) { errstr << ':' << ChangedConfig[index].key; } else { errstr << ' ' << ChangedConfig[index].key << "=\"" << ChangedConfig[index].value << "\""; } errstr << "> - " << ChangedConfig[index].reason << " (at " << i->second->getTagLocation() << ")\n"; } } } Fill(); // Handle special items CrossCheckOperClassType(); CrossCheckConnectBlocks(old); } catch (CoreException &ce) { errstr << ce.GetReason(); } // Check errors before dealing with failed binds, since continuing on failed bind is wanted in some circumstances. valid = errstr.str().empty(); // write once here, to try it out and make sure its ok if (valid) ServerInstance->WritePID(this->PID); if (old) { // On first run, ports are bound later on FailedPortList pl; ServerInstance->BindPorts(pl); if (pl.size()) { errstr << "Not all your client ports could be bound.\nThe following port(s) failed to bind:\n"; int j = 1; for (FailedPortList::iterator i = pl.begin(); i != pl.end(); i++, j++) { char buf[MAXBUF]; snprintf(buf, MAXBUF, "%d. Address: %s Reason: %s\n", j, i->first.empty() ? "<all>" : i->first.c_str(), i->second.c_str()); errstr << buf; } } } User* user = useruid.empty() ? NULL : ServerInstance->FindNick(useruid); if (!valid) ServerInstance->Logs->Log("CONFIG",LOG_DEFAULT, "There were errors in your configuration file:"); while (errstr.good()) { std::string line; getline(errstr, line, '\n'); if (line.empty()) continue; // On startup, print out to console (still attached at this point) if (!old) std::cout << line << std::endl; // If a user is rehashing, tell them directly if (user) user->SendText(":%s NOTICE %s :*** %s", ServerInstance->Config->ServerName.c_str(), user->nick.c_str(), line.c_str()); // Also tell opers ServerInstance->SNO->WriteGlobalSno('a', line); } errstr.clear(); errstr.str(std::string()); // Re-parse our MOTD and RULES files for colors -- Justasic for (ClassVector::const_iterator it = this->Classes.begin(), it_end = this->Classes.end(); it != it_end; ++it) { ConfigTag *tag = (*it)->config; // Make sure our connection class allows motd colors if(!tag->getBool("allowmotdcolors")) continue; ConfigFileCache::iterator file = this->Files.find(tag->getString("motd", "motd")); if (file != this->Files.end()) InspIRCd::ProcessColors(file->second); file = this->Files.find(tag->getString("rules", "rules")); if (file != this->Files.end()) InspIRCd::ProcessColors(file->second); } /* No old configuration -> initial boot, nothing more to do here */ if (!old) { if (!valid) { ServerInstance->Exit(EXIT_STATUS_CONFIG); } return; } // If there were errors processing configuration, don't touch modules. if (!valid) return; ApplyModules(user); if (user) user->SendText(":%s NOTICE %s :*** Successfully rehashed server.", ServerInstance->Config->ServerName.c_str(), user->nick.c_str()); ServerInstance->SNO->WriteGlobalSno('a', "*** Successfully rehashed server."); }
void ServerConfig::Apply(ServerConfig* old, const std::string &useruid) { valid = true; if (old) { /* * These values can only be set on boot. Keep their old values. Do it before we send messages so we actually have a servername. */ this->CaseMapping = old->CaseMapping; this->ServerName = old->ServerName; this->sid = old->sid; this->cmdline = old->cmdline; } /* The stuff in here may throw CoreException, be sure we're in a position to catch it. */ try { // Ensure the user has actually edited ther config. ConfigTagList dietags = ConfTags("die"); if (dietags.first != dietags.second) { errstr << "Your configuration has not been edited correctly!" << std::endl; for (ConfigIter iter = dietags.first; iter != dietags.second; ++iter) { ConfigTag* tag = iter->second; const std::string reason = tag->getString("reason", "You left a <die> tag in your config", 1); errstr << reason << " (at " << tag->getTagLocation() << ")" << std::endl; } } Fill(); // Handle special items CrossCheckOperClassType(); CrossCheckConnectBlocks(old); } catch (CoreException &ce) { errstr << ce.GetReason() << std::endl; } // Check errors before dealing with failed binds, since continuing on failed bind is wanted in some circumstances. valid = errstr.str().empty(); // write once here, to try it out and make sure its ok if (valid) ServerInstance->WritePID(this->PID, !old); ConfigTagList binds = ConfTags("bind"); if (binds.first == binds.second) errstr << "Possible configuration error: you have not defined any <bind> blocks." << std::endl << "You will need to do this if you want clients to be able to connect!" << std::endl; if (old && valid) { // On first run, ports are bound later on FailedPortList pl; ServerInstance->BindPorts(pl); if (pl.size()) { errstr << "Not all your client ports could be bound." << std::endl << "The following port(s) failed to bind:" << std::endl; int j = 1; for (FailedPortList::iterator i = pl.begin(); i != pl.end(); i++, j++) { errstr << j << ".\tAddress: " << i->first.str() << "\tReason: " << strerror(i->second) << std::endl; } } } User* user = useruid.empty() ? NULL : ServerInstance->FindNick(useruid); if (!valid) { ServerInstance->Logs.Log("CONFIG", LOG_DEFAULT, "There were errors in your configuration file:"); Classes.clear(); } while (errstr.good()) { std::string line; getline(errstr, line, '\n'); if (line.empty()) continue; // On startup, print out to console (still attached at this point) if (!old) std::cout << line << std::endl; // If a user is rehashing, tell them directly if (user) user->WriteRemoteNotice(InspIRCd::Format("*** %s", line.c_str())); // Also tell opers ServerInstance->SNO.WriteGlobalSno('a', line); } errstr.clear(); errstr.str(std::string()); /* No old configuration -> initial boot, nothing more to do here */ if (!old) { if (!valid) { ServerInstance->Exit(EXIT_STATUS_CONFIG); } return; } // If there were errors processing configuration, don't touch modules. if (!valid) return; ApplyModules(user); if (user) user->WriteRemoteNotice("*** Successfully rehashed server."); ServerInstance->SNO.WriteGlobalSno('a', "*** Successfully rehashed server."); }