examples/xep0047.lua
changeset 38 1f141d9a081a
parent 34 8206d7cb1447
child 42 18d801679feb
equal deleted inserted replaced
37:b438d630a556 38:1f141d9a081a
    11 
    11 
    12 ibb_incoming_iq_handler = lm.message_handler.new ( 
    12 ibb_incoming_iq_handler = lm.message_handler.new ( 
    13 	function ( conn, mess )
    13 	function ( conn, mess )
    14 		local id   = mess:attribute ( 'id' )
    14 		local id   = mess:attribute ( 'id' )
    15 		local from = mess:attribute ( 'from' )
    15 		local from = mess:attribute ( 'from' )
    16 		if mess:child ( 'open' ) and mess:child( 'open' ):attribute ( 'xmlns' ) == 'http://jabber.org/protocol/ibb' then
    16 
    17 			local sid  = mess:child( 'open' ):attribute ( 'sid' )
    17 		local open = mess:child ( 'open' )
       
    18 		if open and open:attribute ( 'xmlns' ) == 'http://jabber.org/protocol/ibb' then
       
    19 			local sid  = open:attribute ( 'sid' )
    18 			if not receiving_files[sid] then
    20 			if not receiving_files[sid] then
    19 				local buffer = ''
    21 				local buffer = ''
    20 				receiving_files[sid] = { from = from, status = 'pending' }
    22 				receiving_files[sid] = { from = from, status = 'pending' }
    21 				receiving_files[sid].accept =
    23 				receiving_files[sid].accept =
    22 					function ( name )
    24 					function ( name )
    42 						error = { code = '409', type = 'cancel',
    44 						error = { code = '409', type = 'cancel',
    43 							conflict = { xmlns = 'urn:ietf:params:xml:ns:xmpp-stanzas' }
    45 							conflict = { xmlns = 'urn:ietf:params:xml:ns:xmpp-stanzas' }
    44 						}
    46 						}
    45 					} )
    47 					} )
    46 			end
    48 			end
    47 		elseif mess:child ( 'data' ) and mess:child( 'data' ):attribute ( 'xmlns' ) == 'http://jabber.org/protocol/ibb' then
    49 			return true
    48 			local sid  = mess:child( 'data' ):attribute ( 'sid' )
    50 		end
    49 			local seq  = mess:child( 'data' ):attribute ( 'seq' )
    51 
       
    52 		local qdata = mess:child ( 'data' )
       
    53 		if qdata and qdata:attribute ( 'xmlns' ) == 'http://jabber.org/protocol/ibb' then
       
    54 			local sid  = qdata:attribute ( 'sid' )
       
    55 			local seq  = qdata:attribute ( 'seq' )
    50 			if receiving_files[sid] and from == receiving_files[sid].from and not receiving_files[sid][tonumber(seq)+1] then
    56 			if receiving_files[sid] and from == receiving_files[sid].from and not receiving_files[sid][tonumber(seq)+1] then
    51 				local data = mess:child( 'data' ):value ()
    57 				local data = qdata:value ()
    52 				main.print_info ( from, string.format ( " - stream part %s, id %s, %d bytes", seq, sid, data:len() ) )
    58 				main.print_info ( from, string.format ( " - stream part %s, id %s, %d bytes", seq, sid, data:len() ) )
    53 				conn:send ( lm.message.create { to = from, mtype = 'iq-result', id = id } )
    59 				conn:send ( lm.message.create { to = from, mtype = 'iq-result', id = id } )
    54 				receiving_files[sid][tonumber(seq)+1] = data
    60 				receiving_files[sid][tonumber(seq)+1] = data
    55 			else
    61 			else
    56 				receiving_files[sid] = nil -- invalidate session
    62 				receiving_files[sid] = nil -- invalidate session
    59 						error = { code = '409', type = 'cancel',
    65 						error = { code = '409', type = 'cancel',
    60 							conflict = { xmlns = 'urn:ietf:params:xml:ns:xmpp-stanzas' }
    66 							conflict = { xmlns = 'urn:ietf:params:xml:ns:xmpp-stanzas' }
    61 						}
    67 						}
    62 					} )
    68 					} )
    63 			end
    69 			end
    64 		elseif mess:child ( 'close' ) and mess:child( 'close' ):attribute ( 'xmlns' ) == 'http://jabber.org/protocol/ibb' then
    70 			return true
    65 			local sid  = mess:child( 'close' ):attribute ( 'sid' )
    71 		end
       
    72 
       
    73 		local close = mess:child ( 'close' )
       
    74 		if close and close:attribute ( 'xmlns' ) == 'http://jabber.org/protocol/ibb' then
       
    75 			local sid  = close:attribute ( 'sid' )
    66 			if receiving_files[sid] and from == receiving_files[sid].from then
    76 			if receiving_files[sid] and from == receiving_files[sid].from then
    67 				main.print_info ( from, "Done with stream id " .. sid )
    77 				main.print_info ( from, "Done with stream id " .. sid )
    68 				conn:send ( lm.message.create { to = from, mtype = 'iq-result', id = id } )
    78 				conn:send ( lm.message.create { to = from, mtype = 'iq-result', id = id } )
    69 				local decoder = io.popen ( string.format ( "base64 -d -i >%q", receiving_files[sid].name ), "w" )
    79 				local decoder = io.popen ( string.format ( "base64 -d -i >%q", receiving_files[sid].name ), "w" )
    70 				if not decoder then
    80 				if not decoder then
    82 						error = { code = '409', type = 'cancel',
    92 						error = { code = '409', type = 'cancel',
    83 							conflict = { xmlns = 'urn:ietf:params:xml:ns:xmpp-stanzas' }
    93 							conflict = { xmlns = 'urn:ietf:params:xml:ns:xmpp-stanzas' }
    84 						}
    94 						}
    85 					} )
    95 					} )
    86 			end
    96 			end
    87 		else
    97 			return true
    88 			return false
    98 		end
    89 		end
    99 
    90 		return true
   100 		return false
    91 	end )
   101 	end )
    92 
   102 
    93 function send_file ( to, name )
   103 function ibb_send_file ( conn, to, name )
    94 	if not to then
   104 	if not to then
    95 		to = main.full_jid ()
   105 		to = main.full_jid ()
    96 	elseif not to:match ( "/" ) then
   106 	elseif not to:match ( "/" ) then
    97 		to = main.full_jid ( to )
   107 		to = main.full_jid ( to )
    98 	end
   108 	end
    99 	local sid = gen_unique_sid ()
   109 	local sid = gen_unique_sid ()
   100 	local conn = lm.connection.bless ( main.connection () )
       
   101 	conn:send (
   110 	conn:send (
   102 		lm.message.create { to = to, mtype = 'iq-set',
   111 		lm.message.create { to = to, mtype = 'iq-set',
   103 			open = { sid = sid, ['block-size'] = ibb_block_size, xmlns = 'http://jabber.org/protocol/ibb' }
   112 			open = { sid = sid, ['block-size'] = ibb_block_size, xmlns = 'http://jabber.org/protocol/ibb' }
   104 		},
   113 		},
   105 		function ( conn, message )
   114 		function ( conn, message )
   173 			if args.t then
   182 			if args.t then
   174 				who = args.t
   183 				who = args.t
   175 			else
   184 			else
   176 				who = main.full_jid ()
   185 				who = main.full_jid ()
   177 			end
   186 			end
   178 			send_file ( who, args[2] )
   187 			ibb_send_file ( lm.connection.bless ( main.connection () ), who, args[2] )
   179 		elseif action == 'accept' then
   188 		elseif action == 'accept' then
   180 			local id = args[2]
   189 			local id = args[2]
   181 			if receiving_files[id] then
   190 			if receiving_files[id] then
   182 				receiving_files[id].accept ( args[3] )
   191 				receiving_files[id].accept ( args[3] )
   183 			end
   192 			end
   205 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."
   214 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."
   206 
   215 
   207 hooks_d['hook-post-connect'].xep0047 =
   216 hooks_d['hook-post-connect'].xep0047 =
   208 	function ( args )
   217 	function ( args )
   209 		lm.connection.bless( main.connection () ):handler ( ibb_incoming_iq_handler, 'iq', 'normal' )
   218 		lm.connection.bless( main.connection () ):handler ( ibb_incoming_iq_handler, 'iq', 'normal' )
   210 		main.add_feature ( 'http://jabber.org/protocol/ibb' )
       
   211 		ibb_handler_registered = true
   219 		ibb_handler_registered = true
   212 		hooks_d['hook-post-connect'].xep0047 = nil
   220 		hooks_d['hook-post-connect'].xep0047 = nil
   213 		hooks_d['hook-quit'].xep0047 =
   221 		hooks_d['hook-quit'].xep0047 =
   214 			function ( args )
   222 			function ( args )
   215 				if ibb_handler_registered then
   223 				if ibb_handler_registered then
   216 					lm.connection.bless( main.connection () ):handler ( ibb_incoming_iq_handler, 'iq' )
   224 					lm.connection.bless( main.connection () ):handler ( ibb_incoming_iq_handler, 'iq' )
   217 				end
   225 				end
   218 			end
   226 			end
   219 	end
   227 	end
   220 
   228 
       
   229 main.add_feature ( 'http://jabber.org/protocol/ibb' )
       
   230 
   221 -- vim: se ts=4: --
   231 -- vim: se ts=4: --