]> git.e2factory.org Git - e2factory.git/commitdiff
Rework howtounpack() and friends to fix shell quoting.
authorTobias Ulmer <tu@emlix.com>
Tue, 15 Jan 2013 15:56:51 +0000 (16:56 +0100)
committerTobias Ulmer <tu@emlix.com>
Tue, 26 Feb 2013 18:07:13 +0000 (19:07 +0100)
Signed-off-by: Tobias Ulmer <tu@emlix.com>
generic/e2lib.lua
local/files.lua

index 98b2c19c0ab346e60e62ef7b942dada979fc91a2..f2019ea8a210eb1488e3da4dc1d074525c5f3b38 100644 (file)
@@ -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
index 6881ee3cfcb95fc1f0fae939850c60b2657b0545..a2d36438d1ec62be1ad93cb2f3862c333e604152 100644 (file)
@@ -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,