Re: [Slightly-OT] On usability: managing usb devices & network profiles in a ion3 environment

Tuomo Valkonen <[email protected]>
Newsgroups gmane.comp.window-managers.ion.general
Message-ID <[email protected]>
On 2009-03-03 17:21 -0500, Antonio De Leon wrote:
> On the question of detecting usb devices this tool can help on the
> detection part.

Here's my ls-removable script too. It's in Lua, and needs
both luafilesystem and posix packages for Lua.

There are two versions. The suffix-1 version worked with
the old 2.6.18 or whateveritwas Etch. Suffix-2 is a
conversion to work the modified /sys layout in *buntu 8.10,
but it fails to work because pmount doesn't seem to have
been upgraded to to reflect that. It, however, shouldn't be
too difficult to create a suid-root counterpart based on my
code, that just calls mount -- this time with sane FAT and
NTFS mounting arguments.

(*sigh*, even the ntfs-3g in 8.10 ubuntu is old, and does
not seem to support .NTFS-3G/UserMapping. A lot of shit in
it is _old_, and yet it has just half-a-year release
cycles.)

-- 
"[Fashion] is usually a form of ugliness so intolerable that we have
 to alter it every six months." -- Oscar Wilde
"The computer industry is the only industry that is more fashion-driven
 than women's fashion." -- RMS
ls-removable-1 (text/plain, 4.4 KB)
#!/usr/local/bin/lua
--
-- Copyright (c) Tuomo Valkonen 2008.
--

require('lfs')
require('posix')

local function filtered_dir(d) 
    local f, s_, v_ = lfs.dir(d)
    local function g(s, v)
        while true do
            local vn=f(s, v)
            if vn~='.' and vn~='..' then
                return vn
            end
        end
    end
    return g, s_, v_
end

local function readfile(d)
    local f, err = io.open(d, 'r')
    if f then
        local s=f:read('*a')
        f:close()
        return s
    end
end

local function simplify_string(s)
    if s then
        return string.gsub(s, "\n$", "")
    end
end

local function readfile_simple(d)
    return simplify_string(readfile(d))
end

local function removable(d)
    return readfile_simple(d.."/removable")=="1";
end

local function removable_class(d)
    -- Super-dirty hack
    return d and string.match(d, "/usb%d+/")
end

local function simplify_path(p)
    local capts={}
    local start=string.match(p, "^(/)")
    string.gsub(p, "([^/]+)",
                   function(e)
                       if e==".." and #capts > 1 then
                           capts[#capts]=nil
                       elseif e~="." then
                           table.insert(capts, e)
                       end
                    end) 
    return (start or "")..table.concat(capts, "/")
end

local function get_device(d)
    l=posix.readlink(d.."/device")
    if not l then
        return nil
    end
    if string.match(l, "^.") then
        return simplify_path(d.."/"..l)
    else
        return simplify_path(l)
    end
end

local function get_info(dev)
    return {
        vendor=readfile_simple(dev.."/vendor"),
        model=readfile_simple(dev.."/model"),
        serial=readfile_simple(dev.."/serial")
    }
end

local function get_info_usb(dev)
    par=string.match(dev, "(.*)/[^/]+")
    if not par then
        return {}
    else
        local m=readfile_simple(par.."/manufacturer")
        if not m then
            return get_info_usb(par)
        else
            return {
                vendor=m,
                model=readfile_simple(par.."/product"),
                serial=readfile_simple(par.."/serial")
            }
        end
    end
end

local function scan_volumes(bd, d)
    local function g()
        local found=false
        for v in filtered_dir(bd..d) do
            if string.match(v, "^"..d.."%d+$") then
                coroutine.yield(v)
                found=true
            end
        end
        if not found then
            coroutine.yield(d)
        end
    end
    
    return coroutine.wrap(g)
end



local mounts={}
--local mounts_=io.popen("mount"):read('*a')
--string.gsub(mounts_, "[^\n]+", function(l) table.insert(mounts, l) end)
local f=io.open("/etc/mtab")
for l in f:lines() do
    table.insert(mounts, l)
end
f:close()

local function mounted(v)
    for _, l in ipairs(mounts) do
        local mp=string.match(l, "^/dev/"..v.."%s+([^%s]+)")
        if mp then
            return mp
        end
    end
    return false
end

local bd='/sys/block/'

local volumes={}

for d in filtered_dir(bd) do
    local dev=get_device(bd..d)
    if removable(bd..d) or removable_class(dev) then
        local i1=get_info(dev)
        local i2=get_info_usb(dev)
        
        if i2 and i2.vendor then
            info=table.concat({i2.vendor, i2.model, i2.serial}, " ")
        else
            info=table.concat({i1.vendor, i1.model, i1.serial}, " ")
        end
        
        for v in scan_volumes(bd, d) do
            table.insert(volumes, {
                kernel=v,
                info=info,
                mountpoint=mounted(v),
            })
        end
    end
end

table.sort(volumes,
           function(a, b) 
               if a.mountpoint and not b.mountpoint then
                   return false
               elseif not a.mountpoint and b.mountpoint then
                   return true
               else
                   return (a.kernel < b.kernel)
               end
           end)


for k, v in ipairs(volumes) do
    if not v.mountpoint then
        io.write(string.format("%d) %s (%s)\n",  k, v.kernel, v.info))
    else
        io.write(string.format("[ %d) %s (%s) %s ]\n",  k, v.kernel, v.info, v.mountpoint))
    end
end
io.write("Choice (1): ")
local a=io.read()
local i=((not a or a=="") and 1) or tonumber(a)

if i then
    if volumes[i].mountpoint then
        os.execute("pumount "..volumes[i].mountpoint)
    else
        os.execute("pmount /dev/"..volumes[i].kernel)
    end
end
ls-removable-2 (text/plain, 4.5 KB)
#!/usr/bin/lua
--
-- Copyright (c) Tuomo Valkonen 2008.
--

require('lfs')
require('posix')

local function filtered_dir(d) 
    local f, s_, v_ = lfs.dir(d)
    local function g(s, v)
        while true do
            local vn=f(s, v)
            if vn~='.' and vn~='..' then
                return vn
            end
        end
    end
    return g, s_, v_
end

local function readfile(d)
    local f, err = io.open(d, 'r')
    if f then
        local s=f:read('*a')
        f:close()
        return s
    end
end

local function basename(d)
    return string.gsub(d, "^(.*)/[^/]*$", "%1")
end

local function simplify_string(s)
    if s then
        return string.gsub(s, "\n$", "")
    end
end

local function readfile_simple(d)
    return simplify_string(readfile(d))
end

local function removable(d)
    return readfile_simple(d.."/removable")=="1";
end

local function removable_class(d)
    -- Super-dirty hack
    return d and string.match(d, "/usb%d+/")
end

local function simplify_path(p)
    local capts={}
    local start=string.match(p, "^(/)")
    string.gsub(p, "([^/]+)",
                   function(e)
                       if e==".." and #capts > 1 then
                           capts[#capts]=nil
                       elseif e~="." then
                           table.insert(capts, e)
                       end
                    end) 
    return (start or "")..table.concat(capts, "/")
end

local function get_device(d)
    --l=posix.readlink(d.."/device")
    l=posix.readlink(d)
    if not l then
        return nil
    end
    if string.match(l, "^.") then
        return simplify_path(basename(d).."/"..l.."/device")
    else
        return simplify_path(l.."/device")
    end
end

local function get_info(dev)
    return {
        vendor=readfile_simple(dev.."/vendor"),
        model=readfile_simple(dev.."/model"),
        serial=readfile_simple(dev.."/serial")
    }
end

local function get_info_usb(dev)
    par=string.match(dev, "(.*)/[^/]+")
    if not par then
        return {}
    else
        local m=readfile_simple(par.."/manufacturer")
        if not m then
            return get_info_usb(par)
        else
            return {
                vendor=m,
                model=readfile_simple(par.."/product"),
                serial=readfile_simple(par.."/serial")
            }
        end
    end
end

local function scan_volumes(bd, d)
    local function g()
        local found=false
        for v in filtered_dir(bd..d) do
            if string.match(v, "^"..d.."%d+$") then
                coroutine.yield(v)
                found=true
            end
        end
        if not found then
            coroutine.yield(d)
        end
    end
    
    return coroutine.wrap(g)
end



local mounts={}
--local mounts_=io.popen("mount"):read('*a')
--string.gsub(mounts_, "[^\n]+", function(l) table.insert(mounts, l) end)
local f=io.open("/etc/mtab")
for l in f:lines() do
    table.insert(mounts, l)
end
f:close()

local function mounted(v)
    for _, l in ipairs(mounts) do
        local mp=string.match(l, "^/dev/"..v.."%s+([^%s]+)")
        if mp then
            return mp
        end
    end
    return false
end

local bd='/sys/block/'

local volumes={}

for d in filtered_dir(bd) do
    local dev=get_device(bd..d)
    if removable(bd..d) or removable_class(dev) then
        local i1=get_info(dev)
        local i2=get_info_usb(dev)
        
        if i2 and i2.vendor then
            info=table.concat({i2.vendor, i2.model, i2.serial}, " ")
        else
            info=table.concat({i1.vendor, i1.model, i1.serial}, " ")
        end
        
        for v in scan_volumes(bd, d) do
            table.insert(volumes, {
                kernel=v,
                info=info,
                mountpoint=mounted(v),
            })
        end
    end
end

table.sort(volumes,
           function(a, b) 
               if a.mountpoint and not b.mountpoint then
                   return false
               elseif not a.mountpoint and b.mountpoint then
                   return true
               else
                   return (a.kernel < b.kernel)
               end
           end)


for k, v in ipairs(volumes) do
    if not v.mountpoint then
        io.write(string.format("%d) %s (%s)\n",  k, v.kernel, v.info))
    else
        io.write(string.format("[ %d) %s (%s) %s ]\n",  k, v.kernel, v.info, v.mountpoint))
    end
end
io.write("Choice (1): ")
local a=io.read()
local i=((not a or a=="") and 1) or tonumber(a)

if i then
    if volumes[i].mountpoint then
        os.execute("pumount "..volumes[i].mountpoint)
    else
        os.execute("pmount /dev/"..volumes[i].kernel)
    end
end
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.