Files
NeoTachyon/tachyon/files/usr/lib/providers/status.uc
T

323 lines
10 KiB
Ucode

#!/usr/bin/env ucode
let fs = require("fs");
let common = require("core.common");
let as_string = common.as_string;
let write_json = common.write_json;
let read_json_file = common.read_json_file;
let read_stdin = common.read_stdin;
let array_or_empty = common.array_or_empty;
function int_arg(value) {
value = as_string(value);
return value == "" ? 0 : int(value, 10);
}
function bool_arg(value) {
value = as_string(value);
return value == "1" || value == "true";
}
function first_field(line) {
let fields = split(trim(as_string(line)), /[ \t\r\n]+/);
return length(fields) > 0 ? as_string(fields[0]) : "";
}
function stdin_first_nonempty_field() {
for (let line in split(read_stdin(), "\n")) {
let field = first_field(line);
if (field != "") {
print(field, "\n");
return;
}
}
}
function stdin_first_line_version_field() {
let data = read_stdin();
let newline = index(data, "\n");
let line = newline >= 0 ? substr(data, 0, newline) : data;
if (match(line, /^.*version[ \t]*/) == null)
return;
let field = first_field(replace(line, /^.*version[ \t]*/, ""));
if (field != "")
print(field, "\n");
}
function byedpi_restart_count_file(path) {
let data = fs.readfile(path);
let count = 0;
if (data != null)
for (let line in split(data, "\n"))
if (match(as_string(line), /ciadpi for rule .* exited with code/) != null)
count++;
print(count, "\n");
}
function byedpi_validation_result(valid, message, needle) {
let needles = [];
if (!bool_arg(valid)) {
for (let line in split(read_stdin(), "\n")) {
if (line != "")
push(needles, line);
}
}
write_json({
valid: bool_arg(valid),
message: as_string(message),
needle: as_string(needle),
needles
});
}
function has_socks_outbound(config_path, tag, address, port) {
let config = read_json_file(config_path);
port = int_arg(port);
for (let outbound in array_or_empty(config && config.outbounds)) {
if (type(outbound) == "object" &&
outbound.type == "socks" &&
outbound.tag == tag &&
outbound.server == address &&
int(outbound.server_port || 0) == port)
return true;
}
return false;
}
function has_direct_mark_outbound(config_path, tag, routing_mark) {
let config = read_json_file(config_path);
routing_mark = int_arg(routing_mark);
for (let outbound in array_or_empty(config && config.outbounds)) {
if (type(outbound) == "object" &&
outbound.type == "direct" &&
outbound.tag == tag &&
int(outbound.routing_mark || 0) == routing_mark)
return true;
}
return false;
}
function has_route_rule(config_path, inbound, outbound_tag) {
let config = read_json_file(config_path);
for (let rule in array_or_empty(config && config.route && config.route.rules)) {
if (type(rule) == "object" &&
rule.action == "route" &&
rule.inbound == inbound &&
rule.outbound == outbound_tag)
return true;
}
return false;
}
function value_contains(value, needle) {
if (type(value) == "array") {
for (let item in value) {
if (as_string(item) == needle)
return true;
}
return false;
}
return as_string(value) == needle;
}
function find_tagged_item(items, tag) {
for (let item in array_or_empty(items)) {
if (type(item) == "object" && item.tag == tag)
return item;
}
return null;
}
function tagged_runtime_summary(config_path, section_name, tag) {
let config = read_json_file(config_path);
let item = find_tagged_item(config && config[section_name], tag);
if (item == null) {
write_json({ exists: 0 });
return;
}
write_json({
exists: 1,
type: as_string(item.type),
listen: as_string(item.listen),
listen_port: int_arg(item.listen_port)
});
}
function has_route_rule_for_inbound(config_path, inbound) {
let config = read_json_file(config_path);
for (let rule in array_or_empty(config && config.route && config.route.rules)) {
if (type(rule) == "object" &&
(rule.action == "route" || rule.action == "reject") &&
value_contains(rule.inbound, inbound))
return true;
}
return false;
}
function byedpi_status(args) {
write_json({
installed: bool_arg(args[0]),
package_installed: bool_arg(args[1]),
provider_available: bool_arg(args[2]),
provider_path: as_string(args[3]),
version: as_string(args[4]),
configured: bool_arg(args[5]),
enabled_rule_count: int_arg(args[6]),
expected_process_count: int_arg(args[7]),
running_process_count: int_arg(args[8]),
supervisor_process_count: int_arg(args[9]),
restart_count: int_arg(args[10]),
runtime_unstable: bool_arg(args[11]),
standalone_service_enabled: bool_arg(args[12]),
standalone_service_running: bool_arg(args[13]),
listen_address: as_string(args[14]),
port_base: int_arg(args[15]),
outbounds_configured: bool_arg(args[16]),
routes_configured: bool_arg(args[17]),
ready: bool_arg(args[18]),
conflict: bool_arg(args[19]),
status_message: as_string(args[20])
});
}
function byedpi_check(installed, package_installed, provider_path) {
write_json({
byedpi_installed: bool_arg(installed),
byedpi_package_installed: bool_arg(package_installed),
byedpi_provider_path: as_string(provider_path)
});
}
function zapret_status(args) {
write_json({
installed: bool_arg(args[0]),
package_installed: bool_arg(args[1]),
provider_available: bool_arg(args[2]),
provider_path: as_string(args[3]),
files_available: bool_arg(args[4]),
ipset_available: bool_arg(args[5]),
version: as_string(args[6]),
configured: bool_arg(args[7]),
enabled_rule_count: int_arg(args[8]),
expected_process_count: int_arg(args[9]),
running_process_count: int_arg(args[10]),
supervisor_process_count: int_arg(args[11]),
standalone_service_enabled: bool_arg(args[12]),
standalone_service_running: bool_arg(args[13]),
standalone_config_present: bool_arg(args[14]),
standalone_conflict: bool_arg(args[15]),
luci_app_installed: bool_arg(args[16]),
queue_base: int_arg(args[17]),
queue_range_end: int_arg(args[18]),
queue_overlap: bool_arg(args[19]),
legacy_runtime_present: bool_arg(args[20]),
ready: bool_arg(args[21]),
conflict: bool_arg(args[22]),
outbounds_configured: bool_arg(args[23]),
routes_configured: bool_arg(args[24]),
status_message: as_string(args[25])
});
}
function zapret_check(installed, package_installed, provider_path) {
write_json({
zapret_installed: bool_arg(installed),
zapret_package_installed: bool_arg(package_installed),
zapret_provider_path: as_string(provider_path)
});
}
function zapret2_status(args) {
write_json({
installed: bool_arg(args[0]),
package_installed: bool_arg(args[1]),
provider_available: bool_arg(args[2]),
provider_path: as_string(args[3]),
files_available: bool_arg(args[4]),
ipset_available: bool_arg(args[5]),
version: as_string(args[6]),
configured: bool_arg(args[7]),
enabled_rule_count: int_arg(args[8]),
expected_process_count: int_arg(args[9]),
running_process_count: int_arg(args[10]),
supervisor_process_count: int_arg(args[11]),
standalone_service_enabled: bool_arg(args[12]),
standalone_service_running: bool_arg(args[13]),
standalone_config_present: bool_arg(args[14]),
standalone_conflict: bool_arg(args[15]),
luci_app_installed: bool_arg(args[16]),
queue_base: int_arg(args[17]),
queue_range_end: int_arg(args[18]),
queue_overlap: bool_arg(args[19]),
ready: bool_arg(args[20]),
conflict: bool_arg(args[21]),
outbounds_configured: bool_arg(args[22]),
routes_configured: bool_arg(args[23]),
status_message: as_string(args[24])
});
}
function zapret2_check(installed, package_installed, provider_path) {
write_json({
zapret2_installed: bool_arg(installed),
zapret2_package_installed: bool_arg(package_installed),
zapret2_provider_path: as_string(provider_path)
});
}
let mode = ARGV[0] || "";
if (mode == "byedpi-validation")
byedpi_validation_result(ARGV[1], ARGV[2], ARGV[3]);
else if (mode == "stdin-first-nonempty-field")
stdin_first_nonempty_field();
else if (mode == "stdin-first-line-version-field")
stdin_first_line_version_field();
else if (mode == "byedpi-restart-count-file")
byedpi_restart_count_file(ARGV[1]);
else if (mode == "has-socks-outbound")
exit(has_socks_outbound(ARGV[1], ARGV[2], ARGV[3], ARGV[4]) ? 0 : 1);
else if (mode == "has-direct-mark-outbound")
exit(has_direct_mark_outbound(ARGV[1], ARGV[2], ARGV[3]) ? 0 : 1);
else if (mode == "has-route-rule")
exit(has_route_rule(ARGV[1], ARGV[2], ARGV[3]) ? 0 : 1);
else if (mode == "inbound-summary")
tagged_runtime_summary(ARGV[1], "inbounds", ARGV[2]);
else if (mode == "endpoint-summary")
tagged_runtime_summary(ARGV[1], "endpoints", ARGV[2]);
else if (mode == "has-route-rule-for-inbound")
exit(has_route_rule_for_inbound(ARGV[1], ARGV[2]) ? 0 : 1);
else if (mode == "byedpi-status")
byedpi_status(slice(ARGV, 1));
else if (mode == "byedpi-check")
byedpi_check(ARGV[1], ARGV[2], ARGV[3]);
else if (mode == "zapret-status")
zapret_status(slice(ARGV, 1));
else if (mode == "zapret-check")
zapret_check(ARGV[1], ARGV[2], ARGV[3]);
else if (mode == "zapret2-status")
zapret2_status(slice(ARGV, 1));
else if (mode == "zapret2-check")
zapret2_check(ARGV[1], ARGV[2], ARGV[3]);
else {
warn("Usage: providers/status.uc <operation> ...\n");
exit(1);
}