#!/bin/sh

DWALL=/etc/dwall-alt
EXP=/etc/dwall-alt/expert

. /usr/share/alterator/build/backend3.sh
list_targets () 
{
	 echo "(\"\" label \"\")
                        (\"ACCEPT\" label \"ACCEPT\")
                        (\"DROP\" label \"DROP\")
                        (\"QUEUE\" label \"QUEUE\")
                        (\"RETURN\" label \"RETURN\")
                        (\"LOG\" label \"LOG\")
                        (\"MARK\" label \"MARK\")
                        (\"REJECT\" label \"REJECT\")
                        (\"TOS\" label \"TOS\")
                        (\"MIRROR\" label \"MIRROR\")
                        (\"SNAT\" label \"SNAT\")
                        (\"DNAT\" label \"DNAT\")
                        (\"MASQUERADE\" label \"MASQUERADE\")
                        (\"REDIRECT\" label \"REDIRECT\")
                        (\"TTL\" label \"TTL\")"
			
                        chains=`find $EXP/v1/ -maxdepth 2 -type d`
			chains_targets=""
			for i in $chains 
			do 
			 echo "(\"${i##*/}\" label \"${i##*/}\")"
			done
			
}

list_mask()
{
    echo '('
    for i in `seq 32 -1 0`; do 
        printf '("%s" label "/%s (%s)")' "$i" "$i" "$(maskname "$i")"
    done
    echo ')'
}

begin_list()
{
     echo -n "("
}

end_list()
{
     echo ")"
}
emit_rule() {
	# having in_* params do generate a rule from
	str="-A $rule"
	if [ "$in_protocol" != "" ] ;
	then
		if [ "${in_inv_protocol}" == "#t"  ];
		then
			str=$str" ! "
		fi
		str=$str" -p $in_protocol "
	fi
	if [ "$in_source" != "" ]
	then
		if [ "${in_inv_source}" == "#t" ];
	       then
			str=$str" -s ! $in_source/$in_source_mask"
	       else	
	    	        str=$str" -s $in_source/$in_source_mask";
	       fi
	fi
	if [ "$in_destination" != "" ]
	then
	       if [ "${in_inv_destination}" == "#t" ];
	       then
			str=$str" -d ! $in_destination/$in_destination_mask "
	       else
	    		str=$str" -d $in_destination/$in_destination_mask";
	       fi	
	fi
	if [ "${in_in_interface}" != "None" ]
	then
	       if [ "${in_inv_in_interface}" == "#t" ];
	       then
			str=$str" -i ! ${in_in_interface} "
	       else
	                str=$str" -i ${in_in_interface}";
	       fi	
	fi
	if [ "${in_out_interface}" != "None" ]
	then
	       if [ "${in_inv_out_interface}" == "#t" ];
	       then
			str=$str" -o ! ${in_out_interface} "
	       else
	         str=$str" -o ${in_out_interface}";
	       fi 
	fi
	if [ "${in_fragment}" == "#t" ]
	then
	       if [ "${in_inv_fragment}" == "#t" ];
	       then
			str=$str" ! -f"
	       else
	         str=$str" -f";
	       fi	 
		 
	fi
	if [ "${in_source_port_start}"  != "" ] ;
	  then
	  if [ "${in_source_port_end}" == "" ] ;
	   then
	   in_source_port_end=${in_source_port_start}
	   fi
	  if [ "${in_inv_source_port}" == "#t" ] ;
	  then
	     str=$str" --sport ! ${in_source_port_start}:${in_source_port_end}"
	  else
	     str=$str" --sport  ${in_source_port_start}:${in_source_port_end}"
	  fi
	fi 
	  
	if [ "${in_destination_port_start}"  != "" ] ;
	  then
	  if [ "${in_destination_port_end}" == "" ] ;
	   then
	   in_destination_port_end=${in_destination_port_start}
	   fi
	  if [ "${in_inv_destination_port}" == "#t" ] ;
	  then
	     str=$str" --dport ! ${in_destination_port_start}:${in_destination_port_end}"
	  else
	     str=$str" --dport  ${in_destination_port_start}:${in_destination_port_end}"
	  fi
	fi
	mask_str=""
	comp_str=""
	mflags=0
	cflags=0
	if [ "${in_tcp_flags_mask_syn}" == "#t" ] ;
	then
	  mask_str=$mask_str"SYN "
	  mflags=1
	fi
	if [ "${in_tcp_flags_comp_syn}" == "#t" ] ;
	then
	  cflags=1
	  comp_str=$comp_str"SYN "
	fi
	if [ "${in_tcp_flags_mask_ack}" == "#t" ] ;
	then
	  mask_str=$mask_str"ACK "
	  mflags=1
	fi
	if [ "${in_tcp_flags_comp_ack}" == "#t" ] ;
	then
	  cflags=1
	  comp_str=$comp_str"ACK "
	fi
	if [ "${in_tcp_flags_mask_psh}" == "#t" ] ;
	then
	  mask_str=$mask_str"PSH "
	  mflags=1
	fi
	if [ "${in_tcp_flags_comp_psh}" == "#t" ] ;
	then
	  cflags=1
	  comp_str=$comp_str"PSH "
	fi
	if [ "${in_tcp_flags_mask_URG}" == "#t" ] ;
	then
	  mask_str=$mask_str"URG "
	  mflags=1
	fi
	if [ "${in_tcp_flags_comp_urg}" == "#t" ] ;
	then
	  cflags=1
	  comp_str=$comp_str"URG "
	fi
	if [ "${in_tcp_flags_mask_fin}" == "#t" ] ;
	then
	  mask_str=$mask_str"FIN "
	  mflags=1
	fi
	if [ "${in_tcp_flags_comp_fin}" == "#t" ] ;
	then
	  cflags=1
	  comp_str=$comp_str"FIN "
	fi
	if [ "${in_tcp_flags_mask_rst}" == "#t" ] ;
	then
	  mask_str=$mask_str"RST "
	  mflags=1
	fi
	if [ "${in_tcp_flags_comp_rst}" == "#t" ] ;
	then
	  cflags=1
	  comp_str=$comp_str"RST "
	fi	
	let flags=$mflags'||'$cflags
	if [ $flags == 1 ] ;
	 then
	    str=$str" --tcp-flags "
	    if [ "${in_inv_tcp_flags}" == "#t" ] ;
	    then
	      str=$str" ! "
	    fi
	    if [ $mflags == 1 ] ;
	    then
	      for i in $mask_str
	      do
	       str=$str"$i,"
	      done
	      str=${str%,}" "
	    fi
	    if [ $cflags == 1 ] ;
	    then
	      for i in $comp_str
	      do
	       str=$str"$i,"
	      done
	      str=${str%,}" "
	    fi
	 fi
	 if [ "${in_tcp_option}" != "" ] ;
	  then
	    str=$str" --tcp-option "
	    if [ "${in_inv_tcp_option}" == "#t" ] ;
	    then
	      str=$str" ! "
	    fi 
	    str=$str" ${in_tcp_option}"
	  fi
	 if [ "${in_icmp_type}" != "" ] ;
	 then
	    str=$str" --icmp-type "
	    if [ "${in_inv_icmp_type}" == "#t" ];
	    then
	      str=$str" ! ${in_icmp_type}"
            else
	      str=$str" ${in_icmp_type}"
	    fi
	 fi
	 state=""
	 if [ "${in_state_new}" == "#t" ];
	 then
	   state=$state"NEW "
	 fi  
	 if [ "${in_state_invalid}" == "#t" ] ;
	 then
	   state=$state"INVALID "
	 fi
	 if [ "${in_state_established}" == "#t" ];
	 then 
	   state=$state"ESTABLISHED "
	 fi
	
	 if [ "${in_state_related}"  == "#t" ];
	 then
	   state=$state"RELATED "
	 fi
	 if [ "$state" != "" ] ;
	 then
	  str=$str" -m state --state "
	  echo "State: $state" >&2
	  for i in $state
	  do
	    str=$str"$i,"
	  done
	  str=${str%,}" "
	 fi
	 if [ "$in_jump" != "" ] ;
	  then
	    str=$str" -j $in_jump"
	  fi
	 if [ "${in_log_level}" != "" ] ;
	 then
	    str=$str" --log-level ${in_log_level}"
	 fi
	 if [ "${in_log_prefix}" != "" ];
	 then
	    str=$str" --log-prefix ${in_log_prefix}"
	 fi 
         if [ "${in_log_tcp_sequence}" == "#t" ] ;
	 then
	    str=$str" --log-tcp-sequence"
	 fi
         if [ "${in_log_tcp_options}" == "#t" ] ;
	 then
	    str=$str" --log-tcp-options"
	 fi
	 if [ "${in_log_ip_options}" == "#t" ] ;
	 then
	    str=$str" --log-ip-options"
	 fi
         if [ "${in_set_mark}" != "" ];
	 then
	    str=$str" --set-mark ${in_set_mark}"
	 fi		  
	 if [ "${in_reject_with}" != "" ] ;
	 then
	    str=$str" --reject-with ${in_reject_with}"
	 fi
	 if [ "${in_set_tos}" != "" ];
	 then
	    str=$str" --set-tos ${in_set_tos}"
	 fi
	 if [ "${in_to_source_start}" != "" ] ;
	 then
	   str=$str" --to-source ${in_to_source_start}"
	   if [  "${in_to_source_end}" != "" ] ;
	   then
	     str=$str"-${in_to_source_end}"
	   fi
	   if [ "${in_to_source_port_start}" != "" ];
	   then
	      str=$str"${in_to_source_port_start}:${in_to_source_port_end}"
	   fi
	 fi
	 if [ "${in_to_destination_start}" != "" ] ;
	 then
	   str=$str" --to-destination ${in_to_destination_start}"
	   if [ "${in_to_destination_end}" != "" ] ;
	   then
	     str=$str"-${in_to_destination_end}"
	   fi
	   if [ "${in_to_destination_port_start}" != "" ];
	   then
	      str=$str"${in_to_destination_port_start}:${in_to_destination_port_end}"
	   fi
	 fi
	 if [ "${in_to_ports_start}" != "" ];
	 then
            str="$str --to-ports ${in_to_ports_start}"
	    if ["${in_to_ports_end}" != "" ];
	    then
	      str="$str:${in_to_ports_end}"
	    fi	   
	 fi
	 if [ "${in_ttl_set}" != "" ];
	 then
	   str="$str --ttl-set ${in_ttl_set}"
	 fi
	 if [ "${in_ttl_inc}" != "" ];
	 then
	   str="$str --ttl-inc ${in_ttl_inc}"
	 fi
	 if [ "${in_ttl_dec}" != "" ];
	 then
	   str="$str --ttl-dec ${in_ttl_dec}"
	 fi
	  
	

     echo  "$str"
}
emit_option() 
{
 echo "  $1 $2 $3 $4 $5 $6" >&2
 
 invoption=$1
 
 invparam=$2
 option=$3
 colval=$4
 val1=$5
 val2=$6
 val3=$7
        case "$3" in 
            "-j")
	       echo "jump \"$val1\" "
	       ;;
	    "-s")
	    
	      if [ "$invparam" == "1" ] ;
	       then
		       echo "inv_source #t ";
	       fi 
	      echo "source \"${val1%/*}\" source_mask \"${val1#*/}\" "
	      ;;
	    "-d")
	    
	      if [ "$invparam" == "1" ] ;
	       then
		       echo "inv_destination #t ";
	       fi 
	      echo "destination \"${val1%/*}\" destination_mask \"${val1#*/}\" "
	      ;;
	    "-p")
	       if [ "$invparam" == "1" ] ;
	       then
		       echo "inv_protocol #t ";
	       fi
	       echo "protocol \"$val1\" "
           ;;
	   
	    "--dport") 
	       if [ "$invparam" == "1" ] ;
	       then
		       echo "inv_destination_port #t ";
	       fi
	       if [ "$val1" != "`echo $val1 | tr -d \:`" ] ;
	         then
		 first_one=${val1%%:*}
		 second_one=${val1##*:}
		 echo "destination_port_start \"$first_one\" destination_port_end \"$second_one\""
		 
	         else
		 echo "destination_port_start \"$val1\" destination_port_end \"$val1\""		 
	       fi
	       ;;
	    "--sport") 
	       if [ "$invparam" == "1" ] ;
	       then
		       echo "inv_source_port #t ";
	       fi
	       if [ "$val1" != "`echo $val1 | tr -d \:`" ] ;
	         then
		 first_one=${val1%%:*}
		 second_one=${val1##*:}
		 echo "source_port_start \"$first_one\" source_port_end \"$second_one\""
		 
	         else
		 echo "source_port_start \"$val1\" source_port_end \"$val1\""		 
	       fi
	       ;;
	       "--tcp-option")
        	if [ "$invparam" == "1" ] ;
		then
			echo "inv_tcp_option #t ";
		fi
		   echo "tcp_option \"$val1\" "
		   
	       
	       ;;
	       "--icmp-type")
	        if [ "$invparam" == "1" ] ;
		then
		       echo "inv_icmp_type #t ";
	        fi
		echo "icmp_type \"$val1\" "
		      
	       ;;
        	"-i")
		if [ "$invparam" == "1" ] ;
		then
			echo "inv_in_interface #t ";
		fi
		   echo "in_interface \"$val1\" "
	       ;;
		"-o")
		if [ "$invparam" == "1" ] ;
		then
			echo "inv_out_interface #t ";
		fi
		   echo "out_interface \"$val1\" "
		   ;;
             "-f")
		if [ "$invoption" == "1" ];
		then
			echo "inv_fragment #t ";
		fi
		echo "fragment #t ";
		;;
	      "--log-level")
	        echo "log_level \"$val1\" "	
                    ;;
	      "--log-prefix")
	          echo "log_prefix \"$val1\" "
		     ;;
	      "--log-tcp-sequence")
	          if [ "$val1" == "1" ] ;
		then
	    
	        echo "log_tcp_sequence #t "
		fi
		     ;;
	      "--log-tcp-options")
	          if [ "$val1" == "1" ] ;
		then
	    
	        echo "log_tcp_options 	#t "
		fi
		;;
		 "--log-ip-options")
		     if [ "$val1" == "1" ] ;
		then
	    
	        echo "log_ip_options 	#t "
		fi
		;;
		"--state")
		  OLDIFS=IFS
		  IFS=IFS","
		  for i in $val1
	           do
	           case $i in 
		   "NEW")
		     echo "state_new #t "
		     ;;
		   "ESTABLISHED")
		     echo "state_established #t "
                   ;;
		   "RELATED")
		     echo "state_related #t "
		     ;;
		   "INVALID")
		     echo "state_invalid #t "
		     ;;
		  esac
		  done 
		  IFS=$OLDIFS
		  ;;
		  "--set-mark")
	        echo "set_mark \"$val1\" "
		;;
		"--reject-with")
		echo "reject_with \"$val1\" "
		   ;;
		"--set-tos")
		    echo "set_tos \"$val1\""
		    ;;
		"--to-source")
                 if  [ "$val1" != "`echo $val1 | tr -d \:`" ] ;
		 then 
		 # having : in here; ports
		  ports_part=${val1##*:}
		  addrs_part=${val1%%:*}
		  echo "to_source_port_start \"${ports_part%%-*}\" "
		  echo "to_source_port_end \"${ports_part##*-}\" "
		  
		 fi
		  if  [ "$addrs_part" != "`echo $addrs_part | tr -d \-`" ] ;
		    then
		     echo "to_source_start \"${addrs_part%%-*}\" to_source_end \"${addrs_part##*-}\" " 
		    else
		     echo "to_source_start \"${val1}\" to_source_end \"${val1}\" "
		      
		   fi
	    	 ;;
			"--to-destination")
                 if  [ "$val1" != "`echo $val1 | tr -d \:`" ] ;
		 then 
		 # having : in here; ports
		  ports_part=${val1##*:}
		  addrs_part=${val1%%:*}
		  echo "to_destination_port_start \"${ports_part%%-*}\" "
		  echo "to_destination_port_end \"${ports_part##*-}\" "
		  
		 fi
		  if  [ "$addrs_part" != "`echo $addrs_part | tr -d \-`" ] ;
		    then
		     echo "to_destination_start \"${addrs_part%%-*}\" to_destination_end \"${addrs_part##*-}\" " 
		    else
		     echo "to_destination_start \"${val1}\" to_destination_end \"${val1}\" "
		      
		   fi
	    	 ;; 
	    "--to-ports")
	          if  [ "$val1" != "`echo $val1 | tr -d \-`" ] ;
		  then
	        	echo "to_ports_start \"${val1%%-*}\" "	   
			echo "to_ports_end \"${val1##*-}\" "
		  else
		        echo "to_ports_start \"${val1}\" "
		  fi
		  ;;
	    "--ttl-set")
		    echo "ttl_set \"$val1\" "
		    
		  ;;
	    "--ttl-dec")
		    echo "ttl_dec \"$val1\" "
		    
		  ;;
	    "--ttl-inc")
		    echo "ttl_inc \"$val1\" "
		    
		  ;;
	    "--ttl-set")
		    echo "ttl_set \"$val1\" "
		    
		  ;;
		  
	    "--tcp-flags") 
	         if [ "$invparm" == "1" ] ;

then
			 echo "inv_tcp_flags #t "
		 else
			 echo "inv_tcp_flags #f "
		 fi
		 
                 comp_set=$val1
		 mask_set=$val2
		 echo "comp set $comp_set mask set $mask_set" >&2
		 OLDIFS=$IFS
		 IFS=','
		 for i in $comp_set
		 do
			 il=`echo $i | tr [[:upper:]] [[:lower:]]`
			 echo "tcp_flags_comp_$il #t "
		 done
		 for i in $mask_set
			 do
			 il=`echo $i | tr [[:upper:]] [[:lower:]]`
			 echo "tcp_flags_mask_$il #t "
		 done
	
	 


	       ;;  
          esac     
}

on_message()
{
	
name=$in__objects

set | grep in_ >&2
case  $in_action in
                constraints) 
                               
                            case  "$in__objects" in
		           import)
			       echo  '(name (required #f) message (required #f))'
			       ;;
		           generate)
			   echo  '(name (required #f) firewall (required #f))'
			       ;;
		           try)
			       echo  '(name (required #f) message (required #f))'
			       ;;
		           install)
			       echo  '(name (required #f) message (required #f))'
			       ;;
		           default)
			       echo  '(name (required #f) message (required #f))'
			       ;;
                           v1/*/chains/)
                                echo -n '(name (required #t)'
                                echo -n 'zonename (required #t)'
				echo -n 'policy (required #f) )'
                                  ;;           
                           v1/*/*/rules)
                                echo -n '(name (required #f))'
                         ;;
                     v1/*/*/rules/*)
                    echo -n '(name (required #f)'
		    echo -n 'id (required #f) '
		    echo -n 'rule (required #f)'
		    echo -n 'num (required #f default 1)'
                    echo -n 'protocol (required #f)'
                    echo -n 'inv_protocol (required #f default #f)'
                    echo -n 'inv_source (required #f default #f )'
                    echo -n 'source (required #f)'
		    echo -n 'source_mask (required #f)'
                    echo -n 'inv_in_interface (required #f default #f)'
                    echo -n 'in_interface (required #f)'
		    echo -n 'inv_out_interface (required #f default #f)'
		    echo -n 'out_interface (required #f)'
                    echo -n 'inv_destination (required #f default #f)'
                    echo -n 'destination (required #f)'
		    echo -n 'destination_mask (required #f)'
                    echo -n 'inv_fragment (required #f default #f)'
                    echo -n 'fragment (required #f default #f)'
                    echo -n 'inv_source_port (required #f default #f)'
                    echo -n 'source_port_start (required #f)'
                    echo -n 'source_port_end (required #f)'
                    echo -n 'inv_destinaton_port (required #f default #f)'
                    echo -n 'destination_port_start (required #f)'
                    echo -n 'destination_port_end (required #f)'
                    echo -n 'inv_tcp_flags (required #f default #f)'
                    echo -n 'tcp_flags_mask_syn (required #f default #f)'
                    echo -n 'tcp_flags_comp_syn (required #f default #f)'
                    echo -n 'tcp_flags_mask_ack (required #f default #f)'
                    echo -n 'tcp_flags_comp_ack (required #f default #f)'
                    echo -n 'tcp_flags_mask_fin (required #f default #f)'
                    echo -n 'tcp_flags_comp_fin (required #f default #f)'
                    echo -n 'tcp_flags_mask_rst (required #f default #f)'
                    echo -n 'tcp_flags_comp_rst (required #f default #f)'
                    echo -n 'tcp_flags_mask_urg (required #f default #f)'
                    echo -n 'tcp_flags_comp_urg (required #f default #f)'
                    echo -n 'tcp_flags_mask_psh  (required #f default #f)'
                    echo -n 'tcp_flags_comp_psh  (required #f default #f)'
                    echo -n 'inv_tcp_option (required #f default #f)'
                    echo -n 'tcp_option (required #f)'
                    echo -n 'inv_icmp_type (required #f default #f)'
                    echo -n 'icmp_type (required #f)'
		    echo -n 'state_new (required #f default #f)'
                    echo -n 'state_invalid (required #f default #f )'
                    echo -n 'state_established (required #f default #f)'
                    echo -n 'state_related (required #f)'
                    echo -n 'jump (required #t)'
                    echo -n 'log_level (required #f)'
                    echo -n 'log_prefix (required #f)'
                    echo -n 'log_tcp_sequence (required #f default #f)'
                    echo -n 'log_tcp_options (required #f default #f)'
                    echo -n 'log_ip_options (required #f default #f)'
                    echo -n 'set_mark (required #f)'
                    echo -n 'reject_with (required #f)'
                    echo -n 'set_tos  (required #f)'
                    echo -n 'to_source_start (required #f)'
                    echo -n 'to_source_end (required #f)'
                    echo -n 'to_source_port_start (required #f)'
                    echo -n 'to_source_port_end (required #f)'
                    echo -n 'to_destination_start (required #f)'
                    echo -n 'to_destination_end (required #f)'
                    echo -n 'to_destination_port_start (required #f)'
                    echo -n 'to_destination_port_end (required #f)'
                    echo -n 'to_ports_start (required #f)'
                    echo -n 'to_ports_end (required #f)'
                    echo -n 'ttl_set (required #f)'
                    echo -n 'ttl_inc (required #f)'
                    echo -n 'ttl_dec (required #f))'



                         ;;

                           *) 
                              echo '#f'
                              ;;
                              esac
                         ;;
     list)
     case $name in
       v1/*/chains)
# just a chains list       
        begin_list
          ls -1 $EXP/${name%chains} | 
                (while read X
                 do
		      policy=`cat $EXP/${name%chains}/$X/.policy`
                         echo -n  "(\"$X\" policy_current \"$policy\")"
                 done
                ) 
        end_list
	;;
       v1/*/chains/*/policies)
         # first find out if this is a default chain
	 begin_list
	 X=${name#v1/*/chains/}
	 Y=${X%/policies}
	 echo "$Y" >&2
	 to_show="-"
	 if [ "$Y" == "OUTPUT" ];
	 then
		 to_show=all;
	 fi
         if [ "$Y" == "INPUT" ];
	 then
  		 to_show=all;
         fi
	 if [ "$Y" == "FORWARD" ];
	 then
		 to_show=all;
	 fi	 
	 if [ "$Y" == "PREROUTING" ];
	 then
		 to_show=all;
	 fi
	 if [ "$Y" == "POSTROUTING" ];
	 then
		 to_show=all;

	 fi
         if [ "$to_show" == "-" ];
	 then
	     echo "(\"-\")"	 
	 else 
             list_targets
         fi    

         end_list
       ;;

        v1/*/chains/*/rules)
         begin_list
             
             TM1=${name//\/chains/}
             TM2=${TM1//\/rules/}
	     cd $EXP/$TM2
	     
             ls -1 $EXP/$TM2  | sort -g | 
                   (while read X
                    do
               if [ "$X" != ".policy" ] ;
               then

                         DIR=TM2
			 Z=`cat $EXP/$TM2/$X`
                         echo -n  "(\"$X\" id \""
                         echo $Z 
                         echo "\")" 
               fi

                    done
                   ) 
             end_list
         ;;
	 v1/*/chains/*/rules/*jumps)
	 begin_list
	 list_targets
	 end_list
         ;;
	 v1/*/chains/*/rules/*avail_masks)
	 list_mask
	 ;;
        v1/*/chains/*/rules/*protocols)
         begin_list
         echo "(\"\" label \"\") (\"all\" label \"ALL\") ( \"tcp\" label \"TCP\" )(\"udp\" label \"UDP\")(\"icmp\" label \"ICMP\")(\"raw\" label \"RAW\")" 
         end_list
         ;;
	  v1/*/chains/*/rules/*interfaces)
         begin_list
	 for i in `cat /etc/dwall-alt/expert/interfaces`
	 do
		 echo "(\"$i\" label \"$i\")"
	 done
	 flg=0
	 for  i in `alterator-cmdline /net-tcp action list`
	 do
		 echo "#$i#" >&2
		 if [ "$i" == "name" ] ;
		 then
			 flg=1;
			 continue;
		 fi
                 if [ "$flg" == "1" ] ;
		 then
			 # already in ""
                   echo "($i label $i)"
		   flg=0
		 fi
	 done
	   
	 

	  

	 end_list
         ;;
	 v1/*/chains/*/rules/*log-level)
	 begin_list
         echo "(\"\" label \"\") (\"debug\" label \"debug\")    (\"info\" label \"info\" )(\"notice\" label \"notice\")(\"warning\" label \"warning\")(\"crit\" label \"crit\")(\"alert\" label \"alert\") (\"emerg\" label \"emerg\")" 
	   
	 end_list
	 
         ;;
	 v1/*/chains/*/rules/*reject-with)
	 begin_list
	 echo "(\"\" label \"\")"

	 echo "(\"icmp-port-unreachable\" label \"icmp_port_unreachable\")"
		
	 echo "(\"icmp-net-unreachable\" label \"icmp_net_unreachable\")"

	 echo "(\"icmp-host-unreachable\" label \"icmp_host_unreachable\")"
	 echo "(\"icmp-proto-unreachable\" label \"icmp_proto_unreachable\")"
	 echo "(\"icmp-net-prohibited\" label \"icmp_net_prohibited\")"
	 echo "(\"icmp-host-prohibited\" label \"icmp_host_prohibited\")"
	 echo "(\"tcp-reset\" label \"tcp_reset\")"
								
	 end_list
	 ;;
	 v1/*/chains/*/rules/*set-tos)
	 begin_list
	 echo "(\"\" label \"\")"
	 echo "(\"0x00\" label \"0x00 - Normal-Service\")"
	 echo "(\"0x02\" label \"0x02 - Minimize-Cost\")"
	 echo "(\"0x04\" label \"0x04 - Maximize-Reliability\")"
	 echo "(\"0x08\" label \"0x08 - Maximize-Throughput\")"
	 echo "(\"0x10\" label \"0x10 - Minimize-Delay\")"
	end_list
	;;
	  v1/*/chains/*/rules/*icmptype)
         begin_list
	 cat /etc/dwall-alt/expert/icmptypes | (
	  while read namex label
	  do
	 
		 echo "($namex label $label)"
          done
	 ) 
	 end_list
	 ;;
          *)
           \echo "#f"

           ;;
    
        esac
	;;
      new)
      #  echo "##as $name ##" >&2
        case $name in
            v1/*/chains)
         # options name, policy
          TM1=${name//\/chains}
          mkdir $EXP/$TM1/$in_name
          echo $in_policy >$EXP/$TM1/$in_name/.policy
             echo "()"
          ;;


            
        esac
        ;;
      delete)
        case $name in
            v1/*/chains/*)
	     echo $name >&2
	     # we can either delete non-builtin rules or change policy to builtin rules. That's all.
		     removename=${name//\chains}
	     if [ "$in_policy_current" == "-" ];
	     then
		     removename=${name//\chains}
		     echo "removing chain $EXP/$removename" >&2
		     rm -rf $EXP/$removename
	     else
                     echo "$in_policy_current" >$EXP/$removename/.policy
	     fi
             echo "()"
	     ;;
            v1/*/*/rules/*)
             TM1=${name//\/chains/}
             TM2=${TM1//\/rules/}
             rm -f $EXP/$TM2
             echo "()"
            ;;
             
           *)
            begin_list; echo "error -wrong request delete";
            end_list
           ;; 
        esac
        ;;
      "read")
        case $name in
         v1/*/chains/*/rules)
# example   in__objects=v1/mangle/chains/standard   
# WARNING:reserved words: chains rules

             TM1=${name//\/chains/}
             TM2=${TM1//\/rules/}
          POLICY=`cat $EXP/$TM2/.policy`;
	  
          echo -n "( chain \"${TM2#v1}\" policy \"$POLICY\" )"
            ;;
          v1/*/chains)
           begin_list
           
            TM1=${name//\/chains/}
            TM1=${TM1#v1/}
             ls -1 $EXP/${name%chains} | 
                   (while read X
                    do
                         echo -n  "(\"$X\" zonename \"$TM1\" delete #f)"
                    done
                   ) 
           end_list
        ;;
         v1/*/chains/*/rules/*)
           begin_list
# example   in__objects=v1/mangle/chains/standard/rules/1
# WARNING:reserved words: chains rules
# if trying to read "new" rule then it'll be the last rule
             echo "in read chains" >&2
             TM1=${name//\/chains/}
             TM2=${TM1//\/rules/}
	     X=${name#v1/*/chains/*}
	     rule=${X%/rules/*}
             echo "Rule: $rule" >&2
	      
          STRING_FW=`cat $EXP/$TM2`
	  STRING_FW="$STRING_FW --"
	  INV_OPTION=0
	  INV_OPTION_PARAM=0
	  INV_OPTION_OPTION=0
	  OPTION_STARTED=0
	  FIRST_TIME=1
	  OPTION_NAME=""
	  OPTION_VALUES=0
	  OPTION_VALUE_0=""
	  OPTION_VALUE_1=""
	  OPTION_VALUE_2=""
          for i in $STRING_FW
	  do
		  echo "parsing $i" >&2
        	  if [  "$i" == "!" ] ;
		    then
		    if [ "$INV_OPTION" == "0" ] ;
		     then
		     INV_OPTION=1;
		     echo "Inv option " >&2
		     continue;
		     fi
		    fi
	          if [ "${i:0:1}" == "-" ] ;
	                  then
			   echo "Option started $i" >&2
			   if [ "$FIRST_TIME" == "1" ] ;
		              then
			         OPTION_NAME=$i
			         OPTION_VALUES=0
		            
		                 OPTION_STARTED=1;
				 FIRST_TIME=0
				
			      else	
		                 
		              
				echo "Flushing $OPTION_NAME" >&2
	                        OPTION_STARTED=0
		                emit_option $INV_OPTION_OPTION $INV_OPTION_PARAM $OPTION_NAME $OPTION_VALUES $OPTION_VALUE_0 $OPTION_VALUE_1 $OPTION_VALUE_2
		                OPTION_NAME=$i
				OPTION_VALUES=0
				INV_OPTION_PARAM=0
			         if [ "$INV_OPTION" == "1" ] ;
		         	      then
			              INV_OPTION_OPTION=1
			              INV_OPTION=0
			              
			         else
		
				
				  INV_OPTION_OPTION=0
				fi
                              fi
		           else	      
                # otherwise its an option's value   
		   if [ "$INV_OPTION" == "1" ];
		     then
		       INV_OPTION_PARAM=1
		       INV_OPTION=0      
		     fi  
		   let OPTION_VALUES=$OPTION_VALUES+1;
		   case "$OPTION_VALUES" in
			     "1") OPTION_VALUE_0=$i ; ;;

			     "2") OPTION_VALUE_1=$i; ;;
			     "3") OPTION_VALUE_2=$i; ;;
		   esac 
		  
		          fi
	             	 
          done
          
		 
	  echo "finished" >&2
	  dir=$EXP/$TM2
	  dir=${DIR%/*}
         if [  -e $EXP/$TM2 ] ;
	 then
          echo " num \"${name##*/}\" "
             else
		 # actually, it's a new rule, has number last
             numrule=`ls -1 $dir | wc -l`
	     let numrule=$numrule+1;
	  echo "num \"$numrule\" "
	 fi
	 echo " rule \"$rule\""            
	  end_list
            ;;
          
         import)
	 rm -rf $EXP/v1/*
	 tclsh /etc/dwall-alt/expert/scripts/parse.tcl >$TMPDIR/res
         if [ "$res" != "" ];
	 then
		 echo "(error "
		   cat $TMPDIR/res
		   rm $TMPDIR/res
                 echo ")"
	 else
		 echo "()"
	 fi

	    ;;
         generate)
	   set -x
	   if [ -z "$in_firewall" ]; 
	   then
	     rm -rf $TMPDIR/file
	     ( $EXP/scripts/gather.sh) >/dev/null 2>$TMPDIR/errors
           fi  
	   if [ "`cat $TMPDIR/errors`" == "" ] ;
	   then
            echo -n "(error `cat $TMPDIR/errors`)"
            else
	
	     echo -n "(firewall  \""
    	     cat $TMPDIR/file | simple_quote
             echo -n "\" )"
           fi

          set +x
            ;;
         install)
	    
	   /sbin/iptables-restore <$TMPDIR/file 2>&1 >$TMPDIR/errors
	   if [ "`cat $TMPDIR/errors`" != "" ] ;
	   then
            echo -n "(error `cat $TMPDIR/errors`)"
           else  
	 
	   /sbin/iptables-save >/etc/sysconfig/iptables
         
	      echo "()"
            fi
         ;;
	 try)
           /sbin/iptables-restore <$TMPDIR/file 2>&1 >/$TMPDIR/errors
	   if [ "`cat $TMPDIR/errors`" != "" ];
	   then
            echo -n "(error `cat $TMPDIR/errors`)"
	   else

	   sleep 60
	   /sbin/iptables-restore </etc/sysconfig/iptables
	   echo "()"
           fi
	 ;;
	 "default")
	   rm -rf $EXP/v1/*
	   rmdir $EXP/v1 
	   cp -rf $EXP/vmin/ $EXP/v1
	  echo "()"
	  ;;
            
        
         *)
	 echo "()";
	 ;;
	esac
	;; 
      write)
        case $name in
           v1/*/chains/*/rules/*)
             set -x
             TM1=${name//\/chains/}
             TM2=${TM1//\/rules/}
                 nm=$EXP/$TM2
		 nm1=`dirname $nm`
		 oldid=${nm1##*/}
		 # if the rule is NOT new, delete its old value now 
		 # move rule to temp
		 # if its new place is free , move it there
		 # if no, renumber rules from the offending  rule up
		 # and move rule from temp to its new place
		 if [ "$oldid" != "new" ];
		 then
			 rm -f $EXP/$TM2
		 fi
		 emit_rule >$TMPDIR/rule
		 if [ -e "$nm1/$in_num" ];
	           then	   
		   (
			 # do shift up other rules
			 mkdir $nm1/.tmp;
                   pushd $nm1
		   ls -1  | grep -v ".policy" | sort -g | (
		      while read X
		      do
                         if [  "$X"  -ge  "$in_num" ];
			 then
			    let xn=$X+1
			    mv $X $nm1/.tmp/$xn
		         fi   
		      done
		      )
		     popd
		     mv $nm1/.tmp/* $nm1
		     rmdir $nm1/.tmp
                       ) >/dev/null 
	            fi
		  mv $TMPDIR/rule $nm1/$in_num  
           echo "()"
            ;;
         generate)
         	 echo $in_firewall >$TMPDIR/file
	         echo "()"
	    ;;
	 default)
	         echo "()"
	    ;;
	 try)
	         echo "()"
		 ;;
	 import)
	         echo "()"
	        ;;
	  install)
	         echo "()"
		;;
         *)
	 echo "#f"
         ;;
        esac
        ;;
esac

}      



message_loop



