Skip to content

Instantly share code, notes, and snippets.

@pgdad
Created July 24, 2025 14:38
Show Gist options
  • Select an option

  • Save pgdad/7720d368185b2b229da53960bf21e121 to your computer and use it in GitHub Desktop.

Select an option

Save pgdad/7720d368185b2b229da53960bf21e121 to your computer and use it in GitHub Desktop.
Bash scripts for porkbun-txt DNS file storage system
#!/bin/bash
# fetch-file.sh - Fetch a single file from DNS TXT records
# Usage: ./fetch-file.sh <filename> [output_directory]
set -e
# Check if filename is provided
if [ "$#" -lt 1 ] || [ "$#" -gt 2 ]; then
echo "Usage: $0 <filename> [output_directory]" >&2
echo "Example: $0 myfile.txt" >&2
echo "Example: $0 myfile.txt /path/to/output" >&2
echo "If output_directory is not specified, uses 'porkbun-downloads' in current directory" >&2
exit 1
fi
FILENAME="$1"
OUTPUT_DIR="${2:-porkbun-downloads}"
# Function to lookup TXT record
lookup_txt() {
local domain="$1"
# Use nslookup to get TXT record, extract the quoted content
nslookup -type=TXT "$domain" 2>/dev/null | \
grep "text = " | \
sed 's/.*text = "//' | \
sed 's/"$//' | \
sed 's/\\"/"/g' | \
head -n1
}
# Read index from DNS
echo "Reading index from DNS..." >&2
INDEX_CONTENT=$(lookup_txt "index.pgdad.org")
if [ -z "$INDEX_CONTENT" ]; then
echo "Error: Could not read index from DNS" >&2
exit 1
fi
# Parse JSON to find the file entry
# This uses a simple approach - for production use, consider using jq
SUFFIX=$(echo "$INDEX_CONTENT" | grep -o "\"$FILENAME\":{[^}]*}" | grep -o '"suffix":"[^"]*"' | cut -d'"' -f4)
if [ -z "$SUFFIX" ]; then
echo "Error: File '$FILENAME' not found in index" >&2
exit 1
fi
# Extract subindex from suffix (remove "content.pgdad.org" part)
SUBINDEX=$(echo "$SUFFIX" | sed 's/content\.pgdad\.org$//')
echo "Found file '$FILENAME' with subindex: $SUBINDEX" >&2
# Fetch content chunks sequentially
echo "Fetching content chunks..." >&2
RECORD_INDEX=0
CONTENT=""
while true; do
RECORD_NAME="c${RECORD_INDEX}-${SUBINDEX}content.pgdad.org"
CHUNK=$(lookup_txt "$RECORD_NAME")
if [ -z "$CHUNK" ]; then
break
fi
CONTENT="${CONTENT}${CHUNK}"
RECORD_INDEX=$((RECORD_INDEX + 1))
echo " Fetched chunk $RECORD_INDEX" >&2
done
if [ "$RECORD_INDEX" -eq 0 ]; then
echo "Error: No content records found for file '$FILENAME'" >&2
exit 1
fi
echo "Successfully fetched $RECORD_INDEX chunks" >&2
# Create output directory if it doesn't exist
if [ ! -d "$OUTPUT_DIR" ]; then
echo "Creating output directory: $OUTPUT_DIR" >&2
mkdir -p "$OUTPUT_DIR"
fi
# Write content to file (unescaping octal sequences)
OUTPUT_FILE="$OUTPUT_DIR/$FILENAME"
printf '%s' "$CONTENT" | sed 's/\\010/\n/g; s/\\009/\t/g' > "$OUTPUT_FILE"
echo "File saved to: $OUTPUT_FILE" >&2
#!/bin/bash
# list-files.sh - List all stored files from DNS TXT records
# Usage: ./list-files.sh
# Requirements: jq, nslookup
set -e
# Check if jq is available
if ! command -v jq &> /dev/null; then
echo "Error: jq is required but not installed" >&2
exit 1
fi
# Function to lookup TXT record
lookup_txt() {
local domain="$1"
# Use nslookup to get TXT record, extract the quoted content and unescape
nslookup -type=TXT "$domain" 2>/dev/null | \
grep "text = " | \
sed 's/.*text = "//' | \
sed 's/"$//' | \
sed 's/\\"/"/g' | \
head -n1
}
# Read index from DNS
echo "Reading index from DNS..." >&2
INDEX_CONTENT=$(lookup_txt "index.pgdad.org")
if [ -z "$INDEX_CONTENT" ]; then
echo "Error: Could not read index from DNS" >&2
exit 1
fi
# Validate JSON
if ! echo "$INDEX_CONTENT" | jq empty 2>/dev/null; then
echo "Error: Invalid JSON in index" >&2
exit 1
fi
# Check if index is empty
if [ "$(echo "$INDEX_CONTENT" | jq 'length')" -eq 0 ]; then
echo "No files stored."
exit 0
fi
# Extract file information using jq and sort by filename
echo "Stored files:"
echo "$INDEX_CONTENT" | jq -r 'to_entries | sort_by(.key) | .[] |
.key as $filename |
.value.suffix as $suffix |
.value.encrypted as $encrypted |
if $encrypted then
" " + $filename + " -> " + $suffix + " [encrypted]"
else
" " + $filename + " -> " + $suffix
end'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment