aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/luarocks/tools/tar.tl (renamed from src/luarocks/tools/tar.lua)61
1 files changed, 40 insertions, 21 deletions
diff --git a/src/luarocks/tools/tar.lua b/src/luarocks/tools/tar.tl
index bac7b2a9..a156bf9f 100644
--- a/src/luarocks/tools/tar.lua
+++ b/src/luarocks/tools/tar.tl
@@ -1,14 +1,35 @@
1 1
2--- A pure-Lua implementation of untar (unpacking .tar archives) 2--- A pure-Lua implementation of untar (unpacking .tar archives)
3local tar = {} 3local record tar
4 record Header
5 name: string
6 mode: string
7 uid: integer
8 gid: integer
9 size: integer
10 mtime: integer
11 chksum: integer
12 typeflag: string
13 linkname: string
14 magic: string
15 version: string
16 uname: string
17 gname: string
18 devmajor: integer
19 devminor: integer
20 prefix: string
21 end
22end
4 23
5local fs = require("luarocks.fs") 24local fs = require("luarocks.fs")
6local dir = require("luarocks.dir") 25local dir = require("luarocks.dir")
7local fun = require("luarocks.fun") 26local fun = require("luarocks.fun")
8 27
28local type Header = tar.Header
29
9local blocksize = 512 30local blocksize = 512
10 31
11local function get_typeflag(flag) 32local function get_typeflag(flag: string): string
12 if flag == "0" or flag == "\0" then return "file" 33 if flag == "0" or flag == "\0" then return "file"
13 elseif flag == "1" then return "link" 34 elseif flag == "1" then return "link"
14 elseif flag == "2" then return "symlink" -- "reserved" in POSIX, "symlink" in GNU 35 elseif flag == "2" then return "symlink" -- "reserved" in POSIX, "symlink" in GNU
@@ -25,22 +46,22 @@ local function get_typeflag(flag)
25 return "unknown" 46 return "unknown"
26end 47end
27 48
28local function octal_to_number(octal) 49local function octal_to_number(octal: string): integer
29 local exp = 0 50 local exp = 0
30 local number = 0 51 local number: integer = 0
31 octal = octal:gsub("%s", "") 52 octal = octal:gsub("%s", "")
32 for i = #octal,1,-1 do 53 for i = #octal,1,-1 do
33 local digit = tonumber(octal:sub(i,i)) 54 local digit = math.tointeger(octal:sub(i,i))
34 if not digit then 55 if not digit then
35 break 56 break
36 end 57 end
37 number = number + (digit * 8^exp) 58 number = number + (digit * math.tointeger(8^exp))
38 exp = exp + 1 59 exp = exp + 1
39 end 60 end
40 return number 61 return number
41end 62end
42 63
43local function checksum_header(block) 64local function checksum_header(block: string): number
44 local sum = 256 65 local sum = 256
45 66
46 if block:byte(1) == 0 then 67 if block:byte(1) == 0 then
@@ -59,12 +80,12 @@ local function checksum_header(block)
59 return sum 80 return sum
60end 81end
61 82
62local function nullterm(s) 83local function nullterm(s: string): string
63 return s:match("^[^%z]*") 84 return s:match("^[^%z]*")
64end 85end
65 86
66local function read_header_block(block) 87local function read_header_block(block: string): boolean | Header, string
67 local header = {} 88 local header: Header = {}
68 header.name = nullterm(block:sub(1,100)) 89 header.name = nullterm(block:sub(1,100))
69 header.mode = nullterm(block:sub(101,108)):gsub(" ", "") 90 header.mode = nullterm(block:sub(101,108)):gsub(" ", "")
70 header.uid = octal_to_number(nullterm(block:sub(109,116))) 91 header.uid = octal_to_number(nullterm(block:sub(109,116)))
@@ -96,18 +117,16 @@ local function read_header_block(block)
96 return header 117 return header
97end 118end
98 119
99function tar.untar(filename, destdir) 120function tar.untar(filename: string, destdir: string): boolean, string
100 assert(type(filename) == "string")
101 assert(type(destdir) == "string")
102 121
103 local tar_handle = io.open(filename, "rb") 122 local tar_handle = io.open(filename, "rb")
104 if not tar_handle then return nil, "Error opening file "..filename end 123 if not tar_handle then return nil, "Error opening file "..filename end
105 124
106 local long_name, long_link_name 125 local long_name, long_link_name: string, string
107 local ok, err 126 local ok, err: boolean, string
108 local make_dir = fun.memoize(fs.make_dir) 127 local make_dir = fun.memoize(fs.make_dir)
109 while true do 128 while true do
110 local block 129 local block: string
111 repeat 130 repeat
112 block = tar_handle:read(blocksize) 131 block = tar_handle:read(blocksize)
113 until (not block) or block:byte(1) > 0 132 until (not block) or block:byte(1) > 0
@@ -117,13 +136,13 @@ function tar.untar(filename, destdir)
117 break 136 break
118 end 137 end
119 138
120 local header 139 local headerp: boolean | Header
121 header, err = read_header_block(block) 140 headerp, err = read_header_block(block)
122 if not header then 141 if not headerp then
123 ok = false 142 ok = false
124 break 143 break
125 end 144 end
126 145 local header: Header = headerp as Header --! cast
127 local file_data = "" 146 local file_data = ""
128 if header.size > 0 then 147 if header.size > 0 then
129 local nread = math.ceil(header.size / blocksize) * blocksize 148 local nread = math.ceil(header.size / blocksize) * blocksize
@@ -162,7 +181,7 @@ function tar.untar(filename, destdir)
162 break 181 break
163 end 182 end
164 end 183 end
165 local file_handle 184 local file_handle: FILE
166 file_handle, err = io.open(pathname, "wb") 185 file_handle, err = io.open(pathname, "wb")
167 if not file_handle then 186 if not file_handle then
168 ok = nil 187 ok = nil