Till Wegmüller
2024-04-07 32d55185c6e52012a7f3fbcd5ff32dbce22c3104
commit | author | age
de89cf 1 #!/usr/bin/python3.9
9c75c0 2 #
NJ 3 # CDDL HEADER START
4 #
5 # The contents of this file are subject to the terms of the
6 # Common Development and Distribution License (the "License").
7 # You may not use this file except in compliance with the License.
8 #
9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 # or http://www.opensolaris.org/os/licensing.
11 # See the License for the specific language governing permissions
12 # and limitations under the License.
13 #
14 # When distributing Covered Code, include this CDDL HEADER in each
15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 # If applicable, add the following below this CDDL HEADER, with the
17 # fields enclosed by brackets "[]" replaced with your own identifying
18 # information: Portions Copyright [yyyy] [name of copyright owner]
19 #
20 # CDDL HEADER END
21 #
22 # Copyright (c) 2010, Oracle and/or it's affiliates.  All rights reserved.
681a42 23 # Copyright (c) 2018-2019, Michal Nowak
9c75c0 24 #
NJ 25 #
26 # unpack.py - an archive unpack utility
27 #
28 #  A simple program to uncompress and unpack source archive files into a target
29 #  directory and fix permissions if requested.
30 #
31
32 import os
33 import sys
34
35 def uncompress_unpack_commands(filename, verbose=False):
36     import re
37
38     uncompress = "/bin/cat"
39
40     if (re.search("(\.bz2|\.tbz|\.tbz2)$", filename) != None):
41         uncompress = "/usr/bin/bzip2 -dc"
42     elif (re.search("(\.gz|\.tgz)$", filename) != None):
43         uncompress = "/usr/bin/gzip -dc"
44     elif (re.search("(\.Z)$", filename) != None):
45         uncompress = "/usr/bin/uncompress -c"
46     elif (re.search("(\.7z)$", filename) != None):
2759f2 47         uncompress = "/usr/bin/7z x"
b1b371 48     elif (re.search("(\.lz)$", filename) != None):
MN 49         uncompress = "/usr/bin/lzip -dc"
8ae331 50     elif (re.search("(\.xz)$", filename) != None):
RB 51         uncompress = "/usr/bin/xz -dc"
9c75c0 52     elif (re.search("(\.zip)$", filename) != None):
NJ 53         uncompress = "/usr/bin/unzip -qo"
db3be8 54     elif (re.search("(\.oxt)$", filename) != None):
AP 55         uncompress = "/usr/bin/unzip -qo"
681a42 56     elif (re.search("(\.zst|\.tzst)$", filename) != None):
MN 57         uncompress = "/usr/bin/unzstd -c"
18b823 58     elif (re.search("(\.gem)$", filename) != None):
1e5ead 59         ruby_ver = os.getenv('RUBY_VERSION', '')
AP 60         uncompress = "/usr/ruby/" + ruby_ver + "/bin/gem unpack"
9c75c0 61
200706 62     # if the file is just compressed, redirect stdout to ./filename with
D 63     # one less extension.
64     unpack = " > ./" + '.'.join(os.path.basename(filename).split('.')[:-1])
9c75c0 65
200706 66     if (re.search("(\.tar\.[^\.]+|\.tgz|\.txz|\.tbz2?)$",filename) != None):
D 67         unpack = " | gtar -xf -"
68     elif (re.search("(\.zip)$", filename) != None):
9c75c0 69         unpack = ""
db3be8 70     elif (re.search("(\.oxt)$", filename) != None):
AP 71         unpack = ""
9c75c0 72     elif (re.search("(\.jar)$", filename) != None):
NJ 73         unpack = " | jar xf -"
18b823 74     elif (re.search("(\.gem)$", filename) != None):
AP 75         unpack = ""
9c75c0 76
NJ 77     if (verbose == True):
200706 78         print("command: %s %s%s" % (uncompress, filename, unpack))
9c75c0 79
NJ 80     return uncompress, unpack
81
82 #
83 # recurse down a directory tree opening permissions so that others may access
84 # files in the tree.
85 #
86 def fixup_permissions(dir, verbose):
87     for entry in os.listdir(dir):
88         import stat
89
90         path = "%s/%s" % (dir, entry)
91
92         st = os.lstat(path)
93         mode = stat.S_IMODE(st.st_mode)
94         mode |= (stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
95         if stat.S_ISDIR(st.st_mode):
96             mode |= (stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
97
98         if (stat.S_IMODE(st.st_mode) != mode):
99             if (verbose == True):
fb10ba 100                 print("Changing %s from %4.4o to %4.4o" % (path,
AP 101                         stat.S_IMODE(st.st_mode), mode))
9c75c0 102             os.chmod(path, mode)
NJ 103
104         if stat.S_ISDIR(st.st_mode):
105             fixup_permissions(path, verbose)
106
107
108 def usage():
fb10ba 109     print("Usage: %s [-v|--verbose] [-f|--fix-permissions] [-r|--relocate-to (dir)] (file)" % (sys.argv[0].split('/')[-1]))
9c75c0 110     sys.exit(1)
NJ 111
112 def main():
113     import getopt
114     import sys
115     import tempfile
116
117     verbose = False
118     permissions = None
119     relocate_to = None
fab151 120
200706 121     if len(sys.argv) == 1:
D 122         usage()
123
9c75c0 124     try:
NJ 125         opts, args = getopt.getopt(sys.argv[1:], "fr:v",
126             ["fix-permissions", "relocate-to=", "verbose"])
fb10ba 127     except getopt.GetoptError as err:
AP 128         print(str(err))
9c75c0 129         usage()
NJ 130
131     for opt, arg in opts:
132         if opt in [ "-v", "--verbose" ]:
133             verbose = True
134         elif opt in [ "-f", "--fix-permissions" ]:
135             permissions = True
136         elif opt in [ "-r", "--relocate-to" ]:
137             relocate_to = arg
138         else:
139             assert False, "unknown option"
140
e18339 141     filename = ((args[0][0] == '/') and "%s" or "../%s") % args[0]
9c75c0 142     uncompress, unpack = uncompress_unpack_commands(filename)
NJ 143     tempdir = tempfile.mkdtemp(dir='.')
144
145     # extract the archive contents
146     if (verbose == True):    
fb10ba 147         print("cd %s ; %s %s%s" % (tempdir, uncompress, filename,
AP 148                         unpack))
9c75c0 149     os.system("cd %s ; %s %s%s" % (tempdir, uncompress, filename, unpack))
NJ 150
151     # open up the permissions on what we extracted
152     if permissions:
153         fixup_permissions(tempdir, verbose)
154
155     if (relocate_to == None):
156         # move everything in the tempdir here
157         for entry in os.listdir(tempdir):
158             path= "%s/%s" % (tempdir, entry)
159             os.renames(path, entry)
160     else:
161         # rename the tempdir and open it's permissions
162         os.renames(tempdir, relocate_to)
fb10ba 163         os.chmod(relocate_to, 0o755)
9c75c0 164
NJ 165
166 if __name__ == "__main__":
167     main()