Merge 0.9->0.10
[prosody.git] / core / configmanager.lua
index 9720f48ac1156ed243b3d324f1cb968273c12ce9..48f039eac8c3eea55ebe45c64efe23b10cdb93e7 100644 (file)
@@ -1,7 +1,7 @@
 -- Prosody IM
 -- Copyright (C) 2008-2010 Matthew Wild
 -- Copyright (C) 2008-2010 Waqas Hussain
--- 
+--
 -- This project is MIT/X11 licensed. Please see the
 -- COPYING file in the source package for more information.
 --
@@ -14,11 +14,18 @@ local format, math_max = string.format, math.max;
 local fire_event = prosody and prosody.events.fire_event or function () end;
 
 local envload = require"util.envload".envload;
-local lfs = require "lfs";
+local deps = require"util.dependencies";
+local resolve_relative_path = require"util.paths".resolve_relative_path;
+local glob_to_pattern = require"util.paths".glob_to_pattern;
 local path_sep = package.config:sub(1,1);
 
+local have_encodings, encodings = pcall(require, "util.encodings");
+local nameprep = have_encodings and encodings.stringprep.nameprep or function (host) return host:lower(); end
+
 module "configmanager"
 
+_M.resolve_relative_path = resolve_relative_path; -- COMPAT
+
 local parsers = {};
 
 local config_mt = { __index = function (t, k) return rawget(t, "*"); end};
@@ -66,41 +73,6 @@ function _M.set(host, key, value, _oldvalue)
        return set(config, host, key, value);
 end
 
--- Helper function to resolve relative paths (needed by config)
-do
-       function resolve_relative_path(parent_path, path)
-               if path then
-                       -- Some normalization
-                       parent_path = parent_path:gsub("%"..path_sep.."+$", "");
-                       path = path:gsub("^%.%"..path_sep.."+", "");
-                       
-                       local is_relative;
-                       if path_sep == "/" and path:sub(1,1) ~= "/" then
-                               is_relative = true;
-                       elseif path_sep == "\\" and (path:sub(1,1) ~= "/" and (path:sub(2,3) ~= ":\\" or path:sub(2,3) ~= ":/")) then
-                               is_relative = true;
-                       end
-                       if is_relative then
-                               return parent_path..path_sep..path;
-                       end
-               end
-               return path;
-       end     
-end
-
--- Helper function to convert a glob to a Lua pattern
-local function glob_to_pattern(glob)
-       return "^"..glob:gsub("[%p*?]", function (c)
-               if c == "*" then
-                       return ".*";
-               elseif c == "?" then
-                       return ".";
-               else
-                       return "%"..c;
-               end
-       end).."$";
-end
-
 function load(filename, format)
        format = format or filename:match("%w+$");
 
@@ -167,9 +139,10 @@ do
                                        set(config, env.__currenthost or "*", k, v);
                                end
                });
-               
+
                rawset(env, "__currenthost", "*") -- Default is global
                function env.VirtualHost(name)
+                       name = nameprep(name);
                        if rawget(config, name) and rawget(config[name], "component_module") then
                                error(format("Host %q clashes with previously defined %s Component %q, for services use a sub-domain like conference.%s",
                                        name, config[name].component_module:gsub("^%a+$", { component = "external", muc = "MUC"}), name, name), 0);
@@ -185,8 +158,9 @@ do
                        end;
                end
                env.Host, env.host = env.VirtualHost, env.VirtualHost;
-               
+
                function env.Component(name)
+                       name = nameprep(name);
                        if rawget(config, name) and rawget(config[name], "defined") and not rawget(config[name], "component_module") then
                                error(format("Component %q clashes with previously defined Host %q, for services use a sub-domain like conference.%s",
                                        name, name, name), 0);
@@ -201,7 +175,7 @@ do
                                        set(config, name or "*", option_name, option_value);
                                end
                        end
-       
+
                        return function (module)
                                        if type(module) == "string" then
                                                set(config, name, "component_module", module);
@@ -211,9 +185,13 @@ do
                                end
                end
                env.component = env.Component;
-               
+
                function env.Include(file)
                        if file:match("[*?]") then
+                               local lfs = deps.softreq "lfs";
+                               if not lfs then
+                                       error(format("Error expanding wildcard pattern in Include %q - LuaFileSystem not available", file));
+                               end
                                local path_pos, glob = file:match("()([^"..path_sep.."]+)$");
                                local path = file:sub(1, math_max(path_pos-2,0));
                                local config_path = config_file:gsub("[^"..path_sep.."]+$", "");
@@ -240,26 +218,26 @@ do
                        end
                end
                env.include = env.Include;
-               
+
                function env.RunScript(file)
                        return dofile(resolve_relative_path(config_file:gsub("[^"..path_sep.."]+$", ""), file));
                end
-               
+
                local chunk, err = envload(data, "@"..config_file, env);
-               
+
                if not chunk then
                        return nil, err;
                end
-               
+
                local ok, err = pcall(chunk);
-               
+
                if not ok then
                        return nil, err;
                end
-               
+
                return true;
        end
-       
+
 end
 
 return _M;