bool configure({ArgParser argp, OptionResultsHandler optionsHandler })

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;
}