3b149fb168e5ce2401568404399eb8a9e7406fc6
[project/luci.git] / core / src / model / ipkg.lua
1 --[[
2 FFLuCI - IPKG wrapper library
3
4 Description:
5 Wrapper for the ipkg Package manager
6
7 Any return value of false or nil can be interpreted as an error
8
9 FileId:
10 $Id$
11
12 License:
13 Copyright 2008 Steven Barth <steven@midlink.org>
14
15 Licensed under the Apache License, Version 2.0 (the "License");
16 you may not use this file except in compliance with the License.
17 You may obtain a copy of the License at 
18
19         http://www.apache.org/licenses/LICENSE-2.0 
20
21 Unless required by applicable law or agreed to in writing, software
22 distributed under the License is distributed on an "AS IS" BASIS,
23 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24 See the License for the specific language governing permissions and
25 limitations under the License.
26
27 ]]--
28 module("ffluci.model.ipkg", package.seeall)
29 require("ffluci.sys")
30 require("ffluci.util")
31
32 ipkg = "ipkg"
33
34 -- Returns repository information
35 function info(pkg)
36         return _lookup("info", pkg)
37 end
38
39 -- Returns a table with status information
40 function status(pkg)
41         return _lookup("status", pkg)
42 end
43
44 -- Installs packages
45 function install(...)
46         return _action("install", ...)
47 end
48
49 -- Returns whether a package is installed
50 function installed(pkg, ...)
51         local p = status(...)[pkg]
52         return (p and p.Status and p.Status.installed)
53 end
54
55 -- Removes packages
56 function remove(...)
57         return _action("remove", ...)
58 end
59
60 -- Updates package lists
61 function update()
62         return _action("update")
63 end
64
65 -- Upgrades installed packages
66 function upgrade()
67         return _action("upgrade")
68 end
69
70
71 -- Internal action function
72 function _action(cmd, ...)
73         local pkg = ""
74         arg.n = nil
75         for k, v in pairs(arg) do
76                 pkg = pkg .. " '" .. v:gsub("'", "") .. "'"
77         end
78         
79         local c = ipkg.." "..cmd.." "..pkg.." >/dev/null 2>&1"
80         local r = os.execute(c)
81         return (r == 0), r      
82 end
83
84 -- Internal lookup function
85 function _lookup(act, pkg)
86         local cmd = ipkg .. " " .. act
87         if pkg then
88                 cmd = cmd .. " '" .. pkg:gsub("'", "") .. "'"
89         end
90         
91         return _parselist(ffluci.sys.exec(cmd .. " 2>/dev/null"))
92 end
93
94 -- Internal parser function
95 function _parselist(rawdata)    
96         if type(rawdata) ~= "string" then
97                 error("IPKG: Invalid rawdata given")
98         end
99         
100         rawdata = ffluci.util.split(rawdata) 
101         local data = {}
102         local c = {}
103         local l = nil
104         
105         for k, line in pairs(rawdata) do
106                 if line:sub(1, 1) ~= " " then
107                         local split = ffluci.util.split(line, ":", 1)
108                         local key = nil
109                         local val = nil
110                         
111                         if split[1] then
112                                 key = ffluci.util.trim(split[1])
113                         end
114                         
115                         if split[2] then
116                                 val = ffluci.util.trim(split[2])
117                         end
118                         
119                         if key and val then
120                                 if key == "Package" then
121                                         c = {Package = val}
122                                         data[val] = c
123                                 elseif key == "Status" then
124                                         c.Status = {}
125                                         for i, j in pairs(ffluci.util.split(val, " ")) do
126                                                 c.Status[j] = true
127                                         end
128                                 else
129                                         c[key] = val
130                                 end
131                                 l = key
132                         end
133                 else
134                         -- Multi-line field
135                         c[l] = c[l] .. "\n" .. line:sub(2)
136                 end
137         end
138         
139         return data
140 end