Commit 9fd960a7 authored by Gabriel Monnerat's avatar Gabriel Monnerat

rpm2cpio: Support python 3

parent 4a984112
...@@ -6,4 +6,4 @@ parts = ...@@ -6,4 +6,4 @@ parts =
# https://github.com/ruda/rpm2cpio # https://github.com/ruda/rpm2cpio
recipe = slapos.recipe.build:download recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/${:_buildout_section_name_} url = ${:_profile_base_location_}/${:_buildout_section_name_}
md5sum = aa3a5920a1d8963592be0c2666ee05e2 md5sum = cc898f0b12f7264bcc21738473a4da88
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
# Standalone RPM to CPIO converter # Lightweight RPM to CPIO converter.
# Copyright (c) 2012 Rudá Moura # Copyright © 2008-2017 Rudá Moura. All rights reserved.
# https://github.com/ruda/rpm2cpio
# #
# Impove gzip header detection thanks to
# http://afb.users.sourceforge.net/centos/rpm2cpio.py
#
# Copyright (C) 1997,1998,1999, Roger Espel Llima
# Copyright (C) 2000, Sergey Babkin
# Copyright (C) 2009, Alex Kozlov
# Copyright (C) 2010, Anders F Bjorklund
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and any associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# SOFTWARE'S COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE
'''Extract cpio archive from RPM package. '''Extract cpio archive from RPM package.
...@@ -46,57 +20,115 @@ rpm2cpio < adjtimex-1.20-2.1.i386.rpm | cpio -it ...@@ -46,57 +20,115 @@ rpm2cpio < adjtimex-1.20-2.1.i386.rpm | cpio -it
133 blocks 133 blocks
''' '''
from __future__ import print_function
import sys import sys
import struct
import StringIO
import gzip import gzip
import subprocess
from io import BytesIO
HAS_LZMA_MODULE = True
try:
import lzma
except ImportError:
try:
import backports.lzma as lzma
except ImportError:
HAS_LZMA_MODULE = False
RPM_MAGIC = '\xed\xab\xee\xdb'
GZIP_MAGIC = '\x1f\x8b' RPM_MAGIC = b'\xed\xab\xee\xdb'
GZIP_MAGIC = b'\x1f\x8b'
def rpm2cpio(stream_in=sys.stdin, stream_out=sys.stdout): XZ_MAGIC = b'\xfd7zXZ\x00'
lead = stream_in.read(96)
if lead[0:4] != RPM_MAGIC:
raise IOError, 'the input is not a RPM package' def gzip_decompress(data):
lead = stream_in.read(16) gzstream = BytesIO(data)
if not lead: gzipper = gzip.GzipFile(fileobj=gzstream)
raise IOError, 'No header'
while True:
(magic, ignore, sections, bytes) = struct.unpack("!LLLL", lead)
(smagic, smagic2) = struct.unpack("!HL", lead[0:6])
if smagic == 0x1f8b:
break
# skip the headers
stream_in.seek(16 * sections + bytes, 1)
while True:
lead = stream_in.read(1)
if lead == "":
raise IOError, 'No header'
if (0,) == struct.unpack("B", lead):
continue
break
lead += stream_in.read(15)
if lead == "":
raise IOError, 'No header'
stream_in.seek(-len(lead), 1)
gzipper = gzip.GzipFile(fileobj=stream_in)
data = gzipper.read() data = gzipper.read()
stream_out.write(data) return data
if __name__ == '__main__':
if sys.argv[1:]: def xz_decompress(data):
if HAS_LZMA_MODULE:
return lzma.decompress(data)
unxz = subprocess.Popen(['unxz'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
data = unxz.communicate(input=data)[0]
return data
def is_rpm(reader):
lead = reader.read(96)
return lead[0:4] == RPM_MAGIC
def extract_cpio(reader):
data = reader.read()
decompress = None
idx = data.find(XZ_MAGIC)
if idx != -1:
decompress = xz_decompress
pos = idx
idx = data.find(GZIP_MAGIC)
if idx != -1 and decompress is None:
decompress = gzip_decompress
pos = idx
if decompress is None:
return None
data = decompress(data[pos:])
return data
def rpm2cpio(stream_in=None, stream_out=None):
if stream_in is None:
stream_in = sys.stdin
if stream_out is None:
stream_out = sys.stdout
try:
reader = stream_in.buffer
writer = stream_out.buffer
except AttributeError:
reader = stream_in
writer = stream_out
if not is_rpm(reader):
raise IOError('the input is not a RPM package')
cpio = extract_cpio(reader)
if cpio is None:
raise IOError('could not find compressed cpio archive')
writer.write(cpio)
def main(args=None):
if args is None:
args = sys.argv
if args[1:]:
try: try:
fin = open(sys.argv[1]) fin = open(args[1])
rpm2cpio(fin) rpm2cpio(fin)
fin.close() fin.close()
except IOError, e: except IOError as e:
print 'Error:', sys.argv[1], e print('Error:', args[1], e)
sys.exit(1)
except OSError as e:
print('Error: could not find lzma extractor')
print("Please, install Python's lzma module or the xz utility")
sys.exit(1)
else: else:
try: try:
rpm2cpio() rpm2cpio()
except IOError, e: except IOError as e:
print 'Error:', e print('Error:', e)
sys.exit(1)
except OSError as e:
print('Error: could not find lzma extractor')
print("Please install Python's lzma module or the xz utility")
sys.exit(1)
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
print('Interrupted!')
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment