Rewrite of ibb in object style
authorMyhailo Danylenko <isbear@ukrpost.net>
Fri, 27 Mar 2009 01:46:53 +0200
changeset 64 bf7521ed96eb
parent 63 423555c07763
child 65 f1be8dbb209c
Rewrite of ibb in object style
examples/disco.lua
examples/evil.lua
examples/ibb.lua
examples/iq.lua
examples/iq_register.lua
examples/mc_ibb.lua
examples/mcabberrc.lua
examples/oob.lua
examples/pep.lua
examples/ping.lua
examples/pubsub.lua
examples/remote.lua
examples/vcard.lua
--- a/examples/disco.lua	Mon Mar 23 09:22:04 2009 +0200
+++ b/examples/disco.lua	Fri Mar 27 01:46:53 2009 +0200
@@ -4,7 +4,7 @@
 -- library
 
 require 'lm'
-require 'iq'
+local iq = require 'iq'
 
 -- public
 
--- a/examples/evil.lua	Mon Mar 23 09:22:04 2009 +0200
+++ b/examples/evil.lua	Fri Mar 27 01:46:53 2009 +0200
@@ -7,7 +7,7 @@
 -- library
 
 require 'lm'
-require 'iq'
+local iq = require 'iq'
 
 -- public
 
@@ -55,9 +55,9 @@
 		local evillevel = tonumber(main.option ( 'lua_evil_sensibility' ))
 		local mtype, smtype = mess:type ()
 		if evillevel > 1 then
-			main.print_info ( mess:attribute ( 'from' ), 'Evil stanza of type "' .. mtype .. ' ' .. smtype .. '" detected!' )
+			main.print_info ( mess:attribute ( 'from' ), 'Evil stanza of type ' .. mtype .. '.' .. smtype .. ' detected!' )
 		elseif evillevel > 0 then
-			print ( 'Tainted by evil stanza of type "' .. mtype .. ' ' .. smtype .. '" from ' .. ( mess:attribute ( 'from' ) or '... unknown in black' ) )
+			print ( 'Tainted by evil stanza of type ' .. mtype .. '.' .. smtype .. ' from ' .. ( mess:attribute ( 'from' ) or '... unknown in black' ) )
 		end
 		return main.yesno ( main.option ( 'lua_filter_evil' ) )
 	end
--- a/examples/ibb.lua	Mon Mar 23 09:22:04 2009 +0200
+++ b/examples/ibb.lua	Fri Mar 27 01:46:53 2009 +0200
@@ -1,304 +1,184 @@
 
 -- IN-BAND BYTESTREAMS (XEP-0047)
 
--- library
-
-require 'lm'
-require 'iq'
-require 'base64'
+-- TODO bidirectionality
+--        thus, on stream accept we can add our sid to incoming files structure,
+--        as if we received and accepted incoming request.
+--      message stanzas
 
--- public
+require 'lm' -- FIXME
+local iq     = require 'iq'
+local base64 = require 'base64'
 
-ibb = {
-	block_size    = 4096,
-	streamhandler =
+local F = { }
+local M = { }
+M.__index = M
+local O = {
+	handler =
 		function ( accept, reject )
 			reject ()
 		end,
 }
 
-local ibb_sid = 0 -- private
+function F.new ( conn, to, bs, sid )
+	local obj = {
+		conn = conn,
+		to   = to,
+		sbs  = bs,
+		bs   = math.floor ( bs * 3 / 4 ),
+		sid  = sid,
+		seq  = 0,
+	}
+	setmetatable ( obj, M )
+	return obj
+end
 
-function ibb.send ( conn, to, success, fail, id )
-	local bs    = ibb.block_size -- local instance
-	local sid   = id
-	if not sid then
-		ibb_sid = ibb_sid + 1
-		sid     = 'ibb_' .. ibb_sid
-	end
-	iq.send ( conn, to, 'set',
+function M.open ( obj, success, fail )
+	iq.send ( obj.conn, obj.to, 'set',
 		{
-			open = { sid = sid, ['block-size'] = bs, xmlns = 'http://jabber.org/protocol/ibb' }
-		},
-		function ()
-			local seq   = 0
-			local noerr = true
-			success (
-				function ( data, success, fail )
-					if not data  then
-						iq.send ( conn, to, 'set',
-							{
-								close = { sid = sid, xmlns = 'http://jabber.org/protocol/ibb' },
-							},
-							function ()
-								success ( 'end' ) -- XXX
-							end, fail )
-					elseif data ~= '' then
-						local encoded = base64.encode ( data )
-						while encoded:len () > 0 and noerr do
-							local chunk = encoded:sub ( 1, bs )
-							local cseq  = seq -- local instance for closure
-							encoded     = encoded:sub ( bs + 1 )
-							seq         = seq + 1
-							iq.send ( conn, to, 'set',
-								{
-									data = { sid = sid, xmlns = 'http://jabber.org/protocol/ibb', seq = cseq,
-										chunk,
-									},
-								},
-								function ()
-									success ( cseq )
-								end,
-								function ( mesg )
-									noerr = false
-									fail ( mesg )
-								end )
-						end
-					end
+			open = { sid = obj.sid, ['block-size'] = obj.sbs, xmlns = 'http://jabber.org/protocol/ibb' }
+		}, success, fail )
+end
+
+function M.send ( obj, data, success, fail )
+	if data and data ~= '' then
+		local start = 0
+		while start < data:len () do
+			local chunk = base64.encode ( data:sub ( start, obj.bs ) )
+			local cseq  = obj.seq -- local instance
+			iq.send ( obj.conn, obj.to, 'set',
+				{
+					data = { sid = obj.sid, xmlns = 'http://jabber.org/protocol/ibb', seq = cseq,
+						chunk,
+					},
+				},
+				function ()
+					success ( cseq )
+				end,
+				function ( mesg )
+					noerr = false
+					fail ( mesg )
 				end )
-		end, fail )
+			start   = start + obj.bs
+			obj.seq = obj.seq + 1
+		end
+	end
+end
+
+function M.close ( obj, success, fail )
+	iq.send ( obj.conn, obj.to, 'set',
+		{
+			close = { sid = obj.sid, xmlns = 'http://jabber.org/protocol/ibb' },
+		}, success, fail )
 end
 
--- private
+function F.handler ( handler )
+	O.handler = handler
+end
+
+local ibb_files = {}
 
-local ibb_files               = {}
-local ibb_handler_registered  = false
-local ibb_incoming_iq_handler = lm.message_handler.new ( 
-	function ( conn, mess )
-		local mtype, smtype = mess:type ()
-		if smtype ~= 'set' then
-			return false
-		end
+function F.iq_handler ( conn, mess )
+	local mtype, smtype = mess:type ()
+	if smtype ~= 'set' then
+		return false
+	end
 
-		local child = mess:children ()
-		if not child or child:attribute ( 'xmlns' ) ~= 'http://jabber.org/protocol/ibb' then
-			return false
-		end
+	local child = mess:children ()
+	if not child or child:attribute ( 'xmlns' ) ~= 'http://jabber.org/protocol/ibb' then
+		return false
+	end
+
+	local id     = mess:attribute ( 'id' )
+	local from   = mess:attribute ( 'from' )
+	local action = child:name ()
+	local sid    = child:attribute ( 'sid' )
 
-		local id     = mess:attribute ( 'id' )
-		local from   = mess:attribute ( 'from' )
-		local action = child:name ()
-		local sid    = child:attribute ( 'sid' )
-
-		if action == 'open' then
-			if not ibb_files[sid] then
-				ibb.streamhandler ( from,
-					function ( success, fail )
-						ibb_files[sid] = { from = from, success = success, fail = fail }
-						conn:send ( lm.message.create { to = from, mtype = 'iq-result', id = id } )
-					end,
-					function ()
-						conn:send (
-							lm.message.create { to = from, mtype = 'iq-error', id = id,
-								error = { code = '405', type = 'cancel',
-									['not-allowed'] = { xmlns = 'urn:ietf:params:xml:ns:xmpp-stanzas' },
-								},
-							} )
-					end )
-			else
+	if action == 'open' then
+		if not ibb_files[sid] then
+			O.handler ( from,
+				function ( success, fail )
+					ibb_files[sid] = { from = from, success = success, fail = fail }
+					conn:send ( lm.message.create { to = from, mtype = 'iq-result', id = id } )
+				end,
+				function ()
+					conn:send (
+						lm.message.create { to = from, mtype = 'iq-error', id = id,
+							error = { code = '405', type = 'cancel',
+								['not-allowed'] = { xmlns = 'urn:ietf:params:xml:ns:xmpp-stanzas' },
+							},
+						} )
+				end )
+		else
+			conn:send (
+				lm.message.create { to = from, mtype = 'iq-error', id = id,
+					error = { code = '409', type = 'cancel',
+						conflict = { xmlns = 'urn:ietf:params:xml:ns:xmpp-stanzas' },
+					},
+				} )
+		end
+	elseif action == 'data' then
+		local seq = child:attribute ( 'seq' )
+		if ibb_files[sid] and from == ibb_files[sid].from and not ibb_files[sid][tonumber(seq)+1] then
+			local data = child:value ()
+			conn:send ( lm.message.create { to = from, mtype = 'iq-result', id = id } )
+			ibb_files[sid][tonumber(seq)+1] = data
+-- XXX		ibb_files[sid].success ( seq )
+		else
+			if ibb_files[sid] then
+				ibb_files[sid].fail ( 'conflict' )
+				ibb_files[sid] = nil -- invalidate session
 				conn:send (
 					lm.message.create { to = from, mtype = 'iq-error', id = id,
 						error = { code = '409', type = 'cancel',
 							conflict = { xmlns = 'urn:ietf:params:xml:ns:xmpp-stanzas' },
 						},
 					} )
-			end
-		elseif action == 'data' then
-			local seq = child:attribute ( 'seq' )
-			if ibb_files[sid] and from == ibb_files[sid].from and not ibb_files[sid][tonumber(seq)+1] then
-				local data = child:value ()
-				conn:send ( lm.message.create { to = from, mtype = 'iq-result', id = id } )
-				ibb_files[sid][tonumber(seq)+1] = data
--- XXX			ibb_files[sid].success ( seq )
-			else
-				if ibb_files[sid] then
-					ibb_files[sid].fail ( 'conflict' )
-					ibb_files[sid] = nil -- invalidate session
-					conn:send (
-						lm.message.create { to = from, mtype = 'iq-error', id = id,
-							error = { code = '409', type = 'cancel',
-								conflict = { xmlns = 'urn:ietf:params:xml:ns:xmpp-stanzas' },
-							},
-						} )
-				else
-					conn:send (
-						lm.message.create { to = from, mtype = 'iq-error', id = id,
-							error = { code = '404', type = 'cancel', -- XXX: check
-								['item-not-found'] = { xmlns = 'urn:ietf:params:xml:ns:xmpp-stanzas' },
-							},
-						} )
-				end
-			end
-		elseif action == 'close' then
-			if ibb_files[sid] and from == ibb_files[sid].from then
-				local data = ''
-				for seq, chunk in ipairs ( ibb_files[sid] ) do
-					data = data .. chunk
-				end
-				local decoded = base64.decode ( data )
-				ibb_files[sid].success ( decoded )
-				conn:send ( lm.message.create { to = from, mtype = 'iq-result', id = id } )
-				ibb_files[sid] = nil
 			else
-				if ibb_files[sid] then
-					ibb_files[sid].fail ( 'conflict' )
-					ibb_files[sid] = nil -- invalidate session
-					conn:send (
-						lm.message.create { to = from, mtype = 'iq-error', id = id,
-							error = { code = '409', type = 'cancel',
-								conflict = { xmlns = 'urn:ietf:params:xml:ns:xmpp-stanzas' },
-							},
-						} )
-				else
-					conn:send (
-						lm.message.create { to = from, mtype = 'iq-error', id = id,
-							error = { code = '404', type = 'cancel', -- XXX: check
-								['item-not-found'] = { xmlns = 'urn:ietf:params:xml:ns:xmpp-stanzas' },
-							},
-						} )
-				end
+				conn:send (
+					lm.message.create { to = from, mtype = 'iq-error', id = id,
+						error = { code = '404', type = 'cancel', -- XXX: check
+							['item-not-found'] = { xmlns = 'urn:ietf:params:xml:ns:xmpp-stanzas' },
+						},
+					} )
 			end
-		else
-			return false
 		end
-
-		return true
-	end )
-
--- mcabber
-
-local mc_incoming_files = { }
-
-ibb.streamhandler =
-	function ( from, accept, reject )
-		local fid = #mc_incoming_files + 1
-		mc_incoming_files[fid] = {
-				from   = from,
-				accept =
-					function ( name )
-						mc_incoming_files[fid].name = name
-						accept (
-							function ( data )
-								local h = io.open ( mc_incoming_files[fid].name, 'w' )
-								if not h then
-									print ( 'Cannot open output file: ' .. mc_incoming_files[fid].name )
-									return
-								end
-								h:write ( data )
-								h:close ()
-								print ( 'Stream ' .. fid .. ' successfully saved to ' .. mc_incoming_files[fid].name )
-								mc_incoming_files[fid] = nil
-							end,
-							function ( mesg )
-								main.print_info ( from, 'Stream error: ' .. mesg )
-								mc_incoming_files[fid] = nil -- XXX
-							end )
-					end,
-				reject =
-					function ()
-						reject ()
-						print ( 'Stream ' .. fid .. ' rejected' )
-						mc_incoming_files[fid] = nil
-					end,
-		}
-		main.print_info ( from, from .. ' wants you to receive stream. Use /ibb [accept|reject] ' .. fid .. ' to process his request.' )
+	elseif action == 'close' then
+		if ibb_files[sid] and from == ibb_files[sid].from then
+			local data = ''
+			for seq, chunk in ipairs ( ibb_files[sid] ) do
+				data = data .. chunk
+			end
+			local decoded = base64.decode ( data )
+			ibb_files[sid].success ( decoded )
+			conn:send ( lm.message.create { to = from, mtype = 'iq-result', id = id } )
+			ibb_files[sid] = nil
+		else
+			if ibb_files[sid] then
+				ibb_files[sid].fail ( 'conflict' )
+				ibb_files[sid] = nil -- invalidate session
+				conn:send (
+					lm.message.create { to = from, mtype = 'iq-error', id = id,
+						error = { code = '409', type = 'cancel',
+							conflict = { xmlns = 'urn:ietf:params:xml:ns:xmpp-stanzas' },
+						},
+					} )
+			else
+				conn:send (
+					lm.message.create { to = from, mtype = 'iq-error', id = id,
+						error = { code = '404', type = 'cancel', -- XXX: check
+							['item-not-found'] = { xmlns = 'urn:ietf:params:xml:ns:xmpp-stanzas' },
+						},
+					} )
+			end
+		end
+	else
+		return false
 	end
 
-main.command ( 'ibb',
-	function ( args )
-		local action = args[1]
-		if action == 'send' then
-			local who
-			if args.t then
-				who = args.t
-			else
-				who = main.full_jid ()
-			end
-			local fname = args[2]
-			ibb.send ( lm.connection.bless ( main.connection () ), who,
-				function ( sender )
-					main.print_info ( who, 'Stream accepted' )
-					local noerr = true
-					local h     = io.open ( fname, 'r' )
-					if not h then
-						print ( 'Cannot open file ' .. fname )
-						return
-					end
-					local data = h:read ( '*a' ) -- In fact, it is better to read it in chunks :/
-					h:close ()
-					local fail =
-						function ( mesg )
-							noerr = false
-							main.print_info ( who, 'Stream error: ' .. mesg )
-						end
-					sender ( data,
-						function ( seq )
-							main.print_info ( who, 'Delivery notification of chunk #' .. seq )
-						end, fail )
-					if noerr then
-						sender ( nil,
-							function ( seq )
-								main.print_info ( who, 'Stream finalizing notification' )
-							end, fail )
-					end
-					if noerr then
-						main.print_info ( who, 'Stream sent' )
-					else
-						main.print_info ( who, 'Stream error occured' )
-					end
-				end,
-				function ( mesg )
-					main.print_info ( who, 'Stream initiation error: ' .. mesg )
-				end )
-		elseif action == 'accept' then
-			local id = tonumber(args[2])
-			if mc_incoming_files[id] then
-				mc_incoming_files[id].accept ( args[3] )
-			end
-		elseif action == 'reject' then
-			local id = tonumber(args[2])
-			if mc_incoming_files[id] then
-				mc_incoming_files[id].reject ()
-			end
-		else
-			local text = ''
-			for sid, data in pairs ( mc_incoming_files ) do
-				text = text .. '\n' ..  sid .. ': ' .. data.from .. ' --> ' .. ( data.name or '?' )
-			end
-			if text ~= '' then
-				print ( 'List of incoming streams:' .. text )
-			else
-				print ( 'No streams' )
-			end
-		end
-	end, true, { "send", "accept", "reject" } )
+	return true
+end
 
-
-commands_help['ibb'] = "[[-t target_jid] send filename | accept sid filename | reject sid]\n\nRequests, accepts or rejects sending file via in-band bytestream."
-
-hooks_d['hook-post-connect'].ibb =
-	function ( args )
-		lm.connection.bless( main.connection () ):handler ( ibb_incoming_iq_handler, 'iq', 'normal' )
-		ibb_handler_registered = true
-		hooks_d['hook-post-connect'].ibb = nil
-		hooks_d['hook-quit'].ibb =
-			function ( args )
-				if ibb_handler_registered then
-					lm.connection.bless( main.connection () ):handler ( ibb_incoming_iq_handler, 'iq' )
-				end
-			end
-	end
-
-main.add_feature ( 'http://jabber.org/protocol/ibb' )
+return F
 
 -- vim: se ts=4: --
--- a/examples/iq.lua	Mon Mar 23 09:22:04 2009 +0200
+++ b/examples/iq.lua	Fri Mar 27 01:46:53 2009 +0200
@@ -7,9 +7,9 @@
 
 -- public
 
-iq = { }
+local F = { }
 
-function iq.send ( conn, to, smtype, data, success, fail )
+function F.send ( conn, to, smtype, data, success, fail )
 	data.mtype = 'iq-' .. smtype
 	data.to    = to
 	conn:send ( lm.message.create ( data ),
@@ -27,4 +27,6 @@
 		end )
 end
 
+return F
+
 -- vim: se ts=4: --
--- a/examples/iq_register.lua	Mon Mar 23 09:22:04 2009 +0200
+++ b/examples/iq_register.lua	Fri Mar 27 01:46:53 2009 +0200
@@ -4,7 +4,7 @@
 -- library
 
 require 'lm'
-require 'iq'
+local iq = require 'iq'
 require 'x_data'
 
 -- public
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/mc_ibb.lua	Fri Mar 27 01:46:53 2009 +0200
@@ -0,0 +1,138 @@
+
+require 'lm'
+local ibb = require 'ibb'
+
+local mc_incoming_files = { }
+
+ibb.handler (
+	function ( from, accept, reject )
+		local fid = #mc_incoming_files + 1
+		mc_incoming_files[fid] = {
+				from   = from,
+				accept =
+					function ( name )
+						mc_incoming_files[fid].name = name
+						accept (
+							function ( data )
+								local h = io.open ( mc_incoming_files[fid].name, 'w' )
+								if not h then
+									print ( 'Cannot open output file: ' .. mc_incoming_files[fid].name )
+									return
+								end
+								h:write ( data )
+								h:close ()
+								print ( 'Stream ' .. fid .. ' successfully saved to ' .. mc_incoming_files[fid].name )
+								mc_incoming_files[fid] = nil
+							end,
+							function ( mesg )
+								main.print_info ( from, 'Stream error: ' .. mesg )
+								mc_incoming_files[fid] = nil -- XXX
+							end )
+					end,
+				reject =
+					function ()
+						reject ()
+						print ( 'Stream ' .. fid .. ' rejected' )
+						mc_incoming_files[fid] = nil
+					end,
+		}
+		main.print_info ( from, from .. ' wants you to receive stream. Use /ibb [accept|reject] ' .. fid .. ' to process his request.' )
+	end )
+
+local ibb_sid = 0
+
+main.command ( 'ibb',
+	function ( args )
+		local action = args[1]
+		if action == 'send' then
+			local who
+			if args.t then
+				who = args.t
+			else
+				who = main.full_jid ()
+			end
+			local fname = args[2]
+			local conn  = lm.connection.bless ( main.connection () )
+			local sid   = ibb_sid
+			ibb_sid     = ibb_sid + 1
+			local stream = ibb.new ( conn, who, 4096, sid )
+			stream:open (
+				function ()
+					main.print_info ( who, 'Stream accepted' )
+					local noerr = true
+					local h     = io.open ( fname, 'r' )
+					if not h then
+						print ( 'Cannot open file ' .. fname )
+						return
+					end
+					local data = h:read ( '*a' ) -- In fact, it is better to read it in chunks :/
+					h:close ()
+					local fail =
+						function ( mesg )
+							noerr = false
+							main.print_info ( who, 'Stream error: ' .. mesg )
+						end
+					stream:send ( data,
+						function ( seq )
+							main.print_info ( who, 'Delivery notification of chunk #' .. seq )
+						end, fail )
+					if noerr then
+						stream:close (
+							function ()
+								main.print_info ( who, 'Stream finalizing notification' )
+							end, fail )
+					end
+					if noerr then
+						main.print_info ( who, 'Stream sent' )
+					else
+						main.print_info ( who, 'Stream error occured' )
+					end
+				end,
+				function ( mesg )
+					main.print_info ( who, 'Stream initiation error: ' .. mesg )
+				end )
+		elseif action == 'accept' then
+			local id = tonumber(args[2])
+			if mc_incoming_files[id] then
+				mc_incoming_files[id].accept ( args[3] )
+			end
+		elseif action == 'reject' then
+			local id = tonumber(args[2])
+			if mc_incoming_files[id] then
+				mc_incoming_files[id].reject ()
+			end
+		else
+			local text = ''
+			for sid, data in pairs ( mc_incoming_files ) do
+				text = text .. '\n' ..  sid .. ': ' .. data.from .. ' --> ' .. ( data.name or '?' )
+			end
+			if text ~= '' then
+				print ( 'List of incoming streams:' .. text )
+			else
+				print ( 'No streams' )
+			end
+		end
+	end, true, { "send", "accept", "reject" } )
+
+
+commands_help['ibb'] = "[[-t target_jid] send filename | accept sid filename | reject sid]\n\nRequests, accepts or rejects sending file via in-band bytestream."
+
+local ibb_handler            = lm.message_handler.new ( ibb.iq_handler )
+local ibb_handler_registered = false
+
+hooks_d['hook-post-connect'].ibb =
+	function ( args )
+		lm.connection.bless( main.connection () ):handler ( ibb_handler, 'iq', 'normal' )
+		ibb_handler_registered = true
+		hooks_d['hook-post-connect'].ibb = nil
+		hooks_d['hook-quit'].ibb =
+			function ( args )
+				if ibb_handler_registered then
+					lm.connection.bless( main.connection () ):handler ( ibb_handler, 'iq' )
+				end
+			end
+	end
+
+main.add_feature ( 'http://jabber.org/protocol/ibb' )
+
+-- vim: se ts=4: --
--- a/examples/mcabberrc.lua	Mon Mar 23 09:22:04 2009 +0200
+++ b/examples/mcabberrc.lua	Fri Mar 27 01:46:53 2009 +0200
@@ -265,7 +265,7 @@
 
 -- IN-BAND BYTESTREAMS (XEP-0047)
 
-require 'ibb'
+require 'mc_ibb'
 
 -- VCARD-TEMP (XEP-0054)
 
--- a/examples/oob.lua	Mon Mar 23 09:22:04 2009 +0200
+++ b/examples/oob.lua	Fri Mar 27 01:46:53 2009 +0200
@@ -4,7 +4,7 @@
 -- library
 
 require 'lm'
-require 'iq'
+local iq = require 'iq'
 
 -- public
 
--- a/examples/pep.lua	Mon Mar 23 09:22:04 2009 +0200
+++ b/examples/pep.lua	Fri Mar 27 01:46:53 2009 +0200
@@ -4,7 +4,7 @@
 -- library
 
 require 'lm'
-require 'iq'
+local iq = require 'iq'
 
 -- public
 
--- a/examples/ping.lua	Mon Mar 23 09:22:04 2009 +0200
+++ b/examples/ping.lua	Fri Mar 27 01:46:53 2009 +0200
@@ -4,7 +4,7 @@
 -- library
 
 require 'lm'
-require 'iq'
+local iq = require 'iq'
 
 -- public
 
--- a/examples/pubsub.lua	Mon Mar 23 09:22:04 2009 +0200
+++ b/examples/pubsub.lua	Fri Mar 27 01:46:53 2009 +0200
@@ -4,7 +4,7 @@
 -- library
 
 require 'lm'
-require 'iq'
+local iq = require 'iq'
 require 'x_data'
 
 -- public
--- a/examples/remote.lua	Mon Mar 23 09:22:04 2009 +0200
+++ b/examples/remote.lua	Fri Mar 27 01:46:53 2009 +0200
@@ -4,7 +4,7 @@
 -- library
 
 require 'lm'
-require 'iq'
+local iq = require 'iq'
 require 'x_data'
 require 'disco'
 
--- a/examples/vcard.lua	Mon Mar 23 09:22:04 2009 +0200
+++ b/examples/vcard.lua	Fri Mar 27 01:46:53 2009 +0200
@@ -4,7 +4,7 @@
 -- library
 
 require 'lm'
-require 'iq'
+local iq = require 'iq'
 require 'x_data'
 
 -- public