#!/bin/bash version=0.28 program=${0##*/} progdir=${0%/*} if [ "$progdir" = "$program" ]; then progdir="."; fi hostname=$(hostname) ext=${progdir##*/} # ---------------------------------------------------------------------- function usage() { cat < COPYRIGHT Copyright 2006 Henrik Levkowetz. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. There is NO WARRANTY; not even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. EOF } # ---------------------------------------------------------------------- function die() { echo -e "\n$program: error: $*" > /dev/stderr exit 1 } function note() { if [ -n "$VERBOSE" ]; then echo -e "$*"; fi } # ---------------------------------------------------------------------- function version() { echo -e "$program $version" } # ---------------------------------------------------------------------- trap 'echo "$program($LINENO): Command failed with error code $? ([$$] $0 $*)"; exit 1' ERR # ---------------------------------------------------------------------- # Option parsing # Options shortopts=hV longopts=help,version # Default values if [ "$(uname)" = "Linux" ]; then args=$(getopt -o "$shortopts" --long "$longopts" -n '$program' -- $SV "$@") if [ $? != 0 ] ; then die "Terminating..." >&2 ; exit 1 ; fi eval set -- "$args" sed="sed -r" else # Darwin, BSDs args=$(getopt -o$shortopts $SV $*) if [ $? != 0 ] ; then die "Terminating..." >&2 ; exit 1 ; fi set -- $args sed="sed -E" fi while true ; do case "$1" in -h| --help) usage; exit;; # Show this help, then exit # -v| --verbose) VERBOSE=1;; # Be more talkative -V| --version) version; exit;; # Show program version, then exit --) shift; break;; *) die "Internal error, inconsistent option specification: '$1'";; esac shift done # ---------------------------------------------------------------------- # Re-define die() and trap with cgi versions function die() { cat <<-EOF Status: $1 $2 Content-Type: text/html The requested document ($base) was not found on this server. The link on the ">referring page seems to be wrong or outdated. Please inform the author of ">that page about the error. If you entered the URL manually please check your spelling and try again.

Additional information: "$extra"

EOF exit 0 } # ---------------------------------------------------------------------- # usage() function usage() { cat <<-EOF Status: 302 Usage Location: https://$SERVER_NAME/$ext/ EOF exit 0 } # ---------------------------------------------------------------------- # trap trap 'die 404 "Content generation failed (on script line $LINENO) with error code $?"' ERR # ---------------------------------------------------------------------- # Check preconditions [ "$1" ] && export PATH_INFO="${1#/$ext}" [ "$REDIRECT_URL" ] && export PATH_INFO="${REDIRECT_URL#/$ext}" [ "$PATH_INFO" ] || usage [ "$SERVER_NAME" ] || export SERVER_NAME="$(hostname)" # ---------------------------------------------------------------------- # The program itself # Get the base name base="${PATH_INFO#/}" base=${base//[^A-Za-z0-9_.+ -]/_} # fix RFC case base=${base/RFC/rfc} # Document names don't contain spaces -- collapse them... base=${base/rfc /rfc} base=${base/draft /draft-} orig=$base base=${base%%/*} base=${base%%[^A-Za-z0-9-]*} if [ "$orig" != "$base" ]; then cat <<-EOF Status: 302 See Alternative Location: https://$SERVER_NAME/$ext/$base EOF exit fi # Check if it's a plain number if [ ${base} -gt 0 ]; then base=rfc${base}; fi 2>/dev/null # Determin path from beginning of string if [ ${base:0:3} = "rfc" ]; then path=/home/ietf/rfc; fi if [ ${base:0:3} = "std" ]; then path=/home/ietf/rfc/std; fi if [ ${base:0:3} = "fyi" ]; then path=/home/ietf/rfc/fyi; fi if [ ${base:0:3} = "bcp" ]; then path=/home/ietf/rfc/bcp; fi if [ ${base:0:7} = "charter" ]; then path=/www/tools.ietf.org/charter; fi if [ ${base:0:5} = "draft" ]; then path=/home/ietf/id; fi if [ ${base:0:3} = "ion" ]; then path=/home/ietf/ion/approved; fi if [ ${base:0:5} = "draft" -o ${base:0:3} = "ion" -o ${base:0:7} = "charter" ]; then file="$base.txt" if [ ! -f "$path/$file" ]; then declare -a names=($(wget -q -O - https://datatracker.ietf.org/api/v1/doc/document?name__startswith=$base | jq '.objects[]|.name+"-"+.rev' | tr -d '"')) if [ ${#names[@]} = 0 ]; then cat <<-EOF Status: 404 Not Found EOF exit elif [ ${#names[@]} = 1 ]; then base=${names[0]//\"/} file="$base.txt" elif [ "${names[0]%-[0-9][0-9]}" = "$base" ]; then base=${names[0]} file="$base.txt" else cat <<-EOF Status: 302 See This Location: https://$SERVER_NAME/id/$base EOF exit fi fi fi #if [ -d "/www/tools.ietf.org/wg/$base" ]; then # cat <<-EOF # Status: 302 Found # Location: https://$SERVER_NAME/wg/$base # # EOF # exit #fi #[ "$path" ] || die 404 "Not found." if [ ! "$path" ]; then sleep 1 path=/home/ietf/id; file=$(wget --prefer-family=IPv4 -S -O /dev/null https://tools.ietf.org/id/$base 2>&1 | grep "^Location:" | awk '{ sub(".*/", ""); print $1; }' ) if [ "$file" ]; then base="${file%.*}" else cat <<-EOF Status: 302 See Other Location: https://$SERVER_NAME/id/$base EOF exit fi fi if [ "$path" = "/home/ietf/rfc" -o \ "$path" = "/home/ietf/rfc/bcp" -o \ "$path" = "/home/ietf/rfc/std" -o \ "$path" = "/home/ietf/rfc/fyi" ]; then tail=${base#???} tail=${tail#0} tail=${tail#0} tail=${tail#0} base="${base:0:3}$tail" file="$base.txt" fi [ -f "$path/$file" ] || die 404 "Not found: ($file)" urld="${REQUEST_URI%/*}" urld="${urld#/}" urlb="${REQUEST_URI##*/}" [ "$urld" ] || urld=$ext #if [ -f "$path/$base.$ext" ]; then # cp $path/$base.$ext . if [ ! -f "$base.$ext" ]; then sleep 5 unset QUERY_STRING SCRIPT_NAME="/$urld" #/www/tools.ietf.org/tools/rfcmarkup/rfcmarkup "static=true&doc=$base" > $base.$ext 2>&1 if [ "$ext" = "html" ]; then /www/tools.ietf.org/tools/rfcmarkup/rfcmarkup "robots=index,follow&staticpath=true&topmenu=true&doc=$base.txt" > $base.$ext 2>&1 content_type="text/html" for patch in $(ls -tr $base.*.patch 2>/dev/null); do patch -sf -p0 < $patch done elif [ "$ext" = "abnf" ]; then /www/tools.ietf.org/tools/aex/aex $path/$base.txt > $base.$ext 2>&1 content_type="text/plain" if [ $(stat -c %s $base.$ext) = "0" ]; then echo -e ";\n; No ABNF found in $base.txt\n;" > $base.$ext; fi fi if head $base.$ext | grep -qs "^Location: "; then echo -e "Status: 302 Available\n" head $base.$ext mv $base.$ext $base.$ext.location exit fi if tail $base.$ext | grep -qs "

    Sorry, couldn't find"; then rm $base.$ext fi fi if [ -f "$base.$ext" ]; then if [ "$urlb" = "$base" ]; then cat <<-EOF Status: 200 OK Content-Type: $content_type; charset=UTF-8 EOF cat $base.$ext else cat <<-EOF Status: 302 Found Location: https://$SERVER_NAME/$urld/$base Content-Type: text/html; charset=UTF-8

The document is available here: http://$SERVER_NAME/$urld/$base.

EOF fi else die 404 "Not Found [$base.$ext] " fi