[pve-devel] [Patch V3 acme 02/13] Copy the needed function form acme.sh

Wolfgang Link w.link at proxmox.com
Thu Apr 16 07:18:22 CEST 2020


For the thin wrapper around acme.sh DNS plugins, the required functions are copied.
The project acme.sh can be found here.
https://github.com/Neilpang/acme.sh

Signed-off-by: Wolfgang Link <w.link at proxmox.com>
---
 Makefile         |   1 +
 src/proxmox-acme | 806 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 807 insertions(+)
 create mode 100644 src/proxmox-acme

diff --git a/Makefile b/Makefile
index 5ed0522..0a78b63 100644
--- a/Makefile
+++ b/Makefile
@@ -12,6 +12,7 @@ all: $(DEB)
 
 $(BUILDDIR): src debian
 	rm -rf $(BUILDDIR)
+
 	rsync -a src/ debian $(BUILDDIR)
 	# remove if repository exists
 	# echo "git clone git://git.proxmox.com/git/proxmox-acme\\ngit checkout $(GITVERSION)" > $(BUILDDIR)/debian/SOURCE
diff --git a/src/proxmox-acme b/src/proxmox-acme
new file mode 100644
index 0000000..007c58d
--- /dev/null
+++ b/src/proxmox-acme
@@ -0,0 +1,806 @@
+#!/usr/bin/env sh
+
+# copied from acme.sh
+# Usage: multiline
+_base64() {
+  [ "" ] #urgly
+  if [ "$1" ]; then
+    _debug3 "base64 multiline:'$1'"
+    ${ACME_OPENSSL_BIN:-openssl} base64 -e
+  else
+    _debug3 "base64 single line."
+    ${ACME_OPENSSL_BIN:-openssl} base64 -e | tr -d '\r\n'
+  fi
+}
+
+# Usage: multiline
+_dbase64() {
+  if [ "$1" ]; then
+    ${ACME_OPENSSL_BIN:-openssl} base64 -d -A
+  else
+    ${ACME_OPENSSL_BIN:-openssl} base64 -d
+  fi
+}
+
+# Usage: hashalg  [outputhex]
+# Output Base64-encoded digest
+_digest() {
+  alg="$1"
+  if [ -z "$alg" ]; then
+    _usage "Usage: _digest hashalg"
+    return 1
+  fi
+
+  outputhex="$2"
+
+  if [ "$alg" = "sha256" ] || [ "$alg" = "sha1" ] || [ "$alg" = "md5" ]; then
+    if [ "$outputhex" ]; then
+      ${ACME_OPENSSL_BIN:-openssl} dgst -"$alg" -hex | cut -d = -f 2 | tr -d ' '
+    else
+      ${ACME_OPENSSL_BIN:-openssl} dgst -"$alg" -binary | _base64
+    fi
+  else
+    _err "$alg is not supported yet"
+    return 1
+  fi
+
+}
+
+_upper_case() {
+  # shellcheck disable=SC2018,SC2019
+  tr 'a-z' 'A-Z'
+}
+
+_lower_case() {
+  # shellcheck disable=SC2018,SC2019
+  tr 'A-Z' 'a-z'
+}
+
+_startswith() {
+  _str="$1"
+  _sub="$2"
+  echo "$_str" | grep "^$_sub" >/dev/null 2>&1
+}
+
+_endswith() {
+  _str="$1"
+  _sub="$2"
+  echo "$_str" | grep -- "$_sub\$" >/dev/null 2>&1
+}
+
+_contains() {
+  _str="$1"
+  _sub="$2"
+  echo "$_str" | grep -- "$_sub" >/dev/null 2>&1
+}
+
+# str index [sep]
+_getfield() {
+  _str="$1"
+  _findex="$2"
+  _sep="$3"
+
+  if [ -z "$_findex" ]; then
+    _usage "Usage: str field  [sep]"
+    return 1
+  fi
+
+  if [ -z "$_sep" ]; then
+    _sep=","
+  fi
+
+  _ffi="$_findex"
+  while [ "$_ffi" -gt "0" ]; do
+    _fv="$(echo "$_str" | cut -d "$_sep" -f "$_ffi")"
+    if [ "$_fv" ]; then
+      printf -- "%s" "$_fv"
+      return 0
+    fi
+    _ffi="$(_math "$_ffi" - 1)"
+  done
+
+  printf -- "%s" "$_str"
+
+}
+
+_exists() {
+  cmd="$1"
+  if [ -z "$cmd" ]; then
+    _usage "Usage: _exists cmd"
+    return 1
+  fi
+
+  if eval type type >/dev/null 2>&1; then
+    eval type "$cmd" >/dev/null 2>&1
+  elif command >/dev/null 2>&1; then
+    command -v "$cmd" >/dev/null 2>&1
+  else
+    which "$cmd" >/dev/null 2>&1
+  fi
+  ret="$?"
+  _debug3 "$cmd exists=$ret"
+  return $ret
+}
+
+# a + b
+_math() {
+  _m_opts="$@"
+  printf "%s" "$(($_m_opts))"
+}
+
+_egrep_o() {
+  if ! egrep -o "$1" 2>/dev/null; then
+    sed -n 's/.*\('"$1"'\).*/\1/p'
+  fi
+}
+
+_inithttp() {
+
+  if [ -z "$HTTP_HEADER" ] || ! touch "$HTTP_HEADER"; then
+    HTTP_HEADER="$(_mktemp)"
+    _debug2 HTTP_HEADER "$HTTP_HEADER"
+  fi
+
+  if [ "$__HTTP_INITIALIZED" ]; then
+    if [ "$_ACME_CURL$_ACME_WGET" ]; then
+      _debug2 "Http already initialized."
+      return 0
+    fi
+  fi
+
+  if [ -z "$_ACME_CURL" ] && _exists "curl"; then
+    _ACME_CURL="curl -L --silent --dump-header $HTTP_HEADER "
+    if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
+      _CURL_DUMP="$(_mktemp)"
+      _ACME_CURL="$_ACME_CURL --trace-ascii $_CURL_DUMP "
+    fi
+
+    if [ "$CA_PATH" ]; then
+      _ACME_CURL="$_ACME_CURL --capath $CA_PATH "
+    elif [ "$CA_BUNDLE" ]; then
+      _ACME_CURL="$_ACME_CURL --cacert $CA_BUNDLE "
+    fi
+
+    if _contains "$(curl --help 2>&1)" "--globoff"; then
+      _ACME_CURL="$_ACME_CURL -g "
+    fi
+  fi
+
+  if [ -z "$_ACME_WGET" ] && _exists "wget"; then
+    _ACME_WGET="wget -q"
+    if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
+      _ACME_WGET="$_ACME_WGET -d "
+    fi
+    if [ "$CA_PATH" ]; then
+      _ACME_WGET="$_ACME_WGET --ca-directory=$CA_PATH "
+    elif [ "$CA_BUNDLE" ]; then
+      _ACME_WGET="$_ACME_WGET --ca-certificate=$CA_BUNDLE "
+    fi
+  fi
+
+  #from wget 1.14: do not skip body on 404 error
+  if [ "$_ACME_WGET" ] && _contains "$($_ACME_WGET --help 2>&1)" "--content-on-error"; then
+    _ACME_WGET="$_ACME_WGET --content-on-error "
+  fi
+
+  __HTTP_INITIALIZED=1
+
+}
+
+# body  url [needbase64] [POST|PUT|DELETE] [ContentType]
+_post() {
+  body="$1"
+  _post_url="$2"
+  needbase64="$3"
+  httpmethod="$4"
+  _postContentType="$5"
+
+  if [ -z "$httpmethod" ]; then
+    httpmethod="POST"
+  fi
+  _debug $httpmethod
+  _debug "_post_url" "$_post_url"
+  _debug2 "body" "$body"
+  _debug2 "_postContentType" "$_postContentType"
+
+  _inithttp
+
+  if [ "$_ACME_CURL" ] && [ "${ACME_USE_WGET:-0}" = "0" ]; then
+    _CURL="$_ACME_CURL"
+    if [ "$HTTPS_INSECURE" ]; then
+      _CURL="$_CURL --insecure  "
+    fi
+    if [ "$httpmethod" = "HEAD" ]; then
+      _CURL="$_CURL -I  "
+    fi
+    _debug "_CURL" "$_CURL"
+    if [ "$needbase64" ]; then
+      if [ "$body" ]; then
+        if [ "$_postContentType" ]; then
+          response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "Content-Type: $_postContentType" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url" | _base64)"
+        else
+          response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url" | _base64)"
+        fi
+      else
+        if [ "$_postContentType" ]; then
+          response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "Content-Type: $_postContentType" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" "$_post_url" | _base64)"
+        else
+          response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" "$_post_url" | _base64)"
+        fi
+      fi
+    else
+      if [ "$body" ]; then
+        if [ "$_postContentType" ]; then
+          response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "Content-Type: $_postContentType" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url")"
+        else
+          response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url")"
+        fi
+      else
+        if [ "$_postContentType" ]; then
+          response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "Content-Type: $_postContentType" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" "$_post_url")"
+        else
+          response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" "$_post_url")"
+        fi
+      fi
+    fi
+    _ret="$?"
+    if [ "$_ret" != "0" ]; then
+      _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $_ret"
+      if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
+        _err "Here is the curl dump log:"
+        _err "$(cat "$_CURL_DUMP")"
+      fi
+    fi
+  elif [ "$_ACME_WGET" ]; then
+    _WGET="$_ACME_WGET"
+    if [ "$HTTPS_INSECURE" ]; then
+      _WGET="$_WGET --no-check-certificate "
+    fi
+    if [ "$httpmethod" = "HEAD" ]; then
+      _WGET="$_WGET --read-timeout=3.0  --tries=2  "
+    fi
+    _debug "_WGET" "$_WGET"
+    if [ "$needbase64" ]; then
+      if [ "$httpmethod" = "POST" ]; then
+        if [ "$_postContentType" ]; then
+          response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --header "Content-Type: $_postContentType" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER" | _base64)"
+        else
+          response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER" | _base64)"
+        fi
+      else
+        if [ "$_postContentType" ]; then
+          response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --header "Content-Type: $_postContentType" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER" | _base64)"
+        else
+          response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER" | _base64)"
+        fi
+      fi
+    else
+      if [ "$httpmethod" = "POST" ]; then
+        if [ "$_postContentType" ]; then
+          response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --header "Content-Type: $_postContentType" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER")"
+        else
+          response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER")"
+        fi
+      elif [ "$httpmethod" = "HEAD" ]; then
+        if [ "$_postContentType" ]; then
+          response="$($_WGET --spider -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --header "Content-Type: $_postContentType" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER")"
+        else
+          response="$($_WGET --spider -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER")"
+        fi
+      else
+        if [ "$_postContentType" ]; then
+          response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --header "Content-Type: $_postContentType" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER")"
+        else
+          response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER")"
+        fi
+      fi
+    fi
+    _ret="$?"
+    if [ "$_ret" = "8" ]; then
+      _ret=0
+      _debug "wget returns 8, the server returns a 'Bad request' response, lets process the response later."
+    fi
+    if [ "$_ret" != "0" ]; then
+      _err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $_ret"
+    fi
+    _sed_i "s/^ *//g" "$HTTP_HEADER"
+  else
+    _ret="$?"
+    _err "Neither curl nor wget is found, can not do $httpmethod."
+  fi
+  _debug "_ret" "$_ret"
+  printf "%s" "$response"
+  return $_ret
+}
+
+# url getheader timeout
+_get() {
+  _debug GET
+  url="$1"
+  onlyheader="$2"
+  t="$3"
+  _debug url "$url"
+  _debug "timeout=$t"
+
+  _inithttp
+
+  if [ "$_ACME_CURL" ] && [ "${ACME_USE_WGET:-0}" = "0" ]; then
+    _CURL="$_ACME_CURL"
+    if [ "$HTTPS_INSECURE" ]; then
+      _CURL="$_CURL --insecure  "
+    fi
+    if [ "$t" ]; then
+      _CURL="$_CURL --connect-timeout $t"
+    fi
+    _debug "_CURL" "$_CURL"
+    if [ "$onlyheader" ]; then
+      $_CURL -I --user-agent "$USER_AGENT" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" "$url"
+    else
+      $_CURL --user-agent "$USER_AGENT" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" "$url"
+    fi
+    ret=$?
+    if [ "$ret" != "0" ]; then
+      _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $ret"
+      if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
+        _err "Here is the curl dump log:"
+        _err "$(cat "$_CURL_DUMP")"
+      fi
+    fi
+  elif [ "$_ACME_WGET" ]; then
+    _WGET="$_ACME_WGET"
+    if [ "$HTTPS_INSECURE" ]; then
+      _WGET="$_WGET --no-check-certificate "
+    fi
+    if [ "$t" ]; then
+      _WGET="$_WGET --timeout=$t"
+    fi
+    _debug "_WGET" "$_WGET"
+    if [ "$onlyheader" ]; then
+      $_WGET --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" -S -O /dev/null "$url" 2>&1 | sed 's/^[ ]*//g'
+    else
+      $_WGET --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" -O - "$url"
+    fi
+    ret=$?
+    if [ "$ret" = "8" ]; then
+      ret=0
+      _debug "wget returns 8, the server returns a 'Bad request' response, lets process the response later."
+    fi
+    if [ "$ret" != "0" ]; then
+      _err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $ret"
+    fi
+  else
+    ret=$?
+    _err "Neither curl nor wget is found, can not do GET."
+  fi
+  _debug "ret" "$ret"
+  return $ret
+}
+
+_head_n() {
+  head -n "$1"
+}
+
+_tail_n() {
+  if ! tail -n "$1" 2>/dev/null; then
+    #fix for solaris
+    tail -"$1"
+  fi
+}
+
+# stdin  output hexstr splited by one space
+# input:"abc"
+# output: " 61 62 63"
+_hex_dump() {
+  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"
+    str=$(cat)
+    _ascii_hex "$str"
+  fi
+}
+
+# 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
+      "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")
+        printf "%s" "O"
+        ;;
+      "50")
+        printf "%s" "P"
+        ;;
+      "51")
+        printf "%s" "Q"
+        ;;
+      "52")
+        printf "%s" "R"
+        ;;
+      "53")
+        printf "%s" "S"
+        ;;
+      "54")
+        printf "%s" "T"
+        ;;
+      "55")
+        printf "%s" "U"
+        ;;
+      "56")
+        printf "%s" "V"
+        ;;
+      "57")
+        printf "%s" "W"
+        ;;
+      "58")
+        printf "%s" "X"
+        ;;
+      "59")
+        printf "%s" "Y"
+        ;;
+      "5a")
+        printf "%s" "Z"
+        ;;
+
+      #lower case
+      "61")
+        printf "%s" "a"
+        ;;
+      "62")
+        printf "%s" "b"
+        ;;
+      "63")
+        printf "%s" "c"
+        ;;
+      "64")
+        printf "%s" "d"
+        ;;
+      "65")
+        printf "%s" "e"
+        ;;
+      "66")
+        printf "%s" "f"
+        ;;
+      "67")
+        printf "%s" "g"
+        ;;
+      "68")
+        printf "%s" "h"
+        ;;
+      "69")
+        printf "%s" "i"
+        ;;
+      "6a")
+        printf "%s" "j"
+        ;;
+      "6b")
+        printf "%s" "k"
+        ;;
+      "6c")
+        printf "%s" "l"
+        ;;
+      "6d")
+        printf "%s" "m"
+        ;;
+      "6e")
+        printf "%s" "n"
+        ;;
+      "6f")
+        printf "%s" "o"
+        ;;
+      "70")
+        printf "%s" "p"
+        ;;
+      "71")
+        printf "%s" "q"
+        ;;
+      "72")
+        printf "%s" "r"
+        ;;
+      "73")
+        printf "%s" "s"
+        ;;
+      "74")
+        printf "%s" "t"
+        ;;
+      "75")
+        printf "%s" "u"
+        ;;
+      "76")
+        printf "%s" "v"
+        ;;
+      "77")
+        printf "%s" "w"
+        ;;
+      "78")
+        printf "%s" "x"
+        ;;
+      "79")
+        printf "%s" "y"
+        ;;
+      "7a")
+        printf "%s" "z"
+        ;;
+      #numbers
+      "30")
+        printf "%s" "0"
+        ;;
+      "31")
+        printf "%s" "1"
+        ;;
+      "32")
+        printf "%s" "2"
+        ;;
+      "33")
+        printf "%s" "3"
+        ;;
+      "34")
+        printf "%s" "4"
+        ;;
+      "35")
+        printf "%s" "5"
+        ;;
+      "36")
+        printf "%s" "6"
+        ;;
+      "37")
+        printf "%s" "7"
+        ;;
+      "38")
+        printf "%s" "8"
+        ;;
+      "39")
+        printf "%s" "9"
+        ;;
+      "2d")
+        printf "%s" "-"
+        ;;
+      "5f")
+        printf "%s" "_"
+        ;;
+      "2e")
+        printf "%s" "."
+        ;;
+      "7e")
+        printf "%s" "~"
+        ;;
+      #other hex
+      *)
+        printf '%%%s' "$_hex_code"
+        ;;
+    esac
+  done
+}
+
+# Usage: hashalg  secret_hex  [outputhex]
+# Output binary hmac
+_hmac() {
+  alg="$1"
+  secret_hex="$2"
+  outputhex="$3"
+
+  if [ -z "$secret_hex" ]; then
+    _usage "Usage: _hmac hashalg secret [outputhex]"
+    return 1
+  fi
+
+  if [ "$alg" = "sha256" ] || [ "$alg" = "sha1" ]; then
+    if [ "$outputhex" ]; then
+      (${ACME_OPENSSL_BIN:-openssl} dgst -"$alg" -mac HMAC -macopt "hexkey:$secret_hex" 2>/dev/null || ${ACME_OPENSSL_BIN:-openssl} dgst -"$alg" -hmac "$(printf "%s" "$secret_hex" | _h2b)") | cut -d = -f 2 | tr -d ' '
+    else
+      ${ACME_OPENSSL_BIN:-openssl} dgst -"$alg" -mac HMAC -macopt "hexkey:$secret_hex" -binary 2>/dev/null || ${ACME_OPENSSL_BIN:-openssl} dgst -"$alg" -hmac "$(printf "%s" "$secret_hex" | _h2b)" -binary
+    fi
+  else
+    _err "$alg is not supported yet"
+    return 1
+  fi
+
+}
+
+# domain
+_is_idn() {
+  _is_idn_d="$1"
+  _debug2 _is_idn_d "$_is_idn_d"
+  _idn_temp=$(printf "%s" "$_is_idn_d" | tr -d '0-9' | tr -d 'a-z' | tr -d 'A-Z' | tr -d '*.,-_')
+  _debug2 _idn_temp "$_idn_temp"
+  [ "$_idn_temp" ]
+}
+
+# aa.com
+# aa.com,bb.com,cc.com
+_idn() {
+  __idn_d="$1"
+  if ! _is_idn "$__idn_d"; then
+    printf "%s" "$__idn_d"
+    return 0
+  fi
+
+  if _exists idn; then
+    if _contains "$__idn_d" ','; then
+      _i_first="1"
+      for f in $(echo "$__idn_d" | tr ',' ' '); do
+        [ -z "$f" ] && continue
+        if [ -z "$_i_first" ]; then
+          printf "%s" ","
+        else
+          _i_first=""
+        fi
+        idn --quiet "$f" | tr -d "\r\n"
+      done
+    else
+      idn "$__idn_d" | tr -d "\r\n"
+    fi
+  else
+    _err "Please install idn to process IDN names."
+  fi
+}
+
+_normalizeJson() {
+  sed "s/\" *: *\([\"{\[]\)/\":\1/g" | sed "s/^ *\([^ ]\)/\1/" | tr -d "\r\n"
+}
+
+# options file
+_sed_i() {
+  options="$1"
+  filename="$2"
+  if [ -z "$filename" ]; then
+    _usage "Usage:_sed_i options filename"
+    return 1
+  fi
+  _debug2 options "$options"
+  if sed -h 2>&1 | grep "\-i\[SUFFIX]" >/dev/null 2>&1; then
+    _debug "Using sed  -i"
+    sed -i "$options" "$filename"
+  else
+    _debug "No -i support in sed"
+    text="$(cat "$filename")"
+    echo "$text" | sed "$options" >"$filename"
+  fi
+}
+
+# sleep sec
+_sleep() {
+  _sleep_sec="$1"
+  if [ "$__INTERACTIVE" ]; then
+    _sleep_c="$_sleep_sec"
+    while [ "$_sleep_c" -ge "0" ]; do
+      printf "\r      \r"
+      __green "$_sleep_c"
+      _sleep_c="$(_math "$_sleep_c" - 1)"
+      sleep 1
+    done
+    printf "\r"
+  else
+    sleep "$_sleep_sec"
+  fi
+}
+
+_stat() {
+  #Linux
+  if stat -c '%U:%G' "$1" 2>/dev/null; then
+    return
+  fi
+
+  #BSD
+  if stat -f '%Su:%Sg' "$1" 2>/dev/null; then
+    return
+  fi
+
+  return 1 #error, 'stat' not found
+}
+
+
+_time() {
+  date -u "+%s"
+}
+
+_utc_date() {
+  date -u "+%Y-%m-%d %H:%M:%S"
+}
+
+# stubbed/aliased:
+__green() {
+  if [ "${__INTERACTIVE}${ACME_NO_COLOR:-0}" = "10" -o "${ACME_FORCE_COLOR}" = "1" ]; then
+    printf '\033[1;31;32m%b\033[0m' "$1"
+    return
+  fi
+  printf -- "%b" "$1"
+}
+
+__red() {
+  if [ "${__INTERACTIVE}${ACME_NO_COLOR:-0}" = "10" -o "${ACME_FORCE_COLOR}" = "1" ]; then
+    printf '\033[1;31;40m%b\033[0m' "$1"
+    return
+  fi
+  printf -- "%b" "$1"
+}
+
+_log() {
+  [ -z "$LOG_FILE" ] && return
+  _printargs "$@" >>"$LOG_FILE"
+}
+
+_info() {
+  _log "$@"
+  if [ "${SYS_LOG:-$SYSLOG_LEVEL_NONE}" -ge "$SYSLOG_LEVEL_INFO" ]; then
+    _syslog "$SYSLOG_INFO" "$@"
+  fi
+  _printargs "$@"
+}
+
+_err() {
+  _syslog "$SYSLOG_ERROR" "$@"
+  _log "$@"
+  if [ -z "$NO_TIMESTAMP" ] || [ "$NO_TIMESTAMP" = "0" ]; then
+    printf -- "%s" "[$(date)] " >&2
+  fi
+  if [ -z "$2" ]; then
+    __red "$1" >&2
+  else
+    __red "$1='$2'" >&2
+  fi
+  printf "\n" >&2
+  return 1
+}
+
+# key
+_readaccountconf() {
+  _read_conf "$ACCOUNT_CONF_PATH" "$1"
+}
+
+# key
+_readaccountconf_mutable() {
+  _rac_key="$1"
+  _readaccountconf "SAVED_$_rac_key"
+}
-- 
2.20.1





More information about the pve-devel mailing list