#!/bin/bash

DWALL=/etc/dwall-alt

. /usr/share/alterator/build/backend3.sh


begin_list()
{
	echo -n "("
}

end_list()
{
	echo ")"
}


on_message()
{
name=$in__objects

set | grep in_ >&2
case  $in_action in
                constraints) 
				           
				        case  "$in__objects" in
                           fwsimple)
				     		   echo -n '(firewall (required 0))'
                                  ;;           
                           *) 
                              echo '(name (required #f) intf
	                         (required #f) dest (required #f)	state (required #f)	      
			      )'

                              ;;
						esac
					;;
	list)
	case $name in
	  zone)
# just a zone list	  
	   begin_list
	     cut -f1 -d" " $DWALL/zone.conf | 
	           (IFS="";while read 
	            do
	            if [ "${REPLY}" != "" ] ;
	             then 
	              if  [ "${REPLY:0:1}" != "#" ];  
	               then
                         intf=`grep ${REPLY} $DWALL/zone.conf| cut -f2 -d" "`
                         echo -n  "(\"$REPLY\" intf \"$intf\")"
	              fi
	             fi    
	            done
	           ) 
#          #lterator -c cmdline.layout -l "/fw/zones/internal" action write to so serv ftp state allowed from all to 
	  end_list
	  ;;
          zoneifs)
	   begin_list
	    cat $DWALL/zone.conf |
	      (while read X Y
	        do 
	         if [ "${X}" != "" ] ;
		  then
		   if [ "${X:0:1}" != "#" ] ;
		     then 
		       echo -n "(\"$Y\")"
		     fi  
		  fi
		done  
	      )  
	   end_list
	  ;;
          services/*/*)
            
	     N=0;
             unset services
             unset in
 	     unset out
             declare -a -x services 
             declare -a -x out
	     declare -a -x in
             ls -1 /etc/dwall-alt/services_simple >$TMPDIR/ls
	     while read X 
              do
		services[$N]=$X;
                in[$N]=0;
		out[$N]=0;
		let N=$N+1;
                export services in out 
	      done </$TMPDIR/ls
             
               
	       
              cd $DWALL/chains
	      function findserv () { 
      		N=0 
                
                for i in ${services[@]}
                do  
   		    
                if [ "$i" == "$1" ] ; 
                    then
                      echo -n $N
                    else
                     let N=$N+1;
                 fi
               done
              
             
     
              }
	       FIL=`mktemp`
	       zonefrom_d=${name%/*}
	       zonefrom=${zonefrom_d#services/}
	       zoneto=${name#$zonefrom_d/}
	       echo $zonefrom " " $zoneto >&2
               zonename=$zonefrom-$zoneto.chain
	       zonename_back=$zoneto-$zonefrom.chain
               echo "1" >&2
               echo "("
                   OLDIFS=$IFS
                   IFS=" ";
                      while read STATUS SERVICE FROM TO OPTIONS;
                        do 
			 if [ "$STATUS" == "allow" ] ; then STATE="#t"; else STATE="#f"; fi;
                         echo "(\"$SERVICE\" dest "to"  state $STATE from \"$FROM\" to \"$TO\" options \"$OPTIONS\" )" >>$FIL
			 XN=`findserv  $SERVICE`
		
			 in[$XN]=1
   			 export in
                         done <$zonename
                      
                      while read STATUS SERVICE FROM TO OPTIONS;
		         do
			 if [ "$STATUS" == "allow" ] ; then STATE="#t"; else STATE="#f"; fi;
                        
                         echo "(\"$SERVICE\" dest "from"  state $STATE from \"$FROM\" to \"$TO\" options \"$OPTIONS\" )" >>$FIL
			 XN=`findserv   $SERVICE` 
			 out[$XN]=1
    			 export out
 		        done <$zonename_back
			uniq $FIL | sort
                      IFS=$OLDIFS
                     
		 
                
	       #and not mentioned services...
               echo "3" >&2
                set >/tmp/allres
                 for x in ${services[@]}
	        do
		 N=${services[$x]}
                 
		 if [ "${in[$N]}" == "0" ] ;
		   then if [ "${out[$N]}" == "0" ] ;
		     then
                         echo "(\"$x\" dest "from"  state \"#f\" from \"$zonefrom\" to \"$zoneto\" options \"\" )"
                         echo "(\"$x\" dest "to"  state \"#f\" from \"$zoneto\" to \"$zonefrom\" options \"\" )"
                         
                     fi
		 fi
		done
                set +x
             echo ")"
              
             
# Look up services for zoneX against zoneY
	  ;;
          allservices)
           if [ "$in_type" == "simple" ] ;
		then
		begin_list
	     	for i in `ls -x $DWALL/services_simple`
	  	do
		  echo " (\"$i\") "
		done
		end_list
	  fi
          if [ "$in_type" != "simple" ] ;
                then
                begin_list
                for i in `ls -x $DWALL/services`
                do
                  echo " (\"$i\") "
                done
                end_list
          fi
	  ;;
          *)
# Look up zone's links against other zone	  
# example          /fw/zoneX - shows  all zones o which this zone has any relations defined
           
            begin_list

              (cd $DWALL/chains; ls -1 ${name#zones/}*.chain |  (IFS="-.";while  read DUM NAM DUM2 ; do echo -n "(\"$NAM\")"; done) )
            end_list
          ;;  
        esac 
        ;;
      new)
        case $name in
            zone)
             begin_list;
	          echo "${in_name} $in_intf" >>$DWALL/zone.conf
             end_list;
            ;;
            *)
           begin_list; echo "error -wrong request new";
           end_list
           ;; 
        esac
        ;;
      delete)
        case $name in
           zone/*)
             begin_list;
                zonename=${in_name}
                rm -f $DWALL/chains/$zonename-* $DWALL/chains/*-$zonename.*
                fname=`mktemp`
                
                cat $DWALL/zone.conf | grep -v "^$zonename" >$fname
                mv $fname $DWALL/zone.conf
             end_list;
           ;;
           *)
            begin_list; echo "error -wrong request delete";
            end_list
           ;; 
        esac
        ;;
      read)
         case $name in
	   zone/*)
	      # iface xxx 
            zonename=${name#zone/}
	    cat $DWALL/zone.conf |
	      (while read X Y
	        do 
	         if [ "${X}" != "" ] ;
		  then
		   if [ "${X:0:1}" != "#" ] ;
		     then 
		     if [ "$zonename" == "$X" ];
		       then
		         echo -n "(intf \"$Y\")"
		       fi
		     fi  
		  fi
		done  
	      )  

	   ;;
           *)
	       echo "in read" >&2
           echo "( "
		   echo "firewall "
           echo -n "\""
	       cat $DWALL/firewall | simple_quote
           echo -n "\""

           echo ")"
           ;;
	 esac
        ;;
      write)
        case $name in
         zone/*)
           zonename=${in_name}
           #echo "$in_state $in_serv $in_from $in_to $in_options"  >>$DWALL/chains/$zonename-$in_against.chain

	        echo >&2 "in write zone intf"
                fname=`mktemp`
                cat $DWALL/zone.conf | grep -v "^$zonename" >$fname
                mv $fname $DWALL/zone.conf
	          echo "$zonename $in_intf" >>$DWALL/zone.conf
		  echo "()"
         ;;
         generate)
           begin_list
           /usr/bin/dwall
           end_list
         ;;
         install)
           begin_list
           /sbin/service dwall restart
           end_list
         ;;
         "fwsimple")
           begin_list
           echo "$in_firewall" >$DWALL/firewall
           end_list
         ;;
         *)
            begin_list; echo "error -wrong request write";
            end_list
         ;;
        esac
        ;;
esac

}      



message_loop



