Files
debian/prebuilds/usr/local/lib/libnet.sh
T

156 lines
4.2 KiB
Bash

#!/bin/bash
# Ver: 1.3 by Endial Fang (endial@126.com)
#
# 文件管理函数库
# 加载依赖项
source "/usr/local/lib/liblog.sh"
source "/usr/local/lib/libos.sh"
source "/usr/local/lib/libvalidations.sh"
# 函数列表
# 域名解析
# 参数:
# $1 - 需要解析的主机名
# $2 - IP 地址版本 v4/v6, 为空时解析所有版本
# 返回值:
# IP地址
dns_lookup() {
local host="${1:?host is missing}"
local ip_version="${2:-}"
getent "ahosts${ip_version}" "$host" | awk '/STREAM/ {print $1 }' | head -n 1
}
# 尝试解析域名并返回对应的 IP
# 参数:
# $1 - 主机名
# $2 - 尝试次数
# $3 - 重试间隔时间(秒)
# 返回值:
# IP地址
wait_for_dns_lookup() {
local hostname="${1:?hostname is missing}"
local retries="${2:-5}"
local seconds="${3:-1}"
check_host() {
if [[ $(dns_lookup "$hostname") == "" ]]; then
false
else
true
fi
}
# Wait for the host to be ready
retry_while "check_host ${hostname}" "$retries" "$seconds"
dns_lookup "$hostname"
}
# 获取当前主机 IP
# 返回值:
# IP地址
get_machine_ip() {
local -a ip_addresses
local hostname
hostname="$(hostname)"
read -r -a ip_addresses <<< "$(dns_lookup "$hostname" | xargs echo)"
if [[ "${#ip_addresses[@]}" -gt 1 ]]; then
warn "Found more than one IP address associated to hostname ${hostname}: ${ip_addresses[*]}, will use ${ip_addresses[0]}"
elif [[ "${#ip_addresses[@]}" -lt 1 ]]; then
error "Could not find any IP address associated to hostname ${hostname}"
exit 1
fi
# Check if the first IP address is IPv6 to add brackets
if validate_ipv6 "${ip_addresses[0]}" ; then
echo "[${ip_addresses[0]}]"
else
echo "${ip_addresses[0]}"
fi
}
# 检测指定的主机名是否可解析
# 参数:
# $1 - 待检测的主机名
# 返回值:
# true / false
is_hostname_resolved() {
local -r host="${1:?missing value}"
if [[ -n "$(dns_lookup "$host")" ]]; then
true
else
false
fi
}
# 解析 URL
# 参数:
# $1 - URI 字符串
# $2 - 类型字符串. 有效值 (scheme, authority, userinfo, host, port, path, query or fragment)
# 返回值:
# 字符串
parse_uri() {
local uri="${1:?uri is missing}"
local component="${2:?component is missing}"
# Solution based on https://tools.ietf.org/html/rfc3986#appendix-B with
# additional sub-expressions to split authority into userinfo, host and port
# Credits to Patryk Obara (see https://stackoverflow.com/a/45977232/6694969)
local -r URI_REGEX='^(([^:/?#]+):)?(//((([^@/?#]+)@)?([^:/?#]+)(:([0-9]+))?))?(/([^?#]*))?(\?([^#]*))?(#(.*))?'
# || | ||| | | | | | | | | |
# |2 scheme | ||6 userinfo 7 host | 9 port | 11 rpath | 13 query | 15 fragment
# 1 scheme: | |5 userinfo@ 8 :... 10 path 12 ?... 14 #...
# | 4 authority
# 3 //...
local index=0
case "$component" in
scheme)
index=2
;;
authority)
index=4
;;
userinfo)
index=6
;;
host)
index=7
;;
port)
index=9
;;
path)
index=10
;;
query)
index=13
;;
fragment)
index=14
;;
*)
stderr_print "unrecognized component $component"
return 1
;;
esac
[[ "$uri" =~ $URI_REGEX ]] && echo "${BASH_REMATCH[${index}]}"
}
# Wait for a HTTP connection to succeed
# 等待 HTTP 连接成功
# 参数:
# $1 - URL 地址
# $2 - 最大重试次数 (可选)
# $3 - 重试间隔时间 (可选)
wait_for_http_connection() {
local url="${1:?missing url}"
local retries="${2:-}"
local sleep_time="${3:-}"
if ! retry_while "debug_execute curl --silent ${url}" "$retries" "$sleep_time"; then
error "Could not connect to ${url}"
return 1
fi
}