2 FFLuCI - System library
5 Utilities for interaction with the Linux system
11 Copyright 2008 Steven Barth <steven@midlink.org>
13 Licensed under the Apache License, Version 2.0 (the "License");
14 you may not use this file except in compliance with the License.
15 You may obtain a copy of the License at
17 http://www.apache.org/licenses/LICENSE-2.0
19 Unless required by applicable law or agreed to in writing, software
20 distributed under the License is distributed on an "AS IS" BASIS,
21 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 See the License for the specific language governing permissions and
23 limitations under the License.
27 module("ffluci.sys", package.seeall)
29 require("ffluci.bits")
30 require("ffluci.util")
32 -- Runs "command" and returns its output
33 function exec(command)
34 local pp = io.popen(command)
35 local data = pp:read("*a")
41 -- Runs "command" and returns its output as a array of lines
42 function execl(command)
43 local pp = io.popen(command)
49 if (line == nil) then break end
50 table.insert(data, line)
57 -- Uses "ffluci-flash" to flash a new image file to the system
58 function flash(image, kpattern)
59 local cmd = "ffluci-flash "
61 cmd = cmd .. "-k '" .. kpattern:gsub("'", "") .. "' "
63 cmd = cmd .. "'" .. image:gsub("'", "") .. "' >/dev/null 2>&1"
65 return os.execute(cmd)
68 -- Returns the hostname
70 return io.lines("/proc/sys/kernel/hostname")()
73 -- Returns the contents of a documented referred by an URL
75 return exec("wget -qO- '"..url:gsub("'", "").."'")
78 -- Returns the load average
80 local loadavg = io.lines("/proc/loadavg")()
81 return loadavg:match("^(.-) (.-) (.-) (.-) (.-)$")
86 return os.execute("reboot >/dev/null 2>&1")
89 -- Returns the system type, cpu name, and installed physical memory
91 local c1 = "cat /proc/cpuinfo|grep system\\ typ|cut -d: -f2 2>/dev/null"
92 local c2 = "uname -m 2>/dev/null"
93 local c3 = "cat /proc/cpuinfo|grep model\\ name|cut -d: -f2 2>/dev/null"
94 local c4 = "cat /proc/cpuinfo|grep cpu\\ model|cut -d: -f2 2>/dev/null"
95 local c5 = "cat /proc/meminfo|grep MemTotal|cut -d: -f2 2>/dev/null"
97 local s = ffluci.util.trim(exec(c1))
102 s = ffluci.util.trim(exec(c2))
103 m = ffluci.util.trim(exec(c3))
105 m = ffluci.util.trim(exec(c4))
108 r = ffluci.util.trim(exec(c5))
115 group.getgroup = posix.getgroup
118 -- Returns whether an IP-Adress belongs to a certain net
119 function net.belongs(ip, net)
120 local netparts = ffluci.util.split(net, "/")
122 if #netparts ~= 2 then
126 local binadr = net.ip4bin(ip)
127 local binnet = net.ip4bin(netparts[1])
129 return (binadr:sub(1, netparts[2]) == binnet:sub(1, netparts[2]))
132 -- Returns all available network interfaces
133 function net.devices()
135 for line in io.lines("/proc/net/dev") do
136 table.insert(devices, line:match(" *(.-):"))
141 -- Returns the kernel routing table
142 function net.routes()
143 return _parse_delimited_table(io.lines("/proc/net/route"))
146 -- Returns the numeric IP to a given hexstring
147 function net.hexip4(hex)
152 local hexdec = ffluci.bits.Hex2Dec
155 ip = ip .. tostring(hexdec(hex:sub(7,8))) .. "."
156 ip = ip .. tostring(hexdec(hex:sub(5,6))) .. "."
157 ip = ip .. tostring(hexdec(hex:sub(3,4))) .. "."
158 ip = ip .. tostring(hexdec(hex:sub(1,2)))
163 -- Returns the binary IP to a given IP
164 function net.ip4bin(ip)
165 local parts = ffluci.util.split(ip, '%.')
170 local decbin = ffluci.bits.Dec2Bin
173 bin = bin .. decbin(parts[1], 8)
174 bin = bin .. decbin(parts[2], 8)
175 bin = bin .. decbin(parts[3], 8)
176 bin = bin .. decbin(parts[4], 8)
181 -- Tests whether a host is pingable
182 function net.pingtest(host)
183 return os.execute("ping -c1 '"..host:gsub("'", '').."' >/dev/null 2>&1")
188 process.info = posix.getpid
190 -- Sets the gid of a process
191 function process.setgroup(pid, gid)
192 return posix.setpid("g", pid, gid)
195 -- Sets the uid of a process
196 function process.setuser(pid, uid)
197 return posix.setpid("u", pid, uid)
201 -- returns user information to a given uid
202 user.getuser = posix.getpasswd
204 -- Changes the user password of given user
205 function user.setpasswd(user, pwd)
207 pwd = pwd:gsub("'", "")
211 user = user:gsub("'", "")
214 local cmd = "(echo '"..pwd.."';sleep 1;echo '"..pwd.."')|"
215 cmd = cmd .. "passwd '"..user.."' >/dev/null 2>&1"
216 return os.execute(cmd)
222 function wifi.getiwconfig()
223 local cnt = exec("/usr/sbin/iwconfig 2>/dev/null")
226 for i, l in pairs(ffluci.util.split(ffluci.util.trim(cnt), "\n\n")) do
227 local k = l:match("^(.-) ")
228 l = l:gsub("^(.-) +", "", 1)
230 iwc[k] = _parse_mixed_record(l)
237 function wifi.iwscan()
238 local cnt = exec("iwlist scan 2>/dev/null")
241 for i, l in pairs(ffluci.util.split(ffluci.util.trim(cnt), "\n\n")) do
242 local k = l:match("^(.-) ")
243 l = l:gsub("^[^\n]+", "", 1)
246 for j, c in pairs(ffluci.util.split(l, "\n Cell")) do
247 c = c:gsub("^(.-)- ", "", 1)
248 c = ffluci.util.split(c, "\n", 7)
249 c = table.concat(c, "\n", 1, 7)
250 table.insert(iws[k], _parse_mixed_record(c))
259 -- Internal functions
261 function _parse_delimited_table(iter, delimiter)
262 delimiter = delimiter or "\t+"
265 local trim = ffluci.util.trim
266 local split = ffluci.util.split
268 local keys = split(trim(iter()), delimiter)
269 for i, j in pairs(keys) do
270 keys[i] = trim(keys[i])
277 for i, j in pairs(split(line, delimiter)) do
283 table.insert(data, row)
289 function _parse_mixed_record(cnt)
292 for i, l in pairs(ffluci.util.split(ffluci.util.trim(cnt), "\n")) do
293 for j, f in pairs(ffluci.util.split(ffluci.util.trim(l), " ")) do
294 local k, x, v = f:match('([^%s][^:=]+) *([:=]*) *"*([^\n"]*)"*')
298 table.insert(data, k)