Add support for InstallShield archives. trunk

Sun, 13 Jul 2008 17:47:57 -0400

author
Brett Smith <brettcsmith@brettcsmith.org>
date
Sun, 13 Jul 2008 17:47:57 -0400
branch
trunk
changeset 72
c4cfaf634bb9
parent 71
b0290eeb3b7a
child 73
a4fff3df2242

Add support for InstallShield archives.

INSTALL file | annotate | diff | comparison | revisions
TODO file | annotate | diff | comparison | revisions
scripts/dtrx file | annotate | diff | comparison | revisions
--- a/INSTALL	Thu Jul 10 20:55:09 2008 -0400
+++ b/INSTALL	Sun Jul 13 17:47:57 2008 -0400
@@ -39,6 +39,9 @@
 Microsoft Cabinet archives
   cabextract
 
+InstallShield archives
+  unshield
+
 Files compressed with gzip or compress
   zcat
 
--- a/TODO	Thu Jul 10 20:55:09 2008 -0400
+++ b/TODO	Sun Jul 13 17:47:57 2008 -0400
@@ -9,8 +9,6 @@
   itself is an archive.  Follow all the usual rules for recursive
   extraction when we do this.
 
-* Support InstallShield extraction with Unshield.
-
 * --expert mode: prompts don't show an explanation of what the options are,
   unless you ask with ?.
 
--- a/scripts/dtrx	Thu Jul 10 20:55:09 2008 -0400
+++ b/scripts/dtrx	Sun Jul 13 17:47:57 2008 -0400
@@ -16,6 +16,8 @@
 # You should have received a copy of the GNU General Public License along
 # with this program; if not, see <http://www.gnu.org/licenses/>.
 
+# Python 2.3 string methods: 'rfind', 'rindex', 'rjust', 'rstrip'
+
 import errno
 import glob
 import logging
@@ -494,6 +496,35 @@
         self.run_pipes()
 
 
+class ShieldExtractor(NoPipeExtractor):
+    file_type = 'InstallShield archive'
+    prefix_re = re.compile(r'^\s+\d+\s+')
+    end_re = re.compile(r'^\s+-+\s+-+\s*$')
+
+    def get_filenames(self):
+        self.pipe(['unshield', 'l', self.filename], "listing")
+        self.run_pipes()
+        self.archive.seek(0, 0)
+        for line in self.archive:
+            if self.end_re.match(line):
+                break
+            else:
+                match = self.prefix_re.match(line)
+                if match:
+                    yield line[match.end():].rstrip('\n')
+        self.archive.close()
+
+    def extract_archive(self):
+        self.pipe(['unshield', 'x', self.filename])
+        self.run_pipes()
+
+    def basename(self):
+        result = NoPipeExtractor.basename(self)
+        if result.endswith('.hdr'):
+            result = result[:-4]
+        return result
+
+
 class BaseHandler(object):
     def __init__(self, extractor, options):
         self.extractor = extractor
@@ -717,7 +748,8 @@
                      'gem': (GemExtractor, GemMetadataExtractor),
                      'compress': (CompressionExtractor, None),
                      '7z': (SevenExtractor, None),
-                     'cab': (CABExtractor, None)}
+                     'cab': (CABExtractor, None),
+                     'shield': (ShieldExtractor, None)}
 
     mimetype_map = {}
     for mapping in (('tar', 'x-tar'),
@@ -727,7 +759,8 @@
                     ('cpio', 'x-cpio'),
                     ('gem', 'x-ruby-gem'),
                     ('7z', 'x-7z-compressed'),
-                    ('cab', 'x-cab')):
+                    ('cab', 'x-cab'),
+                    ('shield', 'x-cab')):
         for mimetype in mapping[1:]:
             if '/' not in mimetype:
                 mimetype = 'application/' + mimetype
@@ -740,7 +773,8 @@
                     ('zip', '(Zip|ZIP self-extracting) archive'),
                     ('rpm', 'RPM'),
                     ('7z', '7-zip archive'),
-                    ('cab', 'Microsoft Cabinet archive')):
+                    ('cab', 'Microsoft Cabinet archive'),
+                    ('shield', 'InstallShield CAB')):
         for pattern in mapping[1:]:
             magic_mime_map[re.compile(pattern)] = mapping[0]
     
@@ -763,7 +797,8 @@
                     ('compress', 'bzip2', 'bz2'),
                     ('compress', 'lzma', 'lzma'),
                     ('7z', None, '7z'),
-                    ('cab', None, 'cab', 'exe')):
+                    ('cab', None, 'cab', 'exe'),
+                    ('shield', None, 'cab', 'hdr')):
         for extension in mapping[2:]:
             extension_map.setdefault(extension, []).append(mapping[:2])
 

mercurial