This commit is contained in:
81
list_root_domains.sh
Normal file
81
list_root_domains.sh
Normal file
@@ -0,0 +1,81 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
# Print a comma-separated list of unique registrable root domains (eTLD+1)
|
||||
# for non-suspended cPanel users based on /etc/userdomains.
|
||||
#
|
||||
# Tries to use `psl` (libpsl) if available for correct public suffix handling.
|
||||
# Falls back to a heuristic for common multi-level TLDs if `psl` is unavailable.
|
||||
|
||||
USERDOMAINS_PATH="/etc/userdomains"
|
||||
SUSPENDED_DIR="/var/cpanel/suspended"
|
||||
|
||||
error() {
|
||||
printf "Error: %s\n" "$*" 1>&2
|
||||
}
|
||||
|
||||
have_psl() {
|
||||
command -v psl >/dev/null 2>&1
|
||||
}
|
||||
|
||||
get_root_domain() {
|
||||
# Derive registrable domain (eTLD+1) from a hostname
|
||||
# 1) Prefer libpsl via `psl --print`
|
||||
# 2) Fallback heuristic for common multi-level TLDs
|
||||
hostname="$1"
|
||||
# strip trailing dot if any
|
||||
case "$hostname" in
|
||||
*.) hostname=${hostname%\.} ;;
|
||||
esac
|
||||
|
||||
if have_psl; then
|
||||
printed=$(psl --print "$hostname" 2>/dev/null | tr -d '\r')
|
||||
if [ -n "$printed" ]; then
|
||||
printf "%s\n" "$printed"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# Fallback heuristic implemented in awk to avoid bashisms
|
||||
printf "%s\n" "$hostname" | awk '
|
||||
BEGIN { FS = "." }
|
||||
{
|
||||
n = NF
|
||||
if (n >= 3) {
|
||||
lastTwo = $(n-1) "." $n
|
||||
if (lastTwo ~ /^(co\.uk|org\.uk|ac\.uk|gov\.uk|ltd\.uk|plc\.uk|me\.uk|co\.jp|ne\.jp|or\.jp|go\.jp|ac\.jp|ed\.jp|gr\.jp|com\.au|net\.au|org\.au|edu\.au|gov\.au|id\.au|asn\.au|com\.br|com\.cn|net\.cn|org\.cn|com\.sg|com\.my|co\.nz)$/) {
|
||||
print $(n-2) "." lastTwo
|
||||
next
|
||||
}
|
||||
}
|
||||
if (n >= 2) {
|
||||
print $(n-1) "." $n
|
||||
} else {
|
||||
print $0
|
||||
}
|
||||
}'
|
||||
}
|
||||
|
||||
main() {
|
||||
if [ ! -r "${USERDOMAINS_PATH}" ]; then
|
||||
error "Cannot read ${USERDOMAINS_PATH}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Read, normalize whitespace removal like original, skip lines starting with '*'
|
||||
# Format is typically: domain: user
|
||||
# For each non-suspended user, emit root domain; then unique-sort and join with commas
|
||||
sed -e 's/[[:space:]]*//g' -e '/^\*/d' "${USERDOMAINS_PATH}" \
|
||||
| awk -F: 'NF>=2 { print $1 ":" $2 }' \
|
||||
| while IFS=":" read -r domain username; do
|
||||
if [ ! -f "${SUSPENDED_DIR}/${username}" ]; then
|
||||
get_root_domain "${domain}"
|
||||
fi
|
||||
done \
|
||||
| sort -u \
|
||||
| paste -sd, -
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user