libs/ipkg: use -force-defaults to ensure non-interactive execution
[project/luci.git] / libs / ipkg / luasrc / model / ipkg.lua
index 706d36c..a04f0a4 100644 (file)
@@ -14,13 +14,14 @@ $Id$
 ]]--
 
 local os   = require "os"
+local io   = require "io"
 local util = require "luci.util"
 
 local type  = type
 local pairs = pairs
 local error = error
 
-local ipkg = "opkg"
+local ipkg = "opkg -force-defaults"
 
 --- LuCI IPKG/OPKG call abstraction library
 module "luci.model.ipkg"
@@ -33,44 +34,33 @@ local function _action(cmd, ...)
        for k, v in pairs(arg) do
                pkg = pkg .. " '" .. v:gsub("'", "") .. "'"
        end
-       
+
        local c = ipkg.." "..cmd.." "..pkg.." >/dev/null 2>&1"
        local r = os.execute(c)
-       return (r == 0), r      
+       return (r == 0), r
 end
 
 -- Internal parser function
-local function _parselist(rawdata)     
-       if type(rawdata) ~= "string" then
+local function _parselist(rawdata)
+       if type(rawdata) ~= "function" then
                error("IPKG: Invalid rawdata given")
        end
-       
-       rawdata = util.split(rawdata) 
+
        local data = {}
        local c = {}
        local l = nil
-       
-       for k, line in pairs(rawdata) do
+
+       for line in rawdata do
                if line:sub(1, 1) ~= " " then
-                       local split = util.split(line, ":", 1)
-                       local key = nil
-                       local val = nil
-                       
-                       if split[1] then
-                               key = util.trim(split[1])
-                       end
-                       
-                       if split[2] then
-                               val = util.trim(split[2])
-                       end
-                       
+                       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 i, j in pairs(util.split(val, " ")) do
+                                       for j in val:gmatch("([^ ]+)") do
                                                c.Status[j] = true
                                        end
                                else
@@ -80,10 +70,10 @@ local function _parselist(rawdata)
                        end
                else
                        -- Multi-line field
-                       c[l] = c[l] .. "\n" .. line:sub(2)
+                       c[l] = c[l] .. "\n" .. line
                end
        end
-       
+
        return data
 end
 
@@ -93,8 +83,16 @@ local function _lookup(act, pkg)
        if pkg then
                cmd = cmd .. " '" .. pkg:gsub("'", "") .. "'"
        end
-       
-       return _parselist(util.exec(cmd .. " 2>/dev/null"))
+
+       -- IPKG 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))
+
+       local data = _parselist(io.lines(tmpfile))
+       os.remove(tmpfile)
+       return data
 end
 
 
@@ -149,4 +147,3 @@ end
 function upgrade()
        return _action("upgrade")
 end
-