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 (little endian)
147 function net.hexip4(hex, bigendian)
152 local hexdec = ffluci.bits.Hex2Dec
156 ip = ip .. tostring(hexdec(hex:sub(1,2))) .. "."
157 ip = ip .. tostring(hexdec(hex:sub(3,4))) .. "."
158 ip = ip .. tostring(hexdec(hex:sub(5,6))) .. "."
159 ip = ip .. tostring(hexdec(hex:sub(7,8)))
161 ip = ip .. tostring(hexdec(hex:sub(7,8))) .. "."
162 ip = ip .. tostring(hexdec(hex:sub(5,6))) .. "."
163 ip = ip .. tostring(hexdec(hex:sub(3,4))) .. "."
164 ip = ip .. tostring(hexdec(hex:sub(1,2)))
170 -- Returns the binary IP to a given IP
171 function net.ip4bin(ip)
172 local parts = ffluci.util.split(ip, '.')
177 local decbin = ffluci.bits.Dec2Bin
180 bin = bin .. decbin(parts[1], 8)
181 bin = bin .. decbin(parts[2], 8)
182 bin = bin .. decbin(parts[3], 8)
183 bin = bin .. decbin(parts[4], 8)
188 -- Tests whether a host is pingable
189 function net.pingtest(host)
190 return os.execute("ping -c1 '"..host:gsub("'", '').."' >/dev/null 2>&1")
195 process.info = posix.getpid
197 -- Sets the gid of a process
198 function process.setgroup(pid, gid)
199 return posix.setpid("g", pid, gid)
202 -- Sets the uid of a process
203 function process.setuser(pid, uid)
204 return posix.setpid("u", pid, uid)
208 -- returns user information to a given uid
209 user.getuser = posix.getpasswd
211 -- Changes the user password of given user
212 function user.setpasswd(user, pwd)
214 pwd = pwd:gsub("'", "")
218 user = user:gsub("'", "")
221 local cmd = "(echo '"..pwd.."';sleep 1;echo '"..pwd.."')|"
222 cmd = cmd .. "passwd '"..user.."' >/dev/null 2>&1"
223 return os.execute(cmd)
229 function wifi.getiwconfig()
230 local cnt = exec("/usr/sbin/iwconfig 2>/dev/null")
233 for i, l in pairs(ffluci.util.split(ffluci.util.trim(cnt), "\n\n")) do
234 local k = l:match("^(.-) ")
235 l = l:gsub("^(.-) +", "", 1)
237 iwc[k] = _parse_mixed_record(l)
244 function wifi.iwscan()
245 local cnt = exec("iwlist scan 2>/dev/null")
248 for i, l in pairs(ffluci.util.split(ffluci.util.trim(cnt), "\n\n")) do
249 local k = l:match("^(.-) ")
250 l = l:gsub("^[^\n]+", "", 1)
251 l = ffluci.util.trim(l)
254 for j, c in pairs(ffluci.util.split(l, "\n Cell")) do
255 c = c:gsub("^(.-)- ", "", 1)
256 c = ffluci.util.split(c, "\n", 7)
257 c = table.concat(c, "\n", 1)
258 table.insert(iws[k], _parse_mixed_record(c))
267 -- Internal functions
269 function _parse_delimited_table(iter, delimiter)
270 delimiter = delimiter or "\t+"
273 local trim = ffluci.util.trim
274 local split = ffluci.util.split
276 local keys = split(trim(iter()), delimiter, nil, true)
277 for i, j in pairs(keys) do
278 keys[i] = trim(keys[i])
285 for i, j in pairs(split(line, delimiter, nil, true)) do
291 table.insert(data, row)
297 function _parse_mixed_record(cnt)
300 for i, l in pairs(ffluci.util.split(ffluci.util.trim(cnt), "\n")) do
301 for j, f in pairs(ffluci.util.split(ffluci.util.trim(l), " ")) do
302 local k, x, v = f:match('([^%s][^:=]+) *([:=]*) *"*([^\n"]*)"*')
306 table.insert(data, k)