#!/bin/bash
# 
#* abuse.sh  v2.32 Sat 04/20/02 07:16:44 PM
#* By: Hal Burgiss <hal@foobox.net>
#
#* A bash/shell script that helps automate filing abuse reports for
#* unwanted connection attempts. Pass one or more IP addresses on command
#* line and follow the prompts. Optionally, can be invoked with the '-c'
#* option to use Chad Wagner's chainlysis program for input instead. Or '-f'
#* to use a file generated by chainlysis. chainlyis is an ipchains log 
#* data collecting tool. http://glycerine.dyndns.org/linux/chainlysis/
#
#* abuse.sh is meant to be used in conjunction with ipchains on Linux.
#* Read comments in script to get an idea of what it does. Or just run it ;)
#
#* usage: abuse.sh <abusers's ip addresses, ip address, ...>
#*        abuse.sh -c  (uses chainlysis for input)
#*        abuse.sh -f <file> (reads from file generated by chainlysis)
#
#* Requires: ipchains, and logged data from ipchains.
#*           bind-utils (for 'host' command, not essential but helps)
#*           chainlysis (v1.10 or later), for the -c and -f options only.
#
#* Also, requires an up and working connection at run time for whois.
#
#* Note: still a work in progress. Come again.
#
#* Try the help with 'h' key to see what keys/options are available at each 
#* prompt. 
#
#* WHAT'S NEW:
#* Should be working with iptables log format now. (require recent 
#* chainlysis if you are using that.
#* Fix for broken 'host' command from RH7.1 (not valid return value)
#*
#* Recent additions: more than one IP can be passed on the command line.
#* abuse.sh can now parse chainlysis output and run the results as a batch.
#* Text browser can be invoked from any prompt for Q&E web searches. A 
#* little bit of help is available with 'h' key. 
#
#* Note that while sometimes determining the appropriate 'abuse' address 
#* for complaints is straightforward, sometimes it is by no means obvious no 
#* matter what you do. Pretty much all ISPs and large orgainizations have an 
#* abuse mailbox like 'abuse@isp.com'. Generally, if the address is bad, the
#* mail will bounce, and then you will know to try something else. Otherwise, 
#* you have probably hit a 'good' address. If you think you have the correct 
#* domain name for complaints (ie. isp.com), and 'abuse' bounces, as a last 
#* resort try 'root' or 'postmaster'. This should be rarely necessary though.
#
#* Don't expect a response either. Many do not respond at all, or send some
#* kind of auto-responder back. This does not necessarily mean you are being
#* ignored. Most of these organizations get 1,000's of such emails.
#
#* Please look at the first few variables, and make sure they are 
#* appropriate for your system. I use some non-standard stuff. I much
#* prefer bw-whois to the standard whois for instance.
#
#* TIP: This works much better with bind-utils and bw-whois installed. 
#* jwhois is good too. FYI.
#
#* This is free software. No warranty whatsoever of any kind. Use at 
#* your own risk, and that of your assailants. Seat belt and helmet, 
#* optional.
#
#########################################################################
#
# DO NOT USE! Well, for testing. No real mail will be sent, and no logging.
DEBUG=false
# Iptables or not...may need to be set, true for iptables, false for ipchains.
K24=true
#
# Where ipchains logs to...check the location here.
# Typically this is /var/log/messages. If you are logging somewhere else, then 
# this must be set correctly.
#LOG_FILE=/var/log/messages
LOG_FILE=/var/log/klog

# Program to do a 'whois' lookup. Plain 'whois' is std. Again, may need to be
# changed. bw-whois is an improved 'whois'... does a better better job for
# addresses that are not covered by ARIN, ie European (ripe.net) and Asian
# (apnic.net). Better all the way around.
#WHOIS=whois
WHOIS=bw-whois

# Mailer command. Again, 'mail' is std. You may want that instead of mutt.
#MAILER=mail
MAILER=mutt

# Set to true if you want a copy of each mail sent to you also.
#ME_TOO=true
ME_TOO=false

# Pager/viewer command ... used to view whois output and preview the generated
# abuse mail.
#PAGER="less -cMsi"
PAGER="less +Gg"
export LESS="-P abuse\.sh\:  Line %lb/%L   q to return  "

# Define this if you want to include a sig.
SIG="/home/hal/.signature"

# You can edit the message body when in preview mode. To do this, press 'v'
# once 'less' fires up. If you don't wind up with your editor of choice, then
# try setting this to appropriate value:
#EDITOR=pico
#EDITOR=mcedit

# Text mode browser to lookup port scanning help info ...
#TEXT_BROWSER=lynx
# In most respects, w3m is hands down better than lynx IMNSHO. HIGHLY 
# recommended!
TEXT_BROWSER="/usr/bin/w3m"

# Page with port scan reference data .... invoked with 'p'.
PORT_URL="http://www.robertgraham.com/pubs/firewall-seen.html#1.1"

# What text we put at the top of our form letter ...
BOILERPLATE="\
The following is an unwanted connection attempt from one of
your IP addresses. Based on port destination, the chances are
good that someone was trying an unlawful entry or other exploit,
and it certainly is unauthorized and unwanted. This is just a heads 
up notification that something is not right. No harm has been done. 
Please take the appriopriate action. All timestamps 
are `date +%Z` (`date +%z`)." #gives Timezone, eg EST.

# A regexp list of attempts that probably are not worth reporting.
# A warning will be issued for these. NOT IMPLEMENTED!
#WARNINGS=":137\ \|PROTO=1\ \|:113\ "

# Log our abuse complaints. Leave blank to disable. Make sure you have write
# permissions also or you will get an error.
#LOG_TO=
LOG_TO=/var/log/abuse

# You might want to set this if <backspace> does not behave ...
#stty erase ^?
#stty erase ^H
#
#######################################################################
# None of these should be modified ...
#
TMP_DIR=/tmp/abuse.d
TMP_FILE=$TMP_DIR/`basename $0`.tmp
ARGS=$*
ARGS_ORG=$ARGS
ABUSE=
OLD_ABUSE=
HOST=
NUM_FIELDS=
IP=
NUM_ARGS=0
NUM_MAILS=0
SKIP_IT=false
#######################################################################
#
############ Function Declarations ####################################
#
# --- short function ---------- #
input() {

 read -e -p "> " $1
# read -e -p "$USERNAME > " $1
 echo

}


# --- another one ---------- #
cancel() {

 echo -n "Reporting cancelled, " 
 
 if [ $NUM_MAILS -eq 0 ]; then
 
  echo -n "no mail sent. "

 else

  echo -n "$NUM_MAILS mail(s) sent. "

 fi
 
 echo Exiting.
 rm -rf $TMP_DIR
 exit 0

}


# -- and another one ------- #
# This is used to look up whatever you want. PORT_URL is defaulted to 
# a page with port scanning info, common trojans, etc.
# Keystroke for this is 'p' on most screens.
browser_help() {

 if ! [ "$TEXT_BROWSER" = "" ]; then
 
  echo Loading "$PORT_URL ..."
  $TEXT_BROWSER "$PORT_URL"
  clear

 else

  echo "Browser configuration error. Not available."

 fi

}

# -- and another one ------- #

browser() {
# Start up a text browser, optionally can pass an argument and the 
# browser will start at that page. The default is Apache/localhost.
# Keystroke for this is 'b' on most screens.
 local start_page=localhost
 local arg="`echo $* |sed 's/^[b,B]\ \{0,1\}//'`"

 if [ "$arg" != "" ]; then
  
   start_page="$arg"

 fi

 if ! [ "$TEXT_BROWSER" = "" ]; then
 
  $TEXT_BROWSER "$start_page"
  clear
 
 else

  echo "Browser configuration error. Not available."

 fi

}


#-- pop the first IP from top of the arg list ---#
first(){

echo $ARGS |awk '{print $1}'

}


#-- go to top, and start with the next IP -#
next(){


ARGS=`echo $ARGS |sed "s/$IP//"`
IP=`first`
ABUSE=
HOST=
clear
continue

}


#-- The header for each IP processed -----#
do_banner() {
 local num=1
 local total_num=1
 local i=1

 for i in $ARGS_ORG; do 

   if [ "$i" = "$IP" ]; then

    break

   fi

  num=$(($num+1))

 done

 echo "`basename $0`: 'q' to quit program. 'h' for help. $IP, $num of $NUM_ARGS"
 echo

}


#-- gives us neater logging ------#
# pad a string to a set length
#
pad() {
# $1 is the string, $2 is ultimate length.
 local str=""

 while [ `echo "$1$str" | wc -c` -le $2 ]; do 

  # pad with spaces.
  str="$str "

 done

 echo "$1$str"

}


#-- a little help please ----------------#
# This just covers keystrokes
help() {
 local message

message=\
"Keystrokes available on all screens:
 <ENTER> = Accept value, and move to the next item.
 'y' = yes, accept current value.
 'n' = no, do not accept.
 'q' = quit. Will exit program immediately if issued 
       from a prompt. If you use chainlysis for input, any 
       remaining data that is not processed, is lost.
       When in 'less', will exit 'less' and return to abuse.sh 
       prompt.
 'p' = Invoke text browser and look up port scan and trojan info.
 'b' = Invoke text browser.
 'h' = Help! How you got here dummy.
 's' = Skip current IP complaint and move to the Next (if 
       available).
" 

case $1 in

  whois)
   message="$message

Other Keys available here:
 'a' = Use APNIC (Asian) for a whois lookup.
 'r' = Use RIPE (Euro) for a whois lookup.
 'k' = Use nic.or.kr (Korean) for a whois lookup.
 
HINTS: If whois draws a blank, there is a good chance that 
$IP is registered with APNIC or RIPE. Try the 'a' and 'r' 
keys to see. Most whois data does not report an 'abuse' 
address. You will have to try to dig out the likely looking 
domain and send it there."
 ;;

  abuse)
   if [ -z $ABUSE ]; then
   message="$message

You have to type in an address to send abuse mail here. 
The other options are 's' to skip this one, or 'q' to 
quit program.
"  
   else
   message="$message

Press enter to accept $ABUSE as the place to send this 
complaint. Either that, or enter another address of 
your choosing.
"

   fi
   ;;
 
  preview)
   message="$message

Press 'y' to preview this mail before sending. Once in 
preview mode 'v' will enter edit mode in case you want
to modify or add anything. 'q' to exit preview mode. 
ENTER to proceed.
"
   ;;

  last)
   message="$message

Last chance here. 'y' to send. 'n' or 's' will not send 
and move to the next IP (if any). 'e' will edit.
"
   ;;
 
  
esac

echo "$message" | less
clear

#  'B' = Use RNP (Brazilian)
#  'm' = NIC-Mexico
# 
#  + Delegated Registries Within the Americas
#  o RNP (Brazilian Registry) registro@fapesp.br
#  o NIC-Mexico (Mexican Registry) hostmaster@nic.mx

}


#-- get data from chainlysis ------------#
# Actually this will work with any file that has IP
# addresses in the first column.
# Called if '-c' or '-f' options are specified.
#
get_ipdata() {
 local tmpfile=$TMP_DIR/chainlysis
 local line
 local command="chainlysis"

 if [ "$1" = "-c" ] && ! which chainlysis >/dev/null 2>&1; then

  echo chainlysis is not installed or not in your PATH.
  cancel
 
 elif [ "$1" = "-c" ]; then

  echo -n "Getting chainlysis data.."

 elif [ "$1" = "-f" ]; then
 
    if  [ "$2" = "" ]; then

     echo No data file specified. We cannot go on like this.
     cancel

    elif ! [ -f "$2" ]; then

     echo "$2" does not seem to exist. Check spelling and PATH.
     cancel
    
    fi

   command="cat $2"
   echo -n "Reading data from `basename $2`.."

 fi
 

 # Read data in here ...
 $command | while read line; do

  if echo "$line" | grep "^Reject" >/dev/null ; then
  # Stop the read at this line. 
   
   break
  
  elif ! echo "$line" | grep "^[1-9][0-9]\{0,2\}\." >/dev/null; then
  # Ignore non-IP addresses, this is half ass evaluation but should 
  # be sufficient given our input criteria.

   continue
  
  fi

  # workaround for variable scoping issue in pipe.
  echo $line |awk '{print $1}' >> $tmpfile
  echo -n .

 done  

 if [ -s $tmpfile ]; then
 
  ARGS=`cat $tmpfile`
  echo done.

 else

  ARGS=
  echo .no data this time.

 fi
 
 ARGS_ORG=$ARGS
 rm -f $tmpfile

}


#-- See if we should skip this one --#
skip_it() {
# Moves on to the next IP in the list.

 if $SKIP_IT; then

  # Reset to default
  SKIP_IT=false
  
  echo Skipping $IP ...
  # Go to next IP in ARG list...
  next

 fi

}

#-- do the whois lookup here ----#
iswho() {

 echo Use mouse to copy abuse info...'q' to quit from 'less'.
 echo
 sleep 1
 $WHOIS $IP\@"$1" 2>/dev/null | $PAGER
 clear

}

########## end functions ##############################################


#######################################################################
########### start program execution here ##############################
#
# and start with a few sanity checks...

clear

# Start with trying to see if we have a valid IP address to work with ...
# We need at least something. DO NOT USE hostnames!!!!
if [ "$ARGS" = "" ]; then

 echo "We need an IP address from somewhere! Aborting."
 exit 1

fi

# Look for specified log ...
if ! [ -f $LOG_FILE ]; then 

   if [ -f /var/log/messages ]; then 
 
    LOG_FILE="/var/log/messages"

   else

     echo Cannot find a valid log file. Set the LOG_FILE variable. Aborting.
     exit 1

   fi
 
fi


# Check if a web browser is available ... 
if ! which "$TEXT_BROWSER" >/dev/null 2>&1; then

  if which lynx >/dev/null 2>&1; then

    TEXT_BROWSER="lynx"

  else

    TEXT_BROWSER=

  fi

fi

##################################################################
## end global sanity checks, and start doing something usefull ...

mkdir -p $TMP_DIR

if [ "$1" = "-c" ] || [ "$1" = "-f" ]; then

 get_ipdata $*

fi


# we need to do it this way since chainlysis may be providing the ARGS.
for i in $ARGS; do 

 NUM_ARGS=$(($NUM_ARGS+1))

done



# Get the first IP to process from $ARGS
IP=`first`


#########################################################################
######## Main Program Loop ##############################################
#
while [ "$ARGS" != "" ]; do

 do_banner

 # Start verifying we have a good IP ...
 #
 # A quick test for non-IP type chars ...
 if echo "$IP" |grep [^[:digit:]\.] >/dev/null ||\
    ! echo "$IP" |grep "[0-9]\.[0-9]" >/dev/null ; then

  echo "Silly Boy! ' $IP ' is not a legit IP address!"
  echo -en \\n"  Press any key ..."
  read
  next
 # exit 1

 fi

 #<172\.16\. -> 31.

 # Check for a bogus, private IP address ...
 if echo "$IP" |grep "\<192\.168\.[0-9]\{0,3\}\.[0-9]\{0,3\}" >/dev/null ||\
     echo "$IP" |\
        grep "\<10\.[0-9]\{0,3\}\.[0-9]\{0,3\}\.[0-9]\{0,3\}" >/dev/null ||\
       echo "$IP" |\
         grep "\<172\.[1][6-9]\.[0-9]\{0,3\}\.[0-9]\{0,3\}" >/dev/null ||\
        echo "$IP" |\
          grep "\<172\.[2][0-9]\.[0-9]\{0,3\}\.[0-9]\{0,3\}" >/dev/null ||\
         echo "$IP" |\
           grep "\<172\.[3][0-1]\.[0-9]\{0,3\}\.[0-9]\{0,3\}" >/dev/null ||\
          echo "$IP" |\
            grep "\<169\.254\.[0-9]\{0,3\}\.[0-9]\{0,3\}" >/dev/null ; then

  echo \
"$IP is a private, non-traceable IP address. The mostly 
likely reason you see this is a misconfiguration somewhere 
near you. Either your ISP or another user on your subnet. 
It is unlikely that this is an attack of any kind. This IP 
address cannot be traced, or reported to anyone.
"
  echo -ne \\n"  Press any key ..."
  read
  
  next
  #exit 1

 fi


 # Another quick sanity check...see what's in the log ...
 # Add support iptables...
 if ! grep "PROTO=.*\ \<$IP:[0-9]" $LOG_FILE >/dev/null 2>&1 &&\
    ! grep "SRC=$IP DST" $LOG_FILE >/dev/null 2>&1; then

  echo No log data available. Double check that \'$IP\' is correct.
  echo
  echo -en \\n"Press any key ..."
  read
  next
  #exit 1

 fi



 # Show a little log data on screen for reference ...
 echo Summary data from $LOG_FILE for $IP:

 grep $IP $LOG_FILE |  while read line; do

   echo -en \ Origin: $IP \\t Local Port tried:\ 

  # for iptables...
  if echo $line |grep "SPT=.*DPT" >/dev/null; then
    echo $line | sed 's/^.*DPT=//' |cut -f1 -d\ 
  else
  # echo -e \ Origin: $IP \\t Local Port tried:\
    echo $line |cut -f7 -d:|cut -f1 -d' '
  fi

  done

 echo

 echo -n "Checking DNS for name of $IP ... "
 # Let's see if we can grok a hostname, and then extract a default 
 # abuse address from that.
 # If we do get a valid DNS, then we probably have a good place to send 
 # the complaint, and whois lookup is maybe not necessary. Just depends.
 # This can give a false-positive, in which case 'whois' is your friend.
 if ! which host >/dev/null 2>&1; then

  echo no can do. Bind-utils not installed.
  
 elif host $IP >/dev/null 2>&1 &&\
      host $IP | grep -i "pointer" >/dev/null; then
 
  # Just the hostname ...
  # RH7.1 (BIND 9) breaks return value on 'host'...
  if host $IP |head -n 1 |sed s/'^.*pointer '//  >/dev/null 2>&1; then
  
  
     HOST=`host $IP |head -n 1 |sed s/'^.*pointer '//`  >/dev/null 2>&1

     # more for BIND 9 host...
     HOST=`echo $HOST |sed 's/\.$//'`
    
  fi

  # See how much is tacked on to the domain name, by stripping all but '.'s.
  NUM_FIELDS=$((`echo -n $HOST | tr -d ' [a-z][A-Z][0-9]-' |wc -c`+1))

    # get a default abuse address from the domain...eg abuse@isp.com
    if echo $HOST |cut -f$(($NUM_FIELDS-1)) -d. |\
            grep "\<com\>\|\<net\>\|\<org\>" >/dev/null; then 
    
    # This one will catch names like isp.com.ar
    # This does not catch all cases, by any means.
     ABUSE=abuse\@`echo $HOST | cut -f$(($NUM_FIELDS-2)) -d.`\.`echo $HOST |\
      cut -f$(($NUM_FIELDS-1)) -d.`\.`echo $HOST |cut -f$(($NUM_FIELDS)) -d.`

    else
    # Just plain isp.com here ...

     ABUSE=abuse\@`echo $HOST | cut -f$(($NUM_FIELDS-1)) -d.`\.`echo $HOST |\
      cut -f$(($NUM_FIELDS)) -d.`

    fi   

  echo "Bingo!"

    #Special situations ...
    if [ "$ABUSE" = "abuse@aol.com" ] || \
          [ "$ABUSE" = "abuse@aol.net" ] ; then

     ABUSE="tosgeneral@aol.com"

    elif [ "$ABUSE" = "abuse@rr.com" ] ; then

     ABUSE="security@rr.com"
   
    elif [ "$ABUSE" = "abuse@dsl-verizon.net" ] ; then

     ABUSE="abuse@verizon.net"
    fi

  # Note that probably 90% of the time, this default abuse address will 
  # get the job done. The only way to make sure, is to do a 'whois' on 
  # the IP, and then ferret out a correct email address.
  echo Default abuse mail address is $ABUSE for 
  echo host: $HOST.
  echo "This is often a 'good' address for abuse."
  echo You can try this or ...

 else

  #No reverse DNS...
  echo not available.

 fi


 # whois now ?
 echo "Do a whois lookup on $IP now? (y/n/q/p/s/a/r/k/h):"

 input lookup

   ####################################################################
   # whois loop. Allow for repeated lookups... ########################
   while true; do

       case $lookup in 

        y|Y|yes|Yes)
         iswho whois.arin.net
        ;;
        
       a|A)
         iswho whois.apnic.net 
        ;;

       b\ *|b)
         browser $lookup
        ;;
       
       p|P)
         browser_help
        ;;
        
       r|R)
         iswho whois.ripe.net
        ;;

       k|K)
         iswho whois.nic.or.kr
        ;;
    
       s)
        SKIP_IT=true
        break
       ;;
       
       n|no|No|"")
        break
       ;;

       q|Q|quit|exit)
        cancel
       ;;

       h|H|help)
        help whois
       ;;

       *)
         #FIXME, this looks like it could break ...#
         # The idea here is to refine the search, presumably using 
         # NETBLK type info supplied by whois.
         #if echo $lookup | grep 'NET'; then
         # TODO @whois.ripe.net or apnic.net. HELP language.
         if ! [ "$lookup" = "" ]; then
         
          echo Use mouse to copy abuse info...'q' to quit from 'less'.
          echo
          sleep 1

             if echo $lookup | grep "whois\." >/dev/null; then

              $WHOIS $lookup 2>/dev/null | $PAGER
             
             else
             
              $WHOIS $lookup\@whois.arin.net 2>/dev/null | $PAGER

             fi

          clear

         else

          echo \"\ $lookup\ \" looks like invalid search criteria.

         fi
         
        ;;

       esac

    echo "Do a whois lookup now (y/n/q/p/a/r/k)?"
    echo "'y' to do a lookup on $IP now or"
    echo "Enter another search criteria (like NETBLK-*),"
    echo "or another database like ripe.net or apnic.net":
    echo "Type 'a' to try apnic.net (Asian) or 'r' for"
    echo "ripe.net (European), 'k' for nic.or.kr (Korean)"
    echo "with this IP."

    input lookup

   done
   ## end whois loop ################################################

 # look for 's', and then move to next IP in the list.
 skip_it

    
 #Start email addy section.
    
 OLD_ABUSE=$ABUSE

   ##################################################################
   ## start abuse address loop ######################################
   while true; do

     if ! [ "$ABUSE" = "" ]; then

      echo You can now use $ABUSE. Or another address
      echo you got from whois, or elsewhere. Press
      echo ENTER to accept $ABUSE, or input something else
      echo now. Just make sure it is a full, valid email address:

     else

      echo Enter full mailing address to send abuse complaint:

     fi

     # Now get input for the abuse addy...last chance here. 
     # Note that almost all IP block owners have an 'abuse' mailbox.
     # It is strongly suggested to try this, rather someone's name 
     # that may appear in a whois lookup.
     input lookup


     # This to over-ride the default abuse@isp.com...
     if ! [ "$lookup" = "" ]; then 

      ABUSE="$lookup"

     fi

     
     case $ABUSE in 
     
      q|Q|quit)
       cancel
      ;;

      b\ *|b)
       browser $ABUSE
       ABUSE=$OLD_ABUSE
      ;;
      
      p|P)
       browser_help
       ABUSE=$OLD_ABUSE
      ;;
       
      h|H)
       ABUSE=$OLD_ABUSE
       help abuse
       ;;
       
      s)
       SKIP_IT=true
       break
     ;;
       

      *)
      # Let's do a minimal amount of error testing ...
      if ! echo "$ABUSE" |grep "..\@.*\..." >/dev/null 2>&1 ||\
           echo $ABUSE |grep "\@\@" ; then

       echo "Apparently \" $ABUSE \" is not a properly formatted email addy!"
       echo "Let's try that again. 'q' to quit program."
       echo
       sleep 1

       ABUSE=$OLD_ABUSE

      else

       break

      fi
      ;;

    esac

   done 
   ## end address loop ##############################################

 skip_it


 # Start building mail message body here ... ########################
 clear
 echo -n Building mail message body...

 echo -e \\n"$BOILERPLATE"\\n\\n > $TMP_FILE
 > $TMP_FILE.out

 # do a little formatting and remove a bit of cruft ...
 if $K24; then
  grep $IP $LOG_FILE | sed 's/LEN.*DF//'  |sed 's/OUT.*:..//' |\
  while read line; do
 
   echo -e "$line"\\n >> $TMP_FILE.out

  done
 
 else
  grep $IP $LOG_FILE | sed s/'localhost kernel: Packet log: input '// |\
  while read line; do
 
   echo -e "$line"\\n >> $TMP_FILE.out

  done
 
 fi
  

 # Let's make sure we have something to submit ...
 # FIXME, redundant.#
 if ! [ -s $TMP_FILE.out ]; then

  echo .failed.
  echo No log data to send. Double check $IP is correct. Aborting.
  rm -rf $TMP_DIR
  next
  #exit 1

 fi

 cat $TMP_FILE.out >> $TMP_FILE

 echo -e \\n\\nThank you for your attention in this matter.\\n >> $TMP_FILE

 if [ -s "$SIG" ]; then
  
  echo "-- " >> $TMP_FILE
  cat "$SIG" >> $TMP_FILE

 fi

 echo .done.
 echo

   ##################################################################
   ## Edit loop #####################################################
   while true; do

     # We can preview and/or edit the full mail message here...
     echo "Mailing complaint to: $ABUSE."
     echo "Preview/Edit abuse mail now (y/n/q/p/b/s/h)?"
     echo "This uses 'less', type 'v' from within 'less'" 
     echo "to edit if you want. 'q' to exit from 'less'."
     echo  "Press ENTER to continue."

     input answer

     case $answer in 

      y|Y|yes|Yes|v)
       OLD_LESS=$LESS
       export LESS="$LESS    v to edit "
       $PAGER $TMP_FILE
       export LESS=$OLD_LESS
       clear
       #break
      ;;
      
      p|P)
       browser_help
      ;;

      b\ *|b)
       browser $answer
      ;;

      s)
       SKIP_IT=true
       break
      ;;
       
      h|H)
       help preview
      ;;
       
      "")
       break
      ;;

      q|Q|quit|exit)
       cancel
      ;;

     esac

   done
   ## end edit loop #################################################

 skip_it


   ##################################################################
   ## Last chance loop ##############################################
   while true; do
       
     clear

     # Last chance to cancel message ...
     echo "Send abuse complaint now to $ABUSE (y/n/q/p/b/s/h)?"

     input answer

     case $answer in 

      y|Y|yes|Yes)

       if ! $DEBUG; then
       
        # OK, message is mailed here ...
        echo -n Mailing...
        $MAILER -s "Abuse Complaint $IP"  $ABUSE < $TMP_FILE
       
        echo -n "."

       fi

          if $ME_TOO || $DEBUG; then
          
           # Second copy send to you also.
           $MAILER -s "Abuse Complaint $IP"  root@localhost  < $TMP_FILE

          fi

       echo Abuse complaint mailed to $ABUSE
       NUM_MAILS=$(($NUM_MAILS+1))

          # Log our action if we have a log file specified.
          if ! [ "$LOG_TO" = "" ] && ! $DEBUG; then

           echo -e `date '+%b %d %T'` \\t "`pad "$IP" 20`" \\t mailed to: $ABUSE \
             >> $LOG_TO

#           echo -e `date '+%b %d %T'` \\t $IP \\t mailed to: $ABUSE >> $LOG_TO
           echo And logged.

          fi
       
       sleep 1
      
       break
      ;;
      
      p|P)
       browser_help
      ;;

      b\ *|b)
       browser $answer
      ;;

      q|Q|quit)
       cancel
      ;;

      h|H)
       help last
      ;;

      e|E)
       $EDITOR $TMP_FILE
      ;;

      n|N|no|s|S)
       break
      ;;


     esac

   done
   ## end mailer loop ###############################################

 # Get the next ip, if any, and start at the top ...
 next

done
## End Main Program Loop here ##########################################
########################################################################

echo "`basename $0` is done. $NUM_MAILS complaint(s) processed."
rm -rf $TMP_DIR

#--- eof abuse.sh
