* luci/libs/sys: fix function name of init.disable()
[project/luci.git] / libs / sys / luasrc / sys.lua
index 3fa34fd..230201d 100644 (file)
@@ -60,35 +60,15 @@ exec = luci.util.exec
 --- Invoke the luci-flash executable to write an image to the flash memory.
 -- @param image                Local path or URL to image file
 -- @param kpattern     Pattern of files to keep over flash process
--- @return                     boolean indicating status
--- @return                     error message if any
+-- @return                     Return value of os.execute()
 function flash(image, kpattern)
        local cmd = "luci-flash "
        if kpattern then
                cmd = cmd .. "-k '" .. kpattern:gsub("'", "") .. "' "
        end
-       cmd = cmd .. "'" .. image:gsub("'", "") .. "' 2>/dev/null"
-
-       local fp = io.popen(cmd)
-       local line = fp:read()
-       
-       if line == "Invalid image type" then
-               fp:close()
-               return false, line
-       else
-               line = fp:read()
-               if line == "Performing system upgrade..." then
-                       return true
-               end
-               
-               line = fp:read()
-               if line == "Performing system upgrade..." then
-                       return true
-               end
-               
-               fp:close()
-               return false, line
-       end
+       cmd = cmd .. "'" .. image:gsub("'", "") .. "' >/dev/null 2>&1"
+
+       return os.execute(cmd)
 end
 
 --- Retrieve information about currently mounted file systems.
@@ -97,27 +77,44 @@ function mounts()
        local data = {}
        local k = {"fs", "blocks", "used", "available", "percent", "mountpoint"}
        local ps = luci.util.execi("df")
-       
+
        if not ps then
                return
        else
                ps()
        end
-       
+
        for line in ps do
                local row = {}
-               
+
                local j = 1
                for value in line:gmatch("[^%s]+") do
                        row[k[j]] = value
                        j = j + 1
                end
-               
+
                if row[k[1]] then
+
+                       -- this is a rather ugly workaround to cope with wrapped lines in
+                       -- the df output:
+                       --
+                       --      /dev/scsi/host0/bus0/target0/lun0/part3
+                       --                   114382024  93566472  15005244  86% /mnt/usb
+                       --
+
+                       if not row[k[2]] then
+                               j = 2
+                               line = ps()
+                               for value in line:gmatch("[^%s]+") do
+                                       row[k[j]] = value
+                                       j = j + 1
+                               end
+                       end
+
                        table.insert(data, row)
                end
        end
-       
+
        return data
 end
 
@@ -355,37 +352,37 @@ function process.list()
        local data = {}
        local k
        local ps = luci.util.execi("top -bn1")
-       
+
        if not ps then
                return
        end
-       
+
        while true do
                local line = ps()
                if not line then
                        return
                end
-               
+
                k = luci.util.split(luci.util.trim(line), "%s+", nil, true)
                if k[1] == "PID" then
                        break
                end
        end
-       
+
        for line in ps do
                local row = {}
-               
+
                line = luci.util.trim(line)
                for i, value in ipairs(luci.util.split(line, "%s+", #k-1, true)) do
                        row[k[i]] = value
                end
-               
+
                local pid = tonumber(row[k[1]])
                if pid then
                        data[pid] = row
                end
        end
-       
+
        return data
 end
 
@@ -440,11 +437,29 @@ function user.checkpasswd(username, password)
        local account = user.getuser(username)
 
        if account then
-               if account.passwd == "!" then
-                       return true
-               else
-                       return (account.passwd == posix.crypt(password, account.passwd))
+               local pwd = account.passwd
+               local shadowpw
+               if #pwd == 1 then
+                       if luci.fs.stat("/etc/shadow") then
+                               if not pcall(function()
+                                       for l in io.lines("/etc/shadow") do
+                                               shadowpw = l:match("^%s:([^:]+)" % username)
+                                               if shadowpw then
+                                                       pwd = shadowpw
+                                                       break
+                                               end
+                                       end
+                               end) then
+                                       return nil, "Unable to access shadow-file"
+                               end
+                       end
+
+                       if pwd == "!" then
+                               return true
+                       end
                end
+
+               return (pwd == posix.crypt(password, pwd))
        end
 end
 
@@ -515,6 +530,56 @@ function wifi.iwscan(iface)
 end
 
 
+--- LuCI system utilities / init related functions.
+-- @class      module
+-- @name       luci.sys.init
+init = {}
+init.dir = "/etc/init.d/"
+
+--- Get the names of all installed init scripts
+-- @return     Table containing the names of all inistalled init scripts
+function init.names()
+       local names = { }
+       for _, name in ipairs(luci.fs.glob(init.dir.."*")) do
+               names[#names+1] = luci.fs.basename(name)
+       end
+       return names
+end
+
+--- Test whether the given init script is enabled
+-- @return     Boolean indicating whether init is enabled
+function init.enabled(name)
+       if luci.fs.access(init.dir..name) then
+               return ( call(init.dir..name.." enabled") == 0 )
+       end
+       return false
+end
+
+--- Get the index of he given init script
+-- @return     Numeric index value
+function init.index(name)
+       if luci.fs.access(init.dir..name) then
+               return call("source "..init.dir..name.." && exit $START")
+       end
+end
+
+--- Enable the given init script
+-- @return     Boolean indicating success
+function init.enable(name)
+       if luci.fs.access(init.dir..name) then
+               return ( call(init.dir..name.." enable") == 0 )
+       end
+end
+
+--- Disable the given init script
+-- @return     Boolean indicating success
+function init.disable(name)
+       if luci.fs.access(init.dir..name) then
+               return ( call(init.dir..name.." disable") == 0 )
+       end
+end
+
+
 -- Internal functions
 
 function _parse_delimited_table(iter, delimiter)