From: Tobias Ulmer Date: Tue, 15 Jan 2013 15:56:51 +0000 (+0100) Subject: Rework howtounpack() and friends to fix shell quoting. X-Git-Tag: e2factory-2.3.13rc1~55 X-Git-Url: https://git.e2factory.org/?a=commitdiff_plain;h=58cf8b67657bccfd54539a48e3887e2ed1946c08;p=e2factory.git Rework howtounpack() and friends to fix shell quoting. Signed-off-by: Tobias Ulmer --- diff --git a/generic/e2lib.lua b/generic/e2lib.lua index 98b2c19..f2019ea 100644 --- a/generic/e2lib.lua +++ b/generic/e2lib.lua @@ -660,23 +660,43 @@ function e2lib.shquote(str) return "'"..str.."'" end --- determines the type of an archive --- say "z" for gzip, "j" for bzip2, "" for tar archive --- nil is returned for unknown data +--- 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 f, e = io.open(path, "r") + local e = err.new("Could not determine archive type") + local c + + local f, re = io.open(path, "r") if not f then - e2lib.abort(e) + return false, e:append(": %s", re) + end + + local d = f:read(512) + if not d then + return false, e:append(": read error") end - local d = f and f:read(512) - local l = d and string.len(d) or 0 - local c = nil + f:close() - 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" + + 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 @@ -699,19 +719,38 @@ function e2lib.tartype_by_suffix(filename) return tartype end --- generates a command to unpack an archive file --- physpath is the current location and filename to be unpacked later --- virtpath is the location and name of the file at the time of unpacking --- destdir is the path to where the unpacked files shall be put --- return unix command on success, nil otherwise +--- 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 c = e2lib.tartype(physpath) - if c == "zip" then - c = "unzip \"" .. virtpath .. "\" -d \"" .. destdir .. "\"" - elseif c then - c = string.format("tar -C '%s' %s -xf '%s'", destdir, c, virtpath) + local tool + local toolargv = {} + local rc, re = e2lib.tartype(physpath) + + if not rc then + return false, re end - return c + + 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 -- Input/Output operations diff --git a/local/files.lua b/local/files.lua index 6881ee3..a2d3643 100644 --- a/local/files.lua +++ b/local/files.lua @@ -35,6 +35,7 @@ local err = require("err") local e2lib = require("e2lib") local e2tool = require("e2tool") local strict = require("strict") +local tools = require("tools") plugin_descriptor = { description = "Files SCM Plugin", @@ -268,10 +269,19 @@ function files.prepare_source(info, sourcename, sourceset, buildpath) if not path then return false, e:cat(re) end - local y = e2lib.howtounpack(path, path, buildpath) - if not y or e2lib.callcmd_capture(y) ~= 0 then - return false, e:append("failed to unpack: %s", path) + + local rc, re = e2lib.howtounpack(path, path, buildpath) + if not rc then + return false, e:cat(re) + end + + local tool, toolargv = rc, re + rc, re = e2lib.call_tool_argv(tool, toolargv) + if not rc then + e:cat(err.new("unpacking archive '%s' failed", path)) + return false, e:cat(re) end + if not symlink then symlink = buildpath .. "/" .. sourcename if file.unpack ~= sourcename then @@ -463,18 +473,23 @@ function files.toresult(info, sourcename, sourceset, directory) e2lib.basename(checksum_file))) end if file.unpack then - local c = e2lib.howtounpack( - string.format("%s/%s", destdir, - e2lib.basename(file.location)), - string.format("%s/%s", source, - e2lib.basename(file.location)), - string.format("$(BUILD)")) - if not c then - return false, e:cat("%s:%s: ".. - "can't generate command to unpack", - file.server, file.location) + 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)") + if not rc then + e:cat("unable to generate unpack command") + return false, e:cat(re) end - f:write(string.format("\t%s\n", c)) + + local tool, toolargv = rc, re + local toolname = tools.get_tool_name(tool) + + f:write(string.format("\t%s", toolname)) + for _,v in ipairs(toolargv) do + f:write(string.format(" %s", e2lib.shquote(v))) + end + f:write("\n") + if file.unpack ~= sourcename then f:write(string.format( "\tln -s %s $(BUILD)/%s\n", file.unpack,