-- -- rpmlua -- OpenPKG RPM Lua Script -- Copyright (c) 2000-2012 OpenPKG GmbH -- -- This software is property of the OpenPKG GmbH, DE MUC HRB 160208. -- All rights reserved. Licenses which grant limited permission to use, -- copy, modify and distribute this software are available from the -- OpenPKG GmbH. -- -- THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -- WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -- IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR -- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -- USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -- SUCH DAMAGE. -- -- -- The purpose of this Lua script is to extend the default Lua functions -- in the OpenPKG RPM installation for the @l_prefix@ hierarchy. -- -- provide namespace openpkg = {} -- small wrapper around the realpath(3) call provided by RPM function openpkg.realpath(path) if posix.stat(path) ~= nil then -- path exists, so resolve as a whole path = rpm.realpath(path) else -- path not exists, so recursively resolve only prefix local s, _, m = util.rmatch(path, "^(.+?)/([^/]+)/?$") if s ~= nil then local prefix = openpkg.realpath(m[1]) if util.rmatch(prefix, "/$") == nil then prefix = prefix .. "/" end path = prefix .. m[2] end end return path end -- try to reduce real path to symbolic one (if posssible) function openpkg.unrealpath(path, prefix_unreal) local prefix_real = openpkg.realpath(prefix_unreal) if prefix_real ~= prefix_unreal then if string.sub(path, 1, string.len(prefix_real)) == prefix_real then path = prefix_unreal .. string.sub(path, string.len(prefix_real)+1) end end return path end -- canonicalize filesystem path as good as possible function openpkg.canonicalize(path) path = openpkg.unrealpath(path, os.getenv("PWD")) path = openpkg.unrealpath(path, rpm.expand("%{l_prefix}")) return path end -- temporary directory determination function openpkg.tmpdir() local tmpdir = os.getenv("TMPDIR") if tmpdir ~= nil then tmpdir = openpkg.canonicalize(openpkg.realpath(tmpdir)) else tmpdir = "/tmp" end tmpdir = tmpdir .. "/openpkg" return tmpdir end -- layout determination: RPM Lua based implementation function openpkg.layout(args) local dir = "" -- parse arguments local arg = { variable = "", layout = "", macrosfile = "", basedir = "", shared = "no", debug = "no", specdir = "", sourcedir = "", builddir = "", tmppath = "", rpmdir = "", srcrpmdir = "" } local arg_map_fwd = { binrpmdir = "rpmdir", tmpdir = "tmppath" } local arg_map_rev = { rpmdir = "binrpmdir", tmppath = "tmpdir" } if rpm.debug() then arg.debug = "yes" end util.rsubst(args, "(?s)\\s*([a-z_][a-zA-Z0-9_-]*)=(?:\"((?:\\\\.|[^\"])*)\"|(\\S*))", function (key, _, value1, value2) if arg_map_fwd[key] ~= nil then key = arg_map_fwd[key] end if arg[key] == nil then io.stderr:write("rpm: invalid parameter \"" .. key .. "\" on call to \"openpkg.layout()\"\n") else if value1 ~= nil then arg[key] = value1 else arg[key] = value2 end end return false end ) if arg.variable == "" then io.stderr:write("rpm: missing \"variable\" parameter on call to \"openpkg.layout()\"\n") return "" end if arg.layout == "" then io.stderr:write("rpm: missing \"layout\" parameter on call to \"openpkg.layout()\"\n") return "" end if arg.macrosfile == "" and arg.basedir == "" then io.stderr:write("rpm: missing \"macrosfile\" or \"basedir\" parameter on call to \"openpkg.layout()\"\n") return "" end -- determine base directory if arg.basedir == "" then if util.rmatch(arg.macrosfile, "^.*/\.openpkg/rpmmacros$") ~= nil then arg.basedir = openpkg.canonicalize(openpkg.realpath( util.rsubst( openpkg.realpath(arg.macrosfile), "/[^/]+$", "/.." ) )) else arg.basedir = rpm.expand("%{l_prefix}") end end -- temporarily define "__openpkg_basedir" macro rpm.define("__openpkg_basedir " .. arg.basedir) -- temporarily define "__openpkg_shared" macro if arg.shared == "yes" then rpm.define("__openpkg_shared yes") end -- determine layout directory list local list = "" if arg[arg.variable] ~= nil and arg[arg.variable] ~= "" then list = arg[arg.variable] else list = rpm.expand( "%{?__openpkg_layout_" .. arg.layout .. "_" .. arg.variable .. "}" .. "%{!?__openpkg_layout_" .. arg.layout .. "_" .. arg.variable .. ":" .. "%{__openpkg_layout_global_" .. arg.variable .. "}}" ) end -- remove temporarily defined "__openpkg_basedir" macro rpm.undefine("__openpkg_basedir") -- remove temporarily defined "__openpkg_shared" macro if arg.shared == "yes" then rpm.undefine("__openpkg_shared") end -- iterate over all directory specifications local dirs = util.rsplit(list, "(?s)\\s+") local k = table.maxn(dirs) for i, _ in ipairs(dirs) do -- parse specification into path to check and optionally path to make local path_check = dirs[i] local path_append = false local path_make = path_check local s, _, m = util.rmatch(path_check, "^(.+):(\\+?)(.*)$") if s ~= nil then path_check = m[1] path_append = (m[2] == "+") path_make = m[3] end -- check whether path should be taken (last path is always taken) if posix.stat(path_check) ~= nil or i == k then if path_append then -- special case: simply append a suffix dir = path_check .. path_make else -- regular case: use full path to make dir = path_make end break end end if dir ~= "" then -- make sure path really exists and resolve to absolute path if posix.stat(dir) == nil then io.stderr:write("rpm: creating \"" .. arg.variable .. "\" directory \"" .. dir .. "\"\n") if posix.mkdir(dir) ~= 0 then io.stderr:write("rpm: failed to create directory \"" .. dir .. "\"\n") end end dir = openpkg.canonicalize(openpkg.realpath(dir)) end -- debugging if arg.debug == "yes" then local variable = arg.variable if arg_map_rev[variable] ~= nil then variable = arg_map_rev[variable] end io.stderr:write(string.format("rpm: openpkg: layout: [%s] %s = \"%s\"\n", arg.layout, variable, dir)) end -- provide result directory return dir end