Created
January 19, 2026 16:29
-
-
Save itsfolf/2c9267fd75edfc192932516a453fe552 to your computer and use it in GitHub Desktop.
PoDNS bash
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/sh | |
| # pronouns.sh - query pronouns over DNS | |
| set -euo pipefail | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[1;33m' | |
| BLUE='\033[0;34m' | |
| NC='\033[0m' | |
| usage() { | |
| echo "usage: $0 <domain>" | |
| exit 1 | |
| } | |
| strip_quotes() { | |
| echo "$1" | sed 's/^"//;s/"$//' | |
| } | |
| normalize() { | |
| echo "$1" | tr '[:upper:]' '[:lower:]' | tr -d '[:space:]' | |
| } | |
| remove_comment() { | |
| echo "$1" | sed 's/#.*//' | |
| } | |
| get_comment() { | |
| [[ "$1" == *"#"* ]] && echo "$1" | sed 's/^[^#]*#[[:space:]]*//' || echo "" | |
| } | |
| parse_tags() { | |
| [[ "$1" == *";"* ]] && echo "$1" | cut -d';' -f2- | tr ';' '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | grep -v '^$' | sort -u | |
| } | |
| get_pronoun_set() { | |
| echo "$1" | cut -d';' -f1 | sed 's/[[:space:]]*$//' | |
| } | |
| validate_pronoun_set() { | |
| local parts=$(echo "$1" | tr '/' '\n' | wc -l) | |
| [[ $parts -ge 2 && $parts -le 5 ]] && echo "$1" | grep -qE '^[a-z]+(/[a-z]+){1,4}$' | |
| } | |
| convert_pronoun_set() { | |
| [[ "$1" == "it/its" ]] && echo "it/it/its/its/itself" || echo "$1" | |
| } | |
| format_pronoun_set() { | |
| local output="$1" | |
| [[ -n "$2" ]] && output="$output (tags: $(echo "$2" | tr '\n' ',' | sed 's/,$//' | sed 's/,/, /g'))" | |
| echo "$output" | |
| } | |
| has_preferred_tag() { | |
| [[ -z "$1" ]] && return 1 | |
| echo "$1" | grep -qx 'preferred' | |
| } | |
| main() { | |
| [[ $# -ne 1 ]] && usage | |
| local domain="$1" | |
| local query_domain="$domain" | |
| # don't prepend pronouns. if it's already there | |
| if [[ "$domain" != pronouns.* ]]; then | |
| query_domain="pronouns.$domain" | |
| fi | |
| echo -e "${BLUE}Querying: ${query_domain}${NC}" | |
| echo "" | |
| local raw_records | |
| if ! command -v dig &> /dev/null; then | |
| echo -e "${RED}Error: 'dig' not found. Install bind-tools or dnsutils.${NC}" >&2 | |
| exit 1 | |
| fi | |
| raw_records=$(dig +short TXT "$query_domain" 2>/dev/null) | |
| if [[ -z "$raw_records" ]]; then | |
| echo -e "${YELLOW}No pronoun records found for ${domain}${NC}" | |
| exit 0 | |
| fi | |
| declare -a records=() | |
| declare -a record_tags=() | |
| declare -a comments=() | |
| local has_wildcard=false | |
| local has_none=false | |
| while IFS= read -r raw_record; do | |
| local stripped=$(strip_quotes "$raw_record") | |
| local comment=$(get_comment "$stripped") | |
| local record=$(remove_comment "$stripped") | |
| record=$(normalize "$record") | |
| # handle comment-only records | |
| if [[ -z "$record" && -n "$comment" ]]; then | |
| records+=("#") | |
| record_tags+=("") | |
| comments+=("$comment") | |
| continue | |
| fi | |
| [[ -z "$record" ]] && continue | |
| if [[ "$record" == "*" ]]; then | |
| has_wildcard=true | |
| records+=("*") | |
| record_tags+=("") | |
| comments+=("$comment") | |
| continue | |
| fi | |
| if [[ "$record" == "!" ]]; then | |
| has_none=true | |
| records+=("!") | |
| record_tags+=("") | |
| comments+=("$comment") | |
| continue | |
| fi | |
| local pronoun_set=$(get_pronoun_set "$record") | |
| local tags=$(parse_tags "$record") | |
| pronoun_set=$(convert_pronoun_set "$pronoun_set") | |
| if ! validate_pronoun_set "$pronoun_set"; then | |
| echo -e "${RED}Warning: Invalid pronoun set: ${record}${NC}" >&2 | |
| continue | |
| fi | |
| # auto-add plural tag for they/them | |
| if [[ "$pronoun_set" == "they/them"* && ! "$tags" =~ "plural" ]]; then | |
| tags=$(echo -e "${tags:+$tags\n}plural" | grep -v '^$' | sort -u) | |
| fi | |
| records+=("$pronoun_set") | |
| record_tags+=("$tags") | |
| comments+=("$comment") | |
| done <<< "$raw_records" | |
| if [[ ${#records[@]} -eq 0 ]]; then | |
| echo -e "${YELLOW}No valid pronoun records found${NC}" | |
| exit 0 | |
| fi | |
| # count non-comment records for validation | |
| local non_comment_count=0 | |
| for r in "${records[@]}"; do | |
| [[ "$r" != "#" ]] && ((non_comment_count++)) || true | |
| done | |
| if [[ "$has_none" == true && $non_comment_count -gt 1 ]]; then | |
| echo -e "${RED}Error: ! record must be alone${NC}" >&2 | |
| exit 1 | |
| fi | |
| echo -e "${GREEN}Found ${#records[@]} pronoun record(s):${NC}" | |
| echo "" | |
| for i in "${!records[@]}"; do | |
| local record="${records[$i]}" | |
| local tags="${record_tags[$i]}" | |
| local comment="${comments[$i]}" | |
| if [[ "$record" == "#" ]]; then | |
| echo -e " ${BLUE}#${NC} $comment" | |
| elif [[ "$record" == "*" ]]; then | |
| local output=" ${YELLOW}*${NC} - Wildcard (any pronouns)" | |
| [[ -n "$comment" ]] && output="$output # $comment" | |
| echo -e "$output" | |
| elif [[ "$record" == "!" ]]; then | |
| local output=" ${YELLOW}!${NC} - None (use name)" | |
| [[ -n "$comment" ]] && output="$output # $comment" | |
| echo -e "$output" | |
| else | |
| local formatted=$(format_pronoun_set "$record" "$tags") | |
| if has_preferred_tag "$tags"; then | |
| local output=" ${GREEN}✓${NC} $formatted ${GREEN}[PREFERRED]${NC}" | |
| [[ -n "$comment" ]] && output="$output # $comment" | |
| echo -e "$output" | |
| else | |
| local output=" • $formatted" | |
| [[ -n "$comment" ]] && output="$output # $comment" | |
| echo -e "$output" | |
| fi | |
| fi | |
| done | |
| echo "" | |
| echo -e "${BLUE}Default pronoun selection:${NC}" | |
| if [[ "$has_none" == true ]]; then | |
| echo -e " ${YELLOW}Use name (no pronouns)${NC}" | |
| elif [[ "$has_wildcard" == true ]]; then | |
| local preferred_idx=-1 | |
| local non_wildcard_count=0 | |
| for i in "${!records[@]}"; do | |
| if [[ "${records[$i]}" != "*" && "${records[$i]}" != "#" ]]; then | |
| ((non_wildcard_count++)) || true | |
| has_preferred_tag "${record_tags[$i]}" && preferred_idx=$i && break | |
| fi | |
| done | |
| if [[ $non_wildcard_count -eq 0 ]]; then | |
| echo -e " ${YELLOW}Any, default: they/them${NC}" | |
| elif [[ $preferred_idx -ge 0 ]]; then | |
| echo -e " ${YELLOW}Any, default: ${records[$preferred_idx]}${NC}" | |
| else | |
| for i in "${!records[@]}"; do | |
| [[ "${records[$i]}" != "*" && "${records[$i]}" != "#" ]] && echo -e " ${YELLOW}Any, default: ${records[$i]}${NC}" && break | |
| done | |
| fi | |
| else | |
| local preferred_idx=-1 | |
| for i in "${!records[@]}"; do | |
| [[ "${records[$i]}" == "#" ]] && continue | |
| has_preferred_tag "${record_tags[$i]}" && preferred_idx=$i && break | |
| done | |
| if [[ $preferred_idx -ge 0 ]]; then | |
| echo -e " ${GREEN}${records[$preferred_idx]}${NC}" | |
| else | |
| # find first non-comment record | |
| for i in "${!records[@]}"; do | |
| if [[ "${records[$i]}" != "#" ]]; then | |
| echo -e " ${GREEN}${records[$i]}${NC} (first record)" | |
| break | |
| fi | |
| done | |
| fi | |
| fi | |
| } | |
| main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment