Chris PeBenito 89ec23
#!/usr/bin/python
Chris PeBenito 89ec23
Chris PeBenito 89ec23
#  Author: Joshua Brindle <jbrindle@tresys.com>
Chris PeBenito 89ec23
#
Chris PeBenito 89ec23
# Copyright (C) 2003 - 2005 Tresys Technology, LLC
Chris PeBenito 89ec23
#      This program is free software; you can redistribute it and/or modify
Chris PeBenito 89ec23
#      it under the terms of the GNU General Public License as published by
Chris PeBenito 89ec23
#      the Free Software Foundation, version 2.
Chris PeBenito 89ec23
Chris PeBenito 89ec23
"""
Chris PeBenito 5a3299
	This module generates configuration files and documentation from the 
Chris PeBenito 5a3299
	SELinux reference policy XML format. 
Chris PeBenito 89ec23
"""
Chris PeBenito 89ec23
Chris PeBenito 89ec23
import sys
Chris PeBenito 89ec23
import getopt
Chris PeBenito 89ec23
import pyplate
Chris PeBenito 5a3299
import os
Chris PeBenito 5d9417
import string
Chris PeBenito 5d9417
from xml.dom.minidom import parse, parseString
Chris PeBenito 89ec23
Chris PeBenito 2d56fd
#modules enabled and disabled values
Chris PeBenito f0cc1a
MOD_BASE = "base"
Chris PeBenito f0cc1a
MOD_ENABLED = "module"
Chris PeBenito 2d56fd
MOD_DISABLED = "off"
Chris PeBenito 2d56fd
Chris PeBenito 2d56fd
#tunables enabled and disabled values
Chris PeBenito 2d56fd
TUN_ENABLED = "true"
Chris PeBenito 2d56fd
TUN_DISABLED = "false"
Chris PeBenito a4c639
Chris PeBenito 896bad
Chris PeBenito 89ec23
def read_policy_xml(filename):
Chris PeBenito 896bad
	"""
Chris PeBenito 896bad
	Takes in XML from a file and returns a parsed file.
Chris PeBenito 896bad
	"""
Chris PeBenito 896bad
Chris PeBenito 89ec23
	try:
Chris PeBenito 1601fb
		xml_fh = open(filename)
Chris PeBenito 1601fb
	except:
Chris PeBenito 1601fb
		error("error opening " + filename)
Chris PeBenito 1601fb
Chris PeBenito 1601fb
	try:
Chris PeBenito 5d9417
		doc = parseString(xml_fh.read())
Chris PeBenito 89ec23
	except: 
Chris PeBenito 1601fb
		xml_fh.close()
Chris PeBenito 89ec23
		error("Error while parsing xml")
Chris PeBenito 1601fb
Chris PeBenito 1601fb
	xml_fh.close()	
Chris PeBenito 89ec23
	return doc
Chris PeBenito 89ec23
Chris PeBenito f0cc1a
def gen_tunable_conf(doc, file_name, namevalue_list):
Chris PeBenito 896bad
	"""
Chris PeBenito 896bad
	Generates the tunable configuration file using the XML provided and the
Chris PeBenito 896bad
	previous tunable configuration.
Chris PeBenito 896bad
	"""
Chris PeBenito 896bad
Chris PeBenito 89ec23
	for node in doc.getElementsByTagName("tunable"):
Chris PeBenito fae6ff
		s = string.split(format_txt_desc(node), "\n")
Chris PeBenito 89ec23
		for line in s:
Chris PeBenito f0cc1a
			file_name.write("# %s\n" % line)
Chris PeBenito 89ec23
		tun_name = tun_val = None
Chris PeBenito 89ec23
        	for (name, value) in node.attributes.items():
Chris PeBenito 5d9417
			if name == "name":
Chris PeBenito 5d9417
				tun_name = value
Chris PeBenito 5d9417
			elif name == "dftval":
Chris PeBenito 5d9417
				tun_val = value
Chris PeBenito 89ec23
Chris PeBenito 2d56fd
			if [tun_name,TUN_ENABLED] in namevalue_list:
Chris PeBenito 2d56fd
				tun_val = TUN_ENABLED
Chris PeBenito 2d56fd
			elif [tun_name,TUN_DISABLED] in namevalue_list:
Chris PeBenito 2d56fd
				tun_val = TUN_DISABLED
Chris PeBenito 2d56fd
Chris PeBenito 89ec23
			if tun_name and tun_val:
Chris PeBenito f0cc1a
	            		file_name.write("%s = %s\n\n" % (tun_name, tun_val))
Chris PeBenito 89ec23
				tun_name = tun_val = None
Chris PeBenito 89ec23
Chris PeBenito f0cc1a
def gen_module_conf(doc, file_name, namevalue_list):
Chris PeBenito 896bad
	"""
Chris PeBenito 896bad
	Generates the module configuration file using the XML provided and the
Chris PeBenito 896bad
	previous module configuration.
Chris PeBenito 896bad
	"""
Chris PeBenito a4c639
	# If file exists, preserve settings and modify if needed.
Chris PeBenito a4c639
	# Otherwise, create it.
Chris PeBenito 896bad
Chris PeBenito f0cc1a
	file_name.write("#\n# This file contains a listing of available modules.\n")
Chris PeBenito f0cc1a
	file_name.write("# To prevent a module from  being used in policy\n")
Chris PeBenito f0cc1a
	file_name.write("# creation, set the module name to \"%s\".\n#\n" % MOD_DISABLED)
Chris PeBenito f0cc1a
	file_name.write("# For monolithic policies, modules set to \"%s\" and \"%s\"\n" % (MOD_BASE, MOD_ENABLED))
Chris PeBenito f0cc1a
	file_name.write("# will be built into the policy.\n#\n")
Chris PeBenito f0cc1a
	file_name.write("# For modular policies, modules set to \"%s\" will be\n" % MOD_BASE)
Chris PeBenito f0cc1a
	file_name.write("# included in the base module.  \"%s\" will be compiled\n" % MOD_ENABLED)
Chris PeBenito f0cc1a
	file_name.write("# as individual loadable modules.\n#\n\n")
Chris PeBenito f0cc1a
Chris PeBenito f0cc1a
	# For required in [True,False] is present so that the requiered modules
Chris PeBenito f0cc1a
	# are at the top of the config file.
Chris PeBenito f0cc1a
	for required in [True,False]:
Chris PeBenito f0cc1a
		for node in doc.getElementsByTagName("module"):
Chris PeBenito f0cc1a
			mod_req = False
Chris PeBenito f0cc1a
			for req in node.getElementsByTagName("required"):
Chris PeBenito f0cc1a
				if req.getAttribute("val") == "true":
Chris PeBenito f0cc1a
					mod_req = True
Chris PeBenito f0cc1a
Chris PeBenito f0cc1a
			# Skip if we arnt working on the right set of modules.
Chris PeBenito f0cc1a
			if mod_req and not required or not mod_req and required:
Chris PeBenito f0cc1a
				continue
Chris PeBenito 5a3299
Chris PeBenito 5a3299
Chris PeBenito f0cc1a
			mod_name = mod_layer = None
Chris PeBenito f0cc1a
Chris PeBenito f0cc1a
			mod_name = node.getAttribute("name")	
Chris PeBenito f0cc1a
			mod_layer = node.parentNode.getAttribute("name")
Chris PeBenito a4c639
Chris PeBenito f0cc1a
			if mod_name and mod_layer:
Chris PeBenito f0cc1a
				file_name.write("# Layer: %s\n# Module: %s\n" % (mod_layer,mod_name))
Chris PeBenito f0cc1a
				if required:
Chris PeBenito f0cc1a
					file_name.write("# Required in base\n")
Chris PeBenito f0cc1a
				file_name.write("#\n")
Chris PeBenito f0cc1a
Chris PeBenito f0cc1a
			for desc in node.getElementsByTagName("summary"):
Chris PeBenito f0cc1a
				if not desc.parentNode == node:
Chris PeBenito f0cc1a
					continue
Chris PeBenito f0cc1a
				s = string.split(format_txt_desc(desc), "\n")
Chris PeBenito f0cc1a
				for line in s:
Chris PeBenito f0cc1a
					file_name.write("# %s\n" % line)
Chris PeBenito f0cc1a
Chris PeBenito f0cc1a
				if [mod_name, MOD_DISABLED] in namevalue_list:
Chris PeBenito f0cc1a
					file_name.write("%s = %s\n\n" % (mod_name, MOD_DISABLED))
Chris PeBenito f0cc1a
				elif [mod_name, MOD_ENABLED] in namevalue_list:
Chris PeBenito f0cc1a
					file_name.write("%s = %s\n\n" % (mod_name, MOD_ENABLED))
Chris PeBenito f0cc1a
				else:
Chris PeBenito f0cc1a
					file_name.write("%s = %s\n\n" % (mod_name, MOD_BASE))
Chris PeBenito a4c639
Chris PeBenito 896bad
def get_conf(conf):
Chris PeBenito 896bad
	"""
Chris PeBenito 896bad
	Returns a list of [name, value] pairs from a config file with the format
Chris PeBenito 896bad
	name = value
Chris PeBenito 896bad
	"""
Chris PeBenito a4c639
Chris PeBenito a4c639
	conf_lines = conf.readlines()
Chris PeBenito a4c639
Chris PeBenito 2d56fd
	namevalue_list = []
Chris PeBenito 896bad
	for i in range(0,len(conf_lines)):
Chris PeBenito 896bad
		line = conf_lines[i]
Chris PeBenito a4c639
		if line.strip() != '' and line.strip()[0] != "#":
Chris PeBenito 2d56fd
			namevalue = line.strip().split("=")
Chris PeBenito 896bad
			if len(namevalue) != 2:
Chris PeBenito 896bad
				warning("line %d: \"%s\" is not a valid line, skipping"\
Chris PeBenito 896bad
					 % (i, line.strip()))
Chris PeBenito 896bad
				continue
Chris PeBenito 896bad
Chris PeBenito 2d56fd
			namevalue[0] = namevalue[0].strip()
Chris PeBenito 896bad
			if len(namevalue[0].split()) > 1:
Chris PeBenito 896bad
				warning("line %d: \"%s\" is not a valid line, skipping"\
Chris PeBenito 896bad
					 % (i, line.strip()))
Chris PeBenito 896bad
				continue
Chris PeBenito 896bad
Chris PeBenito 2d56fd
			namevalue[1] = namevalue[1].strip()
Chris PeBenito 896bad
			if len(namevalue[1].split()) > 1:
Chris PeBenito 896bad
				warning("line %d: \"%s\" is not a valid line, skipping"\
Chris PeBenito 896bad
					 % (i, line.strip()))
Chris PeBenito 896bad
				continue
Chris PeBenito 896bad
Chris PeBenito 2d56fd
			namevalue_list.append(namevalue)
Chris PeBenito 2d56fd
Chris PeBenito 2d56fd
	return namevalue_list
Chris PeBenito 5a3299
Chris PeBenito 896bad
def first_cmp(a, b):
Chris PeBenito 896bad
	"""
Chris PeBenito 896bad
	Compares the two first elements of a list instead of the entire list.
Chris PeBenito 896bad
	"""
Chris PeBenito 896bad
Karl MacMillan d6b0f3
	return cmp(a[0], b[0])
Chris PeBenito d46f02
Chris PeBenito d46f02
def int_cmp(a, b):
Chris PeBenito 896bad
	"""
Chris PeBenito 896bad
	Compares two interfaces.
Chris PeBenito 896bad
	"""
Chris PeBenito 896bad
Chris PeBenito d46f02
	return cmp(a["interface_name"], b["interface_name"])
Chris PeBenito effd58
		
Chris PeBenito effd58
def temp_cmp(a, b):
Chris PeBenito effd58
	"""
Chris PeBenito effd58
	Compares two templates.
Chris PeBenito effd58
	"""
Chris PeBenito effd58
Chris PeBenito effd58
	return cmp(a["template_name"], b["template_name"])
Chris PeBenito 249d46
Chris PeBenito 249d46
def tun_cmp(a, b):
Chris PeBenito 249d46
	"""
Chris PeBenito 249d46
	Compares two tunables.
Chris PeBenito 249d46
	"""
Chris PeBenito 249d46
Chris PeBenito 249d46
	return cmp(a["tun_name"], b["tun_name"])
Chris PeBenito 249d46
def bool_cmp(a, b):
Chris PeBenito 249d46
	"""
Chris PeBenito 249d46
	Compares two booleans.
Chris PeBenito 249d46
	"""
Chris PeBenito 249d46
Chris PeBenito 249d46
	return cmp(a["bool_name"], b["bool_name"])
Chris PeBenito 249d46
Chris PeBenito 5a3299
def gen_doc_menu(mod_layer, module_list):
Chris PeBenito 896bad
	"""
Chris PeBenito 896bad
	Generates the HTML document menu.
Chris PeBenito 896bad
	"""
Chris PeBenito 896bad
Karl MacMillan d6b0f3
	menu = []
Karl MacMillan d6b0f3
	for layer, value in module_list.iteritems():
Karl MacMillan d6b0f3
		cur_menu = (layer, [])
Karl MacMillan d6b0f3
		menu.append(cur_menu)
Karl MacMillan d6b0f3
		if layer != mod_layer and mod_layer != None:
Karl MacMillan d6b0f3
			continue
Chris PeBenito 5a3299
		#we are in our layer so fill in the other modules or we want them all
Karl MacMillan d6b0f3
		for mod, desc in value.iteritems():
Karl MacMillan d6b0f3
			cur_menu[1].append((mod, desc))
Karl MacMillan d6b0f3
Chris PeBenito 896bad
	menu.sort(first_cmp)
Karl MacMillan d6b0f3
	for x in menu:
Chris PeBenito 896bad
		x[1].sort(first_cmp)
Chris PeBenito 5a3299
	return menu
Chris PeBenito 5a3299
Chris PeBenito fae6ff
def format_html_desc(node):
Chris PeBenito 896bad
	"""
Chris PeBenito 896bad
	Formats a XML node into a HTML format.
Chris PeBenito 896bad
	"""
Chris PeBenito e214f6
Chris PeBenito e214f6
	desc_buf = ''
Chris PeBenito e214f6
	for desc in node.childNodes:
Chris PeBenito e214f6
		if desc.nodeName == "#text":
Chris PeBenito 3c6d78
			if desc.data is not '':
Chris PeBenito 3c6d78
				desc_buf += "

" + desc.data + "

"
Chris PeBenito e214f6
		elif desc.nodeName == "p":
Chris PeBenito 3c6d78
			if desc.firstChild.data is not '':
Chris PeBenito 3c6d78
				desc_buf += "

" + desc.firstChild.data + "

"
Chris PeBenito e214f6
			for chld in desc.childNodes: 
Chris PeBenito e214f6
				if chld.nodeName == "ul":
Chris PeBenito e214f6
					desc_buf += "
    "
Chris PeBenito e214f6
					for li in chld.getElementsByTagName("li"):
Chris PeBenito e214f6
						desc_buf += "
  • " + li.firstChild.data + "
  • "
    Chris PeBenito 3c6d78
    					desc_buf += ""
    Chris PeBenito e214f6
    Chris PeBenito e214f6
    	return desc_buf
    Chris PeBenito e214f6
    Chris PeBenito fae6ff
    def format_txt_desc(node):
    Chris PeBenito 896bad
    	"""
    Chris PeBenito 896bad
    	Formats a XML node into a plain text format.
    Chris PeBenito 896bad
    	"""
    Chris PeBenito fae6ff
    Chris PeBenito fae6ff
    	desc_buf = ''
    Chris PeBenito fae6ff
    	for desc in node.childNodes:
    Chris PeBenito fae6ff
    		if desc.nodeName == "#text":
    Chris PeBenito fae6ff
    			desc_buf += desc.data + "\n"
    Chris PeBenito fae6ff
    		elif desc.nodeName == "p":
    Chris PeBenito fae6ff
    			desc_buf += desc.firstChild.data + "\n"
    Chris PeBenito fae6ff
    			for chld in desc.childNodes: 
    Chris PeBenito fae6ff
    				if chld.nodeName == "ul":
    Chris PeBenito fae6ff
    					desc_buf += "\n"
    Chris PeBenito fae6ff
    					for li in chld.getElementsByTagName("li"):
    Chris PeBenito fae6ff
    						desc_buf += "\t -" + li.firstChild.data + "\n"
    Chris PeBenito fae6ff
    Chris PeBenito f0cc1a
    	return desc_buf.strip() + "\n"
    Chris PeBenito e214f6
    Chris PeBenito f0cc1a
    def gen_docs(doc, working_dir, templatedir):
    Chris PeBenito 896bad
    	"""
    Chris PeBenito 896bad
    	Generates all the documentation.
    Chris PeBenito 896bad
    	"""
    Chris PeBenito 89ec23
    Chris PeBenito 89ec23
    	try:
    Chris PeBenito d46f02
    		#get the template data ahead of time so we don't reopen them over and over
    Chris PeBenito 5a3299
    		bodyfile = open(templatedir + "/header.html", "r")
    Chris PeBenito 5a3299
    		bodydata = bodyfile.read()
    Chris PeBenito 5a3299
    		bodyfile.close()
    Chris PeBenito 5a3299
    		intfile = open(templatedir + "/interface.html", "r")
    Chris PeBenito 5a3299
    		intdata = intfile.read()
    Chris PeBenito 5a3299
    		intfile.close()
    Chris PeBenito effd58
    		templatefile = open(templatedir + "/template.html", "r")
    Chris PeBenito effd58
    		templatedata = templatefile.read()
    Chris PeBenito effd58
    		templatefile.close()
    Chris PeBenito 5a3299
    		menufile = open(templatedir + "/menu.html", "r")
    Chris PeBenito 5a3299
    		menudata = menufile.read()
    Chris PeBenito 5a3299
    		menufile.close()
    Chris PeBenito 5a3299
    		indexfile = open(templatedir + "/module_list.html","r")
    Chris PeBenito 5a3299
    		indexdata = indexfile.read()
    Chris PeBenito 5a3299
    		indexfile.close()
    Chris PeBenito 5a3299
    		modulefile = open(templatedir + "/module.html","r")
    Chris PeBenito 5a3299
    		moduledata = modulefile.read()
    Chris PeBenito 5a3299
    		modulefile.close()
    Chris PeBenito d46f02
    		intlistfile = open(templatedir + "/int_list.html", "r")
    Chris PeBenito d46f02
    		intlistdata = intlistfile.read()
    Chris PeBenito d46f02
    		intlistfile.close()
    Chris PeBenito effd58
    		templistfile = open(templatedir + "/temp_list.html", "r")
    Chris PeBenito effd58
    		templistdata = templistfile.read()
    Chris PeBenito effd58
    		templistfile.close()
    Chris PeBenito 249d46
    		boollistfile = open(templatedir + "/global_bool_list.html", "r")
    Chris PeBenito 249d46
    		boollistdata = boollistfile.read()
    Chris PeBenito 249d46
    		boollistfile.close()
    Chris PeBenito 249d46
    		tunlistfile = open(templatedir + "/global_tun_list.html", "r")
    Chris PeBenito 249d46
    		tunlistdata = tunlistfile.read()
    Chris PeBenito 249d46
    		tunlistfile.close()
    Chris PeBenito 89ec23
    	except:
    Chris PeBenito 89ec23
    		error("Could not open templates")
    Chris PeBenito 89ec23
    Chris PeBenito 5a3299
    Chris PeBenito 5a3299
    	try:
    Chris PeBenito f0cc1a
    		os.chdir(working_dir)
    Chris PeBenito 5a3299
    	except:
    Chris PeBenito 7fb9c1
    		error("Could not chdir to target directory")	
    Chris PeBenito 5a3299
    Chris PeBenito 5a3299
    Chris PeBenito 5a3299
    #arg, i have to go through this dom tree ahead of time to build up the menus
    Chris PeBenito 5a3299
    	module_list = {}
    Chris PeBenito 5a3299
    	for node in doc.getElementsByTagName("module"):
    Chris PeBenito 5a3299
                    mod_name = mod_layer = interface_buf = ''
    Chris PeBenito 7fb9c1
    Chris PeBenito f0cc1a
    		mod_name = node.getAttribute("name")
    Chris PeBenito f0cc1a
    		mod_layer = node.parentNode.getAttribute("name")
    Chris PeBenito 7fb9c1
    Chris PeBenito 5a3299
    		for desc in node.getElementsByTagName("summary"):
    Chris PeBenito fae6ff
    			if desc.parentNode == node and desc:
    Chris PeBenito fae6ff
    				mod_summary = format_html_desc(desc)
    Chris PeBenito 5a3299
    		if not module_list.has_key(mod_layer):
    Chris PeBenito 5a3299
    			module_list[mod_layer] = {}
    Chris PeBenito 5a3299
    Chris PeBenito 5a3299
    		module_list[mod_layer][mod_name] = mod_summary
    Chris PeBenito 5a3299
    Chris PeBenito 5a3299
    #generate index pages
    Chris PeBenito 5a3299
    	main_content_buf = ''
    Chris PeBenito 5a3299
    	for mod_layer,modules in module_list.iteritems():
    Chris PeBenito 5a3299
    		menu = gen_doc_menu(mod_layer, module_list)
    Chris PeBenito 5a3299
    Chris PeBenito acb668
    		layer_summary = None
    Chris PeBenito acb668
    		for desc in doc.getElementsByTagName("summary"):
    Chris PeBenito acb668
    			if desc.parentNode.getAttribute("name") == mod_layer:
    Chris PeBenito acb668
    				layer_summary = format_html_desc(desc)
    Chris PeBenito acb668
    Chris PeBenito 5a3299
    		menu_args = { "menulist" : menu,
    Chris PeBenito acb668
    			      "mod_layer" : mod_layer,
    Chris PeBenito acb668
    			      "layer_summary" : layer_summary }
    Chris PeBenito 5a3299
    		menu_tpl = pyplate.Template(menudata)
    Chris PeBenito 5a3299
    		menu_buf = menu_tpl.execute_string(menu_args)
    Chris PeBenito 5a3299
    Chris PeBenito 5a3299
    		content_tpl = pyplate.Template(indexdata)
    Chris PeBenito 5a3299
    		content_buf = content_tpl.execute_string(menu_args)
    Chris PeBenito 5a3299
    Chris PeBenito 5a3299
    		main_content_buf += content_buf
    Chris PeBenito 5a3299
    Chris PeBenito 5a3299
    		body_args = { "menu" : menu_buf,
    Chris PeBenito 5a3299
    			      "content" : content_buf }
    Chris PeBenito 5a3299
    	
    Chris PeBenito 5a3299
    		index_file = mod_layer + ".html"
    Chris PeBenito 5a3299
    		index_fh = open(index_file, "w")
    Chris PeBenito 5a3299
    		body_tpl = pyplate.Template(bodydata)
    Chris PeBenito 5a3299
    		body_tpl.execute(index_fh, body_args)
    Chris PeBenito 5a3299
    		index_fh.close()	
    Chris PeBenito 5a3299
    Chris PeBenito 5a3299
    	menu = gen_doc_menu(None, module_list)
    Chris PeBenito 5a3299
    	menu_args = { "menulist" : menu,
    Chris PeBenito 5a3299
    		      "mod_layer" : None }
    Chris PeBenito 5a3299
    	menu_tpl = pyplate.Template(menudata)
    Chris PeBenito 5a3299
    	menu_buf = menu_tpl.execute_string(menu_args)
    Chris PeBenito 5a3299
    Chris PeBenito 5a3299
    	body_args = { "menu" : menu_buf,
    Chris PeBenito 5a3299
    		      "content" : main_content_buf }
    Chris PeBenito 5a3299
    Chris PeBenito 5a3299
    	index_file = "index.html"
    Chris PeBenito 5a3299
    	index_fh = open(index_file, "w")
    Chris PeBenito 5a3299
    	body_tpl = pyplate.Template(bodydata)
    Chris PeBenito 5a3299
    	body_tpl.execute(index_fh, body_args)
    Chris PeBenito 5a3299
    	index_fh.close()
    Chris PeBenito d46f02
    #now generate the individual module pages
    Chris PeBenito 89ec23
    Chris PeBenito d46f02
    	all_interfaces = []
    Chris PeBenito effd58
    	all_templates = []
    Chris PeBenito 89ec23
    	for node in doc.getElementsByTagName("module"):
    Chris PeBenito e214f6
                    mod_name = mod_layer = mod_desc = interface_buf = ''
    Chris PeBenito 7fb9c1
    Chris PeBenito f0cc1a
    		mod_name = node.getAttribute("name")
    Chris PeBenito f0cc1a
    		mod_layer = node.parentNode.getAttribute("name")
    Chris PeBenito f0cc1a
    Chris PeBenito f0cc1a
    		mod_req = None
    Chris PeBenito f0cc1a
    		for req in node.getElementsByTagName("required"):
    Chris PeBenito f0cc1a
    			if req.getAttribute("val") == "true":
    Chris PeBenito f0cc1a
    				mod_req = True
    Chris PeBenito 7fb9c1
    Chris PeBenito 5a3299
    		for desc in node.getElementsByTagName("summary"):
    Chris PeBenito e214f6
    			if desc.parentNode == node:
    Chris PeBenito fae6ff
    				mod_summary = format_html_desc(desc)
    Chris PeBenito 7c2b84
    		for desc in node.getElementsByTagName("desc"):
    Chris PeBenito e214f6
    			if desc.parentNode == node:
    Chris PeBenito fae6ff
    				mod_desc = format_html_desc(desc)
    Chris PeBenito d46f02
    Chris PeBenito d46f02
    		interfaces = []
    Chris PeBenito 89ec23
    		for interface in node.getElementsByTagName("interface"):
    Chris PeBenito 5a3299
    			interface_parameters = []
    Chris PeBenito 815ff3
    			interface_desc = interface_secdesc = interface_summary = None
    Chris PeBenito 89ec23
    			for i,v in interface.attributes.items():
    Chris PeBenito 5d9417
    				interface_name = v
    Chris PeBenito 7c2b84
    			for desc in interface.getElementsByTagName("desc"):
    Chris PeBenito fae6ff
    				interface_desc = format_html_desc(desc)
    Chris PeBenito 7c2b84
    			for desc in interface.getElementsByTagName("secdesc"):
    Chris PeBenito 89ec23
    				if desc:
    Chris PeBenito fae6ff
    					interface_secdesc = format_html_desc(desc)
    Chris PeBenito e214f6
    			for desc in interface.getElementsByTagName("summary"):
    Chris PeBenito fae6ff
    				interface_summary = format_html_desc(desc)
    Chris PeBenito 89ec23
    			
    Chris PeBenito 7c2b84
    			for args in interface.getElementsByTagName("param"):
    Chris PeBenito 89ec23
    				paramdesc = args.firstChild.data
    Chris PeBenito 5a3299
    				paramname = None
    Chris PeBenito 1601fb
    				paramopt = "No"
    Chris PeBenito 5a3299
    				for name,val in args.attributes.items():
    Chris PeBenito 5d9417
    					if name == "name":
    Chris PeBenito 5d9417
    						paramname = val
    Chris PeBenito 5d9417
    					if name == "optional":
    Chris PeBenito 5d9417
    						if val == "true":
    Chris PeBenito 1601fb
    							paramopt = "yes"
    Chris PeBenito 5a3299
    				parameter = { "name" : paramname,
    Chris PeBenito 5a3299
    					      "desc" : paramdesc,
    Chris PeBenito 5a3299
    					      "optional" : paramopt }
    Chris PeBenito 5a3299
    				interface_parameters.append(parameter)
    Chris PeBenito d46f02
    			interfaces.append( { "interface_name" : interface_name,
    Chris PeBenito e214f6
    					   "interface_summary" : interface_summary,
    Chris PeBenito 5a3299
    					   "interface_desc" : interface_desc,
    Chris PeBenito 5a3299
    					   "interface_parameters" : interface_parameters,
    Chris PeBenito d46f02
    					   "interface_secdesc" : interface_secdesc })
    Chris PeBenito d46f02
    			#all_interfaces is for the main interface index with all interfaces
    Chris PeBenito d46f02
    			all_interfaces.append( { "interface_name" : interface_name,
    Chris PeBenito e214f6
    					   "interface_summary" : interface_summary,
    Chris PeBenito d46f02
    					   "interface_desc" : interface_desc,
    Chris PeBenito d46f02
    					   "interface_parameters" : interface_parameters,
    Chris PeBenito d46f02
    					   "interface_secdesc" : interface_secdesc,
    Chris PeBenito d46f02
    					   "mod_name": mod_name,
    Chris PeBenito d46f02
    					   "mod_layer" : mod_layer })
    Chris PeBenito d46f02
    		interfaces.sort(int_cmp)	
    Chris PeBenito d46f02
    		interface_tpl = pyplate.Template(intdata)
    Chris PeBenito d46f02
    		interface_buf = interface_tpl.execute_string({"interfaces" : interfaces})
    Chris PeBenito d46f02
    	
    Chris PeBenito effd58
    Chris PeBenito effd58
    # now generate individual template pages
    Chris PeBenito effd58
    		templates = []
    Chris PeBenito effd58
    		for template in node.getElementsByTagName("template"):
    Chris PeBenito effd58
    			template_parameters = []
    Chris PeBenito effd58
    			template_desc = template_secdesc = template_summary = None
    Chris PeBenito effd58
    			for i,v in template.attributes.items():
    Chris PeBenito effd58
    				template_name = v
    Chris PeBenito effd58
    			for desc in template.getElementsByTagName("desc"):
    Chris PeBenito effd58
    				template_desc = format_html_desc(desc)
    Chris PeBenito effd58
    			for desc in template.getElementsByTagName("secdesc"):
    Chris PeBenito effd58
    				if desc:
    Chris PeBenito effd58
    					template_secdesc = format_html_desc(desc)
    Chris PeBenito effd58
    			for desc in template.getElementsByTagName("summary"):
    Chris PeBenito effd58
    				template_summary = format_html_desc(desc)
    Chris PeBenito effd58
    			
    Chris PeBenito effd58
    			for args in template.getElementsByTagName("param"):
    Chris PeBenito effd58
    				paramdesc = args.firstChild.data
    Chris PeBenito effd58
    				paramname = None
    Chris PeBenito effd58
    				paramopt = "No"
    Chris PeBenito effd58
    				for name,val in args.attributes.items():
    Chris PeBenito effd58
    					if name == "name":
    Chris PeBenito effd58
    						paramname = val
    Chris PeBenito effd58
    					if name == "optional":
    Chris PeBenito effd58
    						if val == "true":
    Chris PeBenito effd58
    							paramopt = "yes"
    Chris PeBenito effd58
    				parameter = { "name" : paramname,
    Chris PeBenito effd58
    					      "desc" : paramdesc,
    Chris PeBenito effd58
    					      "optional" : paramopt }
    Chris PeBenito effd58
    				template_parameters.append(parameter)
    Chris PeBenito effd58
    			templates.append( { "template_name" : template_name,
    Chris PeBenito effd58
    					   "template_summary" : template_summary,
    Chris PeBenito effd58
    					   "template_desc" : template_desc,
    Chris PeBenito effd58
    					   "template_parameters" : template_parameters,
    Chris PeBenito effd58
    					   "template_secdesc" : template_secdesc })
    Chris PeBenito effd58
    			#all_templates is for the main interface index with all templates
    Chris PeBenito effd58
    			all_templates.append( { "template_name" : template_name,
    Chris PeBenito effd58
    					   "template_summary" : template_summary,
    Chris PeBenito effd58
    					   "template_desc" : template_desc,
    Chris PeBenito effd58
    					   "template_parameters" : template_parameters,
    Chris PeBenito effd58
    					   "template_secdesc" : template_secdesc,
    Chris PeBenito effd58
    					   "mod_name": mod_name,
    Chris PeBenito effd58
    					   "mod_layer" : mod_layer })
    Chris PeBenito effd58
    Chris PeBenito effd58
    		templates.sort(temp_cmp)	
    Chris PeBenito effd58
    		template_tpl = pyplate.Template(templatedata)
    Chris PeBenito effd58
    		template_buf = template_tpl.execute_string({"templates" : templates})
    Chris PeBenito effd58
    Chris PeBenito effd58
    Chris PeBenito 5a3299
    		menu = gen_doc_menu(mod_layer, module_list)
    Chris PeBenito 5a3299
    Chris PeBenito 5a3299
    		menu_tpl = pyplate.Template(menudata)
    Chris PeBenito d46f02
    		menu_buf = menu_tpl.execute_string({ "menulist" : menu })
    Chris PeBenito 5a3299
    Chris PeBenito 06c968
    Chris PeBenito 06c968
    		# pyplate's execute_string gives us a line of whitespace in
    Chris PeBenito 06c968
    		# template_buf or interface_buf if there are no interfaces or
    Chris PeBenito 06c968
    		# templates for this module. This is problematic because the
    Chris PeBenito 06c968
    		# HTML templates use a conditional if on interface_buf or
    Chris PeBenito 06c968
    		# template_buf being 'None' to decide if the "Template:" or
    Chris PeBenito 06c968
    		# "Interface:" headers need to be printed in the module pages.
    Chris PeBenito 06c968
    		# This detects if either of these are just whitespace, and sets
    Chris PeBenito 06c968
    		# their values to 'None' so that when applying it to the
    Chris PeBenito 06c968
    		# templates, they are properly recognized as not existing.
    Chris PeBenito 06c968
    		if not interface_buf.strip():
    Chris PeBenito 06c968
    			interface_buf = None
    Chris PeBenito 06c968
    		if not template_buf.strip():
    Chris PeBenito 06c968
    			template_buf = None
    Chris PeBenito 06c968
    Chris PeBenito 5a3299
    		module_args = { "mod_layer" : mod_layer,
    Chris PeBenito 5a3299
    			      "mod_name" : mod_name,	
    Chris PeBenito 5a3299
    			      "mod_summary" : mod_summary,
    Chris PeBenito e214f6
    			      "mod_desc" : mod_desc,
    Chris PeBenito f0cc1a
    			      "mod_req" : mod_req,
    Chris PeBenito effd58
    			      "interfaces" : interface_buf,
    Chris PeBenito effd58
    			      "templates": template_buf }
    Chris PeBenito 5a3299
    Chris PeBenito 5a3299
    		module_tpl = pyplate.Template(moduledata)
    Chris PeBenito 5a3299
    		module_buf = module_tpl.execute_string(module_args)
    Chris PeBenito 5a3299
    Chris PeBenito 5a3299
    		body_args = { "menu" : menu_buf,
    Chris PeBenito 5a3299
    			      "content" : module_buf }
    Chris PeBenito 5a3299
    			  
    Chris PeBenito 5a3299
    		module_file = mod_layer + "_" + mod_name + ".html"
    Chris PeBenito 5a3299
    		module_fh = open(module_file, "w")
    Chris PeBenito 5a3299
    		body_tpl = pyplate.Template(bodydata)
    Chris PeBenito 5a3299
    		body_tpl.execute(module_fh, body_args)
    Chris PeBenito 5a3299
    		module_fh.close()
    Chris PeBenito 89ec23
    Chris PeBenito effd58
    		
    Chris PeBenito 249d46
    	menu = gen_doc_menu(None, module_list)
    Chris PeBenito 249d46
    	menu_args = { "menulist" : menu,
    Chris PeBenito 249d46
    		      "mod_layer" : None }
    Chris PeBenito 249d46
    	menu_tpl = pyplate.Template(menudata)
    Chris PeBenito 249d46
    	menu_buf = menu_tpl.execute_string(menu_args)
    Chris PeBenito d46f02
    	
    Chris PeBenito 249d46
    	#build the interface index
    Chris PeBenito 249d46
    	all_interfaces.sort(int_cmp)
    Chris PeBenito 249d46
    	interface_tpl = pyplate.Template(intlistdata)
    Chris PeBenito 249d46
    	interface_buf = interface_tpl.execute_string({"interfaces" : all_interfaces})
    Chris PeBenito 249d46
    	int_file = "interfaces.html"
    Chris PeBenito 249d46
    	int_fh = open(int_file, "w")
    Chris PeBenito 249d46
    	body_tpl = pyplate.Template(bodydata)
    Chris PeBenito d46f02
    Chris PeBenito 249d46
    	body_args = { "menu" : menu_buf, 
    Chris PeBenito 249d46
    		      "content" : interface_buf }
    Chris PeBenito d46f02
    Chris PeBenito 249d46
    	body_tpl.execute(int_fh, body_args)
    Chris PeBenito 249d46
    	int_fh.close()
    Chris PeBenito d46f02
    Chris PeBenito effd58
    Chris PeBenito 249d46
    	#build the template index
    Chris PeBenito 249d46
    	all_templates.sort(temp_cmp)
    Chris PeBenito 249d46
    	template_tpl = pyplate.Template(templistdata)
    Chris PeBenito 249d46
    	template_buf = template_tpl.execute_string({"templates" : all_templates})
    Chris PeBenito 249d46
    	temp_file = "templates.html"
    Chris PeBenito 249d46
    	temp_fh = open(temp_file, "w")
    Chris PeBenito 249d46
    	body_tpl = pyplate.Template(bodydata)
    Chris PeBenito 249d46
    Chris PeBenito 249d46
    	body_args = { "menu" : menu_buf, 
    Chris PeBenito 249d46
    		      "content" : template_buf }
    Chris PeBenito 249d46
    Chris PeBenito 249d46
    	body_tpl.execute(temp_fh, body_args)
    Chris PeBenito 249d46
    	temp_fh.close()
    Chris PeBenito 249d46
    Chris PeBenito 249d46
    Chris PeBenito 249d46
    	#build the global tunable index
    Chris PeBenito 249d46
    	global_tun_buf = []
    Chris PeBenito 249d46
    	for tunable in doc.getElementsByTagName("tunable"):
    Chris PeBenito 249d46
    		if tunable.parentNode.nodeName == "policy":
    Chris PeBenito 249d46
    			tunable_name = tunable.getAttribute("name")
    Chris PeBenito 249d46
    			default_value = tunable.getAttribute("dftval")
    Chris PeBenito 4d7511
    			description = format_html_desc(tunable)
    Chris PeBenito 249d46
    			global_tun_buf.append( { "tun_name" : tunable_name,
    Chris PeBenito 4d7511
    						"def_val" : default_value,
    Chris PeBenito 4d7511
    						"desc" : description } )
    Chris PeBenito 249d46
    	global_tun_buf.sort(tun_cmp)
    Chris PeBenito 249d46
    	global_tun_tpl = pyplate.Template(tunlistdata)
    Chris PeBenito 249d46
    	global_tun_buf = global_tun_tpl.execute_string({"tunables" : global_tun_buf})
    Chris PeBenito 249d46
    	global_tun_file = "global_tunables.html"
    Chris PeBenito 249d46
    	global_tun_fh = open(global_tun_file, "w")
    Chris PeBenito 249d46
    	body_tpl = pyplate.Template(bodydata)
    Chris PeBenito 249d46
    Chris PeBenito 249d46
    	body_args = { "menu" : menu_buf,
    Chris PeBenito 249d46
    		      "content" : global_tun_buf }
    Chris PeBenito 249d46
    Chris PeBenito 249d46
    	body_tpl.execute(global_tun_fh, body_args)
    Chris PeBenito 249d46
    	global_tun_fh.close()
    Chris PeBenito 249d46
    Chris PeBenito 249d46
    Chris PeBenito 249d46
    	#build the global boolean index
    Chris PeBenito 249d46
    	global_bool_buf = []
    Chris PeBenito 249d46
    	for boolean in doc.getElementsByTagName("boolean"):
    Chris PeBenito 249d46
    		if boolean.parentNode.nodeName == "policy":
    Chris PeBenito 249d46
    			bool_name = boolean.getAttribute("name")
    Chris PeBenito 249d46
    			default_value = boolean.getAttribute("dftval")
    Chris PeBenito 4d7511
    			description = format_html_desc(boolean)
    Chris PeBenito 249d46
    			global_bool_buf.append( { "bool_name" : bool_name,
    Chris PeBenito 4d7511
    						"def_val" : default_value,
    Chris PeBenito 4d7511
    						"desc" : description } )
    Chris PeBenito 249d46
    	global_bool_buf.sort(bool_cmp)
    Chris PeBenito 249d46
    	global_bool_tpl = pyplate.Template(boollistdata)
    Chris PeBenito 249d46
    	global_bool_buf = global_bool_tpl.execute_string({"booleans" : global_bool_buf})
    Chris PeBenito 249d46
    	global_bool_file = "global_booleans.html"
    Chris PeBenito 249d46
    	global_bool_fh = open(global_bool_file, "w")
    Chris PeBenito 249d46
    	body_tpl = pyplate.Template(bodydata)
    Chris PeBenito 249d46
    Chris PeBenito 249d46
    	body_args = { "menu" : menu_buf,
    Chris PeBenito 249d46
    		      "content" : global_bool_buf }
    Chris PeBenito 249d46
    Chris PeBenito 249d46
    	body_tpl.execute(global_bool_fh, body_args)
    Chris PeBenito 249d46
    	global_bool_fh.close()
    Chris PeBenito effd58
    Chris PeBenito effd58
    Chris PeBenito effd58
    Chris PeBenito 89ec23
    def error(error):
    Chris PeBenito 896bad
    	"""
    Chris PeBenito 896bad
    	Print an error message and exit.
    Chris PeBenito 896bad
    	"""
    Chris PeBenito 896bad
    Chris PeBenito 89ec23
            sys.stderr.write("%s exiting for: " % sys.argv[0])
    Chris PeBenito 89ec23
            sys.stderr.write("%s\n" % error)
    Chris PeBenito 89ec23
            sys.stderr.flush()
    Chris PeBenito 89ec23
            sys.exit(1)
    Chris PeBenito 89ec23
    Chris PeBenito 896bad
    def warning(warn):
    Chris PeBenito 896bad
    	"""
    Chris PeBenito 896bad
    	Print a warning message.
    Chris PeBenito 896bad
    	"""
    Chris PeBenito 896bad
    Chris PeBenito 896bad
    	sys.stderr.write("%s warning: " % sys.argv[0])
    Chris PeBenito 896bad
    	sys.stderr.write("%s\n" % warn)
    Chris PeBenito 896bad
    Chris PeBenito 89ec23
    def usage():
    Chris PeBenito 896bad
    	"""
    Chris PeBenito 896bad
    	Describes the proper usage of this tool.
    Chris PeBenito 896bad
    	"""
    Chris PeBenito 896bad
    Chris PeBenito 5a3299
    	sys.stdout.write("%s [-tmdT] -x <xmlfile>\n\n" % sys.argv[0])
    Chris PeBenito 89ec23
    	sys.stdout.write("Options:\n")
    Chris PeBenito 5a3299
    	sys.stdout.write("-t --tunables	<file>		--	write tunable config to <file>\n")
    Chris PeBenito 89ec23
    	sys.stdout.write("-m --modules <file>		--	write module config to <file>\n")
    Chris PeBenito 89ec23
    	sys.stdout.write("-d --docs <dir>		--	write interface documentation to <dir>\n")
    Chris PeBenito 89ec23
    	sys.stdout.write("-x --xml <file>		--	filename to read xml data from\n")
    Chris PeBenito 5a3299
    	sys.stdout.write("-T --templates <dir>		--	template directory for documents\n")
    Chris PeBenito 89ec23
    Chris PeBenito 896bad
    Chris PeBenito 896bad
    # MAIN PROGRAM
    Chris PeBenito 89ec23
    try:
    Chris PeBenito 5a3299
    	opts, args = getopt.getopt(sys.argv[1:], "t:m:d:x:T:", ["tunables","modules","docs","xml", "templates"])
    Chris PeBenito 89ec23
    except getopt.GetoptError:
    Chris PeBenito 89ec23
    	usage()
    Chris PeBenito 89ec23
    	sys.exit(1)
    Chris PeBenito 89ec23
    Chris PeBenito 1601fb
    tunables = modules = docsdir = None
    Chris PeBenito 5a3299
    templatedir = "templates/"
    Chris PeBenito 5a3299
    xmlfile = "policy.xml"
    Chris PeBenito 89ec23
    Chris PeBenito 89ec23
    for opt, val in opts:
    Chris PeBenito 89ec23
    	if opt in ("-t", "--tunables"):
    Chris PeBenito 89ec23
    		tunables = val
    Chris PeBenito 89ec23
    	if opt in ("-m", "--modules"):
    Chris PeBenito 89ec23
    		modules = val
    Chris PeBenito 89ec23
    	if opt in ("-d", "--docs"):
    Chris PeBenito 5a3299
    		docsdir = val
    Chris PeBenito 89ec23
    	if opt in ("-x", "--xml"):
    Chris PeBenito 89ec23
    		xmlfile = val
    Chris PeBenito 5a3299
    	if opt in ("-T", "--templates"):
    Chris PeBenito 5a3299
    		templatedir = val
    Chris PeBenito 89ec23
    Chris PeBenito 89ec23
    doc = read_policy_xml(xmlfile)
    Chris PeBenito 89ec23
    		
    Chris PeBenito 89ec23
    if tunables:
    Chris PeBenito 2d56fd
    	namevalue_list = []
    Chris PeBenito 2d56fd
    	if os.path.exists(tunables):
    Chris PeBenito 2d56fd
    		try:
    Chris PeBenito 2d56fd
    			conf = open(tunables, 'r')
    Chris PeBenito 2d56fd
    		except:
    Chris PeBenito 2d56fd
    			error("Could not open tunables file for reading")
    Chris PeBenito 2d56fd
    Chris PeBenito 896bad
    		namevalue_list = get_conf(conf)
    Chris PeBenito 2d56fd
    Chris PeBenito 2d56fd
    		conf.close()
    Chris PeBenito 2d56fd
    Chris PeBenito 89ec23
    	try:
    Chris PeBenito 89ec23
    		conf = open(tunables, 'w')
    Chris PeBenito 89ec23
    	except:
    Chris PeBenito 89ec23
    		error("Could not open tunables file for writing")
    Chris PeBenito 2d56fd
    Chris PeBenito 2d56fd
    	gen_tunable_conf(doc, conf, namevalue_list)
    Chris PeBenito 89ec23
    	conf.close()
    Chris PeBenito 89ec23
    Chris PeBenito 89ec23
    Chris PeBenito 89ec23
    if modules:
    Chris PeBenito 2d56fd
    	namevalue_list = []
    Chris PeBenito a4c639
    	if os.path.exists(modules):
    Chris PeBenito a4c639
    		try:
    Chris PeBenito a4c639
    			conf = open(modules, 'r')
    Chris PeBenito a4c639
    		except:
    Chris PeBenito a4c639
    			error("Could not open modules file for reading")
    Chris PeBenito 896bad
    		namevalue_list = get_conf(conf)	
    Chris PeBenito a4c639
    		conf.close()
    Chris PeBenito a4c639
    Chris PeBenito 89ec23
    	try:
    Chris PeBenito 89ec23
    		conf = open(modules, 'w')
    Chris PeBenito 89ec23
    	except:
    Chris PeBenito 89ec23
    		error("Could not open modules file for writing")
    Chris PeBenito 2d56fd
    	gen_module_conf(doc, conf, namevalue_list)
    Chris PeBenito 89ec23
    	conf.close()
    Chris PeBenito 89ec23
    Chris PeBenito 5a3299
    if docsdir: 
    Chris PeBenito 5a3299
    	gen_docs(doc, docsdir, templatedir)