openpkg/rpmlua

Mon, 28 Jan 2013 17:37:18 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Mon, 28 Jan 2013 17:37:18 +0100
changeset 758
a2c6460cfb16
permissions
-rw-r--r--

Correct socket error reporting improvement with IPv6 portable code,
after helpful recommendation by Saúl Ibarra Corretgé on OSips devlist.

michael@428 1 --
michael@428 2 -- rpmlua -- OpenPKG RPM Lua Script
michael@428 3 -- Copyright (c) 2000-2012 OpenPKG GmbH <http://openpkg.com/>
michael@428 4 --
michael@428 5 -- This software is property of the OpenPKG GmbH, DE MUC HRB 160208.
michael@428 6 -- All rights reserved. Licenses which grant limited permission to use,
michael@428 7 -- copy, modify and distribute this software are available from the
michael@428 8 -- OpenPKG GmbH.
michael@428 9 --
michael@428 10 -- THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
michael@428 11 -- WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
michael@428 12 -- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
michael@428 13 -- IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
michael@428 14 -- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
michael@428 15 -- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
michael@428 16 -- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
michael@428 17 -- USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
michael@428 18 -- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
michael@428 19 -- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
michael@428 20 -- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
michael@428 21 -- SUCH DAMAGE.
michael@428 22 --
michael@428 23
michael@428 24 --
michael@428 25 -- The purpose of this Lua script is to extend the default Lua functions
michael@428 26 -- in the OpenPKG RPM installation for the @l_prefix@ hierarchy.
michael@428 27 --
michael@428 28
michael@428 29 -- provide namespace
michael@428 30 openpkg = {}
michael@428 31
michael@428 32 -- small wrapper around the realpath(3) call provided by RPM
michael@428 33 function openpkg.realpath(path)
michael@428 34 if posix.stat(path) ~= nil then
michael@428 35 -- path exists, so resolve as a whole
michael@428 36 path = rpm.realpath(path)
michael@428 37 else
michael@428 38 -- path not exists, so recursively resolve only prefix
michael@428 39 local s, _, m = util.rmatch(path, "^(.+?)/([^/]+)/?$")
michael@428 40 if s ~= nil then
michael@428 41 local prefix = openpkg.realpath(m[1])
michael@428 42 if util.rmatch(prefix, "/$") == nil then
michael@428 43 prefix = prefix .. "/"
michael@428 44 end
michael@428 45 path = prefix .. m[2]
michael@428 46 end
michael@428 47 end
michael@428 48 return path
michael@428 49 end
michael@428 50
michael@428 51 -- try to reduce real path to symbolic one (if posssible)
michael@428 52 function openpkg.unrealpath(path, prefix_unreal)
michael@428 53 local prefix_real = openpkg.realpath(prefix_unreal)
michael@428 54 if prefix_real ~= prefix_unreal then
michael@428 55 if string.sub(path, 1, string.len(prefix_real)) == prefix_real then
michael@428 56 path = prefix_unreal .. string.sub(path, string.len(prefix_real)+1)
michael@428 57 end
michael@428 58 end
michael@428 59 return path
michael@428 60 end
michael@428 61
michael@428 62 -- canonicalize filesystem path as good as possible
michael@428 63 function openpkg.canonicalize(path)
michael@428 64 path = openpkg.unrealpath(path, os.getenv("PWD"))
michael@428 65 path = openpkg.unrealpath(path, rpm.expand("%{l_prefix}"))
michael@428 66 return path
michael@428 67 end
michael@428 68
michael@428 69 -- temporary directory determination
michael@428 70 function openpkg.tmpdir()
michael@428 71 local tmpdir = os.getenv("TMPDIR")
michael@428 72 if tmpdir ~= nil then
michael@428 73 tmpdir = openpkg.canonicalize(openpkg.realpath(tmpdir))
michael@428 74 else
michael@428 75 tmpdir = "/tmp"
michael@428 76 end
michael@428 77 tmpdir = tmpdir .. "/openpkg"
michael@428 78 return tmpdir
michael@428 79 end
michael@428 80
michael@428 81 -- layout determination: RPM Lua based implementation
michael@428 82 function openpkg.layout(args)
michael@428 83 local dir = ""
michael@428 84
michael@428 85 -- parse arguments
michael@428 86 local arg = {
michael@428 87 variable = "",
michael@428 88 layout = "",
michael@428 89 macrosfile = "",
michael@428 90 basedir = "",
michael@428 91 shared = "no",
michael@428 92 debug = "no",
michael@428 93 specdir = "",
michael@428 94 sourcedir = "",
michael@428 95 builddir = "",
michael@428 96 tmppath = "",
michael@428 97 rpmdir = "",
michael@428 98 srcrpmdir = ""
michael@428 99 }
michael@428 100 local arg_map_fwd = {
michael@428 101 binrpmdir = "rpmdir",
michael@428 102 tmpdir = "tmppath"
michael@428 103 }
michael@428 104 local arg_map_rev = {
michael@428 105 rpmdir = "binrpmdir",
michael@428 106 tmppath = "tmpdir"
michael@428 107 }
michael@428 108 if rpm.debug() then
michael@428 109 arg.debug = "yes"
michael@428 110 end
michael@428 111 util.rsubst(args, "(?s)\\s*([a-z_][a-zA-Z0-9_-]*)=(?:\"((?:\\\\.|[^\"])*)\"|(\\S*))",
michael@428 112 function (key, _, value1, value2)
michael@428 113 if arg_map_fwd[key] ~= nil then
michael@428 114 key = arg_map_fwd[key]
michael@428 115 end
michael@428 116 if arg[key] == nil then
michael@428 117 io.stderr:write("rpm: invalid parameter \"" .. key .. "\" on call to \"openpkg.layout()\"\n")
michael@428 118 else
michael@428 119 if value1 ~= nil then arg[key] = value1 else arg[key] = value2 end
michael@428 120 end
michael@428 121 return false
michael@428 122 end
michael@428 123 )
michael@428 124 if arg.variable == "" then
michael@428 125 io.stderr:write("rpm: missing \"variable\" parameter on call to \"openpkg.layout()\"\n")
michael@428 126 return ""
michael@428 127 end
michael@428 128 if arg.layout == "" then
michael@428 129 io.stderr:write("rpm: missing \"layout\" parameter on call to \"openpkg.layout()\"\n")
michael@428 130 return ""
michael@428 131 end
michael@428 132 if arg.macrosfile == "" and arg.basedir == "" then
michael@428 133 io.stderr:write("rpm: missing \"macrosfile\" or \"basedir\" parameter on call to \"openpkg.layout()\"\n")
michael@428 134 return ""
michael@428 135 end
michael@428 136
michael@428 137 -- determine base directory
michael@428 138 if arg.basedir == "" then
michael@428 139 if util.rmatch(arg.macrosfile, "^.*/\.openpkg/rpmmacros$") ~= nil then
michael@428 140 arg.basedir = openpkg.canonicalize(openpkg.realpath(
michael@428 141 util.rsubst(
michael@428 142 openpkg.realpath(arg.macrosfile),
michael@428 143 "/[^/]+$", "/.."
michael@428 144 )
michael@428 145 ))
michael@428 146 else
michael@428 147 arg.basedir = rpm.expand("%{l_prefix}")
michael@428 148 end
michael@428 149 end
michael@428 150
michael@428 151 -- temporarily define "__openpkg_basedir" macro
michael@428 152 rpm.define("__openpkg_basedir " .. arg.basedir)
michael@428 153
michael@428 154 -- temporarily define "__openpkg_shared" macro
michael@428 155 if arg.shared == "yes" then
michael@428 156 rpm.define("__openpkg_shared yes")
michael@428 157 end
michael@428 158
michael@428 159 -- determine layout directory list
michael@428 160 local list = ""
michael@428 161 if arg[arg.variable] ~= nil and arg[arg.variable] ~= "" then
michael@428 162 list = arg[arg.variable]
michael@428 163 else
michael@428 164 list = rpm.expand(
michael@428 165 "%{?__openpkg_layout_" .. arg.layout .. "_" .. arg.variable .. "}" ..
michael@428 166 "%{!?__openpkg_layout_" .. arg.layout .. "_" .. arg.variable .. ":" ..
michael@428 167 "%{__openpkg_layout_global_" .. arg.variable .. "}}"
michael@428 168 )
michael@428 169 end
michael@428 170
michael@428 171 -- remove temporarily defined "__openpkg_basedir" macro
michael@428 172 rpm.undefine("__openpkg_basedir")
michael@428 173
michael@428 174 -- remove temporarily defined "__openpkg_shared" macro
michael@428 175 if arg.shared == "yes" then
michael@428 176 rpm.undefine("__openpkg_shared")
michael@428 177 end
michael@428 178
michael@428 179 -- iterate over all directory specifications
michael@428 180 local dirs = util.rsplit(list, "(?s)\\s+")
michael@428 181 local k = table.maxn(dirs)
michael@428 182 for i, _ in ipairs(dirs) do
michael@428 183 -- parse specification into path to check and optionally path to make
michael@428 184 local path_check = dirs[i]
michael@428 185 local path_append = false
michael@428 186 local path_make = path_check
michael@428 187 local s, _, m = util.rmatch(path_check, "^(.+):(\\+?)(.*)$")
michael@428 188 if s ~= nil then
michael@428 189 path_check = m[1]
michael@428 190 path_append = (m[2] == "+")
michael@428 191 path_make = m[3]
michael@428 192 end
michael@428 193 -- check whether path should be taken (last path is always taken)
michael@428 194 if posix.stat(path_check) ~= nil or i == k then
michael@428 195 if path_append then
michael@428 196 -- special case: simply append a suffix
michael@428 197 dir = path_check .. path_make
michael@428 198 else
michael@428 199 -- regular case: use full path to make
michael@428 200 dir = path_make
michael@428 201 end
michael@428 202 break
michael@428 203 end
michael@428 204 end
michael@428 205 if dir ~= "" then
michael@428 206 -- make sure path really exists and resolve to absolute path
michael@428 207 if posix.stat(dir) == nil then
michael@428 208 io.stderr:write("rpm: creating \"" .. arg.variable .. "\" directory \"" .. dir .. "\"\n")
michael@428 209 if posix.mkdir(dir) ~= 0 then
michael@428 210 io.stderr:write("rpm: failed to create directory \"" .. dir .. "\"\n")
michael@428 211 end
michael@428 212 end
michael@428 213 dir = openpkg.canonicalize(openpkg.realpath(dir))
michael@428 214 end
michael@428 215
michael@428 216 -- debugging
michael@428 217 if arg.debug == "yes" then
michael@428 218 local variable = arg.variable
michael@428 219 if arg_map_rev[variable] ~= nil then
michael@428 220 variable = arg_map_rev[variable]
michael@428 221 end
michael@428 222 io.stderr:write(string.format("rpm: openpkg: layout: [%s] %s = \"%s\"\n", arg.layout, variable, dir))
michael@428 223 end
michael@428 224
michael@428 225 -- provide result directory
michael@428 226 return dir
michael@428 227 end
michael@428 228

mercurial