examples/xep0047.lua
changeset 66 542f61e113cb
parent 65 f1be8dbb209c
child 67 d33ca5572e91
--- a/examples/xep0047.lua	Fri Mar 27 09:48:17 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,237 +0,0 @@
-
-receiving_files = {}
-ibb_block_size  = 4096
-local ibb_sid = 0
-
-ibb_incoming_iq_handler = lm.message_handler.new ( 
-	function ( conn, mess )
-		local id   = mess:attribute ( 'id' )
-		local from = mess:attribute ( 'from' )
-
-		local open = mess:child ( 'open' )
-		if open and open:attribute ( 'xmlns' ) == 'http://jabber.org/protocol/ibb' then
-			local sid  = open:attribute ( 'sid' )
-			if not receiving_files[sid] then
-				local buffer = ''
-				receiving_files[sid] = { from = from, status = 'pending' }
-				receiving_files[sid].accept =
-					function ( name )
-						main.print_info ( from, string.format ( "Receiving stream from %s, id %s", from, sid ) )
-						conn:send ( lm.message.create { to = from, mtype = 'iq-result', id = id } )
-						receiving_files[sid].name = name
-						receiving_files[sid].status = 'accepted'
-					end
-				receiving_files[sid].reject =
-					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' }
-								}
-							} )
-						receiving_files[sid].status = 'rejected'
-					end
-				print ( 'You have a new bytestream to receive. To save it use /ibb accept ' .. sid .. ' filename' )
-			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
-			return true
-		end
-
-		local qdata = mess:child ( 'data' )
-		if qdata and qdata:attribute ( 'xmlns' ) == 'http://jabber.org/protocol/ibb' then
-			local sid  = qdata:attribute ( 'sid' )
-			local seq  = qdata:attribute ( 'seq' )
-			if receiving_files[sid] and from == receiving_files[sid].from and not receiving_files[sid][tonumber(seq)+1] then
-				local data = qdata:value ()
-				main.print_info ( from, string.format ( " - stream part %s, id %s, %d bytes", seq, sid, data:len() ) )
-				conn:send ( lm.message.create { to = from, mtype = 'iq-result', id = id } )
-				receiving_files[sid][tonumber(seq)+1] = data
-			else
-				receiving_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
-			return true
-		end
-
-		local close = mess:child ( 'close' )
-		if close and close:attribute ( 'xmlns' ) == 'http://jabber.org/protocol/ibb' then
-			local sid  = close:attribute ( 'sid' )
-			if receiving_files[sid] and from == receiving_files[sid].from then
-				main.print_info ( from, "Done with stream id " .. sid )
-				conn:send ( lm.message.create { to = from, mtype = 'iq-result', id = id } )
-				local decoder = io.popen ( string.format ( "base64 -d -i >%q", receiving_files[sid].name ), "w" )
-				if not decoder then
-					main.print_info ( from, "Error opening decoder" )
-				else
-					for i, v in ipairs ( receiving_files[sid] ) do
-						decoder:write ( v )
-					end
-					decoder:close ()
-				end
-			else
-				receiving_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
-			return true
-		end
-
-		return false
-	end )
-
-function ibb_send_file ( conn, to, name, id )
-	if not to then
-		to = main.full_jid ()
-	elseif not to:match ( "/" ) then
-		to = main.full_jid ( to )
-	end
-	local sid = id
-	if not sid then -- XXX: move out of here?
-		ibb_sid = ibb_sid + 1
-		sid = 'ibb_' .. ibb_sid
-	end
-	conn:send (
-		lm.message.create { to = to, mtype = 'iq-set',
-			open = { sid = sid, ['block-size'] = ibb_block_size, xmlns = 'http://jabber.org/protocol/ibb' }
-		},
-		function ( conn, message )
-			if message:child ( 'error' ) then
-				main.print_info ( to, "Stream request refused: " .. message:child( 'error' ):children():name () )
-			else
-				main.print_info ( to, "Stream accepted, starting sequence" )
-				local buffer = ''
-				main.bgread ( string.format ( 'base64 -w 0 %q', name ), -- FIXME: stream reader function? XXX: then we need in-place base64 encoder.
-					function ( data )
-						if data then
-							buffer = buffer .. data
-							return true
-						else
-							local seq = 0
-							local msgbuf = buffer:sub ( 1, ibb_block_size )
-							buffer = buffer:sub ( ibb_block_size + 1 )
-							local function handler ( conn, mess )
-								local mtype, smtype = mess:type ()
-								if smtype == 'error' then
-									main.print_info ( to, "Stream error, transfer ceased at seq = " .. seq .. ": " .. message:child( 'error' ):children():name () )
-								elseif smtype == 'result' then
-									main.print_info ( to, " - acquired seq = " .. seq )
-									seq = seq + 1
-									if buffer:len () == 0 then
-										conn:send (
-											lm.message.create { to = to, mtype = 'iq-set',
-												close = { sid = sid, xmlns = 'http://jabber.org/protocol/ibb' }
-											},
-											function ( conn, mess )
-												local mtype, smtype = mess:type ()
-												if smtype == 'error' then
-													main.print_info ( to, "Error at closing stream: " .. mess:child( 'error' ):children():name () )
-												elseif smtype == 'result' then
-													main.print_info ( to, "File successfully transferred" )
-												else
-													print ( 'Weird response for close of ibb stream: ' .. mess:xml () )
-													return false
-												end
-												return true
-											end )
-									else
-										local msgbuf = buffer:sub ( 1, ibb_block_size )
-										buffer = buffer:sub ( ibb_block_size )
-										conn:send (
-											lm.message.create { to = to, mtype = 'iq-set',
-												data = { sid = sid, xmlns = 'http://jabber.org/protocol/ibb', seq = seq,
-													msgbuf
-												}
-											},
-											handler )
-									end
-								else
-									print ( 'Weird response for ibb block: ' .. mess:xml () )
-									return false
-								end
-								return true
-							end
-							conn:send (
-								lm.message.create { to = to, mtype = 'iq-set',
-									data = { sid = sid, xmlns = 'http://jabber.org/protocol/ibb', seq = seq,
-										msgbuf
-									}
-								},
-								handler )
-							return false
-						end
-					end )
-			end
-			return true
-		end )
-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
-			ibb_send_file ( lm.connection.bless ( main.connection () ), who, args[2] )
-		elseif action == 'accept' then
-			local id = args[2]
-			if receiving_files[id] then
-				receiving_files[id].accept ( args[3] )
-			end
-		elseif action == 'reject' then
-			local id = args[2]
-			if receiving_files[id] then
-				receiving_files[id].reject ()
-			end
-		elseif action == 'del' then
-			local id = args[2]
-			receiving_files[id] = nil
-		else
-			local text = ''
-			for sid, data in pairs ( receiving_files ) do
-				text = text .. '\n' ..  sid .. ': ' .. ( data.name or '(not set)' ) .. ' [' .. data.status .. ']'
-			end
-			if text ~= '' then
-				print ( 'List of incoming streams:' .. text )
-			else
-				print ( 'No streams' )
-			end
-		end
-	end, true, { "send", "accept", "reject", "del" } )
-
-commands_help['ibb'] = "[[-t target_jid] send filename | accept sid filename | reject sid filename | del sid]\n\nRequests, accepts or rejects sending file via in-band bytestream."
-
-hooks_d['hook-post-connect'].xep0047 =
-	function ( args )
-		lm.connection.bless( main.connection () ):handler ( ibb_incoming_iq_handler, 'iq', 'normal' )
-		ibb_handler_registered = true
-		hooks_d['hook-post-connect'].xep0047 = nil
-		hooks_d['hook-quit'].xep0047 =
-			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' )
-
--- vim: se ts=4: --