/usr/lib/prosody/migrator/jabberd14.lua is in prosody 0.9.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | local lfs = require "lfs";
local st = require "util.stanza";
local parse_xml = require "util.xml".parse;
local os_getenv = os.getenv;
local io_open = io.open;
local assert = assert;
local ipairs = ipairs;
local coroutine = coroutine;
local print = print;
module "jabberd14"
local function is_dir(path) return lfs.attributes(path, "mode") == "directory"; end
local function is_file(path) return lfs.attributes(path, "mode") == "file"; end
local function clean_path(path)
return path:gsub("\\", "/"):gsub("//+", "/"):gsub("^~", os_getenv("HOME") or "~");
end
local function load_xml(path)
local f, err = io_open(path);
if not f then return f, err; end
local data = f:read("*a");
f:close();
if not data then return; end
return parse_xml(data);
end
local function load_spool_file(host, filename, path)
local xml = load_xml(path);
if not xml then return; end
local register_element = xml:get_child("query", "jabber:iq:register");
local username_element = register_element and register_element:get_child("username", "jabber:iq:register");
local password_element = register_element and register_element:get_child("password", "jabber:iq:auth");
local username = username_element and username_element:get_text();
local password = password_element and password_element:get_text();
if not username then
print("[warn] Missing /xdb/{jabber:iq:register}register/username> in file "..filename)
return;
elseif username..".xml" ~= filename then
print("[warn] Missing /xdb/{jabber:iq:register}register/username does not match filename "..filename);
return;
end
local userdata = {
user = username;
host = host;
stores = {};
};
local stores = userdata.stores;
stores.accounts = { password = password };
for i=1,#xml.tags do
local tag = xml.tags[i];
local xname = (tag.attr.xmlns or "")..":"..tag.name;
if tag.attr.j_private_flag == "1" and tag.attr.xmlns then
-- Private XML
stores.private = stores.private or {};
tag.attr.j_private_flag = nil;
stores.private[tag.attr.xmlns] = st.preserialize(tag);
elseif xname == "jabber:iq:auth:password" then
if stores.accounts.password ~= tag:get_text() then
if password then
print("[warn] conflicting passwords")
else
stores.accounts.password = tag:get_text();
end
end
elseif xname == "jabber:iq:register:query" then
-- already processed
elseif xname == "jabber:xdb:nslist:foo" then
-- ignore
elseif xname == "jabber:iq:auth:0k:zerok" then
-- ignore
elseif xname == "jabber:iq:roster:query" then
-- Roster
local roster = {};
local subscription_types = { from = true, to = true, both = true, none = true };
for _,item_element in ipairs(tag.tags) do
assert(item_element.name == "item");
assert(item_element.attr.jid);
assert(subscription_types[item_element.attr.subscription]);
assert((item_element.attr.ask or "subscribe") == "subscribe")
if item_element.name == "item" then
local groups = {};
for _,group_element in ipairs(item_element.tags) do
assert(group_element.name == "group");
groups[group_element:get_text()] = true;
end
local item = {
name = item_element.attr.name;
subscription = item_element.attr.subscription;
ask = item_element.attr.ask;
groups = groups;
};
roster[item_element.attr.jid] = item;
end
end
stores.roster = roster;
elseif xname == "jabber:iq:last:query" then
-- Last activity
elseif xname == "jabber:x:offline:foo" then
-- Offline messages
elseif xname == "vcard-temp:vCard" then
-- vCards
stores.vcard = st.preserialize(tag);
else
print("[warn] Unknown tag: "..xname);
end
end
return userdata;
end
local function loop_over_users(path, host, cb)
for file in lfs.dir(path) do
if file:match("%.xml$") then
local user = load_spool_file(host, file, path.."/"..file);
if user then cb(user); end
end
end
end
local function loop_over_hosts(path, cb)
for host in lfs.dir(path) do
if host ~= "." and host ~= ".." and is_dir(path.."/"..host) then
loop_over_users(path.."/"..host, host, cb);
end
end
end
function reader(input)
local path = clean_path(assert(input.path, "no input.path specified"));
assert(is_dir(path), "input.path is not a directory");
if input.host then
return coroutine.wrap(function() loop_over_users(input.path, input.host, coroutine.yield) end);
else
return coroutine.wrap(function() loop_over_hosts(input.path, coroutine.yield) end);
end
end
return _M;
|