aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHisham Muhammad <hisham@gobolinux.org>2018-07-13 22:53:43 -0300
committerHisham Muhammad <hisham@gobolinux.org>2018-07-18 11:24:07 -0300
commitb2ac4f3a9b780f6bde413dc1b5463654bb8be8d7 (patch)
treee09137afe8a7670adec497adcae39266644a3566
parentd93459dcf4250dd025a1baa802a6243516b7395d (diff)
downloadluarocks-b2ac4f3a9b780f6bde413dc1b5463654bb8be8d7.tar.gz
luarocks-b2ac4f3a9b780f6bde413dc1b5463654bb8be8d7.tar.bz2
luarocks-b2ac4f3a9b780f6bde413dc1b5463654bb8be8d7.zip
tar: compatibility improvement tweaks
-rw-r--r--src/luarocks/tools/tar.lua69
1 files changed, 45 insertions, 24 deletions
diff --git a/src/luarocks/tools/tar.lua b/src/luarocks/tools/tar.lua
index 9ff8d04a..7828c517 100644
--- a/src/luarocks/tools/tar.lua
+++ b/src/luarocks/tools/tar.lua
@@ -28,12 +28,14 @@ end
28local function octal_to_number(octal) 28local function octal_to_number(octal)
29 local exp = 0 29 local exp = 0
30 local number = 0 30 local number = 0
31 octal = octal:gsub("%s", "")
31 for i = #octal,1,-1 do 32 for i = #octal,1,-1 do
32 local digit = tonumber(octal:sub(i,i)) 33 local digit = tonumber(octal:sub(i,i))
33 if digit then 34 if not digit then
34 number = number + (digit * 8^exp) 35 break
35 exp = exp + 1
36 end 36 end
37 number = number + (digit * 8^exp)
38 exp = exp + 1
37 end 39 end
38 return number 40 return number
39end 41end
@@ -41,10 +43,12 @@ end
41local function checksum_header(block) 43local function checksum_header(block)
42 local sum = 256 44 local sum = 256
43 for i = 1,148 do 45 for i = 1,148 do
44 sum = sum + block:byte(i) 46 local b = block:byte(i) or 0
47 sum = sum + b
45 end 48 end
46 for i = 157,500 do 49 for i = 157,500 do
47 sum = sum + block:byte(i) 50 local b = block:byte(i) or 0
51 sum = sum + b
48 end 52 end
49 return sum 53 return sum
50end 54end
@@ -71,12 +75,12 @@ local function read_header_block(block)
71 header.devmajor = octal_to_number(nullterm(block:sub(330,337))) 75 header.devmajor = octal_to_number(nullterm(block:sub(330,337)))
72 header.devminor = octal_to_number(nullterm(block:sub(338,345))) 76 header.devminor = octal_to_number(nullterm(block:sub(338,345)))
73 header.prefix = block:sub(346,500) 77 header.prefix = block:sub(346,500)
74 if header.magic ~= "ustar " and header.magic ~= "ustar\0" then 78 -- if header.magic ~= "ustar " and header.magic ~= "ustar\0" then
75 return false, "Invalid header magic "..header.magic 79 -- return false, ("Invalid header magic %6x"):format(bestring_to_number(header.magic))
76 end 80 -- end
77 if header.version ~= "00" and header.version ~= " \0" then 81 -- if header.version ~= "00" and header.version ~= " \0" then
78 return false, "Unknown version "..header.version 82 -- return false, "Unknown version "..header.version
79 end 83 -- end
80 if not checksum_header(block) == header.chksum then 84 if not checksum_header(block) == header.chksum then
81 return false, "Failed header checksum" 85 return false, "Failed header checksum"
82 end 86 end
@@ -87,20 +91,26 @@ function tar.untar(filename, destdir)
87 assert(type(filename) == "string") 91 assert(type(filename) == "string")
88 assert(type(destdir) == "string") 92 assert(type(destdir) == "string")
89 93
90 local tar_handle = io.open(filename, "r") 94 local tar_handle = io.open(filename, "rb")
91 if not tar_handle then return nil, "Error opening file "..filename end 95 if not tar_handle then return nil, "Error opening file "..filename end
92 96
93 local long_name, long_link_name 97 local long_name, long_link_name
98 local ok, err
94 while true do 99 while true do
95 local block 100 local block
96 repeat 101 repeat
97 block = tar_handle:read(blocksize) 102 block = tar_handle:read(blocksize)
98 until (not block) or checksum_header(block) > 256 103 until (not block) or checksum_header(block) > 256
99 if not block then break end 104 if not block then break end
100 local header, err = read_header_block(block) 105 if #block < blocksize then
106 ok, err = nil, "Invalid block size -- corrupted file?"
107 break
108 end
109 local header
110 header, err = read_header_block(block)
101 if not header then 111 if not header then
102 util.printerr(err) 112 ok = false
103 return nil, err 113 break
104 end 114 end
105 115
106 local file_data = tar_handle:read(math.ceil(header.size / blocksize) * blocksize):sub(1,header.size) 116 local file_data = tar_handle:read(math.ceil(header.size / blocksize) * blocksize):sub(1,header.size)
@@ -120,22 +130,33 @@ function tar.untar(filename, destdir)
120 end 130 end
121 end 131 end
122 local pathname = dir.path(destdir, header.name) 132 local pathname = dir.path(destdir, header.name)
133 pathname = fs.absolute_name(pathname)
123 if header.typeflag == "directory" then 134 if header.typeflag == "directory" then
124 local ok, err = fs.make_dir(pathname) 135 ok, err = fs.make_dir(pathname)
125 if not ok then return nil, err end 136 if not ok then
137 break
138 end
126 elseif header.typeflag == "file" then 139 elseif header.typeflag == "file" then
127 local dirname = dir.dir_name(pathname) 140 local dirname = dir.dir_name(pathname)
128 if dirname ~= "" then 141 if dirname ~= "" then
129 local ok, err = fs.make_dir(dirname) 142 ok, err = fs.make_dir(dirname)
130 if not ok then return nil, err end 143 if not ok then
144 break
145 end
146 end
147 local file_handle
148 file_handle, err = io.open(pathname, "wb")
149 if not file_handle then
150 ok = nil
151 break
131 end 152 end
132 local file_handle = io.open(pathname, "wb")
133 file_handle:write(file_data) 153 file_handle:write(file_data)
134 file_handle:close() 154 file_handle:close()
135 fs.set_time(pathname, header.mtime) 155 fs.set_time(pathname, header.mtime)
136 -- TODO Use fs.set_permissions 156 if header.mode:match("[75]") then
137 if fs.chmod then 157 fs.set_permissions(pathname, "exec", "all")
138 fs.chmod(pathname, header.mode) 158 else
159 fs.set_permissions(pathname, "read", "all")
139 end 160 end
140 end 161 end
141 --[[ 162 --[[
@@ -146,7 +167,7 @@ function tar.untar(filename, destdir)
146 --]] 167 --]]
147 end 168 end
148 tar_handle:close() 169 tar_handle:close()
149 return true 170 return ok, err
150end 171end
151 172
152return tar 173return tar