rgadu 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. data/lib/gg/dccclient.rb +4 -0
  2. data/lib/gg/dccserver.rb +27 -10
  3. data/lib/gg.rb +43 -27
  4. metadata +3 -3
data/lib/gg/dccclient.rb CHANGED
@@ -32,6 +32,8 @@ class DCCClient < DCCServer
32
32
  @callback[@code] = callback if callback
33
33
  begin
34
34
  send7(@code, @socket, filename, filesize, offset)
35
+ rescue SystemCallError
36
+ callback.call(:aborted)
35
37
  ensure
36
38
  @progress.delete(@server_uin)
37
39
  end
@@ -41,6 +43,8 @@ class DCCClient < DCCServer
41
43
  @callback[@code] = callback if callback
42
44
  begin
43
45
  recv7(@code, @socket, filename, filesize, offset)
46
+ rescue SystemCallError, RuntimeError
47
+ callback.call(:aborted) if callback
44
48
  ensure
45
49
  @progress.delete(@server_uin)
46
50
  end
data/lib/gg/dccserver.rb CHANGED
@@ -40,6 +40,8 @@ class DCCServer
40
40
  session.write(code)
41
41
  begin
42
42
  send7(code, session, filename, filesize, offset)
43
+ rescue SystemCallError
44
+ @callback[code].call(:aborted) if @callback[code]
43
45
  ensure
44
46
  @progress[code]=@callback[code]=nil
45
47
  end
@@ -47,6 +49,8 @@ class DCCServer
47
49
  session.write(packet_raw)
48
50
  begin
49
51
  recv7(code, session, filename, filesize, offset)
52
+ rescue SystemCallError, RuntimeError
53
+ @callback[code].call(:aborted) if @callback[code]
50
54
  ensure
51
55
  @progress[code]=@callback[code]=nil
52
56
  end
@@ -62,11 +66,18 @@ class DCCServer
62
66
  base=File.basename(filename)
63
67
  alternate=base[0..12].upcase
64
68
  session.write([0x01, 0x03, 0, 0, fileattr, creationlow, creationhigh, accesslow, accesshigh, writelow, writehigh, sizehigh, filesize, 0, 0, base, alternate].pack('LLLLLLLLLLLLLLLa262a14'))
65
- packet_raw = session.read(12) or return
69
+ begin
70
+ packet_raw = session.read(12) or raise
71
+ rescue SystemCallError, RuntimeError
72
+ @callback[client_uin].call(:rejected) if @callback[client_uin]
73
+ return
74
+ end
66
75
  type, offset = packet_raw.unpack('LLL')
67
76
  if type==0x06 and offset<filesize
68
77
  begin
69
78
  send(client_uin, session, filename, filesize, offset)
79
+ rescue SystemCallError
80
+ @callback[client_uin].call(:aborted) if @callback[client_uin]
70
81
  ensure
71
82
  @progress[client_uin]=@callback[client_uin]=nil
72
83
  end
@@ -75,7 +86,7 @@ class DCCServer
75
86
 
76
87
  def send(client_uin, session, filename, filesize, offset)
77
88
  @progress[client_uin] = bytes = offset
78
- file=File.open(filename, 'r')
89
+ file=File.open(filename, 'rb')
79
90
  file.seek(offset) if offset>0
80
91
  while bytes<filesize and data=file.read(4096)
81
92
  length = data.length
@@ -90,6 +101,7 @@ class DCCServer
90
101
  @progress[client_uin] = bytes
91
102
  @callback[client_uin].call(bytes) if @callback[client_uin]
92
103
  end
104
+ file.close
93
105
  end
94
106
 
95
107
  def init_recv(session, client_uin)
@@ -116,6 +128,8 @@ class DCCServer
116
128
  session.write([0x06, offset, 0].pack('LLL')) or return
117
129
  begin
118
130
  recv(client_uin, session, local_filename, filesize, offset)
131
+ rescue SystemCallError, RuntimeError
132
+ @callback[client_uin].call(:aborted) if @callback[client_uin]
119
133
  ensure
120
134
  @progress[client_uin]=@callback[client_uin]=nil
121
135
  end
@@ -126,19 +140,20 @@ class DCCServer
126
140
 
127
141
  def recv(client_uin, session, filename, filesize, offset)
128
142
  if offset>0
129
- mode='a'
143
+ mode='ab'
130
144
  else
131
- mode='w'
145
+ mode='wb'
132
146
  end
133
147
  file=File.open(filename, mode)
134
148
  @progress[client_uin] = bytes = offset
135
- while packet_raw=session.read(12)
149
+ while bytes < filesize
150
+ packet_raw=session.read(12) or raise
136
151
  type, length = packet_raw.unpack('LLL')
137
152
  if bytes+length > filesize
138
153
  break
139
154
  end
140
155
  if type==0x03 or type==0x02
141
- packet=session.read(length) or return
156
+ packet=session.read(length) or raise
142
157
  file.write(packet)
143
158
  bytes+=length
144
159
  @progress[client_uin] = bytes
@@ -152,7 +167,7 @@ class DCCServer
152
167
  def send7(code, session, filename, filesize, offset)
153
168
  return unless File.exist?(filename)
154
169
  @progress[code]=bytes=offset
155
- file=File.open(filename, 'r')
170
+ file=File.open(filename, 'rb')
156
171
  file.seek(offset) if offset>0
157
172
  while bytes<filesize and data=file.read(4096)
158
173
  session.write(data) or return
@@ -160,17 +175,19 @@ class DCCServer
160
175
  @progress[code] = bytes
161
176
  @callback[code].call(bytes) if @callback[code]
162
177
  end
178
+ file.close
163
179
  end
164
180
 
165
181
  def recv7(code, session, filename, filesize, offset)
166
182
  if offset>0
167
- mode='a'
183
+ mode='ab'
168
184
  else
169
- mode='w'
185
+ mode='wb'
170
186
  end
171
187
  file=File.open(filename, mode)
172
188
  @progress[code]=bytes=offset
173
- while bytes<filesize and data=session.read(4096)
189
+ while bytes<filesize
190
+ data=session.read(4096) or raise
174
191
  file.write(data)
175
192
  bytes += data.length
176
193
  @progress[code] = bytes
data/lib/gg.rb CHANGED
@@ -36,9 +36,9 @@ class GG
36
36
  0x1f => 'LLa8a21a43'}
37
37
 
38
38
  =begin rdoc
39
- Tworzy nowy obiekt GG i loguje sie na serwerze. Opcjonalnie uruchamia serwer DCC na porcie *dccport*.
39
+ Tworzy nowy obiekt GG i loguje sie na serwerze. Opcjonalnie uruchamia serwer DCC na porcie *dccport* i przesy�a serwerowi tablic� z list� kontakt�w.
40
40
  =end
41
- def initialize(uin, password, dccport=0, server='217.17.45.146', port=8074)
41
+ def initialize(uin, password, dccport=0, contacts=nil, server='217.17.45.146', port=8074)
42
42
  @uin=uin
43
43
  @dccport=dccport
44
44
  @socket=TCPSocket.new(server, port)
@@ -60,7 +60,11 @@ Tworzy nowy obiekt GG i loguje sie na serwerze. Opcjonalnie uruchamia serwer DCC
60
60
  unless type==0x03 or type==0x14
61
61
  raise "Authorization failed"
62
62
  end
63
- write(0x12, '')
63
+ if contacts and contacts.length > 0
64
+ write(0x10, 'LC'*contacts.length, *(contacts.map {|contact| [contact, 0x03] }.flatten))
65
+ else
66
+ write(0x12, '')
67
+ end
64
68
  @action, @status, @search_reply, @dcc_code, @dcc_action, @dcc_client_action = {}, {}, {}, [], {}, {}
65
69
  @action_thread, @dcc_client, @dcc_client_thread = [], [], []
66
70
  @action[0x0a] = lambda {|sender, seq, time, cl, message| msg_received(sender, seq, time, cl, message) }
@@ -71,6 +75,7 @@ Tworzy nowy obiekt GG i loguje sie na serwerze. Opcjonalnie uruchamia serwer DCC
71
75
  @action[0x0e] = lambda {|type, seq, response| @search_reply[seq] = response }
72
76
  @action[0x23] = lambda {|type, code| @dcc_code << code }
73
77
  @action[0x21] = lambda {|uin, code, offset, x| @dcc_action[code].call(offset) if @dcc_action[code] }
78
+ @action[0x22] = lambda {|uin, code, reason| @dcc_action[code].call(-1) if @dcc_action[code] }
74
79
  @action[0x1f] = lambda do |uin, x, code, ip_port, y|
75
80
  if action = @dcc_client_action[code]
76
81
  @dcc_client_action.delete(code)
@@ -95,7 +100,7 @@ Tworzy nowy obiekt GG i loguje sie na serwerze. Opcjonalnie uruchamia serwer DCC
95
100
  Wysyla wiadomosc *message* do *uin*.
96
101
  =end
97
102
  def msg(uin, message)
98
- write(0x0b, 'LLLa*C', uin, rand(2**32), 0x04, message, 0)
103
+ write(0x0b, 'LLLa*C', uin, rand(2**32), 0x08, message, 0)
99
104
  end
100
105
 
101
106
  =begin rdoc
@@ -177,42 +182,53 @@ Wyszukiwanie w katalogu publicznym. *params* moze byc numerem GG lub tablica aso
177
182
  end
178
183
 
179
184
  =begin rdoc
180
- Wysyla plik *filename* do *uin*. Jesli dolaczono blok kodu, blok ten bedzie wywolywany podczas wysylania pliku. Blok przyjmuje jeden parametr - aktualna pozycje pliku w bajtach. Funkcja w zaleznosci od wersji protokolu DCC zwraca kod transferu lub numer GG odbiorcy.
185
+ Wysyla plik *filename* do *uin*. Mo�na poda� hash SHA1 pliku w postaci ci�gu bajt�w, w przeciwnym razie hash jest obliczany w razie potrzeby. Jesli dolaczono blok kodu, blok ten bedzie wywolywany podczas wysylania pliku. Blok przyjmuje jeden parametr - aktualn� pozycj� pliku w bajtach, symbol :rejected je�li po��czenie zosta�o odrzucone lub :aborted w przypadku przerwania transferu. Funkcja w zaleznosci od wersji protokolu DCC zwraca kod transferu lub numer GG odbiorcy.
181
186
  =end
182
- def dcc_request(uin, filename, &callback)
187
+ def dcc_request(uin, filename, hash=nil, &callback)
183
188
  raise "No DCC server" unless @dcc
184
189
  if File.exist?(filename)
185
- if @status[uin] and version=@status[uin][:version] and version.to_f >= 7.7
190
+ if @status[uin] and version=@status[uin][:version] and version.to_f >= 7.6
186
191
  write(0x23, 'L', 0x04)
187
192
  sleep 0.1 until code = @dcc_code.shift
188
193
  filesize=File.size(filename)
189
- hash=Digest::SHA1.digest(File.read(filename))
194
+ unless hash
195
+ checksum = Digest::SHA1.new
196
+ file = File.open(filename, 'rb')
197
+ while chunk = file.read(1048576)
198
+ checksum << chunk
199
+ end
200
+ file.close
201
+ hash = checksum.digest
202
+ end
190
203
  write(0x20, 'a8LLLa226a29LLa20', code, @uin, uin, 0x04, File.basename(filename), '', filesize, 0, hash)
191
204
  @dcc_action[code] = lambda do |offset|
192
- if callback
193
- @dcc.add_send_code(code, filename, filesize, offset) {|pos| callback.call(pos) }
205
+ if offset == -1
206
+ callback.call(:rejected)
194
207
  else
195
- @dcc.add_send_code(code, filename, filesize, offset)
196
- end
197
- write(0x1f, 'LLa8a21a43', uin, 0x01, code, @socket.addr[3]+' '+@dccport.to_s, '')
198
- if @socket.addr[3] =~ /^(10\.|172\.16\.|192\.168\.)/
199
- @dcc_client_action[code] = lambda do |ip, port|
200
- @dcc_client_thread << Thread.new(ip, port, @uin, uin, code, filename, filesize, offset, callback) do |ip, port, client_uin, server_uin, code, filename, filesize, offset, callback|
201
- begin
202
- client = DCCClient.new(ip, port, client_uin, server_uin, code)
203
- @dcc_client << client
204
- if callback
205
- client.client_send7(filename, filesize, offset) {|pos| callback.call(pos) }
206
- else
207
- client.client_send7(filename, filesize, offset)
208
+ if callback
209
+ @dcc.add_send_code(code, filename, filesize, offset) {|pos| callback.call(pos) }
210
+ else
211
+ @dcc.add_send_code(code, filename, filesize, offset)
212
+ end
213
+ write(0x1f, 'LLa8a21a43', uin, 0x01, code, @socket.addr[3]+' '+@dccport.to_s, '')
214
+ if @socket.addr[3] =~ /^(10\.|172\.16\.|192\.168\.)/
215
+ @dcc_client_action[code] = lambda do |ip, port|
216
+ @dcc_client_thread << Thread.new(ip, port, @uin, uin, code, filename, filesize, offset, callback) do |ip, port, client_uin, server_uin, code, filename, filesize, offset, callback|
217
+ begin
218
+ client = DCCClient.new(ip, port, client_uin, server_uin, code)
219
+ @dcc_client << client
220
+ if callback
221
+ client.client_send7(filename, filesize, offset) {|pos| callback.call(pos) }
222
+ else
223
+ client.client_send7(filename, filesize, offset)
224
+ end
225
+ rescue
226
+ warn "Error: #{$!}"
208
227
  end
209
- rescue
210
- warn "Error: #{$!}"
211
228
  end
212
229
  end
213
230
  end
214
231
  end
215
-
216
232
  end
217
233
  code
218
234
  else
@@ -362,7 +378,7 @@ Rozlacza sie z serwerem GG, wylacza serwer DCC i zamyka wszystkie polaczenia DCC
362
378
  @ping_loop.exit
363
379
  @read_loop.exit
364
380
  @socket.close
365
- @dcc.close
381
+ @dcc.close if @dcc
366
382
  @dcc_client_thread.each {|t| t.exit }
367
383
  end
368
384
 
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: rgadu
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.1.0
7
- date: 2007-08-04 00:00:00 +02:00
6
+ version: 0.1.1
7
+ date: 2007-08-22 00:00:00 +02:00
8
8
  summary: A simple pure-Ruby implementation of the Gadu-Gadu protocol.
9
9
  require_paths:
10
10
  - lib
@@ -12,7 +12,7 @@ email: bl4@playker.info
12
12
  homepage:
13
13
  rubyforge_project:
14
14
  description:
15
- autorequire: gg
15
+ autorequire:
16
16
  default_executable:
17
17
  bindir: bin
18
18
  has_rdoc: true