+-- Internal action function
+local function _action(cmd, ...)
+ local pkg = ""
+ for k, v in pairs({...}) do
+ pkg = pkg .. " '" .. v:gsub("'", "") .. "'"
+ end
+
+ local c = "%s %s %s >/tmp/opkg.stdout 2>/tmp/opkg.stderr" %{ ipkg, cmd, pkg }
+ local r = os.execute(c)
+ local e = fs.readfile("/tmp/opkg.stderr")
+ local o = fs.readfile("/tmp/opkg.stdout")
+
+ fs.unlink("/tmp/opkg.stderr")
+ fs.unlink("/tmp/opkg.stdout")
+
+ return r, o or "", e or ""
+end
+
+-- Internal parser function
+local function _parselist(rawdata)
+ if type(rawdata) ~= "function" then
+ error("OPKG: Invalid rawdata given")
+ end
+
+ local data = {}
+ local c = {}
+ local l = nil
+
+ for line in rawdata do
+ if line:sub(1, 1) ~= " " then
+ local key, val = line:match("(.-): ?(.*)%s*")
+
+ if key and val then
+ if key == "Package" then
+ c = {Package = val}
+ data[val] = c
+ elseif key == "Status" then
+ c.Status = {}
+ for j in val:gmatch("([^ ]+)") do
+ c.Status[j] = true
+ end
+ else
+ c[key] = val
+ end
+ l = key
+ end
+ else
+ -- Multi-line field
+ c[l] = c[l] .. "\n" .. line
+ end
+ end
+
+ return data
+end
+
+-- Internal lookup function
+local function _lookup(act, pkg)
+ local cmd = ipkg .. " " .. act
+ if pkg then
+ cmd = cmd .. " '" .. pkg:gsub("'", "") .. "'"
+ end
+
+ -- OPKG sometimes kills the whole machine because it sucks
+ -- Therefore we have to use a sucky approach too and use
+ -- tmpfiles instead of directly reading the output
+ local tmpfile = os.tmpname()
+ os.execute(cmd .. (" >%s 2>/dev/null" % tmpfile))