260 lines
8.6 KiB
Ucode
260 lines
8.6 KiB
Ucode
#!/usr/bin/env ucode
|
|
|
|
let fs = require("fs");
|
|
let common = require("core.common");
|
|
let as_string = common.as_string;
|
|
let shell_quote = common.shell_quote;
|
|
let command_from_args = common.command_from_args;
|
|
let command_output = common.command_output;
|
|
let command_status = common.command_status;
|
|
|
|
function command_output_args(args) {
|
|
return command_output(command_from_args(args));
|
|
}
|
|
|
|
function command_success(args) {
|
|
return command_status(command_from_args(args) + " >/dev/null 2>&1") == 0;
|
|
}
|
|
|
|
function command_exists(name) {
|
|
return system(command_from_args([ "command", "-v", name ]) + " >/dev/null 2>&1") == 0;
|
|
}
|
|
|
|
function binary_installed(package_name) {
|
|
if (package_name == "zapret2")
|
|
return fs.stat("/opt/zapret2/nfq2/nfqws2") != null || fs.stat("/opt/zapret2/nfqws2") != null || fs.stat("/usr/bin/nfqws2") != null;
|
|
if (package_name == "zapret")
|
|
return fs.stat("/opt/zapret/nfq/nfqws") != null || fs.stat("/opt/zapret/nfqws") != null;
|
|
if (package_name == "byedpi")
|
|
return fs.stat("/usr/bin/ciadpi") != null;
|
|
if (package_name == "fptn" || package_name == "fptn-client")
|
|
return fs.stat("/usr/bin/fptn-client-cli") != null || fs.stat("/usr/bin/fptn-client") != null;
|
|
if (package_name == "sing-box" || package_name == "sing-box-extended" || package_name == "sing-box-lx")
|
|
return fs.stat("/usr/bin/sing-box") != null;
|
|
return false;
|
|
}
|
|
|
|
function apk_installed(package_name) {
|
|
package_name = as_string(package_name);
|
|
if (command_exists("apk") && command_success([ "apk", "info", "-e", package_name ]))
|
|
return true;
|
|
return binary_installed(package_name);
|
|
}
|
|
|
|
function opkg_installed(package_name) {
|
|
package_name = as_string(package_name);
|
|
if (command_exists("opkg")) {
|
|
let prefix = package_name + " - ";
|
|
for (let line in split(command_output_args([ "opkg", "list-installed" ]), "\n")) {
|
|
line = trim(as_string(line));
|
|
if (substr(line, 0, length(prefix)) == prefix)
|
|
return true;
|
|
}
|
|
}
|
|
return binary_installed(package_name);
|
|
}
|
|
|
|
function installed(package_name) {
|
|
return apk_installed(package_name) || opkg_installed(package_name);
|
|
}
|
|
|
|
function apk_manifest_version(package_name, output) {
|
|
package_name = as_string(package_name);
|
|
let found = false;
|
|
|
|
for (let line in split(as_string(output), "\n")) {
|
|
line = trim(as_string(line));
|
|
if (substr(line, 0, 2) == "P:")
|
|
found = substr(line, 2) == package_name;
|
|
else if (found && substr(line, 0, 2) == "V:")
|
|
return substr(line, 2);
|
|
}
|
|
return "";
|
|
}
|
|
|
|
function apk_info_version(package_name, output) {
|
|
package_name = as_string(package_name);
|
|
let prefix = package_name + "-";
|
|
|
|
for (let line in split(as_string(output), "\n")) {
|
|
line = trim(as_string(line));
|
|
if (line == "")
|
|
continue;
|
|
if (substr(line, 0, length(prefix)) == prefix)
|
|
return substr(line, length(prefix));
|
|
}
|
|
return "";
|
|
}
|
|
|
|
function apk_list_version(package_name, output) {
|
|
package_name = as_string(package_name);
|
|
let prefix = package_name + "-";
|
|
|
|
for (let line in split(as_string(output), "\n")) {
|
|
for (let field in split(trim(as_string(line)), /[ \t]+/)) {
|
|
field = as_string(field);
|
|
if (substr(field, 0, length(prefix)) != prefix)
|
|
continue;
|
|
|
|
let version = substr(field, length(prefix));
|
|
if (version != "")
|
|
return version;
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
|
|
function apk_query_version(package_name, output) {
|
|
package_name = as_string(package_name);
|
|
let packages;
|
|
|
|
try {
|
|
packages = json(as_string(output));
|
|
}
|
|
catch (e) {
|
|
return "";
|
|
}
|
|
|
|
if (type(packages) != "array")
|
|
return "";
|
|
|
|
for (let package in packages) {
|
|
if (type(package) != "object" || as_string(package.name) != package_name)
|
|
continue;
|
|
|
|
let version = as_string(package.version);
|
|
if (version != "")
|
|
return version;
|
|
}
|
|
return "";
|
|
}
|
|
|
|
function binary_version(package_name) {
|
|
if (package_name == "zapret2") {
|
|
for (let p in [ "/opt/zapret2/nfq2/nfqws2", "/opt/zapret2/nfqws2", "/usr/bin/nfqws2" ]) {
|
|
if (fs.stat(p) != null) {
|
|
let out = command_output_args([ p, "--version" ]);
|
|
let m = match(out, /version[ \t]*([0-9a-zA-Z._-]+)/i);
|
|
if (m) return m[1];
|
|
}
|
|
}
|
|
}
|
|
if (package_name == "zapret") {
|
|
for (let p in [ "/opt/zapret/nfq/nfqws", "/opt/zapret/nfqws" ]) {
|
|
if (fs.stat(p) != null) {
|
|
let out = command_output_args([ p, "--version" ]);
|
|
let m = match(out, /version[ \t]*([0-9a-zA-Z._-]+)/i);
|
|
if (m) return m[1];
|
|
}
|
|
}
|
|
}
|
|
if (package_name == "byedpi" && fs.stat("/usr/bin/ciadpi") != null) {
|
|
let out = command_output_args([ "/usr/bin/ciadpi", "--version" ]);
|
|
let m = match(out, /([0-9a-zA-Z._-]+)/);
|
|
if (m) return m[1];
|
|
}
|
|
if ((package_name == "fptn" || package_name == "fptn-client")) {
|
|
for (let p in [ "/usr/bin/fptn-client-cli", "/usr/bin/fptn-client" ]) {
|
|
if (fs.stat(p) != null) {
|
|
let out = command_output_args([ p, "--version" ]);
|
|
let m = match(out, /version[ \t]*([0-9a-zA-Z._-]+)/i) || match(out, /([0-9]+\.[0-9a-zA-Z._-]+)/);
|
|
if (m) return m[1];
|
|
}
|
|
}
|
|
}
|
|
if ((package_name == "sing-box" || package_name == "sing-box-extended" || package_name == "sing-box-lx") && fs.stat("/usr/bin/sing-box") != null) {
|
|
let out = command_output_args([ "/usr/bin/sing-box", "version" ]);
|
|
let m = match(out, /version[ \t]*([0-9a-zA-Z._-]+)/i);
|
|
if (m) return m[1];
|
|
}
|
|
return "";
|
|
}
|
|
|
|
function apk_version(package_name) {
|
|
package_name = as_string(package_name);
|
|
if (!apk_installed(package_name))
|
|
return "";
|
|
|
|
let version = apk_list_version(package_name, command_output_args([ "apk", "list", "--installed", package_name ]));
|
|
if (version != "")
|
|
return version;
|
|
|
|
version = apk_info_version(package_name, command_output_args([ "apk", "info", "-v", package_name ]));
|
|
if (version != "")
|
|
return version;
|
|
|
|
version = apk_manifest_version(package_name, command_output_args([ "apk", "list", "--installed", "--manifest", package_name ]));
|
|
if (version != "")
|
|
return version;
|
|
|
|
version = apk_manifest_version(package_name, command_output_args([ "apk", "list", "--installed", "--manifest" ]));
|
|
if (version != "")
|
|
return version;
|
|
|
|
return binary_version(package_name);
|
|
}
|
|
|
|
function apk_available_version(package_name) {
|
|
package_name = as_string(package_name);
|
|
if (!command_exists("apk"))
|
|
return "";
|
|
return apk_query_version(
|
|
package_name,
|
|
command_output_args([ "apk", "query", "--from", "repositories", "--available", "--format", "json", "--fields", "name,version", package_name ])
|
|
);
|
|
}
|
|
|
|
function opkg_version(package_name) {
|
|
package_name = as_string(package_name);
|
|
if (command_exists("opkg")) {
|
|
let prefix = package_name + " - ";
|
|
for (let line in split(command_output_args([ "opkg", "list-installed" ]), "\n")) {
|
|
line = trim(as_string(line));
|
|
if (substr(line, 0, length(prefix)) == prefix)
|
|
return substr(line, length(prefix));
|
|
}
|
|
}
|
|
return binary_version(package_name);
|
|
}
|
|
|
|
function version(package_name) {
|
|
let value = apk_version(package_name);
|
|
return value != "" ? value : opkg_version(package_name);
|
|
}
|
|
|
|
function module_exports() {
|
|
return {
|
|
installed: installed,
|
|
apk_installed: apk_installed,
|
|
opkg_installed: opkg_installed,
|
|
version: version,
|
|
installed_package_version: version,
|
|
apk_version: apk_version,
|
|
apk_available_version: apk_available_version,
|
|
opkg_version: opkg_version
|
|
};
|
|
}
|
|
|
|
if ((sourcepath(1) != null && sourcepath(1) != "") || ARGV[0] == null)
|
|
return module_exports();
|
|
|
|
let mode = ARGV[0] || "";
|
|
|
|
if (mode == "installed")
|
|
exit(installed(ARGV[1]) ? 0 : 1);
|
|
else if (mode == "apk-installed")
|
|
exit(apk_installed(ARGV[1]) ? 0 : 1);
|
|
else if (mode == "opkg-installed")
|
|
exit(opkg_installed(ARGV[1]) ? 0 : 1);
|
|
else if (mode == "version")
|
|
print(version(ARGV[1]), "\n");
|
|
else if (mode == "apk-version")
|
|
print(apk_version(ARGV[1]), "\n");
|
|
else if (mode == "apk-available-version")
|
|
print(apk_available_version(ARGV[1]), "\n");
|
|
else if (mode == "opkg-version")
|
|
print(opkg_version(ARGV[1]), "\n");
|
|
else {
|
|
warn("Usage: core/packages.uc <installed|apk-installed|opkg-installed|version|apk-version|apk-available-version|opkg-version> <package>\n");
|
|
exit(1);
|
|
} |