#!/usr/bin/env lua
--- Prosody IM v0.1
--- Copyright (C) 2008 Matthew Wild
--- Copyright (C) 2008 Waqas Hussain
+-- Prosody IM v0.4
+-- Copyright (C) 2008-2009 Matthew Wild
+-- Copyright (C) 2008-2009 Waqas Hussain
--
--- This program is free software; you can redistribute it and/or
--- modify it under the terms of the GNU General Public License
--- as published by the Free Software Foundation; either version 2
--- of the License, or (at your option) any later version.
---
--- This program is distributed in the hope that it will be useful,
--- but WITHOUT ANY WARRANTY; without even the implied warranty of
--- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--- GNU General Public License for more details.
---
--- You should have received a copy of the GNU General Public License
--- along with this program; if not, write to the Free Software
--- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+-- This project is MIT/X11 licensed. Please see the
+-- COPYING file in the source package for more information.
--
\r
require "erlparse";\r
-require "serialize";\r
\r
package.path = package.path ..";../?.lua";\r
+local serialize = require "util.serialization".serialize;
local st = require "util.stanza";\r
package.loaded["util.logger"] = {init = function() return function() end; end}\r
local dm = require "util.datamanager"\r
-local data_path = "data";\r
-dm.set_data_path(data_path);\r
-\r
-local path_separator = "/"; if os.getenv("WINDIR") then path_separator = "\\" end\r
-local _mkdir = {}\r
-function mkdir(path)\r
- path = path:gsub("/", path_separator);\r
- --print("mkdir",path);\r
- local x = io.popen("mkdir "..path.." 2>&1"):read("*a");\r
-end\r
-function encode(s) return s and (s:gsub("%W", function (c) return string.format("%%%x", c:byte()); end)); end\r
-function getpath(username, host, datastore, ext)\r
- ext = ext or "dat";\r
- if username then\r
- return format("%s/%s/%s/%s.%s", data_path, encode(host), datastore, encode(username), ext);\r
- elseif host then\r
- return format("%s/%s/%s.%s", data_path, encode(host), datastore, ext);\r
- else\r
- return format("%s/%s.%s", data_path, datastore, ext);\r
- end\r
-end\r
-function mkdirs(host)\r
- if not _mkdir[host] then\r
- local host_dir = string.format("%s/%s", data_path, encode(host));\r
- mkdir(host_dir);\r
- mkdir(host_dir.."/accounts");\r
- mkdir(host_dir.."/vcard");\r
- mkdir(host_dir.."/roster");\r
- mkdir(host_dir.."/private");\r
- mkdir(host_dir.."/offline");\r
- _mkdir[host] = true;\r
- end\r
-end\r
-mkdir(data_path);\r
+dm.set_data_path("data");\r
\r
function build_stanza(tuple, stanza)\r
if tuple[1] == "xmlelement" then\r
elseif tuple[1] == "xmlcdata" then\r
stanza:text(tuple[2]);\r
else\r
- error("unknown element type: "..serialize.serialize(tuple));\r
+ error("unknown element type: "..serialize(tuple));\r
end\r
end\r
function build_time(tuple)\r
end\r
\r
function vcard(node, host, stanza)\r
- mkdirs(host);\r
local ret, err = dm.store(node, host, "vcard", st.preserialize(stanza));\r
print("["..(err or "success").."] vCard: "..node.."@"..host);\r
end\r
function password(node, host, password)\r
- mkdirs(host);\r
local ret, err = dm.store(node, host, "accounts", {password = password});\r
print("["..(err or "success").."] accounts: "..node.."@"..host.." = "..password);\r
end\r
-function roster(node, host, jid, item)\r
- mkdirs(host);\r
- local roster = dm.load(node, host, "roster") or {};\r
- roster[jid] = item;\r
- local ret, err = dm.store(node, host, "roster", roster);\r
- print("["..(err or "success").."] roster: " ..node.."@"..host.." - "..jid);\r
-end\r
+function roster(node, host, jid, item)
+ local roster = dm.load(node, host, "roster") or {};
+ roster[jid] = item;
+ local ret, err = dm.store(node, host, "roster", roster);
+ print("["..(err or "success").."] roster: " ..node.."@"..host.." - "..jid);
+end
+function roster_pending(node, host, jid)
+ local roster = dm.load(node, host, "roster") or {};
+ roster.pending = roster.pending or {};
+ roster.pending[jid] = true;
+ local ret, err = dm.store(node, host, "roster", roster);
+ print("["..(err or "success").."] roster: " ..node.."@"..host.." - "..jid);
+end
function private_storage(node, host, xmlns, stanza)\r
- mkdirs(host);\r
local private = dm.load(node, host, "private") or {};\r
private[xmlns] = st.preserialize(stanza);\r
local ret, err = dm.store(node, host, "private", private);\r
print("["..(err or "success").."] private: " ..node.."@"..host.." - "..xmlns);\r
end\r
function offline_msg(node, host, t, stanza)\r
- mkdirs(host);\r
stanza.attr.stamp = os.date("!%Y-%m-%dT%H:%M:%SZ", t);\r
stanza.attr.stamp_legacy = os.date("!%Y%m%dT%H:%M:%S", t);\r
local ret, err = dm.list_append(node, host, "offline", st.preserialize(stanza));\r
end;\r
roster = function(tuple)\r
local node = tuple[3][1]; local host = tuple[3][2];\r
- local contact = tuple[4][1].."@"..tuple[4][2];\r
+ local contact = (type(tuple[4][1]) == "table") and tuple[4][2] or tuple[4][1].."@"..tuple[4][2];\r
local name = tuple[5]; local subscription = tuple[6];\r
local ask = tuple[7]; local groups = tuple[8];\r
if type(name) ~= type("") then name = nil; end\r
- if ask == "none" then ask = nil; elseif ask == "out" then ask = "subscribe" else error(ask) end\r
+ if ask == "none" then ask = nil; elseif ask == "out" then ask = "subscribe" elseif ask == "in" then
+ roster_pending(node, host, contact);
+ return;
+ else error(ask) end\r
if subscription ~= "both" and subscription ~= "from" and subscription ~= "to" and subscription ~= "none" then error(subscription) end\r
local item = {name = name, ask = ask, subscription = subscription, groups = {}};\r
for _, g in ipairs(groups) do item.groups[g] = true; end\r
count = count + 1;\r
local name = item[1];\r
t[name] = (t[name] or 0) + 1;\r
- --print(count, serialize.serialize(item));\r
+ --print(count, serialize(item));\r
if filters[name] then filters[name](item); end\r
end\r
---print(serialize.serialize(t));\r
+--print(serialize(t));\r