mod_admin_telnet: Don't rely on getpeerchain returning an empty list
[prosody.git] / tools / openfire2prosody.lua
1 #!/usr/bin/env lua
2 -- Prosody IM
3 -- Copyright (C) 2008-2009 Waqas Hussain
4 -- 
5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information.
7 --
8
9 package.path = package.path..";../?.lua";
10 package.cpath = package.cpath..";../?.so"; -- needed for util.pposix used in datamanager
11
12 -- ugly workaround for getting datamanager to work outside of prosody :(
13 prosody = { };
14 prosody.platform = "unknown";
15 if os.getenv("WINDIR") then
16         prosody.platform = "windows";
17 elseif package.config:sub(1,1) == "/" then
18         prosody.platform = "posix";
19 end
20
21 local parse_xml = require "util.xml".parse;
22
23 -----------------------------------------------------------------------
24
25 package.loaded["util.logger"] = {init = function() return function() end; end}
26 local dm = require "util.datamanager"
27 dm.set_data_path("data");
28
29 local arg = ...;
30 local help = "/? -? ? /h -h /help -help --help";
31 if not arg or help:find(arg, 1, true) then
32         print([[Openfire importer for Prosody
33
34   Usage: openfire2prosody.lua filename.xml hostname
35
36 ]]);
37         os.exit(1);
38 end
39
40 local host = select(2, ...) or "localhost";
41
42 local file = assert(io.open(arg));
43 local data = assert(file:read("*a"));
44 file:close();
45
46 local xml = assert(parse_xml(data));
47
48 assert(xml.name == "Openfire", "The input file is not an Openfire XML export");
49
50 local substatus_mapping = { ["0"] = "none", ["1"] = "to", ["2"] = "from", ["3"] = "both" };
51
52 for _,tag in ipairs(xml.tags) do
53         if tag.name == "User" then
54                 local username, password, roster;
55
56                 for _,tag in ipairs(tag.tags) do
57                         if tag.name == "Username" then
58                                 username = tag:get_text();
59                         elseif tag.name == "Password" then
60                                 password = tag:get_text();
61                         elseif tag.name == "Roster" then
62                                 roster = {};
63                                 local pending = {};
64                                 for _,tag in ipairs(tag.tags) do
65                                         if tag.name == "Item" then
66                                                 local jid = assert(tag.attr.jid, "Roster item has no JID");
67                                                 if tag.attr.substatus ~= "-1" then
68                                                         local item = {};
69                                                         item.name = tag.attr.name;
70                                                         item.subscription = assert(substatus_mapping[tag.attr.substatus], "invalid substatus");
71                                                         item.ask = tag.attr.askstatus == "0" and "subscribe" or nil;
72
73                                                         local groups = {};
74                                                         for _,tag in ipairs(tag) do
75                                                                 if tag.name == "Group" then
76                                                                         groups[tag:get_text()] = true;
77                                                                 end
78                                                         end
79                                                         item.groups = groups;
80                                                         roster[jid] = item;
81                                                 end
82                                                 if tag.attr.recvstatus == "1" then pending[jid] = true; end
83                                         end
84                                 end
85
86                                 if next(pending) then
87                                         roster[false] = { pending = pending };
88                                 end
89                         end
90                 end
91
92                 assert(username and password, "No username or password");
93
94                 local ret, err = dm.store(username, host, "accounts", {password = password});
95                 print("["..(err or "success").."] stored account: "..username.."@"..host.." = "..password);
96
97                 if roster then
98                         local ret, err = dm.store(username, host, "roster", roster);
99                         print("["..(err or "success").."] stored roster: "..username.."@"..host.." = "..password);
100                 end
101         end
102 end
103