#!/usr/bin/tclsh8.5
#
# $Id: 15ae7858d547596f8feaa3e3016ffcfd4c50b43f $
#

## The common defaults
set filters_init_file "/usr/local/libexec/nbsp/filters.init";
if {[file exists $filters_init_file] == 0} {
	puts "nbspfilter disabled: $filters_init_file not found.";
	return 1;
}
source $filters_init_file;
unset filters_init_file;

if {$filters_init_status == 1} {
	return 1;
}
unset filters_init_status;

# default configuration
set nbspfilter(conf)	[file join $common(confdir) "nbspfilter.conf"];
set nbspfilter(rc)	[file join $common(confdir) "nbspfilter.rc"];
set nbspfilter(ri)	[file join $common(confdir) "nbspfilter.ri"];
set nbspfilter(rq)	[file join $common(confdir) "nbspfilter.rq"];
set nbspfilter(rcdir)	[file join $common(rcdir) "nbsp"];
set nbspfilter(lib)	[file join $common(libdir) "nbspfilter.lib"];
set nbspfilter(rcfiles) [list];
set nbspfilter(localconfdirs) $common(localconfdirs);
set nbspfilter(prerc)  [file join $common(confdir) "nbspfilterpre.rc"];
set nbspfilter(postrc)  [file join $common(confdir) "nbspfilterpost.rc"];
#
# Variables
#
set nbspfilter(condition)		[list];
set nbspfilter(action)		[list];

#
# Read the optional configuration file.
#
if {[file exists $nbspfilter(conf)] == 1} {
    source $nbspfilter(conf);
}

# The main rc file is required
if {[file exists $nbspfilter(rc)] == 0} {
    log_msg "Filter disabled: $nbspfilter(rc) not found.";
    return 1;
}

# Build the list of rc files
set nbspfilter(rcfiles) [filterlib_get_rcfiles [file tail $nbspfilter(rc)] \
        $nbspfilter(localconfdirs) $nbspfilter(rcdir) \
	$nbspfilter(prerc) $nbspfilter(postrc)];

# Load the rules sets
source $nbspfilter(rc);

proc main {argc argv} {

    global errorInfo;

    # gets returns -1 on eof. In addition the server explicitly
    # signals the filters to quit by sending a blankline
    # (gets returns 0 in this case, and finfo is "").

    while {[gets stdin finfo] >= 0} {
	if {$finfo == ""} {
	    log_msg "Received request to quit.";
	    break;
	}

	set status [catch {process $finfo} errmsg];
	if {$status != 0} {
	    log_msg "Error processing $finfo";
	    log_msg $errmsg;
	    log_msg $errorInfo;
	}
    }
}

proc process {finfo} {

    global nbspfilter;

    filterlib_get_rcvars rc $finfo;

    set rc_status 1;

    # Evaluate the condition/action pairs, from all sets.
    set i 0;		# counts the sets
    foreach condlist $nbspfilter(condition) {
        set actionlist [lindex $nbspfilter(action) $i];
	set j 0;	# counts the rules with each set
	foreach c $condlist {
	    set a [lindex $actionlist $j];
            if {[expr $c]} {
                eval $a;
            }
	    incr j;
        }
        incr i;
    }
}

proc init_quit {ext} {

    global nbspfilter;

    # Read any initialization or termination code from the files:
    #
    # nbspfilter.${ext}
    # defaults/nbspfilter.${ext}
    # site/nbspfilter.${ext}
    # rc.d/nbsp/*.${ext}
    #
    
    if {[file exists $nbspfilter(${ext})] == 1} {
	source $nbspfilter(${ext});
    }

    #
    # defaults and site
    #
    set _qname [file tail $nbspfilter(${ext})]
    foreach _d $nbspfilter(localconfdirs) {
	set _localqname ${_d}/${_qname}
	if {[file exists ${_localqname}] == 1} {
	    source ${_localqname};
	}
    }
    unset -nocomplain _d;
    unset -nocomplain _localqname;
    unset _qname;

    #
    # rc.d/nbsp
    #
    if {[file isdirectory $nbspfilter(rcdir)] == 1} {
       set _q "";
	foreach _q [glob -nocomplain -directory $nbspfilter(rcdir) *.${ext}] {
	    if {[file exists ${_q}] == 1} {
		source ${_q};
	    }
	}
	unset _q;
    }
}

# Read any initialization code in the ri files
set status [catch {init_quit "ri"} errmsg];
if {$status != 0} {
    log_msg $errmsg;
    return 1;
}

filterlib_init;		# open the cpool if enabled
main $argc $argv;
filterlib_end;		# close the cpool if enabled

# Read any termination code in the rq files
set status [catch {init_quit "rq"} errmsg];
if {$status != 0} {
    log_msg $errmsg;
    return 1;
}
