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 885b83
		for desc in node.getElementsByTagName("desc"):
Chris PeBenito 885b83
			tun_desc = format_txt_desc(desc)
Chris PeBenito 885b83
		s = string.split(tun_desc, "\n")
Chris PeBenito 885b83
		file_name.write("#\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 a57379
				# If the module is set as disabled.
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 a57379
				# If the module is set as enabled.
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 a57379
				# If the module is set as base.
Chris PeBenito a57379
				elif [mod_name, MOD_BASE] in namevalue_list:
Chris PeBenito f0cc1a
					file_name.write("%s = %s\n\n" % (mod_name, MOD_BASE))
Chris PeBenito a57379
				# If the module is a new module.
Chris PeBenito a57379
				else:
Chris PeBenito a57379
					# Set the module to base if it is marked as required.
Chris PeBenito a57379
					if mod_req:
Chris PeBenito a57379
						file_name.write("%s = %s\n\n" % (mod_name, MOD_BASE))
Chris PeBenito a57379
					# Set the module to enabled if it is not required. 
Chris PeBenito a57379
					else:
Chris PeBenito a57379
						file_name.write("%s = %s\n\n" % (mod_name, MOD_ENABLED))
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 78d30c
				if desc.parentNode.nodeName != "p":
Chris PeBenito 78d30c
					desc_buf += "

" + desc.data + "

"
Chris PeBenito 78d30c
				else:
Chris PeBenito 78d30c
					desc_buf += desc.data
Chris PeBenito 78d30c
		else:
Chris PeBenito 78d30c
			desc_buf += "<" + desc.nodeName + ">" \
Chris PeBenito 78d30c
				 + format_html_desc(desc) \
Chris PeBenito 78d30c
				 + "</" + desc.nodeName +">"
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 d06f3c
			interface_desc = interface_summary = None
Chris PeBenito bff1ce
			interface_name = interface.getAttribute("name")
Chris PeBenito bff1ce
			interface_line = interface.getAttribute("lineno")
Chris PeBenito 885b83
			for desc in interface.childNodes:
Chris PeBenito 885b83
				if desc.nodeName == "desc":
Chris PeBenito 885b83
					interface_desc = format_html_desc(desc)
Chris PeBenito 885b83
				elif desc.nodeName == "summary":
Chris PeBenito 885b83
					interface_summary = format_html_desc(desc)
Chris PeBenito 885b83
Chris PeBenito 7c2b84
			for args in interface.getElementsByTagName("param"):
Chris PeBenito 885b83
				for desc in args.getElementsByTagName("summary"):
Chris PeBenito 885b83
					paramdesc = format_html_desc(desc)
Chris PeBenito bff1ce
				paramname = args.getAttribute("name")
Chris PeBenito bff1ce
				if args.getAttribute("optional") == "true":
Chris PeBenito bff1ce
					paramopt = "Yes"
Chris PeBenito bff1ce
				else:
Chris PeBenito bff1ce
					paramopt = "No"
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 d06f3c
					   "interface_parameters" : interface_parameters })
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
					   "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 d06f3c
			template_desc = template_summary = None
Chris PeBenito bff1ce
			template_name = template.getAttribute("name")
Chris PeBenito bff1ce
			template_line = template.getAttribute("lineno")
Chris PeBenito 885b83
			for desc in template.childNodes:
Chris PeBenito 885b83
				if desc.nodeName == "desc":
Chris PeBenito 885b83
					template_desc = format_html_desc(desc)
Chris PeBenito 885b83
				elif desc.nodeName == "summary":
Chris PeBenito 885b83
					template_summary = format_html_desc(desc)
Chris PeBenito 885b83
Chris PeBenito effd58
			for args in template.getElementsByTagName("param"):
Chris PeBenito 885b83
				for desc in args.getElementsByTagName("summary"):
Chris PeBenito 885b83
					paramdesc = format_html_desc(desc)
Chris PeBenito bff1ce
				paramname = args.getAttribute("name")
Chris PeBenito bff1ce
				if args.getAttribute("optional") == "true":
Chris PeBenito bff1ce
					paramopt = "Yes"
Chris PeBenito bff1ce
				else:
Chris PeBenito bff1ce
					paramopt = "No"
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 d06f3c
					   "template_parameters" : template_parameters })
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
					   "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 885b83
			for desc in tunable.getElementsByTagName("desc"):
Chris PeBenito 885b83
				description = format_html_desc(desc)
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 4f9f30
	for boolean in doc.getElementsByTagName("bool"):
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 885b83
			for desc in boolean.getElementsByTagName("desc"):
Chris PeBenito 885b83
				description = format_html_desc(desc)
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)