diff options
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) |
3 | local tar = {} | 3 | local 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 | ||
22 | end | ||
4 | 23 | ||
5 | local fs = require("luarocks.fs") | 24 | local fs = require("luarocks.fs") |
6 | local dir = require("luarocks.dir") | 25 | local dir = require("luarocks.dir") |
7 | local fun = require("luarocks.fun") | 26 | local fun = require("luarocks.fun") |
8 | 27 | ||
28 | local type Header = tar.Header | ||
29 | |||
9 | local blocksize = 512 | 30 | local blocksize = 512 |
10 | 31 | ||
11 | local function get_typeflag(flag) | 32 | local 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" |
26 | end | 47 | end |
27 | 48 | ||
28 | local function octal_to_number(octal) | 49 | local 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 |
41 | end | 62 | end |
42 | 63 | ||
43 | local function checksum_header(block) | 64 | local 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 |
60 | end | 81 | end |
61 | 82 | ||
62 | local function nullterm(s) | 83 | local function nullterm(s: string): string |
63 | return s:match("^[^%z]*") | 84 | return s:match("^[^%z]*") |
64 | end | 85 | end |
65 | 86 | ||
66 | local function read_header_block(block) | 87 | local 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 |
97 | end | 118 | end |
98 | 119 | ||
99 | function tar.untar(filename, destdir) | 120 | function 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 |