Configure the link.
If argp is provided for argument parsing, it is used.
This includes:
- processing command-line arguments
- setting broker urls
- loading dslink.json files
- loading or creating private keys
Source
bool configure({ArgParser argp, OptionResultsHandler optionsHandler}) {
_configured = true;
if (link != null) {
link.close();
link = null;
}
if (argp == null) {
argp = _argp == null ? _argp = new ArgParser(allowTrailingOptions: !strictOptions) : _argp;
}
argp.addOption("broker",
abbr: "b",
help: "Broker URL",
defaultsTo: "http://127.0.0.1:8080/conn");
argp.addOption("name", abbr: "n", help: "Link Name");
argp.addOption("home", help: "Home");
argp.addOption("token", help: "Token");
argp.addOption("base-path", help: "Base Path for DSLink");
argp.addOption("watch-file", help: "Watch File for DSLink", hide: true);
argp.addOption("log-file", help: "Log File for DSLink");
List<String> logLevelNames = Level.LEVELS.map(_logLevelToName).toList();
logLevelNames.addAll(["auto", "debug"]);
argp.addOption("log",
abbr: "l",
allowed: logLevelNames,
help: "Log Level",
defaultsTo: "AUTO");
argp.addFlag("help",
abbr: "h", help: "Displays this Help Message", negatable: false);
argp.addFlag("discover",
abbr: "d", help: "Automatically Discover a Broker", negatable: false);
argp.addFlag("strictTls",
help: "Enforces valid SSL/TLS certificates for secure connections to " +
"broker.");
ArgResults opts = _parsedArguments = argp.parse(args);
if (opts["log"] == "auto") {
if (DEBUG_MODE) {
updateLogLevel("all");
} else {
updateLogLevel(defaultLogLevel);
}
} else {
updateLogLevel(opts["log"]);
}
if (opts["base-path"] != null) {
_basePath = opts["base-path"];
if (_basePath.endsWith("/")) {
_basePath = _basePath.substring(0, _basePath.length - 1);
}
}
if (opts["watch-file"] != null) {
_watchFile = opts["watch-file"];
}
_logFile = opts["log-file"];
if (opts["strictTls"]) {
strictTls = true;
}
if (_logFile != null) {
var file = new File(_logFile);
if (!file.existsSync()) {
file.createSync(recursive: true);
}
logger.clearListeners();
IOSink out = _logFileOut = file.openWrite(mode: FileMode.APPEND);
logger.onRecord.listen((record) {
out.writeln("[${new DateTime.now()}][${record.level.name}] ${record.message}");
if (record.error != null) {
out.writeln(record.error);
}
if (record.stackTrace != null) {
out.writeln(record.stackTrace);
}
out.flush();
});
}
if (_watchFile != null) {
var file = new File(_watchFile);
StreamSubscription sub;
sub = file.watch(events: FileSystemEvent.DELETE).listen((_) {
close();
sub.cancel();
if (_logFileOut != null) {
try {
_logFileOut.close();
} catch (e) {}
}
});
}
if (const bool.fromEnvironment("dslink.debugger.console", defaultValue: false)) {
readStdinLines().listen((String cmd) {
if (cmd == "list-stored-nodes") {
if (provider is SimpleNodeProvider) {
SimpleNodeProvider prov = provider;
print(prov.nodes.keys.join("\n"));
} else {
print("Not a SimpleNodeProvider.");
}
} else if (cmd == "list-stub-nodes") {
if (provider is SimpleNodeProvider) {
SimpleNodeProvider prov = provider;
for (var node in prov.nodes.values) {
Path p = new Path(node.path);
if (prov.nodes[p.parentPath] == null) {
print(node.path);
} else if (!prov.nodes[p.parentPath].children.containsKey(p.name)) {
print(node.path);
}
}
} else {
print("Not a SimpleNodeProvider.");
}
}
});
}
{
var runtimeConfig = Zone.current["dslink.runtime.config"];
if (runtimeConfig != null) {
var closeHandler = () {
close();
if (_logFileOut != null) {
try {
_logFileOut.close();
} catch (e) {}
}
};
runtimeConfig["closeHandler"] = closeHandler;
}
}
String helpStr =
"usage: $command [--broker URL] [--log LEVEL] [--name NAME] [--discover]";
if (opts["help"]) {
print(helpStr);
print(argp.usage);
if (exitOnFailure) {
exit(1);
} else {
return false;
}
}
brokerUrl = opts["broker"];
if (brokerUrl == null && !opts["discover"]) {
print(
"No Broker URL Specified. One of [--broker, --discover] is required.");
print(helpStr);
print(argp.usage);
if (exitOnFailure) {
exit(1);
} else {
return false;
}
}
String name = opts["name"];
home = opts["home"];
token = opts["token"];
if (name != null) {
if (name.endsWith("-")) {
prefix = name;
} else {
prefix = "${name}-";
}
}
// load configs
File dslinkFile = new File("${_basePath}/dslink.json");
if (dslinkFile.existsSync()) {
var e;
try {
String configStr = dslinkFile.readAsStringSync();
dslinkJson = DsJson.decode(configStr);
} catch (err) {
e = err;
}
if (dslinkJson == null) {
logger.severe("Invalid dslink.json", e);
if (exitOnFailure) {
exit(1);
} else {
return false;
}
}
} else {
dslinkJson = {};
}
if (brokerUrl != null) {
if (!brokerUrl.startsWith("http")) {
brokerUrl = "http://$brokerUrl";
}
}
File keyFile = getConfig("key") == null
? new File("${_basePath}/.dslink.key")
: new File.fromUri(Uri.parse(getConfig("key")));
String key;
try {
key = keyFile.readAsStringSync();
privateKey = new PrivateKey.loadFromString(key);
} catch (err) {}
if (key == null || key.length != 131) {
// 43 bytes d, 87 bytes Q, 1 space
// generate the key
if (DSRandom.instance.needsEntropy) {
String macs;
if (Platform.isWindows) {
macs = Process.runSync("getmac", []).stdout.toString();
} else {
try {
macs = Process.runSync("arp", ["-an"]).stdout.toString();
} catch (e) {
try {
var envs = "";
for (var i in Platform.environment.keys) {
envs += "${i}=${Platform.environment[i]}\n";
}
macs = envs;
} catch (e) {}
}
}
// randomize the PRNG with the system mac (as well as timestamp)
DSRandom.instance.addEntropy(macs);
}
privateKey = new PrivateKey.generateSync();
key = privateKey.saveToString();
if (savePrivateKey) {
keyFile.writeAsStringSync(key);
}
}
SimpleNode.initEncryption(privateKey.saveToString());
if (opts["discover"]) {
_discoverBroker = true;
}
if (optionsHandler != null) {
optionsHandler(opts);
}
return true;
}