mirror of
https://github.com/RangeNetworks/openbts.git
synced 2025-10-24 16:43:58 +00:00
247 lines
7.5 KiB
C++
247 lines
7.5 KiB
C++
/*
|
|
* Copyright 2014 Range Networks, Inc.
|
|
*
|
|
* This software is distributed under multiple licenses;
|
|
* see the COPYING file in the main directory for licensing
|
|
* information for this specific distribution.
|
|
*
|
|
* This use of this software may be subject to additional restrictions.
|
|
* See the LEGAL file in the main directory for details.
|
|
|
|
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.
|
|
|
|
*/
|
|
|
|
#include <ostream>
|
|
#include <Globals.h>
|
|
#include <Configuration.h>
|
|
#include "CLI.h"
|
|
|
|
namespace CommandLine {
|
|
|
|
|
|
/** Print or modify the global configuration table. */
|
|
CLIStatus configCmd(string mode, int argc, char** argv, ostream& os)
|
|
{
|
|
// no args, just print
|
|
if (argc==1) {
|
|
ConfigurationKeyMap::iterator mp = gConfig.mSchema.begin();
|
|
while (mp != gConfig.mSchema.end()) {
|
|
if (mode.compare("customer") == 0) {
|
|
if (mp->second.getVisibility() == ConfigurationKey::CUSTOMER ||
|
|
mp->second.getVisibility() == ConfigurationKey::CUSTOMERSITE ||
|
|
mp->second.getVisibility() == ConfigurationKey::CUSTOMERTUNE ||
|
|
mp->second.getVisibility() == ConfigurationKey::CUSTOMERWARN) {
|
|
ConfigurationKey::printKey(mp->second, gConfig.getStr(mp->first), os);
|
|
}
|
|
} else if (mode.compare("developer") == 0) {
|
|
ConfigurationKey::printKey(mp->second, gConfig.getStr(mp->first), os);
|
|
}
|
|
mp++;
|
|
}
|
|
return SUCCESS;
|
|
}
|
|
|
|
// one arg
|
|
if (argc==2) {
|
|
// matches exactly? print single key
|
|
if (gConfig.keyDefinedInSchema(argv[1])) {
|
|
ConfigurationKey::printKey(gConfig.mSchema[argv[1]], gConfig.getStr(argv[1]), os);
|
|
ConfigurationKey::printDescription(gConfig.mSchema[argv[1]], os);
|
|
os << endl;
|
|
// ...otherwise print all similar keys
|
|
} else {
|
|
int foundCount = 0;
|
|
ConfigurationKeyMap matches = gConfig.getSimilarKeys(argv[1]);
|
|
ConfigurationKeyMap::iterator mp = matches.begin();
|
|
while (mp != matches.end()) {
|
|
if (mode.compare("customer") == 0) {
|
|
if (mp->second.getVisibility() == ConfigurationKey::CUSTOMER ||
|
|
mp->second.getVisibility() == ConfigurationKey::CUSTOMERSITE ||
|
|
mp->second.getVisibility() == ConfigurationKey::CUSTOMERTUNE ||
|
|
mp->second.getVisibility() == ConfigurationKey::CUSTOMERWARN) {
|
|
ConfigurationKey::printKey(mp->second, gConfig.getStr(mp->first), os);
|
|
foundCount++;
|
|
}
|
|
} else if (mode.compare("developer") == 0) {
|
|
ConfigurationKey::printKey(mp->second, gConfig.getStr(mp->first), os);
|
|
foundCount++;
|
|
}
|
|
mp++;
|
|
}
|
|
if (!foundCount) {
|
|
os << argv[1] << " - no keys matched";
|
|
if (mode.compare("customer") == 0) {
|
|
os << ", developer/factory keys can be accessed with \"devconfig\".";
|
|
} else if (mode.compare("developer") == 0) {
|
|
os << ", custom keys can be accessed with \"rawconfig\".";
|
|
}
|
|
os << endl;
|
|
}
|
|
}
|
|
return SUCCESS;
|
|
}
|
|
|
|
// >1 args: set new value
|
|
string val;
|
|
for (int i=2; i<argc; i++) {
|
|
val.append(argv[i]);
|
|
if (i!=(argc-1)) val.append(" ");
|
|
}
|
|
if (!gConfig.keyDefinedInSchema(argv[1])) {
|
|
os << argv[1] << " is not a valid key, change failed. If you're trying to define a custom key/value pair (e.g. the Log.Level.Filename.cpp pairs), use \"rawconfig\"." << endl;
|
|
return SUCCESS;
|
|
}
|
|
if (mode.compare("customer") == 0) {
|
|
if (gConfig.mSchema[argv[1]].getVisibility() == ConfigurationKey::DEVELOPER) {
|
|
os << argv[1] << " should only be changed by developers. Use \"devconfig\" if you are ABSOLUTELY sure this needs to be changed." << endl;
|
|
return SUCCESS;
|
|
}
|
|
if (gConfig.mSchema[argv[1]].getVisibility() == ConfigurationKey::FACTORY) {
|
|
os << argv[1] << " should only be set once by the factory. Use \"devconfig\" if you are ABSOLUTELY sure this needs to be changed." << endl;
|
|
return SUCCESS;
|
|
}
|
|
}
|
|
if (!gConfig.isValidValue(argv[1], val)) {
|
|
os << argv[1] << " new value \"" << val << "\" is invalid, change failed.";
|
|
if (mode.compare("developer") == 0) {
|
|
os << " To override the configuration value checks, use \"rawconfig\".";
|
|
}
|
|
os << endl;
|
|
return SUCCESS;
|
|
}
|
|
|
|
string previousVal = gConfig.getStr(argv[1]);
|
|
if (val.compare(previousVal) == 0) {
|
|
os << argv[1] << " is already set to \"" << val << "\", nothing changed" << endl;
|
|
return SUCCESS;
|
|
}
|
|
// TODO : removing of default values from DB disabled for now. Breaks webui.
|
|
// if (val.compare(gConfig.mSchema[argv[1]].getDefaultValue()) == 0) {
|
|
// if (!gConfig.remove(argv[1])) {
|
|
// os << argv[1] << " storing new value (default) failed" << endl;
|
|
// return SUCCESS;
|
|
// }
|
|
// } else {
|
|
if (!gConfig.set(argv[1],val)) {
|
|
os << "DB ERROR: " << argv[1] << " could not be updated" << endl;
|
|
return FAILURE;
|
|
}
|
|
// }
|
|
os << argv[1] << " changed from \"" << previousVal << "\" to \"" << val << "\"" << endl;
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
/** Disable a configuration key. */
|
|
CLIStatus unconfig(int argc, char** argv, ostream& os)
|
|
{
|
|
if (argc!=2) return BAD_NUM_ARGS;
|
|
|
|
if (!gConfig.defines(argv[1])) {
|
|
os << argv[1] << " is not in the table" << endl;
|
|
return BAD_VALUE;
|
|
}
|
|
|
|
if (gConfig.keyDefinedInSchema(argv[1]) && !gConfig.isValidValue(argv[1], "")) {
|
|
os << argv[1] << " is not disableable" << endl;
|
|
return BAD_VALUE;
|
|
}
|
|
|
|
if (!gConfig.set(argv[1], "")) {
|
|
os << "DB ERROR: " << argv[1] << " could not be disabled" << endl;
|
|
return FAILURE;
|
|
}
|
|
|
|
os << argv[1] << " disabled" << endl;
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
|
|
/** Set a configuration value back to default or remove from table if custom key. */
|
|
CLIStatus rmconfig(int argc, char** argv, ostream& os)
|
|
{
|
|
if (argc!=2) return BAD_NUM_ARGS;
|
|
|
|
if (!gConfig.defines(argv[1])) {
|
|
os << argv[1] << " is not in the table" << endl;
|
|
return BAD_VALUE;
|
|
}
|
|
|
|
// TODO : removing of default values from DB disabled for now. Breaks webui.
|
|
if (gConfig.keyDefinedInSchema(argv[1])) {
|
|
if (!gConfig.set(argv[1],gConfig.mSchema[argv[1]].getDefaultValue())) {
|
|
os << "DB ERROR: " << argv[1] << " could not be set back to the default value" << endl;
|
|
return FAILURE;
|
|
}
|
|
|
|
os << argv[1] << " set back to its default value" << endl;
|
|
vector<string> warnings = gConfig.crossCheck(argv[1]);
|
|
vector<string>::iterator warning = warnings.begin();
|
|
while (warning != warnings.end()) {
|
|
os << "WARNING: " << *warning << endl;
|
|
warning++;
|
|
}
|
|
if (gConfig.isStatic(argv[1])) {
|
|
os << argv[1] << " is static; change takes effect on restart" << endl;
|
|
}
|
|
return SUCCESS;
|
|
}
|
|
|
|
if (!gConfig.remove(argv[1])) {
|
|
os << "DB ERROR: " << argv[1] << " could not be removed from the configuration table" << endl;
|
|
return FAILURE;
|
|
}
|
|
|
|
os << argv[1] << " removed from the configuration table" << endl;
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
|
|
/** Print or modify the global configuration table. */
|
|
CLIStatus rawconfig(int argc, char** argv, ostream& os)
|
|
{
|
|
// no args, just print
|
|
if (argc==1) {
|
|
gConfig.find("",os);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// one arg, pattern match and print
|
|
if (argc==2) {
|
|
gConfig.find(argv[1],os);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// >1 args: set new value
|
|
string val;
|
|
for (int i=2; i<argc; i++) {
|
|
val.append(argv[i]);
|
|
if (i!=(argc-1)) val.append(" ");
|
|
}
|
|
bool existing = gConfig.defines(argv[1]);
|
|
string previousVal;
|
|
if (existing) {
|
|
previousVal = gConfig.getStr(argv[1]);
|
|
}
|
|
if (!gConfig.set(argv[1],val)) {
|
|
os << "DB ERROR: " << argv[1] << " change failed" << endl;
|
|
return FAILURE;
|
|
}
|
|
if (gConfig.isStatic(argv[1])) {
|
|
os << argv[1] << " is static; change takes effect on restart" << endl;
|
|
}
|
|
if (!existing) {
|
|
os << "defined new config " << argv[1] << " as \"" << val << "\"" << endl;
|
|
} else {
|
|
os << argv[1] << " changed from \"" << previousVal << "\" to \"" << val << "\"" << endl;
|
|
}
|
|
return SUCCESS;
|
|
}
|
|
|
|
}; // namespace
|