diff -r 984b3ba0ea99 -r 9e0e56393978 verse.lua
--- a/verse.lua Mon Sep 10 09:50:42 2018 +0100
+++ b/verse.lua Mon Sep 10 09:51:01 2018 +0100
@@ -1,217 +1,118 @@
package.preload['util.encodings']=(function(...)
+local _ENV=_ENV;
+local function a(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
local function e()
error("Function not implemented");
end
local e=require"mime";
-return{
+a"encodings"
stringprep={};
base64={encode=e.b64,decode=e.unb64};
-};
+return _M;
end)
package.preload['util.hashes']=(function(...)
-local t,e=pcall(require,"crypto");
-if t then
-local t={};
-local o=e.digest;
-local function s(e)
-return function(t,a)
-return o(e,t,not a);
-end
-end
-local e=e.hmac.digest;
-local function n(o)
-return function(i,a,t)
-return e(o,a,i,not t);
-end
-end
-local e={"md5","sha1","sha256","sha512"};
-for a,e in ipairs(e)do
-t[e]=s(e);
-t["hmac_"..e]=n(e);
-end
-return t;
-else
-local t=require"util.sha1".sha1;
-local s=require"bit".bxor;
-local a=string.rep;
-local n=string.char;
-local d=string.byte;
-local i=table.concat;
-local function r(e,h,r)
-if#e>64 then
-e=t(e);
-elseif#e<64 then
-e=e..a("\0",64-#e);
-end
-local o,a={},{}
-for t=1,64 do
-local e=d(e,t)
-o[t]=n(s(e,92));
-a[t]=n(s(e,54));
-end
-o=i(o);
-a=i(a);
-return t(o..t(a..h),r);
-end
-return{
-sha1=t;
-hmac_sha1=r;
-};
-end
-end)
-package.preload['util.sha1']=(function(...)
-local r=string.len
-local o=string.char
-local j=string.byte
-local q=string.sub
-local h=math.floor
-local t=require"bit"
-local g=t.bnot
-local e=t.band
-local y=t.bor
-local n=t.bxor
-local a=t.lshift
-local i=t.rshift
-local m,d,c,l,u
-local function p(e,t)
-return a(e,t)+i(e,32-t)
-end
-local function s(i)
-local t,a
-local t=""
-for n=1,8 do
-a=e(i,15)
-if(a<10)then
-t=o(a+48)..t
-else
-t=o(a+87)..t
-end
-i=h(i/16)
-end
-return t
-end
-local function k(t)
-local i,a
-local n=""
-i=r(t)*8
-t=t..o(128)
-a=56-e(r(t),63)
-if(a<0)then
-a=a+64
-end
-for e=1,a do
-t=t..o(0)
-end
-for t=1,8 do
-n=o(e(i,255))..n
-i=h(i/256)
-end
-return t..n
-end
-local function b(f)
-local s,t,i,o,w,h,r,v
-local a,a
-local a={}
-while(f~="")do
-for e=0,15 do
-a[e]=0
-for t=1,4 do
-a[e]=a[e]*256+j(f,e*4+t)
-end
-end
-for e=16,79 do
-a[e]=p(n(n(a[e-3],a[e-8]),n(a[e-14],a[e-16])),1)
-end
-s=m
-t=d
-i=c
-o=l
-w=u
-for d=0,79 do
-if(d<20)then
-h=y(e(t,i),e(g(t),o))
-r=1518500249
-elseif(d<40)then
-h=n(n(t,i),o)
-r=1859775393
-elseif(d<60)then
-h=y(y(e(t,i),e(t,o)),e(i,o))
-r=2400959708
-else
-h=n(n(t,i),o)
-r=3395469782
-end
-v=p(s,5)+h+w+r+a[d]
-w=o
-o=i
-i=p(t,30)
-t=s
-s=v
-end
-m=e(m+s,4294967295)
-d=e(d+t,4294967295)
-c=e(c+i,4294967295)
-l=e(l+o,4294967295)
-u=e(u+w,4294967295)
-f=q(f,65)
-end
-end
-local function t(e,t)
-e=k(e)
-m=1732584193
-d=4023233417
-c=2562383102
-l=271733878
-u=3285377520
-b(e)
-local e=s(m)..s(d)..s(c)
-..s(l)..s(u);
-if t then
-return e;
-else
-return(e:gsub("..",function(e)
-return string.char(tonumber(e,16));
-end));
-end
-end
-_G.sha1={sha1=t};
-return _G.sha1;
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
+local function t(t,e)
+error("Hash method "..e.." not available",2);
+end
+local e=setmetatable({},{__index=t});
+local function t(e,o)
+local e,a=pcall(require,e);
+if e then o(a);end
+end
+t("bgcrypto.md5",function(t)
+e.md5=t.digest;
+e.hmac_md5=t.hmac.digest;
+end);
+t("bgcrypto.sha1",function(t)
+e.sha1=t.digest;
+e.hmac_sha1=t.hmac.digest;
+e.scram_Hi_sha1=function(e,a,o)return t.pbkdf2(e,a,o,20);end;
+end);
+t("bgcrypto.sha256",function(t)
+e.sha256=t.digest;
+e.hmac_sha256=t.hmac.digest;
+end);
+t("bgcrypto.sha512",function(t)
+e.sha512=t.digest;
+e.hmac_sha512=t.hmac.digest;
+end);
+t("sha1",function(t)
+e.sha1=function(e,a)
+if a then
+return t.sha1(e);
+else
+return(t.binary(e));
+end
+end;
+end);
+return e;
end)
package.preload['lib.adhoc']=(function(...)
-local s,r=require"util.stanza",require"util.uuid";
+local _ENV=_ENV;
+local function r(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
+local s,i=require"util.stanza",require"util.uuid";
local e="http://jabber.org/protocol/commands";
-local i={}
+local n={}
local h={};
-local function n(o,i,t,a)
-local e=s.stanza("command",{xmlns=e,node=o.node,status=i});
+local function o(i,o,t,a)
+local e=s.stanza("command",{xmlns=e,node=i.node,status=o});
if t then e.attr.sessionid=t;end
if a then e.attr.action=a;end
return e;
end
-function h.new(o,a,t,e)
-return{name=o,node=a,handler=t,cmdtag=n,permission=(e or"user")};
+function h.new(a,i,e,t)
+return{name=a,node=i,handler=e,cmdtag=o,permission=(t or"user")};
end
function h.handle_cmd(o,h,t)
-local e=t.tags[1].attr.sessionid or r.generate();
+local e=t.tags[1].attr.sessionid or i.generate();
local a={};
a.to=t.attr.to;
a.from=t.attr.from;
a.action=t.tags[1].attr.action or"execute";
a.form=t.tags[1]:child_with_ns("jabber:x:data");
-local a,n=o:handler(a,i[e]);
-i[e]=n;
-local n=s.reply(t);
+local a,i=o:handler(a,n[e]);
+n[e]=i;
+local i=s.reply(t);
local t;
if a.status=="completed"then
-i[e]=nil;
+n[e]=nil;
t=o:cmdtag("completed",e);
elseif a.status=="canceled"then
-i[e]=nil;
+n[e]=nil;
t=o:cmdtag("canceled",e);
elseif a.status=="error"then
-i[e]=nil;
-n=s.error_reply(n,a.error.type,a.error.condition,a.error.message);
-h.send(n);
+n[e]=nil;
+i=s.error_reply(i,a.error.type,a.error.condition,a.error.message);
+h.send(i);
return true;
else
t=o:cmdtag("executing",e);
@@ -229,7 +130,7 @@
if(e=="prev")or(e=="next")or(e=="complete")then
a:tag(e):up();
else
-module:log("error",'Command "'..o.name..
+r:log("error",'Command "'..o.name..
'" at node "'..o.node..'" provided an invalid action "'..e..'"');
end
end
@@ -242,57 +143,66 @@
t:add_child(e);
end
end
-n:add_child(t);
-h.send(n);
+i:add_child(t);
+h.send(i);
return true;
end
return h;
end)
package.preload['util.stanza']=(function(...)
+local _ENV=_ENV;
+local function h(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
local t=table.insert;
-local d=table.remove;
-local y=table.concat;
-local h=string.format;
-local l=string.match;
-local f=tostring;
+local s=table.remove;
+local p=table.concat;
+local r=string.format;
+local u=string.match;
+local w=tostring;
local m=setmetatable;
-local p=getmetatable;
local n=pairs;
-local o=ipairs;
-local i=type;
-local b=string.gsub;
-local w=string.sub;
-local c=string.find;
+local i=ipairs;
+local o=type;
+local y=string.gsub;
+local l=string.sub;
+local f=string.find;
local e=os;
-local u=not e.getenv("WINDIR");
-local r,a;
-if u then
+local c=not e.getenv("WINDIR");
+local d,a;
+if c then
local t,e=pcall(require,"util.termcolours");
if t then
-r,a=e.getstyle,e.getstring;
-else
-u=nil;
+d,a=e.getstyle,e.getstring;
+else
+c=nil;
end
end
local v="urn:ietf:params:xml:ns:xmpp-stanzas";
-local e=nil;
-local e={__type="stanza"};
-e.__index=e;
-local function s(t,a)
-local t={name=t,attr=a or{},tags={}};
+h"stanza"
+stanza_mt={__type="stanza"};
+stanza_mt.__index=stanza_mt;
+local e=stanza_mt;
+function stanza(a,t)
+local t={name=a,attr=t or{},tags={}};
return m(t,e);
end
-local function k(t)
-return p(t)==e;
-end
+local h=stanza;
function e:query(e)
return self:tag("query",{xmlns=e});
end
function e:body(t,e)
return self:tag("body",e):text(t);
end
-function e:tag(e,a)
-local a=s(e,a);
+function e:tag(a,e)
+local a=h(a,e);
local e=self.last_add;
if not e then e={};self.last_add=e;end
(e[#e]or self):add_direct_child(a);
@@ -306,7 +216,7 @@
end
function e:up()
local e=self.last_add;
-if e then d(e);end
+if e then s(e);end
return self;
end
function e:reset()
@@ -314,7 +224,7 @@
return self;
end
function e:add_direct_child(e)
-if i(e)=="table"then
+if o(e)=="table"then
t(self.tags,e);
end
t(self,e);
@@ -325,7 +235,7 @@
return self;
end
function e:get_child(t,a)
-for o,e in o(self.tags)do
+for o,e in i(self.tags)do
if(not t or e.name==t)
and((not a and self.attr.xmlns==e.attr.xmlns)
or e.attr.xmlns==a)then
@@ -333,20 +243,20 @@
end
end
end
-function e:get_child_text(t,e)
-local e=self:get_child(t,e);
+function e:get_child_text(e,t)
+local e=self:get_child(e,t);
if e then
return e:get_text();
end
return nil;
end
function e:child_with_name(t)
-for a,e in o(self.tags)do
+for a,e in i(self.tags)do
if e.name==t then return e;end
end
end
function e:child_with_ns(t)
-for a,e in o(self.tags)do
+for a,e in i(self.tags)do
if e.attr.xmlns==t then return e;end
end
end
@@ -357,15 +267,15 @@
return t[e];
end,self,e;
end
-function e:childtags(o,i)
+function e:childtags(i,o)
local e=self.tags;
local a,t=1,#e;
return function()
for t=a,t do
local e=e[t];
-if(not o or e.name==o)
-and((not i and self.attr.xmlns==e.attr.xmlns)
-or e.attr.xmlns==i)then
+if(not i or e.name==i)
+and((not o and self.attr.xmlns==e.attr.xmlns)
+or e.attr.xmlns==o)then
a=t+1;
return e;
end
@@ -373,27 +283,27 @@
end;
end
function e:maptags(i)
-local o,e=self.tags,1;
+local o,t=self.tags,1;
local n,a=#self,#o;
-local t=1;
-while e<=a and a>0 do
-if self[t]==o[e]then
-local i=i(self[t]);
+local e=1;
+while t<=a and a>0 do
+if self[e]==o[t]then
+local i=i(self[e]);
if i==nil then
-d(self,t);
-d(o,e);
+s(self,e);
+s(o,t);
n=n-1;
a=a-1;
+e=e-1;
t=t-1;
-e=e-1;
-else
-self[t]=i;
-o[e]=i;
+else
+self[e]=i;
+o[t]=i;
+end
+t=t+1;
end
e=e+1;
end
-t=t+1;
-end
return self;
end
function e:find(a)
@@ -401,13 +311,13 @@
local s=#a+1;
repeat
local o,t,n;
-local i=w(a,e,e);
+local i=l(a,e,e);
if i=="@"then
-return self.attr[w(a,e+1)];
+return self.attr[l(a,e+1)];
elseif i=="{"then
-o,e=l(a,"^([^}]+)}()",e+1);
-end
-t,n,e=l(a,"^([^@/#]*)([/#]?)()",e);
+o,e=u(a,"^([^}]+)}()",e+1);
+end
+t,n,e=u(a,"^([^@/#]*)([/#]?)()",e);
t=t~=""and t or nil;
if e==s then
if n=="#"then
@@ -418,17 +328,21 @@
self=self:get_child(t,o);
until not self
end
-local w={["'"]="'",["\""]=""",["<"]="<",[">"]=">",["&"]="&"};
-local function d(e)return(b(e,"['&<>\"]",w));end
-local function w(o,e,h,a,r)
+local l
+do
+local e={["'"]="'",["\""]=""",["<"]="<",[">"]=">",["&"]="&"};
+function l(t)return(y(t,"['&<>\"]",e));end
+_M.xml_escape=l;
+end
+local function y(o,e,h,a,r)
local i=0;
local s=o.name
t(e,"<"..s);
for o,n in n(o.attr)do
-if c(o,"\1",1,true)then
-local o,s=l(o,"^([^\1]*)\1?(.*)$");
+if f(o,"\1",1,true)then
+local s,o=u(o,"^([^\1]*)\1?(.*)$");
i=i+1;
-t(e," xmlns:ns"..i.."='"..a(o).."' ".."ns"..i..":"..s.."='"..a(n).."'");
+t(e," xmlns:ns"..i.."='"..a(s).."' ".."ns"..i..":"..o.."='"..a(n).."'");
elseif not(o=="xmlns"and n==r)then
t(e," "..o.."='"..a(n).."'");
end
@@ -451,280 +365,288 @@
end
function e.__tostring(t)
local e={};
-w(t,e,w,d,nil);
-return y(e);
-end
-function e.top_tag(e)
-local t="";
-if e.attr then
-for e,a in n(e.attr)do if i(e)=="string"then t=t..h(" %s='%s'",e,d(f(a)));end end
-end
-return h("<%s%s>",e.name,t);
+y(t,e,y,l,nil);
+return p(e);
+end
+function e.top_tag(t)
+local e="";
+if t.attr then
+for t,a in n(t.attr)do if o(t)=="string"then e=e..r(" %s='%s'",t,l(w(a)));end end
+end
+return r("<%s%s>",t.name,e);
end
function e.get_text(e)
if#e.tags==0 then
-return y(e);
+return p(e);
end
end
function e.get_error(e)
-local i,t,a;
+local o,a,t;
local e=e:get_child("error");
if not e then
return nil,nil,nil;
end
-i=e.attr.type;
-for o,e in o(e.tags)do
+o=e.attr.type;
+for o,e in i(e.tags)do
if e.attr.xmlns==v then
-if not a and e.name=="text"then
-a=e:get_text();
-elseif not t then
-t=e.name;
-end
-if t and a then
+if not t and e.name=="text"then
+t=e:get_text();
+elseif not a then
+a=e.name;
+end
+if a and t then
break;
end
end
end
-return i,t or"undefined-condition",a;
-end
-local w=0;
-local function y()
-w=w+1;
-return"lx"..w;
-end
-local function w(e)
+return o,a or"undefined-condition",t;
+end
+do
+local e=0;
+function new_id()
+e=e+1;
+return"lx"..e;
+end
+end
+function preserialize(e)
local a={name=e.name,attr=e.attr};
-for o,e in o(e)do
-if i(e)=="table"then
-t(a,w(e));
+for i,e in i(e)do
+if o(e)=="table"then
+t(a,preserialize(e));
else
t(a,e);
end
end
return a;
end
-local function p(a)
+function deserialize(a)
if a then
local s=a.attr;
for e=1,#s do s[e]=nil;end
local h={};
for e in n(s)do
-if c(e,"|",1,true)and not c(e,"\1",1,true)then
-local a,t=l(e,"^([^|]+)|(.+)$");
-h[a.."\1"..t]=s[e];
+if f(e,"|",1,true)and not f(e,"\1",1,true)then
+local t,a=u(e,"^([^|]+)|(.+)$");
+h[t.."\1"..a]=s[e];
s[e]=nil;
end
end
-for e,t in n(h)do
-s[e]=t;
+for t,e in n(h)do
+s[t]=e;
end
m(a,e);
-for t,e in o(a)do
-if i(e)=="table"then
-p(e);
+for t,e in i(a)do
+if o(e)=="table"then
+deserialize(e);
end
end
if not a.tags then
-local e={};
-for n,o in o(a)do
-if i(o)=="table"then
-t(e,o);
-end
-end
-a.tags=e;
+local n={};
+for i,e in i(a)do
+if o(e)=="table"then
+t(n,e);
+end
+end
+a.tags=n;
end
end
return a;
end
-local function l(a)
-local o,i={},{};
-for t,e in n(a.attr)do o[t]=e;end
-local o={name=a.name,attr=o,tags=i};
+local function s(a)
+local i,o={},{};
+for t,e in n(a.attr)do i[t]=e;end
+local i={name=a.name,attr=i,tags=o};
for e=1,#a do
local e=a[e];
if e.name then
-e=l(e);
-t(i,e);
-end
+e=s(e);
t(o,e);
end
-return m(o,e);
-end
-local function b(t,e)
+t(i,e);
+end
+return m(i,e);
+end
+clone=s;
+function message(t,e)
if not e then
-return s("message",t);
-else
-return s("message",t):tag("body"):text(e):up();
-end
-end
-local function g(e)
-if e and not e.id then e.id=y();end
-return s("iq",e or{id=y()});
-end
-local function m(e)
-return s(e.name,e.attr and{to=e.attr.from,from=e.attr.to,id=e.attr.id,type=((e.name=="iq"and"result")or e.attr.type)});
-end
-local c={xmlns=v};
-local function v(e,o,a,t)
-local e=m(e);
+return h("message",t);
+else
+return h("message",t):tag("body"):text(e):up();
+end
+end
+function iq(e)
+if e and not e.id then e.id=new_id();end
+return h("iq",e or{id=new_id()});
+end
+function reply(e)
+return h(e.name,e.attr and{to=e.attr.from,from=e.attr.to,id=e.attr.id,type=((e.name=="iq"and"result")or e.attr.type)});
+end
+do
+local t={xmlns=v};
+function error_reply(e,o,i,a)
+local e=reply(e);
e.attr.type="error";
e:tag("error",{type=o})
-:tag(a,c):up();
-if t then e:tag("text",c):text(t):up();end
-return e;
-end
-local function c(e)
-return s("presence",e);
-end
-if u then
-local s=r("yellow");
-local u=r("red");
-local l=r("red");
-local t=r("magenta");
-local r=" "..a(s,"%s")..a(t,"=")..a(u,"'%s'");
-local s=a(t,"<")..a(l,"%s").."%s"..a(t,">");
-local l=s.."%s"..a(t,"")..a(l,"%s")..a(t,">");
-function e.pretty_print(t)
-local e="";
-for a,t in o(t)do
-if i(t)=="string"then
-e=e..d(t);
-else
-e=e..t:pretty_print();
+:tag(i,t):up();
+if(a)then e:tag("text",t):text(a):up();end
+return e;
+end
+end
+function presence(e)
+return h("presence",e);
+end
+if c then
+local s=d("yellow");
+local h=d("red");
+local u=d("red");
+local t=d("magenta");
+local h=" "..a(s,"%s")..a(t,"=")..a(h,"'%s'");
+local s=a(t,"<")..a(u,"%s").."%s"..a(t,">");
+local d=s.."%s"..a(t,"")..a(u,"%s")..a(t,">");
+function e.pretty_print(e)
+local t="";
+for a,e in i(e)do
+if o(e)=="string"then
+t=t..l(e);
+else
+t=t..e:pretty_print();
end
end
local a="";
-if t.attr then
-for e,t in n(t.attr)do if i(e)=="string"then a=a..h(r,e,f(t));end end
-end
-return h(l,t.name,a,e,t.name);
-end
-function e.pretty_top_tag(t)
-local e="";
-if t.attr then
-for t,a in n(t.attr)do if i(t)=="string"then e=e..h(r,t,f(a));end end
-end
-return h(s,t.name,e);
+if e.attr then
+for e,t in n(e.attr)do if o(e)=="string"then a=a..r(h,e,w(t));end end
+end
+return r(d,e.name,a,t,e.name);
+end
+function e.pretty_top_tag(e)
+local t="";
+if e.attr then
+for e,a in n(e.attr)do if o(e)=="string"then t=t..r(h,e,w(a));end end
+end
+return r(s,e.name,t);
end
else
e.pretty_print=e.__tostring;
e.pretty_top_tag=e.top_tag;
end
-return{
-stanza_mt=e;
-stanza=s;
-is_stanza=k;
-new_id=y;
-preserialize=w;
-deserialize=p;
-clone=l;
-message=b;
-iq=g;
-reply=m;
-error_reply=v;
-presence=c;
-xml_escape=d;
-};
+return _M;
end)
package.preload['util.timer']=(function(...)
+local _ENV=_ENV;
+local function o(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
local a=require"net.server";
-local s=math.min
-local l=math.huge
-local n=require"util.time".now
-local h=table.insert;
-local r=pairs;
-local d=type;
-local i={};
+local h=math.min
+local u=math.huge
+local i=require"socket".gettime;
+local d=table.insert;
+local l=pairs;
+local r=type;
+local s={};
local e={};
-local t=nil;
+o"timer"
local t;
if not a.event then
-function t(o,i)
-local n=n();
-o=o+n;
-if o>=n then
-h(e,{o,i});
-else
-local e=i(n);
-if e and d(e)=="number"then
-return t(e,i);
+function t(o,n)
+local i=i();
+o=o+i;
+if o>=i then
+d(e,{o,n});
+else
+local e=n(i);
+if e and r(e)=="number"then
+return t(e,n);
end
end
end
a._addtimer(function()
-local a=n();
+local a=i();
if#e>0 then
-for a,t in r(e)do
-h(i,t);
+for a,t in l(e)do
+d(s,t);
end
e={};
end
-local e=l;
-for h,o in r(i)do
-local o,n=o[1],o[2];
+local e=u;
+for n,o in l(s)do
+local o,i=o[1],o[2];
if o<=a then
-i[h]=nil;
-local a=n(a);
-if d(a)=="number"then
-t(a,n);
-e=s(e,a);
-end
-else
-e=s(e,o-a);
+s[n]=nil;
+local a=i(a);
+if r(a)=="number"then
+t(a,i);
+e=h(e,a);
+end
+else
+e=h(e,o-a);
end
end
return e;
end);
else
local e=a.event;
-local o=a.event_base;
-local i=(e.core and e.core.LEAVE)or-1;
-function t(a,e)
+local n=a.event_base;
+local a=(e.core and e.core.LEAVE)or-1;
+function t(o,e)
local t;
-t=o:addevent(nil,0,function()
-local e=e(n());
+t=n:addevent(nil,0,function()
+local e=e(i());
if e then
return 0,e;
elseif t then
-return i;
-end
-end
-,a);
-end
-end
-return{
+return a;
+end
+end
+,o);
+end
+end
add_task=t;
-};
+return _M;
end)
package.preload['util.termcolours']=(function(...)
-local h,s=table.concat,table.insert;
-local a,r=string.char,string.format;
-local o=tonumber;
-local d=ipairs;
+local _ENV=_ENV;
+local function a(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
+local n,i=table.concat,table.insert;
+local t,s=string.char,string.format;
+local h=tonumber;
+local c=ipairs;
local l=io.write;
-local i=math.floor;
-local u=type;
-local m=setmetatable;
-local f=pairs;
-local t;
+local e;
if os.getenv("WINDIR")then
-t=require"util.windows";
-end
-local n=t and t.get_consolecolor and t.get_consolecolor();
-local e=nil;
-local e={
+e=require"util.windows";
+end
+local o=e and e.get_consolecolor and e.get_consolecolor();
+a"termcolours"
+local u={
reset=0;bright=1,dim=2,underscore=4,blink=5,reverse=7,hidden=8;
black=30;red=31;green=32;yellow=33;blue=34;magenta=35;cyan=36;white=37;
["black background"]=40;["red background"]=41;["green background"]=42;["yellow background"]=43;["blue background"]=44;["magenta background"]=45;["cyan background"]=46;["white background"]=47;
bold=1,dark=2,underline=4,underlined=4,normal=0;
}
-local c={
-["0"]=n,
+local d={
+["0"]=o,
["1"]=7+8,
["1;33"]=2+4+8,
["1;31"]=4+8
}
-local p={
+local r={
[1]="font-weight: bold",[2]="opacity: 0.5",[4]="text-decoration: underline",[8]="visibility: hidden",
[30]="color:black",[31]="color:red",[32]="color:green",[33]="color:#FFD700",
[34]="color:blue",[35]="color: magenta",[36]="color:cyan",[37]="color: white",
@@ -732,127 +654,123 @@
[43]="background-color:yellow",[44]="background-color:blue",[45]="background-color: magenta",
[46]="background-color:cyan",[47]="background-color: white";
};
-local a=a(27).."[%sm%s"..a(27).."[0m";
-local function y(e,t)
+local a=t(27).."[%sm%s"..t(27).."[0m";
+function getstring(e,t)
if e then
-return r(a,e,t);
+return s(a,e,t);
else
return t;
end
end
-local function w(e)
-return i(e*3/32)+232;
-end
-local function r(e,t,a)
-if e==t and t==a then
-return w(e);
-end
-e=i(e*3/128);
-t=i(t*3/128);
-a=i(a*3/128);
-return 16+(e*36)+(t*6)+(a);
-end
-local function a(e)
-local t=o(e:sub(1,2),16);
-local a=o(e:sub(3,4),16);
-local e=o(e:sub(5,6),16);
-return t,a,e;
-end
-m(e,{__index=function(t,e)
-if u(e)=="string"and e:find("%x%x%x%x%x%x")==1 then
-local t=e:sub(7)==" background"and"48;5;"or"38;5;";
-return t..r(a(e));
-end
-end});
-local a={
-red="ff0000";fuchsia="ff00ff";green="008000";white="ffffff";
-lime="00ff00";yellow="ffff00";purple="800080";blue="0000ff";
-aqua="00ffff";olive="808000";black="000000";navy="000080";
-teal="008080";silver="c0c0c0";maroon="800000";gray="808080";
-}
-for t,a in f(a)do
-e[t]=e[t]or e[a];
-t,a=t.." background",a.." background"
-e[t]=e[t]or e[a];
-end
-local function r(...)
-local t,a={...},{};
-for o,t in d(t)do
-t=e[t];
-if t then
-s(a,t);
-end
-end
-return h(a,";");
+function getstyle(...)
+local e,t={...},{};
+for a,e in c(e)do
+e=u[e];
+if e then
+i(t,e);
+end
+end
+return n(t,";");
end
local a="0";
-local function i(e)
+function setstyle(e)
e=e or"0";
if e~=a then
l("\27["..e.."m");
a=e;
end
end
-if t then
-function i(e)
-e=e or"0";
-if e~=a then
-t.set_consolecolor(c[e]or n);
-a=e;
-end
-end
-if not n then
-function i()end
-end
-end
-local function a(t)
-if t=="0"then return"";end
-local e={};
-for t in t:gmatch("[^;]+")do
-s(e,p[o(t)]);
-end
-return"";
-end
-local function e(e)
+if e then
+function setstyle(t)
+t=t or"0";
+if t~=a then
+e.set_consolecolor(d[t]or o);
+a=t;
+end
+end
+if not o then
+function setstyle(e)end
+end
+end
+local function a(e)
+if e=="0"then return"";end
+local t={};
+for e in e:gmatch("[^;]+")do
+i(t,r[h(e)]);
+end
+return"";
+end
+function tohtml(e)
return e:gsub("\027%[(.-)m",a);
end
-return{
-getstring=y;
-getstyle=r;
-setstyle=i;
-tohtml=e;
-};
+return _M;
end)
package.preload['util.uuid']=(function(...)
-local a=require"util.random";
-local t=a.bytes;
-local o=require"util.hex".to;
-local i=math.ceil;
-local function e(e)
-return o(t(i(e/2))):sub(1,e);
-end
+local _ENV=_ENV;
+local function o(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
+local n=tostring;
+local e=os.time;
+local a=os.clock;
+local i=require"util.hashes".sha1;
+o"uuid"
+local t=0;
local function o()
+local e=e();
+if t>=e then e=t+1;end
+t=e;
+return e;
+end
+local function t(e)
+return i(e..a()..n({}),true);
+end
+local e=t(o());
+local function a(a)
+e=t(e..a);
+end
+local function t(t)
+if#e";
end
return e;
end
-local y={
+local w={
LOC=e.LOC_tostring;
MX=function(e)
return a.format('%2i %s',e.pref,e.mx);
@@ -972,33 +890,40 @@
};
local x={};
function x.__tostring(e)
-local t=(y[e.type]or j)(e);
+local t=(w[e.type]or j)(e);
return a.format('%2s %-5s %6i %-28s %s',e.class,e.type,e.ttl,e.name,t);
end
local j={};
function j.__tostring(t)
local e={};
-for a,t in c(t)do
-h(e,b(t)..'\n');
-end
-return n.concat(e);
-end
-local y={};
-function y.__tostring(e)
-local a=i.gettime();
+for a,t in m(t)do
+n(e,p(t)..'\n');
+end
+return i.concat(e);
+end
+local w={};
+function w.__tostring(e)
+local a=s.gettime();
local t={};
for i,e in o(e)do
for i,e in o(e)do
for o,e in o(e)do
-p(e,a);
-h(t,b(e));
-end
-end
-end
-return n.concat(t);
+y(e,a);
+n(t,p(e));
+end
+end
+end
+return i.concat(t);
+end
+function e:new()
+local t={active={},cache={},unsorted={}};
+r(t,e);
+r(t.cache,w);
+r(t.unsorted,{__mode='kv'});
+return t;
end
function t.random(...)
-v.randomseed(v.floor(1e4*i.gettime())%2147483648);
+v.randomseed(v.floor(1e4*s.gettime())%2147483648);
t.random=v.random;
return t.random(...);
end
@@ -1018,27 +943,27 @@
e.nscount=e.nscount or 0;
e.arcount=e.arcount or 0;
local t=a.char(
-f(e.id),e.id%256,
+c(e.id),e.id%256,
e.rd+2*e.tc+4*e.aa+8*e.opcode+128*e.qr,
e.rcode+16*e.z+128*e.ra,
-f(e.qdcount),e.qdcount%256,
-f(e.ancount),e.ancount%256,
-f(e.nscount),e.nscount%256,
-f(e.arcount),e.arcount%256
+c(e.qdcount),e.qdcount%256,
+c(e.ancount),e.ancount%256,
+c(e.nscount),e.nscount%256,
+c(e.arcount),e.arcount%256
);
return t,e.id;
end
-local function f(t)
+local function c(t)
local e={};
for t in a.gmatch(t,'[^.]+')do
-h(e,a.char(a.len(t)));
-h(e,t);
-end
-h(e,a.char(0));
-return n.concat(e);
-end
-local function T(o,a,e)
-o=f(o);
+n(e,a.char(a.len(t)));
+n(e,t);
+end
+n(e,a.char(0));
+return i.concat(e);
+end
+local function z(o,a,e)
+o=c(o);
a=t.typecode[a or'a'];
e=t.classcode[e or'in'];
return o..a..e;
@@ -1058,8 +983,8 @@
return 256*t+e;
end
function e:dword()
-local e,t,o,a=self:byte(4);
-return 16777216*e+65536*t+256*o+a;
+local o,t,a,e=self:byte(4);
+return 16777216*o+65536*t+256*a+e;
end
function e:sub(e)
e=e or 1;
@@ -1088,24 +1013,24 @@
return e;
end
function e:name()
-local t,a=nil,0;
+local a,t=nil,0;
local e=self:byte();
local o={};
if e==0 then return"."end
while e>0 do
if e>=192 then
-a=a+1;
-if a>=20 then q('dns error: 20 pointers');end;
+t=t+1;
+if t>=20 then q('dns error: 20 pointers');end;
local e=((e-192)*256)+self:byte();
-t=t or self.offset;
+a=a or self.offset;
self.offset=e+1;
else
-h(o,self:sub(e)..'.');
+n(o,self:sub(e)..'.');
end
e=self:byte();
end
-self.offset=t or self.offset;
-return n.concat(o);
+self.offset=a or self.offset;
+return i.concat(o);
end
function e:question()
local e={};
@@ -1114,26 +1039,26 @@
e.class=t.class[self:word()];
return e;
end
-function e:A(n)
-local i,o,e,t=self:byte(4);
-n.a=a.format('%i.%i.%i.%i',i,o,e,t);
+function e:A(e)
+local o,t,n,i=self:byte(4);
+e.a=a.format('%i.%i.%i.%i',o,t,n,i);
end
function e:AAAA(a)
local e={};
for t=1,a.rdlength,2 do
local t,a=self:byte(2);
-n.insert(e,("%02x%02x"):format(t,a));
-end
-e=n.concat(e,":"):gsub("%f[%x]0+(%x)","%1");
+i.insert(e,("%02x%02x"):format(t,a));
+end
+e=i.concat(e,":"):gsub("%f[%x]0+(%x)","%1");
local t={};
for e in e:gmatch(":[0:]+:")do
-n.insert(t,e)
+i.insert(t,e)
end
if#t==0 then
a.aaaa=e;
return
elseif#t>1 then
-n.sort(t,function(e,t)return#e>#t end);
+i.sort(t,function(t,e)return#t>#e end);
end
a.aaaa=e:gsub(t[1],"::",1):gsub("^0::","::"):gsub("::0$","::");
end
@@ -1160,28 +1085,28 @@
e.loc.altitude=self:dword();
end
end
-local function f(e,i,t)
+local function c(e,i,t)
e=e-2147483648;
if e<0 then i=t;e=-e;end
-local n,t,o;
-o=e%6e4;
-e=(e-o)/6e4;
-t=e%60;
-n=(e-t)/60;
-return a.format('%3d %2d %2.3f %s',n,t,o/1e3,i);
+local n,o,t;
+t=e%6e4;
+e=(e-t)/6e4;
+o=e%60;
+n=(e-o)/60;
+return a.format('%3d %2d %2.3f %s',n,o,t/1e3,i);
end
function e.LOC_tostring(e)
local t={};
-h(t,a.format(
+n(t,a.format(
'%s %s %.2fm %.2fm %.2fm %.2fm',
-f(e.loc.latitude,'N','S'),
-f(e.loc.longitude,'E','W'),
+c(e.loc.latitude,'N','S'),
+c(e.loc.longitude,'E','W'),
(e.loc.altitude-1e7)/100,
e.loc.size/100,
e.loc.horiz_pre/100,
e.loc.vert_pre/100
));
-return n.concat(t);
+return i.concat(t);
end
function e:NS(e)
e.ns=self:name();
@@ -1203,7 +1128,7 @@
end
function e:rr()
local e={};
-u(e,x);
+r(e,x);
e.name=self:name(self);
e.type=t.type[self:word()]or e.type;
e.class=t.class[self:word()]or e.class;
@@ -1223,7 +1148,7 @@
end
function e:rrs(t)
local e={};
-for t=1,t do h(e,self:rr());end
+for t=1,t do n(e,self:rr());end
return e;
end
function e:decode(t,o)
@@ -1234,7 +1159,7 @@
t.question={};
local i=self.offset;
for e=1,t.header.qdcount do
-h(t.question,self:question());
+n(t.question,self:question());
end
t.question.raw=a.sub(self.packet,i,self.offset-1);
if not o then
@@ -1251,16 +1176,16 @@
e.delays={1,3};
function e:addnameserver(e)
self.server=self.server or{};
-h(self.server,e);
+n(self.server,e);
end
function e:setnameserver(e)
self.server={};
self:addnameserver(e);
end
function e:adddefaultnameservers()
-if E then
-if w and w.get_nameservers then
-for t,e in c(w.get_nameservers())do
+if _ then
+if b and b.get_nameservers then
+for t,e in m(b.get_nameservers())do
self:addnameserver(e);
end
end
@@ -1269,16 +1194,15 @@
self:addnameserver("208.67.220.220");
end
else
-local e=_.open("/etc/resolv.conf");
+local e=E.open("/etc/resolv.conf");
if e then
for e in e:lines()do
e=e:gsub("#.*$","")
-:match('^%s*nameserver%s+([%x:%.]*%%?%S*)%s*$');
+:match('^%s*nameserver%s+(.*)%s*$');
if e then
-local e=z(e);
-if e then
-self:addnameserver(e.addr);
-end
+e:gsub("%f[%d.](%d+%.%d+%.%d+%.%d+)%f[^%d.]",function(e)
+self:addnameserver(e)
+end);
end
end
end
@@ -1287,29 +1211,24 @@
end
end
end
-function e:getsocket(a)
+function e:getsocket(o)
self.socket=self.socket or{};
self.socketset=self.socketset or{};
-local e=self.socket[a];
+local e=self.socket[o];
if e then return e;end
-local o,t;
-local n=self.server[a];
-if n:find(":")then
-e,t=i.udp6();
-else
-e,t=(i.udp4 or i.udp)();
-end
+local a,t;
+e,t=s.udp();
if e and self.socket_wrapper then e,t=self.socket_wrapper(e,self);end
if not e then
return nil,t;
end
e:settimeout(0);
-self.socket[a]=e;
-self.socketset[e]=a;
-o,t=e:setsockname('*',0);
-if not o then return self:servfail(e,t);end
-o,t=e:setpeername(n,53);
-if not o then return self:servfail(e,t);end
+self.socket[o]=e;
+self.socketset[e]=o;
+a,t=e:setsockname('*',0);
+if not a then return self:servfail(e,t);end
+a,t=e:setpeername(self.server[o],53);
+if not a then return self:servfail(e,t);end
return e;
end
function e:voidsocket(e)
@@ -1326,100 +1245,100 @@
self.socket_wrapper=e;
end
function e:closeall()
-for t,e in c(self.socket)do
+for t,e in m(self.socket)do
self.socket[t]=nil;
self.socketset[e]=nil;
e:close();
end
end
function e:remember(e,t)
-local i,o,a=g(e.name,e.type,e.class);
+local a,o,i=g(e.name,e.type,e.class);
if t~='*'then
t=o;
-local t=r(self.cache,a,'*',i);
-if t then h(t,e);end
-end
-self.cache=self.cache or u({},y);
-local a=r(self.cache,a,t,i)or
-d(self.cache,a,t,i,u({},j));
+local t=d(self.cache,i,'*',a);
+if t then n(t,e);end
+end
+self.cache=self.cache or r({},w);
+local a=d(self.cache,i,t,a)or
+l(self.cache,i,t,a,r({},j));
if not a[e[o:lower()]]then
a[e[o:lower()]]=true;
-h(a,e);
+n(a,e);
end
if t=='MX'then self.unsorted[a]=true;end
end
-local function f(t,e)
-return(t.pref==e.pref)and(t.mx#self.server then
e.server=1;
@@ -1444,28 +1363,28 @@
if e.retries>=#self.server then
a[o]=nil;
else
-t,n=self:getsocket(e.server);
+t,i=self:getsocket(e.server);
if t then t:send(e.packet);end
end
end
end
-if s(a)==nil then
-self.active[i]=nil;
-end
-end
-if h==self.best_server then
+if h(a)==nil then
+self.active[s]=nil;
+end
+end
+if n==self.best_server then
self.best_server=self.best_server+1;
if self.best_server>#self.server then
self.best_server=1;
end
end
-return t,n;
+return t,i;
end
function e:settimeout(e)
self.timeout=e;
end
function e:receive(t)
-self.time=i.gettime();
+self.time=s.gettime();
t=t or self.socket;
local e;
for a,t in o(t)do
@@ -1476,31 +1395,29 @@
if e and self.active[e.header.id]
and self.active[e.header.id][e.question.raw]then
for a,t in o(e.answer)do
-if t.name:sub(-#e.question[1].name,-1)==e.question[1].name then
self:remember(t,e.question[1].type)
end
-end
local t=self.active[e.header.id];
t[e.question.raw]=nil;
-if not s(t)then self.active[e.header.id]=nil;end
-if not s(self.active)then self:closeall();end
+if not h(t)then self.active[e.header.id]=nil;end
+if not h(self.active)then self:closeall();end
local e=e.question[1];
-local t=r(self.wanted,e.class,e.type,e.name);
+local t=d(self.wanted,e.class,e.type,e.name);
if t then
for e in o(t)do
-if l.status(e)=="suspended"then l.resume(e);end
-end
-d(self.wanted,e.class,e.type,e.name,nil);
-end
-end
-end
-end
-end
-return e;
-end
-function e:feed(a,e,t)
-self.time=i.gettime();
-local e=self:decode(e,t);
+if u.status(e)=="suspended"then u.resume(e);end
+end
+l(self.wanted,e.class,e.type,e.name,nil);
+end
+end
+end
+end
+end
+return e;
+end
+function e:feed(a,t,e)
+self.time=s.gettime();
+local e=self:decode(t,e);
if e and self.active[e.header.id]
and self.active[e.header.id][e.question.raw]then
for a,t in o(e.answer)do
@@ -1508,34 +1425,34 @@
end
local t=self.active[e.header.id];
t[e.question.raw]=nil;
-if not s(t)then self.active[e.header.id]=nil;end
-if not s(self.active)then self:closeall();end
+if not h(t)then self.active[e.header.id]=nil;end
+if not h(self.active)then self:closeall();end
local e=e.question[1];
if e then
-local t=r(self.wanted,e.class,e.type,e.name);
+local t=d(self.wanted,e.class,e.type,e.name);
if t then
for e in o(t)do
-if l.status(e)=="suspended"then l.resume(e);end
-end
-d(self.wanted,e.class,e.type,e.name,nil);
+if u.status(e)=="suspended"then u.resume(e);end
+end
+l(self.wanted,e.class,e.type,e.name,nil);
end
end
end
return e;
end
function e:cancel(t,a,i)
-local e=r(self.wanted,t,a,i);
+local e=d(self.wanted,t,a,i);
if e then
for e in o(e)do
-if l.status(e)=="suspended"then l.resume(e);end
-end
-d(self.wanted,t,a,i,nil);
+if u.status(e)=="suspended"then u.resume(e);end
+end
+l(self.wanted,t,a,i,nil);
end
end
function e:pulse()
while self:receive()do end
-if not s(self.active)then return nil;end
-self.time=i.gettime();
+if not h(self.active)then return nil;end
+self.time=s.gettime();
for a,t in o(self.active)do
for o,e in o(t)do
if self.time>=e.retry then
@@ -1546,8 +1463,8 @@
end
if e.delay>#self.delays then
t[o]=nil;
-if not s(t)then self.active[a]=nil;end
-if not s(self.active)then return nil;end
+if not h(t)then self.active[a]=nil;end
+if not h(self.active)then return nil;end
else
local t=self.socket[e.server];
if t then t:send(e.packet);end
@@ -1556,22 +1473,22 @@
end
end
end
-if s(self.active)then return true;end
+if h(self.active)then return true;end
return nil;
end
-function e:lookup(o,a,t)
-self:query(o,a,t)
+function e:lookup(a,e,t)
+self:query(a,e,t)
while self:pulse()do
local e={}
-for t,a in c(self.socket)do
+for t,a in m(self.socket)do
e[t]=a
end
-i.select(e,nil,4)
-end
-return self:peek(o,a,t);
-end
-function e:lookupex(o,t,e,a)
-return self:peek(t,e,a)or self:query(t,e,a);
+s.select(e,nil,4)
+end
+return self:peek(a,e,t);
+end
+function e:lookupex(o,a,t,e)
+return self:peek(a,t,e)or self:query(a,t,e);
end
function e:tohostname(e)
return t.lookup(e:gsub("(%d+)%.(%d+)%.(%d+)%.(%d+)","%4.%3.%2.%1.in-addr.arpa."),"PTR");
@@ -1588,31 +1505,31 @@
type=t.type,
class=t.class
};
-local function n(t,e)
+local function s(t,e)
return(i[e]and i[e][t[e]])or'';
end
-function e.print(e)
-for o,t in o{'id','qr','opcode','aa','tc','rd','ra','z',
+function e.print(t)
+for o,e in o{'id','qr','opcode','aa','tc','rd','ra','z',
'rcode','qdcount','ancount','nscount','arcount'}do
-m(a.format('%-30s','header.'..t),e.header[t],n(e.header,t));
-end
-for e,t in c(e.question)do
-m(a.format('question[%i].name ',e),t.name);
-m(a.format('question[%i].type ',e),t.type);
-m(a.format('question[%i].class ',e),t.class);
-end
-local h={name=1,type=1,class=1,ttl=1,rdlength=1,rdata=1};
-local t;
-for s,i in o({'answer','authority','additional'})do
-for s,e in o(e[i])do
-for h,o in o({'name','type','class','ttl','rdlength'})do
-t=a.format('%s[%i].%s',i,s,o);
-m(a.format('%-30s',t),e[o],n(e,o));
-end
-for e,o in o(e)do
-if not h[e]then
-t=a.format('%s[%i].%s',i,s,e);
-m(a.format('%-30s %s',b(t),b(o)));
+f(a.format('%-30s','header.'..e),t.header[e],s(t.header,e));
+end
+for e,t in m(t.question)do
+f(a.format('question[%i].name ',e),t.name);
+f(a.format('question[%i].type ',e),t.type);
+f(a.format('question[%i].class ',e),t.class);
+end
+local r={name=1,type=1,class=1,ttl=1,rdlength=1,rdata=1};
+local e;
+for n,i in o({'answer','authority','additional'})do
+for h,n in o(t[i])do
+for o,t in o({'name','type','class','ttl','rdlength'})do
+e=a.format('%s[%i].%s',i,h,t);
+f(a.format('%-30s',e),n[t],s(n,t));
+end
+for t,o in o(n)do
+if not r[t]then
+e=a.format('%s[%i].%s',i,h,t);
+f(a.format('%-30s %s',p(e),p(o)));
end
end
end
@@ -1620,9 +1537,9 @@
end
function t.resolver()
local t={active={},cache={},unsorted={},wanted={},best_server=1};
-u(t,e);
-u(t.cache,y);
-u(t.unsorted,{__mode='kv'});
+r(t,e);
+r(t.cache,w);
+r(t.unsorted,{__mode='kv'});
return t;
end
local e=t.resolver();
@@ -1660,192 +1577,208 @@
return t;
end)
package.preload['net.adns']=(function(...)
+local _ENV=_ENV;
+local function o(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
local c=require"net.server";
local a=require"net.dns";
-local e=require"util.logger".init("adns");
-local o,r,l=coroutine,tostring,pcall;
-local function m(a,a,t,e)return(e-t)+1;end
-local t=nil;
-local function u(d,t,s,h)
-return o.wrap(function(i)
-if i then
-e("debug","Records for %s already cached, using those...",t);
-d(i);
+local t=require"util.logger".init("adns");
+local e,e=table.insert,table.remove;
+local n,h,l=coroutine,tostring,pcall;
+local function u(a,a,t,e)return(e-t)+1;end
+o"adns"
+function lookup(d,e,s,r)
+return n.wrap(function(o)
+if o then
+t("debug","Records for %s already cached, using those...",e);
+d(o);
return;
end
-e("debug","Records for %s not in cache, sending query (%s)...",t,r(o.running()));
-local n,i=a.query(t,s,h);
-if n then
-o.yield({h or"IN",s or"A",t,o.running()});
-e("debug","Reply for %s (%s)",t,r(o.running()));
-end
-if n then
-n,i=l(d,a.peek(t,s,h));
-else
-e("error","Error sending DNS query: %s",i);
-n,i=l(d,nil,i);
-end
-if not n then
-e("error","Error in DNS response handler: %s",r(i));
-end
-end)(a.peek(t,s,h));
-end
-local function d(t,o,i)
-e("warn","Cancelling DNS lookup for %s",r(t[3]));
-a.cancel(t[1],t[2],t[3],t[4],o);
-end
-local function r(o,i)
+t("debug","Records for %s not in cache, sending query (%s)...",e,h(n.running()));
+local i,o=a.query(e,s,r);
+if i then
+n.yield({r or"IN",s or"A",e,n.running()});
+t("debug","Reply for %s (%s)",e,h(n.running()));
+end
+if i then
+i,o=l(d,a.peek(e,s,r));
+else
+t("error","Error sending DNS query: %s",o);
+i,o=l(d,nil,o);
+end
+if not i then
+t("error","Error in DNS response handler: %s",h(o));
+end
+end)(a.peek(e,s,r));
+end
+function cancel(e,o,i)
+t("warn","Cancelling DNS lookup for %s",h(e[3]));
+a.cancel(e[1],e[2],e[3],e[4],o);
+end
+function new_async_socket(i,o)
local n="";
local s={};
-local t={};
+local e={};
local h;
-function s.onincoming(o,e)
-if e then
-a.feed(t,e);
-end
-end
-function s.ondisconnect(o,a)
-if a then
-e("warn","DNS socket for %s disconnected: %s",n,a);
-local t=i.server;
-if i.socketset[o]==i.best_server and i.best_server==#t then
-e("error","Exhausted all %d configured DNS servers, next lookup will try %s again",#t,t[1]);
-end
-i:servfail(o);
-end
-end
-t,h=c.wrapclient(o,"dns",53,s);
-if not t then
+function s.onincoming(o,t)
+if t then
+a.feed(e,t);
+end
+end
+function s.ondisconnect(a,i)
+if i then
+t("warn","DNS socket for %s disconnected: %s",n,i);
+local e=o.server;
+if o.socketset[a]==o.best_server and o.best_server==#e then
+t("error","Exhausted all %d configured DNS servers, next lookup will try %s again",#e,e[1]);
+end
+o:servfail(a);
+end
+end
+e,h=c.wrapclient(i,"dns",53,s);
+if not e then
return nil,h;
end
-t.settimeout=function()end
-t.setsockname=function(e,...)return o:setsockname(...);end
-t.setpeername=function(e,...)n=(...);local a,o=o:setpeername(...);e:set_send(m);return a,o;end
-t.connect=function(e,...)return o:connect(...)end
-t.send=function(a,t)
-e("debug","Sending DNS query to %s",n);
-return o:send(t);
-end
-return t;
-end
-a.socket_wrapper_set(r);
-return{
-lookup=u;
-cancel=d;
-new_async_socket=r;
-};
+e.settimeout=function()end
+e.setsockname=function(t,...)return i:setsockname(...);end
+e.setpeername=function(o,...)n=(...);local a,t=i:setpeername(...);o:set_send(u);return a,t;end
+e.connect=function(t,...)return i:connect(...)end
+e.send=function(a,e)
+t("debug","Sending DNS query to %s",n);
+return i:send(e);
+end
+return e;
+end
+a.socket_wrapper_set(new_async_socket);
+return _M;
end)
package.preload['net.server']=(function(...)
-local c=function(e)
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
+local m=function(e)
return _G[e]
end
-local Y,e=require("util.logger").init("socket"),table.concat;
-local i=function(...)return Y("debug",e{...});end
-local L=function(...)return Y("warn",e{...});end
-local he=1
-local w=c"type"
-local D=c"pairs"
-local ee=c"ipairs"
-local f=c"tonumber"
-local r=c"tostring"
-local a=c"table"
-local t=c"string"
-local e=c"coroutine"
-local Z=math.min
-local ue=math.huge
-local we=a.concat
-local fe=t.sub
-local me=e.wrap
-local ye=e.yield
-local U,e=pcall(require,"ssl")
-local p=c"socket"or require"socket"
-local X=p.gettime
-local pe=p.dns.getaddrinfo
-local be=(U and e.wrap)
-local de=p.bind
-local ve=p.sleep
-local ce=p.select
-local V
+local W,e=require("util.logger").init("socket"),table.concat;
+local n=function(...)return W("debug",e{...});end
+local E=function(...)return W("warn",e{...});end
+local ce=1
+local f=m"type"
+local b=m"pairs"
+local ue=m"ipairs"
+local y=m"tonumber"
+local l=m"tostring"
+local t=m"table"
+local a=m"string"
+local e=m"coroutine"
+local Y=math.min
+local re=math.huge
+local pe=t.concat
+local he=t.insert
+local we=a.sub
+local fe=e.wrap
+local me=e.yield
+local O,e=pcall(require,"ssl")
+local g=m"socket"or require"socket"
+local F=g.gettime
+local ee=g.dns.getaddrinfo
+local ye=(O and e.wrap)
+local te=g.bind
+local ve=g.select
+local I
+local B
+local ae
+local G
+local J
+local u
+local ie
+local X
+local se
+local ne
+local oe
+local Q
+local s
+local le
+local Z
+local de
+local p
+local i
local P
-local le
-local B
-local K
-local m
-local re
-local oe
-local ae
-local te
-local ie
-local G
-local d
-local se
-local Q
-local ne
+local r
+local h
+local T
local v
-local h
-local F
-local l
-local s
-local _
-local b
-local y
+local w
local k
local x
local a
local o
-local g
-local W
+local q
+local C
local M
-local I
-local O
+local A
local j
-local A
-local J
-local n
-local E
-local T
local N
+local K
+local d
local H
local S
-local C
-local q
+local R
+local D
+local L
local z
-local R
-v={}
+local _
+local U
+p={}
+i={}
+r={}
+P={}
h={}
-l={}
-F={}
-s={}
-b={}
-y={}
-_={}
+v={}
+w={}
+T={}
k={}
a=0
o=0
-g=0
-W=0
+q=0
+C=0
M=0
-I=1
-O=0
+A=1
j=128
-A=10
-E=51e3*1024
-T=25e3*1024
-N=30
-H=6e4
-S=6*60*60
+N=10
+H=51e3*1024
+S=25e3*1024
+R=30
+D=6e4
+L=14*60
local e=package.config:sub(1,1)=="\\"
-z=(e and math.huge)or p._SETSIZE or 1024
-q=p._SETSIZE or 1024
-R=30
-te=function(y,t,c,u,g,w)
-if t:getfd()>=z then
-L("server.lua: Disallowed FD number: "..t:getfd())
+_=(e and math.huge)or g._SETSIZE or 1024
+z=g._SETSIZE or 1024
+U=30
+ne=function(y,t,m,c,g,w)
+if t:getfd()>=_ then
+E("server.lua: Disallowed FD number: "..t:getfd())
t:close()
return nil,"fd-too-large"
end
local f=0
-local p,e=y.onconnect,y.ondisconnect
+local v,e=y.onconnect,y.ondisconnect
local b=t.accept
local e={}
e.shutdown=function()end
@@ -1863,110 +1796,109 @@
end
e.close=function()
t:close()
-o=d(l,t,o)
-a=d(h,t,a)
-v[c..":"..u]=nil;
-s[t]=nil
+o=s(r,t,o)
+a=s(i,t,a)
+p[m..":"..c]=nil;
+h[t]=nil
e=nil
t=nil
-i"server.lua: closed server handler and removed sockets from list"
+n"server.lua: closed server handler and removed sockets from list"
end
e.pause=function(o)
if not e.paused then
-a=d(h,t,a)
+a=s(i,t,a)
if o then
-s[t]=nil
+h[t]=nil
t:close()
t=nil;
end
e.paused=true;
-i("server.lua: server [",c,"]:",u," paused")
+n("server.lua: server [",m,"]:",c," paused")
end
end
e.resume=function()
if e.paused then
if not t then
-t=de(c,u,j);
+t=te(m,c,j);
t:settimeout(0)
end
-a=m(h,t,a)
-s[t]=e
+a=u(i,t,a)
+h[t]=e
k[e]=nil
e.paused=false;
-i("server.lua: server [",c,"]:",u," resumed")
+n("server.lua: server [",m,"]:",c," resumed")
end
end
e.ip=function()
-return c
+return m
end
e.serverport=function()
-return u
+return c
end
e.socket=function()
return t
end
e.readbuffer=function()
-if a>=q or o>=q then
+if a>=z or o>=z then
e.pause()
-k[e]=n
-i("server.lua: refused new client connection: server full")
+k[e]=d
+n("server.lua: refused new client connection: server full")
return false
end
-local t,s=b(t)
+local t,o=b(t)
if t then
local o,a=t:getpeername()
-local e,n,t=Q(e,y,t,o,u,a,g,w)
-if t then
+local t,i,e=Z(e,y,t,o,c,a,g,w)
+if e then
return false
end
f=f+1
-i("server.lua: accepted new client connection from ",r(o),":",r(a)," to ",r(u))
-if p and not w then
-return p(e);
+n("server.lua: accepted new client connection from ",l(o),":",l(a)," to ",l(c))
+if v and not w then
+return v(t);
end
return;
-elseif s then
-i("server.lua: error with new client connection: ",r(s))
+elseif o then
+n("server.lua: error with new client connection: ",l(o))
e.pause()
-k[e]=n
+k[e]=d
return false
end
end
return e
end
-Q=function(v,f,t,O,J,I,N,g)
-if t:getfd()>=z then
-L("server.lua: Disallowed FD number: "..t:getfd())
+Z=function(p,f,t,z,K,A,N,g)
+if t:getfd()>=_ then
+E("server.lua: Disallowed FD number: "..t:getfd())
t:close()
-if v then
-k[v]=n
-v.pause()
+if p then
+k[p]=d
+p.pause()
end
return nil,nil,"fd-too-large"
end
t:settimeout(0)
-local w
-local z
+local y
+local _
local q
-local Y
+local V
local P=f.onincoming
-local F=f.onstatus
+local Y=f.onstatus
local k=f.ondisconnect
-local L=f.ondrain
+local D=f.ondrain
local Q=f.onreadtimeout;
-local C=f.ondetach
-local p={}
-local u=0
-local G
-local K
-local D
+local R=f.ondetach
+local b={}
local c=0
+local B
+local L
+local m=0
local j=false
-local A=false
-local S,H=0,0
-local E=E
-local T=T
-local e=p
+local E=false
+local W,F=0,0
+local H=H
+local S=S
+local e=b
e.dispatch=function()
return P
end
@@ -1975,30 +1907,30 @@
end
e.onreadtimeout=Q;
e.setlistener=function(a,t)
-if C then
-C(a)
+if R then
+R(a)
end
P=t.onincoming
k=t.ondisconnect
-F=t.onstatus
-L=t.ondrain
+Y=t.onstatus
+D=t.ondrain
e.onreadtimeout=t.onreadtimeout
-C=t.ondetach
+R=t.ondetach
end
e.getstats=function()
-return H,S
+return F,W
end
e.ssl=function()
-return Y
+return V
end
e.sslctx=function()
return g
end
-e.send=function(n,o,i,a)
-return w(t,o,i,a)
+e.send=function(n,o,a,i)
+return y(t,o,a,i)
end
e.receive=function(o,a)
-return z(t,o,a)
+return _(t,o,a)
end
e.shutdown=function(a)
return q(t,a)
@@ -2009,85 +1941,85 @@
end
return false,"setoption not implemented";
end
-e.force_close=function(a,t)
-if u~=0 then
-i("server.lua: discarding unwritten data for ",r(O),":",r(I))
-u=0;
-end
-return a:close(t);
-end
-e.close=function(r,n)
+e.force_close=function(t,a)
+if c~=0 then
+n("server.lua: discarding unwritten data for ",l(z),":",l(A))
+c=0;
+end
+return t:close(a);
+end
+e.close=function(l,d)
if not e then return true;end
-a=d(h,t,a)
-b[e]=nil
-if u~=0 then
+a=s(i,t,a)
+v[e]=nil
+if c~=0 then
e.sendbuffer()
-if u~=0 then
+if c~=0 then
if e then
e.write=nil
end
-G=true
+B=true
return false
end
end
if t then
x=q and q(t)
t:close()
-o=d(l,t,o)
-s[t]=nil
+o=s(r,t,o)
+h[t]=nil
t=nil
else
-i"server.lua: socket already closed"
+n"server.lua: socket already closed"
end
if e then
-y[e]=nil
-_[e]=nil
+w[e]=nil
+T[e]=nil
local t=e;
e=nil
if k then
-k(t,n or false);
+k(t,d or false);
k=nil
end
end
-if v then
-v.remove()
-end
-i"server.lua: closed client handler and removed socket from list"
+if p then
+p.remove()
+end
+n"server.lua: closed client handler and removed socket from list"
return true
end
e.server=function()
-return v
+return p
end
e.ip=function()
-return O
+return z
end
e.serverport=function()
-return J
+return K
end
e.clientport=function()
-return I
+return A
end
e.port=e.clientport
-local v=function(i,a)
+local p=function(i,a)
if not e then return false end
-c=c+#a
-if c>E then
-_[e]="send buffer exceeded"
-e.write=B
+m=m+#a
+if m>H then
+T[e]="send buffer exceeded"
+e.write=G
return false
-elseif t and not l[t]then
-o=m(l,t,o)
-end
-u=u+1
-p[u]=a
+elseif t and not r[t]then
+o=u(r,t,o)
+end
+c=c+1
+b[c]=a
if e then
-y[e]=y[e]or n
+w[e]=w[e]or d
end
return true
end
-e.write=v
+e.write=p
e.bufferqueue=function(t)
-return p
+return b
end
e.socket=function(a)
return t
@@ -2097,27 +2029,27 @@
return N
end
e.set_send=function(a,t)
-w=t or w
-return w
-end
-e.bufferlen=function(o,t,a)
-E=a or E
-T=t or T
-return c,T,E
-end
-e.lock_read=function(i,o)
+y=t or y
+return y
+end
+e.bufferlen=function(o,a,t)
+H=t or H
+S=a or S
+return m,S,H
+end
+e.lock_read=function(n,o)
if o==true then
local o=a
-a=d(h,t,a)
-b[e]=nil
+a=s(i,t,a)
+v[e]=nil
if a~=o then
j=true
end
elseif o==false then
if j then
j=false
-a=m(h,t,a)
-b[e]=n
+a=u(i,t,a)
+v[e]=d
end
end
return j
@@ -2131,209 +2063,207 @@
e.lock=function(i,a)
e.lock_read(a)
if a==true then
-e.write=B
+e.write=G
local a=o
-o=d(l,t,o)
-y[e]=nil
+o=s(r,t,o)
+w[e]=nil
if o~=a then
-A=true
+E=true
end
elseif a==false then
-e.write=v
-if A then
-A=false
-v("")
-end
-end
-return j,A
-end
-local v=function()
-local a,t,o=z(t,N)
+e.write=p
+if E then
+E=false
+p("")
+end
+end
+return j,E
+end
+local p=function()
+local a,t,o=_(t,N)
if not t or(t=="wantread"or t=="timeout")then
-local a=a or o or""
-local o=#a
-if o>T then
+local o=a or o or""
+local a=#o
+if a>S then
e:close("receive buffer exceeded")
return false
end
-local o=o*he
-H=H+o
-M=M+o
-b[e]=n
-return P(e,a,t)
-else
-i("server.lua: client ",r(O),":",r(I)," read error: ",r(t))
-K=true
+local a=a*ce
+F=F+a
+M=M+a
+v[e]=d
+return P(e,o,t)
+else
+n("server.lua: client ",l(z),":",l(A)," read error: ",l(t))
x=e and e:force_close(t)
return false
end
end
-local y=function()
-local f,a,s,h,m;
+local v=function()
+local f,a,h,i,u;
if t then
-h=we(p,"",1,u)
-f,a,s=w(t,h,1,c)
-m=(f or s or 0)*he
-S=S+m
-W=W+m
-for e=u,1,-1 do
-p[e]=nil
-end
-else
-f,a,m=false,"unexpected close",0;
+i=pe(b,"",1,c)
+f,a,h=y(t,i,1,m)
+u=(f or h or 0)*ce
+W=W+u
+C=C+u
+for e=c,1,-1 do
+b[e]=nil
+end
+else
+f,a,u=false,"unexpected close",0;
end
if f then
-u=0
c=0
-o=d(l,t,o)
-y[e]=nil
-if L then
-L(e)
-end
-x=D and e:starttls(nil)
-x=G and e:force_close()
+m=0
+o=s(r,t,o)
+w[e]=nil
+if D then
+D(e)
+end
+x=L and e:starttls(nil)
+x=B and e:force_close()
return true
-elseif s and(a=="timeout"or a=="wantwrite")then
-h=fe(h,s+1,c)
-p[1]=h
-u=1
-c=c-s
-y[e]=n
+elseif h and(a=="timeout"or a=="wantwrite")then
+i=we(i,h+1,m)
+b[1]=i
+c=1
+m=m-h
+w[e]=d
return true
else
-i("server.lua: client ",r(O),":",r(I)," write error: ",r(a))
-K=true
+n("server.lua: client ",l(z),":",l(A)," write error: ",l(a))
x=e and e:force_close(a)
return false
end
end
-local c;
+local d;
function e.set_sslctx(w,t)
g=t;
-local s,r
-c=me(function(n)
+local m,l
+d=fe(function(h)
local t
-for c=1,R do
-o=(r and d(l,n,o))or o
-a=(s and d(h,n,a))or a
-s,r=nil,nil
-c,t=n:dohandshake()
+for d=1,U do
+o=(l and s(r,h,o))or o
+a=(m and s(i,h,a))or a
+m,l=nil,nil
+d,t=h:dohandshake()
if not t then
-i("server.lua: ssl handshake done")
-e.readbuffer=v
-e.sendbuffer=y
-c=F and F(e,"ssl-handshake-complete")
+n("server.lua: ssl handshake done")
+e.readbuffer=p
+e.sendbuffer=v
+d=Y and Y(e,"ssl-handshake-complete")
if w.autostart_ssl and f.onconnect then
f.onconnect(w);
-if u~=0 then
-o=m(l,n,o)
-end
-end
-a=m(h,n,a)
+if c~=0 then
+o=u(r,h,o)
+end
+end
+a=u(i,h,a)
return true
else
if t=="wantwrite"then
-o=m(l,n,o)
-r=true
+o=u(r,h,o)
+l=true
elseif t=="wantread"then
-a=m(h,n,a)
-s=true
+a=u(i,h,a)
+m=true
else
break;
end
t=nil;
-ye()
+me()
end
end
t="ssl handshake error: "..(t or"handshake too long");
-i("server.lua: ",t);
+n("server.lua: ",t);
x=e and e:force_close(t)
return false,t
end
)
end
-if U then
-e.starttls=function(f,n)
-if n then
-e:set_sslctx(n);
-end
-if u>0 then
-i"server.lua: we need to do tls, but delaying until send buffer empty"
-D=true
+if O then
+e.starttls=function(f,m)
+if m then
+e:set_sslctx(m);
+end
+if c>0 then
+n"server.lua: we need to do tls, but delaying until send buffer empty"
+L=true
return
end
-i("server.lua: attempting to start tls on "..r(t))
-local n,u=t
-t,u=be(t,g)
+n("server.lua: attempting to start tls on "..l(t))
+local c,m=t
+t,m=ye(t,g)
if not t then
-i("server.lua: error while starting tls on client: ",r(u or"unknown error"))
-return nil,u
+n("server.lua: error while starting tls on client: ",l(m or"unknown error"))
+return nil,m
end
t:settimeout(0)
-w=t.send
-z=t.receive
-q=V
-s[t]=e
-a=m(h,t,a)
-a=d(h,n,a)
-o=d(l,n,o)
-s[n]=nil
+y=t.send
+_=t.receive
+q=I
+h[t]=e
+a=u(i,t,a)
+a=s(i,c,a)
+o=s(r,c,o)
+h[c]=nil
e.starttls=nil
-D=nil
-Y=true
-e.readbuffer=c
-e.sendbuffer=c
-return c(t)
-end
-end
-e.readbuffer=v
-e.sendbuffer=y
-w=t.send
-z=t.receive
-q=(Y and V)or t.shutdown
-s[t]=e
-a=m(h,t,a)
-if g and U then
-i"server.lua: auto-starting ssl negotiation..."
+L=nil
+V=true
+e.readbuffer=d
+e.sendbuffer=d
+return d(t)
+end
+end
+e.readbuffer=p
+e.sendbuffer=v
+y=t.send
+_=t.receive
+q=(V and I)or t.shutdown
+h[t]=e
+a=u(i,t,a)
+if g and O then
+n"server.lua: auto-starting ssl negotiation..."
e.autostart_ssl=true;
-local e,t=e:starttls(g);
-if e==false then
-return nil,nil,t
+local t,e=e:starttls(g);
+if t==false then
+return nil,nil,e
end
end
return e,t
end
-V=function()
-end
-B=function()
+I=function()
+end
+G=function()
return false
end
-m=function(a,t,e)
-if not a[t]then
+u=function(t,a,e)
+if not t[a]then
e=e+1
-a[e]=t
-a[t]=e
-end
-return e;
-end
-d=function(e,a,t)
-local i=e[a]
-if i then
-e[a]=nil
+t[e]=a
+t[a]=e
+end
+return e;
+end
+s=function(e,i,t)
+local a=e[i]
+if a then
+e[i]=nil
local o=e[t]
e[t]=nil
-if o~=a then
-e[o]=i
-e[i]=o
+if o~=i then
+e[o]=a
+e[a]=o
end
return t-1
end
return t
end
-G=function(e)
-o=d(l,e,o)
-a=d(h,e,a)
-s[e]=nil
+Q=function(e)
+o=s(r,e,o)
+a=s(i,e,a)
+h[e]=nil
e:close()
end
local function x(e,t,o)
@@ -2356,342 +2286,425 @@
end
e:set_mode("*a");
end
-re=function(e,t,d,l,r)
-e=e or"*"
+ie=function(t,e,d,l,r)
+t=t or"*"
local o
-if w(d)~="table"then
+if f(d)~="table"then
o="invalid listener table"
-elseif w(e)~="string"then
+elseif f(t)~="string"then
o="invalid address"
-elseif w(t)~="number"or not(t>=0 and t<=65535)then
+elseif f(e)~="number"or not(e>=0 and e<=65535)then
o="invalid port"
-elseif v[e..":"..t]then
-o="listeners on '["..e.."]:"..t.."' already exist"
-elseif r and not U then
+elseif p[t..":"..e]then
+o="listeners on '["..t.."]:"..e.."' already exist"
+elseif r and not O then
o="luasec not found"
end
if o then
-L("server.lua, [",e,"]:",t,": ",o)
+E("server.lua, [",t,"]:",e,": ",o)
return nil,o
end
-local o,n=de(e,t,j)
-if n then
-L("server.lua, [",e,"]:",t,": ",n)
-return nil,n
-end
-local n,d=te(d,o,e,t,l,r)
-if not n then
+local o,s=te(t,e,j)
+if s then
+E("server.lua, [",t,"]:",e,": ",s)
+return nil,s
+end
+local s,d=ne(d,o,t,e,l,r)
+if not s then
o:close()
return nil,d
end
o:settimeout(0)
-a=m(h,o,a)
-v[e..":"..t]=n
-s[o]=n
-i("server.lua: new "..(r and"ssl "or"").."server listener on '[",e,"]:",t,"'")
-return n
-end
-ae=function(t,e)
-return v[t..":"..e];
+a=u(i,o,a)
+p[t..":"..e]=s
+h[o]=s
+n("server.lua: new "..(r and"ssl "or"").."server listener on '[",t,"]:",e,"'")
+return s
end
se=function(t,e)
-local a=v[t..":"..e]
+return p[t..":"..e];
+end
+le=function(t,e)
+local a=p[t..":"..e]
if not a then
-return nil,"no server found on '["..t.."]:"..r(e).."'"
+return nil,"no server found on '["..t.."]:"..l(e).."'"
end
a:close()
-v[t..":"..e]=nil
+p[t..":"..e]=nil
return true
end
-K=function()
-for t,e in D(s)do
-e:close()
-s[t]=nil
+J=function()
+for e,t in b(h)do
+t:close()
+h[e]=nil
end
a=0
o=0
-g=0
-v={}
+q=0
+p={}
+i={}
+r={}
+P={}
h={}
-l={}
-F={}
-s={}
-end
-ie=function()
+end
+oe=function()
return{
-select_timeout=I;
-select_sleep_time=O;
+select_timeout=A;
tcp_backlog=j;
-max_send_buffer_size=E;
-max_receive_buffer_size=T;
-select_idle_check_interval=N;
-send_timeout=H;
-read_timeout=S;
-max_connections=q;
-max_ssl_handshake_roundtrips=R;
-highest_allowed_fd=z;
-accept_retry_interval=A;
+max_send_buffer_size=H;
+max_receive_buffer_size=S;
+select_idle_check_interval=R;
+send_timeout=D;
+read_timeout=L;
+max_connections=z;
+max_ssl_handshake_roundtrips=U;
+highest_allowed_fd=_;
+accept_retry_interval=N;
}
end
-ne=function(e)
-if w(e)~="table"then
+de=function(e)
+if f(e)~="table"then
return nil,"invalid settings table"
end
-I=f(e.select_timeout)or I
-O=f(e.select_sleep_time)or O
-E=f(e.max_send_buffer_size)or E
-T=f(e.max_receive_buffer_size)or T
-N=f(e.select_idle_check_interval)or N
-j=f(e.tcp_backlog)or j
-H=f(e.send_timeout)or H
-S=f(e.read_timeout)or S
-A=f(e.accept_retry_interval)or A
-q=e.max_connections or q
-R=e.max_ssl_handshake_roundtrips or R
-z=e.highest_allowed_fd or z
+A=y(e.select_timeout)or A
+H=y(e.max_send_buffer_size)or H
+S=y(e.max_receive_buffer_size)or S
+R=y(e.select_idle_check_interval)or R
+j=y(e.tcp_backlog)or j
+D=y(e.send_timeout)or D
+L=y(e.read_timeout)or L
+N=y(e.accept_retry_interval)or N
+z=e.max_connections or z
+U=e.max_ssl_handshake_roundtrips or U
+_=e.highest_allowed_fd or _
+return true
+end
+X=function(e)
+if f(e)~="function"then
+return nil,"invalid listener function"
+end
+q=q+1
+P[q]=e
return true
end
-oe=function(e)
-if w(e)~="function"then
-return nil,"invalid listener function"
-end
-g=g+1
-F[g]=e
-return true
-end
-le=function()
-return M,W,a,o,g
-end
-local t;
-local function f(e)
-t=not not e;
-end
-P=function(a)
-if t then return"quitting";end
-if a then t="once";end
-local e=ue;
+local l do
+local a={};
+local e={};
+function l(t,a)
+local o=F();
+t=t+o;
+if t>=o then
+he(e,{t,a});
+else
+local e=a(o);
+if e and f(e)=="number"then
+return l(e,a);
+end
+end
+end
+X(function(t)
+if#e>0 then
+for o,t in b(e)do
+he(a,t);
+end
+e={};
+end
+local e=re;
+for n,o in b(a)do
+local i,o=o[1],o[2];
+if i<=t then
+a[n]=nil;
+local t=o(t);
+if f(t)=="number"then
+l(t,o);
+e=Y(e,t);
+end
+else
+e=Y(e,i-t);
+end
+end
+return e;
+end);
+end
+ae=function()
+return M,C,a,o,q
+end
+local e;
+local function p(t)
+e=t;
+end
+B=function(t)
+if e then return"quitting";end
+if t then e="once";end
+d=F()
repeat
-local o,a,h=ce(h,l,Z(I,e))
-for e,t in ee(a)do
-local e=s[t]
-if e then
-e.sendbuffer()
-else
-G(t)
-i"server.lua: found no handler and closed socket (writelist)"
-end
-end
-for e,t in ee(o)do
-local e=s[t]
-if e then
-e.readbuffer()
-else
-G(t)
-i"server.lua: found no handler and closed socket (readlist)"
-end
-end
-for e,t in D(_)do
+local t=re;
+for e=1,q do
+local e=P[e](d)
+if e then t=Y(t,e);end
+end
+local t,a,o=ve(i,r,Y(A,t))
+for t,e in ue(t)do
+local t=h[e]
+if t then
+t.readbuffer()
+else
+Q(e)
+n"server.lua: found no handler and closed socket (readlist)"
+end
+end
+for t,e in ue(a)do
+local t=h[e]
+if t then
+t.sendbuffer()
+else
+Q(e)
+n"server.lua: found no handler and closed socket (writelist)"
+end
+end
+for e,t in b(T)do
e.disconnect()(e,t)
e:force_close()
-_[e]=nil;
-end
-n=X()
-if n-J>N then
-J=n
-for e,t in D(y)do
-if n-t>H then
+T[e]=nil;
+end
+d=F()
+if d-K>R then
+K=d
+for e,t in b(w)do
+if d-t>D then
e.disconnect()(e,"send timeout")
e:force_close()
end
end
-for e,t in D(b)do
-if n-t>S then
+for e,t in b(v)do
+if d-t>L then
if not(e.onreadtimeout)or e:onreadtimeout()~=true then
e.disconnect()(e,"read timeout")
e:close()
else
-b[e]=n
-end
-end
-end
-end
-if n-C>=Z(e,1)then
-e=ue;
-for t=1,g do
-local t=F[t](n)
-if t then e=Z(e,t);end
-end
-C=n
-else
-e=e-(n-C);
-end
-for e,t in D(k)do
-if n-t>A then
+v[e]=d
+end
+end
+end
+end
+for e,t in b(k)do
+if d-t>N then
k[e]=nil;
e.resume();
end
end
-ve(O)
-until t;
-if a and t=="once"then t=nil;return;end
-K();
+until e;
+if e=="once"then e=nil;return;end
+J();
return"quitting"
end
-local function u()
-return P(true);
-end
-local function d()
+local function k()
+return B(true);
+end
+local function y()
return"select";
end
-local i=function(e,a,h,t,n,i)
-local e,a,n=Q(nil,t,e,a,h,"clientport",n,i)
-if not e then return nil,n end
-s[a]=e
-if not i then
-o=m(l,a,o)
-if t.onconnect then
-local a=e.sendbuffer;
+local c=function(l,e,t,n,d,s)
+local e,t,d=Z(nil,n,l,e,t,"clientport",d,s)
+if not e then return nil,d end
+h[t]=e
+if not s then
+a=u(i,t,a)
+o=u(r,t,o)
+if n.onconnect then
+local t=e.sendbuffer;
e.sendbuffer=function()
-e.sendbuffer=a;
-t.onconnect(e);
-return a();
-end
-end
-end
-return e,a
-end
-local o=function(o,t,s,r,n,a)
+e.sendbuffer=t;
+n.onconnect(e);
+return t();
+end
+end
+end
+return e,t
+end
+local b=function(a,t,n,s,i,o)
local e
-if w(s)~="table"then
+if f(n)~="table"then
e="invalid listener table"
-elseif w(o)~="string"then
+elseif f(a)~="string"then
e="invalid address"
-elseif w(t)~="number"or not(t>=0 and t<=65535)then
+elseif f(t)~="number"or not(t>=0 and t<=65535)then
e="invalid port"
-elseif n and not U then
+elseif i and not O then
e="luasec not found"
end
-if not a then
-local e,t=pe(o)
+if ee and not o then
+local e,t=ee(a)
if not e then return nil,t end
if e[1]and e[1].family=="inet6"then
-a="tcp6"
-else
-a="tcp"
-end
-end
-local a=p[a]
-if w(a)~="function"then
+o="tcp6"
+end
+end
+local o=g[o or"tcp"]
+if f(o)~="function"then
e="invalid socket type"
end
if e then
-L("server.lua, addclient: ",e)
+E("server.lua, addclient: ",e)
return nil,e
end
-local e,a=a()
-if a then
-return nil,a
+local e,o=o()
+if o then
+return nil,o
end
e:settimeout(0)
-local h,a=e:connect(o,t)
-if h or a=="timeout"then
-return i(e,o,t,s,r,n)
-else
-return nil,a
-end
-end
-c"setmetatable"(s,{__mode="k"})
-c"setmetatable"(b,{__mode="k"})
-c"setmetatable"(y,{__mode="k"})
-C=X()
-J=X()
+local h,o=e:connect(a,t)
+if h or o=="timeout"or o=="Operation already in progress"then
+return c(e,a,t,n,s,i)
+else
+return nil,o
+end
+end
+local g=function(e)
+local e=e.conn;
+o=s(r,e,o)
+a=s(i,e,a)
+h[e]=nil
+end;
+local t=function(n,t,d)
+local e=n.conn
+h[e]=n
+if t~=nil then
+if t then
+a=u(i,e,a)
+else
+o=s(r,e,o)
+end
+end
+if d~=nil then
+if d then
+o=u(r,e,o)
+else
+a=s(i,e,a)
+end
+end
+end
+local t=function(e,o,a)
+local i=e
+if f(e)=="number"then
+i={getfd=function()return e;end}
+end
+local e={
+conn=i;
+readbuffer=o or I;
+sendbuffer=a or I;
+close=g;
+setflags=t;
+};
+t(e,o,a)
+return e
+end
+m"setmetatable"(h,{__mode="k"})
+m"setmetatable"(v,{__mode="k"})
+m"setmetatable"(w,{__mode="k"})
+K=F()
local function a(e)
-local t=Y;
+local t=W;
if e then
-Y=e;
+W=e;
end
return t;
end
return{
-_addtimer=oe,
-addclient=o,
-wrapclient=i,
-loop=P,
+_addtimer=X,
+add_task=l;
+addclient=b,
+wrapclient=c,
+watchfd=t,
+loop=B,
link=x,
-step=u,
-stats=le,
-closeall=K,
-addserver=re,
-getserver=ae,
+step=k,
+stats=ae,
+closeall=J,
+addserver=ie,
+getserver=se,
setlogger=a,
-getsettings=ie,
-setquitting=f,
-removeserver=se,
-get_backend=d,
-changesettings=ne,
+getsettings=oe,
+setquitting=p,
+removeserver=le,
+get_backend=y,
+changesettings=de,
}
end)
package.preload['util.xmppstream']=(function(...)
+local _ENV=_ENV;
+local function o(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
local e=require"lxp";
-local b=require"util.stanza";
-local k=b.stanza_mt;
-local m=error;
+local t=require"util.stanza";
+local p=t.stanza_mt;
+local f=error;
local t=tostring;
-local d=table.insert;
-local p=table.concat;
-local x=table.remove;
-local v=setmetatable;
-local q=pcall(e.new,{StartDoctypeDecl=false});
-local j=pcall(e.new,{XmlDecl=false});
+local l=table.insert;
+local w=table.concat;
+local T=table.remove;
+local y=setmetatable;
+local x=pcall(e.new,{StartDoctypeDecl=false});
+local z=pcall(e.new,{XmlDecl=false});
local a=not not e.new({}).getcurrentbytecount;
-local z=1024*1024*10;
-local o=nil;
-local y=e.new;
-local _={
+local _=1024*1024*10;
+o"xmppstream"
+local k=e.new;
+local E={
["http://www.w3.org/XML/1998/namespace\1lang"]="xml:lang";
["http://www.w3.org/XML/1998/namespace\1space"]="xml:space";
["http://www.w3.org/XML/1998/namespace\1base"]="xml:base";
["http://www.w3.org/XML/1998/namespace\1id"]="xml:id";
};
-local s="http://etherx.jabber.org/streams";
-local r="\1";
-local g="^([^"..r.."]*)"..r.."?(.*)$";
-local function h()end
-local function w(i,e,n)
-local o={};
-local w=e.streamopened;
-local f=e.streamclosed;
-local l=e.error or function(o,a,e)m("XML stream error: "..t(a)..(e and": "..t(e)or""),2);end;
-local y=e.handlestanza;
-n=n or h;
-local t=e.stream_ns or s;
-local c=e.stream_tag or"stream";
+local o="http://etherx.jabber.org/streams";
+local d="\1";
+local b="^([^"..d.."]*)"..d.."?(.*)$";
+_M.ns_separator=d;
+_M.ns_pattern=b;
+local function s()end
+function new_sax_handlers(n,e,h)
+local i={};
+local g=e.streamopened;
+local v=e.streamclosed;
+local u=e.error or function(o,a,e)f("XML stream error: "..t(a)..(e and": "..t(e)or""),2);end;
+local k=e.handlestanza;
+h=h or s;
+local t=e.stream_ns or o;
+local m=e.stream_tag or"stream";
if t~=""then
-c=t..r..c;
-end
-local b=t..r..(e.error_tag or"error");
-local z=e.default_ns;
-local u={};
+m=t..d..m;
+end
+local q=t..d..(e.error_tag or"error");
+local j=e.default_ns;
+local d={};
local s,e={};
local t=0;
-local h=0;
-function o:StartElement(m,o)
+local r=0;
+function i:StartElement(c,o)
if e and#s>0 then
-d(e,p(s));
+l(e,w(s));
s={};
end
-local r,s=m:match(g);
-if s==""then
-r,s="",r;
-end
-if r~=z or h>0 then
-o.xmlns=r;
-h=h+1;
+local s,i=c:match(b);
+if i==""then
+s,i="",s;
+end
+if s~=j or r>0 then
+o.xmlns=s;
+r=r+1;
end
for t=1,#o do
local e=o[t];
o[t]=nil;
-local t=_[e];
+local t=E[e];
if t then
o[t]=o[e];
o[e]=nil;
@@ -2701,481 +2714,408 @@
if a then
t=self:getcurrentbytecount();
end
-if i.notopen then
-if m==c then
-h=0;
-if w then
+if n.notopen then
+if c==m then
+r=0;
+if g then
if a then
-n(t);
+h(t);
t=0;
end
-w(i,o);
-end
-else
-l(i,"no-stream",m);
+g(n,o);
+end
+else
+u(n,"no-stream",c);
end
return;
end
-if r=="jabber:client"and s~="iq"and s~="presence"and s~="message"then
-l(i,"invalid-top-level-element");
-end
-e=v({name=s,attr=o,tags={}},k);
+if s=="jabber:client"and i~="iq"and i~="presence"and i~="message"then
+u(n,"invalid-top-level-element");
+end
+e=y({name=i,attr=o,tags={}},p);
else
if a then
t=t+self:getcurrentbytecount();
end
-d(u,e);
+l(d,e);
local t=e;
-e=v({name=s,attr=o,tags={}},k);
-d(t,e);
-d(t.tags,e);
-end
-end
-if j then
-function o:XmlDecl(e,e,e)
+e=y({name=i,attr=o,tags={}},p);
+l(t,e);
+l(t.tags,e);
+end
+end
+if z then
+function i:XmlDecl(e,e,e)
if a then
-n(self:getcurrentbytecount());
-end
-end
-end
-function o:StartCdataSection()
+h(self:getcurrentbytecount());
+end
+end
+end
+function i:StartCdataSection()
if a then
if e then
t=t+self:getcurrentbytecount();
else
-n(self:getcurrentbytecount());
-end
-end
-end
-function o:EndCdataSection()
+h(self:getcurrentbytecount());
+end
+end
+end
+function i:EndCdataSection()
if a then
if e then
t=t+self:getcurrentbytecount();
else
-n(self:getcurrentbytecount());
-end
-end
-end
-function o:CharacterData(o)
+h(self:getcurrentbytecount());
+end
+end
+end
+function i:CharacterData(o)
if e then
if a then
t=t+self:getcurrentbytecount();
end
-d(s,o);
+l(s,o);
elseif a then
-n(self:getcurrentbytecount());
-end
-end
-function o:EndElement(o)
+h(self:getcurrentbytecount());
+end
+end
+function i:EndElement(o)
if a then
t=t+self:getcurrentbytecount()
end
-if h>0 then
-h=h-1;
+if r>0 then
+r=r-1;
end
if e then
if#s>0 then
-d(e,p(s));
+l(e,w(s));
s={};
end
-if#u==0 then
+if#d==0 then
if a then
-n(t);
+h(t);
end
t=0;
-if o~=b then
-y(i,e);
-else
-l(i,"stream-error",e);
+if o~=q then
+k(n,e);
+else
+u(n,"stream-error",e);
end
e=nil;
else
-e=x(u);
-end
-else
-if f then
-f(i);
+e=T(d);
+end
+else
+if v then
+v(n);
end
end
end
local function a(e)
-l(i,"parse-error","restricted-xml","Restricted XML, see RFC 6120 section 11.1.");
+u(n,"parse-error","restricted-xml","Restricted XML, see RFC 6120 section 11.1.");
if not e.stop or not e:stop()then
-m("Failed to abort parsing");
-end
-end
-if q then
-o.StartDoctypeDecl=a;
-end
-o.Comment=a;
-o.ProcessingInstruction=a;
+f("Failed to abort parsing");
+end
+end
+if x then
+i.StartDoctypeDecl=a;
+end
+i.Comment=a;
+i.ProcessingInstruction=a;
local function a()
e,s,t=nil,{},0;
-u={};
-end
-local function t(t,e)
-i=e;
-end
-return o,{reset=a,set_session=t};
-end
-local function u(d,l,o)
-local t=0;
-local e;
+d={};
+end
+local function e(t,e)
+n=e;
+end
+return i,{reset=a,set_session=e};
+end
+function new(n,i,o)
+local e=0;
+local t;
if a then
-function e(e)
-t=t-e;
-end
-o=o or z;
+function t(t)
+e=e-t;
+end
+o=o or _;
elseif o then
-m("Stanza size limits are not supported on this version of LuaExpat")
-end
-local n,s=w(d,l,e);
-local i=y(n,r,false);
-local h=i.parse;
-function d.open_stream(e,a,i)
-local o=e.sends2s or e.send;
-local t={
-["xmlns:stream"]="http://etherx.jabber.org/streams",
-["xml:lang"]="en",
-xmlns=l.default_ns,
-version=e.version and(e.version>0 and"1.0"or nil),
-id=e.streamid,
-from=a or e.host,to=i,
-};
-if e.stream_attrs then
-e:stream_attrs(a,i,t)
-end
-o("");
-o(b.stanza("stream:stream",t):top_tag());
-return true;
-end
+f("Stanza size limits are not supported on this version of LuaExpat")
+end
+local i,n=new_sax_handlers(n,i,t);
+local t=k(i,d,false);
+local s=t.parse;
return{
reset=function()
-i=y(n,r,false);
-h=i.parse;
-t=0;
-s.reset();
+t=k(i,d,false);
+s=t.parse;
+e=0;
+n.reset();
end,
-feed=function(n,e)
+feed=function(n,i)
if a then
-t=t+#e;
-end
-local i,e=h(i,e);
-if a and t>o then
+e=e+#i;
+end
+local i,t=s(t,i);
+if a and e>o then
return nil,"stanza-too-large";
end
-return i,e;
+return i,t;
end,
-set_session=s.set_session;
+set_session=n.set_session;
};
end
-return{
-ns_separator=r;
-ns_pattern=g;
-new_sax_handlers=w;
-new=u;
-};
+return _M;
end)
package.preload['util.jid']=(function(...)
-local o=select;
-local a,i=string.match,string.sub;
+local _ENV=_ENV;
+local function a(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
+local t,s=string.match,string.sub;
local l=require"util.encodings".stringprep.nodeprep;
-local r=require"util.encodings".stringprep.nameprep;
-local d=require"util.encodings".stringprep.resourceprep;
-local h={
+local d=require"util.encodings".stringprep.nameprep;
+local r=require"util.encodings".stringprep.resourceprep;
+local n={
[" "]="\\20";['"']="\\22";
["&"]="\\26";["'"]="\\27";
["/"]="\\2f";[":"]="\\3a";
["<"]="\\3c";[">"]="\\3e";
["@"]="\\40";["\\"]="\\5c";
};
-local s={};
-for e,t in pairs(h)do s[t]=e;end
-local e=nil;
-local function t(e)
+local i={};
+for e,t in pairs(n)do i[t]=e;end
+a"jid"
+local function o(e)
if not e then return;end
-local i,t=a(e,"^([^@/]+)@()");
-local t,o=a(e,"^([^@/]+)()",t)
-if i and not t then return nil,nil,nil;end
-local a=a(e,"^/(.+)$",o);
-if(not t)or((not a)and#e>=o)then return nil,nil,nil;end
-return i,t,a;
-end
-local function m(e)
-local t,e=t(e);
+local i,a=t(e,"^([^@/]+)@()");
+local a,o=t(e,"^([^@/]+)()",a)
+if i and not a then return nil,nil,nil;end
+local t=t(e,"^/(.+)$",o);
+if(not a)or((not t)and#e>=o)then return nil,nil,nil;end
+return i,a,t;
+end
+split=o;
+function bare(e)
+local t,e=o(e);
if t and e then
return t.."@"..e;
end
return e;
end
-local function n(e)
-local t,e,a=t(e);
-if e and e~="."then
-if i(e,-1,-1)=="."then
-e=i(e,1,-2);
-end
-e=r(e);
+local function h(e)
+local a,e,t=o(e);
+if e then
+if s(e,-1,-1)=="."then
+e=s(e,1,-2);
+end
+e=d(e);
if not e then return;end
-if t then
-t=l(t);
-if not t then return;end
-end
if a then
-a=d(a);
+a=l(a);
if not a then return;end
end
-return t,e,a;
-end
-end
-local function i(a,e,t)
-if not e then return end
-if a and t then
+if t then
+t=r(t);
+if not t then return;end
+end
+return a,e,t;
+end
+end
+prepped_split=h;
+function prep(e)
+local a,e,t=h(e);
+if e then
+if a then
+e=a.."@"..e;
+end
+if t then
+e=e.."/"..t;
+end
+end
+return e;
+end
+function join(a,e,t)
+if a and e and t then
return a.."@"..e.."/"..t;
-elseif a then
+elseif a and e then
return a.."@"..e;
-elseif t then
+elseif e and t then
return e.."/"..t;
-end
-return e;
-end
-local function c(e)
-local a,t,e=n(e);
-return i(a,t,e);
-end
-local function u(e,a)
-local o,n,i=t(e);
-local e,t,a=t(a);
-if((e~=nil and e==o)or e==nil)and
-((t~=nil and t==n)or t==nil)and
-((a~=nil and a==i)or a==nil)then
+elseif e then
+return e;
+end
+return nil;
+end
+function compare(t,e)
+local n,i,s=o(t);
+local a,t,e=o(e);
+if((a~=nil and a==n)or a==nil)and
+((t~=nil and t==i)or t==nil)and
+((e~=nil and e==s)or e==nil)then
return true
end
return false
end
-local function l(e)
-return(o(1,t(e)));
-end
-local function d(e)
-return(o(2,t(e)));
-end
-local function r(e)
-return(o(3,t(e)));
-end
-local function a(e)return e and(e:gsub(".",h));end
-local function o(e)return e and(e:gsub("\\%x%x",s));end
-return{
-split=t;
-bare=m;
-prepped_split=n;
-join=i;
-prep=c;
-compare=u;
-node=l;
-host=d;
-resource=r;
-escape=a;
-unescape=o;
-};
+function escape(e)return e and(e:gsub(".",n));end
+function unescape(e)return e and(e:gsub("\\%x%x",i));end
+return _M;
end)
package.preload['util.events']=(function(...)
-local a=pairs;
-local s=table.insert;
-local l=table.remove;
-local r=table.sort;
-local d=setmetatable;
-local h=next;
-local e=nil;
-local function u()
-local o={};
-local t;
-local n={};
-local i={};
-local function u(n,o)
-local e=i[o];
-if not e or h(e)==nil then return;end
+local _ENV=_ENV;
+local function a(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
+local i=pairs;
+local r=table.insert;
+local s=table.sort;
+local h=setmetatable;
+local n=next;
+a"events"
+function new()
local t={};
-for e in a(e)do
-s(t,e);
-end
-r(t,function(a,t)return e[a]>e[t];end);
-n[o]=t;
+local e={};
+local function o(o,a)
+local e=e[a];
+if not e or n(e)==nil then return;end
+local t={};
+for e in i(e)do
+r(t,e);
+end
+s(t,function(a,t)return e[a]>e[t];end);
+o[a]=t;
return t;
end;
-d(o,{__index=u});
-local function s(t,n,a)
-local e=i[t];
-if e then
-e[n]=a or 0;
-else
-e={[n]=a or 0};
-i[t]=e;
-end
-o[t]=nil;
+h(t,{__index=o});
+local function h(o,i,n)
+local a=e[o];
+if a then
+a[i]=n or 0;
+else
+a={[i]=n or 0};
+e[o]=a;
+end
+t[o]=nil;
end;
-local function r(e,a)
-local t=i[e];
-if t then
-t[a]=nil;
-o[e]=nil;
-if h(t)==nil then
-i[e]=nil;
+local function s(o,i)
+local a=e[o];
+if a then
+a[i]=nil;
+t[o]=nil;
+if n(a)==nil then
+e[o]=nil;
end
end
end;
-local function m(e)
-return o[e];
-end;
-local function f(e)
-for e,t in a(e)do
-s(e,t);
+local function n(e)
+for t,e in i(e)do
+h(t,e);
end
end;
-local function c(e)
-for t,e in a(e)do
-r(t,e);
+local function a(e)
+for t,e in i(e)do
+s(t,e);
end
end;
-local function h(e,t)
-local e=o[e];
+local function o(e,...)
+local e=t[e];
if e then
-for a=1,#e do
-local e=e[a](t);
+for t=1,#e do
+local e=e[t](...);
if e~=nil then return e;end
end
end
end;
-local function u(i,s)
-local a=n[i]or t;
-if a then
-local e=#a;
-local function n(i,o)
-e=e-1;
-if e==0 then
-if t==nil or a==t then
-return h(i,o);
-end
-a,e=t,#t;
-return a[e](n,i,o);
-else
-return a[e](n,i,o);
-end
-end
-return a[e](n,i,s);
-end
-return h(i,s);
-end
-local function d(a,o)
-local e;
-if a==false then
-e=t;
-if not e then
-e={};
-t=e;
-end
-else
-e=n[a];
-if not e then
-e={};
-n[a]=e;
-end
-end
-e[#e+1]=o;
-end
-local function h(a,o)
-local e;
-if a==false then
-e=t;
-else
-e=n[a];
-end
-if not e then return;end
-for t=#e,1 do
-if e[t]==o then
-l(e,t);
-end
-end
-if#e==0 then
-if a==false then
-t=nil;
-else
-n[a]=nil;
-end
-end
-end
return{
-add_handler=s;
-remove_handler=r;
-add_handlers=f;
-remove_handlers=c;
-get_handlers=m;
-wrappers={
-add_handler=d;
-remove_handler=h;
+add_handler=h;
+remove_handler=s;
+add_handlers=n;
+remove_handlers=a;
+fire_event=o;
+_handlers=t;
+_event_map=e;
};
-add_wrapper=d;
-remove_wrapper=h;
-fire_event=u;
-_handlers=o;
-_event_map=i;
-};
-end
-return{
-new=u;
-};
+end
+return _M;
end)
package.preload['util.dataforms']=(function(...)
-local e=setmetatable;
-local t,i=pairs,ipairs;
-local d,r,u=tostring,type,next;
-local h=table.concat;
-local m=require"util.stanza";
-local l=require"util.jid".prep;
+local _ENV=_ENV;
+local function o(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
+local a=setmetatable;
+local e,i=pairs,ipairs;
+local h,r,c=tostring,type,next;
+local s=table.concat;
+local u=require"util.stanza";
+local d=require"util.jid".prep;
+o"dataforms"
+local l='jabber:x:data';
local n={};
-local c='jabber:x:data';
-local s={};
-local a={__index=s};
-function n.new(t)
-return e(t,a);
-end
-function n.from_stanza(e)
+local e={__index=n};
+function new(t)
+return a(t,e);
+end
+function from_stanza(e)
local o={
title=e:get_child_text("title");
instructions=e:get_child_text("instructions");
};
-for e in e:childtags("field")do
+for t in e:childtags("field")do
local a={
-name=e.attr.var;
-label=e.attr.label;
-type=e.attr.type;
-required=e:get_child("required")and true or nil;
-value=e:get_child_text("value");
+name=t.attr.var;
+label=t.attr.label;
+type=t.attr.type;
+required=t:get_child("required")and true or nil;
+value=t:get_child_text("value");
};
o[#o+1]=a;
if a.type then
-local t={};
+local e={};
if a.type:match"list%-"then
-for e in e:childtags("option")do
-t[#t+1]={label=e.attr.label,value=e:get_child_text("value")};
-end
-for e in e:childtags("value")do
-t[#t+1]={label=e.attr.label,value=e:get_text(),default=true};
+for t in t:childtags("option")do
+e[#e+1]={label=t.attr.label,value=t:get_child_text("value")};
+end
+for t in t:childtags("value")do
+e[#e+1]={label=t.attr.label,value=t:get_text(),default=true};
end
elseif a.type:match"%-multi"then
-for e in e:childtags("value")do
-t[#t+1]=e.attr.label and{label=e.attr.label,value=e:get_text()}or e:get_text();
+for t in t:childtags("value")do
+e[#e+1]=t.attr.label and{label=t.attr.label,value=t:get_text()}or t:get_text();
end
if a.type=="text-multi"then
-a.value=h(t,"\n");
-else
-a.value=t;
+a.value=s(e,"\n");
+else
+a.value=e;
end
end
end
end
return new(o);
end
-function s.form(t,n,e)
-local e=m.stanza("x",{xmlns=c,type=e or"form"});
+function n.form(t,n,e)
+local e=u.stanza("x",{xmlns=l,type=e or"form"});
if t.title then
e:tag("title"):text(t.title):up();
end
@@ -3193,7 +3133,7 @@
:add_child(t)
:up();
else
-e:tag("value"):text(d(t)):up();
+e:tag("value"):text(h(t)):up();
end
elseif a=="boolean"then
e:tag("value"):text((t and"1")or"0"):up();
@@ -3220,7 +3160,7 @@
a=true;
end
else
-e:tag("option",{label=t}):tag("value"):text(d(t)):up():up();
+e:tag("option",{label=t}):tag("value"):text(h(t)):up():up();
end
end
elseif a=="list-multi"then
@@ -3231,7 +3171,7 @@
e:tag("value"):text(t.value):up();
end
else
-e:tag("option",{label=t}):tag("value"):text(d(t)):up():up();
+e:tag("option",{label=t}):tag("value"):text(h(t)):up():up();
end
end
end
@@ -3244,7 +3184,7 @@
return e;
end
local e={};
-function s.data(t,n)
+function n.data(t,n)
local o={};
local a={};
for i,t in i(t)do
@@ -3266,7 +3206,7 @@
end
end
end
-if u(a)then
+if c(a)then
return o,a;
end
return o;
@@ -3285,7 +3225,7 @@
e["jid-single"]=
function(t,o)
local t=t:get_child_text("value")
-local a=l(t);
+local a=d(t);
if a and#a>0 then
return a
elseif t then
@@ -3300,14 +3240,14 @@
local t={};
for e in o:childtags("value")do
local e=e:get_text();
-local o=l(e);
+local o=d(e);
a[#a+1]=o;
if e and not o then
t[#t+1]=("Invalid JID: "..e);
end
end
if#a>0 then
-return a,(#t>0 and h(t,"\n")or nil);
+return a,(#t>0 and s(t,"\n")or nil);
elseif i then
return nil,"Required value missing";
end
@@ -3324,7 +3264,7 @@
function(t,a)
local t,a=e["list-multi"](t,a);
if t then
-t=h(t,"\n");
+t=s(t,"\n");
end
return t,a;
end
@@ -3350,24 +3290,35 @@
function(e)
return e:get_child_text("value");
end
-return n;
+return _M;
end)
package.preload['util.caps']=(function(...)
-local d=require"util.encodings".base64.encode;
-local l=require"util.hashes".sha1;
+local _ENV=_ENV;
+local function a(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
+local l=require"util.encodings".base64.encode;
+local d=require"util.hashes".sha1;
local n,s,h=table.insert,table.sort,table.concat;
local r=ipairs;
-local e=nil;
-local function u(e)
-local a,i,o={},{},{};
+a"caps"
+function calculate_hash(e)
+local a,o,i={},{},{};
for t,e in r(e)do
if e.name=="identity"then
n(a,(e.attr.category or"").."\0"..(e.attr.type or"").."\0"..(e.attr["xml:lang"]or"").."\0"..(e.attr.name or""));
elseif e.name=="feature"then
-n(i,e.attr.var or"");
+n(o,e.attr.var or"");
elseif e.name=="x"and e.attr.xmlns=="jabber:x:data"then
local t={};
-local i;
+local o;
for a,e in r(e.tags)do
if e.name=="field"and e.attr.var then
local a={};
@@ -3377,7 +3328,7 @@
end
s(a);
if e.attr.var=="FORM_TYPE"then
-i=a[1];
+o=a[1];
elseif#a>0 then
n(t,e.attr.var.."\0"..h(a,"<"));
else
@@ -3387,42 +3338,52 @@
end
s(t);
t=h(t,"<");
-if i then t=i.."\0"..t;end
-n(o,t);
+if o then t=o.."\0"..t;end
+n(i,t);
end
end
s(a);
+s(o);
s(i);
-s(o);
if#a>0 then a=h(a,"<"):gsub("%z","/").."<";else a="";end
-if#i>0 then i=h(i,"<").."<";else i="";end
-if#o>0 then o=h(o,"<"):gsub("%z","<").."<";else o="";end
-local e=a..i..o;
-local t=d(l(e));
+if#o>0 then o=h(o,"<").."<";else o="";end
+if#i>0 then i=h(i,"<"):gsub("%z","<").."<";else i="";end
+local e=a..o..i;
+local t=l(d(e));
+print(("CAPS %q %q"):format(t,e));
return t,e;
end
-return{
-calculate_hash=u;
-};
+return _M;
end)
package.preload['util.vcard']=(function(...)
-local o=require"util.stanza";
-local a,u=table.insert,table.concat;
-local h=type;
-local e,s,m=next,pairs,ipairs;
-local c,d,l,r;
-local f="\n";
-local i;
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
+local i=require"util.stanza";
+local a,h=table.insert,table.concat;
+local s=type;
+local e,n,c=next,pairs,ipairs;
+local d,r,l,u;
+local m="\n";
+local o;
local function e()
error"Not implemented"
end
local function e()
error"Not implemented"
end
-local function w(e)
+local function y(e)
return e:gsub("[,:;\\]","\\%1"):gsub("\n","\\n");
end
-local function n(e)
+local function p(e)
return e:gsub("\\?[\\nt:;,]",{
["\\\\"]="\\",
["\\n"]="\n",
@@ -3436,104 +3397,104 @@
[","]="\31",
});
end
-local function y(t)
-local a=o.stanza(t.name,{xmlns="vcard-temp"});
-local e=i[t.name];
-if e=="text"then
-a:text(t[1]);
-elseif h(e)=="table"then
-if e.types and t.TYPE then
-if h(t.TYPE)=="table"then
-for o,e in s(e.types)do
-for o,t in s(t.TYPE)do
-if t:upper()==e then
-a:tag(e):up();
+local function w(e)
+local a=i.stanza(e.name,{xmlns="vcard-temp"});
+local t=o[e.name];
+if t=="text"then
+a:text(e[1]);
+elseif s(t)=="table"then
+if t.types and e.TYPE then
+if s(e.TYPE)=="table"then
+for o,t in n(t.types)do
+for o,e in n(e.TYPE)do
+if e:upper()==t then
+a:tag(t):up();
break;
end
end
end
else
-a:tag(t.TYPE:upper()):up();
-end
-end
-if e.props then
-for o,e in s(e.props)do
-if t[e]then
-a:tag(e):up();
-end
-end
-end
-if e.value then
-a:tag(e.value):text(t[1]):up();
-elseif e.values then
-local o=e.values;
+a:tag(e.TYPE:upper()):up();
+end
+end
+if t.props then
+for o,t in n(t.props)do
+if e[t]then
+a:tag(t):up();
+end
+end
+end
+if t.value then
+a:tag(t.value):text(e[1]):up();
+elseif t.values then
+local o=t.values;
local i=o.behaviour=="repeat-last"and o[#o];
-for o=1,#t do
-a:tag(e.values[o]or i):text(t[o]):up();
+for o=1,#e do
+a:tag(t.values[o]or i):text(e[o]):up();
end
end
end
return a;
end
-local function t(e)
-local t=o.stanza("vCard",{xmlns="vcard-temp"});
+local function f(t)
+local e=i.stanza("vCard",{xmlns="vcard-temp"});
+for a=1,#t do
+e:add_child(w(t[a]));
+end
+return e;
+end
+function u(e)
+if not e[1]or e[1].name then
+return f(e)
+else
+local t=i.stanza("xCard",{xmlns="vcard-temp"});
for a=1,#e do
-t:add_child(y(e[a]));
+t:add_child(f(e[a]));
end
return t;
end
-function r(e)
-if not e[1]or e[1].name then
-return t(e)
-else
-local a=o.stanza("xCard",{xmlns="vcard-temp"});
-for o=1,#e do
-a:add_child(t(e[o]));
-end
-return a;
-end
-end
-function c(t)
+end
+function d(t)
t=t
:gsub("\r\n","\n")
:gsub("\n ","")
:gsub("\n\n+","\n");
-local h={};
+local s={};
local e;
for t in t:gmatch("[^\n]+")do
-local t=n(t);
-local s,t,n=t:match("^([-%a]+)(\30?[^\29]*)\29(.*)$");
-n=n:gsub("\29",":");
+local t=p(t);
+local n,t,i=t:match("^([-%a]+)(\30?[^\29]*)\29(.*)$");
+i=i:gsub("\29",":");
if#t>0 then
-local a={};
-for e,o,i in t:gmatch("\30([^=]+)(=?)([^\30]*)")do
-e=e:upper();
-local t={};
-for e in i:gmatch("[^\31]+")do
-t[#t+1]=e
-t[e]=true;
-end
-if o=="="then
-a[e]=t;
-else
-a[e]=true;
-end
-end
-t=a;
-end
-if s=="BEGIN"and n=="VCARD"then
+local o={};
+for a,n,i in t:gmatch("\30([^=]+)(=?)([^\30]*)")do
+a=a:upper();
+local e={};
+for t in i:gmatch("[^\31]+")do
+e[#e+1]=t
+e[t]=true;
+end
+if n=="="then
+o[a]=e;
+else
+o[a]=true;
+end
+end
+t=o;
+end
+if n=="BEGIN"and i=="VCARD"then
e={};
-h[#h+1]=e;
-elseif s=="END"and n=="VCARD"then
+s[#s+1]=e;
+elseif n=="END"and i=="VCARD"then
e=nil;
-elseif e and i[s]then
-local o=i[s];
-local i={name=s};
-e[#e+1]=i;
+elseif e and o[n]then
+local o=o[n];
+local n={name=n};
+e[#e+1]=n;
local s=e;
-e=i;
+e=n;
if o.types then
-for o,a in m(o.types)do
+for o,a in c(o.types)do
local a=a:lower();
if(t.TYPE and t.TYPE[a]==true)
or t[a]==true then
@@ -3542,12 +3503,12 @@
end
end
if o.props then
-for o,a in m(o.props)do
+for o,a in c(o.props)do
if t[a]then
if t[a]==true then
e[a]=true;
else
-for o,t in m(t[a])do
+for o,t in c(t[a])do
e[a]=t;
end
end
@@ -3555,9 +3516,9 @@
end
end
if o=="text"or o.value then
-a(e,n);
+a(e,i);
elseif o.values then
-local t="\30"..n;
+local t="\30"..i;
for t in t:gmatch("\30([^\30]*)")do
a(e,t);
end
@@ -3565,82 +3526,82 @@
e=s;
end
end
-return h;
-end
-local function n(e)
-local t={};
-for a=1,#e do
-t[a]=w(e[a]);
-end
-t=u(t,";");
+return s;
+end
+local function i(t)
+local e={};
+for a=1,#t do
+e[a]=y(t[a]);
+end
+e=h(e,";");
local a="";
-for e,t in s(e)do
-if h(e)=="string"and e~="name"then
-a=a..(";%s=%s"):format(e,h(t)=="table"and u(t,",")or t);
-end
-end
-return("%s%s:%s"):format(e.name,a,t)
-end
-local function o(t)
+for t,e in n(t)do
+if s(t)=="string"and t~="name"then
+a=a..(";%s=%s"):format(t,s(e)=="table"and h(e,",")or e);
+end
+end
+return("%s%s:%s"):format(t.name,a,e)
+end
+local function t(t)
local e={};
a(e,"BEGIN:VCARD")
for o=1,#t do
-a(e,n(t[o]));
+a(e,i(t[o]));
end
a(e,"END:VCARD")
-return u(e,f);
-end
-function d(e)
+return h(e,m);
+end
+function r(e)
if e[1]and e[1].name then
-return o(e)
-else
-local a={};
-for t=1,#e do
-a[t]=o(e[t]);
-end
-return u(a,f);
-end
-end
-local function n(o)
-local t=o.name;
-local e=i[t];
+return t(e)
+else
+local o={};
+for a=1,#e do
+o[a]=t(e[a]);
+end
+return h(o,m);
+end
+end
+local function h(i)
+local t=i.name;
+local e=o[t];
local t={name=t};
if e=="text"then
-t[1]=o:get_text();
-elseif h(e)=="table"then
+t[1]=i:get_text();
+elseif s(e)=="table"then
if e.value then
-t[1]=o:get_child_text(e.value)or"";
+t[1]=i:get_child_text(e.value)or"";
elseif e.values then
local e=e.values;
if e.behaviour=="repeat-last"then
-for e=1,#o.tags do
-a(t,o.tags[e]:get_text()or"");
-end
-else
-for i=1,#e do
-a(t,o:get_child_text(e[i])or"");
+for e=1,#i.tags do
+a(t,i.tags[e]:get_text()or"");
+end
+else
+for o=1,#e do
+a(t,i:get_child_text(e[o])or"");
end
end
elseif e.names then
local e=e.names;
for a=1,#e do
-if o:get_child(e[a])then
+if i:get_child(e[a])then
t[1]=e[a];
break;
end
end
end
if e.props_verbatim then
-for e,a in s(e.props_verbatim)do
-t[e]=a;
+for a,e in n(e.props_verbatim)do
+t[a]=e;
end
end
if e.types then
local e=e.types;
t.TYPE={};
-for i=1,#e do
-if o:get_child(e[i])then
-a(t.TYPE,e[i]:lower());
+for o=1,#e do
+if i:get_child(e[o])then
+a(t.TYPE,e[o]:lower());
end
end
if#t.TYPE==0 then
@@ -3649,9 +3610,9 @@
end
if e.props then
local e=e.props;
-for i=1,#e do
-local e=e[i]
-local o=o:get_child_text(e);
+for o=1,#e do
+local e=e[o]
+local o=i:get_child_text(e);
if o then
t[e]=t[e]or{};
a(t[e],o);
@@ -3663,11 +3624,11 @@
end
return t;
end
-local function t(e)
+local function i(e)
local e=e.tags;
local t={};
for o=1,#e do
-a(t,n(e[o]));
+a(t,h(e[o]));
end
return t
end
@@ -3677,16 +3638,16 @@
end
if e.name=="xCard"then
local a={};
-local e=e.tags;
-for o=1,#e do
-a[o]=t(e[o]);
+local t=e.tags;
+for e=1,#t do
+a[e]=i(t[e]);
end
return a
elseif e.name=="vCard"then
-return t(e)
-end
-end
-i={
+return i(e)
+end
+end
+o={
VERSION="text",
FN="text",
N={
@@ -3808,159 +3769,188 @@
},
DESC="text",
};
-i.LOGO=i.PHOTO;
-i.SOUND=i.PHOTO;
+o.LOGO=o.PHOTO;
+o.SOUND=o.PHOTO;
return{
-from_text=c;
-to_text=d;
+from_text=d;
+to_text=r;
from_xep54=l;
-to_xep54=r;
-lua_to_text=d;
-lua_to_xep54=r;
-text_to_lua=c;
-text_to_xep54=function(...)return r(c(...));end;
+to_xep54=u;
+lua_to_text=r;
+lua_to_xep54=u;
+text_to_lua=d;
+text_to_xep54=function(...)return u(d(...));end;
xep54_to_lua=l;
-xep54_to_text=function(...)return d(l(...))end;
+xep54_to_text=function(...)return r(l(...))end;
};
end)
package.preload['util.logger']=(function(...)
-local o=pairs;
-local e=nil;
-local t={};
-local e;
-local function i(t)
-local a=e(t,"debug");
-local n=e(t,"info");
-local i=e(t,"warn");
-local o=e(t,"error");
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
+local e=pcall;
+local e=string.find;
+local e,o,e=ipairs,pairs,setmetatable;
+local a={};
+local e={};
+local t;
+function a.init(e)
+local a=t(e,"debug");
+local o=t(e,"info");
+local i=t(e,"warn");
+local n=t(e,"error");
return function(t,e,...)
if t=="debug"then
return a(e,...);
elseif t=="info"then
-return n(e,...);
+return o(e,...);
elseif t=="warn"then
return i(e,...);
elseif t=="error"then
-return o(e,...);
-end
-end
-end
-function e(o,a)
-local e=t[a];
-if not e then
-e={};
-t[a]=e;
-end
-local e=function(i,...)
-for t=1,#e do
-e[t](o,a,i,...);
-end
-end
-return e;
-end
-local function n()
-for t,e in o(t)do
+return n(e,...);
+end
+end
+end
+function t(o,a)
+local t=e[a];
+if not t then
+t={};
+e[a]=t;
+end
+local e=function(e,...)
+for i=1,#t do
+t[i](o,a,e,...);
+end
+end
+return e;
+end
+function a.reset()
+for t,e in o(e)do
for t=1,#e do
e[t]=nil;
end
end
end
-local function o(e,a)
-if not t[e]then
-t[e]={a};
-else
-t[e][#t[e]+1]=a;
-end
-end
-return{
-init=i;
-make_logger=e;
-reset=n;
-add_level_sink=o;
-new=e;
-};
+function a.add_level_sink(t,o)
+if not e[t]then
+e[t]={o};
+else
+e[t][#e[t]+1]=o;
+end
+end
+a.new=t;
+return a;
end)
package.preload['util.datetime']=(function(...)
+local _ENV=_ENV;
+local function a(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
local e=os.date;
local i=os.time;
-local w=os.difftime;
-local l=tonumber;
-local t=nil;
-local function c(t)
+local u=os.difftime;
+local t=error;
+local s=tonumber;
+a"datetime"
+function date(t)
return e("!%Y-%m-%d",t);
end
-local function u(t)
+function datetime(t)
return e("!%Y-%m-%dT%H:%M:%SZ",t);
end
-local function m(t)
+function time(t)
return e("!%H:%M:%S",t);
end
-local function f(t)
+function legacy(t)
return e("!%Y%m%dT%H:%M:%S",t);
end
-local function y(t)
-if t then
-local n,d,h,s,r,o,a;
-n,d,h,s,r,o,a=t:match("^(%d%d%d%d)%-?(%d%d)%-?(%d%d)T(%d%d):(%d%d):(%d%d)%.?%d*([Z+%-]?.*)$");
+function parse(o)
+if o then
+local n,h,l,d,r,t,a;
+n,h,l,d,r,t,a=o:match("^(%d%d%d%d)%-?(%d%d)%-?(%d%d)T(%d%d):(%d%d):(%d%d)%.?%d*([Z+%-]?.*)$");
if n then
-local u=w(i(e("*t")),i(e("!*t")));
-local t=0;
+local u=u(i(e("*t")),i(e("!*t")));
+local o=0;
if a~=""and a~="Z"then
-local o,a,e=a:match("([+%-])(%d%d):?(%d*)");
-if not o then return;end
+local a,t,e=a:match("([+%-])(%d%d):?(%d*)");
+if not a then return;end
if#e~=2 then e="0";end
-a,e=l(a),l(e);
-t=a*60*60+e*60;
-if o=="-"then t=-t;end
-end
-o=(o+u)-t;
-return i({year=n,month=d,day=h,hour=s,min=r,sec=o,isdst=false});
-end
-end
-end
-return{
-date=c;
-datetime=u;
-time=m;
-legacy=f;
-parse=y;
-};
+t,e=s(t),s(e);
+o=t*60*60+e*60;
+if a=="-"then o=-o;end
+end
+t=(t+u)-o;
+return i({year=n,month=h,day=l,hour=d,min=r,sec=t,isdst=false});
+end
+end
+end
+return _M;
end)
package.preload['util.json']=(function(...)
-local v=type;
-local t,p,y,j=table.insert,table.concat,table.remove,table.sort;
-local n=string.char;
-local q,l=tostring,tonumber;
-local c,s=pairs,ipairs;
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
+local w=type;
+local t,v,p,q=table.insert,table.concat,table.remove,table.sort;
+local h=string.char;
+local j,l=tostring,tonumber;
+local u,s=pairs,ipairs;
local i=next;
-local b,w=getmetatable,setmetatable;
-local m=print;
-local a,e=pcall(require,"util.array");
-local f=a and b(e())or{};
+local e=error;
+local e,r,b=newproxy,getmetatable,setmetatable;
+local c=print;
+local a,o=pcall(require,"util.array");
+local f=a and r(o())or{};
local a={};
-local r=w({},{__tostring=function()return"null";end;});
-a.null=r;
-local d={
+local n=e and e(true)or{};
+if r and r(n)then
+r(n).__tostring=function()return"null";end;
+end
+a.null=n;
+local y={
["\""]="\\\"",["\\"]="\\\\",["\b"]="\\b",
["\f"]="\\f",["\n"]="\\n",["\r"]="\\r",["\t"]="\\t"};
local e={
["\""]="\"",["\\"]="\\",["/"]="/",
b="\b",f="\f",n="\n",r="\r",t="\t"};
-for t=0,31 do
-local e=n(t);
-if not d[e]then d[e]=("\\u%.4X"):format(t);end
+for e=0,31 do
+local t=h(e);
+if not y[t]then y[t]=("\\u%.4X"):format(e);end
end
local function x(e)
-if e<128 then return n(e);end
+if e<128 then return h(e);end
local t=e%64;
if e<2048 then
local e=(e-t)/64;
-return n(128+64+e,128+t);
+return h(128+64+e,128+t);
end
local a=e%4096;
local o=(a-t)/64;
local e=(e-a)/4096;
-return n(128+64+32+e,128+o,128+t);
+return h(128+64+32+e,128+o,128+t);
end
local g={
number=true,
@@ -3972,96 +3962,94 @@
__array=true;
__hash=true;
};
-local o,k,h,u;
-function u(a,e)
-t(e,"\""..(a:gsub(".",d)).."\"");
-end
-function h(a,e)
+local o,k,d,m;
+function m(a,e)
+t(e,"\""..(a:gsub(".",y)).."\"");
+end
+function d(a,e)
t(e,"[");
if i(a)then
for i,a in s(a)do
o(a,e);
t(e,",");
end
-y(e);
+p(e);
end
t(e,"]");
end
function k(l,e)
local a={};
-local d={};
-local n={};
-for e,t in s(l)do
-a[e]=t;
-end
-for e,t in c(l)do
-local o,i=v(e),v(t);
-if g[i]or t==r then
+local r={};
+local h={};
+for t,e in s(l)do
+a[t]=e;
+end
+for e,t in u(l)do
+local o,i=w(e),w(t);
+if g[i]or t==n then
if o=="string"and not z[e]then
-n[e]=t;
-elseif(g[o]or e==r)and a[e]==nil then
-d[e]=t;
-end
-end
-end
-if i(d)~=nil or i(n)~=nil or i(a)==nil then
+h[e]=t;
+elseif(g[o]or e==n)and a[e]==nil then
+r[e]=t;
+end
+end
+end
+if i(r)~=nil or i(h)~=nil or i(a)==nil then
t(e,"{");
-local r=#e;
+local n=#e;
if e.ordered then
local a={};
-for e in c(n)do
+for e in u(h)do
t(a,e);
end
-j(a);
+q(a);
for i,a in s(a)do
-u(a,e);
+m(a,e);
t(e,":");
-o(n[a],e);
+o(h[a],e);
t(e,",");
end
else
-for a,i in c(n)do
-u(a,e);
+for a,i in u(h)do
+m(a,e);
t(e,":");
o(i,e);
t(e,",");
end
end
-if i(d)~=nil then
+if i(r)~=nil then
t(e,"\"__hash\":[");
-for i,a in c(d)do
+for i,a in u(r)do
o(i,e);
t(e,",");
o(a,e);
t(e,",");
end
-y(e);
+p(e);
t(e,"]");
t(e,",");
end
if i(a)then
t(e,"\"__array\":");
-h(a,e);
+d(a,e);
t(e,",");
end
-if r~=#e then y(e);end
+if n~=#e then p(e);end
t(e,"}");
else
-h(a,e);
+d(a,e);
end
end
function o(e,a)
-local o=v(e);
-if e==r then
-t(a,"null");
-elseif o=="number"then
-t(a,q(e));
+local o=w(e);
+if o=="number"then
+t(a,j(e));
elseif o=="string"then
-u(e,a);
+m(e,a);
elseif o=="table"then
-local t=b(e);
+local t=r(e);
if t==f then
-h(e,a);
+d(e,a);
else
k(e,a);
end
@@ -4074,17 +4062,17 @@
function a.encode(t)
local e={};
o(t,e);
-return p(e);
+return v(e);
end
function a.encode_ordered(t)
local e={ordered=true};
o(t,e);
-return p(e);
+return v(e);
end
function a.encode_array(t)
local e={};
-h(t,e);
-return p(e);
+d(t,e);
+return v(e);
end
local function o(t,e)
return t:find("[^ \t\r\n]",e)or e;
@@ -4111,119 +4099,119 @@
end
return e;
end
-local i,h;
-local function u(t,e)
-local a={};
+local i,r;
+local function m(t,e)
+local s={};
while true do
-local n,s;
+local n,a;
e=o(t,e+1);
if t:byte(e)~=34 then
-if t:byte(e)==125 then return a,e+1;end
+if t:byte(e)==125 then return s,e+1;end
return nil,"key expected";
end
-n,e=h(t,e);
+n,e=r(t,e);
if n==nil then return nil,e;end
e=o(t,e);
if t:byte(e)~=58 then return nil,"colon expected";end
-s,e=i(t,e+1);
-if s==nil then return nil,e;end
-a[n]=s;
+a,e=i(t,e+1);
+if a==nil then return nil,e;end
+s[n]=a;
e=o(t,e);
local t=t:byte(e);
-if t==125 then return d(a),e+1;end
+if t==125 then return d(s),e+1;end
if t~=44 then return nil,"object eof";end
end
end
-local function c(a,e)
+local function u(n,e)
local s={};
local h=e;
while true do
-local n;
-n,e=i(a,e+1);
-if n==nil then
-if a:byte(h+1)==93 then return w(s,f),h+2;end
-return n,e;
-end
-t(s,n);
-e=o(a,e);
-local t=a:byte(e);
-if t==93 then return w(s,f),e+1;end
+local a;
+a,e=i(n,e+1);
+if a==nil then
+if n:byte(h+1)==93 then return b(s,f),h+2;end
+return a,e;
+end
+t(s,a);
+e=o(n,e);
+local t=n:byte(e);
+if t==93 then return b(s,f),e+1;end
if t~=44 then return nil,"array eof";end
end
end
-local s;
+local t;
local function e(e)
-local t,e=l(e:sub(3,6),16),l(e:sub(9,12),16);
-local e=t*1024+e-56613888;
-local o=e%64;
-e=(e-o)/64;
+local e,t=l(e:sub(3,6),16),l(e:sub(9,12),16);
+local e=e*1024+t-56613888;
local a=e%64;
e=(e-a)/64;
local t=e%64;
e=(e-t)/64;
-return n(240+e,128+t,128+a,128+o);
-end
-local function n(e)
+local o=e%64;
+e=(e-o)/64;
+return h(240+e,128+o,128+t,128+a);
+end
+local function s(e)
e=e:match("%x%x%x%x",3);
if e then
return x(l(e,16));
end
-s=true;
-end
-function h(a,e)
+t=true;
+end
+function r(o,e)
e=e+1;
-local t=a:find("\"",e,true);
-if t then
-local e=a:sub(e,t-1);
-s=nil;
-e=e:gsub("\\u.?.?.?.?",n);
-if s then return nil,"invalid escape";end
-return e,t+1;
+local a=o:find("\"",e,true);
+if a then
+local e=o:sub(e,a-1);
+t=nil;
+e=e:gsub("\\u.?.?.?.?",s);
+if t then return nil,"invalid escape";end
+return e,a+1;
end
return nil,"string eof";
end
-local function d(e,t)
-local e=e:match("[0-9%.%-eE%+]+",t);
-return l(e),t+#e;
-end
-local function l(t,e)
-local t,o,a=t:byte(e+1,e+3);
-if t==117 and o==108 and a==108 then
-return r,e+4;
-end
-return nil,"null parse failed";
+local function d(t,e)
+local t=t:match("[0-9%.%-eE%+]+",e);
+return l(t),e+#t;
end
local function s(t,e)
local o,a,t=t:byte(e+1,e+3);
-if o==114 and a==117 and t==101 then
+if o==117 and a==108 and t==108 then
+return n,e+4;
+end
+return nil,"null parse failed";
+end
+local function n(t,e)
+local a,t,o=t:byte(e+1,e+3);
+if a==114 and t==117 and o==101 then
return true,e+4;
end
return nil,"true parse failed";
end
-local function n(t,e)
-local t,o,a,i=t:byte(e+1,e+4);
-if t==97 and o==108 and a==115 and i==101 then
+local function h(t,e)
+local t,a,o,i=t:byte(e+1,e+4);
+if t==97 and a==108 and o==115 and i==101 then
return false,e+5;
end
return nil,"false parse failed";
end
-function i(a,e)
-e=o(a,e);
-local t=a:byte(e);
-if t==123 then
-return u(a,e);
-elseif t==91 then
-return c(a,e);
-elseif t==34 then
-return h(a,e);
-elseif t~=nil and t>=48 and t<=57 or t==45 then
-return d(a,e);
-elseif t==110 then
-return l(a,e);
-elseif t==116 then
-return s(a,e);
-elseif t==102 then
-return n(a,e);
+function i(a,t)
+t=o(a,t);
+local e=a:byte(t);
+if e==123 then
+return m(a,t);
+elseif e==91 then
+return u(a,t);
+elseif e==34 then
+return r(a,t);
+elseif e~=nil and e>=48 and e<=57 or e==45 then
+return d(a,t);
+elseif e==110 then
+return s(a,t);
+elseif e==116 then
+return n(a,t);
+elseif e==102 then
+return h(a,t);
else
return nil,"value expected";
end
@@ -4251,20 +4239,31 @@
local t=a.decode(e);
local t=a.encode(t);
if e~=t then
-m("FAILED");
-m("encoded:",e);
-m("recoded:",t);
-else
-m(e);
+c("FAILED");
+c("encoded:",e);
+c("recoded:",t);
+else
+c(e);
end
return e==t;
end
return a;
end)
package.preload['util.xml']=(function(...)
+local _ENV=_ENV;
+local function a(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
local t=require"util.stanza";
local h=require"lxp";
-local e=nil;
+a("xml")
local e=(function()
local n={
["http://www.w3.org/XML/1998/namespace"]="xml";
@@ -4299,34 +4298,44 @@
function o:CharacterData(e)
a:text(e);
end
-function o:EndElement()
+function o:EndElement(e)
a:up();
end
-local t=h.new(o,"\1");
-local e,n,i,o=t:parse(s);
-if e then e,n,i,o=t:parse();end
+local n=h.new(o,"\1");
+local e,i,t,o=n:parse(s);
+if e then e,i,t,o=n:parse();end
if e then
return a.tags[1];
else
-return e,n.." (line "..i..", col "..o..")";
+return e,i.." (line "..t..", col "..o..")";
end
end;
end)();
-return{
parse=e;
-};
+return _M;
end)
package.preload['util.rsm']=(function(...)
-local s=require"util.stanza".stanza;
-local a,i=tostring,tonumber;
-local h=type;
-local r=pairs;
-local n='http://jabber.org/protocol/rsm';
-local o={};
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
+local h=require"util.stanza".stanza;
+local t,o=tostring,tonumber;
+local n=type;
+local s=pairs;
+local i='http://jabber.org/protocol/rsm';
+local a={};
do
-local e=o;
+local e=a;
local function t(e)
-return i((e:get_text()));
+return o((e:get_text()));
end
local function a(t)
return t:get_text();
@@ -4339,62 +4348,73 @@
e.max=t;
e.index=t;
e.first=function(e)
-return{index=i(e.attr.index);e:get_text()};
+return{index=o(e.attr.index);e:get_text()};
end;
e.last=a;
e.count=t;
end
-local h=setmetatable({
-first=function(t,e)
-if h(e)=="table"then
-t:tag("first",{index=e.index}):text(e[1]):up();
-else
-t:tag("first"):text(a(e)):up();
+local r=setmetatable({
+first=function(a,e)
+if n(e)=="table"then
+a:tag("first",{index=e.index}):text(e[1]):up();
+else
+a:tag("first"):text(t(e)):up();
end
end;
-before=function(e,t)
-if t==true then
+before=function(e,a)
+if a==true then
e:tag("before"):up();
else
-e:tag("before"):text(a(t)):up();
+e:tag("before"):text(t(a)):up();
end
end
},{
-__index=function(t,e)
-return function(o,t)
-o:tag(e):text(a(t)):up();
+__index=function(e,o)
+return function(e,a)
+e:tag(o):text(t(a)):up();
end
end;
});
+local function t(e)
+local t={};
+for o in e:childtags()do
+local e=o.name;
+local a=e and a[e];
+if a then
+t[e]=a(o);
+end
+end
+return t;
+end
+local function n(t)
+local e=h("set",{xmlns=i});
+for t,o in s(t)do
+if a[t]then
+r[t](e,o);
+end
+end
+return e;
+end
local function a(e)
-local i={};
-for a in e:childtags()do
-local e=a.name;
-local t=e and o[e];
-if t then
-i[e]=t(a);
-end
-end
-return i;
-end
-local function i(t)
-local e=s("set",{xmlns=n});
-for t,a in r(t)do
-if o[t]then
-h[t](e,a);
-end
-end
-return e;
-end
-local function t(e)
-local e=e:get_child("set",n);
+local e=e:get_child("set",i);
if e and#e.tags>0 then
-return a(e);
-end
-end
-return{parse=a,generate=i,get=t};
+return t(e);
+end
+end
+return{parse=t,generate=n,get=a};
end)
package.preload['util.random']=(function(...)
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
local e=io.open("/dev/urandom","r");
if e then
return{
@@ -4406,10 +4426,21 @@
return e.rand;
end)
package.preload['util.ip']=(function(...)
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
local o={};
local i={__index=function(t,e)return(o[e])(t);end,
__tostring=function(e)return e.addr;end,
-__eq=function(e,t)return e.addr==t.addr;end};
+__eq=function(t,e)return t.addr==e.addr;end};
local n={["0"]="0000",["1"]="0001",["2"]="0010",["3"]="0011",["4"]="0100",["5"]="0101",["6"]="0110",["7"]="0111",["8"]="1000",["9"]="1001",["A"]="1010",["B"]="1011",["C"]="1100",["D"]="1101",["E"]="1110",["F"]="1111"};
local function e(e,t)
if not t then
@@ -4431,37 +4462,37 @@
end
if t=="IPv6"and e:find('.',1,true)then
local t;
-e,t=e:gsub(":(%d+)%.(%d+)%.(%d+)%.(%d+)$",function(e,a,t,o)
-return(":%04X:%04X"):format(e*256+a,t*256+o);
+e,t=e:gsub(":(%d+)%.(%d+)%.(%d+)%.(%d+)$",function(t,e,a,o)
+return(":%04X:%04X"):format(t*256+e,a*256+o);
end);
if t~=1 then return nil,"invalid-address";end
end
return setmetatable({addr=e,proto=t,zone=a},i);
end
-local function i(t)
-local e="";
-local a={};
-if t.proto=="IPv4"then
-t=t.toV4mapped;
-end
-t=(t.addr):upper();
-t:gsub("([^:]*):?",function(e)a[#a+1]=e end);
-if not t:match(":$")then a[#a]=nil;end
-for o,t in ipairs(a)do
-if t:len()==0 and o~=1 and o~=#a then
-for t=1,16*(9-#a)do
-e=e.."0";
-end
-else
-for t=1,4-t:len()do
-e=e.."0000";
-end
-for a=1,t:len()do
-e=e..n[t:sub(a,a)];
-end
-end
-end
-return e;
+local function i(a)
+local t="";
+local e={};
+if a.proto=="IPv4"then
+a=a.toV4mapped;
+end
+a=(a.addr):upper();
+a:gsub("([^:]*):?",function(t)e[#e+1]=t end);
+if not a:match(":$")then e[#e]=nil;end
+for o,a in ipairs(e)do
+if a:len()==0 and o~=1 and o~=#e then
+for e=1,16*(9-#e)do
+t=t.."0";
+end
+else
+for e=1,4-a:len()do
+t=t.."0000";
+end
+for e=1,a:len()do
+t=t..n[a:sub(e,e)];
+end
+end
+end
+return t;
end
local function t(a,t)
a,t=i(a),i(t);
@@ -4472,7 +4503,7 @@
end
return 128;
end
-local function s(t)
+local function h(t)
local e={};
t:gsub("([^.]*).?",function(t)e[#e+1]=tonumber(t)end);
if e[1]==127 then
@@ -4496,7 +4527,7 @@
return 14;
end
end
-local function n(a)
+local function i(a)
if t(a,e("::1","IPv6"))==128 then
return 0;
elseif t(a,e("2002::","IPv6"))>=16 then
@@ -4517,7 +4548,7 @@
return 1;
end
end
-local function i(a)
+local function n(a)
if t(a,e("::1","IPv6"))==128 then
return 50;
elseif t(a,e("2002::","IPv6"))>=16 then
@@ -4538,7 +4569,7 @@
return 40;
end
end
-local function h(o)
+local function s(o)
local a={};
local t="::ffff:";
o:gsub("([^.]*).?",function(e)a[#a+1]=tonumber(e)end);
@@ -4551,16 +4582,16 @@
end
function o:toV4mapped()
if self.proto~="IPv4"then return nil,"No IPv4 address"end
-local e=h(self.addr);
+local e=s(self.addr);
self.toV4mapped=e;
return e;
end
function o:label()
local e;
if self.proto=="IPv4"then
-e=n(self.toV4mapped);
-else
-e=n(self);
+e=i(self.toV4mapped);
+else
+e=i(self);
end
self.label=e;
return e;
@@ -4568,9 +4599,9 @@
function o:precedence()
local e;
if self.proto=="IPv4"then
-e=i(self.toV4mapped);
-else
-e=i(self);
+e=n(self.toV4mapped);
+else
+e=n(self);
end
self.precedence=e;
return e;
@@ -4578,126 +4609,111 @@
function o:scope()
local e;
if self.proto=="IPv4"then
-e=s(self.addr);
+e=h(self.addr);
else
e=r(self.addr);
end
self.scope=e;
return e;
end
-function o:private()
-local t=self.scope~=14;
-if not t and self.proto=="IPv4"then
-local a=self.addr;
-local e={};
-a:gsub("([^.]*).?",function(t)e[#e+1]=tonumber(t)end);
-if e[1]==127 or e[1]==10 or(e[1]==192 and e[2]==168)
-or(e[1]==172 and(e[2]>=16 or e[2]<=32))then
-t=true;
-end
-end
-self.private=t;
-return t;
-end
-local function i(t)
-local o;
-local a=t:find("/",1,true);
-if a then
-o=tonumber(t:sub(a+1,-1));
-t=t:sub(1,a-1);
-end
-return e(t),o;
-end
-local function n(e,a,o)
-local e=t(e,a);
-if o and a.proto=="IPv4"then
-e=e-96;
-end
-return e>=(o or 128);
-end
return{new_ip=e,
-commonPrefixLength=t,
-parse_cidr=i,
-match=n};
-end)
-package.preload['util.time']=(function(...)
-local e=require"socket".gettime;
-return{
-now=e;
-}
+commonPrefixLength=t};
end)
package.preload['util.sasl.scram']=(function(...)
-local i,l=require"mime".b64,require"mime".unb64;
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
+local n,u=require"mime".b64,require"mime".unb64;
local e=require"util.hashes";
local a=require"bit";
-local r=require"util.random";
-local p=tonumber;
-local d,t=string.char,string.byte;
-local s=string.gsub;
-local h=a.bxor;
-local function n(e,o)
-return(s(e,"()(.)",function(e,a)
-return d(h(t(a),t(o,e)))
+local s=require"util.random";
+local d=tonumber;
+local h,t=string.char,string.byte;
+local i=string.gsub;
+local r=a.bxor;
+local function l(e,o)
+return(i(e,"()(.)",function(a,e)
+return h(r(t(e),t(o,a)))
end));
end
-local y,e=e.sha1,e.hmac_sha1;
-local function f(o,t,i)
-local t=e(o,t.."\0\0\0\1");
-local a=t;
+local y,t=e.sha1,e.hmac_sha1;
+local function w(o,e,i)
+local e=t(o,e.."\0\0\0\1");
+local a=e;
for i=2,i do
-t=e(o,t);
-a=n(a,t);
+e=t(o,e);
+a=l(a,e);
end
return a;
end
-local function w(e)
-return e;
-end
-local function t(e)
-return(s(e,"[,=]",{[","]="=2C",["="]="=3D"}));
-end
-local function u(o,a)
-local t="n="..t(o.username);
-local d=i(r.bytes(15));
-local r="r="..d;
-local h=t..","..r;
-local s="";
-local t=o.conn:ssl()and"y"or"n";
-if a=="SCRAM-SHA-1-PLUS"then
-s=o.conn:socket():getfinished();
-t="p=tls-unique";
-end
-local u=t..",,";
-local t=u..h;
-local t,m=coroutine.yield(t);
-if t~="challenge"then return false end
-local a,t,c=m:match("(r=[^,]+),s=([^,]*),i=(%d+)");
-local c=p(c);
-t=l(t);
-if not a or not t or not c then
+local function p(e)
+return e;
+end
+local function a(e)
+return(i(e,"[,=]",{[","]="=2C",["="]="=3D"}));
+end
+local function f(e,i)
+local a="n="..a(e.username);
+local h=n(s.bytes(15));
+local c="r="..h;
+local m=a..","..c;
+local o="";
+local a=e.conn:ssl()and"y"or"n";
+if i=="SCRAM-SHA-1-PLUS"then
+o=e.conn:socket():getfinished();
+a="p=tls-unique";
+end
+local s=a..",,";
+local a=s..m;
+local a,r=coroutine.yield(a);
+if a~="challenge"then return false end
+local a,i,f=r:match("(r=[^,]+),s=([^,]*),i=(%d+)");
+local d=d(f);
+i=u(i);
+if not a or not i or not d then
return false,"Could not parse server_first_message";
-elseif a:find(d,3,true)~=3 then
+elseif a:find(h,3,true)~=3 then
return false,"nonce sent by server does not match our nonce";
-elseif a==r then
+elseif a==c then
return false,"server did not append s-nonce to nonce";
end
-local s=u..s;
-local s="c="..i(s);
-local s=s..","..a;
-local o=f(w(o.password),t,c);
-local t=e(o,"Client Key");
-local r=y(t);
-local a=h..","..m..","..s;
-local h=e(r,a);
-local n=n(t,h);
-local t=e(o,"Server Key");
-local t=e(t,a);
-local e="p="..i(n);
-local e=s..","..e;
+local o=s..o;
+local o="c="..n(o);
+local h=o..","..a;
+local o;
+local a;
+local s;
+if e.client_key and e.server_key then
+a=e.client_key;
+s=e.server_key;
+else
+if e.salted_password then
+o=e.salted_password;
+elseif e.password then
+o=w(p(e.password),i,d);
+end
+s=t(o,"Server Key");
+a=t(o,"Client Key");
+end
+local o=y(a);
+local e=m..","..r..","..h;
+local o=t(o,e);
+local a=l(a,o);
+local t=t(s,e);
+local e="p="..n(a);
+local e=h..","..e;
local e,a=coroutine.yield(e);
if e~="success"then return false,"success-expected"end
local e=a:match("v=([^,]+)");
-if l(e)~=t then
+if u(e)~=t then
return false,"server signature did not match";
end
return true;
@@ -4705,17 +4721,28 @@
return function(e,t)
if e.username and(e.password or(e.client_key or e.server_key))then
if t=="SCRAM-SHA-1"then
-return u,99;
+return f,99;
elseif t=="SCRAM-SHA-1-PLUS"then
local e=e.conn:ssl()and e.conn:socket();
if e and e.getfinished then
-return u,100;
+return f,100;
end
end
end
end
end)
package.preload['util.sasl.plain']=(function(...)
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
return function(e,t)
if t=="PLAIN"and e.username and e.password then
return function(e)
@@ -4725,6 +4752,17 @@
end
end)
package.preload['util.sasl.anonymous']=(function(...)
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
return function(t,e)
if e=="ANONYMOUS"then
return function()
@@ -4734,6 +4772,17 @@
end
end)
package.preload['verse.plugins.tls']=(function(...)
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
local a=require"verse";
local t="urn:ietf:params:xml:ns:xmpp-tls";
function a.plugins.tls(e)
@@ -4769,26 +4818,37 @@
end
end)
package.preload['verse.plugins.sasl']=(function(...)
-local n=require"verse";
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
+local i=require"verse";
local s,h=require"mime".b64,require"mime".unb64;
local a="urn:ietf:params:xml:ns:xmpp-sasl";
-function n.plugins.sasl(e)
+function i.plugins.sasl(e)
local function r(t)
if e.authenticated then return;end
e:debug("Authenticating with SASL...");
local t=t:get_child("mechanisms",a);
if not t then return end
local o={};
-local i={};
+local n={};
for t in t:childtags("mechanism")do
t=t:get_text();
e:debug("Server offers %s",t);
if not o[t]then
-local n=t:match("[^-]+");
-local s,a=pcall(require,"util.sasl."..n:lower());
+local i=t:match("[^-]+");
+local s,a=pcall(require,"util.sasl."..i:lower());
if s then
-e:debug("Loaded SASL %s module",n);
-o[t],i[t]=a(e,t);
+e:debug("Loaded SASL %s module",i);
+o[t],n[t]=a(e,t);
elseif not tostring(a):match("not found")then
e:debug("Loading failed: %s",tostring(a));
end
@@ -4803,14 +4863,14 @@
e:close();
return;
end
-table.sort(t,function(t,e)return i[t]>i[e];end);
-local t,i=t[1];
+table.sort(t,function(t,e)return n[t]>n[e];end);
+local t,n=t[1];
e:debug("Selecting %s mechanism...",t);
e.sasl_mechanism=coroutine.wrap(o[t]);
-i=e:sasl_mechanism(t);
-local t=n.stanza("auth",{xmlns=a,mechanism=t});
-if i then
-t:text(s(i));
+n=e:sasl_mechanism(t);
+local t=i.stanza("auth",{xmlns=a,mechanism=t});
+if n then
+t:text(s(n));
end
e:send(t);
return true;
@@ -4833,7 +4893,7 @@
e.authenticated=true
e:reopen();
else
-e:send(n.stanza("response",{xmlns=a}):text(s(t)));
+e:send(i.stanza("response",{xmlns=a}):text(s(t)));
end
return true;
end
@@ -4843,11 +4903,22 @@
end
end)
package.preload['verse.plugins.bind']=(function(...)
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
local t=require"verse";
-local o=require"util.jid";
+local i=require"util.jid";
local a="urn:ietf:params:xml:ns:xmpp-bind";
function t.plugins.bind(e)
-local function i(i)
+local function o(o)
if e.bound then return;end
e:debug("Binding resource...");
e:send_iq(t.iq({type="set"}):tag("bind",{xmlns=a}):tag("resource"):text(e.resource),
@@ -4856,7 +4927,7 @@
local t=t
:get_child("bind",a)
:get_child_text("jid");
-e.username,e.host,e.resource=o.split(t);
+e.username,e.host,e.resource=i.split(t);
e.jid,e.bound=t,true;
e:event("bind-success",{jid=t});
elseif t.attr.type=="error"then
@@ -4866,44 +4937,66 @@
end
end);
end
-e:hook("stream-features",i,200);
+e:hook("stream-features",o,200);
return true;
end
end)
package.preload['verse.plugins.session']=(function(...)
-local t=require"verse";
-local a="urn:ietf:params:xml:ns:xmpp-session";
-function t.plugins.session(e)
-local function i(o)
-local o=o:get_child("session",a);
-if o and not o:get_child("optional")then
-local function o(o)
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
+local a=require"verse";
+local o="urn:ietf:params:xml:ns:xmpp-session";
+function a.plugins.session(e)
+local function n(t)
+local t=t:get_child("session",o);
+if t and not t:get_child("optional")then
+local function i(t)
e:debug("Establishing Session...");
-e:send_iq(t.iq({type="set"}):tag("session",{xmlns=a}),
+e:send_iq(a.iq({type="set"}):tag("session",{xmlns=o}),
function(t)
if t.attr.type=="result"then
e:event("session-success");
elseif t.attr.type=="error"then
-local t,o,a=t:get_error();
-e:event("session-failure",{error=o,text=a,type=t});
+local t,a,o=t:get_error();
+e:event("session-failure",{error=a,text=o,type=t});
end
end);
return true;
end
-e:hook("bind-success",o);
-end
-end
-e:hook("stream-features",i);
+e:hook("bind-success",i);
+end
+end
+e:hook("stream-features",n);
return true;
end
end)
package.preload['verse.plugins.legacy']=(function(...)
-local i=require"verse";
-local s=require"util.uuid".generate;
-local o="jabber:iq:auth";
-function i.plugins.legacy(e)
-local function n(t)
-local a=t:get_child("query",o);
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
+local o=require"verse";
+local n=require"util.uuid".generate;
+local i="jabber:iq:auth";
+function o.plugins.legacy(e)
+local function s(t)
+local a=t:get_child("query",i);
if t.attr.type~="result"or not a then
local o,a,t=t:get_error();
e:debug("warn","%s %s: %s",o,a,t);
@@ -4911,11 +5004,11 @@
local t={
username=e.username;
password=e.password;
-resource=e.resource or s();
+resource=e.resource or n();
digest=false,sequence=false,token=false;
};
-local o=i.iq({to=e.host,type="set"})
-:tag("query",{xmlns=o});
+local o=o.iq({to=e.host,type="set"})
+:tag("query",{xmlns=i});
if#a>0 then
for a in a:childtags()do
local a=a.name;
@@ -4947,52 +5040,63 @@
end
end);
end
-local function t(t)
+local function a(t)
if not t.version then
-e:send_iq(i.iq({type="get"})
+e:send_iq(o.iq({type="get"})
:tag("query",{xmlns="jabber:iq:auth"})
:tag("username"):text(e.username),
-n);
-end
-end
-e:hook("opened",t);
+s);
+end
+end
+e:hook("opened",a);
end
end)
package.preload['verse.plugins.compression']=(function(...)
-local a=require"verse";
-local i=require"zlib";
-local e="http://jabber.org/features/compress"
-local t="http://jabber.org/protocol/compress"
-local e="http://etherx.jabber.org/streams";
-local e=9;
-local function h(o)
-local i,e=pcall(i.deflate,e);
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
+local t=require"verse";
+local e=require"zlib";
+local a="http://jabber.org/features/compress"
+local a="http://jabber.org/protocol/compress"
+local o="http://etherx.jabber.org/streams";
+local n=9;
+local function i(o)
+local i,e=pcall(e.deflate,n);
if i==false then
-local t=a.stanza("failure",{xmlns=t}):tag("setup-failed");
+local t=t.stanza("failure",{xmlns=a}):tag("setup-failed");
o:send(t);
o:error("Failed to create zlib.deflate filter: %s",tostring(e));
return
end
return e
end
-local function d(o)
-local i,e=pcall(i.inflate);
+local function s(o)
+local i,e=pcall(e.inflate);
if i==false then
-local t=a.stanza("failure",{xmlns=t}):tag("setup-failed");
+local t=t.stanza("failure",{xmlns=a}):tag("setup-failed");
o:send(t);
o:error("Failed to create zlib.inflate filter: %s",tostring(e));
return
end
return e
end
-local function l(e,o)
+local function h(e,o)
function e:send(i)
local i,o,n=pcall(o,tostring(i),'sync');
if i==false then
e:close({
condition="undefined-condition";
text=o;
-extra=a.stanza("failure",{xmlns=t}):tag("processing-failed");
+extra=t.stanza("failure",{xmlns=a}):tag("processing-failed");
});
e:warn("Compressed send failed: %s",tostring(o));
return;
@@ -5009,7 +5113,7 @@
e:close({
condition="undefined-condition";
text=o;
-extra=a.stanza("failure",{xmlns=t}):tag("processing-failed");
+extra=t.stanza("failure",{xmlns=a}):tag("processing-failed");
});
stream:warn("%s",tostring(o));
return;
@@ -5017,15 +5121,15 @@
return s(n,o);
end;
end
-function a.plugins.compression(e)
-local function i(o)
+function t.plugins.compression(e)
+local function n(o)
if not e.compressed then
local o=o:child_with_name("compression");
if o then
for o in o:children()do
local o=o[1]
if o=="zlib"then
-e:send(a.stanza("compress",{xmlns=t}):tag("method"):text("zlib"))
+e:send(t.stanza("compress",{xmlns=a}):tag("method"):text("zlib"))
e:debug("Enabled compression using zlib.")
return true;
end
@@ -5034,49 +5138,60 @@
end
end
end
-local function o(t)
-if t.name=="compressed"then
+local function o(a)
+if a.name=="compressed"then
e:debug("Activating compression...")
-local t=h(e);
+local a=i(e);
+if not a then return end
+local t=s(e);
if not t then return end
-local a=d(e);
-if not a then return end
-l(e,t);
-r(e,a);
+h(e,a);
+r(e,t);
e.compressed=true;
e:reopen();
-elseif t.name=="failure"then
+elseif a.name=="failure"then
e:warn("Failed to establish compression");
end
end
-e:hook("stream-features",i,250);
-e:hook("stream/"..t,o);
+e:hook("stream-features",n,250);
+e:hook("stream/"..a,o);
end
end)
package.preload['verse.plugins.smacks']=(function(...)
-local s=require"verse";
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
+local i=require"verse";
local h=require"socket".gettime;
-local n="urn:xmpp:sm:2";
-function s.plugins.smacks(e)
+local s="urn:xmpp:sm:3";
+function i.plugins.smacks(e)
local t={};
local a=0;
local r=h();
local o;
-local i=0;
-local function l(t)
+local n=0;
+local function d(t)
if t.attr.xmlns=="jabber:client"or not t.attr.xmlns then
-i=i+1;
-e:debug("Increasing handled stanzas to %d for %s",i,t:top_tag());
-end
-end
-local function d(a)
+n=n+1;
+e:debug("Increasing handled stanzas to %d for %s",n,t:top_tag());
+end
+end
+local function l(a)
if a.name and not a.attr.xmlns then
t[#t+1]=tostring(a);
r=h();
if not o then
o=true;
e:debug("Waiting to send ack request...");
-s.add_task(1,function()
+i.add_task(1,function()
if#t==0 then
o=false;
return;
@@ -5087,7 +5202,7 @@
end
e:debug("Time up, sending ...");
o=false;
-e:send(s.stanza("r",{xmlns=n}));
+e:send(i.stanza("r",{xmlns=s}));
end);
end
end
@@ -5098,20 +5213,20 @@
if e.resumption_token then
e:debug("smacks: have resumption token, reconnecting in 1s...");
e.authenticated=nil;
-s.add_task(1,function()
+i.add_task(1,function()
e:connect(e.connect_host or e.host,e.connect_port or 5222);
end);
return true;
end
end
-local function r()
+local function u()
e.resumption_token=nil;
e:unhook("disconnected",h);
end
-local function u(o)
+local function r(o)
if o.name=="r"then
-e:debug("Ack requested... acking %d handled stanzas",i);
-e:send(s.stanza("a",{xmlns=n,h=tostring(i)}));
+e:debug("Ack requested... acking %d handled stanzas",n);
+e:send(i.stanza("a",{xmlns=s,h=tostring(n)}));
elseif o.name=="a"then
local o=tonumber(o.attr.h);
if o>a then
@@ -5127,7 +5242,7 @@
elseif o.name=="enabled"then
if o.attr.id then
e.resumption_token=o.attr.id;
-e:hook("closed",r,100);
+e:hook("closed",u,100);
e:hook("disconnected",h,100);
end
elseif o.name=="resumed"then
@@ -5147,36 +5262,47 @@
e:debug("Resumed successfully");
e:event("resumed");
else
-e:warn("Don't know how to handle "..n.."/"..o.name);
-end
-end
-local function o()
+e:warn("Don't know how to handle "..s.."/"..o.name);
+end
+end
+local function t()
if not e.smacks then
e:debug("smacks: sending enable");
-e:send(s.stanza("enable",{xmlns=n,resume="true"}));
+e:send(i.stanza("enable",{xmlns=s,resume="true"}));
e.smacks=true;
-e:hook("stanza",l);
-e:hook("outgoing",d);
-end
-end
-local function a(t)
-if t:get_child("sm",n)then
+e:hook("stanza",d);
+e:hook("outgoing",l);
+end
+end
+local function a(a)
+if a:get_child("sm",s)then
e.stream_management_supported=true;
if e.smacks and e.bound then
-e:debug("Resuming stream with %d handled stanzas",i);
-e:send(s.stanza("resume",{xmlns=n,
-h=i,previd=e.resumption_token}));
+e:debug("Resuming stream with %d handled stanzas",n);
+e:send(i.stanza("resume",{xmlns=s,
+h=n,previd=e.resumption_token}));
return true;
else
-e:hook("bind-success",o,1);
+e:hook("bind-success",t,1);
end
end
end
e:hook("stream-features",a,250);
-e:hook("stream/"..n,u);
+e:hook("stream/"..s,r);
end
end)
package.preload['verse.plugins.keepalive']=(function(...)
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
local t=require"verse";
function t.plugins.keepalive(e)
e.keepalive_timeout=e.keepalive_timeout or 300;
@@ -5187,16 +5313,28 @@
end
end)
package.preload['verse.plugins.disco']=(function(...)
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
local a=require"verse";
-local r=require("mime").b64;
-local h=require("util.hashes").sha1;
+local e=require("mime").b64;
+local e=require("util.hashes").sha1;
+local r=require"util.caps".calculate_hash;
local s="http://jabber.org/protocol/caps";
local e="http://jabber.org/protocol/disco";
local i=e.."#info";
local o=e.."#items";
function a.plugins.disco(e)
e:add_plugin("presence");
-local t={
+local n={
__index=function(t,e)
local a={identities={},features={}};
if e=="identities"or e=="features"then
@@ -5206,10 +5344,10 @@
return a;
end,
};
-local n={
-__index=function(t,a)
+local t={
+__index=function(a,t)
local e={};
-t[a]=e;
+a[t]=e;
return e;
end,
};
@@ -5226,56 +5364,32 @@
[o]=true,
},
},
-},t);
-items=setmetatable({[false]={}},n);
+},n);
+items=setmetatable({[false]={}},t);
};
e.caps={}
e.caps.node='http://code.matthewwild.co.uk/verse/'
-local function n(t,e)
-if t.category0 then
+local a={};
+for t,e in pairs(self.s5b_peer_candidates or{})do
+a[#a+1]=e;
+end
+if#a>0 then
self.connecting_peer_candidates=true;
-local function s(t,e)
-self.jingle:send_command("transport-info",a.stanza("content",{creator=self.creator,name=self.name})
+local function s(e,a)
+self.jingle:send_command("transport-info",t.stanza("content",{creator=self.creator,name=self.name})
:tag("transport",{xmlns=o,sid=self.s5b_sid})
-:tag("candidate-used",{cid=t.cid}));
+:tag("candidate-used",{cid=e.cid}));
self.onconnect_callback=i;
-self.conn=e;
-end
-local e=n(self.s5b_sid..self.peer..e.jid,true);
-h(s,t,e);
+self.conn=a;
+end
+local e=h(self.s5b_sid..self.peer..e.jid,true);
+n(s,a,e);
else
e:warn("Actually, I'm going to wait for my peer to tell me its streamhost...");
self.onconnect_callback=i;
end
end
-function t:info_received(t)
+function a:info_received(a)
e:warn("Info received");
-local s=t:child_with_name("content");
+local s=a:child_with_name("content");
local i=s:child_with_name("transport");
if i:get_child("candidate-used")and not self.connecting_peer_candidates then
-local t=i:child_with_name("candidate-used");
-if t then
-local function d(i,e)
+local a=i:child_with_name("candidate-used");
+if a then
+local function i(i,e)
if self.jingle.role=="initiator"then
-self.jingle.stream:send_iq(a.iq({to=i.jid,type="set"})
+self.jingle.stream:send_iq(t.iq({to=i.jid,type="set"})
:tag("query",{xmlns=r,sid=self.s5b_sid})
:tag("activate"):text(self.jingle.peer),function(i)
if i.attr.type=="result"then
-self.jingle:send_command("transport-info",a.stanza("content",s.attr)
+self.jingle:send_command("transport-info",t.stanza("content",s.attr)
:tag("transport",{xmlns=o,sid=self.s5b_sid})
-:tag("activated",{cid=t.attr.cid}));
+:tag("activated",{cid=a.attr.cid}));
self.conn=e;
self.onconnect_callback(e);
else
@@ -6120,25 +6304,25 @@
end);
end
end
-self.jingle.stream:debug("CID: %s",self.jingle.stream.proxy65.available_streamhosts[t.attr.cid]);
+self.jingle.stream:debug("CID: %s",self.jingle.stream.proxy65.available_streamhosts[a.attr.cid]);
local t={
-self.jingle.stream.proxy65.available_streamhosts[t.attr.cid];
+self.jingle.stream.proxy65.available_streamhosts[a.attr.cid];
};
-local e=n(self.s5b_sid..e.jid..self.peer,true);
-h(d,t,e);
+local e=h(self.s5b_sid..e.jid..self.peer,true);
+n(i,t,e);
end
elseif i:get_child("activated")then
self.onconnect_callback(self.conn);
end
end
-function t:disconnect()
+function a:disconnect()
if self.conn then
self.conn:close();
end
end
-function t:handle_accepted(e)
-end
-local t={__index=t};
+function a:handle_accepted(e)
+end
+local t={__index=a};
e:hook("jingle/transport/"..o,function(e)
return setmetatable({
role=e.role,
@@ -6150,8 +6334,19 @@
end
end)
package.preload['verse.plugins.proxy65']=(function(...)
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
local a=require"verse";
-local h=require"util.uuid";
+local d=require"util.uuid";
local r=require"util.hashes".sha1;
local n={};
n.__index=n;
@@ -6222,31 +6417,31 @@
t:event("proxy65/request",e);
end);
end
-function n:new(t,n)
+function n:new(t,h)
local e=a.new(nil,{
target_jid=t;
-bytestream_sid=h.generate();
+bytestream_sid=d.generate();
});
local o=a.iq{type="set",to=t}
:tag("query",{xmlns=i,mode="tcp",sid=e.bytestream_sid});
-for t,e in ipairs(n or self.proxies)do
+for t,e in ipairs(h or self.proxies)do
o:tag("streamhost",e):up();
end
self.stream:send_iq(o,function(o)
if o.attr.type=="error"then
-local t,a,o=o:get_error();
-e:event("connection-failed",{conn=e,type=t,condition=a,text=o});
+local a,t,o=o:get_error();
+e:event("connection-failed",{conn=e,type=a,condition=t,text=o});
else
local o=o.tags[1]:get_child("streamhost-used");
e.streamhost_jid=o.attr.jid;
-local o,h;
-for a,t in ipairs(n or self.proxies)do
+local n,o;
+for a,t in ipairs(h or self.proxies)do
if t.jid==e.streamhost_jid then
-o,h=t.host,t.port;
+n,o=t.host,t.port;
break;
end
end
-e:connect(o,h);
+e:connect(n,o);
local function o()
e:unhook("connected",o);
local t=a.iq{to=e.streamhost_jid,type="set"}
@@ -6265,10 +6460,10 @@
end);
return e;
end
-function s(i,e,t,o,a)
-local t=r(t..o..a);
-local function i()
-e:unhook("connected",i);
+function s(i,e,a,t,o)
+local a=r(a..t..o);
+local function t()
+e:unhook("connected",t);
return true;
end
local function o(t)
@@ -6279,25 +6474,36 @@
e:event("connected");
return true;
end
-local function a(i)
-e:unhook("incoming-raw",a);
-if i~="\005\000"then
-local t="version-mismatch";
-if i:sub(1,1)=="\005"then
-t="authentication-failure";
-end
-return e:event("error",t);
-end
-e:send(string.char(5,1,0,3,#t)..t.."\0\0");
+local function i(t)
+e:unhook("incoming-raw",i);
+if t~="\005\000"then
+local a="version-mismatch";
+if t:sub(1,1)=="\005"then
+a="authentication-failure";
+end
+return e:event("error",a);
+end
+e:send(string.char(5,1,0,3,#a)..a.."\0\0");
e:hook("incoming-raw",o,100);
return true;
end
-e:hook("connected",i,200);
-e:hook("incoming-raw",a,100);
+e:hook("connected",t,200);
+e:hook("incoming-raw",i,100);
e:send("\005\001\000");
end
end)
package.preload['verse.plugins.jingle_ibb']=(function(...)
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
local e=require"verse";
local i=require"util.encodings".base64;
local s=require"util.uuid".generate;
@@ -6313,11 +6519,11 @@
t=e.eventable(t);
return t;
end
-function a:initiate(a,e,t)
+function a:initiate(e,t,a)
self.block=2048;
-self.stanza=t or'iq';
-self.peer=a;
-self.sid=e or tostring(self):match("%x+$");
+self.stanza=a or'iq';
+self.peer=e;
+self.sid=t or tostring(self):match("%x+$");
self.iseq=0;
self.oseq=0;
local e=function(e)
@@ -6325,10 +6531,10 @@
end
self.feeder=e;
print("Hooking incomming IQs");
-local a=self.stream;
-a:hook("iq/"..o,e)
-if t=="message"then
-a:hook("message",e)
+local t=self.stream;
+t:hook("iq/"..o,e)
+if a=="message"then
+t:hook("message",e)
end
end
function a:open(t)
@@ -6476,15 +6682,26 @@
end
end)
package.preload['verse.plugins.pubsub']=(function(...)
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
local i=require"verse";
-local h=table.insert;
+local n=table.insert;
local o="http://jabber.org/protocol/pubsub";
-local s="http://jabber.org/protocol/pubsub#owner";
+local h="http://jabber.org/protocol/pubsub#owner";
local a="http://jabber.org/protocol/pubsub#event";
local e={};
-local n={__index=e};
+local s={__index=e};
function i.plugins.pubsub(e)
-e.pubsub=setmetatable({stream=e},n);
+e.pubsub=setmetatable({stream=e},s);
e:hook("message",function(t)
local o=t.attr.from;
for t in t:childtags("event",a)do
@@ -6503,32 +6720,32 @@
end);
return true;
end
-function e:create(e,t,a)
-return self:service(e):node(t):create(nil,a);
-end
-function e:subscribe(e,t,a,o)
-return self:service(e):node(t):subscribe(a,nil,o);
-end
-function e:publish(i,o,t,e,a)
-return self:service(i):node(o):publish(t,nil,e,a);
+function e:create(e,a,t)
+return self:service(e):node(a):create(nil,t);
+end
+function e:subscribe(a,e,o,t)
+return self:service(a):node(e):subscribe(o,nil,t);
+end
+function e:publish(e,a,o,i,t)
+return self:service(e):node(a):publish(o,nil,i,t);
end
local a={};
local t={__index=a};
function e:service(e)
return setmetatable({stream=self.stream,service=e},t)
end
-local function t(r,h,e,a,n,s,t)
-local e=i.iq{type=r or"get",to=h}
-:tag("pubsub",{xmlns=e or o})
-if a then e:tag(a,{node=n,jid=s});end
+local function t(h,e,r,a,s,n,t)
+local e=i.iq{type=h or"get",to=e}
+:tag("pubsub",{xmlns=r or o})
+if a then e:tag(a,{node=s,jid=n});end
if t then e:tag("item",{id=t~=true and t or nil});end
return e;
end
function a:subscriptions(a)
self.stream:send_iq(t(nil,self.service,nil,"subscriptions")
-,a and function(i)
-if i.attr.type=="result"then
-local e=i:get_child("pubsub",o);
+,a and function(t)
+if t.attr.type=="result"then
+local e=t:get_child("pubsub",o);
local e=e and e:get_child("subscriptions");
local o={};
if e then
@@ -6536,32 +6753,32 @@
local e=self:node(t.attr.node)
e.subscription=t;
e.subscribed_jid=t.attr.jid;
-h(o,e);
+n(o,e);
end
end
a(o);
else
-a(false,i:get_error());
+a(false,t:get_error());
end
end or nil);
end
-function a:affiliations(e)
+function a:affiliations(a)
self.stream:send_iq(t(nil,self.service,nil,"affiliations")
-,e and function(t)
-if t.attr.type=="result"then
-local t=t:get_child("pubsub",o);
-local t=t and t:get_child("affiliations")or{};
-local a={};
-if t then
-for t in t:childtags("affiliation")do
-local e=self:node(t.attr.node)
-e.affiliation=t;
-h(a,e);
-end
-end
-e(a);
-else
-e(false,t:get_error());
+,a and function(e)
+if e.attr.type=="result"then
+local e=e:get_child("pubsub",o);
+local e=e and e:get_child("affiliations")or{};
+local t={};
+if e then
+for e in e:childtags("affiliation")do
+local a=self:node(e.attr.node)
+a.affiliation=e;
+n(t,a);
+end
+end
+a(t);
+else
+a(false,e:get_error());
end
end or nil);
end
@@ -6580,7 +6797,7 @@
function a:node(e)
return setmetatable({stream=self.stream,service=self.service,node=e},o)
end
-function n:__call(t,e)
+function s:__call(t,e)
local t=self:service(t);
return e and t:node(e)or t;
end
@@ -6605,11 +6822,11 @@
end
end
end
-function e:create(e,a)
-if e~=nil then
+function e:create(a,e)
+if a~=nil then
error("Not implemented yet.");
else
-self.stream:send_iq(t("set",self.service,nil,"create",self.node),a);
+self.stream:send_iq(t("set",self.service,nil,"create",self.node),e);
end
end
function e:configure(e,a)
@@ -6618,13 +6835,13 @@
end
self.stream:send_iq(t("set",self.service,nil,e==nil and"default"or"configure",self.node),a);
end
-function e:publish(i,a,e,o)
-if a~=nil then
+function e:publish(a,e,o,i)
+if e~=nil then
error("Node configuration is not implemented yet.");
end
-self.stream:send_iq(t("set",self.service,nil,"publish",self.node,nil,i or true)
-:add_child(e)
-,o);
+self.stream:send_iq(t("set",self.service,nil,"publish",self.node,nil,a or true)
+:add_child(o)
+,i);
end
function e:subscribe(e,o,a)
e=e or self.stream.jid;
@@ -6660,22 +6877,33 @@
self.stream:send_iq(t("get",self.service,nil,"items",self.node,nil,e)
,a);
end
-function e:retract(e,a)
-self.stream:send_iq(t("set",self.service,nil,"retract",self.node,nil,e)
-,a);
+function e:retract(a,e)
+self.stream:send_iq(t("set",self.service,nil,"retract",self.node,nil,a)
+,e);
end
function e:purge(a,e)
assert(not a,"Not implemented yet.");
-self.stream:send_iq(t("set",self.service,s,"purge",self.node)
+self.stream:send_iq(t("set",self.service,h,"purge",self.node)
,e);
end
function e:delete(a,e)
assert(not a,"Not implemented yet.");
-self.stream:send_iq(t("set",self.service,s,"delete",self.node)
+self.stream:send_iq(t("set",self.service,h,"delete",self.node)
,e);
end
end)
package.preload['verse.plugins.pep']=(function(...)
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
local e=require"verse";
local t="http://jabber.org/protocol/pubsub";
local t=t.."#event";
@@ -6700,12 +6928,23 @@
e:remove_disco_feature(t.."+notify");
end
end
-function e:publish_pep(t,a)
-return e.pubsub:service(nil):node(a or t.attr.xmlns):publish(nil,nil,t)
+function e:publish_pep(t,a,o)
+return e.pubsub:service(nil):node(a or t.attr.xmlns):publish(o or"current",nil,t)
end
end
end)
package.preload['verse.plugins.adhoc']=(function(...)
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
local o=require"verse";
local n=require"lib.adhoc";
local t="http://jabber.org/protocol/commands";
@@ -6717,24 +6956,24 @@
e:add_plugin("disco");
e:add_disco_feature(t);
function e:query_commands(a,o)
-e:disco_items(a,t,function(t)
+e:disco_items(a,t,function(a)
e:debug("adhoc list returned")
-local a={};
-for o,t in ipairs(t)do
-a[t.node]=t.name;
+local t={};
+for o,a in ipairs(a)do
+t[a.node]=a.name;
end
e:debug("adhoc calling callback")
-return o(a);
+return o(t);
end);
end
-function e:execute_command(i,o,t)
+function e:execute_command(t,i,o)
local e=setmetatable({
-stream=e,jid=i,
-command=o,callback=t
+stream=e,jid=t,
+command=i,callback=o
},a);
return e:execute();
end
-local function s(t,e)
+local function h(t,e)
if not(e)or e=="user"then return true;end
if type(e)=="function"then
return e(t);
@@ -6745,24 +6984,24 @@
e:add_disco_item({jid=e.jid,node=a,name=o},t);
return i[a];
end
-local function h(t)
-local a=t.tags[1];
-local a=a.attr.node;
-local a=i[a];
-if not a then return;end
-if not s(t.attr.from,a.permission)then
-e:send(o.error_reply(t,"auth","forbidden","You don't have permission to execute this command"):up()
-:add_child(a:cmdtag("canceled")
+local function s(a)
+local t=a.tags[1];
+local t=t.attr.node;
+local t=i[t];
+if not t then return;end
+if not h(a.attr.from,t.permission)then
+e:send(o.error_reply(a,"auth","forbidden","You don't have permission to execute this command"):up()
+:add_child(t:cmdtag("canceled")
:tag("note",{type="error"}):text("You don't have permission to execute this command")));
return true
end
-return n.handle_cmd(a,{send=function(t)return e:send(t)end},t);
+return n.handle_cmd(t,{send=function(t)return e:send(t)end},a);
end
e:hook("iq/"..t,function(e)
-local t=e.attr.type;
-local a=e.tags[1].name;
-if t=="set"and a=="command"then
-return h(e);
+local a=e.attr.type;
+local t=e.tags[1].name;
+if a=="set"and t=="command"then
+return s(e);
end
end);
end
@@ -6786,20 +7025,31 @@
self:_process_response(e);
end);
end
-function a:next(a)
-local e=o.iq({to=self.jid,type="set"})
+function a:next(e)
+local t=o.iq({to=self.jid,type="set"})
:tag("command",{
xmlns=t,
node=self.command,
sessionid=self.sessionid
});
-if a then e:add_child(a);end
-self.stream:send_iq(e,function(e)
+if e then t:add_child(e);end
+self.stream:send_iq(t,function(e)
self:_process_response(e);
end);
end
end)
package.preload['verse.plugins.presence']=(function(...)
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
local a=require"verse";
function a.plugins.presence(t)
t.last_presence=nil;
@@ -6809,8 +7059,8 @@
end
end,1);
function t:resend_presence()
-if last_presence then
-t:send(last_presence);
+if self.last_presence then
+t:send(self.last_presence);
end
end
function t:set_status(e)
@@ -6819,42 +7069,55 @@
if e.show then
a:tag("show"):text(e.show):up();
end
-if e.prio then
-a:tag("priority"):text(tostring(e.prio)):up();
-end
-if e.msg then
-a:tag("status"):text(e.msg):up();
-end
+if e.priority or e.prio then
+a:tag("priority"):text(tostring(e.priority or e.prio)):up();
+end
+if e.status or e.msg then
+a:tag("status"):text(e.status or e.msg):up();
+end
+elseif type(e)=="string"then
+a:tag("status"):text(e):up();
end
t:send(a);
end
end
end)
package.preload['verse.plugins.private']=(function(...)
-local t=require"verse";
-local a="jabber:iq:private";
-function t.plugins.private(o)
-function o:private_set(o,i,e,n)
-local t=t.iq({type="set"})
-:tag("query",{xmlns=a});
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
+local a=require"verse";
+local t="jabber:iq:private";
+function a.plugins.private(o)
+function o:private_set(i,o,e,n)
+local t=a.iq({type="set"})
+:tag("query",{xmlns=t});
if e then
-if e.name==o and e.attr and e.attr.xmlns==i then
+if e.name==i and e.attr and e.attr.xmlns==o then
t:add_child(e);
else
-t:tag(o,{xmlns=i})
+t:tag(i,{xmlns=o})
:add_child(e);
end
end
self:send_iq(t,n);
end
-function o:private_get(e,o,i)
-self:send_iq(t.iq({type="get"})
-:tag("query",{xmlns=a})
-:tag(e,{xmlns=o}),
-function(t)
-if t.attr.type=="result"then
-local t=t:get_child("query",a);
-local e=t:get_child(e,o);
+function o:private_get(o,e,i)
+self:send_iq(a.iq({type="get"})
+:tag("query",{xmlns=t})
+:tag(o,{xmlns=e}),
+function(a)
+if a.attr.type=="result"then
+local t=a:get_child("query",t);
+local e=t:get_child(o,e);
i(e);
end
end);
@@ -6862,13 +7125,24 @@
end
end)
package.preload['verse.plugins.roster']=(function(...)
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
local i=require"verse";
-local d=require"util.jid".bare;
+local l=require"util.jid".bare;
local a="jabber:iq:roster";
local o="urn:xmpp:features:rosterver";
local n=table.insert;
function i.plugins.roster(t)
-local r=false;
+local h=false;
local e={
items={};
ver="";
@@ -6876,7 +7150,7 @@
t.roster=e;
t:hook("stream-features",function(e)
if e:get_child("ver",o)then
-r=true;
+h=true;
end
end);
local function s(t)
@@ -6892,17 +7166,17 @@
end
return e;
end
-local function l(o)
+local function d(a)
local e={};
-local a={};
-e.groups=a;
-for t,a in pairs(o.attr)do
+local t={};
+e.groups=t;
+for t,a in pairs(a.attr)do
if t~="xmlns"then
e[t]=a
end
end
-for e in o:childtags("group")do
-n(a,e:get_text())
+for e in a:childtags("group")do
+n(t,e:get_text())
end
return e;
end
@@ -6915,8 +7189,8 @@
items=e.items,
};
end
-function e:add_contact(o,n,h,e)
-local o={jid=o,name=n,groups=h};
+function e:add_contact(n,o,h,e)
+local o={jid=n,name=o,groups=h};
local a=i.iq({type="set"})
:tag("query",{xmlns=a})
:add_child(s(o));
@@ -6945,24 +7219,24 @@
end
end);
end
-local function h(t)
-local t=l(t);
+local function r(t)
+local t=d(t);
e.items[t.jid]=t;
end
-local function l(t)
+local function d(t)
local a=e.items[t];
e.items[t]=nil;
return a;
end
function e:fetch(o)
-t:send_iq(i.iq({type="get"}):tag("query",{xmlns=a,ver=r and e.ver or nil}),
+t:send_iq(i.iq({type="get"}):tag("query",{xmlns=a,ver=h and e.ver or nil}),
function(t)
if t.attr.type=="result"then
local t=t:get_child("query",a);
if t then
e.items={};
for t in t:childtags("item")do
-h(t)
+r(t)
end
e.ver=t.attr.ver or"";
end
@@ -6972,41 +7246,52 @@
end
end);
end
-t:hook("iq/"..a,function(n)
-local s,o=n.attr.type,n.attr.from;
-if s=="set"and(not o or o==d(t.jid))then
-local s=n:get_child("query",a);
-local o=s and s:get_child("item");
+t:hook("iq/"..a,function(o)
+local s,n=o.attr.type,o.attr.from;
+if s=="set"and(not n or n==l(t.jid))then
+local n=o:get_child("query",a);
+local a=n and n:get_child("item");
+if a then
+local i,o;
+local s=a.attr.jid;
+if a.attr.subscription=="remove"then
+i="removed"
+o=d(s);
+else
+i=e.items[s]and"changed"or"added";
+r(a)
+o=e.items[s];
+end
+e.ver=n.attr.ver;
if o then
-local n,a;
-local i=o.attr.jid;
-if o.attr.subscription=="remove"then
-n="removed"
-a=l(i);
-else
-n=e.items[i]and"changed"or"added";
-h(o)
-a=e.items[i];
-end
-e.ver=s.attr.ver;
-if a then
-t:event("roster/item-"..n,a);
-end
-end
-t:send(i.reply(n))
+t:event("roster/item-"..i,o);
+end
+end
+t:send(i.reply(o))
return true;
end
end);
end
end)
package.preload['verse.plugins.register']=(function(...)
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
local t=require"verse";
-local o="jabber:iq:register";
+local i="jabber:iq:register";
function t.plugins.register(e)
-local function a(i)
-if i:get_child("register","http://jabber.org/features/iq-register")then
+local function a(o)
+if o:get_child("register","http://jabber.org/features/iq-register")then
local t=t.iq({to=e.host_,type="set"})
-:tag("query",{xmlns=o})
+:tag("query",{xmlns=i})
:tag("username"):text(e.username):up()
:tag("password"):text(e.password):up();
if e.register_email then
@@ -7032,8 +7317,19 @@
end
end)
package.preload['verse.plugins.groupchat']=(function(...)
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
local i=require"verse";
-local e=require"events";
+local e=require"util.events";
local n=require"util.jid";
local a={};
a.__index=a;
@@ -7051,17 +7347,17 @@
end
if t and t.opts.source and e.attr.to~=t.opts.source then return end
if t then
-local i=select(3,n.split(e.attr.from));
+local o=select(3,n.split(e.attr.from));
local n=e:get_child_text("body");
-local o=e:get_child("delay",h);
+local i=e:get_child("delay",h);
local a={
room_jid=a;
room=t;
-sender=t.occupants[i];
-nick=i;
+sender=t.occupants[o];
+nick=o;
body=n;
stanza=e;
-delay=(o and o.attr.stamp);
+delay=(i and i.attr.stamp);
};
local t=t:event(e.name,a);
return t or(e.name=="message")or nil;
@@ -7175,17 +7471,17 @@
end
self:send(e);
end
-function a:admin_set(e,a,t,o)
+function a:admin_set(a,t,o,e)
self:send(i.iq({type="set"})
:query(s.."#admin")
-:tag("item",{nick=e,[a]=t})
-:tag("reason"):text(o or""));
-end
-function a:set_role(e,a,t)
-self:admin_set(e,"role",a,t);
-end
-function a:set_affiliation(e,t,a)
-self:admin_set(e,"affiliation",t,a);
+:tag("item",{nick=a,[t]=o})
+:tag("reason"):text(e or""));
+end
+function a:set_role(t,e,a)
+self:admin_set(t,"role",e,a);
+end
+function a:set_affiliation(a,e,t)
+self:admin_set(a,"affiliation",e,t);
end
function a:kick(e,t)
self:set_role(e,"none",t);
@@ -7195,6 +7491,17 @@
end
end)
package.preload['verse.plugins.vcard']=(function(...)
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
local i=require"verse";
local o=require"util.vcard";
local e="vcard-temp";
@@ -7229,6 +7536,17 @@
end
end)
package.preload['verse.plugins.vcard_update']=(function(...)
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
local n=require"verse";
local i="vcard-temp:x:update";
local s=require("util.hashes").sha1;
@@ -7248,16 +7566,16 @@
e:add_plugin("vcard");
e:add_plugin("presence");
local t;
-local function r(o)
-local a;
-for e=1,#o do
-if o[e].name=="PHOTO"then
-a=o[e][1];
+local function r(a)
+local o;
+for e=1,#a do
+if a[e].name=="PHOTO"then
+o=a[e][1];
break
end
end
-if a then
-local a=s(h(a),true);
+if o then
+local a=s(h(o),true);
t=n.stanza("x",{xmlns=i})
:tag("photo"):text(a);
e:resend_presence()
@@ -7285,19 +7603,30 @@
end
end)
package.preload['verse.plugins.carbons']=(function(...)
-local o=require"verse";
-local a="urn:xmpp:carbons:2";
-local r="urn:xmpp:forward:0";
-local h=os.time;
-local s=require"util.datetime".parse;
-local n=require"util.jid".bare;
-function o.plugins.carbons(e)
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
+local a=require"verse";
+local o="urn:xmpp:carbons:2";
+local n="urn:xmpp:forward:0";
+local s=os.time;
+local r=require"util.datetime".parse;
+local h=require"util.jid".bare;
+function a.plugins.carbons(e)
local t={};
t.enabled=false;
e.carbons=t;
function t:enable(i)
-e:send_iq(o.iq{type="set"}
-:tag("enable",{xmlns=a})
+e:send_iq(a.iq{type="set"}
+:tag("enable",{xmlns=o})
,function(e)
local e=e.attr.type=="result";
if e then
@@ -7309,8 +7638,8 @@
end or nil);
end
function t:disable(i)
-e:send_iq(o.iq{type="set"}
-:tag("disable",{xmlns=a})
+e:send_iq(a.iq{type="set"}
+:tag("disable",{xmlns=o})
,function(e)
local e=e.attr.type=="result";
if e then
@@ -7321,24 +7650,24 @@
end
end or nil);
end
-local o;
+local i;
e:hook("bind-success",function()
-o=n(e.jid);
+i=h(e.jid);
end);
-e:hook("message",function(i)
-local t=i:get_child(nil,a);
-if i.attr.from==o and t then
+e:hook("message",function(a)
+local t=a:get_child(nil,o);
+if a.attr.from==i and t then
local o=t.name;
-local t=t:get_child("forwarded",r);
+local t=t:get_child("forwarded",n);
local a=t and t:get_child("message","jabber:client");
local t=t:get_child("delay","urn:xmpp:delay");
local t=t and t.attr.stamp;
-t=t and s(t);
+t=t and r(t);
if a then
return e:event("carbon",{
dir=o,
stanza=a,
-timestamp=t or h(),
+timestamp=t or s(),
});
end
end
@@ -7346,75 +7675,85 @@
end
end)
package.preload['verse.plugins.archive']=(function(...)
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
local a=require"verse";
local t=require"util.stanza";
-local e="urn:xmpp:mam:0"
-local h="urn:xmpp:forward:0";
-local l="urn:xmpp:delay";
-local o=require"util.uuid".generate;
-local u=require"util.datetime".parse;
-local n=require"util.datetime".datetime;
-local i=require"util.dataforms".new;
-local r=require"util.rsm";
-local c={};
-local m=i{
+local e="urn:xmpp:mam:2"
+local n="urn:xmpp:forward:0";
+local c="urn:xmpp:delay";
+local d=require"util.uuid".generate;
+local m=require"util.datetime".parse;
+local s=require"util.datetime".datetime;
+local o=require"util.dataforms".new;
+local h=require"util.rsm";
+local l={};
+local u=o{
{name="FORM_TYPE";type="hidden";value=e;};
{name="with";type="jid-single";};
{name="start";type="text-single"};
{name="end";type="text-single";};
};
-function a.plugins.archive(s)
-function s:query_archive(d,a,s)
-local i=o();
-local o=t.iq{type="set",to=d}
-:tag("query",{xmlns=e,queryid=i});
-local t,d=tonumber(a["start"]),tonumber(a["end"]);
-a["start"]=t and n(t);
-a["end"]=d and n(d);
-o:add_child(m:form(a,"submit"));
-o:add_child(r.generate(a));
-local a={};
-local function n(o)
-local t=o:get_child("fin",e)
-if t and t.attr.queryid==i then
-local e=r.get(t);
-for t,e in pairs(e or c)do a[t]=e;end
-self:unhook("message",n);
-s(a);
+function a.plugins.archive(i)
+function i:query_archive(o,a,r)
+local d=d();
+local o=t.iq{type="set",to=o}
+:tag("query",{xmlns=e,queryid=d});
+local i,t=tonumber(a["start"]),tonumber(a["end"]);
+a["start"]=i and s(i);
+a["end"]=t and s(t);
+o:add_child(u:form(a,"submit"));
+o:add_child(h.generate(a));
+local t={};
+local function i(o)
+local a=o:get_child("result",e);
+if a and a.attr.queryid==d then
+local e=a:get_child("forwarded",n);
+e=e or o:get_child("forwarded",n);
+local o=a.attr.id;
+local a=e:get_child("delay",c);
+local a=a and m(a.attr.stamp)or nil;
+local e=e:get_child("message","jabber:client")
+t[#t+1]={id=o,stamp=a,message=e};
return true
end
-local e=o:get_child("result",e);
-if e and e.attr.queryid==i then
-local t=e:get_child("forwarded",h);
-t=t or o:get_child("forwarded",h);
-local o=e.attr.id;
-local e=t:get_child("delay",l);
-local e=e and u(e.attr.stamp)or nil;
-local t=t:get_child("message","jabber:client")
-a[#a+1]={id=o,stamp=e,message=t};
-return true
-end
-end
-self:hook("message",n,1);
-self:send_iq(o,function(e)
-if e.attr.type=="error"then
-self:warn(table.concat({e:get_error()}," "))
-self:unhook("message",n);
-s(false,e:get_error())
-end
+end
+self:hook("message",i,1);
+self:send_iq(o,function(a)
+self:unhook("message",i);
+if a.attr.type=="error"then
+self:warn(table.concat({a:get_error()}," "))
+r(false,a:get_error())
+return true;
+end
+local e=a:get_child("fin",e)
+if e then
+local e=h.get(e);
+for a,e in pairs(e or l)do t[a]=e;end
+end
+r(t);
return true
end);
end
-local i={
+local n={
always=true,[true]="always",
never=false,[false]="never",
roster="roster",
}
-local function h(t)
+local function s(t)
local e={};
local a=t.attr.default;
if a then
-e[false]=i[a];
+e[false]=n[a];
end
local a=t:get_child("always");
if a then
@@ -7432,11 +7771,11 @@
end
return e;
end
-local function n(o)
+local function h(o)
local a
a,o[false]=o[false],nil;
if a~=nil then
-a=i[a];
+a=n[a];
end
local i=t.stanza("prefs",{xmlns=e,default=a})
local a=t.stanza("always");
@@ -7446,31 +7785,42 @@
end
return i:add_child(a):add_child(e);
end
-function s:archive_prefs_get(a)
+function i:archive_prefs_get(a)
self:send_iq(t.iq{type="get"}:tag("prefs",{xmlns=e}),
function(e)
if e and e.attr.type=="result"and e.tags[1]then
-local t=h(e.tags[1]);
+local t=s(e.tags[1]);
a(t,e);
else
a(nil,e);
end
end);
end
-function s:archive_prefs_set(a,e)
-self:send_iq(t.iq{type="set"}:add_child(n(a)),e);
+function i:archive_prefs_set(e,a)
+self:send_iq(t.iq{type="set"}:add_child(h(e)),a);
end
end
end)
package.preload['util.http']=(function(...)
-local t,h=string.format,string.char;
-local r,s,i=pairs,ipairs,tonumber;
-local o,d=table.insert,table.concat;
-local function n(e)
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
+local t,n=string.format,string.char;
+local o,s,h=pairs,ipairs,tonumber;
+local i,d=table.insert,table.concat;
+local function r(e)
return e and(e:gsub("[^a-zA-Z0-9.~_-]",function(e)return t("%%%02x",e:byte());end));
end
local function a(e)
-return e and(e:gsub("%%(%x%x)",function(e)return h(i(e,16));end));
+return e and(e:gsub("%%(%x%x)",function(e)return n(h(e,16));end));
end
local function e(e)
return e and(e:gsub("%W",function(e)
@@ -7481,47 +7831,57 @@
end
end));
end
-local function h(t)
+local function n(t)
local a={};
if t[1]then
-for i,t in s(t)do
-o(a,e(t.name).."="..e(t.value));
-end
-else
-for t,i in r(t)do
-o(a,e(t).."="..e(i));
+for o,t in s(t)do
+i(a,e(t.name).."="..e(t.value));
+end
+else
+for o,t in o(t)do
+i(a,e(o).."="..e(t));
end
end
return d(a,"&");
end
local function s(e)
if not e:match("=")then return a(e);end
-local i={};
-for t,e in e:gmatch("([^=&]*)=([^&]*)")do
-t,e=t:gsub("%+","%%20"),e:gsub("%+","%%20");
-t,e=a(t),a(e);
-o(i,{name=t,value=e});
-i[t]=e;
-end
-return i;
-end
-local function t(e,t)
+local o={};
+for e,t in e:gmatch("([^=&]*)=([^&]*)")do
+e,t=e:gsub("%+","%%20"),t:gsub("%+","%%20");
+e,t=a(e),a(t);
+i(o,{name=e,value=t});
+o[e]=t;
+end
+return o;
+end
+local function o(e,t)
e=","..e:gsub("[ \t]",""):lower()..",";
return e:find(","..t:lower()..",",1,true)~=nil;
end
return{
-urlencode=n,urldecode=a;
-formencode=h,formdecode=s;
-contains_token=t;
+urlencode=r,urldecode=a;
+formencode=n,formdecode=s;
+contains_token=o;
};
end)
package.preload['net.http.parser']=(function(...)
-local c=tonumber;
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
+local m=tonumber;
local a=assert;
-local g,u=table.insert,table.concat;
-local q=require"socket.url".parse;
+local v=require"socket.url".parse;
local t=require"util.http".urldecode;
-local function k(e)
+local function b(e)
e=t((e:gsub("//+","/")));
if e:sub(1,1)~="/"then
e="/"..e;
@@ -7539,154 +7899,132 @@
end
return e;
end
-local v={};
-function v.new(f,r,e,l)
-local m=true;
-if not e or e=="server"then m=false;else a(e=="client","Invalid parser type");end
-local e,o,i={},0,true;
-local v=c(l and l().body_size_limit)or 10*1024*1024;
-local p=c(l and l().buffer_size_limit)or v*2;
-local b,a,h;
-local d=nil;
-local n;
+local y={};
+function y.new(c,h,e,y)
+local d=true;
+if not e or e=="server"then d=false;else a(e=="client","Invalid parser type");end
+local e="";
+local p,o,r;
+local s=nil;
local t;
-local y;
-local s;
+local a;
+local u;
+local n;
return{
-feed=function(j,w)
-if s then return nil,"parse has failed";end
-if not w then
-if i then e,i=u(e),false;end
-if d and m and not t then
-n.body=e;
-f(n);
+feed=function(l,i)
+if n then return nil,"parse has failed";end
+if not i then
+if s and d and not a then
+t.body=e;
+c(t);
elseif e~=""then
-s=true;return r("unexpected-eof");
+n=true;return h();
end
return;
end
-if i then
-g(e,w);
-else
-e={e,w};
-i=true;
-end
-o=o+#w;
-if o>p then s=true;return r("max-buffer-size-exceeded");end
-while o>0 do
-if d==nil then
-if i then e,i=u(e),false;end
+e=e..i;
+while#e>0 do
+if s==nil then
local f=e:find("\r\n\r\n",nil,true);
if not f then return;end
-local w,h,u,i,g;
-local p;
-local a={};
+local w,r,l,i,g;
+local c;
+local o={};
for t in e:sub(1,f+1):gmatch("([^\r\n]+)\r\n")do
-if p then
+if c then
local e,t=t:match("^([^%s:]+): *(.*)$");
-if not e then s=true;return r("invalid-header-line");end
+if not e then n=true;return h("invalid-header-line");end
e=e:lower();
-a[e]=a[e]and a[e]..","..t or t;
-else
-p=t;
-if m then
-u,i,g=t:match("^HTTP/(1%.[01]) (%d%d%d) (.*)$");
-i=c(i);
-if not i then s=true;return r("invalid-status-line");end
-y=not
-((l and l().method=="HEAD")
+o[e]=o[e]and o[e]..","..t or t;
+else
+c=t;
+if d then
+l,i,g=t:match("^HTTP/(1%.[01]) (%d%d%d) (.*)$");
+i=m(i);
+if not i then n=true;return h("invalid-status-line");end
+u=not
+((y and y().method=="HEAD")
or(i==204 or i==304 or i==301)
or(i>=100 and i<200));
else
-w,h,u=t:match("^(%w+) (%S+) HTTP/(1%.[01])$");
-if not w then s=true;return r("invalid-status-line");end
-end
-end
-end
-if not p then s=true;return r("invalid-status-line");end
-b=y and a["transfer-encoding"]=="chunked";
-t=c(a["content-length"]);
-if t and t>v then s=true;return r("content-length-limit-exceeded");end
-if m then
-if not y then t=0;end
-n={
+w,r,l=t:match("^(%w+) (%S+) HTTP/(1%.[01])$");
+if not w then n=true;return h("invalid-status-line");end
+end
+end
+end
+if not c then n=true;return h("invalid-status-line");end
+p=u and o["transfer-encoding"]=="chunked";
+a=m(o["content-length"]);
+if d then
+if not u then a=0;end
+t={
code=i;
-httpversion=u;
-headers=a;
-body=y and""or nil;
-responseversion=u;
-responseheaders=a;
+httpversion=l;
+headers=o;
+body=u and""or nil;
+responseversion=l;
+responseheaders=o;
};
else
local e;
-if h:byte()==47 then
-local a,t=h:match("([^?]*).?(.*)");
+if r:byte()==47 then
+local a,t=r:match("([^?]*).?(.*)");
if t==""then t=nil;end
e={path=a,query=t};
else
-e=q(h);
-if not(e and e.path)then s=true;return r("invalid-url");end
-end
-h=k(e.path);
-a.host=e.host or a.host;
-t=t or 0;
-n={
+e=v(r);
+if not(e and e.path)then n=true;return h("invalid-url");end
+end
+r=b(e.path);
+o.host=e.host or o.host;
+a=a or 0;
+t={
method=w;
url=e;
-path=h;
-httpversion=u;
-headers=a;
+path=r;
+httpversion=l;
+headers=o;
body=nil;
};
end
e=e:sub(f+4);
-o=#e;
-d=true;
-end
+s=true;
+end
+if s then
if d then
-if m then
-if b then
-if h and o-h-2=a then
-n.body=n.body..e:sub(h,h+(a-1));
-e=e:sub(h+a+2);
-o=o-(h+a+2-1);
-a,h=nil,nil;
+c(t);
+elseif#e-r-2>=o then
+t.body=t.body..e:sub(r,r+(o-1));
+e=e:sub(r+o+2);
+o,r=nil,nil;
else
break;
end
-elseif t and o>=t then
-if i then e,i=u(e),false;end
-if n.code==101 then
-n.body,e,o,i=e,{},0,true;
-else
-n.body,e=e:sub(1,t),e:sub(t+1);
-o=#e;
-end
-d=nil;f(n);
+elseif a and#e>=a then
+if t.code==101 then
+t.body,e=e,"";
+else
+t.body,e=e:sub(1,a),e:sub(a+1);
+end
+s=nil;c(t);
else
break;
end
-elseif o>=t then
-if i then e,i=u(e),false;end
-n.body,e=e:sub(1,t),e:sub(t+1);
-o=#e;
-d=nil;f(n);
+elseif#e>=a then
+t.body,e=e:sub(1,a),e:sub(a+1);
+s=nil;c(t);
else
break;
end
@@ -7695,35 +8033,45 @@
end;
};
end
-return v;
+return y;
end)
package.preload['net.http']=(function(...)
-local z=require"util.encodings".base64.encode;
-local m=require"socket.url"
-local h=require"net.http.parser".new;
-local u=require"util.http";
-local g=require"util.events";
-local b=pcall(require,"ssl");
-local k=require"net.server"
-local i,o=table.insert,table.concat;
-local w=pairs;
-local v,l,p,s=
-tonumber,tostring,xpcall,debug.traceback;
-local y=error
-local d=require"util.logger".init("http");
-local e=nil;
-local n={};
-local function c(e)return(l(e):match("%x+$"));end
-local r={default_port=80,default_mode="*a"};
-function r.onconnect(t)
-local e=n[t];
+local _ENV=_ENV;
+local function a(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
+local g=require"socket"
+local b=require"util.encodings".base64.encode;
+local l=require"socket.url"
+local u=require"net.http.parser".new;
+local s=require"util.http";
+local k=pcall(require,"ssl");
+local q=require"net.server"
+local d,o=table.insert,table.concat;
+local m=pairs;
+local y,h,w,f,r=
+tonumber,tostring,xpcall,select,debug.traceback;
+local p,v=assert,error
+local c=require"util.logger".init("http");
+a"http"
+local i={};
+local n={default_port=80,default_mode="*a"};
+function n.onconnect(t)
+local e=i[t];
local a={e.method or"GET"," ",e.path," HTTP/1.1\r\n"};
if e.query then
-i(a,4,"?"..e.query);
+d(a,4,"?"..e.query);
end
t:write(o(a));
local a={[2]=": ",[4]="\r\n"};
-for e,i in w(e.headers)do
+for e,i in m(e.headers)do
a[1],a[3]=e,i;
t:write(o(a));
end
@@ -7732,185 +8080,152 @@
t:write(e.body);
end
end
-function r.onincoming(t,a)
-local e=n[t];
+function n.onincoming(a,t)
+local e=i[a];
if not e then
-d("warn","Received response from connection %s with no request attached!",l(t));
+c("warn","Received response from connection %s with no request attached!",h(a));
return;
end
-if a and e.reader then
-e:reader(a);
-end
-end
-function r.ondisconnect(t,a)
-local e=n[t];
+if t and e.reader then
+e:reader(t);
+end
+end
+function n.ondisconnect(t,a)
+local e=i[t];
if e and e.conn then
-e:reader(nil,a or"closed");
-end
-n[t]=nil;
-end
-function r.ondetach(e)
-n[e]=nil;
-end
-local function o(e)
-if e.conn then
-e.conn=nil;
-e.handler:close()
-end
-end
-local function x(e,i,n)
+e:reader(nil,a);
+end
+i[t]=nil;
+end
+function n.ondetach(e)
+i[e]=nil;
+end
+local function x(e,a,i)
if not e.parser then
-local function a(t)
+local function o(t)
if e.callback then
e.callback(t or"connection-closed",0,e);
e.callback=nil;
end
-o(e);
-end
-if not i then
-a(n);
+destroy_request(e);
+end
+if not a then
+o(i);
return;
end
-local function i(t)
+local function a(t)
if e.callback then
e.callback(t.body,t.code,t,e);
e.callback=nil;
end
-o(e);
+destroy_request(e);
end
local function t()
return e;
end
-e.parser=h(i,a,"client",t);
-end
-e.parser:feed(i);
-end
-local function q(e)d("error","Traceback[http]: %s",s(l(e),2));end
-local function j(e,t,...)
-if not t then
-d("error","Request '%s': error in callback: %s",e,l((...)));
-end
-return...;
-end
-local function f(o,a,t,h)
-local e=m.parse(a);
-e.url=a;
+e.parser=u(a,o,"client",t);
+end
+e.parser:feed(a);
+end
+local function j(e)c("error","Traceback[http]: %s",r(h(e),2));end
+function request(e,t,r)
+local e=l.parse(e);
if not(e and e.host)then
-h("invalid-url",0,e);
+r(nil,0,e);
return nil,"invalid-url";
end
if not e.path then
e.path="/";
end
-e.id=t and t.id or c(e);
-do
-local i={http=o,url=a,request=e,options=t,callback=h};
-local o=o.events.fire_event("pre-request",i);
-if o then
-return o;
-end
-e,a,t,h=i.request,i.url,i.options,i.callback;
-end
-local m,s,c;
-local f,i=e.host,e.port;
-local u=f;
-if(i=="80"and e.scheme=="http")
-or(i=="443"and e.scheme=="https")then
-i=nil;
-elseif i then
-u=u..":"..i;
-end
-s={
-["Host"]=u;
+local l,o,s;
+local u,a=e.host,e.port;
+local d=u;
+if(a=="80"and e.scheme=="http")
+or(a=="443"and e.scheme=="https")then
+a=nil;
+elseif a then
+d=d..":"..a;
+end
+o={
+["Host"]=d;
["User-Agent"]="Prosody XMPP Server";
};
if e.userinfo then
-s["Authorization"]="Basic "..z(e.userinfo);
+o["Authorization"]="Basic "..b(e.userinfo);
end
if t then
e.onlystatus=t.onlystatus;
-c=t.body;
-if c then
-m="POST";
-s["Content-Length"]=l(#c);
-s["Content-Type"]="application/x-www-form-urlencoded";
-end
-if t.method then m=t.method;end
+s=t.body;
+if s then
+l="POST";
+o["Content-Length"]=h(#s);
+o["Content-Type"]="application/x-www-form-urlencoded";
+end
+if t.method then l=t.method;end
if t.headers then
-for e,t in w(t.headers)do
-s[e]=t;
-end
-end
-end
-d("debug","Making %s %s request '%s' to %s",e.scheme:upper(),m or"GET",e.id,(t and t.suppress_url and u)or a);
-e.method,e.headers,e.body=m,s,c;
-local s=e.scheme=="https";
-if s and not b then
-y("SSL not available, unable to contact https URL");
-end
-local l=i and v(i)or(s and 443 or 80);
-local i=false;
-if s then
-i=t and t.sslctx or{mode="client",protocol="sslv23",options={"no_sslv2","no_sslv3"}};
-end
-local i,t=k.addclient(f,l,r,"*a",i)
-if not i then
-o.events.fire_event("request-connection-error",{http=o,request=e,url=a,err=t});
-h(t,0,e);
-return nil,t;
-end
-e.handler,e.conn=i,t
+for e,t in m(t.headers)do
+o[e]=t;
+end
+end
+end
+e.method,e.headers,e.body=l,o,s;
+local o=e.scheme=="https";
+if o and not k then
+v("SSL not available, unable to contact https URL");
+end
+local h=a and y(a)or(o and 443 or 80);
+local a=g.tcp();
+a:settimeout(10);
+local d,s=a:connect(u,h);
+if not d and s~="timeout"then
+r(nil,0,e);
+return nil,s;
+end
+local s=false;
+if o then
+s=t and t.sslctx or{mode="client",protocol="sslv23",options={"no_sslv2","no_sslv3"}};
+end
+e.handler,e.conn=p(q.wrapclient(a,u,h,n,"*a",s));
e.write=function(...)return e.handler:write(...);end
-e.callback=function(i,t,n,s)
-do
-local e={http=o,url=a,request=e,response=n,content=i,code=t,callback=h};
-o.events.fire_event("response",e);
-i,t,n=e.content,e.code,e.response;
-end
-d("debug","Request '%s': Calling callback, status %s",e.id,t or"---");
-return j(e.id,p(function()return h(i,t,s,n)end,q));
-end
+e.callback=function(i,t,o,a)c("debug","Calling callback, status %s",t or"---");return f(2,w(function()return r(i,t,o,a)end,j));end
e.reader=x;
e.state="status";
-n[e.handler]=e;
-o.events.fire_event("request",{http=o,request=e,url=a});
-return e;
-end
-local function e(t)
-local e={
-options=t;
-request=f;
-new=t and function(a)
-return e(setmetatable(a,{__index=t}));
-end or e;
-events=g.new();
-request=f;
-};
-return e;
-end
-local t=e();
-return{
-request=function(e,a,o)
-return t:request(e,a,o);
-end;
-new=e;
-events=t.events;
-urlencode=u.urlencode;
-urldecode=u.urldecode;
-formencode=u.formencode;
-formdecode=u.formdecode;
-};
+i[e.handler]=e;
+return e;
+end
+function destroy_request(e)
+if e.conn then
+e.conn=nil;
+e.handler:close()
+end
+end
+local e,t=s.urlencode,s.urldecode;
+local o,a=s.formencode,s.formdecode;
+_M.urlencode,_M.urldecode=e,t;
+_M.formencode,_M.formdecode=o,a;
+return _M;
end)
package.preload['verse.bosh']=(function(...)
-local r=require"util.xmppstream".new;
-local h=require"util.stanza";
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
+local h=require"util.xmppstream".new;
+local i=require"util.stanza";
require"net.httpclient_listener";
local o=require"net.http";
local e=setmetatable({},{__index=verse.stream_mt});
e.__index=e;
-local s="http://etherx.jabber.org/streams";
-local n="http://jabber.org/protocol/httpbind";
-local i=5;
+local n="http://etherx.jabber.org/streams";
+local s="http://jabber.org/protocol/httpbind";
+local a=5;
function verse.new_bosh(a,t)
local t={
bosh_conn_pool={};
@@ -7932,7 +8247,7 @@
end
function e:send(e)
self:debug("Putting into BOSH send buffer: %s",tostring(e));
-self.bosh_outgoing_buffer[#self.bosh_outgoing_buffer+1]=h.clone(e);
+self.bosh_outgoing_buffer[#self.bosh_outgoing_buffer+1]=i.clone(e);
self:flush();
end
function e:flush()
@@ -7944,20 +8259,20 @@
self:debug("Flushing...");
local e=self:_make_body();
local t=self.bosh_outgoing_buffer;
-for o,a in ipairs(t)do
-e:add_child(a);
-t[o]=nil;
+for a,o in ipairs(t)do
+e:add_child(o);
+t[a]=nil;
end
self:_make_request(e);
else
self:debug("Decided not to flush.");
end
end
-function e:_make_request(t)
-local e,t=o.request(self.bosh_url,{body=tostring(t)},function(o,e,a)
+function e:_make_request(i)
+local e,t=o.request(self.bosh_url,{body=tostring(i)},function(o,e,t)
if e~=0 then
self.inactive_since=nil;
-return self:_handle_response(o,e,a);
+return self:_handle_response(o,e,t);
end
local e=os.time();
if not self.inactive_since then
@@ -7966,17 +8281,17 @@
return self:_disconnected();
else
self:debug("%d seconds left to reconnect, retrying in %d seconds...",
-self.bosh_max_inactivity-(e-self.inactive_since),i);
-end
-timer.add_task(i,function()
+self.bosh_max_inactivity-(e-self.inactive_since),a);
+end
+timer.add_task(a,function()
self:debug("Retrying request...");
-for e,t in ipairs(self.bosh_waiting_requests)do
-if t==a then
+for e,a in ipairs(self.bosh_waiting_requests)do
+if a==t then
table.remove(self.bosh_waiting_requests,e);
break;
end
end
-self:_make_request(t);
+self:_make_request(i);
end);
end);
if e then
@@ -8018,19 +8333,19 @@
self:_handle_response_payload(e);
end);
end
-function e:_handle_response(t,a,e)
+function e:_handle_response(o,t,e)
if self.bosh_waiting_requests[1]~=e then
self:warn("Server replied to request that wasn't the oldest");
-for t,a in ipairs(self.bosh_waiting_requests)do
-if a==e then
-self.bosh_waiting_requests[t]=nil;
+for a,t in ipairs(self.bosh_waiting_requests)do
+if t==e then
+self.bosh_waiting_requests[a]=nil;
break;
end
end
else
table.remove(self.bosh_waiting_requests,1);
end
-local e=self:_parse_response(t);
+local e=self:_parse_response(o);
if e then
self:_handle_response_payload(e);
end
@@ -8040,7 +8355,7 @@
local e=t.tags;
for t=1,#e do
local e=e[t];
-if e.attr.xmlns==s then
+if e.attr.xmlns==n then
self:event("stream-"..e.name,e);
elseif e.attr.xmlns then
self:event("stream/"..e.attr.xmlns,e);
@@ -8056,7 +8371,7 @@
stream_ns="http://jabber.org/protocol/httpbind",stream_tag="body",
default_ns="jabber:client",
streamopened=function(e,t)e.notopen=nil;e.payload=verse.stanza("body",t);return true;end;
-handlestanza=function(t,e)t.payload:add_child(e);end;
+handlestanza=function(e,t)e.payload:add_child(t);end;
};
function e:_parse_response(e)
self:debug("Parsing response: %s",e);
@@ -8066,14 +8381,14 @@
return;
end
local t={notopen=true,stream=self};
-local a=r(t,a);
+local a=h(t,a);
a:feed(e);
return t.payload;
end
function e:_make_body()
self.bosh_rid=self.bosh_rid+1;
local e=verse.stanza("body",{
-xmlns=n;
+xmlns=s;
content="text/xml; charset=utf-8";
sid=self.bosh_sid;
rid=self.bosh_rid;
@@ -8086,10 +8401,21 @@
end
end)
package.preload['verse.client']=(function(...)
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
local t=require"verse";
local o=t.stream_mt;
-local h=require"util.jid".split;
-local d=require"net.adns";
+local d=require"util.jid".split;
+local h=require"net.adns";
local e=require"lxp";
local a=require"util.stanza";
t.message,t.presence,t.iq,t.stanza,t.reply,t.error_reply=
@@ -8149,15 +8475,15 @@
end
function o:connect_client(e,a)
self.jid,self.password=e,a;
-self.username,self.host,self.resource=h(e);
+self.username,self.host,self.resource=d(e);
self:add_plugin("tls");
self:add_plugin("sasl");
self:add_plugin("bind");
self:add_plugin("session");
function self.data(t,e)
-local a,t=self.stream:feed(e);
-if a then return;end
-self:debug("Received invalid XML (%s) %d bytes: %s",tostring(t),#e,e:sub(1,300):gsub("[\r\n]+"," "));
+local t,a=self.stream:feed(e);
+if t then return;end
+self:debug("Received invalid XML (%s) %d bytes: %s",tostring(a),#e,e:sub(1,300):gsub("[\r\n]+"," "));
self:close("xml-not-well-formed");
end
self:hook("connected",function()self:reopen();end);
@@ -8218,22 +8544,22 @@
return self:close(e);
end
end
-local function t()
+local function a()
self:connect(self.connect_host or self.host,self.connect_port or 5222);
end
if not(self.connect_host or self.connect_port)then
-d.lookup(function(a)
-if a then
+h.lookup(function(t)
+if t then
local e={};
self.srv_hosts=e;
-for a,t in ipairs(a)do
+for a,t in ipairs(t)do
table.insert(e,t.srv);
end
table.sort(e,s);
-local a=e[1];
+local t=e[1];
self.srv_choice=1;
-if a then
-self.connect_host,self.connect_port=a.target,a.port;
+if t then
+self.connect_host,self.connect_port=t.target,t.port;
self:debug("Best record found, will connect to %s:%d",self.connect_host or self.host,self.connect_port or 5222);
end
self:hook("disconnected",function()
@@ -8241,7 +8567,7 @@
self.srv_choice=self.srv_choice+1;
local e=e[self.srv_choice];
self.connect_host,self.connect_port=e.target,e.port;
-t();
+a();
return true;
end
end,1e3);
@@ -8249,10 +8575,10 @@
self.srv_hosts=nil;
end,1e3);
end
-t();
+a();
end,"_xmpp-client._tcp."..(self.host)..".","SRV");
else
-t();
+a();
end
end
function o:reopen()
@@ -8260,11 +8586,11 @@
self:send(a.stanza("stream:stream",{to=self.host,["xmlns:stream"]='http://etherx.jabber.org/streams',
xmlns="jabber:client",version="1.0"}):top_tag());
end
-function o:send_iq(e,a)
-local t=self:new_id();
-self.tracked_iqs[t]=a;
-e.attr.id=t;
-self:send(e);
+function o:send_iq(t,a)
+local e=self:new_id();
+self.tracked_iqs[e]=a;
+t.attr.id=e;
+self:send(t);
end
function o:new_id()
self.curr_id=self.curr_id+1;
@@ -8272,15 +8598,26 @@
end
end)
package.preload['verse.component']=(function(...)
-local a=require"verse";
-local o=a.stream_mt;
-local d=require"util.jid".split;
+local _ENV=_ENV;
+local function e(t,...)
+local e=package.loaded[t]or _ENV[t]or{_NAME=t};
+package.loaded[t]=e;
+for t=1,select("#",...)do
+(select(t,...))(e);
+end
+_ENV=e;
+_M=e;
+return e;
+end
+local t=require"verse";
+local a=t.stream_mt;
+local h=require"util.jid".split;
local e=require"lxp";
-local t=require"util.stanza";
-local r=require"util.sha1".sha1;
-a.message,a.presence,a.iq,a.stanza,a.reply,a.error_reply=
-t.message,t.presence,t.iq,t.stanza,t.reply,t.error_reply;
-local h=require"util.xmppstream".new;
+local o=require"util.stanza";
+local d=require"util.hashes".sha1;
+t.message,t.presence,t.iq,t.stanza,t.reply,t.error_reply=
+o.message,o.presence,o.iq,o.stanza,o.reply,o.error_reply;
+local r=require"util.xmppstream".new;
local s="http://etherx.jabber.org/streams";
local i="jabber:component:accept";
local n={
@@ -8305,23 +8642,23 @@
end
return t:event("stanza",e);
end
-function o:reset()
+function a:reset()
if self.stream then
self.stream:reset();
else
-self.stream=h(self,n);
+self.stream=r(self,n);
end
self.notopen=true;
return true;
end
-function o:connect_component(e,n)
+function a:connect_component(e,n)
self.jid,self.password=e,n;
-self.username,self.host,self.resource=d(e);
+self.username,self.host,self.resource=h(e);
function self.data(t,e)
-local t,a=self.stream:feed(e);
+local t,o=self.stream:feed(e);
if t then return;end
-o:debug("Received invalid XML (%s) %d bytes: %s",tostring(a),#e,e:sub(1,300):gsub("[\r\n]+"," "));
-o:close("xml-not-well-formed");
+a:debug("Received invalid XML (%s) %d bytes: %s",tostring(o),#e,e:sub(1,300):gsub("[\r\n]+"," "));
+a:close("xml-not-well-formed");
end
self:hook("incoming-raw",function(e)return self.data(self.conn,e);end);
self.curr_id=0;
@@ -8335,30 +8672,30 @@
end
end);
self:hook("stanza",function(e)
-local t;
+local a;
if e.attr.xmlns==nil or e.attr.xmlns=="jabber:client"then
if e.name=="iq"and(e.attr.type=="get"or e.attr.type=="set")then
local o=e.tags[1]and e.tags[1].attr.xmlns;
if o then
-t=self:event("iq/"..o,e);
-if not t then
-t=self:event("iq",e);
-end
-end
-if t==nil then
-self:send(a.error_reply(e,"cancel","service-unavailable"));
+a=self:event("iq/"..o,e);
+if not a then
+a=self:event("iq",e);
+end
+end
+if a==nil then
+self:send(t.error_reply(e,"cancel","service-unavailable"));
return true;
end
else
-t=self:event(e.name,e);
-end
-end
-return t;
+a=self:event(e.name,e);
+end
+end
+return a;
end,-1);
self:hook("opened",function(e)
print(self.jid,self.stream_id,e.id);
-local e=r(self.stream_id..n,true);
-self:send(t.stanza("handshake",{xmlns=i}):text(e));
+local e=d(self.stream_id..n,true);
+self:send(o.stanza("handshake",{xmlns=i}):text(e));
self:hook("stream/"..i,function(e)
if e.name=="handshake"then
self:event("authentication-success");
@@ -8372,26 +8709,26 @@
self:connect(self.connect_host or self.host,self.connect_port or 5347);
self:reopen();
end
-function o:reopen()
+function a:reopen()
self:reset();
-self:send(t.stanza("stream:stream",{to=self.jid,["xmlns:stream"]='http://etherx.jabber.org/streams',
+self:send(o.stanza("stream:stream",{to=self.jid,["xmlns:stream"]='http://etherx.jabber.org/streams',
xmlns=i,version="1.0"}):top_tag());
end
-function o:close(e)
+function a:close(t)
if not self.notopen then
self:send("");
end
-local t=self.conn.disconnect();
+local e=self.conn.disconnect();
self.conn:close();
-t(conn,e);
-end
-function o:send_iq(t,a)
+e(conn,t);
+end
+function a:send_iq(t,a)
local e=self:new_id();
self.tracked_iqs[e]=a;
t.attr.id=e;
self:send(t);
end
-function o:new_id()
+function a:new_id()
self.curr_id=self.curr_id+1;
return tostring(self.curr_id);
end
@@ -8402,18 +8739,17 @@
local a=require"net.server";
local s=require"util.events";
local o=require"util.logger";
-local t={};
-local e=t;
-t.server=a;
+local e={};
+e.server=a;
local t={};
t.__index=t;
e.stream_mt=t;
e.plugins={};
function e.init(...)
for e=1,select("#",...)do
-local a,t=pcall(require,"verse."..select(e,...));
-if not a then
-error("Verse connection module not found: verse."..select(e,...)..t);
+local t,a=pcall(require,"verse."..select(e,...));
+if not t then
+error("Verse connection module not found: verse."..select(e,...)..a);
end
end
return e;
@@ -8433,9 +8769,9 @@
e.logger=o.init;
e.new_logger=o.init;
e.log=e.logger("verse");
-local function n(a,...)
-local e,t,o=0,{...},select('#',...);
-return(a:gsub("%%(.)",function(a)if e<=o then e=e+1;return tostring(t[e]);end end));
+local function n(t,...)
+local e,a,o=0,{...},select('#',...);
+return(t:gsub("%%(.)",function(t)if e<=o then e=e+1;return tostring(a[e]);end end));
end
function e.set_log_handler(e,t)
t=t or{"debug","info","warn","error"};
@@ -8455,8 +8791,8 @@
end
end
end
-function e._default_log_handler(o,a,t)
-return io.stderr:write(o,"\t",a,"\t",t,"\n");
+function e._default_log_handler(a,t,o)
+return io.stderr:write(a,"\t",t,"\t",o,"\n");
end
e.set_log_handler(e._default_log_handler,{"error"});
local function o(t)
@@ -8473,7 +8809,7 @@
return xpcall(a.step,o);
end
function e.quit()
-return a.setquitting(true);
+return a.setquitting("once");
end
function t:listen(t,o)
t=t or"localhost";
@@ -8485,18 +8821,18 @@
end
return e,a;
end
-function t:connect(o,i)
-o=o or"localhost";
-i=tonumber(i)or 5222;
+function t:connect(i,o)
+i=i or"localhost";
+o=tonumber(o)or 5222;
local n=h.tcp()
n:settimeout(0);
n:setoption("keepalive",true);
-local s,t=n:connect(o,i);
+local s,t=n:connect(i,o);
if not s and t~="timeout"then
-self:warn("connect() to %s:%d failed: %s",o,i,t);
+self:warn("connect() to %s:%d failed: %s",i,o,t);
return self:event("disconnected",{reason=t})or false,t;
end
-local e=a.wrapclient(n,o,i,e.new_listener(self),"*a");
+local e=a.wrapclient(n,i,o,e.new_listener(self),"*a");
if not e then
self:warn("connection initialisation failed: %s",t);
return self:event("disconnected",{reason=t})or false,t;
@@ -8541,8 +8877,8 @@
function t:hook(e,...)
return self.events.add_handler(e,...);
end
-function t:unhook(t,e)
-return self.events.remove_handler(t,e);
+function t:unhook(e,t)
+return self.events.remove_handler(e,t);
end
function e.eventable(e)
e.events=s.new();
@@ -8582,10 +8918,10 @@
function a.onincoming(a,e)
t:event("incoming-raw",e);
end
-function a.ondisconnect(e,a)
-if e~=t.conn then return end
+function a.ondisconnect(a,e)
+if a~=t.conn then return end
t.connected=false;
-t:event("disconnected",{reason=a});
+t:event("disconnected",{reason=e});
end
function a.ondrain(e)
t:event("drained");