userland-mangler revision 181
10139N/A#!/usr/bin/python2.6
10139N/A#
10139N/A# CDDL HEADER START
10139N/A#
10139N/A# The contents of this file are subject to the terms of the
10139N/A# Common Development and Distribution License (the "License").
10139N/A# You may not use this file except in compliance with the License.
10139N/A#
10139N/A# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10139N/A# or http://www.opensolaris.org/os/licensing.
10139N/A# See the License for the specific language governing permissions
10139N/A# and limitations under the License.
10139N/A#
10139N/A# When distributing Covered Code, include this CDDL HEADER in each
10139N/A# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
10139N/A# If applicable, add the following below this CDDL HEADER, with the
10139N/A# fields enclosed by brackets "[]" replaced with your own identifying
10139N/A# information: Portions Copyright [yyyy] [name of copyright owner]
10139N/A#
10139N/A# CDDL HEADER END
10139N/A#
10139N/A# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
10139N/A#
10139N/A#
10139N/A# userland-mangler - a file mangling utility
10139N/A#
10139N/A# A simple program to mangle files to conform to Solaris WOS or Consoldation
10139N/A# requirements.
10139N/A#
10139N/A
10139N/Aimport os
10139N/Aimport sys
10139N/Aimport re
10139N/A
10139N/Aimport pkg.fmri
10139N/Aimport pkg.manifest
10139N/Aimport pkg.actions
10139N/Aimport pkg.elf as elf
10139N/A
10139N/Aattribute_table_header = """
10139N/A.SH ATTRIBUTES
10139N/ASee
10139N/A.BR attributes (5)
10139N/Afor descriptions of the following attributes:
10139N/A.sp
10139N/A.TS
10139N/Abox;
10139N/Acbp-1 | cbp-1
10139N/Al | l .
10139N/AATTRIBUTE TYPE ATTRIBUTE VALUE """
10139N/A
10139N/Aattribute_table_availability = """
10139N/A=
10139N/AAvailability %s"""
10139N/A
10139N/Aattribute_table_stability = """
10139N/A=
10139N/AStability %s"""
10139N/A
10139N/Aattribute_table_footer = """
10139N/A.TE
10139N/A.PP
10139N/A"""
10139N/Adef write_attributes_section(ofp, availability, stability):
10139N/A # is there anything to do?
10139N/A if availability is None and stability is None:
10139N/A return
10139N/A
10139N/A # append the ATTRIBUTES section
10139N/A ofp.write(attribute_table_header)
10139N/A if availability is not None:
10139N/A ofp.write(attribute_table_availability % availability)
10139N/A if stability is not None:
10139N/A ofp.write(attribute_table_stability % stability.capitalize())
10139N/A ofp.write(attribute_table_footer)
10139N/A
10139N/A
10139N/Anotes_header = """
10139N/A.SH NOTES
10139N/A"""
10139N/A
10139N/Anotes_community = """
10139N/AFurther information about this software can be found on the open source community website at %s.
10139N/A"""
10139N/Anotes_source = """
10139N/AThis software was built from source available at http://opensolaris.org/. The original community source was downloaded from %s
10139N/A"""
10139N/A
10139N/Adef write_notes_section(ofp, header_seen, community, source):
10139N/A # is there anything to do?
10139N/A if community is None and source is None:
10139N/A return
10139N/A
10139N/A # append the NOTES section
10139N/A if header_seen == False:
10139N/A ofp.write(notes_header)
10139N/A if source is not None:
10139N/A ofp.write(notes_source % source)
10139N/A if community is not None:
10139N/A ofp.write(notes_community % community)
10139N/A
10139N/A
10139N/Asection_re = re.compile('\.SH "?([^"]+).*$', re.IGNORECASE)
10139N/A#
10139N/A# mangler.man.stability = (mangler.man.stability)
10139N/A# mangler.man.availability = (pkg.fmri)
10139N/A# mangler.man.source_url = (pkg.source_url)
10139N/A# mangler.man.upstream_url = (pkg.upstream_url)
10139N/A#
10139N/Adef mangle_manpage(manifest, action, src, dest):
10139N/A # manpages must have a taxonomy defined
10139N/A stability = action.attrs.pop('mangler.man.stability', None)
10139N/A if stability is None:
10139N/A sys.stderr.write("ERROR: manpage action missing mangler.man.stability: %s" % action)
10139N/A sys.exit(1)
10139N/A
10139N/A attributes_written = False
10139N/A notes_seen = False
10139N/A
10139N/A if 'pkg.fmri' in manifest.attributes:
10139N/A fmri = pkg.fmri.PkgFmri(manifest.attributes['pkg.fmri'])
10139N/A availability = fmri.pkg_name
10139N/A
10139N/A if 'info.upstream_url' in manifest.attributes:
10139N/A community = manifest.attributes['info.upstream_url']
10139N/A
10139N/A if 'info.source_url' in manifest.attributes:
10139N/A source = manifest.attributes['info.source_url']
10139N/A
10320N/A # create a directory to write to
10320N/A destdir = os.path.dirname(dest)
10139N/A if not os.path.exists(destdir):
10139N/A os.makedirs(destdir)
10139N/A
10139N/A # read the source document
10139N/A ifp = open(src, "r")
10139N/A lines = ifp.readlines()
10139N/A ifp.close()
10139N/A
10139N/A # skip reference only pages
10139N/A if lines[0].startswith(".so "):
10139N/A return
10139N/A
10139N/A # open a destination
10139N/A ofp = open(dest, "w+")
10139N/A
10139N/A # tell man that we want tables (and eqn)
10139N/A ofp.write("'\\\" te\n")
10139N/A
10139N/A # write the orginal data
10139N/A for line in lines:
10139N/A match = section_re.match(line)
10139N/A if match is not None:
10139N/A section = match.group(1)
10139N/A if section in ['SEE ALSO', 'NOTES']:
10139N/A if attributes_written == False:
10139N/A write_attributes_section(ofp,
10139N/A availability,
10139N/A stability)
10139N/A attributes_written = True
10139N/A if section == 'NOTES':
10139N/A notes_seen = True
10139N/A ofp.write(line)
10139N/A
10139N/A if attributes_written == False:
10139N/A write_attributes_section(ofp, availability, stability)
10139N/A
10139N/A write_notes_section(ofp, notes_seen, community, source)
10139N/A
10139N/A ofp.close()
10139N/A
10139N/A
10139N/A#
10139N/A# mangler.elf.strip = (true|false)
10139N/A#
10139N/Adef mangle_elf(manifest, action, src, dest):
10139N/A pass
10139N/A
10139N/A#
10139N/A# mangler.script.file-magic =
10139N/A#
10139N/Adef mangle_script(manifest, action, src, dest):
10139N/A pass
10139N/A
10139N/Adef mangle_path(manifest, action, src, dest):
10139N/A if 'facet.doc.man' in action.attrs:
10139N/A mangle_manpage(manifest, action, src, dest)
10139N/A elif 'mode' in action.attrs and int(action.attrs['mode'], 8) & 0111 != 0:
10139N/A if elf.is_elf_object(src):
10139N/A mangle_elf(manifest, action, src, dest)
10139N/A else:
10139N/A mangle_script(manifest, action, src, dest)
10139N/A
10139N/A#
10139N/A# mangler.bypass = (true|false)
10139N/A#
10139N/Adef mangle_paths(manifest, search_paths, destination):
10139N/A for action in manifest.gen_actions_by_type("file"):
10139N/A bypass = action.attrs.pop('mangler.bypass', 'false').lower()
10139N/A if bypass == 'true':
10139N/A continue
10139N/A
10139N/A path = None
10139N/A if 'path' in action.attrs:
10139N/A path = action.attrs['path']
10139N/A if action.hash and action.hash != 'NOHASH':
10139N/A path = action.hash
10139N/A if not path:
10139N/A continue
10139N/A
10139N/A dest = os.path.join(destination, path)
10139N/A for directory in search_paths:
10139N/A if directory != destination:
10139N/A src = os.path.join(directory, path)
10139N/A if os.path.exists(src):
10139N/A mangle_path(manifest, action, src, dest)
10139N/A break
10139N/A
10139N/Adef load_manifest(manifest_file):
10139N/A manifest = pkg.manifest.Manifest()
10139N/A manifest.set_content(pathname=manifest_file)
10139N/A
10139N/A return manifest
10139N/A
10139N/Adef usage():
10139N/A print "Usage: %s [-m|--manifest (file)] [-d|--search-directory (dir)] [-D|--destination (dir)] " % (sys.argv[0].split('/')[-1])
10139N/A sys.exit(1)
10139N/A
10139N/Adef main():
10139N/A import getopt
10139N/A
10139N/A # FLUSH STDOUT
10139N/A sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
10139N/A
10139N/A search_paths = []
10139N/A destination = None
10139N/A manifests = []
10139N/A
10139N/A try:
10139N/A opts, args = getopt.getopt(sys.argv[1:], "D:d:m:",
10139N/A ["destination=", "search-directory=", "manifest="])
10139N/A except getopt.GetoptError, err:
10139N/A print str(err)
10139N/A usage()
10139N/A
10139N/A for opt, arg in opts:
10139N/A if opt in [ "-D", "--destination" ]:
10139N/A destination = arg
10139N/A elif opt in [ "-d", "--search-directory" ]:
10139N/A search_paths.append(arg)
10139N/A elif opt in [ "-m", "--manifest" ]:
10139N/A try:
10139N/A manifest = load_manifest(arg)
10139N/A except IOError, err:
10139N/A print "oops, %s: %s" % (arg, str(err))
10139N/A usage()
10139N/A else:
10139N/A manifests.append(manifest)
10139N/A else:
10139N/A usage()
10139N/A
10139N/A if destination == None:
10139N/A usage()
10139N/A
10139N/A for manifest in manifests:
10139N/A mangle_paths(manifest, search_paths, destination)
10139N/A print manifest
10139N/A
10139N/A sys.exit(0)
10139N/A
10139N/Aif __name__ == "__main__":
10139N/A main()
10139N/A