1 |
|
2 local lm = require 'lm' |
|
3 local ibb = require 'ibb' |
|
4 |
|
5 local mc_incoming_files = { } |
|
6 |
|
7 ibb.handler ( |
|
8 function ( from, accept, reject ) |
|
9 local fid = #mc_incoming_files + 1 |
|
10 mc_incoming_files[fid] = { |
|
11 from = from, |
|
12 accept = |
|
13 function ( name ) |
|
14 mc_incoming_files[fid].name = name |
|
15 accept ( |
|
16 function ( data ) |
|
17 local h = io.open ( mc_incoming_files[fid].name, 'w' ) |
|
18 if not h then |
|
19 print ( 'Cannot open output file: ' .. mc_incoming_files[fid].name ) |
|
20 return |
|
21 end |
|
22 h:write ( data ) |
|
23 h:close () |
|
24 print ( 'Stream ' .. fid .. ' successfully saved to ' .. mc_incoming_files[fid].name ) |
|
25 mc_incoming_files[fid] = nil |
|
26 end, |
|
27 function ( mesg ) |
|
28 main.print_info ( from, 'Stream error: ' .. mesg ) |
|
29 mc_incoming_files[fid] = nil -- XXX |
|
30 end ) |
|
31 end, |
|
32 reject = |
|
33 function () |
|
34 reject () |
|
35 print ( 'Stream ' .. fid .. ' rejected' ) |
|
36 mc_incoming_files[fid] = nil |
|
37 end, |
|
38 } |
|
39 main.print_info ( from, from .. ' wants you to receive stream. Use /ibb [accept|reject] ' .. fid .. ' to process his request.' ) |
|
40 end ) |
|
41 |
|
42 local ibb_sid = 0 |
|
43 |
|
44 main.command ( 'ibb', |
|
45 function ( args ) |
|
46 local action = args[1] |
|
47 if action == 'send' then |
|
48 local who |
|
49 if args.t then |
|
50 who = args.t |
|
51 else |
|
52 who = main.full_jid () |
|
53 end |
|
54 local fname = args[2] |
|
55 local conn = lm.connection.bless ( main.connection () ) |
|
56 local sid = ibb_sid |
|
57 ibb_sid = ibb_sid + 1 |
|
58 local stream = ibb.new ( conn, who, 4096, sid ) |
|
59 stream:open ( |
|
60 function () |
|
61 main.print_info ( who, 'Stream accepted' ) |
|
62 local noerr = true |
|
63 local h = io.open ( fname, 'r' ) |
|
64 if not h then |
|
65 print ( 'Cannot open file ' .. fname ) |
|
66 return |
|
67 end |
|
68 local data = h:read ( '*a' ) -- In fact, it is better to read it in chunks :/ |
|
69 h:close () |
|
70 local fail = |
|
71 function ( mesg ) |
|
72 noerr = false |
|
73 main.print_info ( who, 'Stream error: ' .. mesg ) |
|
74 end |
|
75 stream:send ( data, |
|
76 function ( seq ) |
|
77 main.print_info ( who, 'Delivery notification of chunk #' .. seq ) |
|
78 end, fail ) |
|
79 if noerr then |
|
80 stream:close ( |
|
81 function () |
|
82 main.print_info ( who, 'Stream finalizing notification' ) |
|
83 end, fail ) |
|
84 end |
|
85 if noerr then |
|
86 main.print_info ( who, 'Stream sent' ) |
|
87 else |
|
88 main.print_info ( who, 'Stream error occured' ) |
|
89 end |
|
90 end, |
|
91 function ( mesg ) |
|
92 main.print_info ( who, 'Stream initiation error: ' .. mesg ) |
|
93 end ) |
|
94 elseif action == 'accept' then |
|
95 local id = tonumber(args[2]) |
|
96 if mc_incoming_files[id] then |
|
97 mc_incoming_files[id].accept ( args[3] ) |
|
98 end |
|
99 elseif action == 'reject' then |
|
100 local id = tonumber(args[2]) |
|
101 if mc_incoming_files[id] then |
|
102 mc_incoming_files[id].reject () |
|
103 end |
|
104 else |
|
105 local text = '' |
|
106 for sid, data in pairs ( mc_incoming_files ) do |
|
107 text = text .. '\n' .. sid .. ': ' .. data.from .. ' --> ' .. ( data.name or '?' ) |
|
108 end |
|
109 if text ~= '' then |
|
110 print ( 'List of incoming streams:' .. text ) |
|
111 else |
|
112 print ( 'No streams' ) |
|
113 end |
|
114 end |
|
115 end, true, { "send", "accept", "reject" } ) |
|
116 |
|
117 |
|
118 commands_help['ibb'] = "[[-t target_jid] send filename | accept sid filename | reject sid]\n\nRequests, accepts or rejects sending file via in-band bytestream." |
|
119 |
|
120 local ibb_handler = lm.message_handler.new ( ibb.iq_handler ) |
|
121 local ibb_handler_registered = false |
|
122 |
|
123 hooks_d['hook-post-connect'].ibb = |
|
124 function ( args ) |
|
125 lm.connection.bless( main.connection () ):handler ( ibb_handler, 'iq', 'normal' ) |
|
126 ibb_handler_registered = true |
|
127 hooks_d['hook-post-connect'].ibb = nil |
|
128 hooks_d['hook-quit'].ibb = |
|
129 function ( args ) |
|
130 if ibb_handler_registered then |
|
131 lm.connection.bless( main.connection () ):handler ( ibb_handler, 'iq' ) |
|
132 end |
|
133 end |
|
134 end |
|
135 |
|
136 main.add_feature ( 'http://jabber.org/protocol/ibb' ) |
|
137 |
|
138 -- vim: se ts=4: -- |
|