local fs = require("filesystem") local lib = {} local rules_path = "/etc/udev/rules.d/" local auto_rules = "autogenerated.lua" local function fs_key(dir, filename) local long_name = dir .. '/' .. filename local segments = fs.segments(long_name) local result = '/' .. table.concat(segments, '/') return result end function lib.loadRules(root_dir) checkArg(1, root_dir, "string", "nil") root_dir = (root_dir or rules_path) lib.rules = {} lib.rules[fs_key(root_dir, auto_rules)] = {} for file in fs.list(root_dir) do if file:match("%.lua$") then local path = fs_key(root_dir, file) local file_handle = io.open(path) if file_handle then local load_rule = load("return {" .. file_handle:read("*a") .. "}") file_handle:close() if load_rule then local ok, rule = pcall(load_rule) if ok and type(rule) == "table" then local irule = {} lib.rules[path] = irule for _,v in ipairs(rule) do if type(v) == "table" then table.insert(irule, v) end -- else invalid rule end end end end end end end function lib.saveRule(rule_set, path) checkArg(1, rule_set, "table") checkArg(2, path, "string") local file = io.open(path, "w") if not file then return end -- fs may be read only, totally fine, this just won't persist for index, irule in ipairs(rule_set) do file:write(require("serialization").serialize(irule), ",\n") end file:close() end function lib.saveRules(rules) for path, rule_set in pairs(rules) do lib.saveRule(rule_set, path) end end local function getIRule(proxy) checkArg(1, proxy, "table") for path,rule_set in pairs(lib.rules) do for index, irule in ipairs(rule_set) do if irule.address == proxy.address then return irule, index, rule_set, path end end end end function lib.getDeviceLabel(proxy) local irule = getIRule(proxy) if irule and irule.label then return irule.label elseif proxy.getLabel then return proxy.getLabel() end end function lib.setDeviceLabel(proxy, label) local irule, index, rule_set, path = getIRule(proxy) if not irule then -- if the device supports labels, use it instead if proxy.setLabel then return proxy.setLabel(label) end path = fs_key(rules_path, auto_rules) rule_set = lib.rules[path] index = #rule_set + 1 irule = {address=proxy.address} table.insert(rule_set, irule) end irule.label = label lib.saveRule(rule_set, path) end return lib