util.pluginloader: Return full file path from internal file loader on success, not...
[prosody.git] / util / datamanager.lua
index 01c7aab2210f85f817f7e6c63620d5d37cab7937..d5e9c88ca7ad0130b879060950d579420edb65d1 100644 (file)
@@ -21,12 +21,14 @@ local next = next;
 local t_insert = table.insert;
 local append = require "util.serialization".append;
 local path_separator = "/"; if os.getenv("WINDIR") then path_separator = "\\" end
+local lfs = require "lfs";
+local prosody = prosody;
 local raw_mkdir;
 
 if prosody.platform == "posix" then
        raw_mkdir = require "util.pposix".mkdir; -- Doesn't trample on umask
 else
-       raw_mkdir = require "lfs".mkdir;
+       raw_mkdir = lfs.mkdir;
 end
 
 module "datamanager"
@@ -55,7 +57,7 @@ local function mkdir(path)
        return path;
 end
 
-local data_path = "data";
+local data_path = (prosody and prosody.paths and prosody.paths.data) or ".";
 local callbacks = {};
 
 ------- API -------------
@@ -111,14 +113,21 @@ end
 function load(username, host, datastore)
        local data, ret = loadfile(getpath(username, host, datastore));
        if not data then
-               log("debug", "Failed to load "..datastore.." storage ('"..ret.."') for user: "..(username or "nil").."@"..(host or "nil"));
-               return nil;
+               local mode = lfs.attributes(getpath(username, host, datastore), "mode");
+               if not mode then
+                       log("debug", "Assuming empty "..datastore.." storage ('"..ret.."') for user: "..(username or "nil").."@"..(host or "nil"));
+                       return nil;
+               else -- file exists, but can't be read
+                       -- TODO more detailed error checking and logging?
+                       log("error", "Failed to load "..datastore.." storage ('"..ret.."') for user: "..(username or "nil").."@"..(host or "nil"));
+                       return nil, "Error reading storage";
+               end
        end
        setfenv(data, {});
        local success, ret = pcall(data);
        if not success then
                log("error", "Unable to load "..datastore.." storage ('"..ret.."') for user: "..(username or "nil").."@"..(host or "nil"));
-               return nil;
+               return nil, "Error reading storage";
        end
        return ret;
 end
@@ -137,7 +146,7 @@ function store(username, host, datastore, data)
        local f, msg = io_open(getpath(username, host, datastore, nil, true), "w+");
        if not f then
                log("error", "Unable to write to "..datastore.." storage ('"..msg.."') for user: "..(username or "nil").."@"..(host or "nil"));
-               return;
+               return nil, "Error saving to storage";
        end
        f:write("return ");
        append(f, data);
@@ -196,15 +205,22 @@ end
 function list_load(username, host, datastore)
        local data, ret = loadfile(getpath(username, host, datastore, "list"));
        if not data then
-               log("debug", "Failed to load "..datastore.." storage ('"..ret.."') for user: "..(username or "nil").."@"..(host or "nil"));
-               return nil;
+               local mode = lfs.attributes(getpath(username, host, datastore, "list"), "mode");
+               if not mode then
+                       log("debug", "Assuming empty "..datastore.." storage ('"..ret.."') for user: "..(username or "nil").."@"..(host or "nil"));
+                       return nil;
+               else -- file exists, but can't be read
+                       -- TODO more detailed error checking and logging?
+                       log("error", "Failed to load "..datastore.." storage ('"..ret.."') for user: "..(username or "nil").."@"..(host or "nil"));
+                       return nil, "Error reading storage";
+               end
        end
        local items = {};
        setfenv(data, {item = function(i) t_insert(items, i); end});
        local success, ret = pcall(data);
        if not success then
                log("error", "Unable to load "..datastore.." storage ('"..ret.."') for user: "..(username or "nil").."@"..(host or "nil"));
-               return nil;
+               return nil, "Error reading storage";
        end
        return items;
 end