#!/usr/bin/python3 # DpkgControl -*- mode: python; coding: utf-8 -*- # # This module implements control file parsing. # # Copyright (c) 2001 Adam Heath # # DpkgParagraph is a low-level class, that reads/parses a single paragraph # from a file object. # # DpkgControl uses DpkgParagraph in a loop, pulling out the value of a # defined key(package), and using that as a key in it's internal # dictionary. # # DpkgSourceControl grabs the first paragraph from the file object, stores # it in object.source, then passes control to DpkgControl.load, to parse # the rest of the file. # # To test this, pass it a filetype char, a filename, then, optionally, # the key to a paragraph to display, and if a fourth arg is given, only # show that field. # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. from .DpkgDatalist import * from .SignedFile import * class DpkgParagraph(DpkgOrderedDatalist): trueFieldCasing = {} def load( self, f ): """Paragraph data from a file object""" key = None while True: line = f.readline() if not line: return # skip blank lines until we reach a paragraph if line == '\n': if not self: continue else: return if line[ 0 ] != ' ': ( truekey, value ) = line.split( ":", 1 ) key = truekey.lower() self.trueFieldCasing[ key ] = truekey self[ key ] = value.strip() else: self[ key ] += "\n%s" % line.strip() def _storeField( self, f, value, lead = " " ): value = "\n".join(list(map( lambda v, lead = lead: lead + v if v else "", value.splitlines() ))) f.write( "%s\n" % value ) def _store( self, f ): """Write our paragraph data to a file object""" for ( key, value ) in list(self.items()): truekey = self.trueFieldCasing[ key ] f.write( "%s:" % truekey ) self._storeField( f, value ) class DpkgControl(DpkgParagraph): def load( self, f, source = False ): while True: para = DpkgParagraph() para.load( f ) if not para: break if "source" not in para: self[ para[ "package" ] ] = para elif source: self[ "source" ] = para def _store( self, f ): """Write our control data to a file object""" keys = list(self.keys()) while keys: self[ keys.pop( 0 ) ]._store( f ) if keys: f.write( "\n" ) class DpkgSourceControl(DpkgControl): def load( self, f ): f = SignedFile( f ) DpkgControl.load( self, f, source = True ) if __name__ == "__main__": import sys types = { 'p': DpkgParagraph, 'c': DpkgControl, 's': DpkgSourceControl } type = sys.argv[ 1 ] if type not in types: print( "Unknown type `%s'!" % type ) sys.exit( 1 ) file = open( sys.argv[ 2 ], "r" ) data = types[ type ]() data.load( file ) if len( sys.argv ) > 3: rargs = sys.argv[ 3: ] if type != 'p': data = data[ rargs.pop( 0 ) ] if rargs: data._storeField( sys.stdout, data[ rargs[ 0 ].lower() ], "" ) else: data._store( sys.stdout ) else: data._store( sys.stdout ) # vim:ts=4:sw=4:et: