#!/bin/bash

cat <<EOTEXT1 >/dev/null
	(The above line allows me to put the documentation right in the
script... Cool, eh?)

>>>>>>>>>>>>>>>If you read nothing else, please read this<<<<<<<<<<<<<<<<

	This program offers an aid to creating firewall rules.  It offers
ABSOLUTELY NO intelligence in deciding what should be allowed or
disallowed.  It has ABSOLUTELY NO ability to understand your security
policy and implement it.  YOU are responsible for reviewing the rules and
massaging them to fit your needs.
	While the documentation in mason.txt attempts to provide some
general guidelines on how to use Mason, please remember:  the author has
no knowledge of what you want your firewall to do and has not tailored the
documentation or program to specially fit your needs.  If there is ever a
discrepancy between your needs and the program output or your needs and
the documentation, the program and/or documentation are _dead_ _wrong_. 


Copyleft:
	Mason interactively creates a Linux packet filtering firewall.
	Copyright (C) 1998, 1999 William Stearns <wstearns@pobox.com>

	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.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

	The author can also be reached at:
        William Stearns
email:  wstearns@pobox.com				(preferred)
web:    http://www.pobox.com/~wstearns
snail:  544 Winchester Place
        Colchester VT, 05446, USA


	This code is entirely owned by William Stearns
(wstearns@pobox.com) and has no relation to any employer or employer
sponsored project.  

------------------------------ Mason ------------------------------
	The Mason script interactively builds a (fire)wall on a Linux
machine. For more details about how this is done, please see mason.txt,
which gives background, theory of operation, a quick start, and additional
documentation on firewalls and firewall gotchas. 
	mason.txt and related documentation should have been installed to
/usr/doc/mason-{version}/ .  If they are missing or you would like to make
sure you have the latest version, please go to
http://www.pobox.com/~wstearns/mason/ . 
	All configuration of this program is done in the /etc/masonrc
file.  This script should probably not be directly edited.

- Bill Stearns

The EOTEXT line is the end of the text and the start of the code. 
EOTEXT1



	MASONDIR=${MASONDIR:-"/var/lib/mason/"}
	MASONCONF=${MASONCONF:-"/etc/masonrc"}
	MASONLIB=${MASONLIB:-"/var/lib/mason/masonlib"}
	if [ -f $MASONLIB ]; then
		. $MASONLIB
	else
		echo Missing $MASONLIB library file.  Please get a complete copy of Mason from >/dev/stderr
		echo http://www.pobox.com/~wstearns/mason/ .  Exiting. >/dev/stderr
		exit
	fi

#-------------------------------------------------------------------------
# Start setting up.
#-------------------------------------------------------------------------

if [ -w /etc/services ]; then
	if [ `cat /etc/services | grep '22/tcp' | wc -l` -eq 0 ]; then
		echo -e "ssh\t22/tcp\t\t# Secure shell (added by Mason)" >>/etc/services
	fi
	if [ `cat /etc/services | grep '111/udp' | wc -l` -eq 0 ]; then
		echo -e "sunrpc\t111/udp\tportmapper\t# RPC 4.0 portmapper udp (added by Mason)" >>/etc/services
	fi
	if [ `cat /etc/services | grep '111/tcp' | wc -l` -eq 0 ]; then
		echo -e "sunrpc\t111/tcp\tportmapper\t# RPC 4.0 portmapper tcp (added by Mason)" >>/etc/services
	fi
	if [ `cat /etc/services | grep '635/tcp' | wc -l` -eq 0 ]; then
		echo -e "mount\t635/tcp\t\t# NFS Mount Service (added by Mason)" >>/etc/services
	fi
	if [ `cat /etc/services | grep '635/udp' | wc -l` -eq 0 ]; then
		echo -e "mount\t635/udp\t\t# NFS Mount Service (added by Mason)" >>/etc/services
	fi
	if [ `cat /etc/services | grep '2049/tcp' | wc -l` -eq 0 ]; then
		echo -e "nfs\t2049/tcp\t\t# NFS File Service (added by Mason)" >>/etc/services
	fi
	if [ `cat /etc/services | grep '2049/udp' | wc -l` -eq 0 ]; then
		echo -e "nfs\t2049/udp\t\t# NFS File Service (added by Mason)" >>/etc/services
	fi
else
	echo /etc/services is not writable by this user.  Please make sure >/dev/stderr
	echo the following ports are defined in /etc/services: >/dev/stderr
	echo -e "ssh\t22/tcp\t\t# Secure shell" >/dev/stderr
	echo -e "sunrpc\t111/udp\tportmapper\t# RPC 4.0 portmapper udp" >/dev/stderr
	echo -e "sunrpc\t111/tcp\tportmapper\t# RPC 4.0 portmapper tcp" >/dev/stderr
	echo -e "mount\t635/tcp\t\t# NFS Mount Service" >/dev/stderr
	echo -e "mount\t635/udp\t\t# NFS Mount Service" >/dev/stderr
	echo -e "nfs\t2049/tcp\t\t# NFS File Service" >/dev/stderr
	echo -e "nfs\t2049/udp\t\t# NFS File Service" >/dev/stderr
	echo >/dev/stderr
fi

LOGCHAINSEXIST="yes"
ALLCHAINS="`/sbin/ipchains -L -n | grep '^Chain ' | awk '{print $2}'`"

if [ "$DOCOMMAND" = "ipchains" ]; then
	if [ -n "$NOLOGSUFFIX" ]; then
		for ONECHAIN in $ALLCHAINS ; do
			case $ONECHAIN in
			*${NOLOGSUFFIX})	:								;;
			*)	# For each chain (except for the nolog chains themselves) check that a corresponding nolog chain exists.
				#Do not use -n.
				if ! /sbin/ipchains -L ${ONECHAIN}${NOLOGSUFFIX} >/dev/null 2>/dev/null ; then  #If nolog chain does not exist
					LOGCHAINSEXIST="no"
					echo The $ONECHAIN chain exists without a corresponding ${ONECHAIN}${NOLOGSUFFIX} >/dev/stderr
					echo chain.  For the moment, the "nolog" feature will revert to sticking the rules >/dev/stderr
					echo at the top of the original chain. >/dev/stderr
				fi												;;
			esac
		done
		if [ "$LOGCHAINSEXIST" = "no" ]; then $NOLOGSUFFIX = "" ; fi
	fi
fi


LAST1="" ; LAST2="" ; LAST3="" ; LAST4="" ; LAST5="" ; CURRENT=""
EXITMASON=${EXITMASON:-"NO"}

trap sigexitscript SIGHUP
trap loadconf SIGUSR1


#---------- Start of Main code ----------
echo "---- Mason firewall builder for Linux                         ----" >/dev/stderr
echo "---- see http://www.pobox.com/~wstearns/mason/ for more info. ----" >/dev/stderr
echo "---- William Stearns <wstearns@pobox.com>                     ----" >/dev/stderr 
loadconf
SIGGED="NO"

#Hmmm... I _hate_ overwriting /etc/passwd...
if [ -L $NAMECACHE ]; then
	rm -f $NAMECACHE
fi

#Create the name cache file if it doesn't exist
if [ ! -e $NAMECACHE ]; then
	touch $NAMECACHE
	#This is a security-related program.  I don't want to let people know who we're even talking to.
	chmod og-rwx $NAMECACHE
fi

#FIXME - get the commented 0/0 up at the top.
for ONEIF in $DYNIF ; do
	cat <<EOTEXT
#export ${ONEIF}ADDR="0/0"		#Use this version if you want to match any IP address.
export ${ONEIF}ADDR="\`ifconfig $ONEIF | grep 'inet addr' | awk '{print \$2}' | sed -e 's/.*://'\`/32"
EOTEXT
	eval ${ONEIF}ADDR=`ifconfig $ONEIF | grep 'inet addr' | awk '{print $2}' | sed -e 's/.*://'`
done


#Get the first log entry
unset ACK COMMENT DEST DESTHOST DESTIP DESTPORT DIR DIRLETTER \
DOACK ECHOACK IF ISLOGLINE \
J1 J2 J3 J4 J5 J6 J7 J8 J9 J10 J11 J12 J13 J14 J15 J16 J17 J18 J19 \
                  O7 O8 O9 O10 O11 O12 O13 \
                  A7 A8 A9 A10 A11 A12 A13 \
LINEHASDYNAMIC PROTO SRC SRCHOST SRCIP SRCPORT TAIL
#unset DFFLAG FFLAG FOFLAG IFLAG LFLAG MESSPOL SFLAG TFLAG			#These fields are not used at this time.

read J1 J2 J3 J4 J5 J6 J7 J8 J9 J10 J11 J12 J13 J14 J15 J16 J17 J18 J19

while [ "$SIGGED" = "YES" ]; do
	SIGGED="NO"
	read J1 J2 J3 J4 J5 J6 J7 J8 J9 J10 J11 J12 J13 J14 J15 J16 J17 J18 J19
done

while [ ! "$EXITMASON" = "YES" ] && [ -n "$J1" ]; do
#Only do the work if the line is a firewalling log entry.
	if [ "$J6 $J7" = "Packet log:" ]; then		#Load variables from ipchains log entry
		case $J8 in
		output)		DIR='output ' ;	DIRLETTER='O'				;;
		input)		DIR='input  ' ;	DIRLETTER='I'				;;
		forward)	DIR='forward' ;	DIRLETTER='F'				;;
		*)	echo Unknown direction X${J8}X >/dev/stderr			;;
		esac
		#MESSPOL="$J9"		#Unused.
		IF="$J10"
		case "$J11" in
		"PROTO=0")		PROTO="ip"								;;
		"PROTO=1")		PROTO="icmp"							;;
		"PROTO=2")		PROTO="igmp"							;;
		"PROTO=3")		PROTO="ggp"								;;
		"PROTO=6")		PROTO="tcp"								;;
		"PROTO=12")		PROTO="pup"								;;
		"PROTO=17")		PROTO="udp"								;;
		"PROTO=22")		PROTO="idp"								;;
		"PROTO=255")	PROTO="raw"								;;
		*)		echo Unknown protocol X${J11}X >/dev/stderr		;;
		esac
		SRC="$J12" ; DEST="$J13"
		SRCPORT=${SRC##*:}
		DESTPORT=${DEST##*:}
		#LFLAG="$J14" ; SFLAG="$J15" ; IFLAG="$J16" ; FFLAG="$J17" ; TFLAG="$J18"		#Unused
		ISLOGLINE="YES"
	elif [ "$J5 $J6" = "kernel: IP" ] && [ "`echo $J7 | cut -b 1-3`" = "fw-" ]; then	#Load variables from ipfwadm log entry
		case $J7 in
		fw-out)	DIR='output ' ;	DIRLETTER='O'					;;
		fw-in)	DIR='input  ' ;	DIRLETTER='I'					;;
		fw-fwd)	DIR='forward' ;	DIRLETTER='F'					;;
		*)	echo Unknown direction X${J7}X >/dev/stderr			;;
		esac
		IF="$J9"
		PROTO=`echo $J10 | tr A-Z a-z`
		SRC="$J11" ; DEST="$J12"
		#MESSPOL="$J8" ; LFLAG="$J13" ; SFLAG="$J14" ; IFLAG="$J15" ; FOFLAG="$J16" ; TFLAG="$J17" ; DFFLAG="$J18"		#Unused
#Break up ipfwadmin's habit of gluing the icmp port onto the protocol.
		if [ "${PROTO%%/*}" = "icmp" ]; then
			SRCPORT=${PROTO##*/}
			PROTO="icmp"
			DESTPORT=""
			if [ "$DEBUG" = "YES" ]; then echo proto= $PROTO srcport= $SRCPORT destport= $DESTPORT >/dev/stderr ; fi
		else
			SRCPORT=${SRC##*:}
			DESTPORT=${DEST##*:}
		fi
		ISLOGLINE="YES"
	fi

	if [ "$ISLOGLINE" = "YES" ]; then
		SRCIP=${SRC%%:*}
		DESTIP=${DEST%%:*}
		ACK="  "

		if [ ${#IF} -lt 5 ]; then
			IF=`echo "$IF     " | cut -b 1-4`
		fi

		SRCHOST=`generalizeip ${SRCIP}`
		for ONESPARSE in $SSP ; do
			if [ "${SRCPORT}/$PROTO" = "$ONESPARSE" ]; then		SRCHOST="`nameof ${SRCIP}`/32" ; fi
		done
		unset ONESPARSE
		for ONESPARSE in $SCP ; do
			if [ "${DESTPORT}/$PROTO" = "$ONESPARSE" ]; then	SRCHOST="`nameof ${SRCIP}`/32" ; fi
		done
		unset ONESPARSE

		DESTHOST=`generalizeip ${DESTIP}`
		for ONESPARSE in $SSP ; do
			if [ "${DESTPORT}/$PROTO" = "$ONESPARSE" ]; then	DESTHOST="`nameof ${DESTIP}`/32" ; fi
		done
		unset ONESPARSE
		for ONESPARSE in $SCP ; do
			if [ "${SRCPORT}/$PROTO" = "$ONESPARSE" ]; then		DESTHOST="`nameof ${DESTIP}`/32" ; fi
		done
		unset ONESPARSE

		COMMENT2="" ;	COMMENT="#"
		#Clean up protocol type and number fields, visualize source and dest port fields, set ack flag.
		#If port not in /etc/services and >=1024, generalize to "high port"

		if [ "$PROTO" != "icmp" ]; then
			serverportrange $SRCPORT $PROTO
			SRCSERVICE="$READABLEPORT"
			SRCCOMMENT="$PARTIALCOMMENT"

			serverportrange $DESTPORT $PROTO
			DESTSERVICE="$READABLEPORT"
			DESTCOMMENT="$PARTIALCOMMENT"

			if [ -n "$SRCSERVICE" ] && [ "$PROTO" = "tcp" ]; then
				#The ack flag should be set if port=tcp and source port is a server service.
				if [ "${SRCPORT}/$PROTO" != "20/tcp" ]; then ACK="-k" ; fi
			fi
			if [ -n "$SRCSERVICE" ] && [ -n "$DESTSERVICE" ]; then	# Both source and destination ports are servers.  Rare, but possible.
				SRCPORT=$SRCSERVICE
				DESTPORT=$DESTSERVICE
				ACK="  "				#In this case, we can't tell in which direction the connection was made - no ack flag.
			elif [ -n "$SRCSERVICE" ]; then								# Source port is a server port.
				DESTPORT=`clientportrange $DESTPORT $SRCPORT ${PROTO}`
				SRCPORT=$SRCSERVICE
			elif [ -n "$DESTSERVICE" ]; then							# Dest port is a server port.
				SRCPORT=`clientportrange $SRCPORT $DESTPORT ${PROTO}`
				DESTPORT=$DESTSERVICE
			else														# Neither source nor dest is a server port.
				COMMENT2="## S=`nameof ${SRCIP}`:${SRCPORT} D=`nameof ${DESTIP}`:${DESTPORT}"
				ORIGSRCPORT=$SRCPORT
				SRCPORT=`clientportrange $SRCPORT $DESTPORT ${PROTO}`
				DESTPORT=`clientportrange $DESTPORT $ORIGSRCPORT ${PROTO}`
				unset ORIGSRCPORT

				#If we have a high port to high port connection (darn ftp), do _not_ generalize to anywhere
				if [ "$SRCPORT" = "1024:65535" ] && [ "$DESTPORT" = "1024:65535" ]; then
					if [ "$SRCHOST" = "0/0" ]; then		SRCHOST="${SRCIP}/32" ;		fi
					if [ "$DESTHOST" = "0/0" ]; then	DESTHOST="${DESTIP}/32" ;	fi
				fi
			fi
			if [ -n "$SRCCOMMENT" ]; then
				COMMENT="$COMMENT $SRCCOMMENT"
			fi
			if [ -n "$DESTCOMMENT" ]; then
				if [ "$SRCCOMMENT" != "$DESTCOMMENT" ]; then COMMENT="$COMMENT $DESTCOMMENT" ; fi
			fi
			COMMENT="$COMMENT (${DIRLETTER})"
		else
			#Handle ICMP comments
#FIXME - handle subcode (in comment2) if dest != 0
			case $SRCPORT in
			0)		COMMENT="# Echo reply/icmp (${DIRLETTER})"			;;
			3)		COMMENT="# Dest Unreach/icmp (${DIRLETTER})"		;;
			4)		COMMENT="# Source Quench/icmp (${DIRLETTER})"		;;
			5)		COMMENT="# Redirect/icmp (${DIRLETTER})"			;;
			8)		COMMENT="# Echo req/icmp (${DIRLETTER})"			;;
			11)		COMMENT="# Time exceeded/icmp (${DIRLETTER})"		;;
			12)		COMMENT="# Parameter prob/icmp (${DIRLETTER})"		;;
			13)		COMMENT="# Timestamp req/icmp (${DIRLETTER})"		;;
			14)		COMMENT="# Timestamp reply/icmp (${DIRLETTER})"		;;
			15)		COMMENT="# Info req/icmp (${DIRLETTER})"			;;
			16)		COMMENT="# Info reply/icmp (${DIRLETTER})"			;;
			17)		COMMENT="# Addr Mask req/icmp (${DIRLETTER})"		;;
			18)		COMMENT="# Addr Mask reply/icmp (${DIRLETTER})"		;;
#FIXME - include source and dest IPs for the following?
			*)		COMMENT="# unknown-${SRCPORT}/icmp (${DIRLETTER})"	;;
			esac
		fi
		#if [ "$LINEHASDYNAMIC" = "YES" ]; then COMMENT="$COMMENT DynamicIP" ; fi
		#LINEHASDYNAMIC is not exported because generalizeip is a function.  Not used.

		if [ "$DEBUG" = "YES" ]; then
			echo J1=${J1}, J2=${J2}, J3=${J3}, J4=${J4} >/dev/stderr
			echo J5=${J5}, J6=${J6}, J7=${J7}, J8=${J8}, >/dev/stderr 
			echo J9=${J9}, J10=${J10}, J11=${J11}, J12=${J12}, >/dev/stderr
			echo J13=${J13}, J14=${J14}, J15=${J15}, J16=${J16}, >/dev/stderr
			echo J17=${J17}, J18=${J18}, J19=${J19}, >/dev/stderr
			echo DIR=${DIR}, DIRLETTER=${DIRLETTER} >/dev/stderr
			echo MESSPOL=${MESSPOL}, IF=${IF}, PROTO=${PROTO} >/dev/stderr
			echo SRC=${SRC}, DEST=${DEST}, LFLAG=${LFLAG} >/dev/stderr
			echo SFLAG=${SFLAG}, IFLAG=${IFLAG}, FOFLAG=${FOFLAG}, FFLAG=${FFLAG} >/dev/stderr
			echo TFLAG=${TFLAG}, DFFLAG=${DFFLAG}, TAIL=${TAIL} >/dev/stderr
			echo Unused: DFFLAG, FFLAG, FOFLAG, IFLAG, LFLAG, MESSPOL, SFLAG, TFLAG >/dev/stderr
		fi


#Actually create and implement the firewall command to display.  Pad so rules line up.
		case $PROTO in
		ip|IP)												PROTO="$PROTO  "	;;
		tcp|TCP|udp|UDP|ggp|GGP|pup|PUP|idp|IDP|raw|RAW)	PROTO="$PROTO "		;;
		esac
		if [ "$ECHOCOMMAND" = "ipchains" ]; then
			if [ "$ACK" = "  " ]; then ECHOACK="    " ;  else ECHOACK="! -y" ; fi
			CURRENT="/sbin/ipchains -A $DIR -i $IF -p $PROTO $ECHOACK -s $SRCHOST $SRCPORT -d $DESTHOST $DESTPORT -j $UCPOLICY"
		elif [ "$ECHOCOMMAND" = "ipfwadm" ]; then
			CURRENT="/sbin/ipfwadm -a $LCPOLICY -W $IF -${DIRLETTER} -P $PROTO $ACK -S $SRCHOST $SRCPORT -D $DESTHOST $DESTPORT"
		fi # No need to handle ECHOCOMMAND=none :-)
		if [ `echo -n "$CURRENT" | wc -c` -lt 115 ]; then	#We cannot use ${#CURRENT} because it counts multiple spaces as one.
			CURRENT=`echo "$CURRENT                                                   " | cut -b 1-120`	#orig 110 chopped lines, 111 did not pad enough
		fi
		CURRENT="$CURRENT $COMMENT"

		if [ "$DEBUG" = "YES" ]; then echo current= "$CURRENT" >/dev/stderr ; fi

#Don't do anything if this is the same as one of the last 5 rules.  This 
#reduces the occurence of repeated rules showing up.
		case $CURRENT in
		$LAST1|$LAST2|$LAST3|$LAST4|$LAST5)
			if [ "$HEARTBEAT" = "YES" ]; then echo -n "-" >/dev/stderr ; NEEDLF="YES" ; fi
																;;
		*)
			if [ "$NEEDLF" = "YES" ]; then echo >/dev/stderr ; NEEDLF="NO" ; fi
			if [ "$DOBEEP" = "YES" ]; then echo -n -e "\a" >/dev/stderr ; fi
			case $ECHOCOMMAND in
			ipchains|ipfwadm)	echo "$CURRENT $COMMENT2"		;;
			esac

#Put the dynamic IP addresses in the current environment.
			for ONEIF in $DYNIF ; do
				eval ${ONEIF}ADDR=$(eval echo \${$(eval echo ${ONEIF}ADDR)})	#No, really.  That's the IP address.
			done

#Put a real rule in the rule chain so that we don't log it again.  We need to use eval since ${xxxHOST} may be a $DYNIP 
#and may need to be evaluated to its real value.
			if [ "$DOCOMMAND" = "ipfwadm" ]; then 
				eval "/sbin/ipfwadm -i $LCPOLICY -W $IF -${DIRLETTER} -P $PROTO $ACK -S $SRCHOST $SRCPORT -D $DESTHOST $DESTPORT"
			elif [ "$DOCOMMAND" = "ipchains" ]; then
				if [ "$ACK" = "  " ]; then DOACK="    " ; else DOACK="! -y" ; fi
				case $DIRLETTER in
				I)		DIR="input${NOLOGSUFFIX}"				;;
				O)		DIR="output${NOLOGSUFFIX}"				;;
				F)		DIR="forward${NOLOGSUFFIX}"				;;
				esac
				#echo X${DIR}X >/dev/stderr
				eval "/sbin/ipchains -I $DIR 1 -i $IF -p $PROTO $DOACK -s $SRCHOST $SRCPORT -d $DESTHOST $DESTPORT -j $UCPOLICY"
			fi # no need to handle DOCOMMAND=none :-)
			LAST5=$LAST4
			LAST4=$LAST3
			LAST3=$LAST2
			LAST2=$LAST1
			LAST1=$CURRENT										;;
		esac

#Debug
		if [ "$DEBUG" = "YES" ]; then 
			echo src= $SRCIP $SRCPORT dest= $DESTIP $DESTPORT >/dev/stderr
			echo if= $IF proto= $PROTO >/dev/stderr
			echo >/dev/stderr
		fi #if debugging
	fi #if ISLOGLINE

#Get the next log entry and start over.
	unset ACK COMMENT DEST DESTHOST DESTIP DESTPORT DIR DOACK ECHOACK IF ISLOGLINE \
	LINEHASDYNAMIC PROTO SRC SRCHOST SRCIP SRCPORT TAIL
	#unset DFFLAG FFLAG FOFLAG IFLAG LFLAG MESSPOL SFLAG TFLAG		#These are unused.
	A7=$O7 ; A8=$O8 ; A9=$O9 ; A10=$O10 ; A11=$O11 ; A12=$O12 ; A13=$O13
	O7=$J7 ; O8=$J8 ; O9=$J9 ; O10=$J10 ; O11=$J11 ; O12=$J12 ; O13=$J13
	read J1 J2 J3 J4 J5 J6 J7 J8 J9 J10 J11 J12 J13 J14 J15 J16 J17 J18 J19
#Keep reading until a line with different firewall values is found.
	while { [ "$O7"  = "$J7"  ] && [ "$O8"  = "$J8"  ] && [ "$O9"  = "$J9"  ] && [ "$O10" = "$J10" ] && \
	        [ "$O11" = "$J11" ] && [ "$O12" = "$J12" ] && [ "$O13" = "$J13" ] ; } ||
		  { [ "$A7"  = "$J7"  ] && [ "$A8"  = "$J8"  ] && [ "$A9"  = "$J9"  ] && [ "$A10" = "$J10" ] && \
	        [ "$A11" = "$J11" ] && [ "$A12" = "$J12" ] && [ "$A13" = "$J13" ] ; } ||
		  { [ "$SIGGED" = "YES" ] ; } ; do 
		if [ "$SIGGED" = "YES" ]; then
			SIGGED="NO"
		else
			if [ "$HEARTBEAT" = "YES" ]; then echo -n "." >/dev/stderr ; NEEDLF="YES" ; fi
			A7=$O7 ; A8=$O8 ; A9=$O9 ; A10=$O10 ; A11=$O11 ; A12=$O12 ; A13=$O13
			O7=$J7 ; O8=$J8 ; O9=$J9 ; O10=$J10 ; O11=$J11 ; O12=$J12 ; O13=$J13
		fi
		read J1 J2 J3 J4 J5 J6 J7 J8 J9 J10 J11 J12 J13 J14 J15 J16 J17 J18 J19
	done
done

if [ "$NEEDLF" = "YES" ]; then echo >/dev/stderr ; NEEDLF="NO" ; fi
if [ "$EXITMASON" = "YES" ]; then
	echo Mason is exiting because of a SIGHUP or EXITMASON=YES. >/dev/stderr
else
	echo Mason is exiting because of an end of input data. >/dev/stderr
fi


	#unset J1 J2 J3 J4 J5 J6 J7 J8 J9 J10 J11 J12 J13 J14 J15 J16 J17 J18 J19 \
#	                  O7 O8 O9 O10 O11 O12 O13 \
#	                  A7 A8 A9 A10 A11 A12 A13 \
