2016-04-17 11:47:22 +00:00
|
|
|
#!/usr/bin/env sh
|
2016-04-25 12:01:37 +00:00
|
|
|
|
2022-11-23 13:55:19 +00:00
|
|
|
VER=3.0.6
|
2016-04-13 12:37:18 +00:00
|
|
|
|
2016-04-14 13:44:26 +00:00
|
|
|
PROJECT_NAME="acme.sh"
|
2016-04-13 12:37:18 +00:00
|
|
|
|
2016-04-14 13:44:26 +00:00
|
|
|
PROJECT_ENTRY="acme.sh"
|
|
|
|
|
2020-01-30 02:50:39 +00:00
|
|
|
PROJECT="https://github.com/acmesh-official/$PROJECT_NAME"
|
2016-03-08 12:44:12 +00:00
|
|
|
|
2016-09-02 14:37:49 +00:00
|
|
|
DEFAULT_INSTALL_HOME="$HOME/.$PROJECT_NAME"
|
2019-03-13 12:42:02 +00:00
|
|
|
|
|
|
|
_WINDOWS_SCHEDULER_NAME="$PROJECT_NAME.cron"
|
|
|
|
|
2016-09-02 14:37:49 +00:00
|
|
|
_SCRIPT_="$0"
|
|
|
|
|
2019-04-29 14:13:54 +00:00
|
|
|
_SUB_FOLDER_NOTIFY="notify"
|
|
|
|
_SUB_FOLDER_DNSAPI="dnsapi"
|
|
|
|
_SUB_FOLDER_DEPLOY="deploy"
|
|
|
|
|
|
|
|
_SUB_FOLDERS="$_SUB_FOLDER_DNSAPI $_SUB_FOLDER_DEPLOY $_SUB_FOLDER_NOTIFY"
|
2016-09-02 14:37:49 +00:00
|
|
|
|
2020-08-11 15:28:52 +00:00
|
|
|
CA_LETSENCRYPT_V2="https://acme-v02.api.letsencrypt.org/directory"
|
|
|
|
CA_LETSENCRYPT_V2_TEST="https://acme-staging-v02.api.letsencrypt.org/directory"
|
2018-01-06 04:45:24 +00:00
|
|
|
|
2020-08-11 15:28:52 +00:00
|
|
|
CA_BUYPASS="https://api.buypass.com/acme/directory"
|
|
|
|
CA_BUYPASS_TEST="https://api.test4.buypass.no/acme/directory"
|
|
|
|
|
|
|
|
CA_ZEROSSL="https://acme.zerossl.com/v2/DV90"
|
2022-02-04 05:49:58 +00:00
|
|
|
_ZERO_EAB_ENDPOINT="https://api.zerossl.com/acme/eab-credentials-email"
|
2020-08-12 12:43:44 +00:00
|
|
|
|
2021-06-21 13:31:00 +00:00
|
|
|
CA_SSLCOM_RSA="https://acme.ssl.com/sslcom-dv-rsa"
|
|
|
|
CA_SSLCOM_ECC="https://acme.ssl.com/sslcom-dv-ecc"
|
|
|
|
|
2022-03-30 14:47:12 +00:00
|
|
|
CA_GOOGLE="https://dv.acme-v02.api.pki.goog/directory"
|
|
|
|
CA_GOOGLE_TEST="https://dv.acme-v02.test-api.pki.goog/directory"
|
|
|
|
|
2021-06-13 06:29:26 +00:00
|
|
|
DEFAULT_CA=$CA_ZEROSSL
|
2020-08-11 15:28:52 +00:00
|
|
|
DEFAULT_STAGING_CA=$CA_LETSENCRYPT_V2_TEST
|
|
|
|
|
|
|
|
CA_NAMES="
|
2021-06-21 13:31:00 +00:00
|
|
|
ZeroSSL.com,zerossl
|
2020-08-18 15:28:06 +00:00
|
|
|
LetsEncrypt.org,letsencrypt
|
|
|
|
LetsEncrypt.org_test,letsencrypt_test,letsencrypttest
|
2020-08-12 13:45:20 +00:00
|
|
|
BuyPass.com,buypass
|
|
|
|
BuyPass.com_test,buypass_test,buypasstest
|
2021-06-21 13:31:00 +00:00
|
|
|
SSL.com,sslcom
|
2022-03-30 14:47:12 +00:00
|
|
|
Google.com,google
|
|
|
|
Google.com_test,googletest,google_test
|
2020-08-11 15:28:52 +00:00
|
|
|
"
|
|
|
|
|
2022-03-30 14:47:12 +00:00
|
|
|
CA_SERVERS="$CA_ZEROSSL,$CA_LETSENCRYPT_V2,$CA_LETSENCRYPT_V2_TEST,$CA_BUYPASS,$CA_BUYPASS_TEST,$CA_SSLCOM_RSA,$CA_GOOGLE,$CA_GOOGLE_TEST"
|
2017-12-07 13:32:17 +00:00
|
|
|
|
2016-11-13 13:47:58 +00:00
|
|
|
DEFAULT_USER_AGENT="$PROJECT_NAME/$VER ($PROJECT)"
|
2016-03-19 14:04:03 +00:00
|
|
|
|
2022-11-23 13:57:38 +00:00
|
|
|
DEFAULT_ACCOUNT_KEY_LENGTH=ec-256
|
|
|
|
DEFAULT_DOMAIN_KEY_LENGTH=ec-256
|
2016-11-06 15:08:45 +00:00
|
|
|
|
2016-11-22 13:43:42 +00:00
|
|
|
DEFAULT_OPENSSL_BIN="openssl"
|
|
|
|
|
2016-03-08 12:44:12 +00:00
|
|
|
VTYPE_HTTP="http-01"
|
|
|
|
VTYPE_DNS="dns-01"
|
2018-12-18 11:28:38 +00:00
|
|
|
VTYPE_ALPN="tls-alpn-01"
|
2016-06-17 05:23:44 +00:00
|
|
|
|
2020-12-13 07:10:42 +00:00
|
|
|
ID_TYPE_DNS="dns"
|
|
|
|
ID_TYPE_IP="ip"
|
|
|
|
|
2016-09-23 15:14:03 +00:00
|
|
|
LOCAL_ANY_ADDRESS="0.0.0.0"
|
|
|
|
|
2018-12-28 14:52:40 +00:00
|
|
|
DEFAULT_RENEW=60
|
2016-06-26 02:09:51 +00:00
|
|
|
|
2016-09-23 14:35:13 +00:00
|
|
|
NO_VALUE="no"
|
|
|
|
|
2018-03-14 13:20:27 +00:00
|
|
|
W_DNS="dns"
|
2018-12-18 11:28:38 +00:00
|
|
|
W_ALPN="alpn"
|
2018-02-12 13:49:22 +00:00
|
|
|
DNS_ALIAS_PREFIX="="
|
2016-03-08 12:44:12 +00:00
|
|
|
|
2017-02-06 12:42:54 +00:00
|
|
|
MODE_STATELESS="stateless"
|
|
|
|
|
2016-08-07 02:21:27 +00:00
|
|
|
STATE_VERIFIED="verified_ok"
|
|
|
|
|
2017-02-13 15:29:37 +00:00
|
|
|
NGINX="nginx:"
|
2017-02-14 14:03:48 +00:00
|
|
|
NGINX_START="#ACME_NGINX_START"
|
|
|
|
NGINX_END="#ACME_NGINX_END"
|
2017-02-13 15:29:37 +00:00
|
|
|
|
2021-12-13 06:15:49 +00:00
|
|
|
BEGIN_CSR="-----BEGIN [NEW ]\{0,4\}CERTIFICATE REQUEST-----"
|
|
|
|
END_CSR="-----END [NEW ]\{0,4\}CERTIFICATE REQUEST-----"
|
2016-03-17 13:18:09 +00:00
|
|
|
|
|
|
|
BEGIN_CERT="-----BEGIN CERTIFICATE-----"
|
|
|
|
END_CERT="-----END CERTIFICATE-----"
|
|
|
|
|
2018-03-08 11:49:53 +00:00
|
|
|
CONTENT_TYPE_JSON="application/jose+json"
|
2016-06-18 03:29:28 +00:00
|
|
|
RENEW_SKIP=2
|
2022-07-07 12:01:43 +00:00
|
|
|
CODE_DNS_MANUAL=3
|
2016-06-18 03:29:28 +00:00
|
|
|
|
2019-03-05 13:05:10 +00:00
|
|
|
B64CONF_START="__ACME_BASE64__START_"
|
|
|
|
B64CONF_END="__ACME_BASE64__END_"
|
|
|
|
|
2016-08-13 11:22:25 +00:00
|
|
|
ECC_SEP="_"
|
|
|
|
ECC_SUFFIX="${ECC_SEP}ecc"
|
|
|
|
|
2016-09-25 13:58:59 +00:00
|
|
|
LOG_LEVEL_1=1
|
|
|
|
LOG_LEVEL_2=2
|
|
|
|
LOG_LEVEL_3=3
|
|
|
|
DEFAULT_LOG_LEVEL="$LOG_LEVEL_1"
|
|
|
|
|
2017-02-19 04:13:18 +00:00
|
|
|
DEBUG_LEVEL_1=1
|
|
|
|
DEBUG_LEVEL_2=2
|
|
|
|
DEBUG_LEVEL_3=3
|
|
|
|
DEBUG_LEVEL_DEFAULT=$DEBUG_LEVEL_1
|
|
|
|
DEBUG_LEVEL_NONE=0
|
|
|
|
|
2019-10-03 12:37:46 +00:00
|
|
|
DOH_CLOUDFLARE=1
|
|
|
|
DOH_GOOGLE=2
|
2021-05-03 08:35:42 +00:00
|
|
|
DOH_ALI=3
|
|
|
|
DOH_DP=4
|
2019-10-03 12:37:46 +00:00
|
|
|
|
2017-02-19 05:24:00 +00:00
|
|
|
HIDDEN_VALUE="[hidden](please add '--output-insecure' to see this value)"
|
|
|
|
|
2017-02-11 13:15:36 +00:00
|
|
|
SYSLOG_ERROR="user.error"
|
2017-02-19 04:13:18 +00:00
|
|
|
SYSLOG_INFO="user.info"
|
2017-02-11 13:15:36 +00:00
|
|
|
SYSLOG_DEBUG="user.debug"
|
|
|
|
|
2017-02-19 04:13:18 +00:00
|
|
|
#error
|
2017-02-19 04:42:37 +00:00
|
|
|
SYSLOG_LEVEL_ERROR=3
|
2017-02-19 04:13:18 +00:00
|
|
|
#info
|
2017-02-19 04:42:37 +00:00
|
|
|
SYSLOG_LEVEL_INFO=6
|
2017-02-19 04:13:18 +00:00
|
|
|
#debug
|
2017-02-19 04:42:37 +00:00
|
|
|
SYSLOG_LEVEL_DEBUG=7
|
2017-02-19 04:13:18 +00:00
|
|
|
#debug2
|
2017-02-19 04:42:37 +00:00
|
|
|
SYSLOG_LEVEL_DEBUG_2=8
|
2017-02-19 04:13:18 +00:00
|
|
|
#debug3
|
2017-02-19 04:42:37 +00:00
|
|
|
SYSLOG_LEVEL_DEBUG_3=9
|
2017-02-19 04:13:18 +00:00
|
|
|
|
2017-02-19 04:42:37 +00:00
|
|
|
SYSLOG_LEVEL_DEFAULT=$SYSLOG_LEVEL_ERROR
|
2017-02-19 04:13:18 +00:00
|
|
|
#none
|
|
|
|
SYSLOG_LEVEL_NONE=0
|
|
|
|
|
2019-04-29 14:13:54 +00:00
|
|
|
NOTIFY_LEVEL_DISABLE=0
|
|
|
|
NOTIFY_LEVEL_ERROR=1
|
|
|
|
NOTIFY_LEVEL_RENEW=2
|
|
|
|
NOTIFY_LEVEL_SKIP=3
|
|
|
|
|
|
|
|
NOTIFY_LEVEL_DEFAULT=$NOTIFY_LEVEL_RENEW
|
|
|
|
|
|
|
|
NOTIFY_MODE_BULK=0
|
|
|
|
NOTIFY_MODE_CERT=1
|
|
|
|
|
|
|
|
NOTIFY_MODE_DEFAULT=$NOTIFY_MODE_BULK
|
|
|
|
|
2022-01-03 04:38:59 +00:00
|
|
|
_BASE64_ENCODED_CFGS="Le_PreHook Le_PostHook Le_RenewHook Le_Preferred_Chain Le_ReloadCmd"
|
|
|
|
|
2020-01-30 02:50:39 +00:00
|
|
|
_DEBUG_WIKI="https://github.com/acmesh-official/acme.sh/wiki/How-to-debug-acme.sh"
|
2016-03-08 12:44:12 +00:00
|
|
|
|
2020-01-30 02:50:39 +00:00
|
|
|
_PREPARE_LINK="https://github.com/acmesh-official/acme.sh/wiki/Install-preparations"
|
2017-02-05 15:06:06 +00:00
|
|
|
|
2020-01-30 02:50:39 +00:00
|
|
|
_STATELESS_WIKI="https://github.com/acmesh-official/acme.sh/wiki/Stateless-Mode"
|
2017-02-06 12:42:54 +00:00
|
|
|
|
2020-01-30 02:50:39 +00:00
|
|
|
_DNS_ALIAS_WIKI="https://github.com/acmesh-official/acme.sh/wiki/DNS-alias-mode"
|
2018-02-10 02:45:29 +00:00
|
|
|
|
2020-01-30 02:50:39 +00:00
|
|
|
_DNS_MANUAL_WIKI="https://github.com/acmesh-official/acme.sh/wiki/dns-manual-mode"
|
2018-03-21 12:30:52 +00:00
|
|
|
|
2020-08-16 08:57:06 +00:00
|
|
|
_DNS_API_WIKI="https://github.com/acmesh-official/acme.sh/wiki/dnsapi"
|
|
|
|
|
2020-01-30 02:50:39 +00:00
|
|
|
_NOTIFY_WIKI="https://github.com/acmesh-official/acme.sh/wiki/notify"
|
2019-04-29 14:13:54 +00:00
|
|
|
|
2020-01-30 02:50:39 +00:00
|
|
|
_SUDO_WIKI="https://github.com/acmesh-official/acme.sh/wiki/sudo"
|
2019-08-11 06:07:36 +00:00
|
|
|
|
2020-04-18 12:03:48 +00:00
|
|
|
_REVOKE_WIKI="https://github.com/acmesh-official/acme.sh/wiki/revokecert"
|
|
|
|
|
2020-08-11 15:28:52 +00:00
|
|
|
_ZEROSSL_WIKI="https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA"
|
|
|
|
|
2021-06-21 13:31:00 +00:00
|
|
|
_SSLCOM_WIKI="https://github.com/acmesh-official/acme.sh/wiki/SSL.com-CA"
|
|
|
|
|
2020-08-12 13:17:15 +00:00
|
|
|
_SERVER_WIKI="https://github.com/acmesh-official/acme.sh/wiki/Server"
|
|
|
|
|
2020-08-16 08:57:06 +00:00
|
|
|
_PREFERRED_CHAIN_WIKI="https://github.com/acmesh-official/acme.sh/wiki/Preferred-Chain"
|
|
|
|
|
2022-04-01 13:22:42 +00:00
|
|
|
_VALIDITY_WIKI="https://github.com/acmesh-official/acme.sh/wiki/Validity"
|
|
|
|
|
2020-12-23 12:45:43 +00:00
|
|
|
_DNSCHECK_WIKI="https://github.com/acmesh-official/acme.sh/wiki/dnscheck"
|
|
|
|
|
2017-08-22 12:27:13 +00:00
|
|
|
_DNS_MANUAL_ERR="The dns manual mode can not renew automatically, you must issue it again manually. You'd better use the other modes instead."
|
|
|
|
|
|
|
|
_DNS_MANUAL_WARN="It seems that you are using dns manual mode. please take care: $_DNS_MANUAL_ERR"
|
|
|
|
|
2018-03-21 12:30:52 +00:00
|
|
|
_DNS_MANUAL_ERROR="It seems that you are using dns manual mode. Read this link first: $_DNS_MANUAL_WIKI"
|
|
|
|
|
2016-09-06 11:37:41 +00:00
|
|
|
__INTERACTIVE=""
|
2016-11-09 11:30:39 +00:00
|
|
|
if [ -t 1 ]; then
|
2016-09-06 11:37:41 +00:00
|
|
|
__INTERACTIVE="1"
|
|
|
|
fi
|
2016-04-17 09:33:08 +00:00
|
|
|
|
2016-08-13 11:22:25 +00:00
|
|
|
__green() {
|
2018-11-23 14:53:02 +00:00
|
|
|
if [ "${__INTERACTIVE}${ACME_NO_COLOR:-0}" = "10" -o "${ACME_FORCE_COLOR}" = "1" ]; then
|
2019-10-27 03:43:40 +00:00
|
|
|
printf '\33[1;32m%b\33[0m' "$1"
|
2018-11-23 14:53:02 +00:00
|
|
|
return
|
2016-09-02 12:55:11 +00:00
|
|
|
fi
|
2017-04-05 12:54:53 +00:00
|
|
|
printf -- "%b" "$1"
|
2016-08-13 11:22:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
__red() {
|
2018-11-23 14:53:02 +00:00
|
|
|
if [ "${__INTERACTIVE}${ACME_NO_COLOR:-0}" = "10" -o "${ACME_FORCE_COLOR}" = "1" ]; then
|
2019-10-27 03:43:40 +00:00
|
|
|
printf '\33[1;31m%b\33[0m' "$1"
|
2018-11-23 14:53:02 +00:00
|
|
|
return
|
2016-09-02 12:55:11 +00:00
|
|
|
fi
|
2017-04-05 12:54:53 +00:00
|
|
|
printf -- "%b" "$1"
|
2016-08-13 11:22:25 +00:00
|
|
|
}
|
2016-04-17 09:33:08 +00:00
|
|
|
|
2016-09-25 13:58:59 +00:00
|
|
|
_printargs() {
|
2018-03-14 08:52:58 +00:00
|
|
|
_exitstatus="$?"
|
2016-11-28 16:11:02 +00:00
|
|
|
if [ -z "$NO_TIMESTAMP" ] || [ "$NO_TIMESTAMP" = "0" ]; then
|
|
|
|
printf -- "%s" "[$(date)] "
|
|
|
|
fi
|
2016-11-09 11:30:39 +00:00
|
|
|
if [ -z "$2" ]; then
|
2016-11-28 16:11:02 +00:00
|
|
|
printf -- "%s" "$1"
|
2016-08-13 11:22:25 +00:00
|
|
|
else
|
2016-11-28 16:11:02 +00:00
|
|
|
printf -- "%s" "$1='$2'"
|
2016-08-13 11:22:25 +00:00
|
|
|
fi
|
2016-09-25 13:58:59 +00:00
|
|
|
printf "\n"
|
2019-10-05 13:06:58 +00:00
|
|
|
# return the saved exit status
|
2018-03-13 11:43:07 +00:00
|
|
|
return "$_exitstatus"
|
2016-08-13 11:22:25 +00:00
|
|
|
}
|
|
|
|
|
2016-11-04 14:03:41 +00:00
|
|
|
_dlg_versions() {
|
|
|
|
echo "Diagnosis versions: "
|
2017-02-25 11:08:00 +00:00
|
|
|
echo "openssl:$ACME_OPENSSL_BIN"
|
2017-03-30 13:16:25 +00:00
|
|
|
if _exists "${ACME_OPENSSL_BIN:-openssl}"; then
|
|
|
|
${ACME_OPENSSL_BIN:-openssl} version 2>&1
|
2016-11-04 14:03:41 +00:00
|
|
|
else
|
2020-06-29 18:29:10 +00:00
|
|
|
echo "$ACME_OPENSSL_BIN doesn't exist."
|
2016-11-04 14:03:41 +00:00
|
|
|
fi
|
2016-11-09 11:30:39 +00:00
|
|
|
|
2016-11-04 14:03:41 +00:00
|
|
|
echo "apache:"
|
2016-11-09 11:30:39 +00:00
|
|
|
if [ "$_APACHECTL" ] && _exists "$_APACHECTL"; then
|
2017-03-03 14:03:19 +00:00
|
|
|
$_APACHECTL -V 2>&1
|
2016-11-04 14:03:41 +00:00
|
|
|
else
|
2020-06-29 18:29:10 +00:00
|
|
|
echo "apache doesn't exist."
|
2016-11-04 14:03:41 +00:00
|
|
|
fi
|
2016-11-09 11:30:39 +00:00
|
|
|
|
2017-06-15 13:44:10 +00:00
|
|
|
echo "nginx:"
|
|
|
|
if _exists "nginx"; then
|
|
|
|
nginx -V 2>&1
|
|
|
|
else
|
2020-06-29 18:29:10 +00:00
|
|
|
echo "nginx doesn't exist."
|
2017-06-15 13:44:10 +00:00
|
|
|
fi
|
|
|
|
|
2017-09-01 15:01:37 +00:00
|
|
|
echo "socat:"
|
|
|
|
if _exists "socat"; then
|
2020-02-18 15:26:15 +00:00
|
|
|
socat -V 2>&1
|
2016-11-04 14:03:41 +00:00
|
|
|
else
|
2020-06-29 18:29:10 +00:00
|
|
|
_debug "socat doesn't exist."
|
2016-11-04 14:03:41 +00:00
|
|
|
fi
|
|
|
|
}
|
2016-08-13 11:22:25 +00:00
|
|
|
|
2017-02-11 13:15:36 +00:00
|
|
|
#class
|
|
|
|
_syslog() {
|
2018-03-14 08:52:58 +00:00
|
|
|
_exitstatus="$?"
|
2017-02-19 04:13:18 +00:00
|
|
|
if [ "${SYS_LOG:-$SYSLOG_LEVEL_NONE}" = "$SYSLOG_LEVEL_NONE" ]; then
|
2017-02-11 13:15:36 +00:00
|
|
|
return
|
|
|
|
fi
|
|
|
|
_logclass="$1"
|
|
|
|
shift
|
2017-04-30 08:29:20 +00:00
|
|
|
if [ -z "$__logger_i" ]; then
|
|
|
|
if _contains "$(logger --help 2>&1)" "-i"; then
|
|
|
|
__logger_i="logger -i"
|
|
|
|
else
|
|
|
|
__logger_i="logger"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
$__logger_i -t "$PROJECT_NAME" -p "$_logclass" "$(_printargs "$@")" >/dev/null 2>&1
|
2018-03-14 08:52:58 +00:00
|
|
|
return "$_exitstatus"
|
2017-02-11 13:15:36 +00:00
|
|
|
}
|
|
|
|
|
2016-09-25 13:58:59 +00:00
|
|
|
_log() {
|
|
|
|
[ -z "$LOG_FILE" ] && return
|
2016-11-09 12:45:57 +00:00
|
|
|
_printargs "$@" >>"$LOG_FILE"
|
2016-09-25 13:58:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
_info() {
|
2017-02-19 04:13:18 +00:00
|
|
|
_log "$@"
|
2017-02-19 04:42:37 +00:00
|
|
|
if [ "${SYS_LOG:-$SYSLOG_LEVEL_NONE}" -ge "$SYSLOG_LEVEL_INFO" ]; then
|
2017-02-19 04:13:18 +00:00
|
|
|
_syslog "$SYSLOG_INFO" "$@"
|
|
|
|
fi
|
2016-09-25 13:58:59 +00:00
|
|
|
_printargs "$@"
|
2016-03-08 12:44:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
_err() {
|
2017-02-19 04:13:18 +00:00
|
|
|
_syslog "$SYSLOG_ERROR" "$@"
|
|
|
|
_log "$@"
|
2016-11-28 16:11:02 +00:00
|
|
|
if [ -z "$NO_TIMESTAMP" ] || [ "$NO_TIMESTAMP" = "0" ]; then
|
|
|
|
printf -- "%s" "[$(date)] " >&2
|
|
|
|
fi
|
2016-11-09 11:30:39 +00:00
|
|
|
if [ -z "$2" ]; then
|
2016-09-28 05:13:08 +00:00
|
|
|
__red "$1" >&2
|
|
|
|
else
|
|
|
|
__red "$1='$2'" >&2
|
|
|
|
fi
|
2016-09-27 13:27:43 +00:00
|
|
|
printf "\n" >&2
|
2016-03-08 12:44:12 +00:00
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
2016-08-13 11:22:25 +00:00
|
|
|
_usage() {
|
2016-11-09 11:30:39 +00:00
|
|
|
__red "$@" >&2
|
2016-09-28 05:13:08 +00:00
|
|
|
printf "\n" >&2
|
2016-08-13 11:22:25 +00:00
|
|
|
}
|
|
|
|
|
2019-10-15 21:37:38 +00:00
|
|
|
__debug_bash_helper() {
|
|
|
|
# At this point only do for --debug 3
|
|
|
|
if [ "${DEBUG:-$DEBUG_LEVEL_NONE}" -lt "$DEBUG_LEVEL_3" ]; then
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
# Return extra debug info when running with bash, otherwise return empty
|
|
|
|
# string.
|
|
|
|
if [ -z "${BASH_VERSION}" ]; then
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
# We are a bash shell at this point, return the filename, function name, and
|
|
|
|
# line number as a string
|
|
|
|
_dbh_saveIFS=$IFS
|
|
|
|
IFS=" "
|
2019-11-12 16:48:41 +00:00
|
|
|
# Must use eval or syntax error happens under dash. The eval should use
|
|
|
|
# single quotes as older versions of busybox had a bug with double quotes and
|
|
|
|
# eval.
|
2019-10-15 21:37:38 +00:00
|
|
|
# Use 'caller 1' as we want one level up the stack as we should be called
|
|
|
|
# by one of the _debug* functions
|
2019-11-12 16:48:41 +00:00
|
|
|
eval '_dbh_called=($(caller 1))'
|
2019-10-15 21:37:38 +00:00
|
|
|
IFS=$_dbh_saveIFS
|
2019-11-12 16:48:41 +00:00
|
|
|
eval '_dbh_file=${_dbh_called[2]}'
|
2019-10-15 21:37:38 +00:00
|
|
|
if [ -n "${_script_home}" ]; then
|
|
|
|
# Trim off the _script_home directory name
|
2019-11-12 16:48:41 +00:00
|
|
|
eval '_dbh_file=${_dbh_file#$_script_home/}'
|
2019-10-15 21:37:38 +00:00
|
|
|
fi
|
2019-11-12 16:48:41 +00:00
|
|
|
eval '_dbh_function=${_dbh_called[1]}'
|
|
|
|
eval '_dbh_lineno=${_dbh_called[0]}'
|
2019-10-15 21:37:38 +00:00
|
|
|
printf "%-40s " "$_dbh_file:${_dbh_function}:${_dbh_lineno}"
|
|
|
|
}
|
|
|
|
|
2016-03-19 10:18:34 +00:00
|
|
|
_debug() {
|
2017-02-19 04:13:18 +00:00
|
|
|
if [ "${LOG_LEVEL:-$DEFAULT_LOG_LEVEL}" -ge "$LOG_LEVEL_1" ]; then
|
|
|
|
_log "$@"
|
2016-09-25 13:58:59 +00:00
|
|
|
fi
|
2017-02-19 04:42:37 +00:00
|
|
|
if [ "${SYS_LOG:-$SYSLOG_LEVEL_NONE}" -ge "$SYSLOG_LEVEL_DEBUG" ]; then
|
2017-02-19 04:13:18 +00:00
|
|
|
_syslog "$SYSLOG_DEBUG" "$@"
|
|
|
|
fi
|
|
|
|
if [ "${DEBUG:-$DEBUG_LEVEL_NONE}" -ge "$DEBUG_LEVEL_1" ]; then
|
2019-10-15 21:37:38 +00:00
|
|
|
_bash_debug=$(__debug_bash_helper)
|
|
|
|
_printargs "${_bash_debug}$@" >&2
|
2016-03-19 10:18:34 +00:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2017-02-19 05:24:00 +00:00
|
|
|
#output the sensitive messages
|
|
|
|
_secure_debug() {
|
|
|
|
if [ "${LOG_LEVEL:-$DEFAULT_LOG_LEVEL}" -ge "$LOG_LEVEL_1" ]; then
|
|
|
|
if [ "$OUTPUT_INSECURE" = "1" ]; then
|
|
|
|
_log "$@"
|
|
|
|
else
|
|
|
|
_log "$1" "$HIDDEN_VALUE"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
if [ "${SYS_LOG:-$SYSLOG_LEVEL_NONE}" -ge "$SYSLOG_LEVEL_DEBUG" ]; then
|
|
|
|
_syslog "$SYSLOG_DEBUG" "$1" "$HIDDEN_VALUE"
|
|
|
|
fi
|
|
|
|
if [ "${DEBUG:-$DEBUG_LEVEL_NONE}" -ge "$DEBUG_LEVEL_1" ]; then
|
|
|
|
if [ "$OUTPUT_INSECURE" = "1" ]; then
|
|
|
|
_printargs "$@" >&2
|
|
|
|
else
|
|
|
|
_printargs "$1" "$HIDDEN_VALUE" >&2
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2016-04-09 15:40:59 +00:00
|
|
|
_debug2() {
|
2017-02-19 04:13:18 +00:00
|
|
|
if [ "${LOG_LEVEL:-$DEFAULT_LOG_LEVEL}" -ge "$LOG_LEVEL_2" ]; then
|
|
|
|
_log "$@"
|
2016-09-25 13:58:59 +00:00
|
|
|
fi
|
2017-02-19 04:42:37 +00:00
|
|
|
if [ "${SYS_LOG:-$SYSLOG_LEVEL_NONE}" -ge "$SYSLOG_LEVEL_DEBUG_2" ]; then
|
2017-02-19 04:13:18 +00:00
|
|
|
_syslog "$SYSLOG_DEBUG" "$@"
|
|
|
|
fi
|
|
|
|
if [ "${DEBUG:-$DEBUG_LEVEL_NONE}" -ge "$DEBUG_LEVEL_2" ]; then
|
2019-10-15 21:37:38 +00:00
|
|
|
_bash_debug=$(__debug_bash_helper)
|
|
|
|
_printargs "${_bash_debug}$@" >&2
|
2016-04-09 15:40:59 +00:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2017-02-19 05:24:00 +00:00
|
|
|
_secure_debug2() {
|
|
|
|
if [ "${LOG_LEVEL:-$DEFAULT_LOG_LEVEL}" -ge "$LOG_LEVEL_2" ]; then
|
|
|
|
if [ "$OUTPUT_INSECURE" = "1" ]; then
|
|
|
|
_log "$@"
|
|
|
|
else
|
|
|
|
_log "$1" "$HIDDEN_VALUE"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
if [ "${SYS_LOG:-$SYSLOG_LEVEL_NONE}" -ge "$SYSLOG_LEVEL_DEBUG_2" ]; then
|
|
|
|
_syslog "$SYSLOG_DEBUG" "$1" "$HIDDEN_VALUE"
|
|
|
|
fi
|
|
|
|
if [ "${DEBUG:-$DEBUG_LEVEL_NONE}" -ge "$DEBUG_LEVEL_2" ]; then
|
|
|
|
if [ "$OUTPUT_INSECURE" = "1" ]; then
|
|
|
|
_printargs "$@" >&2
|
|
|
|
else
|
|
|
|
_printargs "$1" "$HIDDEN_VALUE" >&2
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2016-08-10 13:54:08 +00:00
|
|
|
_debug3() {
|
2017-02-19 04:13:18 +00:00
|
|
|
if [ "${LOG_LEVEL:-$DEFAULT_LOG_LEVEL}" -ge "$LOG_LEVEL_3" ]; then
|
|
|
|
_log "$@"
|
|
|
|
fi
|
2017-02-19 04:42:37 +00:00
|
|
|
if [ "${SYS_LOG:-$SYSLOG_LEVEL_NONE}" -ge "$SYSLOG_LEVEL_DEBUG_3" ]; then
|
2017-02-19 04:13:18 +00:00
|
|
|
_syslog "$SYSLOG_DEBUG" "$@"
|
2016-09-25 13:58:59 +00:00
|
|
|
fi
|
2017-02-19 04:13:18 +00:00
|
|
|
if [ "${DEBUG:-$DEBUG_LEVEL_NONE}" -ge "$DEBUG_LEVEL_3" ]; then
|
2019-10-15 21:37:38 +00:00
|
|
|
_bash_debug=$(__debug_bash_helper)
|
|
|
|
_printargs "${_bash_debug}$@" >&2
|
2016-08-10 13:54:08 +00:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2017-02-19 05:24:00 +00:00
|
|
|
_secure_debug3() {
|
|
|
|
if [ "${LOG_LEVEL:-$DEFAULT_LOG_LEVEL}" -ge "$LOG_LEVEL_3" ]; then
|
|
|
|
if [ "$OUTPUT_INSECURE" = "1" ]; then
|
|
|
|
_log "$@"
|
|
|
|
else
|
|
|
|
_log "$1" "$HIDDEN_VALUE"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
if [ "${SYS_LOG:-$SYSLOG_LEVEL_NONE}" -ge "$SYSLOG_LEVEL_DEBUG_3" ]; then
|
|
|
|
_syslog "$SYSLOG_DEBUG" "$1" "$HIDDEN_VALUE"
|
|
|
|
fi
|
|
|
|
if [ "${DEBUG:-$DEBUG_LEVEL_NONE}" -ge "$DEBUG_LEVEL_3" ]; then
|
|
|
|
if [ "$OUTPUT_INSECURE" = "1" ]; then
|
|
|
|
_printargs "$@" >&2
|
|
|
|
else
|
|
|
|
_printargs "$1" "$HIDDEN_VALUE" >&2
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2017-03-08 13:51:25 +00:00
|
|
|
_upper_case() {
|
2022-08-03 15:07:02 +00:00
|
|
|
# shellcheck disable=SC2018,SC2019
|
|
|
|
tr '[a-z]' '[A-Z]'
|
2017-03-08 13:51:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
_lower_case() {
|
2022-08-03 15:07:02 +00:00
|
|
|
# shellcheck disable=SC2018,SC2019
|
|
|
|
tr '[A-Z]' '[a-z]'
|
2017-03-08 13:51:25 +00:00
|
|
|
}
|
|
|
|
|
2016-11-09 11:30:39 +00:00
|
|
|
_startswith() {
|
2016-04-16 13:52:24 +00:00
|
|
|
_str="$1"
|
|
|
|
_sub="$2"
|
2021-11-13 07:23:32 +00:00
|
|
|
echo "$_str" | grep -- "^$_sub" >/dev/null 2>&1
|
2016-04-16 13:52:24 +00:00
|
|
|
}
|
|
|
|
|
2016-11-09 11:30:39 +00:00
|
|
|
_endswith() {
|
2016-08-13 11:22:25 +00:00
|
|
|
_str="$1"
|
|
|
|
_sub="$2"
|
|
|
|
echo "$_str" | grep -- "$_sub\$" >/dev/null 2>&1
|
|
|
|
}
|
|
|
|
|
2016-11-09 11:30:39 +00:00
|
|
|
_contains() {
|
2016-04-16 13:52:24 +00:00
|
|
|
_str="$1"
|
|
|
|
_sub="$2"
|
2016-08-13 11:22:25 +00:00
|
|
|
echo "$_str" | grep -- "$_sub" >/dev/null 2>&1
|
2016-04-16 13:52:24 +00:00
|
|
|
}
|
|
|
|
|
2016-05-03 12:41:40 +00:00
|
|
|
_hasfield() {
|
|
|
|
_str="$1"
|
|
|
|
_field="$2"
|
|
|
|
_sep="$3"
|
2016-11-09 11:30:39 +00:00
|
|
|
if [ -z "$_field" ]; then
|
2016-08-13 11:22:25 +00:00
|
|
|
_usage "Usage: str field [sep]"
|
2016-05-03 12:41:40 +00:00
|
|
|
return 1
|
|
|
|
fi
|
2016-11-09 11:30:39 +00:00
|
|
|
|
|
|
|
if [ -z "$_sep" ]; then
|
2016-05-03 12:41:40 +00:00
|
|
|
_sep=","
|
|
|
|
fi
|
2016-11-09 11:30:39 +00:00
|
|
|
|
2017-03-29 01:16:22 +00:00
|
|
|
for f in $(echo "$_str" | tr "$_sep" ' '); do
|
2016-11-09 11:30:39 +00:00
|
|
|
if [ "$f" = "$_field" ]; then
|
2016-09-15 02:41:47 +00:00
|
|
|
_debug2 "'$_str' contains '$_field'"
|
2016-05-03 12:41:40 +00:00
|
|
|
return 0 #contains ok
|
|
|
|
fi
|
|
|
|
done
|
2016-09-15 02:41:47 +00:00
|
|
|
_debug2 "'$_str' does not contain '$_field'"
|
2017-04-17 11:08:34 +00:00
|
|
|
return 1 #not contains
|
2016-05-03 12:41:40 +00:00
|
|
|
}
|
|
|
|
|
2017-07-02 09:02:54 +00:00
|
|
|
# str index [sep]
|
2016-11-09 11:30:39 +00:00
|
|
|
_getfield() {
|
2016-09-23 15:14:03 +00:00
|
|
|
_str="$1"
|
|
|
|
_findex="$2"
|
|
|
|
_sep="$3"
|
2016-11-09 11:30:39 +00:00
|
|
|
|
|
|
|
if [ -z "$_findex" ]; then
|
2016-09-23 15:14:03 +00:00
|
|
|
_usage "Usage: str field [sep]"
|
|
|
|
return 1
|
|
|
|
fi
|
2016-11-09 11:30:39 +00:00
|
|
|
|
|
|
|
if [ -z "$_sep" ]; then
|
2016-09-23 15:14:03 +00:00
|
|
|
_sep=","
|
|
|
|
fi
|
|
|
|
|
2016-11-09 14:28:12 +00:00
|
|
|
_ffi="$_findex"
|
2016-11-09 11:30:39 +00:00
|
|
|
while [ "$_ffi" -gt "0" ]; do
|
2016-11-09 14:28:12 +00:00
|
|
|
_fv="$(echo "$_str" | cut -d "$_sep" -f "$_ffi")"
|
2016-11-09 11:30:39 +00:00
|
|
|
if [ "$_fv" ]; then
|
2016-09-23 15:14:03 +00:00
|
|
|
printf -- "%s" "$_fv"
|
|
|
|
return 0
|
|
|
|
fi
|
2016-11-09 12:45:57 +00:00
|
|
|
_ffi="$(_math "$_ffi" - 1)"
|
2016-09-23 15:14:03 +00:00
|
|
|
done
|
2016-11-09 11:30:39 +00:00
|
|
|
|
2016-09-23 15:14:03 +00:00
|
|
|
printf -- "%s" "$_str"
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2016-11-09 11:30:39 +00:00
|
|
|
_exists() {
|
2016-03-19 10:18:34 +00:00
|
|
|
cmd="$1"
|
2016-11-09 11:30:39 +00:00
|
|
|
if [ -z "$cmd" ]; then
|
2016-08-13 11:22:25 +00:00
|
|
|
_usage "Usage: _exists cmd"
|
2016-03-19 10:18:34 +00:00
|
|
|
return 1
|
|
|
|
fi
|
2016-11-17 05:17:29 +00:00
|
|
|
|
|
|
|
if eval type type >/dev/null 2>&1; then
|
|
|
|
eval type "$cmd" >/dev/null 2>&1
|
|
|
|
elif command >/dev/null 2>&1; then
|
2016-05-13 13:14:00 +00:00
|
|
|
command -v "$cmd" >/dev/null 2>&1
|
2016-11-17 05:20:20 +00:00
|
|
|
else
|
2016-11-11 13:13:33 +00:00
|
|
|
which "$cmd" >/dev/null 2>&1
|
2016-04-16 11:38:11 +00:00
|
|
|
fi
|
2016-03-19 10:18:34 +00:00
|
|
|
ret="$?"
|
2016-08-25 02:45:41 +00:00
|
|
|
_debug3 "$cmd exists=$ret"
|
2016-03-19 10:18:34 +00:00
|
|
|
return $ret
|
|
|
|
}
|
|
|
|
|
2016-04-17 09:33:08 +00:00
|
|
|
#a + b
|
2016-11-09 11:30:39 +00:00
|
|
|
_math() {
|
2016-11-12 02:58:20 +00:00
|
|
|
_m_opts="$@"
|
|
|
|
printf "%s" "$(($_m_opts))"
|
2016-04-17 09:33:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
_h_char_2_dec() {
|
|
|
|
_ch=$1
|
|
|
|
case "${_ch}" in
|
2020-08-17 14:18:20 +00:00
|
|
|
a | A)
|
|
|
|
printf "10"
|
|
|
|
;;
|
|
|
|
b | B)
|
|
|
|
printf "11"
|
|
|
|
;;
|
|
|
|
c | C)
|
|
|
|
printf "12"
|
|
|
|
;;
|
|
|
|
d | D)
|
|
|
|
printf "13"
|
|
|
|
;;
|
|
|
|
e | E)
|
|
|
|
printf "14"
|
|
|
|
;;
|
|
|
|
f | F)
|
|
|
|
printf "15"
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
printf "%s" "$_ch"
|
|
|
|
;;
|
2016-05-13 13:14:00 +00:00
|
|
|
esac
|
2016-04-17 09:33:08 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2016-08-14 14:37:21 +00:00
|
|
|
_URGLY_PRINTF=""
|
2016-11-09 11:30:39 +00:00
|
|
|
if [ "$(printf '\x41')" != 'A' ]; then
|
2016-08-14 14:37:21 +00:00
|
|
|
_URGLY_PRINTF=1
|
|
|
|
fi
|
|
|
|
|
2017-05-29 09:07:59 +00:00
|
|
|
_ESCAPE_XARGS=""
|
2017-06-23 10:11:11 +00:00
|
|
|
if _exists xargs && [ "$(printf %s '\\x41' | xargs printf)" = 'A' ]; then
|
2017-05-29 09:07:59 +00:00
|
|
|
_ESCAPE_XARGS=1
|
|
|
|
fi
|
|
|
|
|
2016-03-08 12:44:12 +00:00
|
|
|
_h2b() {
|
2021-02-24 23:45:22 +00:00
|
|
|
if _exists xxd; then
|
|
|
|
if _contains "$(xxd --help 2>&1)" "assumes -c30"; then
|
|
|
|
if xxd -r -p -c 9999 2>/dev/null; then
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
if xxd -r -p 2>/dev/null; then
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
fi
|
2017-05-17 05:16:53 +00:00
|
|
|
fi
|
|
|
|
|
2016-03-08 12:44:12 +00:00
|
|
|
hex=$(cat)
|
2017-05-20 03:02:48 +00:00
|
|
|
ic=""
|
|
|
|
jc=""
|
2017-05-17 05:16:53 +00:00
|
|
|
_debug2 _URGLY_PRINTF "$_URGLY_PRINTF"
|
|
|
|
if [ -z "$_URGLY_PRINTF" ]; then
|
2017-05-29 09:07:59 +00:00
|
|
|
if [ "$_ESCAPE_XARGS" ] && _exists xargs; then
|
2017-05-20 03:02:48 +00:00
|
|
|
_debug2 "xargs"
|
2017-05-26 06:58:52 +00:00
|
|
|
echo "$hex" | _upper_case | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/g' | xargs printf
|
2017-05-20 03:02:48 +00:00
|
|
|
else
|
2017-05-26 06:58:52 +00:00
|
|
|
for h in $(echo "$hex" | _upper_case | sed 's/\([0-9A-F]\{2\}\)/ \1/g'); do
|
2017-05-20 03:02:48 +00:00
|
|
|
if [ -z "$h" ]; then
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
printf "\x$h%s"
|
|
|
|
done
|
|
|
|
fi
|
2017-05-17 05:16:53 +00:00
|
|
|
else
|
2017-05-26 06:58:52 +00:00
|
|
|
for c in $(echo "$hex" | _upper_case | sed 's/\([0-9A-F]\)/ \1/g'); do
|
2017-05-20 03:02:48 +00:00
|
|
|
if [ -z "$ic" ]; then
|
|
|
|
ic=$c
|
|
|
|
continue
|
2016-04-17 09:33:08 +00:00
|
|
|
fi
|
2017-05-20 03:02:48 +00:00
|
|
|
jc=$c
|
2016-05-13 13:14:00 +00:00
|
|
|
ic="$(_h_char_2_dec "$ic")"
|
|
|
|
jc="$(_h_char_2_dec "$jc")"
|
2016-11-11 14:00:15 +00:00
|
|
|
printf '\'"$(printf "%o" "$(_math "$ic" \* 16 + $jc)")""%s"
|
2017-05-20 03:02:48 +00:00
|
|
|
ic=""
|
|
|
|
jc=""
|
2017-05-17 05:16:53 +00:00
|
|
|
done
|
|
|
|
fi
|
2016-11-11 13:13:33 +00:00
|
|
|
|
2016-03-08 12:44:12 +00:00
|
|
|
}
|
|
|
|
|
2017-01-30 04:07:50 +00:00
|
|
|
_is_solaris() {
|
|
|
|
_contains "${__OS__:=$(uname -a)}" "solaris" || _contains "${__OS__:=$(uname -a)}" "SunOS"
|
|
|
|
}
|
|
|
|
|
2017-02-05 05:16:51 +00:00
|
|
|
#_ascii_hex str
|
|
|
|
#this can only process ascii chars, should only be used when od command is missing as a backup way.
|
|
|
|
_ascii_hex() {
|
|
|
|
_debug2 "Using _ascii_hex"
|
|
|
|
_str="$1"
|
|
|
|
_str_len=${#_str}
|
|
|
|
_h_i=1
|
|
|
|
while [ "$_h_i" -le "$_str_len" ]; do
|
|
|
|
_str_c="$(printf "%s" "$_str" | cut -c "$_h_i")"
|
|
|
|
printf " %02x" "'$_str_c"
|
|
|
|
_h_i="$(_math "$_h_i" + 1)"
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
2017-01-30 04:07:50 +00:00
|
|
|
#stdin output hexstr splited by one space
|
|
|
|
#input:"abc"
|
|
|
|
#output: " 61 62 63"
|
|
|
|
_hex_dump() {
|
2017-02-10 12:55:25 +00:00
|
|
|
if _exists od; then
|
|
|
|
od -A n -v -t x1 | tr -s " " | sed 's/ $//' | tr -d "\r\t\n"
|
|
|
|
elif _exists hexdump; then
|
|
|
|
_debug3 "using hexdump"
|
|
|
|
hexdump -v -e '/1 ""' -e '/1 " %02x" ""'
|
|
|
|
elif _exists xxd; then
|
|
|
|
_debug3 "using xxd"
|
|
|
|
xxd -ps -c 20 -i | sed "s/ 0x/ /g" | tr -d ",\n" | tr -s " "
|
|
|
|
else
|
|
|
|
_debug3 "using _ascii_hex"
|
2017-02-05 05:16:51 +00:00
|
|
|
str=$(cat)
|
|
|
|
_ascii_hex "$str"
|
|
|
|
fi
|
2017-01-30 04:07:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#url encode, no-preserved chars
|
|
|
|
#A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
|
|
|
|
#41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a
|
|
|
|
|
|
|
|
#a b c d e f g h i j k l m n o p q r s t u v w x y z
|
|
|
|
#61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a
|
|
|
|
|
|
|
|
#0 1 2 3 4 5 6 7 8 9 - _ . ~
|
|
|
|
#30 31 32 33 34 35 36 37 38 39 2d 5f 2e 7e
|
|
|
|
|
|
|
|
#stdin stdout
|
|
|
|
_url_encode() {
|
|
|
|
_hex_str=$(_hex_dump)
|
|
|
|
_debug3 "_url_encode"
|
|
|
|
_debug3 "_hex_str" "$_hex_str"
|
|
|
|
for _hex_code in $_hex_str; do
|
|
|
|
#upper case
|
|
|
|
case "${_hex_code}" in
|
2020-08-17 14:18:20 +00:00
|
|
|
"41")
|
|
|
|
printf "%s" "A"
|
|
|
|
;;
|
|
|
|
"42")
|
|
|
|
printf "%s" "B"
|
|
|
|
;;
|
|
|
|
"43")
|
|
|
|
printf "%s" "C"
|
|
|
|
;;
|
|
|
|
"44")
|
|
|
|
printf "%s" "D"
|
|
|
|
;;
|
|
|
|
"45")
|
|
|
|
printf "%s" "E"
|
|
|
|
;;
|
|
|
|
"46")
|
|
|
|
printf "%s" "F"
|
|
|
|
;;
|
|
|
|
"47")
|
|
|
|
printf "%s" "G"
|
|
|
|
;;
|
|
|
|
"48")
|
|
|
|
printf "%s" "H"
|
|
|
|
;;
|
|
|
|
"49")
|
|
|
|
printf "%s" "I"
|
|
|
|
;;
|
|
|
|
"4a")
|
|
|
|
printf "%s" "J"
|
|
|
|
;;
|
|
|
|
"4b")
|
|
|
|
printf "%s" "K"
|
|
|
|
;;
|
|
|
|
"4c")
|
|
|
|
printf "%s" "L"
|
|
|
|
;;
|
|
|
|
"4d")
|
|
|
|
printf "%s" "M"
|
|
|
|
;;
|
|
|
|
"4e")
|
|
|
|
printf "%s" "N"
|
|
|
|
;;
|
|
|
|
"4f")
|
|
|
|
|