#! /usr/bin/python -tt import os import sys import struct # Decent (UK/US English only) number formatting. import locale locale.setlocale(locale.LC_ALL, '') def loc_num(x): """ Return a string of a number in the readable "locale" format. """ return locale.format("%d", int(x), True) # import rpm class rpm: RPMTAG_HEADERIMAGE = 61 RPMTAG_HEADERSIGNATURES = 62 RPMTAG_HEADERIMMUTABLE = 63 RPMTAG_HEADERREGIONS = 64 RPMTAG_HEADERI18NTABLE = 100 RPMTAG_SIGBASE = 256 RPMTAG_TAGBASE = 1000 RPMTAG_SIGSIZE = RPMTAG_SIGBASE+ 1 RPMTAG_SIGPGP = RPMTAG_SIGBASE+ 3 RPMTAG_SIGMD5 = RPMTAG_SIGBASE+ 5 RPMTAG_SIGGPG = RPMTAG_SIGBASE+ 6 RPMTAG_PUBKEYS = RPMTAG_SIGBASE+10 RPMTAG_DSAHEADER = RPMTAG_SIGBASE+11 RPMTAG_RSAHEADER = RPMTAG_SIGBASE+12 RPMTAG_SHA1HEADER = RPMTAG_SIGBASE+13 def err(ern, fmt, *args): print >>sys.stderr, "Error: " + fmt % args sys.exit(ern) def dbg(fmt, *args): print >>sys.stderr, "DBG: " + fmt % args def get_B(fo, num=1): return struct.unpack("B" * num, fo.read(num)) def get_s(fo, num=1): return struct.unpack("%ds" % num, fo.read(num))[0].rstrip('\0') assert struct.calcsize("i") == 4 def get_sbe32(fo): return struct.unpack(">i", fo.read(4))[0] assert struct.calcsize(">I") == 4 def get_ube32(fo): return struct.unpack(">I", fo.read(4))[0] assert struct.calcsize(">h") == 2 def get_sbe16(fo): return struct.unpack(">h", fo.read(2))[0] def padto(num, padto): """ Pad num to padto byte boundry. """ pad = (num % padto) if pad: pad = (padto - pad) return pad __sizeof_lead__ = 96 __sizeof_tag__ = 16 # enum rpmTag_e => RPMTAG_* rpm_tag_enum_map = {} for (val, key) in { 'NAME' : 1000, # /* s */ 'VERSION' : 1001, # /* s */ 'RELEASE' : 1002, # /* s */ 'EPOCH' : 1003, # /* i */ 'SUMMARY' : 1004, # /* s{} */ 'DESCRIPTION' : 1005, # /* s{} */ 'BUILDTIME' : 1006, # /* i */ 'BUILDHOST' : 1007, # /* s */ 'INSTALLTIME' : 1008, # /* i */ 'SIZE' : 1009, # /* i */ 'DISTRIBUTION' : 1010, # /* s */ 'VENDOR' : 1011, # /* s */ 'GIF' : 1012, # /* x */ 'XPM' : 1013, # /* x */ 'LICENSE' : 1014, # /* s */ 'PACKAGER' : 1015, # /* s */ 'GROUP' : 1016, # /* s{} */ 'CHANGELOG' : 1017, # /* s[] internal */ 'SOURCE' : 1018, # /* s[] */ 'PATCH' : 1019, # /* s[] */ 'URL' : 1020, # /* s */ 'OS' : 1021, # /* s legacy used int */ 'ARCH' : 1022, # /* s legacy used int */ 'PREIN' : 1023, # /* s */ 'POSTIN' : 1024, # /* s */ 'PREUN' : 1025, # /* s */ 'POSTUN' : 1026, # /* s */ 'FILESIZES' : 1028, # /* i[] */ 'FILESTATES' : 1029, # /* c[] */ 'FILEMODES' : 1030, # /* h[] */ 'FILEUIDS' : 1031, # /* i[] internal */ 'FILEGIDS' : 1032, # /* i[] internal */ 'FILERDEVS' : 1033, # /* h[] */ 'FILEMTIMES' : 1034, # /* i[] */ 'FILEMD5S' : 1035, # /* s[] */ 'FILELINKTOS' : 1036, # /* s[] */ 'FILEFLAGS' : 1037, # /* i[] */ 'FILEUSERNAME' : 1039, # /* s[] */ 'FILEGROUPNAME' : 1040, # /* s[] */ 'ICON' : 1043, # /* x */ 'SOURCERPM' : 1044, # /* s */ 'FILEVERIFYFLAGS' : 1045, # /* i[] */ 'ARCHIVESIZE' : 1046, # /* i */ 'PROVIDENAME' : 1047, # /* s[] */ 'REQUIREFLAGS' : 1048, # /* i[] */ 'REQUIRENAME' : 1049, # /* s[] */ 'REQUIREVERSION' : 1050, # /* s[] */ 'NOSOURCE' : 1051, # /* i internal */ 'NOPATCH' : 1052, # /* i internal */ 'CONFLICTFLAGS' : 1053, # /* i[] */ 'CONFLICTNAME' : 1054, # /* s[] */ 'CONFLICTVERSION' : 1055, # /* s[] */ 'BUILDROOT' : 1057, # /* s internal */ 'EXCLUDEARCH' : 1059, # /* s[] */ 'EXCLUDEOS' : 1060, # /* s[] */ 'EXCLUSIVEARCH' : 1061, # /* s[] */ 'EXCLUSIVEOS' : 1062, # /* s[] */ 'RPMVERSION' : 1064, # /* s */ 'TRIGGERSCRIPTS' : 1065, # /* s[] */ 'TRIGGERNAME' : 1066, # /* s[] */ 'TRIGGERVERSION' : 1067, # /* s[] */ 'TRIGGERFLAGS' : 1068, # /* i[] */ 'TRIGGERINDEX' : 1069, # /* i[] */ 'VERIFYSCRIPT' : 1079, # /* s */ 'CHANGELOGTIME' : 1080, # /* i[] */ 'CHANGELOGNAME' : 1081, # /* s[] */ 'CHANGELOGTEXT' : 1082, # /* s[] */ 'PREINPROG' : 1085, # /* s */ 'POSTINPROG' : 1086, # /* s */ 'PREUNPROG' : 1087, # /* s */ 'POSTUNPROG' : 1088, # /* s */ 'BUILDARCHS' : 1089, # /* s[] */ 'OBSOLETENAME' : 1090, # /* s[] */ 'VERIFYSCRIPTPROG' : 1091, # /* s */ 'TRIGGERSCRIPTPROG' : 1092, # /* s[] */ 'COOKIE' : 1094, # /* s */ 'FILEDEVICES' : 1095, # /* i[] */ 'FILEINODES' : 1096, # /* i[] */ 'FILELANGS' : 1097, # /* s[] */ 'PREFIXES' : 1098, # /* s[] */ 'INSTPREFIXES' : 1099, # /* s[] */ 'PROVIDEFLAGS' : 1112, # /* i[] */ 'PROVIDEVERSION' : 1113, # /* s[] */ 'OBSOLETEFLAGS' : 1114, # /* i[] */ 'OBSOLETEVERSION' : 1115, # /* s[] */ 'DIRINDEXES' : 1116, # /* i[] */ 'BASENAMES' : 1117, # /* s[] */ 'DIRNAMES' : 1118, # /* s[] */ 'ORIGDIRINDEXES' : 1119, # /* i[] relocation */ 'ORIGBASENAMES' : 1120, # /* s[] relocation */ 'ORIGDIRNAMES' : 1121, # /* s[] relocation */ 'OPTFLAGS' : 1122, # /* s */ 'DISTURL' : 1123, # /* s */ 'PAYLOADFORMAT' : 1124, # /* s */ 'PAYLOADCOMPRESSOR' : 1125, # /* s */ 'PAYLOADFLAGS' : 1126, # /* s */ 'INSTALLCOLOR' : 1127, # /* i transaction color when installed */ 'INSTALLTID' : 1128, # /* i */ 'REMOVETID' : 1129, # /* i */ 'RHNPLATFORM' : 1131, # /* s deprecated */ 'PLATFORM' : 1132, # /* s */ 'CACHECTIME' : 1136, # /* i */ 'CACHEPKGPATH' : 1137, # /* s */ 'CACHEPKGSIZE' : 1138, # /* i */ 'CACHEPKGMTIME' : 1139, # /* i */ 'FILECOLORS' : 1140, # /* i[] */ 'FILECLASS' : 1141, # /* i[] */ 'CLASSDICT' : 1142, # /* s[] */ 'FILEDEPENDSX' : 1143, # /* i[] */ 'FILEDEPENDSN' : 1144, # /* i[] */ 'DEPENDSDICT' : 1145, # /* i[] */ 'SOURCEPKGID' : 1146, # /* x */ 'FILECONTEXTS' : 1147, # /* s[] - obsolete */ 'POLICIES' : 1150, # /* s[] selinux *.te policy file. */ 'PRETRANS' : 1151, # /* s */ 'POSTTRANS' : 1152, # /* s */ 'PRETRANSPROG' : 1153, # /* s */ 'POSTTRANSPROG' : 1154, # /* s */ 'DISTTAG' : 1155, # /* s */ 'SUGGESTSNAME' : 1156, # /* s[] extension */ 'SUGGESTSVERSION' : 1157, # /* s[] extension */ 'SUGGESTSFLAGS' : 1158, # /* i[] extension */ 'ENHANCESNAME' : 1159, # /* s[] extension placeholder */ 'ENHANCESVERSION' : 1160, # /* s[] extension placeholder */ 'ENHANCESFLAGS' : 1161, # /* i[] extension placeholder */ 'PRIORITY' : 1162, # /* i[] extension placeholder */ 'CVSID' : 1163, # /* s */ 'BLINKPKGID' : 1164, # /* s[] */ 'BLINKHDRID' : 1165, # /* s[] */ 'BLINKNEVRA' : 1166, # /* s[] */ 'FLINKPKGID' : 1167, # /* s[] */ 'FLINKHDRID' : 1168, # /* s[] */ 'FLINKNEVRA' : 1169, # /* s[] */ 'PACKAGEORIGIN' : 1170, # /* s */ 'SCRIPTSTATES' : 1174, # /* i[] scriptlet exit codes */ 'SCRIPTMETRICS' : 1175, # /* i[] scriptlet execution times */ 'BUILDCPUCLOCK' : 1176, # /* i */ 'FILEDIGESTALGOS' : 1177, # /* i[] */ 'VARIANTS' : 1178, # /* s[] */ 'XMAJOR' : 1179, # /* i */ 'XMINOR' : 1180, # /* i */ 'REPOTAG' : 1181, # /* s */ 'KEYWORDS' : 1182, # /* s[] */ 'BUILDPLATFORMS' : 1183, # /* s[] */ 'PACKAGECOLOR' : 1184 # /* i */ }.iteritems(): rpm_tag_enum_map[key] = val for key in [ 'HEADERIMAGE', # = HEADER_IMAGE, /*!< Current image. */ 'HEADERSIGNATURES', # = HEADER_SIGNATURES, /*!< Signatures. */ 'HEADERIMMUTABLE', # = HEADER_IMMUTABLE, /*!< Original image. */ 'HEADERREGIONS', # = HEADER_REGIONS, /*!< Regions. */ 'HEADERI18NTABLE', # = HEADER_I18NTABLE, /* s[] !< I18N string locales. */ 'SIGSIZE', # = RPMTAG_SIG_BASE+1, /* i */ 'SIGPGP', # = RPMTAG_SIG_BASE+3, /* x */ 'SIGMD5', # = RPMTAG_SIG_BASE+5, /* x */ 'SIGGPG', # = RPMTAG_SIG_BASE+6, /* x */ 'PUBKEYS', # = RPMTAG_SIG_BASE+10, /* s[] */ 'DSAHEADER', # = RPMTAG_SIG_BASE+11, /* x */ 'RSAHEADER', # = RPMTAG_SIG_BASE+12, /* x */ 'SHA1HEADER' # = RPMTAG_SIG_BASE+13, /* s */ ]: rpm_tag_enum_map[getattr(rpm, 'RPMTAG_' + key)] = key # enum rpmTagType_e => RPM_*_TYPE rpm_tag_type_map = {0 : 'NULL', 1 : 'char', 2 : 'int8', 3 : 'int16', 4 : 'int32', 5 : 'int64', 6 : 'string', 7 : 'bin', 8 : 'string[]', 9 : 'i18n string'} # enum rpmSigTag_e => RPMSIGTAG_* rpm_sigtag_enum_map = {} for (val, key) in { 'SIG_SIZE' : 1000, # /*!< Header+Payload size in bytes. */ 'SIG_LEMD5_1' : 1001, # /*!< Broken MD5, take 1 @deprecated legacy. */ 'SIG_PGP' : 1002, # /*!< PGP 2.6.3 signature. */ 'SIG_LEMD5_2' : 1003, # /*!< Broken MD5, take 2 @deprecated legacy. */ 'SIG_MD5' : 1004, # /*!< MD5 signature. */ 'SIG_GPG' : 1005, # /*!< GnuPG signature. */ 'SIG_PGP5' : 1006, # /*!< PGP5 signature @deprecated legacy. */ 'SIG_PAYLOADSIZE' : 1007 # /*!< uncompressed payload size in bytes. */ }.iteritems(): rpm_sigtag_enum_map[key] = val class RpmTag: def __init__(self, tag_num, fo, sigtype=False, negate=False): self.tag_num = tag_num self.sigtype = sigtype # Need to do: headerVerifyInfo() self._enum = get_ube32(fo) self._type = get_ube32(fo) if negate: self.off = -get_sbe32(fo) else: self.off = get_sbe32(fo) self.num = get_ube32(fo) if sigtype and self._enum in rpm_sigtag_enum_map: enum_map = rpm_sigtag_enum_map else: enum_map = rpm_tag_enum_map assert self._enum in enum_map self.enum = enum_map[self._enum] assert self._type in rpm_tag_type_map self.type = rpm_tag_type_map[self._type] def __repr__(self): ret = "" ret += "%sTag[%u] : %s\n" % (" " * 4, self.tag_num, self.enum) ret += "%sType[%u]: %s\n" % (" " * 4, self.tag_num, self.type) ret += "%sOff[%u] : %d\n" % (" " * 4, self.tag_num, self.off) ret += "%sNum[%u] : %d" % (" " * 4, self.tag_num, self.num) if hasattr(self, 'data'): ret += "\n%sData[%u]: %s\n" % (" " * 4,self.tag_num,str(self.data)) ret += "%sData[%u]: Len=%d" % (" " * 4,self.tag_num, self.data_len) return ret __str__ = __repr__ def __cmp__(self, other): if other is None: return -1 ret = self._enum - other._enum if not ret: ret = cmp(id(self), id(other)) return ret class RpmHdr: def __init__(self, pkg_fname, fo=None): self.pkg_fname = pkg_fname if fo is None: fo = file(pkg_fname) self.fo = fo magic = get_B(fo, 4) if magic != (0xed, 0xab, 0xee, 0xdb): err(1, "Bad magic for: %s = %s", pkg_fname, magic) self.rpm_version = get_B(fo, 2) self.rpm_type = get_B(fo, 2) self.rpm_arch = get_B(fo, 2) self.rpm_name = get_s(fo, 66) self.rpm_os = get_B(fo, 2) self.rpm_sig = get_B(fo, 2) get_B(fo, 16) # Padding self._off_end_lead = fo.tell() assert __sizeof_lead__ == self._off_end_lead # Signature... magic = get_B(fo, 8) if magic != (0x8e, 0xad, 0xe8, 1, 0, 0, 0, 0): err(1, "Bad 2nd header magic for: %s = %s instead of %s", self.pkg_fname, magic, (0x8e, 0xad, 0xe8, 1, 0, 0, 0, 0)) self.sig_tags_idx_num = get_ube32(fo) self.sig_tags_data_sz = get_ube32(fo) self._off_beg_tags = fo.tell() def __repr__(self): ret = '' ret += "PKG : %s\n" % os.path.basename(self.pkg_fname) ret += "Hdr-Version: %d.%d\n" % self.rpm_version if self.rpm_type[0] or self.rpm_type[1] not in (0, 1): ret += "Hdr-Type : = %d/%d\n" % self.rpm_type elif self.rpm_type[1]: ret += "Hdr-Type : Source rpm\n" else: ret += "Hdr-Type : Binary rpm\n" ret += "Hdr-Arch : %d/%d\n" % self.rpm_arch ret += "Hdr-Name : %s\n" % self.rpm_name ret += "Hdr-OS : %d/%d\n" % self.rpm_os if self.rpm_sig[0] or self.rpm_sig[1] != 5: ret += "Hdr-Sig : = %d/%d\n" % self.rpm_sig ret += ("Sig-Tags : %3u tags with %10s bytes of data" % (self.sig_tags_idx_num, loc_num(self.sig_tags_data_sz))) if not hasattr(self, 'data_tags_idx_num'): return ret # No data, yet ret += ("\nData-Tags : %3u tags with %10s bytes of data\n" % (self.data_tags_idx_num, loc_num(self.data_tags_data_sz))) ret += "Name : %s\n" % self.data_tag['NAME'][0].data epoch = '0' if 'EPOCH' in self.data_tag: epoch = self.data_tag['EPOCH'][0].data ret += "EVRA : %s:%s-%s.%s\n" % (epoch, self.data_tag['VERSION'][0].data, self.data_tag['RELEASE'][0].data, self.data_tag['ARCH'][0].data) ret += "Summary : %s" % self.data_tag['SUMMARY'][0].data[0] return ret __str__ = __repr__ def idx_tags(hdr, sigtype=False): if sigtype: idx_num_tags = hdr.sig_tags_idx_num data_sz_tags = hdr.sig_tags_data_sz else: idx_num_tags = hdr.data_tags_idx_num data_sz_tags = hdr.data_tags_data_sz tags = [] for tnum in xrange(1, idx_num_tags + 1): tag = RpmTag(tnum, hdr.fo, sigtype) if tag.off > data_sz_tags: err(1, "Bad tag offset for: %s: %d/%u = %d/%u", hdr.pkg_fname, tnum, idx_num_tags, tag.off, data_sz_tags) tags.append(tag) if sigtype: hdr._off_beg_data = hdr.fo.tell() hdr._off_end_data = hdr._off_beg_data + data_sz_tags hdr._off_end_data += padto(hdr._off_end_data, 8) else: hdr._off_beg_2data = hdr.fo.tell() hdr._off_end_2data = hdr._off_beg_2data + data_sz_tags hdr._off_end_2data += padto(hdr._off_end_2data, 8) if (tags and tags[0].enum == 'HEADERSIGNATURES' and tags[0].type == 'bin' and tags[0].num == __sizeof_tag__): get_B(hdr.fo, tags[0].off) tag = RpmTag(-1, hdr.fo, sigtype, negate=True) # Do old conversion if tag.enum == 'HEADERIMAGE': dbg("HEADERIMAGE beg") dbg(tag) dbg("HEADERIMAGE end") tag.enum = 'HEADERSIGNATURES' assert not (tag.off % __sizeof_tag__) assert (tag.off / __sizeof_tag__) <= idx_num_tags tags.append(tag) tagmap = {} for tag in tags: tagmap.setdefault(tag.enum, []).append(tag) tagmap.setdefault(tag._enum, []).append(tag) return (tags, tagmap) def _load_tag_off(hdr, tag): if tag.sigtype: hdr.fo.seek(hdr._off_beg_data + tag.off) else: hdr.fo.seek(hdr._off_beg_2data + tag.off) def _load_tag_cstr(hdr): ret = [] byte = get_s(hdr.fo, 1) while byte: ret.append(byte) byte = get_s(hdr.fo, 1) # assert (hdr.fo.tell() - hdr._off_beg_data) <= hdr.data_sz_tags return (''.join(ret), len(ret) + 1) def _load_tag_i18ns(hdr, num): ret = [] ret_len = 0 for i in xrange(num): vals = hdr._load_tag_cstr() ret.append(vals[0]) ret_len += vals[1] return (ret, ret_len) def _load_tag_B(hdr, num): return (get_B(hdr.fo, num), num) def _load_tag_s(hdr, num): return (get_s(hdr.fo, num), num) def _load_tag_sbe16(hdr, num): ret = [] for i in xrange(num): ret.append(get_sbe16(hdr.fo)) if num == 1: return (ret[0], 2) return (ret, len(ret) * 2) def _load_tag_sbe32(hdr, num): ret = [] for i in xrange(num): ret.append(get_sbe32(hdr.fo)) if num == 1: return (ret[0], 4) return (ret, len(ret) * 4) def load_tag(hdr, tag): if hasattr(tag, 'data'): return hdr._load_tag_off(tag) if False: pass elif tag.type == 'NULL': (tag.data, tag.data_len) = (None, 0) elif tag.type == 'string': (tag.data, tag.data_len) = hdr._load_tag_cstr() elif tag.type == 'string[]' or tag.type == 'i18n string': (tag.data, tag.data_len) = hdr._load_tag_i18ns(tag.num) elif tag.type == 'bin': (tag.data, tag.data_len) = hdr._load_tag_B(tag.num) elif tag.type == 'char': (tag.data, tag.data_len) = hdr._load_tag_s(tag.num) elif tag.type == 'int8': (tag.data, tag.data_len) = hdr._load_tag_B(tag.num) elif tag.type == 'int16': (tag.data, tag.data_len) = hdr._load_tag_sbe16(tag.num) elif tag.type == 'int32': (tag.data, tag.data_len) = hdr._load_tag_sbe32(tag.num) else: raise TypeError def _load_header(hdr): tag = hdr.sig_tags[0] if tag.enum < rpm.RPMTAG_HEADERI18NTABLE: assert False # untested ... headerLoad() assert tag.off assert tag.type == 'bin' assert tag.num == 16 tag.type = 'int32' tag.num = 4 hdr.load_tag(tag) dbg(tag.data) tag.rdl = -tag.data[2] tag.ril = tag.rdl / __sizeof_tag__ dbg("rdl=%u / ril=%u", tag.rdl, tag.ril) else: # legacy... if False: # Needed, as we have dicts? ... rpm just sorts for search? hdr.sig_tags.sort() def _sig_tags_sizeof(hdr): """ Work out the "size" of the on-disk file hdr tags. """ size = 16 for tag in hdr.sig_tags: if tag._enum >= 61 and tag._enum <= 63: # FIXME: magc numbers size += tag.data_len if False: # FIXME: no understand-ay if tag == hdr.sig_tags[0] and True: # legacy size += __sizeof_tag__ size += tag.num continue if tag.type == 'int16': size += padto(size, 2) if tag.type == 'int32': size += padto(size, 4) if tag.type == 'int64': size += padto(size, 8) size += __sizeof_tag__ size += tag.data_len return size def load_tags(hdr): (hdr.sig_tags, hdr.sig_tag) = hdr.idx_tags(sigtype=True) hdr._load_header() for tag in hdr.sig_tags: hdr.load_tag(tag) hdr.fo.seek(hdr._off_end_data) # Signature... magic = get_B(hdr.fo, 8) if magic != (0x8e, 0xad, 0xe8, 1, 0, 0, 0, 0): err(1, "Bad 2nd header magic for: %s = %s instead of %s", hdr.pkg_fname, magic, (0x8e, 0xad, 0xe8, 1, 0, 0, 0, 0)) hdr.data_tags_idx_num = get_ube32(hdr.fo) hdr.data_tags_data_sz = get_ube32(hdr.fo) hdr._off_beg_2tags = hdr.fo.tell() (hdr.data_tags, hdr.data_tag) = hdr.idx_tags() for tag in hdr.data_tags: hdr.load_tag(tag) hdr.sig_tags_size = hdr._sig_tags_sizeof() hdr.padding = padto(hdr.sig_tags_size, 8) hdr.arch_size = hdr.sig_tag['SIG_SIZE'][0].data hdr.file_size = 0 hdr.file_size += hdr.sig_tags_size hdr.file_size += hdr.padding hdr.file_size += hdr.sig_tag['SIG_SIZE'][0].data hdr.file_size += __sizeof_lead__ return hdr.sig_tags __print_tags__ = False def dump_rpm_info(pkg_fname): hdr = RpmHdr(pkg_fname) # print hdr hdr.load_tags() print hdr if __print_tags__: for tag in hdr.sig_tags: print tag print '' print '' print 'Hdrinfo:' print ' Hdr Size: %10s' % loc_num(hdr.file_size) print ' Stat Size: %10s' % loc_num(os.stat(hdr.pkg_fname).st_size) print ' Sig Size: %10s' % loc_num(hdr.sig_tag['SIG_SIZE'][0].data) print ' Pay Size: %10s' % loc_num(hdr.sig_tag['SIG_PAYLOADSIZE'][0].data) print ' Pkg Size: %10s' % loc_num(hdr.data_tag['SIZE'][0].data) print '' if __print_tags__: for tag in hdr.data_tags: print tag print '' if False: print 'Taginfo:' print ' Size :', hdr.sig_tag['SIG_SIZE'][0].data print ' Payload Size:', hdr.sig_tag['SIG_PAYLOADSIZE'][0].data print ' SHA1 :', hdr.sig_tag['SHA1HEADER'][0].data if 'PAYLOADFORMAT' in hdr.sig_tag: print ' Payload Fmt :', hdr.sig_tag['PAYLOADFORMAT'][0].data else: print ' Payload Fmt :', 'cpio' if 'PAYLOADCOMPRESSOR' in hdr.sig_tag: print ' Payload Zip :', hdr.sig_tag['PAYLOADCOMPRESSOR'][0].data else: print ' Payload Zip :', 'gzip' print '' if len(sys.argv) < 2: err(1, "Usage: dump_rpm_info ...") for fname in sys.argv[1:]: dump_rpm_info(fname)