local path_separator = assert ( package.config:match ( "^([^\n]+)" ) , "package.config not in standard form" ) -- Extract directory seperator from package.config (an undocumented string that comes with lua)
local lfs = require "lfs";
local prosody = prosody;
-local raw_mkdir;
-local fallocate;
-
-if prosody.platform == "posix" then
- raw_mkdir = require "util.pposix".mkdir; -- Doesn't trample on umask
- fallocate = require "util.pposix".fallocate;
-else
- raw_mkdir = lfs.mkdir;
-end
-if not fallocate then -- Fallback
- function fallocate(f, offset, len)
- -- This assumes that current position == offset
- local fake_data = (" "):rep(len);
- local ok, msg = f:write(fake_data);
- if not ok then
- return ok, msg;
- end
- f:seek("set", offset);
- return true;
+local raw_mkdir = lfs.mkdir;
+local function fallocate(f, offset, len)
+ -- This assumes that current position == offset
+ local fake_data = (" "):rep(len);
+ local ok, msg = f:write(fake_data);
+ if not ok then
+ return ok, msg;
end
-end
+ f:seek("set", offset);
+ return true;
+end;
+pcall(function()
+ local pposix = require "util.pposix";
+ raw_mkdir = pposix.mkdir or raw_mkdir; -- Doesn't trample on umask
+ fallocate = pposix.fallocate or fallocate;
+end);
module "datamanager"
return items;
end
-function list_stores(username, host)
- if not host then
- return nil, "bad argument #2 to 'list_stores' (string expected, got nothing)";
+local type_map = {
+ keyval = "dat";
+ list = "list";
+}
+
+function users(host, store, typ)
+ typ = type_map[typ or "keyval"];
+ local store_dir = format("%s/%s/%s", data_path, encode(host), encode(store));
+
+ local mode, err = lfs.attributes(store_dir, "mode");
+ if not mode then
+ return function() log("debug", err or (store_dir .. " does not exist")) end
+ end
+ local next, state = lfs.dir(store_dir);
+ return function(state)
+ for node in next, state do
+ local file, ext = node:match("^(.*)%.([dalist]+)$");
+ if file and ext == typ then
+ return decode(file);
+ end
+ end
+ end, state;
+end
+
+function stores(username, host, typ)
+ typ = type_map[typ or "keyval"];
+ local store_dir = format("%s/%s/", data_path, encode(host));
+
+ local mode, err = lfs.attributes(store_dir, "mode");
+ if not mode then
+ return function() log("debug", err or (store_dir .. " does not exist")) end
end
- local list = {};
- local host_dir = format("%s/%s/", data_path, encode(host));
- for node in lfs.dir(host_dir) do
- if not node:match"^%." then -- dots should be encoded, this is probably . or ..
- local store = decode(node);
- local path = host_dir..node;
- if username == true then
- if lfs.attributes(path, "mode") == "directory" then
- list[#list+1] = store;
+ local next, state = lfs.dir(store_dir);
+ return function(state)
+ for node in next, state do
+ if not node:match"^%." then
+ if username == true then
+ if lfs.attributes(store_dir..node, "mode") == "directory" then
+ return decode(node);
+ end
+ elseif username then
+ local store = decode(node)
+ if lfs.attributes(getpath(username, host, store, typ), "mode") then
+ return store;
+ end
+ elseif lfs.attributes(node, "mode") == "file" then
+ local file, ext = node:match("^(.*)%.([dalist]+)$");
+ if ext == typ then
+ return decode(file)
+ end
end
- elseif username then
- if lfs.attributes(getpath(username, host, store), "mode")
- or lfs.attributes(getpath(username, host, store, "list"), "mode") then
- list[#list+1] = store;
- end
- elseif lfs.attributes(path, "mode") == "file" then
- list[#list+1] = store:gsub("%.[dalist]+$","");
end
end
- end
- return list;
+ end, state;
end
local function do_remove(path)