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: -- |