diff --git a/refpolicy/support/pyplate.py b/refpolicy/support/pyplate.py index 20b1bc6c..c7532cc5 100755 --- a/refpolicy/support/pyplate.py +++ b/refpolicy/support/pyplate.py @@ -179,7 +179,7 @@ class ForTemplateNode(TemplateNode): self.vars = [] for v in self.vars_temp: self.vars.append(v.strip()) - print self.vars + #print self.vars self.expression = match.group(2) def execute(self, stream, data): @@ -188,8 +188,8 @@ class ForTemplateNode(TemplateNode): if data.has_key(var): remember_vars[var] = data[var] for list in eval(self.expression, globals(), data): - if util.is_sequence(list): - for index, value in util.enumerate(list): + if is_sequence(list): + for index, value in enumerate(list): data[self.vars[index]] = value else: data[self.vars[0]] = list @@ -255,7 +255,7 @@ class FunctionTemplateNode(TemplateNode): self.vars = [] for v in self.vars_temp: self.vars.append(v.strip()) - print self.vars + #print self.vars self.parent.functions[self.function_name] = self def execute(self, stream, data): @@ -263,7 +263,7 @@ class FunctionTemplateNode(TemplateNode): def call(self, args, stream, data): remember_vars = {} - for index, var in util.enumerate(self.vars): + for index, var in enumerate(self.vars): if data.has_key(var): remember_vars[var] = data[var] data[var] = args[index] @@ -355,37 +355,10 @@ def TemplateNodeFactory(parent): return template_factory_type_map[i](parent, directive) return ExpressionTemplateNode(parent, directive) - -############################################################ -# TESTING CODE -if __name__ == '__main__': - combinations = (('OneBit', 'Float', 'GreyScale'), - ('GreyScale', 'RGB')) - - template = Template(""" - [[# This is a comment #]] - [[# This example does recursive function calls need to generate feature combinations #]] - [[def switch(layer, args)]] - switch(m[[layer]].id) { - [[for option in combinations[layer]]] - [[exec current = option + '(m' + str(layer) + ')']] - case [[option]]: - [[if layer == layers - 1]] - function_call([[string.join(args + [current], ',')]]); - [[else]] - [[call switch(layer + 1, args + [current])]] - [[end]] - break; - [[end]] - } - [[end]] - - PyObject *py_overload_resolution_[[function_name]](PyObject *args) { - [[call switch(0, [])]] - } - """) - - data = {'combinations' : combinations, - 'function_name' : 'threshold', - 'layers' : 2} - template.execute(sys.stdout, data) +def is_sequence(object): + try: + test = object[0:0] + except: + return False + else: + return True diff --git a/refpolicy/support/sedoctool.py b/refpolicy/support/sedoctool.py index 4db82632..ee20546e 100755 --- a/refpolicy/support/sedoctool.py +++ b/refpolicy/support/sedoctool.py @@ -8,12 +8,14 @@ # the Free Software Foundation, version 2. """ - this does dstuff + This module generates configuration files and documentation from the + SELinux reference policy XML format. """ import sys import getopt import pyplate +import os from xml.dom.ext import * from xml.dom.ext.reader import Sax2 @@ -43,68 +45,211 @@ def gen_tunable_conf(doc, file): tun_name = tun_val = None def gen_module_conf(doc, file): + file.write("#\n# This file contains a listing of available modules.\n") + file.write("# To prevent a module from being used in policy\n") + file.write("# creation, uncomment the line with its name.\n#\n") for node in doc.getElementsByTagName("module"): + mod_name = mod_layer = None + for (name, value) in node.attributes.items(): + if name[1] == "name": + mod_name = value.value + if name[1] == "layer": + mod_layer = value.value + + if mod_name and mod_layer: + file.write("# Layer: %s\n# Module: %s\n#\n" % (mod_layer,mod_name)) + for desc in node.getElementsByTagName("summary"): s = string.split(desc.firstChild.data, "\n") for line in s: file.write("# %s\n" % line) - file.write("#\n") - for (name, value) in node.attributes.items(): - if name[1] == "name": - file.write("# %s\n\n" % value.value) + file.write("#\n#%s\n\n" % mod_name) + +def gen_doc_menu(mod_layer, module_list): + menu = {} + for name, value in module_list.iteritems(): + if not menu.has_key(name): + menu[name] = {} + if name == mod_layer or mod_layer == None: + #we are in our layer so fill in the other modules or we want them all + for mod, desc in value.iteritems(): + menu[name][mod] = desc + return menu + +def gen_docs(doc, dir, templatedir): -def gen_docs(doc, file): try: - bodyfile = open("templates/header.html", "r") - intfile = open("templates/interface.html", "r") + bodyfile = open(templatedir + "/header.html", "r") + bodydata = bodyfile.read() + bodyfile.close() + intfile = open(templatedir + "/interface.html", "r") + intdata = intfile.read() + intfile.close() + menufile = open(templatedir + "/menu.html", "r") + menudata = menufile.read() + menufile.close() + indexfile = open(templatedir + "/module_list.html","r") + indexdata = indexfile.read() + indexfile.close() + modulefile = open(templatedir + "/module.html","r") + moduledata = modulefile.read() + modulefile.close() except: error("Could not open templates") - interface_buf = None - interface_parameters = {} + + try: + os.chdir(dir) + except: + error("Could now chdir to target directory") + + +#arg, i have to go through this dom tree ahead of time to build up the menus + module_list = {} + for node in doc.getElementsByTagName("module"): + mod_name = mod_layer = interface_buf = '' + for (name, value) in node.attributes.items(): + if name[1] == "name": + mod_name = value.value + if name[1] == "layer": + mod_layer = value.value + for desc in node.getElementsByTagName("summary"): + mod_summary = desc.firstChild.data + + if not module_list.has_key(mod_layer): + module_list[mod_layer] = {} + + module_list[mod_layer][mod_name] = mod_summary + +#generate index pages + main_content_buf = '' + for mod_layer,modules in module_list.iteritems(): + menu = gen_doc_menu(mod_layer, module_list) + + menu_args = { "menulist" : menu, + "mod_layer" : mod_layer } + menu_tpl = pyplate.Template(menudata) + menu_buf = menu_tpl.execute_string(menu_args) + + content_tpl = pyplate.Template(indexdata) + content_buf = content_tpl.execute_string(menu_args) + + main_content_buf += content_buf + + body_args = { "menu" : menu_buf, + "content" : content_buf } + + index_file = mod_layer + ".html" + index_fh = open(index_file, "w") + body_tpl = pyplate.Template(bodydata) + body_tpl.execute(index_fh, body_args) + index_fh.close() + + menu = gen_doc_menu(None, module_list) + menu_args = { "menulist" : menu, + "mod_layer" : None } + menu_tpl = pyplate.Template(menudata) + menu_buf = menu_tpl.execute_string(menu_args) + + body_args = { "menu" : menu_buf, + "content" : main_content_buf } + + index_file = "index.html" + index_fh = open(index_file, "w") + body_tpl = pyplate.Template(bodydata) + body_tpl.execute(index_fh, body_args) + index_fh.close() + for node in doc.getElementsByTagName("module"): + mod_name = mod_layer = interface_buf = '' + for (name, value) in node.attributes.items(): + if name[1] == "name": + mod_name = value.value + if name[1] == "layer": + mod_layer = value.value + for desc in node.getElementsByTagName("summary"): + mod_summary = desc.firstChild.data for interface in node.getElementsByTagName("interface"): - interface_tpl = pyplate.Template(intfile.read()) + interface_parameters = [] + interface_secdesc = None + interface_tpl = pyplate.Template(intdata) for i,v in interface.attributes.items(): - interface_name = v + interface_name = v.value for desc in interface.getElementsByTagName("description"): interface_desc = desc.firstChild.data for desc in interface.getElementsByTagName("securitydesc"): if desc: interface_secdesc = desc.firstChild.data - else: - interface_secdesc = None for args in interface.getElementsByTagName("parameter"): paramdesc = args.firstChild.data - for i,v in interface.attributes.items(): - arg = { "name" : v, - "desc" : paramdesc } - + paramname = None + paramopt = False + for name,val in args.attributes.items(): + if name[1] == "name": + paramname = val.value + if name[1] == "optional": + paramopt = val.value + parameter = { "name" : paramname, + "desc" : paramdesc, + "optional" : paramopt } + interface_parameters.append(parameter) + interface_args = { "interface_name" : interface_name, + "interface_desc" : interface_desc, + "interface_parameters" : interface_parameters, + "interface_secdesc" : interface_secdesc } + interface_buf += interface_tpl.execute_string(interface_args) + + menu = gen_doc_menu(mod_layer, module_list) + + menu_args = { "menulist" : menu } + menu_tpl = pyplate.Template(menudata) + menu_buf = menu_tpl.execute_string(menu_args) + + module_args = { "mod_layer" : mod_layer, + "mod_name" : mod_name, + "mod_summary" : mod_summary, + "interfaces" : interface_buf } + + module_tpl = pyplate.Template(moduledata) + module_buf = module_tpl.execute_string(module_args) + + body_args = { "menu" : menu_buf, + "content" : module_buf } + + module_file = mod_layer + "_" + mod_name + ".html" + module_fh = open(module_file, "w") + body_tpl = pyplate.Template(bodydata) + body_tpl.execute(module_fh, body_args) + module_fh.close() def error(error): sys.stderr.write("%s exiting for: " % sys.argv[0]) sys.stderr.write("%s\n" % error) sys.stderr.flush() + raise sys.exit(1) def usage(): - sys.stdout.write("%s [-tmd] -x \n\n" % sys.argv[0]) + sys.stdout.write("%s [-tmdT] -x \n\n" % sys.argv[0]) sys.stdout.write("Options:\n") - sys.stdout.write("-t --tunables -- write tunable config to \n") + sys.stdout.write("-t --tunables -- write tunable config to \n") sys.stdout.write("-m --modules -- write module config to \n") sys.stdout.write("-d --docs -- write interface documentation to \n") sys.stdout.write("-x --xml -- filename to read xml data from\n") + sys.stdout.write("-T --templates -- template directory for documents\n") try: - opts, args = getopt.getopt(sys.argv[1:], "t:m:d:x:", ["tunables","modules","docs","xml"]) + opts, args = getopt.getopt(sys.argv[1:], "t:m:d:x:T:", ["tunables","modules","docs","xml", "templates"]) except getopt.GetoptError: usage() sys.exit(1) -tunables = modules = docs = xmlfile = None +tunables = modules = docs = None +templatedir = "templates/" +xmlfile = "policy.xml" for opt, val in opts: if opt in ("-t", "--tunables"): @@ -112,9 +257,11 @@ for opt, val in opts: if opt in ("-m", "--modules"): modules = val if opt in ("-d", "--docs"): - docs = val + docsdir = val if opt in ("-x", "--xml"): xmlfile = val + if opt in ("-T", "--templates"): + templatedir = val if xmlfile == None: usage() @@ -139,5 +286,5 @@ if modules: gen_module_conf(doc, conf) conf.close() -if docs: - gen_docs(doc, sys.stdout) +if docsdir: + gen_docs(doc, docsdir, templatedir)