#!/bin/sh # domrev --- Reverse domain names or IP addresses # Author: Noah Friedman # Created: 1994-10-10 # Public domain # $Id: domrev,v 1.6 1997/08/10 07:03:48 friedman Exp $ # Commentary: # This script can be used to sort mailing list aliases by order of domain # via a command like: # # domrev address-file | sort | domrev # # It understands parenthesized comments at the end of addresses, e.g. # friedman@prep.ai.mit.edu (Noah Friedman) # But it will NOT grok # Noah Friedman # Code: # Name by which this script was invoked. progname=`echo "$0" | sed -e 's/[^\/]*\///g'` # To prevent hairy quoting and escaping later. bq='`' eq="'" usage="Usage: $progname {options} {files} Options are: -D, --debug Turn on shell debugging ($bq${bq}set -x$eq$eq). -h, --help You're looking at it. -s, --string HOSTNAME Reverse HOSTNAME argument from command line. " # Initialize variables. # Don't use `unset' since old bourne shells don't have this command. # Instead, assign them an empty value. debug= string= # Usage: eval "$getopt"; value=$optarg # or optarg_optional=t; eval "$getopt"; value=$optarg # # This function automatically shifts the positional args as appropriate. # The argument to an option is optional if the variable `optarg_optional' # is non-empty. Otherwise, the argument is required and getopt will cause # the program to exit on an error. optarg_optional is reset to be empty # after every call to getopt. The argument (if any) is stored in the # variable `optarg'. # # Long option syntax is `--foo=bar' or `--foo bar'. 2nd argument # won't get used if first long option syntax was used. # # Note: because of broken bourne shells, using --foo=bar syntax can # actually screw the quoting of args that end with trailing newlines. # Specifically, most shells strip trailing newlines from substituted # output, regardless of quoting. getopt=' { optarg= case "$1" in --*=* ) optarg=`echo "$1" | sed -e "1s/^[^=]*=//"` shift ;; * ) case ${2+set} in set ) optarg="$2" shift shift ;; * ) case "$optarg_optional" in "" ) case "$1" in --*=* ) option=`echo "$1" | sed -e "1s/=.*//;q"` ;; * ) option="$1" ;; esac exec 1>&2 echo "$progname: option $bq$option$eq requires argument." echo "$progname: use $bq--help$eq to list option syntax." exit 1 ;; esac ;; esac ;; esac optarg_optional= }' # Parse command line arguments. # Make sure that all wildcarded options are long enough to be unambiguous. # It's a good idea to document the full long option name in each case. # Long options which take arguments will need a `*' appended to the # canonical name to match the value appended after the `=' character. while : ; do case $# in 0) break ;; esac case "$1" in -D | --debug | --d* ) debug=t shift ;; -h | --help | --h ) echo "$usage" 1>&2 exit 1 ;; # Provided as an example of how to process options with arguments -s | --string* | --s* ) eval "$getopt" string=$optarg ;; -- ) # Stop option processing shift break ;; -? | --* ) case "$1" in --*=* ) arg=`echo "$1" | sed -e 's/=.*//'` ;; * ) arg="$1" ;; esac exec 1>&2 echo "$progname: unknown or ambiguous option $bq$arg$eq" echo "$progname: Use $bq--help$eq for a list of options." exit 1 ;; -??* ) # Split grouped single options into separate args and try again optarg="$1" shift set fnord `echo "x$optarg" | sed -e 's/^x-//;s/\(.\)/-\1 /g'` ${1+"$@"} shift ;; * ) break ;; esac done case "$debug" in t ) set -x ;; esac sedstr=' /\./!{p;q;} H /(.*)/{ s/[^ ]*\([ ]*(.*)\).*$/\1/ b s } s/.*// :s x s/[ ]*(.*)[ ]*$// /[@.]$/!s/$/./ :1 s/\(.*\)\(\n.*[@.]\)\([^@.][^@.]*[@.]\)$/\1\3\2/ t 1 s/\n// s/\.$// G s/\n/ / s/[ ]*$// p s/.*// h ' case ".$string" in . ) sed -ne "$sedstr" ${1+"$@"} ;; * ) echo "$string" | sed -ne "$sedstr" ;; esac # domrev ends here