return "'"..str.."'"
end
---- Determines the type of an archive.
--- Returns an empty string for tar archives, "--gzip" for
--- gzip files, "--bzip2" for bzip2 files,
--- and "zip" for zip archives.
--- @param path Path to an archive file (string).
--- @return False on error, otherwise a string as described above.
--- @return An error object on failure.
-function e2lib.tartype(path)
- local e = err.new("Could not determine archive type")
- local c
-
- local f, re = io.open(path, "r")
- if not f then
- return false, e:append(": %s", re)
- end
-
- local d = f:read(512)
- if not d then
- return false, e:append(": read error")
- end
-
- f:close()
-
- local l = string.len(d)
-
- if l > 261 and string.sub(d, 258, 262) == "ustar" then
- c = ""
- elseif l > 1 and string.sub(d, 1, 2) == "\031\139" then
- c = "--gzip"
- elseif l > 2 and string.sub(d, 1, 3) == "BZh" then
- c = "--bzip2"
- elseif l > 3 and string.sub(d, 1, 4) == "PK\003\004" then
- c = "zip"
- else
- return false, e:append(": could not determine type")
- end
-
- return c
-end
-
---- translate filename suffixes to valid tartypes for e2-su-2.2
+--- Translate filename suffixes to valid tartypes for e2-su-2.2 only.
-- @param filename string: filename
-- @return string: tartype, or nil on failure
-- @return an error object on failure
return tartype
end
---- Generates the command to unpack an archive file.
--- @param physpath Current location and filename to be unpacked later.
--- @param virtpath Location and name of the file at the time of unpacking.
--- @param destdir Path where the unpacked files shall be put.
--- @return Tool name (string), or false on error.
--- @return Argument vector table for the tool, or an error object on failure.
-function e2lib.howtounpack(physpath, virtpath, destdir)
- local tool
- local toolargv = {}
- local rc, re = e2lib.tartype(physpath)
-
- if not rc then
- return false, re
- end
-
- if rc == "zip" then
- tool = "unzip"
- table.insert(toolargv, virtpath)
- table.insert(toolargv, "-d")
- table.insert(toolargv, destdir)
- else
- tool = "tar"
- table.insert(toolargv, "-C")
- table.insert(toolargv, destdir)
- if rc ~= "" then
- table.insert(toolargv, rc)
- end
- table.insert(toolargv, "-xf")
- table.insert(toolargv, virtpath)
- end
-
- return tool, toolargv
-end
-
--- Read the first line from the given file and return it.
-- Beware that end of file is considered an error.
-- @param path Path to file (string).
return destdir, destname
end
+--- Determine archive type by looking at the file extension.
+-- @param filename File name (string).
+-- @return String constant describing archive,
+-- or false if archive suffix is unknown.
+-- @return Error object on failure.
+local function archive_by_suffix(filename)
+ local name = filename:lower() -- case insensitive matching
+ local atype
+
+ if name:match("%.tar$") then
+ atype = "TAR"
+ elseif name:match("%.tgz") or name:match("%.tar%.gz$") then
+ atype = "TAR_GZ"
+ elseif name:match("%.tar%.bz2$") then
+ atype = "TAR_BZIP2"
+ elseif name:match("%.tar%.xz$") then
+ atype = "TAR_XZ"
+ elseif name:match("%.zip$") then
+ atype = "ZIP"
+ else
+ return false, err.new("can not determine archive type of '%s'",
+ filename)
+ end
+
+ return atype
+end
+
+--- Generates the command to unpack an archive file.
+-- @param physpath Current location and filename to be unpacked later.
+-- @param virtpath Location and name of the file at the time of unpacking.
+-- @param destdir Path where the unpacked files shall be put.
+-- @return Tool name (string), or false on error.
+-- @return Argument vector table for the tool, or an error object on failure.
+local function gen_unpack_command(physpath, virtpath, destdir)
+ local tool
+ local toolargv = {}
+
+ local atype, re = archive_by_suffix(physpath)
+ if not atype then
+ return false, re
+ end
+
+ if atype == "ZIP" then
+ tool = "unzip"
+ table.insert(toolargv, virtpath)
+ table.insert(toolargv, "-d")
+ table.insert(toolargv, destdir)
+ elseif atype == "TAR" then
+ tool = "tar"
+ table.insert(toolargv, "-C")
+ table.insert(toolargv, destdir)
+ table.insert(toolargv, "-xf")
+ table.insert(toolargv, virtpath)
+ elseif atype == "TAR_GZ" then
+ tool = "tar"
+ table.insert(toolargv, "-z")
+ table.insert(toolargv, "-C")
+ table.insert(toolargv, destdir)
+ table.insert(toolargv, "-xf")
+ table.insert(toolargv, virtpath)
+ elseif atype == "TAR_BZIP2" then
+ tool = "tar"
+ table.insert(toolargv, "-j")
+ table.insert(toolargv, "-C")
+ table.insert(toolargv, destdir)
+ table.insert(toolargv, "-xf")
+ table.insert(toolargv, virtpath)
+ elseif atype == "TAR_XZ" then
+ tool = "tar"
+ table.insert(toolargv, "--xz")
+ table.insert(toolargv, "-C")
+ table.insert(toolargv, destdir)
+ table.insert(toolargv, "-xf")
+ table.insert(toolargv, virtpath)
+ else
+ return false, err.new("unhandled archive type")
+ end
+
+ return tool, toolargv
+end
+
--- Prepare a files source.
-- @param info The info table.
-- @param sourcename The source name (string)
return false, e:cat(re)
end
- local rc, re = e2lib.howtounpack(path, path, buildpath)
+ local rc, re = gen_unpack_command(path, path, buildpath)
if not rc then
return false, e:cat(re)
end
if file.unpack then
local physpath = e2lib.join(destdir, e2lib.basename(file.location))
local virtpath = e2lib.join(source, e2lib.basename(file.location))
- local rc, re = e2lib.howtounpack(physpath, virtpath, "$(BUILD)")
+ local rc, re = gen_unpack_command(physpath, virtpath, "$(BUILD)")
if not rc then
e:cat("unable to generate unpack command")
return false, e:cat(re)