#!/bin/sh
# the next line restarts using wish \
exec wish "$0" "$@"
              
##############################################################
# top.tcl (top level name space)
#
# SePCuT: SE Linux Security Policy Customization Tool
#
# Copyright (C) 2002-2005 Tresys Technology, LLC
# see file 'COPYING' for use and warranty information 
#
# TCL/TK GUI for SE Linux policy analysis
# Requires tcl and tk 8.3+, with BWidgets
# Author(s): <don.patterson@tresys.com, mayerf@tresys.com>
# Question/comments to: selinux@tresys.com
#
# This tool is designed as a basic customization and editing
# tool for selinux security policy source directory files.
# This tool will allow you to include/exclude/add/delete policy
# program modules, and browse and edit all policy source
# files.  In addition, it will allow you to test, debug,
# load, and install the policy.  

# See the assoicated help file for more information.
#
##############################################################
namespace eval Sepct_db {
	variable lfiles_num_data 3	
	variable tree			
	variable mod_FileArray
	variable mod_FileNames   ""
}
proc Sepct_db::read_fileContents_fromDisk { path data_var } {
	upvar $data_var data
	if { [file exists $path] } {
		if { [file readable $path] } {
			set file_channel [open $path RDONLY]
			set data [read $file_channel]
			::close $file_channel
			return 0
		} else {
			tk_messageBox -icon error \
			-type ok \
			-title "Permission Problem" \
			-message \
			"You do not have permission to read $path."
			return -1
		}
	} else {
		tk_messageBox -icon error \
		-type ok \
		-title "File Does Not Exist" \
		-message "File ($path) does not exist."
		return -1
	}
	return 0
}
proc Sepct_db::file_write { data path } {
	set parent [file dirname $path]
	set parent_exists [file isdirectory $parent] 
	set parent_writeable [file writable $parent]
	set file_exists [file exists $path] 
	set file_writeable [file writable $path]
	if { $file_exists } {
		if { ! $file_writeable } {
			tk_messageBox -icon error  \
				-type ok \
				-parent $Sepct::mainWindow \
				-title "Save Error (existing file)" \
				-message \
				"You do not have permission to write to $path."
			return -1
		}
	} elseif { $parent_exists } {
		if { ! $parent_writeable } {
			tk_messageBox -icon error  \
				-type ok \
				-parent $Sepct::mainWindow \
				-title "Save Error (new file)" \
				-message \
				"You do not have permission to write the directory $parent."
			return -1	
		}		
	}
	set rt [catch { 
		set fileid [open $path "w"]
		puts -nonewline $fileid $data
		::close $fileid} err]
	if { $rt != 0 } {
		tk_messageBox -icon error  \
			-type ok \
			-parent $Sepct::mainWindow \
			-title "Save Error" \
			-message \
			"$err"
		return -1
	} 
	return 0
}
proc Sepct_db:incr_lfiles_mod_cntr { lfiles } {
	if { [llength $lfiles] < 1 } {
		puts stderr "provided lfiles list had no elements!"
		return -1
	}
	set cntr [lindex $lfiles 0]
	if {![string is integer $cntr] } {
		puts stderr "Tree node mod cntr ($cntr) is not a valid integer!"
		return -1
	}
	incr cntr
	set lfiles [lreplace $lfiles 0 0 $cntr]
	return $lfiles	
}
proc Sepct_db::get_file_list { lfiles } {
	if { [llength $lfiles] < 1 } {
		return ""
	}
	set files [lreplace $lfiles 0 0 ]
	return $files
}	
proc Sepct_db::search_file_list_for_names { lfiles file_name } {
	set idx 0
	set length [llength $lfiles]
	while {$idx <= $length} {
		if {[string equal [lindex $lfiles $idx] $file_name]} {
			return $idx
		}
		set idx [expr $idx + 4]
	}
	return -1
}
proc Sepct_db::add_file { fn cntr { pos "1.0"} } {
	variable tree
	if { [catch {scan $pos "%d.%d" line col} err ] } {
		puts stderr "update_pos: Problem scanning position ($pos): $err"
		return -1
	}	
	set parent [file dirname $fn]
	set tail [file tail $fn]
	if { ![$tree exists $parent] } {
		return -1
	}
	set lfiles [$tree itemcget $parent -data]
	set files [Sepct_db::get_file_list $lfiles]
	if {[string is integer $tail]} {
		set idx [Sepct_db::search_file_list_for_names $files $tail]
	} else {
		set idx [lsearch -exact $files $tail]
	}
	if { $idx != -1 } {
		set cidx [expr $idx + 1]
		set new_cntr [expr [ lindex $files $cidx ] + 1]	
		lreplace $files $cidx [expr $cidx + 2] $new_cntr $line $col	
	} else {
		lappend files $tail
		set new_cntr   $cntr
		lappend files $cntr	
		lappend files $line	
		lappend files $col
	}
	set node_cntr [lindex $lfiles 0]
	set new_lfiles [linsert $files 0 $node_cntr]
	set new_lfiles [Sepct_db:incr_lfiles_mod_cntr $new_lfiles]
	if {$lfiles == -1} {
		puts stderr "Add: error incrementing node ($fn) mod counter"
		return -1
	}
	$tree itemconfigure $parent -data $new_lfiles
	return $new_cntr
}
proc Sepct_db::remove_file { fn } {
	variable tree
	set parent [file dirname $fn]
	set tail [file tail $fn]
	if { ![$tree exists $parent] } {
		return -1
	}
	set lfiles [$tree itemcget $parent -data]
	set files [Sepct_db::get_file_list $lfiles]
	if {[string is integer $tail]} {
		set idx [Sepct_db::search_file_list_for_names $files $tail]
	} else {
		set idx [lsearch -exact $files $tail]
	}
	if { $idx == -1 } {
		return 0	
	}
	set files [lreplace $files $idx [expr $idx + 3 ]]
	set node_cntr [lindex $lfiles 0]
	set new_lfiles [linsert $files 0 $node_cntr]
	set new_lfiles [Sepct_db:incr_lfiles_mod_cntr $new_lfiles]
	if {$new_lfiles == -1} {
		puts stderr "Remove: error incrementing node ($fn) mod counter"
		return -1
	}
	$tree itemconfigure $parent -data $new_lfiles
	return 0
}
proc Sepct_db::move_file { oldfn newfn } {
	variable tree
	variable lfiles_num_data
	set oldparn [file dirname $oldfn]
	set newparn [file dirname $newfn]
	if { ![$tree exists $oldparn] || ![$tree exists $newparn] } {
		return -1
	}
	set fdata [Sepct_db::getFileData $oldfn]
	if { [llength $fdata] < $lfiles_num_data } {
		puts stderr "Problem getting file info data for $oldfn"
		return -1
	}
	set rt [Sepct_db::getModFile_Data $oldfn old_data]
	if {$rt != -1} {
		Sepct_db::remove_from_mod_List $oldfn
	}
	if { [Sepct_db::remove_file $oldfn] == -1 } {
		puts stderr "Problem removing $oldfn"
		return -1
	}
	if {[Sepct_db::add_file $newfn 0] == -1 }  {
		puts stderr "Problem adding $newfn"
		return -1
	}
	if {$rt != -1} {
		set cnt [Sepct_db::add_to_mod_List $newfn $old_data]
	} else {
		set cnt 0
	}
	return $cnt
}
proc Sepct_db::getFileData { fn } {
	variable tree
	set parent [file dirname $fn]
	set tail [file tail $fn]	
	if { ![$tree exists $parent] } {
		return ""
	}
	set lfiles [$tree itemcget $parent -data]
	set files [Sepct_db::get_file_list $lfiles]
	if {[string is integer $tail]} {
		set idx [Sepct_db::search_file_list_for_names $files $tail]
	} else {
		set idx [lsearch -exact $files $tail]
	}
	if {  $idx == -1 } {
		return ""
	}
	set fdata [lrange $files [expr $idx + 1] [expr $idx + 3]]
	return $fdata
}
proc Sepct_db::getFileNames {node } {
	variable lfiles_num_data
	variable tree
	if { ![$tree exists $node] } {
		return "-1"
	}
	set lfiles [$tree itemcget $node -data]
	set files [Sepct_db::get_file_list $lfiles]
	set len [llength $files]
	if { $len < 1 } {
		return ""
	}
	for {set x 0} {$x < $len} {incr x} {
		lappend filenames [lindex $files $x]
		set x [expr $x + $lfiles_num_data]
	}
	return $filenames
}
proc Sepct_db::update_mod_cntr { fn } {
	variable tree
	set parent [file dirname $fn]
	set tail [file tail $fn]	
	if { ![$tree exists $parent] } {
		return  -1
	}
	set lfiles [$tree itemcget $parent -data]
	set files [Sepct_db::get_file_list $lfiles]
	if {[string is integer $tail]} {
		set idx [Sepct_db::search_file_list_for_names $files $tail]
	} else {
		set idx [lsearch -exact $files $tail]
	}
	if {  $idx == -1 } {
		return -1
	}
	set cidx [expr $idx + 1]
	set new_cntr [expr [ lindex $files $cidx ] + 1]
	set files [lreplace $files $cidx $cidx $new_cntr]
	set node_cntr [lindex $lfiles 0]
	set new_lfiles [linsert $files 0 $node_cntr]
	$tree itemconfigure $parent -data $new_lfiles
	return $new_cntr
}
proc Sepct_db::update_pos { fn { pos "1.0"} } {
	variable tree
	if { [catch {scan $pos "%d.%d" line col} err ] } {
		puts stderr "update_pos: Problem scanning position ($pos): $err"
		return -1
	}
	set parent [file dirname $fn]
	set tail [file tail $fn]	
	if { ![$tree exists $parent] } {
		return  -1
	}
	set lfiles [$tree itemcget $parent -data]
	set files [Sepct_db::get_file_list $lfiles]
	if {[string is integer $tail]} {
		set idx [Sepct_db::search_file_list_for_names $files $tail]
	} else {
		set idx [lsearch -exact $files $tail]
	}
	if {  $idx == -1 } {
		return -1
	}
	set files [lreplace $files [ expr $idx + 2] [ expr $idx + 3] $line $col]
	set node_cntr [lindex $lfiles 0]
	set new_lfiles [linsert $files 0 $node_cntr]
	$tree itemconfigure $parent -data $new_lfiles
	return 0
}
proc Sepct_db::get_cntr { fn  } {
	variable tree
	set parent [file dirname $fn]
	set tail [file tail $fn]	
	if { ![$tree exists $parent] } {
		return  -2
	}
	set lfiles [$tree itemcget $parent -data]
	set files [Sepct_db::get_file_list $lfiles]
	if {[string is integer $tail]} {
		set idx [Sepct_db::search_file_list_for_names $files $tail]
	} else {
		set idx [lsearch -exact $files $tail]
	}
	if {  $idx == -1 } {
		return -1
	}
	set cntr [lindex $files [expr $idx + 1]]
	return $cntr
}
proc Sepct_db::get_pos { fn  } {
	variable tree
	set parent [file dirname $fn]
	set tail [file tail $fn]	
	if { ![$tree exists $parent] } {
		return  ""
	}
	set lfiles [$tree itemcget $parent -data]
	set files [Sepct_db::get_file_list $lfiles]
	if {[string is integer $tail]} {
		set idx [Sepct_db::search_file_list_for_names $files $tail]
	} else {
		set idx [lsearch -exact $files $tail]
	}
	if {  $idx == -1 } {
		return ""
	}
	set line [lindex $files [expr $idx + 2]]
	set col [lindex $files [expr $idx + 3]]
	return "$line.$col"
}
proc Sepct_db::does_fileExists  { fn } {
	variable tree
	set parent [file dirname $fn]
	set tail [file tail $fn]	
	if { ![$tree exists $parent] } {
		return 0
	}
	set lfiles [$tree itemcget $parent -data]
	set files [Sepct_db::get_file_list $lfiles]
	if {[string is integer $tail]} {
		set idx [Sepct_db::search_file_list_for_names $files $tail]
	} else {
		set idx [lsearch -exact $files $tail]
	}
	if {  $idx == -1 } {
		return 0
	}
	return 1
}
#	- note this does not ensure that any changed files are saved!
proc Sepct_db::close {} {
	variable mod_FileArray
	variable mod_FileNames
	array unset mod_FileArray
	set mod_FileNames ""
	$Sepct_db::tree delete [$Sepct_Browse::tree nodes root]  
	return 0
}
proc Sepct_db::get_node_mod_cntr { node } {
	variable tree 
	if {![$tree exists $node]} {
		return -1
	}
	set lfiles [$tree itemcget $node -data] 
	if { [llength $lfiles] < 1 } {
		puts stderr "$node lfiles list had no elements!"
		return -1
	}
	set cntr [lindex $lfiles 0]
	return $cntr	
}
proc Sepct_db::mkdir_addTree_node { node parent isopen } {
	if { ![file isdirectory $parent] } {
		return 11
	}
	set full_node_name [file join $parent $node]
	if { [file exists $full_node_name] } {
		return 0	# no error if already exists
	}
	set rt [catch {file mkdir $full_node_name} err] 
	if {$rt != 0 }  {
		 tk_messageBox -icon error \
			-type ok  \
			-title "Directory Creation Error" \
			-message \
			"The directory $full_node_name could not be created:\n\n\
			 $err"
		 return -1	
	}
	Sepct_db::addTree_node $full_node_name $isopen 0
        return 0
}
proc Sepct_db::existsTree_node { node } {
	variable tree
	set rt [$tree exists $node]
	return $rt
}
proc Sepct_db::addTree_node { node isopen isroot} {
	variable tree
	set parent [file dirname $node]
	if { !($isroot) && ![$tree exists $parent] } {
		return -1
	}
	if {$isopen} {
		set img [Bitmap::get openfold]
	} else {
		set img [Bitmap::get folder]
	}
	if {$isroot} {
		set pname "root"
		set nname $node
	} else {
		set pname $parent
		set nname [file tail $node] 
	}
	$tree insert end $pname $node -text $nname \
		-image     $img \
		-open $isopen	\
        	-drawcross auto \
        	-data "0"
        return 0
}
proc Sepct_db::removeTree_node { node parent } {
	return 0
}
proc Sepct_db::moveTree_node { node new_parent } {
	return 0
}
proc Sepct_db::remove_from_mod_List { path } {
	variable mod_FileArray
	variable mod_FileNames
	if { [array exists mod_FileArray] && [array names mod_FileArray $path] != ""} {
		array unset mod_FileArray $path
		set mod_FileNames [Sepct_db::getModFileNames]
		set cntr [Sepct_db::update_mod_cntr $path]
		if { $cntr  == -1 } {
			puts stderr "problem updating mod cntr for $path in remove_from_mod_List."
		}
		return $cntr
	}		
    	return  -2
}
# ::add_to_mod_List (update/replace too!)
proc Sepct_db::add_to_mod_List { path data } {
	variable mod_FileArray
	variable mod_FileNames
	set mod_FileArray($path) $data
	set mod_FileNames [Sepct_db::getModFileNames]
	set cntr [Sepct_db::update_mod_cntr $path]
	if { $cntr == -1 } {
		puts stderr "problem updating mod cntr for $path in add_to_mod_List."
	}
    	return $cntr
}
proc Sepct_db::are_there_mod_files { } {
	variable mod_FileArray
	if { [array size mod_FileArray] > 0 } {
		return 1
	} else {
		return 0
	}
}
proc Sepct_db::is_in_mod_FileArray { path } {
	variable mod_FileArray
	if { [array exists mod_FileArray] } {
		set mod_File_Path [array names mod_FileArray $path]
		if {  $mod_File_Path != "" } {
		    	return 1
	   	} 
	}
	return 0
}
proc Sepct_db::discard_All_File_Changes { } {
	set mod_File_Paths [Sepct_db::getModFileNames]
	foreach path $mod_File_Paths {
		Sepct_db::discard_Single_File_Changes $path
	}
	return 0
}
proc Sepct_db::discard_Single_File_Changes { path } {
	if { [Sepct_db::is_in_mod_FileArray $path] } {
		set rt [Sepct_db::remove_from_mod_List $path]
		return $rt
	}
    	return -2
}
proc Sepct_db::getModFile_Data {fn data_var} {
	variable mod_FileArray
	upvar $data_var data
	if { [Sepct_db::is_in_mod_FileArray $fn ] } {
		set data $mod_FileArray($fn)
		return 0
	} else {
		return -1		
	}
}
proc Sepct_db::saveFile { path {pos "none"} } {
	variable mod_FileArray
	if { [Sepct_db::is_in_mod_FileArray $path] } {
		set rt [Sepct_db::file_write $mod_FileArray($path) $path]
		if {$rt != 0 } {
			return -1
		}
		set cntr [Sepct_db::remove_from_mod_List $path]
		if {$cntr == -1 } {
			puts stderr "Problem removing $path from mod list in saveFile."
			return -1
		}
		if { $pos != "none"} {
			Sepct_db::update_pos $path $pos
		}
		return $cntr
	}
	return -2
}
proc Sepct_db::getModFileNames { } {
	variable mod_FileArray
	if { [array exists mod_FileArray] } {
		set list [array names mod_FileArray]
		return $list
	} else {
		return ""
	}
}
namespace eval Sepct {
	variable gui_ver		0.3.8
	variable copyright_date		"2002-2004"
	# install_dir is a magical string to be defined via the makefile!
	variable sepcut_install_dir	/usr/share/setools
	variable bwidget_version	""
	variable helpFilename		""
	variable policyDir		""	
	variable policyOpened	0		
	variable status 		""	
	variable file_name		""
	variable file_modTime		""
	variable file_size		""
	variable line_info		""
	variable tabName_prefix		"Sepct_"
	variable browse_tab		"Sepct_Browse"
	variable customize_tab		"Sepct_Customize"
	variable test_tab		"Sepct_Test"
	variable disable_customize_tab	0
	variable disable_test_tab	0
	variable dot_sepcut_file 	"[file join "$::env(HOME)" ".sepcut"]"
	variable recent_dirs_tmp_list	""
	variable recent_dirs
	variable num_recent_dirs 	0
	variable most_recent_dirs 	-1
	variable max_recent_dirs 	5
	variable text_font		""
	variable title_font		""
	variable dialog_font		""
	variable general_font		""
	variable temp_recent_files	""
        variable top_width             900
        variable top_height            700
	for {set i 0} {$i<$max_recent_dirs } {incr i} {
		set recent_dirs($i) ""
	}
	variable tool_title		"SePCuT: SE Linux Policy Customization Tool"
	variable saveall_choice		""
	variable goto_line_num
	variable goto_cmd
	variable text_font		"fixed"
	variable searchString		""
	variable cur_srch_pos_length	0
	variable case_Insensitive	0
	variable regExpr 		0
	variable srch_Direction		"down"
	variable saveChanges_Dialog_ans
	variable tk_msgBox_Wait
	variable help_file		"${sepcut_install_dir}/sepcut_help.txt"
	variable read_only		0
	variable edit_mode_status	
	variable initial_edit_mode	1
	variable inital_policy_dir	""
	variable tmp_initial_policy_dir ""
	variable show_customize_file_names	0
	variable mainWindow
	set mainWindow .
	variable goto_Dialog
	variable notebook
	variable mainframe
	variable saveAll_Dialog
	set saveAll_Dialog .saveAll_Dialog
	variable helpDlg
	set helpDlg .helpDlg
	variable searchDlg
	set searchDlg .searchDlg	
	variable mod_FileNames_Dialog
	set mod_FileNames_Dialog .mod_FileNames_Dialog
	variable saveChanges_Dialog
	set saveChanges_Dialog .saveChanges_Dialog
	variable tool_settings_Dialog
	set tool_settings_Dialog .tool_settings_Dialog
	variable searchDlg_entryBox
	variable gotoDlg_entryBox
}
proc Sepct::get_tabname {tab} {	
	variable tabName_prefix
	set idx [string last ":" $tab]
	if {$idx != -1} {
		set tab [string range $tab 0 [expr $idx - 1]]
	}
	set prefix_len [string length $tabName_prefix]
	if {[string range $tab 0 $prefix_len] == $tabName_prefix} {
		return $tab
	}
	set tmp $tabName_prefix
	set idx [string first "_" $tab]
	if {$idx == -1} {
		return $tab
	}
	set tab_fixed [append tmp [string range $tab [expr $idx + 1] end]]
	return $tab_fixed
}
proc Sepct::writeConfigFile {config_file used_Modules unUsed_Modules} {
	set rt [catch {set f [open $config_file w+]} err]
	if {$rt != 0} {
		tk_messageBox -icon error -type ok -title "Error" \
			-message "$err"
		return
	}
	puts $f "\[Used_Modules\]"
	puts $f [llength $used_Modules]
	foreach used_mod $used_Modules {
		puts $f $used_mod
	}
	puts $f "\[Unused_Modules\]"
	puts $f [llength $unUsed_Modules]
	foreach unUsed_mod $unUsed_Modules {
		puts $f $unUsed_mod
	}
	close $f
	return 0
}
proc Sepct::save_Configuration {} {	
	set types {
		{"Policy config files"	{.pcfg}}
		{"All files"		*}
    	}
	set filename [tk_getSaveFile -initialdir $Sepct::policyDir \
		-title "Save Module Configuration As?" -filetypes $types \
		-defaultextension ".pcfg"]
	if { $filename != "" } {	
		Sepct_Customize::save_Configuration $filename
	}
	return 0
}
proc Sepct::load_Configuration {} {
	set filename ""
        set types {
		{"Policy config files"	{.pcfg}}
		{"All files"		*}
    	}
        set filename [tk_getOpenFile -filetypes $types -defaultextension ".pcfg" -initialdir $Sepct::policyDir]
        if {$filename != ""} {	
		if {[file exists $filename] == 0 } {
			tk_messageBox -icon error -type ok -title "Error" \
				-message "File: $filename does not exist."
			return
		}
		set rt [catch {set f [open $filename r]} err]
		if {$rt != 0} {
			tk_messageBox -icon error -type ok -title "Error" \
				-message "Cannot open $filename ($rt: $err)"
			return
		}
		set tag_found 0
		set config_error 0
		set used_Mods ""
		set unUsed_Mods ""
		set missing_used_mods ""
		set num_mods_counter 0
		set num_mods [Sepct_Customize::get_num_mods]
		gets $f line
		set tline [string trim $line]
		while {1} {
			if {[eof $f] && $tline == ""} {
				break
			}
			if {[string compare -length 1 $tline "#"] ==0 } {
				gets $f line
				set tline [string trim $line]
				continue
			}
			switch $tline {
				"[Used_Modules]" {
					if {$tag_found == 1} {
						puts "Key word \[Used_Modules\] found twice in file!"
						continue
					}
					set tag_found 1
					gets $f line
					set tline [string trim $line]
					if {[eof $f] == 1 && $tline == ""} {
						puts "EOF reached trying to read num of used modules."
						continue
					}
					if {[string is integer $tline] != 1} {
						set config_error 1
						puts "number of used modules was not given as an integer ($line) and is ignored"
						break
					} elseif {$tline < 0} {
						set config_error 1
						puts "number of used modules was less than 0 and is ignored"
						break
					}
					set num $tline
					for {set i 0} {$i<$num} {incr i} {
						gets $f line
						set tline [string trim $line]
						if {[eof $f] == 1 && $tline == ""} {
							set config_error 1
							puts "EOF reached trying to read used module: $num."
							break
						}
						if {$num_mods_counter > $num_mods} {
							break
						}
						if { [file extension $tline] == ".te" && [Sepct_Customize::is_in_modules_list $tline]} {
							lappend used_Mods $tline
							incr num_mods_counter
						} elseif { [file extension $tline] == ".te" && ![Sepct_Customize::is_in_modules_list $tline] } { 
							lappend missing_used_mods $tline
						} 
					}
					set tag_found 0
				}		
				"[Unused_Modules]" {
					if {$tag_found == 1} {
						puts "Key word \[Unused_Modules\] found twice in file!"
						continue
					}
					set tag_found 1
					gets $f line
					set tline [string trim $line]
					if {[eof $f] == 1 && $tline == ""} {
						puts "EOF reached trying to read num of unused modules."
						continue
					}
					if {[string is integer $tline] != 1} {
						set config_error 1
						puts "number of unused modules was not given as an integer ($line) and is ignored"
						break
					} elseif {$tline < 0} {
						set config_error 1
						puts "number of unused modules was less than 0 and is ignored"
						break
					}
					set num $tline
					for {set i 0} {$i<$num} {incr i} {
						gets $f line
						set tline [string trim $line]
						if {[eof $f] == 1 && $tline == ""} {
							set config_error 1
							puts "EOF reached trying to read unused module: $num."
							break
						}
						if {$num_mods_counter > $num_mods} {
							break
						}
						if { [file extension $tline] == ".te" && [Sepct_Customize::is_in_modules_list $tline]} {
							lappend unUsed_Mods $tline
							incr num_mods_counter
						} 
					}
					set tag_found 0
				}
				default {
					puts "Unrecognized line in $filename: $line"
				}
			}
			gets $f line
			set tline [string trim $line]
		}
		if { $config_error == 0 } {
			Sepct_Customize::load_policy_configuration $used_Mods $unUsed_Mods
			if { $missing_used_mods != "" } {
				Sepct::popup_missingModules_list $missing_used_mods [file tail $filename]
			}
		}
		close $f
	}
	return 0
}
proc Sepct::popup_missingModules_list {missing_used_mods config_filename} {
	set w .missingModules_listBox
	catch {destroy $w}
	toplevel $w 
	wm title $w "Missing Used Policy Modules"
	set sf [ScrolledWindow $w.sf  -scrollbar both -auto both]
	set f [text [$sf getframe].f -font {helvetica 10} -wrap none -width 40 -height 10]
	$sf setwidget $f
     	button $w.close -text Close -command "catch {destroy $w}" -width 10
     	$f insert end "Configuration file: $config_filename\n\n"
     	$f insert end "The following required modules were missing from \nthe policy directory:\n"
     	foreach mod $missing_used_mods {
     		$f insert end "\t$mod\n"
     	}
 	wm geometry $w +50+60
	pack $w.close -side bottom -anchor s -padx 5 -pady 5 
	pack $sf -fill both -expand yes
	return 0
}
proc Sepct::writeInitFile { } {
	variable dot_sepcut_file
	variable num_recent_dirs
	variable recent_dirs
	variable mainWindow
	variable text_font		
	variable title_font
	variable dialog_font
	variable general_font
	set rt [catch {set f [open $dot_sepcut_file w+]} err]
	if {$rt != 0} {
		tk_messageBox -icon error -type ok -title "Error" \
			-message "$err"
		return
	}
	puts $f "\[recent_dirs\]"
	puts $f $num_recent_dirs
	for {set i 0 } {$i < $num_recent_dirs} {incr i} {
		puts $f $recent_dirs($i)
	}
	puts $f "\[initial_edit_mode\]"
	puts $f $Sepct::initial_edit_mode
	puts $f "\[inital_policy_dir\]"
	puts $f $Sepct::inital_policy_dir
	puts $f "\[show_customize_file_names\]"
	puts $f $Sepct::show_customize_file_names
	puts $f "\n"
	puts $f "# Font format: family ?size? ?style? ?style ...?"
	puts $f "# Possible values for the style arguments are as follows:"
	puts $f "# normal bold roman italic underline overstrike\n#\n#"
	puts $f "# NOTE: When configuring fonts, remember to remove the following "
	puts $f "# \[window height\] and \[window width\] entries before starting apol. "
	puts $f "# Not doing this may cause widgets to be obscured when running apol."
	puts $f "\[general_font\]"
	if {$general_font == ""} {
		puts $f "Helvetica 10"
	} else {
		puts $f "$general_font" 
	}
	puts $f "\[title_font\]"
	if {$title_font == ""} {
		puts $f "Helvetica 10 bold italic"
	} else {
		puts $f "$title_font"  
	}
	puts $f "\[dialog_font\]"
	if {$dialog_font == ""} {
		puts $f "Helvetica 10"
	} else {
		puts $f "$dialog_font"
	}
	puts $f "\[text_font\]"
	if {$text_font == ""} {
		puts $f "fixed"
	} else {
		puts $f "$text_font"
	}
        puts $f "\[window_height\]"
        puts $f [winfo height $mainWindow]
        puts $f "\[window_width\]"
        puts $f [winfo width $mainWindow]
	close $f
	return 0
}
proc Sepct::readInitFile { } {
	variable dot_sepcut_file
	variable max_recent_dirs 
	variable recent_dirs
	variable recent_dirs_tmp_list
	variable text_font		
	variable title_font
	variable dialog_font
	variable general_font
	variable top_height
        variable top_width
	if {[file exists $dot_sepcut_file] == 0 } {
		return
	}
	set rt [catch {set f [open $dot_sepcut_file]} err]
	if {$rt != 0} {
		tk_messageBox -icon error -type ok -title "Error" \
			-message "Cannot open .sepcut file ($rt: $err)"
		return
	}
	set got_recent 0
	gets $f line
	set tline [string trim $line]
	while {1} {
		if {[eof $f] && $tline == ""} {
			break
		}
		if {[string compare -length 1 $tline "#"] == 0 || [string is space $tline]} {
			gets $f line
			set tline [string trim $line]
			continue
		}
		switch $tline {
			"[max_recent_dirs]" {
				if {$got_recent == 1 } {
					puts "Key word max_recent_dirs found after recent directory names read; ignored"
					gets $ line
					continue
				}
				gets $f line
				set tline [string trim $line]
				if {[eof $f] == 1 && $tline == ""} {
					puts "EOF reached trying to read max_recent_dirs."
					continue
				}
				if {[string is integer $tline] != 1} {
					puts "max_recent_dirs was not given as an integer ($line) and is ignored"
				} else {
					if {$tline>10} {
						set max_recent_dirs 10
					} elseif {$tline < 2} {
						set max_recent_dirs 2
					}
					else {
						set max_recent_dirs $tline
					}
				}
			}
			"[recent_dirs]" {
				if {$got_recent == 1} {
					puts "Key word recent_dirs found twice in file!"
					continue
				}
				set got_recent 1
				gets $f line
				set tline [string trim $line]
				if {[eof $f] == 1 && $tline == ""} {
					puts "EOF reached trying to read num of recent directories."
					continue
				}
				if {[string is integer $tline] != 1} {
					puts "number of recent directories was not given as an integer ($line) and is ignored"
					break
				} elseif {$tline < 0} {
					puts "number of recent directories was less than 0 and is ignored"
					break
				}
				set num $tline
				for {set i 0} {$i<$num} {incr i} {
					gets $f line
					set tline [string trim $line]
					if {[eof $f] == 1 && $tline == ""} {
						puts "EOF reached trying to read recent directory name $num."
						break
					}
					if {$i >= $max_recent_dirs} {
						continue
					}
					lappend recent_dirs_tmp_list $tline
				}
			}
			"[initial_edit_mode]" {
				gets $f line
				set tline [string trim $line]
				if {[eof $f] == 1 && $tline == ""} {
					puts "EOF reached trying to read \[initial_edit_mode\] value at line: $line."
					break
				}
				if {[string is integer $tline] != 1} {
					puts "\[initial_edit_mode\] value was not given as an integer ($line) and is ignored"
					break
				} 
				set Sepct::initial_edit_mode $tline	
			}
			"[inital_policy_dir]" {
				gets $f line
				set tline [string trim $line]
				if {[eof $f] == 1 && $tline == ""} {
					puts "EOF reached trying to read \[inital_policy_dir\] value at line: $line."
					break
				}
				if {$tline != "" && [file isdirectory $tline] != 1} {
					puts "\[inital_policy_dir\] value ($line) is not a directory and is ignored"
					break
				} 
				set Sepct::inital_policy_dir $tline
			}
			"[show_customize_file_names]" {
				gets $f line
				set tline [string trim $line]
				if {[eof $f] == 1 && $tline == ""} {
					puts "EOF reached trying to read \[show_customize_file_names\] value at line: $line."
					break
				}
				if {[string is integer $tline] != 1} {
					puts "\[show_customize_file_names\] was not given as an integer ($line) and is ignored"
					break
				} 
				set Sepct::show_customize_file_names $tline
			}
			"\[window_height\]" {
			        gets $f line
			        set tline [string trim $line]
			        if {[eof $f] == 1 && $tline == ""} {
				    puts "EOF reached trying to read window_height."
			   	    continue
			        }
			        if {[string is integer $tline] != 1} {
				    puts "window_height was not given as an integer ($line) and is ignored"
				    break
			        }
			        set top_height $tline
			}
		        "\[window_width\]" {
			        gets $f line
			        set tline [string trim $line]
			        if {[eof $f] == 1 && $tline == ""} {
				    puts "EOF reached trying to read window_width."
				    continue
			        }
			        if {[string is integer $tline] != 1} {
				    puts "window_width was not given as an integer ($line) and is ignored"
				    break
			        }
			        set top_width $tline
			}
		        "\[title_font\]" {
				gets $f line
				set tline [string trim $line]
				if {[eof $f] == 1 && $tline == ""} {
					puts "EOF reached trying to read title font."
					continue
				}
				set title_font $tline
			}
			"\[dialog_font\]" {
				gets $f line
				set tline [string trim $line]
				if {[eof $f] == 1 && $tline == ""} {
					puts "EOF reached trying to read dialog font."
					continue
				}
				set dialog_font $tline
			}
			"\[text_font\]" {
				gets $f line
				set tline [string trim $line]
				if {[eof $f] == 1 && $tline == ""} {
					puts "EOF reached trying to read text font."
					continue
				}
				set text_font $tline
			}
			"\[general_font\]" {
				gets $f line
				set tline [string trim $line]
				if {[eof $f] == 1 && $tline == ""} {
					puts "EOF reached trying to read general font."
					continue
				}
				set general_font $tline
			}
			default {
				puts "Unrecognized line in .sepcut: $line"
			}
		}
		gets $f line
		set tline [string trim $line]
	}
	close $f	
	return
}
proc Sepct::addRecent {dir} {
	variable mainframe
	variable recent_dirs
	variable num_recent_dirs
    	variable max_recent_dirs
    	variable most_recent_dirs
    	if {$num_recent_dirs<$max_recent_dirs} {
    		set x $num_recent_dirs
    		set less_than_max 1
    	} else {
    		set x $max_recent_dirs 
    		set less_than_max 0
    	}
    	set dir [string trimright $dir "/"]
	for {set i 0} {$i<$x} {incr i} {
		if {[string equal $dir $recent_dirs($i)]} {
			return
		}
	}
	if {$num_recent_dirs<$max_recent_dirs} {
		set recent_dirs($num_recent_dirs) $dir
		[$mainframe getmenu recent] insert 0 command -label "$recent_dirs($num_recent_dirs)" -command "Sepct::open_recent_dir $recent_dirs($num_recent_dirs) 0"
		set most_recent_dirs $num_recent_dirs
		incr num_recent_dirs
	} else {
		if {$most_recent_dirs != 0} {
			set oldest [expr $most_recent_dirs - 1]
		} else {
			set oldest [expr $max_recent_dirs - 1]
		}
		[$mainframe getmenu recent] delete $recent_dirs($oldest)
		set recent_dirs($oldest) $dir
		[$mainframe getmenu recent] insert 0 command -label "$recent_dirs($oldest)" -command "Sepct::open_recent_dir $recent_dirs($oldest) 0"
		set most_recent_dirs $oldest
	}	
	return	
}
proc Sepct::open_recent_dir {policyDir recent_flag} {
	set rt [Sepct::closePolicy]
	if { $rt != 0 } {
		return -1
	}		
	set rt [Sepct::openPolicyDir $policyDir $recent_flag]
	return 0
}
proc Sepct::isPolicyOpened {} {
	return $Sepct::policyOpened
}
proc Sepct::inReadOnlyMode  {} {
	return $Sepct::read_only
}
proc Sepct::DisplayEditMode  {} {
	variable edit_mode_status
	variable read_only
	if {$read_only} {
		set edit_mode_status "read-only"
	} else {
		set edit_mode_status "edit mode"
	}
	return 0
}
proc Sepct::enableAllModules {} {
	variable notebook
	if { [Sepct::inReadOnlyMode] } {
		return 0
	}
	set raisedPage [$notebook raise]
	if { $raisedPage == $Sepct::customize_tab } {
		set rt [Sepct_Customize::select_all_CheckButtons]
		return $rt
	}
	return 0
}
proc Sepct::addModule {} {
	variable notebook
	if { [Sepct::inReadOnlyMode] } {
		return 0
	}
	set raisedPage [$notebook raise]
	if { $raisedPage == $Sepct::customize_tab } {
		set rt [Sepct_Customize::add_Module]
		return $rt
	}
	return 0
}
proc Sepct::deleteModule  {} {
	variable notebook
	if { [Sepct::inReadOnlyMode] } {
		return 0
	}
	set raisedPage [$notebook raise]
	if { $raisedPage == $Sepct::customize_tab } {
		set rt [Sepct_Customize::delete_Module]
		return $rt
	}
	return 0
}
proc Sepct::ToggleEditMode  {} {
	variable read_only
	variable notebook
	if {$read_only} {
		set read_only 0
		$Sepct::mainframe setmenustate ModEditTag normal
		if {[$notebook raise] != ""} {
			[$notebook raise]::enter_Tab
		}
	} else {
		set read_only 1
		$Sepct::mainframe setmenustate ModEditTag disabled
	}
	Sepct::DisplayEditMode
	return 0
}
proc Sepct::isValidPolicyDir { policyDir parentDlg } {
	if { [file isdirectory $policyDir] != 1} {
		tk_messageBox -icon error \
			-parent $parentDlg \
			-type ok -title "Invalid Directory" \
			-message \
			"Given policy directory is not a directory."
		return 0
	}
	if { [file readable $policyDir] != 1} {
		tk_messageBox -icon error \
			-parent $parentDlg \
			-type ok -title "Directory Permission Problem" \
			-message \
			"You do not have permission to access this directory."
		return 0
	}
	set make_exists [expr ([file exists "$policyDir/Makefile"] || [file exists "$policyDir/makefile"] )]
	if { $make_exists != 1 } {
		tk_messageBox -icon error \
			-parent $parentDlg \
			-type ok  \
			-title "Invalid Policy Directory" \
			-message "Selected directory does not appear to be a valid policy directory\n\n\
			Cannot locate Makefile"
		return 0
	}
	if { [file isdirectory "$policyDir/domains/program"] != 1 } {
		return 2
	}
	return 1
}
proc Sepct::aboutBox {} {
     variable gui_ver
     variable copyright_date
     tk_messageBox \
     	     -parent $Sepct::mainWindow \
	     -icon info \
	     -type ok \
	     -title "About" \
	     -message \
		"SE Linux Policy Customization Tool\n\nCopyright\
		(c) $copyright_date\nTresys Technology, LLC\nwww.tresys.com/selinux\n\nVersion $gui_ver"
     return
}
proc Sepct::helpDlg {} {
	variable help_file
	variable helpDlg
	if { [winfo exists $helpDlg] } {
		raise $helpDlg
		return
	}
	toplevel $helpDlg
	wm protocol $helpDlg WM_DELETE_WINDOW "destroy $helpDlg"
	wm withdraw $helpDlg
	wm title $helpDlg "Help"
	set hbox [frame $helpDlg.hbox ]
	set sw [ScrolledWindow $hbox.sw -auto none]
	set resultsbox [text [$sw getframe].text -bg white -wrap none -font $Sepct::text_font]
	$sw setwidget $resultsbox
	set okButton [Button $hbox.okButton -text "OK" \
		      -command "destroy $helpDlg"]
	if { [file readable "./sepcut_help.txt"] } {
		set hfile "./sepcut_help.txt"
	} elseif { [file readable $help_file] } {
		set hfile $help_file
	} else {
		set hfile ""
	}
	pack $hbox -expand yes -fill both -padx 5 -pady 5
	pack $okButton -side bottom
	pack $sw -side left -expand yes -fill both 
	::tk::PlaceWindow $helpDlg widget center
	wm deiconify $helpDlg
	$resultsbox delete 1.0 end
	if { $hfile != "" } {
		set f [open $hfile]
		$resultsbox insert end [read $f]
		close $f
	} else {
		$resultsbox insert end "Help file could not be found!"
	}
	$resultsbox configure -state disabled
    	return 0
}
proc Sepct::closePolicyDir { } {
	variable policyDir
	variable policyOpened
	variable disable_customize_tab
	variable disable_test_tab
	Sepct::record_outstanding_changes
	set canceled [Sepct::checkAndSaveChanges]
	if {$canceled < 0 } {
		return -1
	} elseif { $canceled } {
		return 1
	}
	Sepct_Browse::close
	if { !$disable_customize_tab } {
		Sepct_Customize::close
	}
	Sepct_Test::close
	set policyDir ""		
	set policyOpened 0
	Sepct::change_tab_state $Sepct::notebook $Sepct::customize_tab enable
	Sepct::change_tab_state $Sepct::notebook $Sepct::test_tab enable
	set disable_customize_tab 0
	set disable_test_tab 0
	return 0
}
proc Sepct::reloadPolicy {} {
	variable policyOpened
	variable policyDir
	variable notebook
	if { !$policyOpened } {
		return 0
	}
	set curr_dir $policyDir
	set rt [Sepct::closePolicy]
	if {$rt != 0 } {
		return 0
	}
	set rt [Sepct::openPolicyDir $curr_dir 0]
	return $rt
}
proc Sepct::closePolicy { } {
	variable mainframe 
	variable notebook
	if { ![Sepct::isPolicyOpened] } {
		return 0
	}
	set rt [Sepct::closePolicyDir]
	if {$rt == 1 } {
		if {[$notebook raise] != ""} {
			[$notebook raise]::enter_Tab
		}
		return -1
	}
	Sepct::clear_fileStatus
	Sepct::setTitleName ""
    	$mainframe setmenustate DisableOnCloseTag disabled
	return 0
}
proc Sepct::revert {} {
	variable notebook
	[$notebook raise]::revert_file
	return 0
}
proc Sepct::show_ModFileNames { } {
	Sepct::record_outstanding_changes
	Sepct::display_mod_FileNames_Dialog
	return 0
}
proc Sepct::display_mod_FileNames_Dialog { } {
	variable mod_FileNames_Dialog	
	variable mainWindow
    	if { [winfo exists $mod_FileNames_Dialog] } {
    		raise $mod_FileNames_Dialog
    		return 
    	}
	toplevel $mod_FileNames_Dialog
	wm protocol $mod_FileNames_Dialog WM_DELETE_WINDOW "destroy $mod_FileNames_Dialog"
	wm withdraw $mod_FileNames_Dialog
	wm title $mod_FileNames_Dialog "Modified Files"
	set frame_a [frame $mod_FileNames_Dialog.frame_a]	
	set f_inner [ScrolledWindow $frame_a.f_inner -auto none]
	pack $frame_a $f_inner -fill both -expand yes
	set lbx_mod_FileNames   [listbox [$f_inner getframe].lbx_mod_FileNames -height 10 -width 50 \
				-highlightthickness 0 \
				-listvar Sepct_db::mod_FileNames ] 
	$f_inner setwidget $lbx_mod_FileNames
	set closeButton [Button $frame_a.closeButton -text "Close" \
		      -command "destroy $mod_FileNames_Dialog"]
	pack $closeButton -side bottom -anchor center -pady 5
	::tk::PlaceWindow $mod_FileNames_Dialog widget center
	wm deiconify $mod_FileNames_Dialog
	return 0
}
proc Sepct::display_saveChanges_Dialog { } {	
	variable saveChanges_Dialog
	global tcl_platform
    	if { [winfo exists $saveChanges_Dialog] } {
    		destroy $saveChanges_Dialog 
    	}
	toplevel $saveChanges_Dialog
	wm protocol $saveChanges_Dialog WM_DELETE_WINDOW "destroy $saveChanges_Dialog"
	wm withdraw $saveChanges_Dialog
	wm title $saveChanges_Dialog "Save unchanged modifications?"
	set inner_f [frame $saveChanges_Dialog.inner_f]
    	set inner_f1 [frame $saveChanges_Dialog.inner_f1]
    	set inner_f2 [frame $saveChanges_Dialog.inner_f2]
    	set lbl_save  [label $inner_f1.lbl_save -image [Bitmap::get question]]
    	set lbl_save2  [label $inner_f2.lbl_save2 -text "There are unsaved changes to at least one policy file.\n\Do you want to save changes?" \
    			-font {Helvetica 11}]
    	set b_yes [button $inner_f.b_yes -text "Yes" -width 6 -command {set Sepct::saveChanges_Dialog_ans yes; destroy $Sepct::saveChanges_Dialog} -font {Helvetica 11}]
	set b_no [button $inner_f.b_no -text "No" -width 6 -command {set Sepct::saveChanges_Dialog_ans no; destroy $Sepct::saveChanges_Dialog} -font {Helvetica 11}]
	set b_discard [button $inner_f.b_discard -text "Discard All" -command {set Sepct::saveChanges_Dialog_ans discard; destroy $Sepct::saveChanges_Dialog} -font {Helvetica 11}]
	set b_cancel [button $inner_f.b_cancel -text "Cancel" -width 6 -command {set Sepct::saveChanges_Dialog_ans cancel; destroy $Sepct::saveChanges_Dialog} -font {Helvetica 11}]
	set b_show [button $inner_f.b_show -text "Show Files" -command {Sepct::show_ModFileNames} -font {Helvetica 11}]
	pack $inner_f -side bottom -anchor nw
	pack $inner_f1 -side left -anchor n  -pady 10
	pack $inner_f2 -side left -anchor n -pady 10
	pack $lbl_save -side left -anchor center -padx 10
	pack $lbl_save2 -side left -anchor center 
	pack $b_yes $b_no $b_discard $b_cancel $b_show -side left -anchor center -padx 2
	::tk::PlaceWindow $saveChanges_Dialog widget center
	wm deiconify $saveChanges_Dialog
	if {$tcl_platform(platform) == "windows"} {
		wm resizable $Sepct::::saveChanges_Dialog 0 0
	} else {
		bind $Sepct::::saveChanges_Dialog <Configure> { wm geometry $Sepct::::saveChanges_Dialog {} }
	}
	vwait Sepct::saveChanges_Dialog_ans 
	return 0
}
proc Sepct::checkAndSaveChanges { } {
	variable saveChanges_Dialog_ans
	if { [Sepct_db::are_there_mod_files] } {
		Sepct::display_saveChanges_Dialog
		switch $saveChanges_Dialog_ans {
			no {	
				return 0
			}
			yes {
				set rt [Sepct::save_all] 
				return $rt
			}
			discard {
				set rt [Sepct_db::discard_All_File_Changes] 
				return $rt
			}
			default {
				return 1
			}
		}		
	} else {
		return 0
	}
}
proc Sepct::display_saveAll_Dialog { path } {
	variable saveAll_Dialog	
	variable mainWindow
	global tcl_platform
    	if { [winfo exists $saveAll_Dialog] } {
    		destroy $saveAll_Dialog 
    	}
	toplevel $saveAll_Dialog
	wm protocol $saveAll_Dialog WM_DELETE_WINDOW "destroy $saveAll_Dialog"
	wm withdraw $saveAll_Dialog
	wm title $saveAll_Dialog "Save Changes?"
	set inner_f  [frame $saveAll_Dialog.inner_f]
    	set inner_f1 [frame $saveAll_Dialog.inner_f1]
    	set inner_f2 [frame $saveAll_Dialog.inner_f2]
    	set lbl_save   [label $inner_f1.lbl_save -image [Bitmap::get question]]
    	set lbl_save2  [label $inner_f2.lbl_save -text "Save changes to $path?" \
    			-font {Helvetica 11}]
    	set b_yes [button $inner_f.b_yes -text "Yes" -width 6 -command {set Sepct::saveall_choice "Yes"; destroy $Sepct::saveAll_Dialog} -font {Helvetica 11}]
	set b_no [button $inner_f.b_no -text "No" -width 6 -command {set Sepct::saveall_choice "No"; destroy $Sepct::saveAll_Dialog} -font {Helvetica 11}]
	set b_discard [button $inner_f.b_discard -text "Discard" -command {set Sepct::saveall_choice "Discard"; destroy $Sepct::saveAll_Dialog} -font {Helvetica 11}]
	set b_cancel [button $inner_f.b_cancel -text "Cancel" -width 6 -command {set Sepct::saveall_choice "Cancel"; destroy $Sepct::saveAll_Dialog} -font {Helvetica 11}]
	set b_show [button $inner_f.b_show -text "ShowFiles" -command {Sepct::show_ModFileNames} -font {Helvetica 11}]
	set b_discard_all [button $inner_f.b_discard_all -text "Discard All" -command {set Sepct::saveall_choice "Discard All"; destroy $Sepct::saveAll_Dialog} -font {Helvetica 11}]
	set b_no_all [button $inner_f.b_no_all -text "No to All" -width 6 -command {set Sepct::saveall_choice "No to All"; destroy $Sepct::saveAll_Dialog} -font {Helvetica 11}]
	set b_save_all [button $inner_f.b_save_all -text "Save All" -width 6 -command {set Sepct::saveall_choice "Save All"; destroy $Sepct::saveAll_Dialog} -font {Helvetica 11}]
	pack $inner_f -side bottom -anchor nw
	pack $inner_f1 -side left -anchor n  -pady 10 
	pack $inner_f2 -side left -anchor n -pady 10 
	pack $lbl_save -side left -anchor center -padx 20 
	pack $lbl_save2 -side left -anchor center -expand yes -padx 5 -pady 10
	pack $b_yes $b_no $b_discard $b_save_all $b_no_all $b_discard_all $b_cancel $b_show -side left -anchor center -padx 2
	::tk::PlaceWindow $saveAll_Dialog widget center
	wm deiconify $saveAll_Dialog
	if {$tcl_platform(platform) == "windows"} {
		wm resizable $Sepct::::saveAll_Dialog 0 0
	} else {
		bind $Sepct::::saveAll_Dialog <Configure> { wm geometry $Sepct::::saveAll_Dialog {} }
	}
	vwait Sepct::saveall_choice
	return 0
}
proc Sepct::save_allFiles {} {
	set mod_File_Paths [Sepct_db::getModFileNames]
	foreach path $mod_File_Paths {
		set rt [Sepct_db::saveFile $path ]
		if { $rt == -1 } {
			puts stderr "Unexpected error in saving file $path in save_allFiles"
			# just keep going!!!
		}
	}
	return 0
}
proc Sepct::record_outstanding_changes { } {
	variable disable_customize_tab
	Sepct_Browse::record_outstanding_changes 
	if {!$disable_customize_tab} {
		Sepct_Customize::record_outstanding_changes 
	}
	return 0
}
proc Sepct::save_all { } {
	variable save_Dialog	
	variable mainWindow
	variable notebook
	variable saveall_choice
	Sepct::record_outstanding_changes
	set mod_File_Paths [Sepct_db::getModFileNames]
    	if { $mod_File_Paths != "" } {
		foreach mod_file $mod_File_Paths {
			Sepct::display_saveAll_Dialog $mod_file
			switch $saveall_choice {
				"Yes" {	
					Sepct_db::saveFile $mod_file
					continue
				}
				"No" {
					# don't do anything with the file; in particular, don't revert it!
					continue
				}
				"Discard" {
					Sepct_db::discard_Single_File_Changes $mod_file
					continue
				}
				"Save All" {
					Sepct::save_allFiles
					break
				}
				"No to All" {
					# don't do anything with the files; in particular, don't revert them!
					break
				}
				"Discard All" {
					set canceled [Sepct_db::discard_All_File_Changes]
					break
				}
				default {
					return 1
				}
			}		
		}
	}  
	if {[$notebook raise] != ""} {
		[$notebook raise]::enter_Tab
	}
	return 0
}
proc Sepct::exitApp {} {
	set rt [Sepct::save_all]
	if { $rt == 1 } {
		return 1
	}
	Sepct::closePolicy
	Sepct_db::close
	Sepct::writeInitFile
	exit
}
proc Sepct::display_searchDlg {} {
	variable searchDlg
	variable searchDlg_entryBox
	global tcl_platform
	if { [winfo exists $searchDlg] } {
		raise $searchDlg
		focus $searchDlg_entryBox
		$searchDlg_entryBox selection range 0 end
		return 0
	}
	toplevel $searchDlg
	wm protocol $searchDlg WM_DELETE_WINDOW "destroy $searchDlg"
	wm withdraw $searchDlg
	wm title $searchDlg "Search"
	if {$tcl_platform(platform) == "windows"} {
		wm resizable $Sepct::searchDlg 0 0
	} else {
		bind $Sepct::searchDlg <Configure> { wm geometry $Sepct::searchDlg {} }
	}
	set sbox [frame $searchDlg.sbox]
	set lframe [frame $searchDlg.lframe]
	set rframe [frame $searchDlg.rframe]
	set lframe_top [frame $lframe.lframe_top]
	set lframe_bot [frame $lframe.lframe_bot]
	set lframe_bot_left [frame $lframe_bot.lframe_bot_left]
	set lframe_bot_right [frame $lframe_bot.lframe_bot_right]
	set lbl_entry [label $lframe_top.lbl_entry -text "Find What:"]
	set searchDlg_entryBox [entry $lframe_top.searchDlg_entryBox -bg white -font $Sepct::text_font -textvariable Sepct::searchString ]
	set b_findNext [button $rframe.b_findNext -text "Find Next" \
		      -command { Sepct::search }]
	set b_cancel [button $rframe.b_cancel -text "Cancel" \
		      -command "destroy $searchDlg"]
	set cb_case [checkbutton $lframe_bot_left.cb_case -text "Case Insensitive" -variable Sepct::case_Insensitive]
	set cb_regExpr [checkbutton $lframe_bot_left.cb_regExpr -text "Regular Expressions" -variable Sepct::regExpr]
	set directionBox [TitleFrame $lframe_bot_right.directionBox -text "Direction" ]
	set dir_up [radiobutton [$directionBox getframe].dir_up -text "Up" -variable Sepct::srch_Direction \
			 -value up ]
    	set dir_down [radiobutton [$directionBox getframe].dir_down -text "Down" -variable Sepct::srch_Direction \
			 -value down ]
	pack $sbox -expand yes -fill both -padx 5 -pady 5
	pack $lframe -expand yes -fill both -padx 5 -pady 5 -side left
	pack $rframe -expand yes -fill both -padx 5 -pady 5 -side right
	pack $lframe_top -expand yes -fill both -padx 5 -pady 5 -side top
	pack $lframe_bot -expand yes -fill both -padx 5 -pady 5 -side bottom
	pack $lframe_bot_left -expand yes -fill both -padx 5 -pady 5 -side left 
	pack $lframe_bot_right -expand yes -fill both -padx 5 -pady 5 -side right
	pack $lbl_entry -expand yes -fill both -side left 
	pack $searchDlg_entryBox -expand yes -fill both -side right
	pack $b_findNext $b_cancel -side top -expand yes -fill x
	pack $cb_case $cb_regExpr -expand yes -side top -anchor nw
	pack $directionBox -side left -expand yes -fill both
	pack $dir_up $dir_down -side left -anchor center 
	::tk::PlaceWindow $searchDlg widget center
	wm deiconify $searchDlg
	focus $searchDlg_entryBox 
	$searchDlg_entryBox selection range 0 end
	bind $Sepct::searchDlg <Return> { Sepct::search }
	return 0
}	
proc Sepct::textSearch { w str case_Insensitive regExpr srch_Direction } {
	if {$str == ""} {
		return 0
	}
	set case_opt " "
	set regExpr_opt " "
	set direction_opt " "
	if { $case_Insensitive } {
		set case_opt "-nocase"
	}
	if { $regExpr } {
		set regExpr_opt "-regexp"
	}
	if { $srch_Direction == "down" } {
		set direction_opt "-forward"
		set cur_srch_pos [$w index insert]
	} else {
		set direction_opt "-backward"
		set cur_srch_pos [lindex [$w tag ranges sel] 0]
	}
	if { $cur_srch_pos == "" } {
		set cur_srch_pos "1.0"
	}
	$w tag remove sel 0.0 end
	set cmd "$w search -count cur_srch_pos_length $case_opt $regExpr_opt $direction_opt"
	set rt [catch {set cur_srch_pos [eval $cmd {"$str"} $cur_srch_pos] } err]
	if { $rt != 0 } {
		tk_messageBox -icon error -type ok -title "Search Error" -message \
				"$err"
		return -1
	}
	if { $cur_srch_pos == "" } {
		set Sepct::tk_msgBox_Wait  \
			[tk_messageBox -parent $Sepct::searchDlg -icon warning -type ok -title "Search Failed" -message \
					"Search string not found!"]
		vwait Sepct::tk_msgBox_Wait
	} else {	
		$w mark set insert "$cur_srch_pos + $cur_srch_pos_length char"
		$w tag add sel $cur_srch_pos "$cur_srch_pos + $cur_srch_pos_length char"
		$w see $cur_srch_pos
	}
	return 0
}
proc Sepct::search {} {
	variable notebook
	variable searchString
	variable case_Insensitive	
	variable regExpr 		
	variable srch_Direction
	[$notebook raise]::search $searchString $case_Insensitive $regExpr $srch_Direction
	return 0
}
proc Sepct::save {} {
	variable notebook
	[$notebook raise]::save
	return 0
}
proc Sepct::save_as {} {
	variable notebook
	[$notebook raise]::save_as
	return 0
}
proc Sepct::goto_line { } {
	variable notebook
	variable goto_line_num
	variable goto_cmd
	variable goto_Dialog
	variable gotoDlg_entryBox
	global tcl_platform
	set goto_Dialog .goto_Dialog
    	if { [winfo exists $goto_Dialog] } {
    		raise $goto_Dialog
    		focus $gotoDlg_entryBox
    		return 0
    	}
    	toplevel $goto_Dialog
   	wm protocol $goto_Dialog WM_DELETE_WINDOW "destroy $goto_Dialog"
    	wm withdraw $goto_Dialog
    	wm title $goto_Dialog "Goto"
    	if {$tcl_platform(platform) == "windows"} {
		wm resizable $Sepct::goto_Dialog 0 0
	} else {
		bind $Sepct::goto_Dialog <Configure> { wm geometry $Sepct::goto_Dialog {} }
	}
    	set goto_line_num ""
    	set goto_cmd "[$notebook raise]::goto_line"
	set gotoDlg_entryBox [entry $goto_Dialog.gotoDlg_entryBox -textvariable Sepct::goto_line_num -width 10 ]
	set lbl_goto  [label $goto_Dialog.lbl_goto -text "Goto:"]
	set b_ok      [button $goto_Dialog.ok -text "OK" -width 6 -command { $Sepct::goto_cmd [string trim $Sepct::goto_line_num]; destroy $Sepct::goto_Dialog}]
	set b_cancel  [button $goto_Dialog.cancel -text "Cancel" -width 6 -command { destroy $Sepct::goto_Dialog }]
	pack $lbl_goto $gotoDlg_entryBox -side left -padx 5 -pady 5 -anchor nw
	pack $b_ok $b_cancel -side left -padx 5 -pady 5 -anchor ne
    	::tk::PlaceWindow $goto_Dialog widget center
	wm deiconify $goto_Dialog
	focus $gotoDlg_entryBox
	bind $Sepct::goto_Dialog <Return> { $Sepct::goto_cmd $Sepct::goto_line_num; destroy $Sepct::goto_Dialog }
	return 0	
}
proc Sepct::loadPolicy {} {
	variable disable_customize_tab
	variable policyDir
	set rt [Sepct_Browse::initialize $policyDir]
	if { $rt != 0 } {
		tk_messageBox \
		     -icon error \
		     -type ok \
		     -title "Initialize Error" \
		     -message \
			"There was an error configuring the widgets for the Browser tab"
		return -1
	}
	if {!$disable_customize_tab} {
		set rt [Sepct_Customize::initialize $policyDir]
		if { $rt != 0 } {
			tk_messageBox \
			     -icon error \
			     -type ok \
			     -title "Initialize Error" \
			     -message \
				"There was an error configuring the widgets for the Customizer tab"
			return -1
		}
	}
	set rt [Sepct_Test::initialize ]
	if { $rt != 0 } {
		tk_messageBox \
		     -icon error \
		     -type ok \
		     -title "Initialize Error" \
		     -message \
			"There was an error configuring the widgets for the Test tab"
		return -1
	}
	return 0    		
}
proc Sepct::setTitleName { { name ""} } {
	variable tool_title
	if {$name != "" } {
		set tname "$tool_title - $name"
	} else {
		set tname $tool_title
	}
	wm title $Sepct::mainWindow $tname
   	return 0
}
proc Sepct::update_positionStatus { pos } { 
	variable line_info
	if { [catch {scan $pos" %d.%d" line col} err ] } {
		puts stderr "update_positionStatus: Problem scanning position ($pos): $err"
		return -1
	}
	set line_info "Ln: $line, Col: $col"
	return 0
}
proc Sepct::clear_fileStatus { } {
	variable file_name
	variable file_modTime
	variable file_size
	variable line_info
	set file_name ""
	set file_modTime ""
	set file_size ""
	set line_info ""
	return 0
}
proc Sepct::switch_tab { tabID } {
	variable notebook
	variable mainframe
	set tabID [Sepct::get_tabname $tabID]
	set raisedPage [$notebook raise]
	if { $raisedPage == $tabID } {
    		return 0
    	}
    	if {$raisedPage != ""} {
 		${raisedPage}::leave_Tab
 	}
	if {[$notebook itemcget $tabID -state] == "disabled"} {
		return 
	}
    	Sepct::clear_fileStatus
	${tabID}::enter_Tab
 	if { $tabID == $Sepct::browse_tab } {
		$mainframe setmenustate AddTag disabled
		$mainframe setmenustate DeleteTag disabled
	} elseif { $tabID == $Sepct::customize_tab } {
		$mainframe setmenustate AddTag normal
		$mainframe setmenustate DeleteTag normal
	} elseif { $tabID== $Sepct::test_tab } {
		$mainframe setmenustate AddTag disabled
		$mainframe setmenustate DeleteTag disabled
	} else {
		puts stderr "update_Widgets had an unexpected error on new tab id ($pageID)...exiting"
		exit
	}
	$Sepct::notebook raise $tabID
	return 0
}
proc Sepct::update_fileStatus { fn {do_pos 0 }} {
	variable policyDir
	set sz [string length $policyDir] 
	if {[string length $fn] >= $sz && [string compare -length $sz $policyDir $fn] == 0 } {
		set relativePath [string replace $fn 0 [expr $sz - 1]]
		set Sepct::file_name ".$relativePath"
	} else {
		set Sepct::file_name $fn 
	}
	if { [catch {set Sepct::file_modTime [clock format [file mtime $fn] -format "%b %d, %Y %I:%M:%S %p"  -gmt 0]} err] } {
		puts stderr "Problem getting file mod time for $fn: $err"
		set Sepct::file_modTime "????"
	}
	if { [catch {set Sepct::file_size  "Sz: [file size $fn]"} err ] } {
		puts stderr "Prolem getting file size for $fn: $err"
		set Sepct::file_size "????"
	}
	if { $do_pos } {
		set pos [Sepct_db::get_pos $fn]
		if { $pos == "" } {
			puts stderr "update_fileStatus: Error getting position info for $fn" 
		} else {
	    		Sepct::update_positionStatus $pos
	    	}
	}
    	return 0
}
proc Sepct::change_tab_state { nb tab cmd } {
	if {$cmd == "disable" } {
		$nb itemconfigure  $tab -state disabled
	} else {
		$nb itemconfigure  $tab -state normal
	}
	return 0
}
proc Sepct::openPolicyDir { policyDir recent_flag } {
	variable disable_customize_tab
	variable disable_test_tab
	variable notebook
	variable mainframe
	if {$policyDir != ""} {
		set Sepct::policyDir [file nativename $policyDir]
		set dir_type [Sepct::isValidPolicyDir $policyDir $Sepct::mainWindow]
		if { $dir_type } {
			if { $dir_type == 1 } {
				set disable_customize_tab 0
			} else {
				tk_messageBox \
				     -icon warning \
				     -parent $Sepct::mainWindow \
				     -type ok \
				     -title "Disabling Tabs" \
				     -message \
					"The policy directory does not appear to be configured for customization (i.e., there\
					is no policy/domains/program directory).  \n\nThe cause may be that you are opening an older\
					policy directory or a non-conventional policy directory.\n\nSePCuT will still\
					work, but the Policy Modules tab and Test Policy tab will be disabled."
				Sepct::change_tab_state $Sepct::notebook $Sepct::customize_tab disable
				Sepct::change_tab_state $Sepct::notebook $Sepct::test_tab disable
				set disable_customize_tab 1
				set disable_test_tab 1
			}
			if { [Sepct::loadPolicy] != 0} {
				set Sepct::policyOpened 1
				Sepct::closePolicy
				return -1
			}
			if {$recent_flag == 1} {
				Sepct::addRecent $policyDir
			}
			set Sepct::policyOpened 1
			$mainframe setmenustate DisableOnCloseTag normal
			if {[$notebook raise] != ""} {
				[$notebook raise]::enter_Tab
			} else {
				foreach tab [$notebook pages 0 end] {
					if {[$notebook itemcget $tab -state] == "normal"} { 
						set raisedTab [$notebook raise $tab]
						${raisedTab}::enter_Tab
						break
					}
				}
			}
		 	Sepct::setTitleName $policyDir
		} else {
			return -1
		}
	}  
	return 0
}
proc Sepct::openPolicy { } {
	variable notebook
	set policyDir [tk_chooseDirectory -title "Choose Policy Directory" \
		-mustexist 1 -initialdir $Sepct::inital_policy_dir]
	if {$policyDir == ""} {
		return -1
	}
	set rt [Sepct::closePolicy]
	if { $rt != 0 } {
		return -1
	}
	set rt [Sepct::openPolicyDir $policyDir 1]
	return $rt
}
proc Sepct::create {} {
    variable notebook 
    variable mainframe  
    variable top_width
    variable top_height
    set descmenu {
        "&Policy" PolicyTag policy 0 {
            {command "&Choose policy directory..." {OpenPolicyTag} "Choose policy directory"  \
            	{} -command Sepct::openPolicy }
            {command "&Reload current policy " {DisableOnCloseTag ReloadPolicyTag} "Re-open current policy directory"  \
            	{} -command Sepct::reloadPolicy }
            {command "C&lose policy" {DisableOnCloseTag ClosePolicyTag} "Close opened policy directory" \
            	{} -command Sepct::closePolicy }
            {separator}
            {command "Sa&ve All " { DisableOnCloseTag SaveAllTag } "Save All Modified Files"  \
            	{} -command Sepct::save_all }
            {separator}
            {command "Save Module Conf&iguration..." { DisableOnCloseTag ConfigTag } "Save module configuration"  \
            	{} -command Sepct::save_Configuration }
            {command "L&oad Module Configuration..." { DisableOnCloseTag ConfigTag } "Load module configuration"  \
            	{} -command Sepct::load_Configuration }
            {separator}
            {command "E&xit                      (C-x C-c)" {} "Exit" \
            	{} -command Sepct::exitApp }
            {separator}
            {cascad "Rece&nt directories" {} recent 0 {}}     
        }
        "&File" FileTag file 0 {
            {command "&Save                     (C-x C-s)" {DisableOnCloseTag SaveFileTag} "Save"  \
            	{} -command Sepct::save }
            {command "Save &As...            (C-x C-w)" {DisableOnCloseTag SaveFileAsTag } "Save File As..."  \
            	{} -command Sepct::save_as }
            {command "Sa&ve All " { DisableOnCloseTag SaveAllTag } "Save All Modified Files"  \
            	{} -command Sepct::save_all }
            {separator}
            {command "&Revert to Saved" {DisableOnCloseTag RevertTag} "Revert to Saved"  \
            	{} -command Sepct::revert }
            {command "Show &modified files..." {DisableOnCloseTag ShowModFilesTag} "Show modified files"  \
            	{} -command Sepct::show_ModFileNames }
        }
        "&Edit" EditTag edit 0 {
            {command "&Add Module..." {DisableOnCloseTag AddTag ModEditTag } "Add a New Policy Module" {} -command Sepct::addModule }
            {command "&Delete Module" { DisableOnCloseTag DeleteTag ModEditTag} "Delete a Policy Module"  \
            	{} -command Sepct::deleteModule } 
            {command "Ena&ble All Modules" {DisableOnCloseTag EnableModTag ModEditTag} "Enable All Modules" {}\
            	 -command Sepct::enableAllModules }
            {separator}
            {command "&Toggle Edit Mode" {DisableOnCloseTag EditModeTag} "Toggle between read-only and editable mode." {} \
            		-command Sepct::ToggleEditMode  }
            {separator}
            {command "&Goto Line...           (C-g)" {DisableOnCloseTag GotoTag} "Goto Line"  \
            	{} -command Sepct::goto_line }      
            {command "&Search...               (C-s)" {DisableOnCloseTag SearchTag} "Search"  \
            	{} -command Sepct::display_searchDlg }	
        }
        "&Options" all options 0 {
            {command "Defa&ult tool settings..." {all option} "Set tool default settings." {}
                -command  Sepct::display_default_settings_Dlg
            }
        }
        "&Help" {} helpmenu 0 {
	    {command "&Help"  {all option} "Show help" {} -command Sepct::helpDlg}
	    {command "&About" {all option} "Show about box" {} -command Sepct::aboutBox}
        }
    }
    set mainframe [MainFrame .mainframe -menu $descmenu -textvariable Sepct::status]
    $mainframe addindicator -textvariable Sepct::line_info -width 18 -anchor w -padx 2
    $mainframe addindicator -textvariable Sepct::file_size -width 12 -anchor w -padx 2
    $mainframe addindicator -textvariable Sepct::file_modTime -width 25 -anchor c -padx 2
    $mainframe addindicator -textvariable Sepct::edit_mode_status -width 9 -anchor c -padx 2
    $mainframe addindicator -textvariable Sepct::file_name -width 35 -anchor e -padx 2
    $mainframe setmenustate DisableOnCloseTag disabled
    $mainframe setmenustate ConfigTag disabled
    set frame    [$mainframe getframe]
    set notebook [NoteBook $frame.nb]
    Sepct_Browse::create $notebook
    Sepct_Customize::create $notebook
    Sepct_Test::create $notebook
    bind $Sepct::mainWindow <Control-x><s> {Sepct::save}
    bind $Sepct::mainWindow <Control-x><w> {Sepct::save_as}
    bind $Sepct::mainWindow <Control-s> {Sepct::display_searchDlg}
    bind $Sepct::mainWindow <Control-g> {Sepct::goto_line}
    $notebook compute_size
    $notebook bindtabs <Button-1> { Sepct::switch_tab }
    pack $notebook -fill both -expand yes -padx 4 -pady 4
    $notebook raise [$notebook page 0]
    pack $mainframe -fill both -expand yes  
    update idletasks	
    return 0
}
proc Sepct::save_default_settings {} {
	variable inital_policy_dir
	variable tmp_initial_policy_dir
	set dir_type [Sepct::isValidPolicyDir $tmp_initial_policy_dir $Sepct::tool_settings_Dialog]
	if {$dir_type != 1} {	
		if { $dir_type == 2 } {
			set ans [tk_messageBox \
				     -icon warning \
				     -type yesno \
				     -parent $Sepct::tool_settings_Dialog \
				     -title "Non-conventional Policy Directory" \
				     -message \
					"The policy directory does not appear to be configured for customization (i.e., there\
					is no policy/domains/program directory).  \n\nThis may because you are specifying an older\
					policy directory or a non-conventional policy directory.  \n\nSePCuT will still\
					work, but the Policy Modules tab will be disabled at start-up. \n\nWould you still like\
					to save these settings?"]
			switch $ans {
				no {return -1}
				yes {}
			}
		} else {
			return -1
		}
	}
	set inital_policy_dir $tmp_initial_policy_dir
	Sepct::writeInitFile
	return 0	
}
proc Sepct::browse_for_init_directory {} {
	set dir [tk_chooseDirectory -initialdir $Sepct::inital_policy_dir -title "Choose initial directory" \
		-mustexist 1 -parent $Sepct::tool_settings_Dialog]
	if { $dir != "" } {
		set Sepct::tmp_initial_policy_dir $dir	
	}
	return 0
}
proc Sepct::display_default_settings_Dlg {} {
	variable inital_policy_dir
	variable tmp_initial_policy_dir
	variable tool_settings_Dialog	
	variable mainWindow
    	if { [winfo exists $tool_settings_Dialog] } {
    		raise $tool_settings_Dialog
    		return 
    	}
	toplevel $tool_settings_Dialog
	wm protocol $tool_settings_Dialog WM_DELETE_WINDOW "destroy $tool_settings_Dialog"
	wm withdraw $tool_settings_Dialog
	wm title $tool_settings_Dialog "Default Tool Settings"
	set title_f [TitleFrame $tool_settings_Dialog.title_f -text "Tool Options"]
	set frame_a [frame [$title_f getframe].frame_a]
	set frame_edit_mode [frame $frame_a.frame_edit_mode]
	set frame_initDir [frame $frame_a.frame_initDir]	
	set frame_b [frame [$title_f getframe].frame_b]
	pack $title_f -side left -expand yes -fill both -padx 5 -pady 5
	pack $frame_a -fill both -expand yes -side top -anchor nw -pady 5 -padx 5
	pack $frame_edit_mode -fill both -side top -anchor nw 
	pack $frame_initDir -fill both -side top -anchor nw -pady 5
	pack $frame_b -side bottom -anchor center
	set tmp_initial_policy_dir $inital_policy_dir
	set cb_show_file_names [checkbutton $frame_a.cb_show_file_names -text "Display program modules by file name at start-up" \
					-variable Sepct::show_customize_file_names]
	set rb_read_only [radiobutton $frame_edit_mode.rb_read_only -variable Sepct::initial_edit_mode -value 0 -text "Read-Only"]
	set rb_edit_mode [radiobutton $frame_edit_mode.rb_edit_mode -variable Sepct::initial_edit_mode -value 1 -text "Edit Mode"]
	set entry_initDir [Entry $frame_initDir.entry_initDir -textvariable Sepct::tmp_initial_policy_dir -bg white]
	set lbl_edit_mode [Label $frame_edit_mode.lbl_edit_mode -text "Initial edit mode:"]
	set lbl_initDir [Label $frame_initDir.lbl_initDir -text "Initial policy directory:"]
	set b_initDir [button $frame_initDir.applyButton -text "Browse..." \
		      -command  {Sepct::browse_for_init_directory}]
	set okButton [Button $frame_b.okButton -text "OK" \
		      -command  {
		      		set rt [Sepct::save_default_settings]
		      		if { $rt == 0 } {
		      			destroy $Sepct::tool_settings_Dialog
		      		}
		      	}]
	set applyButton [Button $frame_b.applyButton -text "Apply" \
		      -command  {Sepct::save_default_settings}]
	set cancelButton [Button $frame_b.cancelButton -text "Cancel" \
		      -command {destroy $Sepct::tool_settings_Dialog}]
	pack $cb_show_file_names -side top -anchor nw 	
	pack $lbl_edit_mode $rb_read_only $rb_edit_mode -side left -anchor nw -padx 5
	pack $lbl_initDir -side left -anchor nw -padx 5 -fill y     	     	        
	pack $entry_initDir -side left -expand yes -anchor nw -fill both
	pack $b_initDir -side left -anchor ne -padx 2 
	pack $okButton $applyButton $cancelButton -side left -anchor center -expand yes -padx 2
	set width 450
	set height 150
	wm geom $tool_settings_Dialog ${width}x${height}
	wm deiconify $tool_settings_Dialog	  		
	return 0
}
proc Sepct::configure_tool_settings {} {
	variable recent_dirs_tmp_list
	if { $Sepct::initial_edit_mode == 0 } {
		set Sepct::read_only	1
	} else {
		set Sepct::read_only	0
	}
	Sepct::DisplayEditMode
	if { $recent_dirs_tmp_list != "" } {
		foreach dir $recent_dirs_tmp_list {
			if { [file isdirectory $dir] } {
				Sepct::addRecent $dir
			}
		}
		unset recent_dirs_tmp_list 
	}
	return 0
}
proc Sepct::load_fonts { } {
	variable title_font
	variable dialog_font
	variable general_font
	variable text_font
	tk scaling -displayof . 1.0
	if {$general_font == ""} {
		option add *Font "Helvetica 10"
	} else {
		option add *Font $general_font
	}
	if {$title_font == ""} {
		option add *TitleFrame.l.font "Helvetica 10 bold italic" 
	} else {
		option add *TitleFrame.l.font $title_font  
	}
	if {$dialog_font == ""} {
		option add *Dialog*font "Helvetica 10" 
	} else {
		option add *Dialog*font $dialog_font
	}
	if {$text_font == ""} {
		option add *text*font "fixed"
		set text_font "fixed"
	} else {
		option add *text*font $text_font
	}
	return 0	
}
proc Sepct::main {} {
	global argv0 argv
	global tk_version
	global tk_patchLevel
	variable mainWindow
	variable top_width
        variable top_height
        variable bwidget_version
	rename send {}
	set rt [catch {set bwidget_version [package require BWidget]} err]
	if {$rt != 0 } {
		tk_messageBox -icon error -type ok -title "Missing BWidgets package" -message \
			"Missing BWidgets package.  Ensure that your installed version of \n\
			TCL/TK includes BWidgets, which can be found at\n\n\
			http://sourceforge.net/projects/tcllib"
		exit
	}
	if {[package vcompare $bwidget_version "1.4.1"] == -1} {
		tk_messageBox -icon warning -type ok -title "Package Version" -message \
			"This tool requires BWidgets 1.4.1 or later. You may experience problems\
			while running the application. It is recommended that you upgrade your BWidgets\
			package to version 1.4.1 or greater. See 'Help' for more information."	
	}
	if {[package vcompare $bwidget_version "1.4.1"] && $tk_version == "8.3"} {
		tk_messageBox -icon error -type ok -title "Warning" -message \
			"Your installed Tk version $tk_version includes an incompatible BWidgets $bwidget_version package version. \
			This has been known to cause a tk application to crash.\n\nIt is recommended that you either upgrade your \
			Tk library to version 8.4 or greater or use BWidgets 1.4.1 instead. See the README for more information."	
		exit
	}
	wm withdraw $mainWindow
	wm title $mainWindow $Sepct::tool_title
	wm protocol $mainWindow WM_DELETE_WINDOW "Sepct::exitApp"
	bind $mainWindow <Control-x><c> {Sepct::exitApp}
	Sepct::readInitFile
	Sepct::load_fonts
	Sepct::create
	Sepct::configure_tool_settings
	wm geom . ${top_width}x${top_height}
	wm deiconify $mainWindow
	raise $mainWindow
	focus -force $mainWindow
	set argv1 [lindex $argv 0]
	if { $argv1 != "" } {
		Sepct::openPolicyDir $argv1 1
	} else {
		if { $Sepct::inital_policy_dir != "" } {
			Sepct::openPolicyDir $Sepct::inital_policy_dir 1
		}
	}
	return 0
}
namespace eval Sepct_Browse {
    variable curr_file			""	
    variable text_dBit			0	
    variable text_mcntr			0	
    variable node_mcntr			0
    variable selected_node		"" 	
    variable max_Filename_Length	255	
    variable home_node			
    variable file_context_tab_name	"File Contents"
    variable notebook
    variable mainframe
    variable tree
    variable list_b
    variable text_c	
    variable text_wrap_proc  "Sepct_Browse::wrap_proc"	# This is hard coded and shouldn't be changed
}
proc Sepct_Browse::initialize_App_Vars {  } {
	set Sepct_Browse::curr_file			""
	set Sepct_Browse::text_mcntr			0
	Sepct_Browse::reset_dirtyState
	return 0
}
proc Sepct_Browse::reset_dirtyState { } {	    		
	set Sepct_Browse::text_dBit 0
	return 0
}
proc Sepct_Browse::remove_modIndicators  {} {
	variable notebook
	$notebook itemconfigure Contents -text $Sepct_Browse::file_context_tab_name
	return 0
}
proc Sepct_Browse::set_modIndicators {} {
	variable notebook
	$notebook itemconfigure Contents -text "$Sepct_Browse::file_context_tab_name*"
	return 0
}
proc Sepct_Browse::wrap_proc { cmd args } {
	if { $Sepct_Browse::curr_file != "" } {
		switch $cmd {
			insert	-
			delete	{ 
				if { [Sepct::inReadOnlyMode] } {
					return 0
				} else {
					if { $Sepct_Browse::text_dBit == 0 }  {
						Sepct_Browse::set_modIndicators
						set Sepct_Browse::text_dBit 1
					}
					Sepct::update_positionStatus [$Sepct_Browse::text_c index insert]
				}
			}
			mark {
				if { [string compare -length 10 $args "set insert"]  == 0 } {
					uplevel "::${Sepct_Browse::text_c}_" $cmd $args
					Sepct::update_positionStatus [$Sepct_Browse::text_c index insert]
					return
				}
			}
		}
	}
	# don't use a return after this!
	uplevel "::${Sepct_Browse::text_c}_" $cmd $args
}
proc Sepct_Browse::insert_Data { path textBox line col} {	
	if { [Sepct_db::is_in_mod_FileArray $path] } {
		$textBox delete 0.0 end
		if {[Sepct_db::getModFile_Data $path data] != 0 } {
			return -1
		}
		$textBox insert end $data
		Sepct_Browse::set_modIndicators
	} else {
    		if { [Sepct_db::read_fileContents_fromDisk $path data] != 0 } {
    			return -1
    		}
		$textBox insert end $data
		Sepct_Browse::remove_modIndicators 
	}
	focus -force $textBox
	$textBox mark set insert $line.$col 
	$textBox see $line.$col 
	return 0	
}
proc Sepct_Browse::search { str case_Insensitive regExpr srch_Direction } {
	variable text_c
	Sepct::textSearch $text_c $str $case_Insensitive $regExpr $srch_Direction
}
proc Sepct_Browse::record_outstanding_changes { } {
	variable curr_file
	variable text_dBit
    	variable text_c
    	variable text_mcntr
	if { $curr_file != "" } {
		if {$text_dBit } {
			set cntr [Sepct_db::add_to_mod_List $curr_file [$text_c get 0.0 end]]
			if { $cntr == -1 } {
				return -1
			}
			Sepct_Browse::reset_dirtyState
			set text_mcntr $cntr
			Sepct_db::update_pos $curr_file [$text_c index insert]
			return $cntr
		}
	}
	return -2
}
proc Sepct_Browse::revert_file { } {
	variable text_mcntr	
	variable curr_file
	variable list_b
	variable text_c
	if {$curr_file == "" } {
		return 0
	}
	set cntr [Sepct_db::discard_Single_File_Changes $curr_file ]
	if {$cntr >= 0 } {
		set text_mcntr $cntr
	} elseif {$cntr == -1} {
		puts stderr "Problem displaying file in revert_file"
		return -1
	}
	set fn $curr_file
	set curr_file ""
	set rt [Sepct_Browse::displayFile $list_b $text_c $fn]
	return $rt
}
proc Sepct_Browse::leave_Tab { } {
	variable node_mcntr	
    	variable selected_node
 	Sepct_Browse::record_outstanding_changes
	set node_mcntr [Sepct_db::get_node_mod_cntr $selected_node]
	return 0
}
proc Sepct_Browse::enter_Tab { } {
	variable text_c
	variable text_mcntr
	variable curr_file
	variable list_b
	variable node_mcntr	
	variable selected_node
	variable tree
    	focus  $text_c
	if { [Sepct::isPolicyOpened] } {
		$Sepct::mainframe setmenustate ModEditTag disabled
		$Sepct::mainframe setmenustate SaveFileTag normal
		$Sepct::mainframe setmenustate SaveFileAsTag normal
		$Sepct::mainframe setmenustate RevertTag normal
		$Sepct::mainframe setmenustate ConfigTag disabled
	}
    	if { $curr_file != "" && [ Sepct_db::does_fileExists $curr_file ] && [file exists $curr_file]} {
    		set cntr [Sepct_db::get_cntr $curr_file]
		if {$cntr != $text_mcntr } {
			set fn $curr_file
			set curr_file ""
    			set rt [Sepct_Browse::displayFile $list_b $text_c $fn]
    			if {$rt != 0} {
    				Sepct::clear_fileStatus   
    				return -1  				
    			}
	    	} else {
	    		Sepct::update_fileStatus $curr_file 1
	    	}
	} else {
		set curr_file ""
		$text_c delete 0.0 end
		Sepct::clear_fileStatus
		Sepct_Browse::reset_dirtyState
		Sepct_Browse::remove_modIndicators
	}	
	if { $selected_node != "" } {
		set cur_mcntr [Sepct_db::get_node_mod_cntr $selected_node]
		if { $node_mcntr != $cur_mcntr || [Sepct_Browse::validate_directory_structure $selected_node] == 0} {
			set node_mcntr $cur_mcntr
			set node $selected_node
			set selected_node ""
			set rt [Sepct_Browse::treeSelect $tree $list_b $node]
			if { $rt != 0 } {
				return -1
			}
		} 
	} else {
		set node_mcntr 0
	}
    	return 0
}
proc Sepct_Browse::close {} {
	Sepct_db::close
	$Sepct_Browse::list_b delete [$Sepct_Browse::list_b items]
	$Sepct_Browse::text_c delete 0.0 end
	set Sepct_Browse::selected_node ""
	set Sepct_Browse::node_mcntr 0
	Sepct_Browse::initialize_App_Vars
	Sepct_Browse::remove_modIndicators
	return 0
}
proc Sepct_Browse::goto_line { line_num} {
	variable text_c
	variable curr_file
	if {$curr_file == "" } {
		return 0
	}
	if {[string is integer -strict $line_num] != 1 || [string is digit -strict $line_num] != 1 || [regexp "\[A-Z\]" $line_num]} {
		tk_messageBox -icon error \
			-type ok  \
			-title "Invalid line number" \
			-message "$line_num is not a valid line number"
		return 0
	}
	$text_c mark set insert ${line_num}.0 
	Sepct_db::update_pos $curr_file ${line_num}.0
	$text_c see ${line_num}.0 
	focus -force $text_c
	return 0
}
proc Sepct_Browse::save { } {
	variable curr_file
    	variable text_c
    	variable text_dBit
    	variable text_mcntr
	if { $curr_file != "" } {
		if {$text_dBit } {
			set cntr [Sepct_db::add_to_mod_List $curr_file [$text_c get 0.0 end]]
			if { $cntr == -1 } {
				return -1
			}
			set mod 1
			Sepct_Browse::reset_dirtyState
		} else {
			set mod [Sepct_db::is_in_mod_FileArray $curr_file]
		}
		if {$mod} {
			set cntr [Sepct_db::saveFile $curr_file [$text_c index insert]]
			if {$cntr == -1 } {
				return -1
			}
			Sepct_Browse::remove_modIndicators 
			Sepct::update_fileStatus $curr_file
			set text_mcntr $cntr
		} 
	}
    	return 0
}
proc Sepct_Browse::save_as { } {
    	variable text_c
    	variable tree
    	variable list_b
    	variable text_mcntr
    	variable text_dBit
    	variable curr_file	
	if { $curr_file != "" } {
		set fileExt [file extension $curr_file]
		set types {
			{"All files"		*}
    		}
		set filename [tk_getSaveFile -initialdir $Sepct::policyDir \
			-title "Save As?" -filetypes $types]
		if { [string equal $filename $curr_file] } {	
			return [Sepct_Browse::save]
		} 
		if { $filename != "" } {
			set parent [file dirname $filename]
			if { ![Sepct_db::existsTree_node  $parent] } {
				tk_messageBox -icon warning \
					-type ok  \
					-title "Save As Warning" \
					-message \
					"Can't save to $parent\n\nCurrently, this tool does not support saving
					outside the policy root directory."
				return 0
			}
			set rt [Sepct_db::file_write [$text_c get 0.0 end] $filename]
			if {$rt != 0 } {
				return -1
			}
			set cntr [Sepct_db::remove_from_mod_List $curr_file]
			if { $cntr >= 0 } {
				set text_mcntr $cntr
			} elseif {$cntr == -1 } {
				return -1
			}
			if { [Sepct_db::existsTree_node $parent] } {
				set position [$text_c index insert]
				set cntr [Sepct_db::add_file $filename 0 $position] 
				if { $cntr == -1 } {
					return -1
				}
				set text_mcntr $cntr
				set Sepct_Browse::selected_node ""
				set curr_file 	""
				Sepct_Browse::treeSelect $tree $list_b $parent
				$tree itemconfigure $parent -open 1
				$tree see $parent
				set rt [Sepct_Browse::displayFile $list_b $text_c $filename]
	    			if {$rt != 0} {
	    				Sepct::clear_fileStatus   
	    				return -1  				
	    			}
				set curr_file $filename				
				Sepct::update_fileStatus $filename	
				Sepct_Browse::remove_modIndicators 
				Sepct_Browse::reset_dirtyState
				$list_b see $filename
				update idletasks
			} else {
				puts stderr "Problem, saving as file outside policy dir!"
				set text_mcntr 0
				$list_b selection clear
				return -1
			}
		}	
	}
    	return 0
}
proc Sepct_Browse::displayFile { list_box text_c selected_file } {
	variable curr_file
	variable text_dBit
	variable text_mcntr
	if {$curr_file == $selected_file } {
		return 0
	}
	if { $selected_file == "" || ![Sepct_db::does_fileExists $selected_file]} {
		return 0
	}
	if { $curr_file != "" } {
		if {$text_dBit} {
			set cntr [Sepct_db::add_to_mod_List $curr_file [$text_c get 0.0 end]]
			if { $cntr == -1 } {
				return -1
			}
		}
		Sepct_db::update_pos $curr_file [$text_c index insert]
	} 
	set curr_file ""
	$text_c delete 0.0 end
	Sepct_Browse::reset_dirtyState 
	$list_box selection set $selected_file
	if { [Sepct_db::does_fileExists $selected_file] && [file exists $selected_file] } {
		set fdata [Sepct_db::getFileData $selected_file]
		if { [llength $fdata] < $Sepct_db::lfiles_num_data } {
			puts stderr "problem with fdata ($fdata: [llength $fdata] ) for file $selected_file"
			return -1
		}
		set text_mcntr [lindex $fdata 0]		
		set line [lindex $fdata 1]
		set col	[lindex $fdata 2]
		Sepct_Browse::insert_Data $selected_file $text_c $line $col
		Sepct_Browse::reset_dirtyState
		set curr_file $selected_file
		Sepct::update_fileStatus $selected_file 1
	} else {
		set ans [tk_messageBox -icon error \
			-type yesnocancel  \
			-title "File Error" \
			-message \
			"In-memory and disk directory structure out of sync for $selected_file\n\n\
			Press YES to re-load the policy directory\n\
			or NO to remove file and continue"]
		if {$ans == "yes" } {
			Sepct::reloadPolicy
		} elseif {$ans == "no" } {
			$list_box delete $selected_file 
		} 
	}
	return 0	
}
proc Sepct_Browse::validate_directory_structure { node } {
	set files_in_mem [Sepct_db::getFileNames $node]
	if { $files_in_mem  == "-1" } {
		return -1
	}
	set files_in_mem [lsort $files_in_mem]
	set files_on_disk [glob -nocomplain [file join $node "*"]]
	if {[string equal "$files_in_mem" "$files_on_disk"]} {
		return 1
	}
	return 0	
}
proc Sepct_Browse::treeSelect { tree list_b node } {
	variable selected_node
	variable curr_file
	if { $selected_node == $node } {
		return 0
	}
	$tree selection set $node
	$list_b delete [$list_b items]
	set files_in_mem [Sepct_db::getFileNames $node ]
	if { $files_in_mem  == "-1" } {
		return -1
	}
	set files_in_mem [lsort $files_in_mem]
	foreach file_in_mem $files_in_mem {
		if { [file exists [file join $node $file_in_mem]] } {
			$list_b insert end [file join $node $file_in_mem] \
			  	-text  $file_in_mem \
			  	-image [Bitmap::get file] 
		} else { 
			if { [Sepct_db::is_in_mod_FileArray [file join $node $file_in_mem]] } {
				Sepct_db::remove_from_mod_List [file join $node $file_in_mem]
			}
			if { [Sepct_db::remove_file [file join $node $file_in_mem]] == -1 } {
				puts stderr "Problem removing [file join $node $file_in_mem]"
				return -1
			}
		}
	} 
	set files_in_mem [Sepct_db::getFileNames $node]
	set files_on_disk [glob -nocomplain [file join $node "*"]]
	foreach file_on_disk $files_on_disk {
		if {[file isfile $file_on_disk] && ![Sepct_db::does_fileExists $file_on_disk]} {
			if {[Sepct_db::add_file $file_on_disk 0 "1.0"] == -1}  {
				puts stderr "Problem adding $file_on_disk"
				return -1
			}
			$list_b insert end $file_on_disk \
			  	-text  [file tail $file_on_disk] \
			  	-image [Bitmap::get file] \
		}	
	}
	$tree configure -redraw 1
	$list_b configure -redraw 1
	if {$curr_file != ""} {
		set curr_dirname [file dirname $curr_file]
		if {$curr_dirname == $node} {
			$list_b selection set $curr_file
			$list_b see $curr_file
		}
	}
	set selected_node $node
	return 0
}
proc Sepct_Browse::readDir { tree parent_node } {
	variable max_Filename_Length	
	set lentries [glob -nocomplain [file join $parent_node "*"]]
	foreach file $lentries {
		set tail [file tail $file]
		if { [string length $tail] > $max_Filename_Length } {
			 tk_messageBox -icon error \
				-type ok  \
				-title "File Problem" \
				-message \
				"A filename is too long. Maximum length for a filename \
				is $max_Filename_Length characters. Please rename the file correctly. "
			 return 1
		}
		if { [file isdirectory $file] } {
			if { [file readable $file] } {
				Sepct_db::addTree_node $file 0 0
				Sepct_Browse::readDir $tree $file
	    		} else {
	    			tk_messageBox -icon warning \
					-type ok  \
					-title "Directory Permission Problem" \
					-message \
					"The directory $file is not readable. It will be skipped."
	    		}
		} elseif { [file isfile $file] } {
	    		if { [Sepct_db::add_file $file 0 "1.0"]  == 1 } {
	    			puts stderr "Problem adding file $file to directory node $parent_node."
	    			return 1
	    		}
		} 
	}
	return 0
}
proc Sepct_Browse::configure_Widgets { tree list_b policyDir} {
	variable home_node
	Sepct_db::addTree_node $policyDir 1 1
	set home_node $policyDir
	set rt [Sepct_Browse::readDir $tree $home_node ] 
	if {$rt != 0} {
		return -1
	}
	set rt [$tree configure -redraw 1]
	if {$rt != ""} {
		return -1
	}
	Sepct_Browse::treeSelect $tree $list_b $home_node
	return 0
}
proc Sepct_Browse::initialize { policyDir } {
	variable tree 
	variable list_b
    	set res [Sepct_Browse::configure_Widgets $tree $list_b $policyDir]
    	return $res
}
proc Sepct_Browse::createNoteBook { tabsBox } {
	variable text_c
	variable notebook
	set notebook [NoteBook $tabsBox.nb -side top]
	set c_frame  [$notebook insert end Contents -text "File Contents"]
	set sw_c [ScrolledWindow $c_frame.sw_c -auto none]
	set text_c [text $sw_c.text -bg white -wrap none -font $Sepct::text_font]
	$sw_c setwidget $text_c
	rename $text_c "::${text_c}_"
	rename $Sepct_Browse::text_wrap_proc "::$text_c"
	pack $sw_c -side left -expand yes -fill both  
	$notebook compute_size
	pack $notebook -fill both -expand yes -padx 4 -pady 4
	$notebook raise [$notebook page 0]
	return 0
}
proc Sepct_Browse::create { nb } {
    variable tree
    variable list_b
    set frame [$nb insert end $Sepct::browse_tab -text "Browse Policy"]
    set topf  [frame $frame.topf -width 100 -height 200]
    set pw1   [PanedWindow $topf.pw -side top]
    set pane  [$pw1 add ]
    set spane [$pw1 add -weight 4]
    set pw2   [PanedWindow $pane.pw -side left]
    set active [$pw2 add -weight 2]
    set contents [$pw2 add -weight 2]
    set tabsBox [frame $spane.tabsBox]
    set activeBox [TitleFrame $active.abox -text "Policy Directory"]
    set contentsBox [TitleFrame $contents.abox -text "Directory Contents"]
    pack $tabsBox -pady 2 -padx 2 -fill both -expand yes -anchor ne 
    pack $activeBox -padx 2 -side left -fill both -expand yes
    pack $contentsBox -padx 2 -side left -fill both -expand yes
    pack $pw1 -fill both -expand yes
    pack $pw2 -fill both -expand yes	
    pack $topf -fill both -expand yes 
    set sw_t  [ScrolledWindow [$activeBox getframe].sw -auto none]		 
    set tree  [Tree $sw_t.tree \
                   -relief flat -borderwidth 0 -width 15 -highlightthickness 0 \
		   -redraw 0 -bg white -showlines 1 
              ]
    set Sepct_db::tree $tree
    $sw_t setwidget $tree 
    set sw_c   	[ScrolledWindow [$contentsBox getframe].sw_c -auto none]
    set list_b 	[ListBox $sw_c.lb \
                  -relief flat -borderwidth 0 -bg white \
                  -width 20 -highlightthickness 2 \
                  -redraw 0 -selectmode single ]
    $sw_c setwidget $list_b
    pack $sw_t -fill both -expand yes
    pack $sw_c -fill both -expand yes 
    Sepct_Browse::createNoteBook $tabsBox
    $tree bindText  <ButtonPress-1>        {Sepct_Browse::treeSelect $Sepct_Browse::tree $Sepct_Browse::list_b}
    $tree bindText  <Double-ButtonPress-1> {Sepct_Browse::treeSelect $Sepct_Browse::tree $Sepct_Browse::list_b}
    $tree bindImage <ButtonPress-1> 	   {Sepct_Browse::treeSelect $Sepct_Browse::tree $Sepct_Browse::list_b}
    $list_b bindText  <ButtonPress-1>        {Sepct_Browse::displayFile $Sepct_Browse::list_b $Sepct_Browse::text_c}
    $list_b bindText  <Double-ButtonPress-1> {Sepct_Browse::displayFile $Sepct_Browse::list_b $Sepct_Browse::text_c}
    $list_b bindImage <Double-ButtonPress-1> {Sepct_Browse::displayFile $Sepct_Browse::list_b $Sepct_Browse::text_c}
    $list_b bindImage <ButtonPress-1>        {Sepct_Browse::displayFile $Sepct_Browse::list_b $Sepct_Browse::text_c}
    Sepct_Browse::initialize_App_Vars
    return $frame
}
namespace eval Sepct_Customize {
	variable curr_TE_file		""
	variable curr_FC_file		""
	variable text_te_dBit			0	
	variable text_fc_dBit			0
	variable text_te_mcntr			0
	variable text_fc_mcntr			0
	variable used_Modules_Dir		""
	variable unUsed_Modules_Dir		""
	variable fc_path			""
	variable unUsed_Modules			""
	variable used_Modules			""
	variable all_Modules			""
	variable missing_fc_files		""
	variable desc_ID			"#DESC"
	variable max_Label_Length		255
	variable show_Filenames
	variable all_Modules			""
	variable cb_value_array
	variable cb_ID				""
	variable num_cbuttons		0
	variable newModuleName		""
    	variable module_Desc		""
	variable add_Module_Flag	0
	variable te_tabName			"Type Enforcement Rules"
	variable fc_tabName			"File Context"
	variable te_tabID			"Sepct_TERules"
	variable fc_tabID			"Sepct_FileContext"
	variable notebook
	variable list_b
	variable text_te
	variable text_fc
	variable add_Dialog
    	variable cb_show_Filenames
    	variable add_Module_Dlg
    	variable duplicate_mods_dlg
    	set duplicate_mods_dlg .duplicate_mods_dlg
    	variable text_TE_wrap_proc  "Sepct_Customize::wrap_proc_te"
    	variable text_FC_wrap_proc  "Sepct_Customize::wrap_proc_fc"	
}
proc Sepct_Customize::embed_checkbutton { te_file is_used } {
	variable list_b
	variable cb_value_array
	variable cb_ID
	variable num_cbuttons
	set rootname [file rootname $te_file]
	set split_list [split $rootname "."]
	if {$split_list != ""} {
		set rootname [join $split_list ":"]	
	}
	set te_file "${rootname}.te"
	set cb_value_array($te_file) $is_used
	incr num_cbuttons
	set cb_name [checkbutton $list_b.cb$num_cbuttons:$rootname -bg white \
		-onvalue 1 -offvalue 0 \
		-variable Sepct_Customize::cb_value_array($te_file) \
		-command {Sepct_Customize::change_module_status $Sepct_Customize::cb_ID} ]
	if { [file writable $Sepct_Customize::used_Modules_Dir] } {
		bind $cb_name <Button-1> {
			set Sepct_Customize::cb_ID %W
		}
		$cb_name configure -state normal
	} else {
		bind $cb_name <Button-1> { 
			tk_messageBox -icon warning \
			-type ok \
			-title "Permission Problem" \
			-message \
			"You don't have permission to Activate or\
			De-activate policy files."
		}
		$cb_name configure -state disabled
	}
	return $cb_name
}
proc Sepct_Customize::display_duplicate_modules_Dlg {duplicate_modules_list} {
	variable duplicate_mods_dlg
	if {[winfo exists $duplicate_mods_dlg]} {
		catch {destroy $duplicate_mods_dlg}
	}
	toplevel $duplicate_mods_dlg
	wm title $duplicate_mods_dlg "Duplicate modules!"
	wm protocol $duplicate_mods_dlg WM_DELETE_WINDOW "catch {destroy $duplicate_mods_dlg}"
     	set close_b [button $duplicate_mods_dlg.close -text "OK" -command "catch {destroy $duplicate_mods_dlg}" -width 10]
     	set lbl_f [frame $duplicate_mods_dlg.lbl_f]
     	set txt_f [frame $duplicate_mods_dlg.txt_f]
	set sw_c [ScrolledWindow $txt_f.sw_c -auto none]
	set dlg_txt [text [$sw_c getframe].dlg_txt -wrap none]
	$sw_c setwidget $dlg_txt
	set lbl_img [label $lbl_f.img -justify left \
		-image [Bitmap::get warning]]
	set lbl_txt [label $lbl_f.txt -justify left \
		-text "Duplicate modules were found in the program directory and have been ignored.\
	\nPlease be aware that these files will be overwritten when disabling the module.\
	\nThe following are the duplicate modules found:"]
	$dlg_txt insert end "$duplicate_modules_list\n"  
	$dlg_txt configure -state disabled
	pack $close_b -side bottom -anchor center 
	pack $lbl_f -side top -anchor nw -pady 4 -padx 4
	pack $txt_f -side top -anchor nw -pady 4 -padx 4 -fill both -expand yes
	pack $lbl_img -side left -anchor nw -expand yes -padx 2
	pack $lbl_txt -side left -anchor nw -fill x -expand yes
	pack $sw_c -side left -expand yes -fill both 
	wm geometry $duplicate_mods_dlg +30+40
	focus -force $duplicate_mods_dlg
	wm transient $duplicate_mods_dlg $Sepct::mainframe
        catch {grab $duplicate_mods_dlg}
	return 0
}
proc Sepct_Customize::insert_ListBox_Items { } {
	variable list_b
	variable item_count
	variable all_Modules
	variable displayList
	variable show_Filenames
	set duplicate_modules ""
	foreach te_file $all_Modules { 
		if {[$list_b exists $te_file]} {
			set duplicate_modules [append duplicate_modules "$te_file\n"]
			continue
		}
		set is_used [Sepct_Customize::is_module_used $te_file]
		set dscp_name [Sepct_Customize::store_mod_descrptive_name $te_file $is_used]
		if {$dscp_name == "-1"} {
			puts stderr "Insert: problem getting descriptive label for $te_file"
			return -1
		}
		$list_b insert end $te_file \
		 	 -data $dscp_name \
		 	 -window [Sepct_Customize::embed_checkbutton $te_file $is_used ]  
	} 
	if {$duplicate_modules != ""} {
		Sepct_Customize::display_duplicate_modules_Dlg $duplicate_modules
	}
	return 0
}
proc Sepct_Customize::draw_list_and_set_buttons { use_filenames} {  
    	variable list_b
    	variable curr_file
    	update idletasks
    	set curr_sel [$list_b selection get]   
    	set items [$list_b items]
    	if { $Sepct_Customize::show_Filenames == 1 } {	
		foreach item $items {
			$list_b itemconfigure $item -text "  $item"
		}
		set items [lsort -dictionary $items]
		$list_b reorder $items
	} else {
		set items ""
		foreach item_text $displayList {
			$list_b itemconfigure $displayList_Array($item_text) -text " $item_text"
			lappend items $displayList_Array($item_text)
		}
		$list_b reorder $items
	}
	$list_b configure -redraw 1
    	if { [$list_b exists $curr_sel] } {
	    	$list_b selection set $curr_sel
	    	$list_b see $curr_sel 
	    	set curr_file $curr_sel
	} else { 
		set curr_file ""
	}
    	$list_b.c xview moveto 0
    	update idletasks
	return 0	
}
proc Sepct_Customize::label_and_order_list { } {
	variable list_b
	variable show_Filenames
	set mods [$list_b items]
	foreach mod $mods {
		if {$show_Filenames} {
			set text_label $mod
		} else {
			set text_label [$list_b itemcget $mod -data]
		}
		# needed to do this because first char was not being displayed!
		set text_label "  $text_label"
		$list_b itemconfigure $mod -text $text_label
	}
	set module_List [$list_b items]
	if {$show_Filenames} {
		set module_List [lsort -dictionary $module_List]		
	} else {	
		set module_List [Sepct_Customize::order_Modules_by_Description $module_List]
	}
	$list_b reorder $module_List
	return 0
}
proc Sepct_Customize::configure_ListBox { } {
	variable list_b
	set rt [Sepct_Customize::get_all_Modules]
		if { $rt == -1} {
		puts stderr "Customize problem: getting all modules"
		return -1
	}
	set rt [Sepct_Customize::check_fc_consistency ]
	if { $rt == -1} {
		puts stderr "Customize problem: getting all modules"
		return -1
	}
	set rt [Sepct_Customize::insert_ListBox_Items]
	if { $rt == -1} {
		puts stderr "Customize problem: getting all modules"
		return -1
	}	
	Sepct_Customize::label_and_order_list
	$list_b configure -redraw 1
    	$list_b.c xview moveto 0
	return 0
}
proc Sepct_Customize::initialize { policyDir } {
	variable list_b
	variable item_count
	set Sepct_Customize::used_Modules_Dir 		"$policyDir/domains/program"
	set Sepct_Customize::fc_path			"$policyDir/file_contexts/program"
	if {[file isdirectory "$policyDir/domains/program/Unused"] && ![file isdirectory "$policyDir/domains/program/unused"]} {
		set Sepct_Customize::unUsed_Modules_Dir "$policyDir/domains/program/Unused"
	} else {
		set Sepct_Customize::unUsed_Modules_Dir "$policyDir/domains/program/unused"
	}
	if {![file isdirectory $Sepct_Customize::used_Modules_Dir] } {
		set err_dir  $Sepct_Customize::used_Modules_Dir 
	} elseif {![file isdirectory $Sepct_Customize::fc_path] } {
		set err_dir $Sepct_Customize::fc_path
	} else {
		set err_dir ""
	}
	if {$err_dir != "" } {	
		tk_messageBox \
		     -icon error \
		     -type ok \
		     -title "Open Error (Customizer)" \
		     -message \
			"The policy dir ($policyDir)\ndoes not appear to be valid.\n\n\
			The subdirectory ($err_dir) is missing or not readable.  Perhaps \
			you are using a policy directory that pre-dates the modular \
			policy model.  This policy directory cannot be opened by this tool."
		return -1    
	}
	set rt [Sepct_Customize::configure_ListBox]
	return $rt
}
proc Sepct_Customize::displayModule { list_b text_te text_fc selected_module } {
	variable curr_TE_file		
	variable curr_FC_file	
	variable text_te_dBit				
	variable text_fc_dBit			
	variable text_te_mcntr			
	variable text_fc_mcntr	
	variable used_Modules_Dir		
	variable unUsed_Modules_Dir		
	variable fc_path
	variable notebook
	if { [file tail $curr_TE_file] == $selected_module } {
		return 0
	}
	if {$curr_TE_file != ""} {	
		if { [Sepct_db::does_fileExists $curr_TE_file]} {		
			if {$text_te_dBit} {
				set cntr [Sepct_db::add_to_mod_List $curr_TE_file [$text_te get 0.0 end]]
				if { $cntr == -1 } {
					return -1
				}
			}
			Sepct_db::update_pos $curr_TE_file [$text_te index insert]
		}
		if {$curr_FC_file != ""} {
			if { [Sepct_db::does_fileExists $curr_FC_file]} {
				if {$text_fc_dBit} {
					set cntr [Sepct_db::add_to_mod_List $curr_FC_file [$text_fc get 0.0 end]]
					if { $cntr == -1 } {
						return -1
					}
				}
				Sepct_db::update_pos $curr_FC_file [$text_fc index insert]
			}
		}
	}	
	set curr_TE_file ""
	set curr_FC_file ""
	$text_te delete 0.0 end
	$text_fc delete 0.0 end
	Sepct_Customize::reset_dirtyState 
	$list_b selection set $selected_module
	if { [Sepct_Customize::is_module_used $selected_module] } {
		set te_file [file join $used_Modules_Dir $selected_module]
	} else {
		set te_file [file join $unUsed_Modules_Dir $selected_module]
	}
	if { [Sepct_db::does_fileExists $te_file] && [file exists $te_file] } {
		set fdata_te [Sepct_db::getFileData $te_file]
		if { [llength $fdata_te] < $Sepct_db::lfiles_num_data } {
			puts stderr "problem with fdata_te ($fdata_te: [llength $fdata_te] ) for file $te_file"
			return -1
		}
		set text_te_mcntr [lindex $fdata_te 0]		
		set line [lindex $fdata_te 1]
		set col	[lindex $fdata_te 2]
		Sepct_Customize::insert_Data $te_file $text_te $line $col $Sepct_Customize::te_tabID
		set curr_TE_file $te_file
		set fc_file [file join $fc_path "[file rootname [file tail $curr_TE_file]].fc"]
		if { [Sepct_db::does_fileExists $fc_file] && [file exists $fc_file] } {
			set fdata_fc [Sepct_db::getFileData $fc_file]
			if { [llength $fdata_fc] < $Sepct_db::lfiles_num_data } {
				puts stderr "problem with fdata_fc ($fdata_fc: [llength $fdata_fc] ) for file $fc_file"
				return -1
			}
			set text_fc_mcntr [lindex $fdata_fc 0]		
			set line [lindex $fdata_fc 1]
			set col	[lindex $fdata_fc 2]
			Sepct_Customize::insert_Data $fc_file $text_fc $line $col $Sepct_Customize::fc_tabID
			set curr_FC_file $fc_file
		} else { 
			set curr_FC_file ""
			set ans [tk_messageBox -icon warning \
				-type ok \
				-title "Missing File Context File Warning" \
				-message \
				"This module does not appear to have an assoicated file context (.fc)\
				 file.  The tool will continue without the .fc file.  You may want to \
				 create the .fc file from outside this tool and re-load the policy."]
		} 
		Sepct_Customize::reset_dirtyState
		set raisedTab [$notebook raise]
		if { $raisedTab == $Sepct_Customize::te_tabID } {
			Sepct::update_fileStatus $curr_TE_file 1
		} else {
			if { $curr_FC_file != "" } {
				Sepct::update_fileStatus $curr_FC_file 1 
			} else {
				Sepct_Customize::remove_modIndicator $raisedTab
				Sepct::clear_fileStatus
			}
		} 
	} else {
		set ans [tk_messageBox -icon error \
			-type yesno  \
			-title "File Error" \
			-message \
			"In-memory and disk directory structure out of sync for $selected_module\n\n\
			Press YES to re-load the policy directory\n\
			or NO to continue leaving the problem."]
		if { $ans == "yes" } {
			Sepct::reloadPolicy
		} else  {
			return -1
		} 
	}
	return 0	
}
proc Sepct_Customize::remove_CheckButtons { } {   
	variable list_b
	set items [$list_b items]
	foreach module $items { 
		set cb [$list_b itemcget $module -window]
    		if { [winfo exists $cb] } {
			set rt [catch {destroy $cb} err]
			if {$rt != 0} {
				tk_messageBox -icon error -type ok -title "Error" \
					-message "$err"
				return -1
			}
		}
	} 
	set Sepct_Customize::num_cbuttons 0
	return 0	
}
proc Sepct_Customize::select_all_CheckButtons { } {   
	variable list_b
	set items [$list_b items]
	foreach module $items { 
		if { $Sepct_Customize::cb_value_array($module) == 0 } {
			set cb [$list_b itemcget $module -window] 
			set Sepct_Customize::cb_ID $cb
			$cb invoke
		}
	} 
	return 0	
}
proc Sepct_Customize::set_modIndicator { tabID } {
	variable notebook
	variable te_tabID
	variable fc_tabID	
	if { [Sepct::inReadOnlyMode] } {
		return 0
	}
	if { $tabID == $te_tabID } {
		$notebook itemconfigure $tabID -text "$Sepct_Customize::te_tabName*"
	} elseif { $tabID == $fc_tabID } {
		$notebook itemconfigure $tabID -text "$Sepct_Customize::fc_tabName*"
	} 
	return 0
}
proc Sepct_Customize::remove_modIndicator { tabID } {
	variable notebook
	variable te_tabName			
	variable fc_tabName	
	variable fc_tabID
	variable te_tabID	
	if { $tabID == $te_tabID } {
		$notebook itemconfigure $tabID -text $Sepct_Customize::te_tabName
	} elseif { $tabID == $fc_tabID } {
		$notebook itemconfigure $tabID -text $Sepct_Customize::fc_tabName
	} 
	return 0	
}
proc Sepct_Customize::change_module_status { cb } {
	variable list_b
	variable notebook
	variable curr_TE_file
	if { [Sepct::inReadOnlyMode] } {
		$cb toggle
		return 0
	}
	set splitPath [split $cb ":"]
	set module "[lindex $splitPath end].te"
	if { $Sepct_Customize::cb_value_array($module) } {
		set source_Path [file join $Sepct_Customize::unUsed_Modules_Dir $module]
		set target_Path	[file join $Sepct_Customize::used_Modules_Dir $module]
		set rt [Sepct_Customize::set_Module_As_Used $module $source_Path $target_Path]
	} else {
		set source_Path [file join $Sepct_Customize::used_Modules_Dir $module]
		set target_Path	[file join $Sepct_Customize::unUsed_Modules_Dir $module]
		set rt [Sepct_Customize::set_Module_As_Unused $module $source_Path $target_Path]
	}
    	if { $rt == 0 } {
	    	set raisedPage [$notebook raise]
		if { $raisedPage == $Sepct_Customize::te_tabID && [$list_b selection get] == $module } {
			set curr_TE_file $target_Path
	    		Sepct::update_fileStatus $curr_TE_file 0
	    	} 
    	}
	return 0
}
proc Sepct_Customize::order_Modules_by_Description { module_List } {  
	set desc_Labels_List ""
	foreach module $module_List {
		lappend desc_Labels_List "{[Sepct_Customize::get_mod_descp_label $module]} {$module}"
	}
	set desc_Labels_List [lsort -dictionary $desc_Labels_List]
	set module_List ""
	foreach module $desc_Labels_List {
		lappend module_List [lindex $module end]
	}
	return $module_List
}
proc Sepct_Customize::change_Module_Labels { } {  
    	variable list_b
    	variable curr_TE_file
    	set curr_sel [$list_b selection get]  
    	set module_List [$list_b items]
    	if { $Sepct_Customize::show_Filenames == 1 } {	
		foreach module $module_List {
			$list_b itemconfigure $module -text "  $module"
		}
		set module_List [lsort -dictionary $module_List]
		$list_b reorder $module_List
	} else {
		foreach module $module_List {
			$list_b itemconfigure [lindex $module end] -text " [Sepct_Customize::get_mod_descp_label $module]"
		}
		set module_List [Sepct_Customize::order_Modules_by_Description $module_List]
		$list_b reorder $module_List
	}
	$list_b configure -redraw 1
    	if { [$list_b exists $curr_sel] } {
	    	$list_b selection set $curr_sel
	    	$list_b see $curr_sel 
	} 
    	$list_b.c xview moveto 0
    	update idletasks
	return 0	
}
proc Sepct_Customize::goto_line { line_num } {
	variable text_te
	variable text_fc
	variable curr_TE_file
	variable curr_FC_file
	variable notebook
	if { $curr_TE_file == "" } {
		return 0
	}
	if {[string is integer -strict $line_num] != 1 || [string is digit -strict $line_num] != 1 || [regexp "\[A-Z\]" $line_num]} {
		tk_messageBox -icon error \
			-type ok  \
			-title "Invalid line number" \
			-message "$line_num is not a valid line number"
		return 0
	}
	set raisedPage [$notebook raise]
	if { $raisedPage == $Sepct_Customize::te_tabID } {
    		set text_c $text_te
    		set curr_file $curr_TE_file
    	} elseif { $raisedPage == $Sepct_Customize::fc_tabID } {
    		if { $curr_FC_file == "" } {
			return 0
		}
    		set text_c $text_fc
    		set curr_file $curr_FC_file
    	} else {
    		return 0
    	}
	$text_c mark set insert ${line_num}.0 
	Sepct_db::update_pos $curr_file ${line_num}.0
	$text_c see ${line_num}.0 
	focus -force $text_c
	return 0
}
proc Sepct_Customize::leave_Tab { } {
	Sepct_Customize::record_outstanding_changes
	return 0
}
proc Sepct_Customize::enter_Tab { } {
	variable list_b
	variable curr_TE_file		
	variable curr_FC_file	
	variable text_te_dBit				
	variable text_fc_dBit			
	variable text_te_mcntr			
	variable text_fc_mcntr	
	variable text_te
	variable text_fc
	variable notebook
	if { [Sepct::isPolicyOpened] } {
		if { ![Sepct::inReadOnlyMode] } {	
			$Sepct::mainframe setmenustate ModEditTag normal
		}
		$Sepct::mainframe setmenustate SaveFileTag normal
		$Sepct::mainframe setmenustate RevertTag normal
		$Sepct::mainframe setmenustate SaveFileAsTag disabled
		$Sepct::mainframe setmenustate ConfigTag normal
	}
    	set raisedPage [$notebook raise]
    	if { $raisedPage == $Sepct_Customize::te_tabID } {
    		focus $text_te
    	} elseif { $raisedPage == $Sepct_Customize::fc_tabID } {
    		focus $text_fc
    	} else {
    		return
    	}
    	if { $curr_TE_file != "" } {
    		set updated 0
    		set te_cntr [Sepct_db::get_cntr $curr_TE_file]
    		if { $curr_FC_file != "" } {
    			set fc_cntr [Sepct_db::get_cntr $curr_FC_file]
    		}
		if { $te_cntr != $text_te_mcntr || ($curr_FC_file != "" && ($fc_cntr != $text_fc_mcntr))} {
			set fn $curr_TE_file
			set curr_TE_file ""
    			set rt [Sepct_Customize::displayModule $list_b $text_te $text_fc [file tail $fn]]
    			if {$rt != 0} {
    				return $rt
    			}
    			set updated 1
	    	} 
		if { $raisedPage == $Sepct_Customize::te_tabID } {
	    		Sepct::update_fileStatus $curr_TE_file 1
	    	} else {
			if { $curr_FC_file != "" } {
				Sepct::update_fileStatus $curr_FC_file 1 
			} else {
				Sepct_Customize::remove_modIndicator $raisedPage
				Sepct::clear_fileStatus
			}
	    	}
	} else {
		$text_te delete 0.0 end
		$text_fc delete 0.0 end
		Sepct::clear_fileStatus
		Sepct_Customize::reset_dirtyState
	}	
	return 0
}
proc Sepct_Customize::display_add_Module_Dlg {} {
	variable add_Module_Dlg 
	global tcl_platform
	set Sepct_Customize::newModuleName  	""
	set Sepct_Customize::module_Desc 	""
    	if { [winfo exists .add_Module_Dlg] } {
    		destroy .add_Module_Dlg
    	}
    	set add_Module_Dlg [Dialog .add_Module_Dlg -parent $Sepct::mainWindow \
    		-title "Add Policy Module" -side right]
    	if {$tcl_platform(platform) == "windows"} {
		wm resizable $Sepct_Customize::::add_Module_Dlg 0 0
	} else {
		bind $Sepct_Customize::::add_Module_Dlg <Configure> { wm geometry $Sepct_Customize::::add_Module_Dlg {} }
	}
    	set l_frame 	[frame $add_Module_Dlg.left -relief flat] 
    	set r_frame 	[frame $add_Module_Dlg.right -relief flat] 
    	set lbl_fName  	[label $l_frame.lbl_fName -text "Module Name:"]
    	set lbl_desc  	[label $l_frame.lbl_desc -text "Module Description:"]
    	set name_Entry 	[Entry $r_frame.name_Entry  -textvariable Sepct_Customize::newModuleName -width 40 \
		    		-helptext "Enter a name for the module to be added." -bg white]
	set desc_Entry 	[Entry $r_frame.desc_Entry  -textvariable Sepct_Customize::module_Desc -width 40 \
		    		-helptext "Enter a description for the module to be added." -bg white]
	pack $l_frame $r_frame -side left -anchor center -fill both -expand yes
	pack $lbl_fName $lbl_desc -side top -padx 5 -pady 5 -anchor ne
	pack $name_Entry $desc_Entry -side top -padx 5 -pady 5 -anchor ne
	focus -force $name_Entry
	$add_Module_Dlg add -text "OK" -width 6 -command {set Sepct_Customize::add_Module_Flag 1; $Sepct_Customize::add_Module_Dlg enddialog 1} 		
	$add_Module_Dlg add -text "Cancel" -width 6 -command {set Sepct_Customize::add_Module_Flag 0; $Sepct_Customize::add_Module_Dlg enddialog 0}
	$add_Module_Dlg draw  
	return 0
}
proc Sepct_Customize::switch_internal_tabs { tabID } {
	variable fc_tabID
	variable te_tabID
	variable text_te
	variable text_fc		
	set tabID [Sepct::get_tabname $tabID]
	if { $tabID == $te_tabID } {
		focus $text_te
		set file_displayed $Sepct_Customize::curr_TE_file
	} elseif { $tabID == $fc_tabID } {
		focus $text_fc
		set file_displayed $Sepct_Customize::curr_FC_file
	} 
	if { $file_displayed != "" } {
		Sepct::update_fileStatus $file_displayed 1 
	} else {
		 Sepct::clear_fileStatus
	}
	return 0
}
proc Sepct_Customize::wrap_proc_te { cmd args } {
	if { $Sepct_Customize::curr_TE_file != "" } {
		switch $cmd {
			insert	-
			delete	{ 
				if { [Sepct::inReadOnlyMode] } {
					return 0
				} else {
					if { $Sepct_Customize::text_te_dBit == 0 }  {
						Sepct_Customize::set_modIndicator $Sepct_Customize::te_tabID
						set Sepct_Customize::text_te_dBit 1
					}
					Sepct::update_positionStatus [$Sepct_Customize::text_te index insert]
					}
				}
			mark {
				if { [string compare -length 10 $args "set insert"]  == 0 } {
					uplevel "::${Sepct_Customize::text_te}_" $cmd $args
					Sepct::update_positionStatus [$Sepct_Customize::text_te index insert]
					return
				}
			}
		}
	}
	uplevel "::${Sepct_Customize::text_te}_" $cmd $args
}
proc Sepct_Customize::wrap_proc_fc { cmd args } {
	if { $Sepct_Customize::curr_FC_file != "" } {
		switch $cmd {
			insert	-
			delete	{ 
				if { [Sepct::inReadOnlyMode] } {
					return 0
				} else {
					if { $Sepct_Customize::text_fc_dBit == 0 }  {
						Sepct_Customize::set_modIndicator $Sepct_Customize::fc_tabID
						set Sepct_Customize::text_fc_dBit 1
					}
					Sepct::update_positionStatus [$Sepct_Customize::text_fc index insert]
					}
				}
			mark {
				if { [string compare -length 10 $args "set insert"]  == 0 } {
					uplevel "::${Sepct_Customize::text_fc}_" $cmd $args
					Sepct::update_positionStatus [$Sepct_Customize::text_fc index insert]
					return
				}
			}
		}
	}
	uplevel "::${Sepct_Customize::text_fc}_" $cmd $args
}
proc Sepct_Customize::createNoteBook { tabsBox } {
	variable text_te
	variable text_fc
	variable notebook
	variable te_tabName
	variable fc_tabName
	variable te_tabID			
	variable fc_tabID			
	set notebook [NoteBook $tabsBox.nb -side top]
	set c_frame [$notebook insert end $te_tabID -text $te_tabName]
	set fc_frame [$notebook insert end $fc_tabID -text $fc_tabName]
	set f [frame $c_frame.fc -container 1]
	pack $f
	set sw_c [ScrolledWindow $c_frame.sw_c -auto none]
	set text_te [text [$sw_c getframe].text -bg white -wrap none -font $Sepct::text_font]
	$sw_c setwidget $text_te
	rename $text_te "::${text_te}_"
	rename $Sepct_Customize::text_TE_wrap_proc "::$text_te"
	set sw_fc [ScrolledWindow $fc_frame.sw_fc -auto none]
	set text_fc [text [$sw_fc getframe].text -bg white -wrap none -font $Sepct::text_font]
	$sw_fc setwidget $text_fc
	rename $text_fc "::${text_fc}_"
	rename $Sepct_Customize::text_FC_wrap_proc "::$text_fc"
	pack $sw_c -side left -expand yes -fill both  
	pack $sw_fc -side left -expand yes -fill both
	$notebook bindtabs <Button-1> { Sepct_Customize::switch_internal_tabs }
	$notebook compute_size
	pack $notebook -fill both -expand yes -padx 4 -pady 4
	$notebook raise [$notebook page 0]
	return 0
}
proc Sepct_Customize::create { nb } {
	variable list_b
	variable cb_show_Filenames
	set frame [$nb insert end $Sepct::customize_tab -text "Policy Modules"]
	set topf  [frame $frame.topf -width 100 -height 200]
	set pw1   [PanedWindow $topf.pw -side top]
	set pane  [$pw1 add -weight 2]
	set spane [$pw1 add -weight 4]
	set pw2   [PanedWindow $pane.pw -side left]
	set contents [$pw2 add -weight 2]
	set tabsBox 	[frame $spane.tabsBox]
	set contentsBox 	[TitleFrame $contents.cbox -text "Program Policy Modules"]
	pack $tabsBox -pady 2 -padx 2 -fill both -expand yes -anchor ne 
	pack $contentsBox -padx 2 -side left -fill both -expand yes
	pack $pw1 -fill both -expand yes
	pack $pw2 -fill both -expand yes	
	pack $topf -fill both -expand yes 
	set sw_list [ScrolledWindow [$contentsBox getframe].sw_c -auto none]
	set list_b [ListBox [$contentsBox getframe].lb \
	          -relief flat -borderwidth 0 -bg white \
	          -selectmode single -deltay 25 \
	          -width 20 -highlightthickness 0 \
	          -redraw 0 -padx 25]
	$sw_list setwidget $list_b
	set cb_show_Filenames [checkbutton [$contentsBox getframe].cb_showf \
		-text "Display File Names Only" \
		-command { Sepct_Customize::change_Module_Labels } \
		-variable Sepct_Customize::show_Filenames]
	pack $sw_list -fill both -expand yes 
	pack $cb_show_Filenames -anchor nw -side bottom -pady 1
	Sepct_Customize::createNoteBook $tabsBox
	$list_b bindText  <ButtonPress-1>        { Sepct_Customize::displayModule $Sepct_Customize::list_b $Sepct_Customize::text_te $Sepct_Customize::text_fc}
	$list_b bindText  <Double-ButtonPress-1> { Sepct_Customize::displayModule $Sepct_Customize::list_b $Sepct_Customize::text_te $Sepct_Customize::text_fc}
	Sepct_Customize::initialize_Tab_Vars
	set Sepct_Customize::show_Filenames $Sepct::show_customize_file_names
	return $frame
}
proc Sepct_Customize::delete_Module { } {	
	variable notebook
	variable list_b	
	variable curr_TE_file
	variable curr_FC_file
	variable fc_extension
	variable unUsed_Modules			
	variable used_Modules			
	variable all_Modules
	variable missing_fc_files
	if { $curr_TE_file != "" } {	
		set rt [tk_messageBox -icon warning -type yesno -title "Warning!" \
			-message "About to delete a module.\n\nIt is recommended that you\
				DISABLE the module instead by deselecting the checkbutton\
				next to the module in the listbox.\n\nWould you still like\
				to continue?"]
		if { $rt == "yes" } {
			set rt [tk_messageBox -icon warning -type yesno -title "Warning!" \
				-message "Deleting $curr_TE_file and $curr_FC_file.\n\n\
				Are you sure you want to continue?"]
			if { $rt == "yes" } {
				set rt [catch {file delete $curr_TE_file} err]
				if { $rt != 0 } {
					tk_messageBox -icon error -type ok -title "Error" \
						-message "$err"
					return -1 
				}
				Sepct_Customize::remove_From_All_Module_Lists [file tail $curr_TE_file]
				set rt [Sepct_db::remove_from_mod_List $curr_TE_file ]
			    	if { $rt == -1 } {
			    		tk_messageBox -icon error -type ok -title "Error" \
						-message "Error removing module TE file from internal mod list."			
				}
			    	set rt [Sepct_db::remove_file $curr_TE_file]
			    	if { $rt == -1 } {
			    		tk_messageBox -icon error -type ok -title "Error" \
						-message "Error removing module TE file from internal database."			
				}
				set cb [$list_b itemcget [file tail $curr_TE_file] -window]
		    		if { [winfo exists $cb] } {
					set rt [catch {destroy $cb} err]
					if {$rt != 0} {
						tk_messageBox -icon error -type ok -title "Error" \
							-message "$err"
						return -1
					}
				}
				$list_b delete [file tail $curr_TE_file]
				$Sepct_Customize::text_te delete 0.0 end
				if { $curr_FC_file != "" } {
					set rt [catch {file delete $curr_FC_file} err]
					if { $rt != 0 } {
						tk_messageBox -icon error -type ok -title "Error" \
							-message "$err"				
					}
					set missing_fc_files [Sepct_Customize::remove_Module_from_List $missing_fc_files $curr_FC_file]
					set rt [Sepct_db::remove_from_mod_List $curr_TE_file ]
				    	if { $rt == -1 } {
				    		tk_messageBox -icon error -type ok -title "Error" \
							-message "Error removing module FC from internal mod list."			
					}
				    	set rt [Sepct_db::remove_file $curr_FC_file]
				    	if { $rt == -1 } {
				    		tk_messageBox -icon error -type ok -title "Error" \
							-message "Error removing module FC file from internal database."			
					}
				}
				$Sepct_Customize::text_fc delete 0.0 end
				Sepct_Customize::reset_dirtyState
				set curr_TE_file ""
				set curr_FC_file ""
				Sepct::clear_fileStatus
				Sepct_Customize::remove_modIndicator $Sepct_Customize::te_tabID
				Sepct_Customize::remove_modIndicator $Sepct_Customize::fc_tabID
			}
		} 
	}
	return 0
}
proc Sepct_Customize::add_Module { } {   
	variable list_b
	variable used_Modules 
	variable all_Modules			
	variable text_te_mcntr			
	variable text_fc_mcntr			
	variable fc_path
	variable newModuleName
	variable module_Desc
	variable text_te
	variable text_fc
	Sepct_Customize::display_add_Module_Dlg
	if { $Sepct_Customize::add_Module_Flag } {
		while { $newModuleName == "" } {
			tk_messageBox -icon error -type ok -title "Error" \
			     -message "Module name cannot be empty."
			Sepct_Customize::add_Module
			return -1
		}
		if { $newModuleName != "" } {
			while { [string length $newModuleName] > $Sepct_Customize::max_Label_Length } {
				tk_messageBox -icon error -type ok -title "Error" \
			     		-message "Module name cannot contain more than 255 characters."
			     	Sepct_Customize::add_Module
			     	return -1
			} 
			set rootName [file rootname $newModuleName]		
			while { [string is digit $rootName] || [string is punct $rootName] || [string is space $rootName] } {
				tk_messageBox -icon error -type ok -title "Error" \
			     		-message "Module root name cannot be a digit, punctuation or space."
			     	Sepct_Customize::add_Module
			     	return -1
			} 
			while { [string is wordchar $rootName] == 0 } {
				tk_messageBox -icon error -type ok -title "Error" \
			     		-message "Module root name can only contain alphanumeric characters\
			     		 and any Unicode connector punctuation characters."
			     	Sepct_Customize::add_Module
			     	return -1
			} 
			if { [file extension $newModuleName] == "" } {
				append newModuleName ".te"
			} else {					
				while { [file extension $newModuleName] != ".te" } {
					tk_messageBox -icon error -type ok -title "Error" \
				     		-message "The given file extension is incorrect. Must be .te"
				     	Sepct_Customize::add_Module
				     	return -1
				}
			}
	        }
		set module_Desc    [string trim $module_Desc]
		if { $module_Desc == "" } {
			set module_Desc $newModuleName
		} 
		set data "#DESC $module_Desc\n#\n# File: $newModuleName\n# Author(s):\n#\n"
		set newModulePath  [file join $Sepct_Customize::used_Modules_Dir $newModuleName]
		if { [file exists $newModulePath] == 0 } {
			set rt 	[Sepct_db::file_write $data $newModulePath]
			if { $rt == 0 } {
				set used_Modules [Sepct_Customize::add_Module_to_List $used_Modules $newModuleName]
				set all_Modules  [Sepct_Customize::add_Module_to_List $all_Modules $newModuleName]
				set parent [file dirname $newModulePath]
				if {[Sepct_db::existsTree_node $parent] } {
					set cntr [Sepct_db::add_file $newModulePath 0 "1.0"] 
					if { $cntr == -1 } {
						return -1
					}
					set text_te_mcntr $cntr
				} else {
					puts stderr "Problem, The parent directory $parent does not exist in the db!"
					return -1
				}
				set fcpath 	[file join $Sepct_Customize::fc_path "[file rootname $newModuleName].fc"]
				set fc_data  	"#DESC $module_Desc\n#\n# File: [file tail $fcpath]\n# Author(s):\n#\n"
				if { [file exists $fcpath] == 0 } {
					set rt 	[Sepct_db::file_write $fc_data $fcpath]	
					if { $rt == 0 } {
						set parent [file dirname $fcpath]
						if {[Sepct_db::existsTree_node $parent] } {
							set cntr [Sepct_db::add_file $fcpath 0 "1.0"] 
							if { $cntr == -1 } {
								return -1
							}
							set text_fc_mcntr $cntr
						} else {
							puts stderr "Problem, The parent directory $parent does not exist in the db!"
							return -1
						}
					}
				} else {
					tk_messageBox -icon info  \
						-type ok \
						-parent $Sepct::mainWindow \
						-title "File Exists" \
						-message \
						"$fcpath already exists."
				}
				$list_b insert end $newModuleName \
				 	 -data $module_Desc \
				 	 -window [Sepct_Customize::embed_checkbutton $newModuleName 1]  
				Sepct_Customize::label_and_order_list
				$list_b configure -redraw 1
			    	$list_b.c xview moveto 0
				update idletasks
				if { [$list_b exists $newModuleName] } {
					$list_b see $newModuleName
					Sepct_Customize::displayModule $list_b $text_te $text_fc $newModuleName
				} else {
					set ans [tk_messageBox \
					     -icon error \
					     -type ok \
					     -title "Error" \
					     -message \
						"After updating the listbox, an error occurred\
						while trying to locate the new module $newModuleName in the listbox.\n\
						Press YES to re-load the policy directory or NO to continue."]
					if {$ans == "yes" } {
						Sepct::reloadPolicy
					} 
				}
			}
		} else { 
			tk_messageBox \
			     -icon error \
			     -type ok \
			     -parent $Sepct::mainWindow \
			     -title "Error" \
			     -message \
				"$newModuleName already exists."
		}		
	}
	return 0
}
proc Sepct_Customize::is_module_used { mod_name } {
	variable used_Modules
	if {[lsearch -exact $used_Modules $mod_name] < 0 } {
		return 0
	} else {
		return 1
	}
}
proc Sepct_Customize::get_mod_descp_label { te_file } {
	variable list_b
	if {![$list_b exists $te_file]} {
		return -1
	}
	set idx [$list_b index $te_file]
	set label [$list_b itemcget $te_file -data]
	return $label
}
proc Sepct_Customize::insert_Data { path textBox line col tabID } {
	if { [Sepct_db::is_in_mod_FileArray $path] } {
		$textBox delete 0.0 end
		if {[Sepct_db::getModFile_Data $path data] != 0 } {
			puts stderr "Problem with getting file ($path) data in insert_Data"
			return -1
		}
		$textBox insert end $data
		Sepct_Customize::set_modIndicator $tabID
	} else {
    		if { [Sepct_db::read_fileContents_fromDisk $path data] != 0 } {
    			puts stderr "Problem reading file ($path) from disk."
    			return -1
    		}
		$textBox insert end $data
		Sepct_Customize::remove_modIndicator $tabID
	}
	focus -force $textBox
	$textBox mark set insert $line.$col 
	$textBox see $line.$col 
	return 0	
}
proc Sepct_Customize::save_as { } {
	variable curr_TE_file		
	variable curr_FC_file	
	variable text_te_dBit				
	variable text_fc_dBit			
	variable text_te_mcntr			
	variable text_fc_mcntr	
	variable text_te
	variable text_fc
	variable notebook	
	return 0
	set raisedPage [$notebook raise]
	if { $raisedPage == $Sepct_Customize::te_tabID } {
    		set curr_file $curr_TE_file
    		set text_c $text_te
    		set text_mcntr $text_te_mcntr
    	} elseif { $raisedPage == $Sepct_Customize::fc_tabID } {
    		set curr_file $curr_FC_file
    		set text_c $text_fc
    		set text_mcntr $text_fc_mcntr
    	}
	if { $curr_file != "" } {
		set fileExt [file extension $curr_file]
		set types {
			{"All files"		*}
    		}
		set filename [tk_getSaveFile -initialdir $Sepct::policyDir \
			-title "Save As?" -filetypes $types]
		if { [string equal $filename $curr_file] } {	
			return [Sepct_Customize::save]
		} 
		if { $filename != "" } {
			set parent [file dirname $filename]
			if { ![Sepct_db::existsTree_node  $parent] } {
				tk_messageBox -icon warning \
					-type ok  \
					-title "Save As Warning" \
					-message \
					"Can't save to $parent\n\nCurrently, this tool does not support saving
					outside the policy root directory."
				return 0
			}
			set rt [Sepct_db::file_write [$text_c get 0.0 end] $filename]
			if {$rt != 0 } {
				return -1
			}
			set cntr [Sepct_db::remove_from_mod_List $curr_file]
			if { $cntr >= 0 } {
				set text_mcntr $cntr
			} elseif {$cntr == -1 } {
				return -1
			}
			set curr_file $filename				
			Sepct::update_fileStatus $filename	
			Sepct_Customize::remove_modIndicator $raisedPage
			Sepct_Customize::reset_dirtyState
		}	
	}
	return 0
}
proc Sepct_Customize::save_Configuration {filename} {			
	variable unUsed_Modules			
	variable used_Modules		
	Sepct::writeConfigFile $filename $used_Modules $unUsed_Modules			
	return 0
}
proc Sepct_Customize::load_policy_configuration {used_Mods unUsed_Mods} {
	variable used_Modules_Dir	
	variable unUsed_Modules_Dir
	foreach used_Mod $used_Mods {
		set source_Path [file join $unUsed_Modules_Dir $used_Mod]
		set target_Path	[file join $used_Modules_Dir $used_Mod]
		if { [file exists $source_Path] } {
			set rt [Sepct_Customize::set_Module_As_Used $used_Mod $source_Path $target_Path]
			if {[array get Sepct_Customize::cb_value_array "$used_Mod"] != ""} {
				set Sepct_Customize::cb_value_array($used_Mod) 1
			}
		} elseif {[file exists $target_Path] == 0} {
			puts "$used_Mod does not exist in $used_Modules_Dir or $unUsed_Modules_Dir and will be ignored."
		}
	}
	foreach unUsed_Mod $unUsed_Mods {
		set source_Path [file join $used_Modules_Dir $unUsed_Mod]
		set target_Path	[file join $unUsed_Modules_Dir $unUsed_Mod]
		if { [file exists $source_Path] } {
			set rt [Sepct_Customize::set_Module_As_Unused $unUsed_Mod $source_Path $target_Path]
			if {[array get Sepct_Customize::cb_value_array "$unUsed_Mod"] != ""} {
				set Sepct_Customize::cb_value_array($unUsed_Mod) 0
			}
		} elseif {[file exists $target_Path] == 0} {
			puts "$used_Mod does not exist in $used_Modules_Dir or $unUsed_Modules_Dir and will be ignored."
		}
	}
	return 0
}
proc Sepct_Customize::is_in_modules_list {mod_name} {
	variable all_Modules
	set idx [lsearch -exact $all_Modules $mod_name]
	if {$idx != -1} {
		return 1
	}
	return 0
}
proc Sepct_Customize::get_num_mods {} {
	variable all_Modules
	return [llength $all_Modules]
}
proc Sepct_Customize::save { } {
	variable curr_TE_file		
	variable curr_FC_file	
	variable text_te_dBit				
	variable text_fc_dBit			
	variable text_te_mcntr			
	variable text_fc_mcntr	
	variable text_te
	variable text_fc
	variable notebook
	if { $curr_TE_file == "" } {
		return 0
	} else {
		if { $text_te_dBit } {
			set cntr [Sepct_db::add_to_mod_List $curr_TE_file [$text_te get 0.0 end]]
			if { $cntr == -1 } {
				return -1
			}
			set mod 1
		} else {
			set mod [Sepct_db::is_in_mod_FileArray $curr_TE_file]
		}
		if {$mod} {
			set cntr [Sepct_db::saveFile $curr_TE_file [$text_te index insert]]
			if {$cntr == -1 } {
				return -1
			}
			set text_te_mcntr $cntr
			Sepct_Customize::remove_modIndicator $Sepct_Customize::te_tabID
		} 
	}
	if { $curr_FC_file != "" } {
		if { $text_fc_dBit } {
			set cntr [Sepct_db::add_to_mod_List $curr_FC_file [$text_fc get 0.0 end]]
			if { $cntr == -1 } {
				return -1
			}
			set mod 1
		} else {
			set mod [Sepct_db::is_in_mod_FileArray $curr_FC_file]
		}
		if {$mod} {
			set cntr [Sepct_db::saveFile $curr_FC_file [$text_fc index insert]]
			if {$cntr == -1 } {
				return -1
			}
			set text_te_mcntr $cntr
			Sepct_Customize::remove_modIndicator $Sepct_Customize::fc_tabID
		} 
	}
	Sepct_Customize::reset_dirtyState
	set raisedPage [$notebook raise]
	if { $raisedPage == $Sepct_Customize::te_tabID } {
    		Sepct::update_fileStatus $curr_TE_file 1
    	} elseif { $raisedPage == $Sepct_Customize::fc_tabID } {
    		Sepct::update_fileStatus $curr_FC_file 1
    	}
	return 0
}
proc Sepct_Customize::revert_file { } {
	variable curr_TE_file		
	variable curr_FC_file				
	variable text_te_mcntr			
	variable text_fc_mcntr	
	variable list_b
	variable text_te
	variable text_fc
	variable notebook
	if { $curr_TE_file == "" } {
		return 0
	}
	set cntr [Sepct_db::discard_Single_File_Changes $curr_TE_file ]
	if { $cntr >= 0 } {
		set text_te_mcntr $cntr
	} elseif {$cntr == -1} {
		puts stderr "Problem displaying file in revert_file"
		return -1
	}
	if { $curr_FC_file != "" } {
		set cntr [Sepct_db::discard_Single_File_Changes $curr_FC_file ]
		if { $cntr >= 0 } {
			set text_fc_mcntr $cntr
		} elseif {$cntr == -1} {
			puts stderr "Problem displaying file in revert_file"
			return -1
		}
	}
	set fn $curr_TE_file
	set curr_TE_file ""
	set rt [Sepct_Customize::displayModule $list_b $text_te $text_fc [file tail $fn]]
	return $rt
}
proc Sepct_Customize::close { } {		
	variable list_b
	variable text_te
	variable text_fc
	set rt [Sepct_Customize::remove_CheckButtons]
	if {$rt != 0} {
		return -1
	}
	$list_b delete [$list_b items]
	$text_te delete 0.0 end
	$text_fc delete 0.0 end
	Sepct_Customize::initialize_Tab_Vars
	Sepct_Customize::remove_modIndicator $Sepct_Customize::te_tabID
	Sepct_Customize::remove_modIndicator $Sepct_Customize::fc_tabID
	return 0
}
proc Sepct_Customize::search { str case_Insensitive regExpr srch_Direction } {
	variable text_te
	variable text_fc
	variable notebook
	variable te_tabID		
	variable fc_tabID	
	set raisedPage [$notebook raise]
	if { $raisedPage == $te_tabID } {
		Sepct::textSearch $text_te $str $case_Insensitive $regExpr $srch_Direction
	} elseif { $raisedPage == $fc_tabID } {
		Sepct::textSearch $text_fc $str $case_Insensitive $regExpr $srch_Direction
	} else {
		return
	}
	return 0
}
proc Sepct_Customize::record_TE_outstanding_changes { } {
	variable curr_TE_file	
	variable text_te_dBit			
	variable text_te_mcntr	
	variable text_te
	if { $curr_TE_file != "" } {
		if { $text_te_dBit } {
			set cntr [Sepct_db::add_to_mod_List $curr_TE_file [$text_te get 0.0 end]]
			if { $cntr == -1 } {
				return -1
			}
			set text_te_mcntr $cntr
			Sepct_db::update_pos $curr_TE_file [$text_te index insert]
			return $cntr
		}
	}	
	return -2
}
proc Sepct_Customize::record_FC_outstanding_changes { } {		
	variable curr_FC_file				
	variable text_fc_dBit			
	variable text_fc_mcntr	
	variable text_fc
	if { $curr_FC_file != "" } {
		if { $text_fc_dBit } {
			set cntr [Sepct_db::add_to_mod_List $curr_FC_file [$text_fc get 0.0 end]]
			if { $cntr == -1 } {
				return -1
			}
			set text_fc_mcntr $cntr
			Sepct_db::update_pos $curr_FC_file [$text_fc index insert]
			return $cntr
		}
	}
	return -2
}
proc Sepct_Customize::record_outstanding_changes { } {
	Sepct_Customize::record_TE_outstanding_changes
	Sepct_Customize::record_FC_outstanding_changes
	return 0
}
proc Sepct_Customize::create_unUsed_Modules_Dir {} {
	if { [file exists $Sepct_Customize::used_Modules_Dir] } {
		set rt [catch {file mkdir $Sepct_Customize::unUsed_Modules_Dir} err]
		if {$rt != 0} {
			return -code error $err
		}
		set rt [Sepct_db::addTree_node $Sepct_Customize::unUsed_Modules_Dir 0 0]
		if {$rt != 0} {
			return -code error "Problem adding unused directory node in tree."
		}
	} else { 
		return -code error "$Sepct_Customize::used_Modules_Dir is not a directory"
	}	
	return 0
}
proc Sepct_Customize::move_file_on_disk { source_Path target_dir overwrite } {
	if {$overwrite} {
		set rt [catch {file rename -force $source_Path $target_dir} err]
	} else {
		set rt [catch {file rename $source_Path $target_dir} err]
	}
	if { $rt != 0 } {
		return -code $err
	}
	return 0
}
proc Sepct_Customize::set_Module_As_Unused { module source_Path target_Path } {
	variable list_b
	variable curr_TE_file
	set cb [$list_b itemcget $module -window]
	set overwrite 0		   	
	if { [file exists $target_Path] && ![file exists $source_Path]} {
		set ans [tk_messageBox -icon error -type yesno -title "File Error" -message \
				"File $target_Path already exists.\n\
				Press YES to re-load the policy directory \
				or NO to do nothing and continue."]
		if {$ans == "yes" } {
			Sepct::reloadPolicy
		} else {
			$cb toggle
		}
		return -1 
	} 
	if { [file exists $target_Path] && [file exists $source_Path] } {
		set ans [tk_messageBox -icon error -type yesno -title "File Error" -message \
				"Duplicate $module modules exists.\n\n\
				Press YES to overwrite $target_Path with $source_Path or NO to do nothing and continue."]
		if {$ans != "yes" } {
			$cb toggle
			return -1 
		} else {
			set overwrite 1
		}
	} 
	if { ![file exists $Sepct_Customize::unUsed_Modules_Dir] } {
		set rt [catch {Sepct_Customize::create_unUsed_Modules_Dir} err]
		if { $rt != 0 } {
			tk_messageBox -icon error \
				-type ok \
				-title "Error" \
				-message \
				"Error creating unused modules directory: $err"
			$cb toggle
			return -1
		}
	}
	set rt [catch {Sepct_Customize::move_file_on_disk $source_Path $Sepct_Customize::unUsed_Modules_Dir $overwrite} err]
	if { $rt != 0 } {
		tk_messageBox -icon error \
			-type ok \
			-title "Error" \
			-message \
			"Error moving $module: $err"
		$cb toggle
		return -1
	}
    	set rt [catch {Sepct_Customize::move_Module_to_Unused_List $module} err]
	if {$rt == -1} {
		set ans [tk_messageBox -icon error -type yesno -title "Error" -message \
				"Problem moving file to new tree node.\n\
				Press YES to re-load the policy directory\
				or NO to continue"]
		if { $ans == "yes" } {
			Sepct::reloadPolicy
			return -1
		} else {
			$cb toggle	
		}
	}	    		
	return 0
}
proc Sepct_Customize::set_Module_As_Used { module source_Path target_Path } {
	variable list_b
	variable curr_TE_file
    	set cb [$list_b itemcget $module -window]
    	set overwrite 0
	if { [file exists $target_Path] && ![file exists $source_Path] } {
		set ans [tk_messageBox -icon error -type yesno -title "File Error" -message \
				"File $target_Path already exists.\n\
				Press YES to re-load the policy directory \
				or NO to do nothing and continue."]
		if {$ans == "yes" } {
			Sepct::reloadPolicy
		} else {
			$cb toggle
		}
		return -1 
	} 
	if { [file exists $target_Path] && [file exists $source_Path] } {
		set overwrite 0	
		set ans [tk_messageBox -icon error -type yesno -title "File Error" -message \
				"Duplicate $module modules exists.\n\n\
				Press YES to overwrite $target_Path with $source_Path or NO to do nothing and continue."]
		if {$ans != "yes" } {
			$cb toggle
			return -1 
		} else {
			set overwrite 1
		}
	} 
	if { ![file exists $Sepct_Customize::used_Modules_Dir] } {
		tk_messageBox -icon error \
			-type ok \
			-title "Directory Problem" \
			-message \
			"The directory $Sepct_Customize::used_Modules_Dir\
			DOES NOT exist. Cannot move $source_Path to this directory."
		$cb toggle
		return	
	} 
	set rt [catch {Sepct_Customize::move_file_on_disk $source_Path $Sepct_Customize::used_Modules_Dir $overwrite} err]
	if { $rt != 0 } {
		tk_messageBox -icon error \
			-type ok \
			-title "Error" \
			-message \
			"$err"
		$cb toggle
		return -1
	}
    	set rt [catch {Sepct_Customize::move_Module_to_Used_List $module} err]
        if { $rt == -1 } {
    		set ans [tk_messageBox -icon error -type yesno -title "Error" -message \
			"Problem moving file to new tree node.\n\
			Press YES to re-load the policy directory\
			or NO to continue"]
		if { $ans == "yes" } {
			Sepct::reloadPolicy
			return -1
		} else {
			$cb toggle			
		}
	}	
	return 0
}
proc Sepct_Customize::initialize_Tab_Vars {  } {
	set Sepct_Customize::text_te_dBit		0	
	set Sepct_Customize::text_fc_dBit		0
	set Sepct_Customize::text_te_mcntr		0
	set Sepct_Customize::text_fc_mcntr		0
	set Sepct_Customize::add_Module_Flag		0
	set Sepct_Customize::curr_TE_file		""
	set Sepct_Customize::curr_FC_file		""
	set Sepct_Customize::used_Modules_Dir 		""
	set Sepct_Customize::unUsed_Modules_Dir 	""
	set Sepct_Customize::fc_path 			""
	set Sepct_Customize::all_Modules 		""
	set Sepct_Customize::unUsed_Modules 		""
	set Sepct_Customize::used_Modules 		""
	set Sepct_Customize::missing_fc_files 		""
	set Sepct_Customize::cb_ID			""
	set Sepct_Customize::newModuleName		""
    	set Sepct_Customize::module_Desc		""
	array unset Sepct_Customize::cb_value_array
	return 0
}
proc Sepct_Customize::reset_dirtyState { } {
	variable text_te_dBit	
	variable text_fc_dBit
	set text_te_dBit 0
	set text_fc_dBit 0
	return 0
}
proc Sepct_Customize::get_all_Modules { } {
	variable used_Modules_Dir
	variable unUsed_Modules_Dir
	variable used_Modules 
	variable unUsed_Modules
	variable all_Modules
	set used [Sepct_db::getFileNames $used_Modules_Dir]
	if { [llength $used] == 1 && $used == "-1" } {
		puts stderr "Problem getting used modules; used dir ($used_Modules_Dir)"
		return -1
	}
	foreach fn $used {	
		if { [file extension $fn] == ".te" } {
			lappend used_Modules $fn
			lappend all_Modules $fn
		}
	}
	set unused [Sepct_db::getFileNames $unUsed_Modules_Dir]
	if { [llength $unused] == 1 && $unused == "-1" } {
		set unUsed_Modules ""
	}
	foreach fn $unused {	
		if { [file extension $fn] == ".te" } {
			lappend unUsed_Modules $fn
			lappend all_Modules $fn
		}
	}
	set all_Modules [lsort -dictionary $all_Modules]
	return 0
}
proc Sepct_Customize::store_mod_descrptive_name { mod_name is_used } {
	variable max_Label_Length
	if {$is_used} {
		set path [file join $Sepct_Customize::used_Modules_Dir $mod_name]
	} else {
		set path [file join $Sepct_Customize::unUsed_Modules_Dir $mod_name]
	}
	if { [file exists $path] } {
		if { [file readable $path] } {
			set file_channel [::open $path r]
			set data ""
			gets $file_channel data
			::close $file_channel
			set split_s [split $data " "]
			set first [lindex $split_s 0]
			if { [string match "$Sepct_Customize::desc_ID" $first] } {
				set d_string [string range $data \
					[expr {[string length $Sepct_Customize::desc_ID] + 1}] end]	
				if { [string length $d_string] > $max_Label_Length } {
					set d_string [string range $d_string 0 $max_Label_Length]
				}
				return [string trim $d_string]
			} else {
				return $mod_name
			}
		} else {
			return "$mod_name (unreadable)"
		}
	} else {
		puts stderr "Can't store module label: canot find $path "
		return -1
	}
}
proc Sepct_Customize::check_fc_consistency {} {
	variable all_Modules
	variable fc_path
	variable missing_fc_files
	set fc_dir_files [Sepct_db::getFileNames $fc_path]
	if { [llength $fc_dir_files] == 1 && $fc_dir_files == "-1" } {
		puts stderr "Problem getting module .fc files; fc_path ($fc_path)"
		return -1
	}
	set fc_files ""
	foreach fn $fc_dir_files {	
		if { [file extension $fn] == ".fc" } {
			lappend fc_files $fn
		}
	}
	set missing_fc_files ""
	foreach te_file $all_Modules {
		set fcname "[file rootname $fn].fc"
		if { [lsearch -exact $fc_files $fcname] == -1 } {
			lappend missing_fc_files $fcname
		}
	}
	return 0
}
proc Sepct_Customize::remove_Module_from_List { moduleList module } {	
	set idx [lsearch -exact $moduleList $module]
	if { $idx == -1 } {
		return 0	
	}
	set moduleList [lreplace $moduleList $idx $idx]
	return $moduleList
}
proc Sepct_Customize::add_Module_to_List { moduleList module } {	
	set idx [lsearch -exact $moduleList $module]
	if { $idx == -1 } {
		lappend moduleList $module
	}
	return $moduleList
}
proc Sepct_Customize::move_Module_to_Unused_List { module source_Path target_Path } {
	variable used_Modules 
	variable unUsed_Modules
	set used_Modules   [Sepct_Customize::remove_Module_from_List $used_Modules $module]
	set unUsed_Modules [Sepct_Customize::add_Module_to_List $unUsed_Modules $module]
    	set rt [Sepct_db::move_file $source_Path $target_Path]
	return $rt
}
proc Sepct_Customize::move_Module_to_Used_List { module source_Path target_Path } {
	variable used_Modules 
	variable unUsed_Modules
	set unUsed_Modules [Sepct_Customize::remove_Module_from_List $unUsed_Modules $module]
	set used_Modules   [Sepct_Customize::add_Module_to_List $used_Modules $module]
    	set rt [Sepct_db::move_file $source_Path $target_Path]	
	return $rt
}
proc Sepct_Customize::remove_From_All_Module_Lists { module } {
	variable used_Modules 
	variable unUsed_Modules
	variable all_Modules
	if { [Sepct_Customize::is_module_used $module] } {
		set used_Modules   [Sepct_Customize::remove_Module_from_List $used_Modules $module]
	} else {
		set unUsed_Modules [Sepct_Customize::remove_Module_from_List $unUsed_Modules $module]
	}		    	
    	set all_Modules [Sepct_Customize::remove_Module_from_List $all_Modules $module]
	return 0
}
namespace eval Sepct_Test {    
	variable progressmsg		""
	variable indicator 		0
	variable MakeOutputTabName	"Sepct_MakeOutputTab"
	variable PolicyConfTabName	"Sepct_PolicyConf"
	variable notebook
	variable textbox_makeOutput
	variable textbox_policyConf
	variable progressDlg
	set progressDlg .progress
	variable b_test
	variable b_clean
	variable b_install
	variable b_reload
	variable b_view_pc
	variable mod_disabled		1
	variable policy_conf_opened	0
	variable tmpfilename		""
	variable policy_conf_wrap_proc	"Sepct_Test::wrap_proc_policy_conf"
	variable indicator
	variable progressmsg
}
proc Sepct_Test::wrap_proc_policy_conf { cmd args } {
	switch $cmd {
		insert	-
		delete	{ 
			set lpos [$Sepct_Test::textbox_policyConf index insert]
			Sepct::update_positionStatus $lpos
			if { $Sepct_Test::mod_disabled  } {
				return
			}
		}
		mark 	{	
			if { [string compare -length 10 $args "set insert"]  == 0 } {
				uplevel "::${Sepct_Test::textbox_policyConf}_" $cmd $args
				set lpos [$Sepct_Test::textbox_policyConf index insert]
				Sepct::update_positionStatus $lpos
				return 
			}
		}
	}
	# don't use a return after this!
	uplevel "::${Sepct_Test::textbox_policyConf}_" $cmd $args
}
proc Sepct_Test::enableMods {} {
	variable mod_disabled
	variable textbox_makeOutput
	$textbox_makeOutput configure -state normal
	set mod_disabled 0
	return  0
}
proc Sepct_Test::disableMods {} {
	variable mod_disabled
	variable textbox_makeOutput
	$textbox_makeOutput configure -state disabled
	set mod_disabled 1
	return  0
}
proc Sepct_Test::save_as { } {
	return 0
}
proc Sepct_Test::save { } {
	return 0
}
proc Sepct_Test::revert_file { } {
	return 0
}
proc Sepct_Test::initialize { } {
	variable b_test
	variable b_clean
	variable b_install
	variable b_reload
	variable b_view_pc
	$b_test configure -state normal
	$b_clean configure -state normal
	$b_install configure -state normal
	$b_reload configure -state normal
	$b_view_pc configure -state normal
	return 0
}
proc Sepct_Test::close { } {
	variable b_test
	variable b_clean
	variable b_install
	variable b_reload
	variable b_view_pc
	$b_test configure -state disabled
	$b_clean configure -state disabled
	$b_install configure -state disabled
	$b_reload configure -state disabled
	$b_view_pc configure -state disabled
	Sepct_Test::clear_Output
	return 0
}
proc Sepct_Test::leave_Tab { } {
	# Nothing to do!
	return 0
}
proc Sepct_Test::enter_Tab { } {
	variable notebook
	variable textbox_policyConf
	variable textbox_makeOutput
	variable MakeOutputTabName
	if { [$notebook raise] == $MakeOutputTabName } {
		focus $textbox_makeOutput
	} else {
		focus $textbox_policyConf
	}
	if { [Sepct::isPolicyOpened] } {
		$Sepct::mainframe setmenustate ModEditTag disabled
		$Sepct::mainframe setmenustate SaveFileTag disabled
		$Sepct::mainframe setmenustate SaveFileAsTag disabled
		$Sepct::mainframe setmenustate RevertTag disabled
		$Sepct::mainframe setmenustate ConfigTag disabled
	}
	return 0
}
proc Sepct_Test::switch_internal_tab { tabID } {
    	variable textbox_makeOutput
    	variable textbox_policyConf
    	variable MakeOutputTabName
    	variable policy_conf_opened
  	set tabID [Sepct::get_tabname $tabID]
	if { $tabID == $MakeOutputTabName } {
		focus $textbox_makeOutput
		Sepct::clear_fileStatus
	} else {
		focus $textbox_policyConf
		if { $policy_conf_opened && [file exists [file join $Sepct::policyDir "policy.conf"]]} {
			Sepct::update_fileStatus [file join $Sepct::policyDir "policy.conf"] 0
			Sepct::update_positionStatus [$Sepct_Test::textbox_policyConf index insert]
		} else {
			Sepct::clear_fileStatus
		}
	}
    	return 0
}
proc Sepct_Test::search { str case_Insensitive regExpr srch_Direction } {
	variable notebook
	variable textbox_makeOutput
	variable textbox_policyConf
	variable MakeOutputTabName	
	variable PolicyConfTabName
	set raisedPage [$notebook raise]
	if { $raisedPage == $MakeOutputTabName } {
		Sepct::textSearch $textbox_makeOutput $str $case_Insensitive $regExpr $srch_Direction
	} elseif { $raisedPage == $PolicyConfTabName } {
		Sepct::textSearch $textbox_policyConf $str $case_Insensitive $regExpr $srch_Direction
	} else {
		return
	}
	return 0
}
proc Sepct_Test::goto_line { line_num} {
	variable notebook
    	variable textbox_policyConf
    	variable MakeOutputTabName
	if { ![Sepct::isPolicyOpened] } {
		return -1
	}
	if { [$notebook raise] == $MakeOutputTabName } {
		return 0
	} 
	if {[string is integer -strict $line_num] != 1 || [string is digit -strict $line_num] != 1 || [regexp "\[A-Z\]" $line_num]} {
		tk_messageBox -icon error \
			-type ok  \
			-title "Invalid line number" \
			-message "$line_num is not a valid line number"
		return 0
	}
	$textbox_policyConf mark set insert ${line_num}.0 
	$textbox_policyConf see ${line_num}.0 
	focus -force $textbox_policyConf
	return 0
}
proc Sepct_Test::get_LineNum_Info {} {
	variable notebook
    	variable textbox_makeOutput
    	variable textbox_policyConf
    	variable MakeOutputTabName
    	variable PolicyConfTabName
	if { ![Sepct::isPolicyOpened] } {
		return -1
	}
	set raisedPage [$notebook raise]
	if { $raisedPage == $MakeOutputTabName } {
		set tBox $textbox_makeOutput
	} elseif { $raisedPage == $PolicyConfTabName } {
		set tBox $textbox_policyConf		
	}
	set indices  [$tBox mark names]
	set line_num [$tBox index [lindex $indices 0]]
    	return $line_num
}
proc Sepct_Test::display_Updated_Policy { } {
	variable textbox_makeOutput
   	variable textbox_policyConf
	if { ![Sepct::isPolicyOpened] } {
		return 1
	}
	set path [file join $Sepct::policyDir "policy.conf"]
	if { [file exists $path] } {
		if { [file readable $path] } {
			set file_channel [open $path r]
			set data [read $file_channel]
			::close $file_channel
			$textbox_policyConf delete 0.0 end
			$textbox_policyConf insert end $data 
			set data ""
		} else {
			tk_messageBox -icon warning \
			-type ok \
			-title "Permission Problem" \
			-message \
			"You do not have permission to read this file."
		}
	}
    	return 0
}
proc Sepct_Test::display_test_policy_conf { } {
   	variable textbox_policyConf
   	variable policy_conf_opened
	set path [file join $Sepct::policyDir "policy.conf"]
	Sepct_Test::enableMods
	$textbox_policyConf delete 0.0 end
	if { [file exists $path] } {
		if { [file readable $path] } {
			set file_channel [::open $path r]
			set data [read $file_channel]
			::close $file_channel
			$textbox_policyConf insert end $data 
			set policy_conf_opened 1
		} else {
			$textbox_policyConf insert end "<policy.conf file exists but is not readable>"
			set policy_conf_opened 0
		}
	} else {
		$textbox_policyConf insert end "<policy.conf file does not exist>"
		set policy_conf_opened 0
	}		
	$textbox_policyConf mark set insert 0.0 
	$textbox_policyConf see 0.0
	Sepct_Test::disableMods
	if {$policy_conf_opened } {
    		Sepct_Test::switch_internal_tab $Sepct_Test::PolicyConfTabName
    	}
    	return 0
}
proc Sepct_Test::open_tmp_file {  } {
	variable tmpfilename
	set chars "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
	set num_chars 8
	set num_tries 8
	set fn_prefix "/tmp/sepcut-"
	set mypid [pid]
	set access [list WRONLY CREAT TRUNC EXCL]
	set perms 0600
	set opened_channel ""
     	for {set i 0} {$i < $num_tries} {incr i} {
 		set fn $fn_prefix
 		for {set j 0} {$j < $num_chars} {incr j} {
 			append fn [string index $chars [expr ([clock clicks] ^ $mypid) % 62]]
		}
		if {[file exists $fn]} {
	 	    	after 1
		} else {
			if {![catch {open $fn $access $perms} opened_channel]} {
				set tmpfilename $fn
				return $opened_channel
		    	}
		    	# TODO: prob should make sure dir is writeable before trying again!
		}
	}
	# If we're here we failed to create the file!
	puts stderr "Failed to create a unique temporary file with prefect $fn_prefix"
	error "Failed to create a unique temporary file with prefect $fn_prefix"
}
proc Sepct_Test::test_Policy { which button } {
	variable textbox_makeOutput
   	variable textbox_policyConf
   	variable MakeOutputTabName
   	variable notebook
   	variable progressmsg
   	variable progressBar
	variable tmpfilename
	variable saveall_choice
   	variable policy_conf_opened
	variable progressDlg
	if { ![Sepct::isPolicyOpened] } {
		return -1
	}
	if {[winfo exists $progressDlg]} {
		return	
	}
	set canceled [Sepct::checkAndSaveChanges]
	if {$canceled < 0 } {
		return -1
	}
	Sepct_Test::enableMods
	if { $canceled == 0 } {
		cd $Sepct::policyDir
		# create a temp file channel with WRONLY access only!
                if { [catch {set of [ Sepct_Test::open_tmp_file ] } ] } {
                	return -1
                }
                $button configure -state disabled
		set progressBar [ ProgressDlg $progressDlg -parent $Sepct::mainWindow -title "Making policy..."  \
                	-textvariable Sepct_Test::progressmsg -variable Sepct_Test::indicator -maximum 6]
		set Sepct_Test::indicator 0
		switch $which {
			test {
				$textbox_policyConf delete 0.0 end
				set policy_conf_opened 0
				set Sepct_Test::indicator 1
				set Sepct_Test::progressmsg "Compiling policy"
				update idletasks
				set rt [catch {eval [list exec make policy >&@ $of]} err]	
				if {$rt != 0} {
					set msg "Problem making policy.conf"
				}			
			}
			clean {
				$textbox_policyConf delete 0.0 end
				set policy_conf_opened 0
				set Sepct_Test::indicator 1
				set Sepct_Test::progressmsg "Cleaning policy"
				update idletasks
				set rt [catch {exec make clean >&@ $of} ]
				if {$rt != 0} {
					set msg "Problem cleaning policy"
				}
			}
			install {
				set Sepct_Test::indicator 1
				set Sepct_Test::progressmsg "Installing policy"
				update idletasks
				set rt [catch {eval [list exec make install >&@ $of]} err]
				if {$rt != 0} {
					set msg "Problem installing policy"
				}
			}
			load {
				set Sepct_Test::indicator 1
				set Sepct_Test::progressmsg "Loading policy"
				update idletasks
				set rt [catch {eval [list exec make reload >&@ $of]} err]
				if {$rt != 0} {
					set msg "Problem loading policy"
				}
			}
			relabel {
				set ans [tk_messageBox \
						-icon warning \
						-type yesno \
						-title "Takes Several Minutes" \
						-message "Relabeling files could take several minutes.  Would you like to continue?"]
				if { $ans == "yes" } {
					set Sepct_Test::indicator 1
					set Sepct_Test::progressmsg "Relabeling Files"
					update idletasks
					set rt [catch {eval [list exec make relabel >&@ $of]} err]
					if {$rt != 0} {
						set msg "Problem relabeling policy"
					}
				}
			}
			default {
				$button configure -state normal
				destroy $progressBar
				Sepct_Test::disableMods
				return -1
			}		
		}
		set Sepct_Test::indicator 2
		set data ""
		::close $of
		set rt [catch {set of [::open $tmpfilename "RDONLY"]} err]
		if {$rt != 0} {
			destroy $progressBar
			$button configure -state normal
		}
		set Sepct_Test::indicator 3
		set rt [catch {set data [::read $of]} err]
		if {$rt != 0} {
			destroy $progressBar
			$button configure -state normal
		}
		set Sepct_Test::indicator 4
		::close $of
		file delete $tmpfilename
		set Sepct_Test::indicator 5
		$textbox_makeOutput delete 0.0 end
		$textbox_makeOutput insert end $data
		focus -force $textbox_makeOutput
		$textbox_makeOutput mark set insert 0.0 
		$textbox_makeOutput see 0.0
		set Sepct_Test::indicator 6		
		destroy $progressBar
		$button configure -state normal
	}	
	focus $textbox_makeOutput
	Sepct_Test::switch_internal_tab $MakeOutputTabName
	$notebook raise $MakeOutputTabName
	Sepct_Test::disableMods
	return 0
}
proc Sepct_Test::clear_Output { } {
	variable textbox_makeOutput
   	variable textbox_policyConf
   	variable policy_conf_opened
	Sepct_Test::enableMods   	
	$textbox_makeOutput delete 0.0 end
	$textbox_policyConf delete 0.0 end
	set policy_conf_opened 0
	Sepct_Test::disableMods
    	return 0
}
proc Sepct_Test::createNoteBook { tabsBox } {
    variable textbox_makeOutput
    variable textbox_policyConf
    variable notebook
    set notebook [NoteBook $tabsBox.nb -side top]
    set c_frame [$notebook insert end $Sepct_Test::MakeOutputTabName -text "Make output"]
    set fc_frame [$notebook insert end $Sepct_Test::PolicyConfTabName -text "policy.conf file"]
    set sw_c [ScrolledWindow $c_frame.sw_c -auto none]
    set textbox_makeOutput [text [$sw_c getframe].text -bg white -wrap none -font $Sepct::text_font]
    $sw_c setwidget $textbox_makeOutput
    set sw_fc [ScrolledWindow $fc_frame.sw_fc -auto none]
    set textbox_policyConf [text [$sw_fc getframe].text -bg white -wrap none -font $Sepct::text_font]
    $sw_fc setwidget $textbox_policyConf
    rename $textbox_policyConf "::${textbox_policyConf}_"
    rename $Sepct_Test::policy_conf_wrap_proc "::$textbox_policyConf"
    pack $sw_c -side left -expand yes -fill both  
    pack $sw_fc -side left -expand yes -fill both
    $notebook compute_size
    pack $notebook -fill both -expand yes -padx 4 -pady 4
    $notebook raise [$notebook page 0]
    $notebook bindtabs <Button-1> { Sepct_Test::switch_internal_tab }
    Sepct_Test::disableMods
    return 0
}
proc Sepct_Test::create { nb } {
	variable b_test
	variable b_clean
	variable b_install
	variable b_reload
	variable b_view_pc
	variable b_relabel
	set frame 	[$nb insert end $Sepct::test_tab -text "Test Policy"]
	set rightf  [frame $frame.rightf -width 100 -height 200]
	set leftf   [frame $frame.leftf -width 100 -height 200]
	pack $leftf -padx 2 -fill both -expand yes -anchor nw -side left
	pack $rightf -padx 2 -pady 2 -fill y -anchor ne -side left -after $leftf
	set b_test    [Button $rightf.test  -text "Test Policy" -width 8 \
		-helptype balloon \
		-helptext "Test build policy.conf to check \nfor policy compile errors"]
	$b_test configure -command "Sepct_Test::test_Policy test $b_test"
	set b_clean   [Button $rightf.clean  -text "Clean Policy" -width 8  \
		-helptype balloon \
		-helptext "Clean policy make directory\n(\"make clean\")"]
	$b_clean configure -command "Sepct_Test::test_Policy clean $b_clean"
	set b_install [Button $rightf.install -text "Install Policy" -width 8   \
		-helptype balloon \
		-helptext "Build binary policy and install\nit, but don't load into running system"]
	$b_install configure -command "Sepct_Test::test_Policy install $b_install"
	set b_reload  [Button $rightf.reload  -text "Load Policy" -width 8  \
		-helptype balloon \
		-helptext "Build binary policy and install\nand load it into running system"]
	$b_reload configure -command "Sepct_Test::test_Policy load $b_reload"
	set b_view_pc [Button $rightf.view_pc -text "Open\npolicy.conf"  -width 8 -command \
		{Sepct_Test::display_test_policy_conf; $Sepct_Test::notebook raise $Sepct_Test::PolicyConfTabName }  \
		-helptype balloon -helptext "Load (reload) policy.conf file"]
	set b_clear   [Button $rightf.clear -text "Clear\nOutput" -width 8 -command {Sepct_Test::clear_Output}  \
		-helptype balloon -helptext "Clear all displays on this tab"]
	Sepct_Test::createNoteBook $leftf
	pack $b_test $b_clean $b_install $b_reload $b_view_pc $b_clear -side top -anchor center -pady 5
	return $frame
}     
Sepct::main
