rims 0.2.9 → 0.3.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -0
- data/lib/rims.rb +31 -29
- data/lib/rims/cmd.rb +38 -1
- data/lib/rims/protocol.rb +28 -7
- data/lib/rims/protocol/decoder.rb +132 -78
- data/lib/rims/protocol/parser.rb +82 -32
- data/lib/rims/service.rb +31 -1
- data/lib/rims/test.rb +1 -2
- data/lib/rims/version.rb +1 -1
- data/rims.gemspec +1 -1
- data/test/cmd/test_command.rb +6 -0
- data/test/test_error.rb +1 -1
- data/test/test_passwd.rb +1 -1
- data/test/test_protocol_decoder.rb +273 -8
- data/test/test_protocol_request.rb +305 -280
- data/test/test_service.rb +39 -0
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 302a70ed845d6af656e11c2a6fde78cfda71a33b1d5673654594634b7fe92f63
|
4
|
+
data.tar.gz: 468e136c3796d1ea15d9e554be3f6dd38b5d34fe3089c7db71a0d7a87d73e9cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 96c2d58c1990e724743581436c0e373bcb147e4afd799f8c9860146cf2c4fa33b5652a2937a4185590a5b7a79c2309bf899d16268eeed92765b08572c74d3884
|
7
|
+
data.tar.gz: 816e5242fbf6c361d81306f516c27eab7046d73829ae7a08065a44788ef28afba71923b0eb6b200d7a0b6f2791fda24e8f7c4a6d481ff9502333fa4fc2179c03
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,29 @@
|
|
1
1
|
Change Log
|
2
2
|
==========
|
3
3
|
|
4
|
+
<!--
|
5
|
+
subsections:
|
6
|
+
### Added
|
7
|
+
### Changed
|
8
|
+
### Removed
|
9
|
+
### Fixed
|
10
|
+
-->
|
11
|
+
|
12
|
+
0.3.0
|
13
|
+
-----
|
14
|
+
|
15
|
+
### Added
|
16
|
+
- Input size limits.
|
17
|
+
[#34](https://github.com/y10k/rims/issues/34)
|
18
|
+
- Configurable bulk_response_size parameter.
|
19
|
+
[#36](https://github.com/y10k/rims/issues/36)
|
20
|
+
|
21
|
+
### Changed
|
22
|
+
- Ready to Ruby 2.7.
|
23
|
+
[#35](https://github.com/y10k/rims/issues/35)
|
24
|
+
- Semantic versioning.
|
25
|
+
[#37](https://github.com/y10k/rims/issues/37)
|
26
|
+
|
4
27
|
0.2.9
|
5
28
|
-----
|
6
29
|
Released on 2019-12-12.
|
data/lib/rims.rb
CHANGED
@@ -5,35 +5,37 @@ require "rims/version"
|
|
5
5
|
autoload :OpenSSL, 'openssl'
|
6
6
|
|
7
7
|
module RIMS
|
8
|
-
autoload :Authentication,
|
9
|
-
autoload :Checksum_KeyValueStore,
|
10
|
-
autoload :Cmd,
|
11
|
-
autoload :
|
12
|
-
autoload :
|
13
|
-
autoload :
|
14
|
-
autoload :
|
15
|
-
autoload :Hash_KeyValueStore,
|
16
|
-
autoload :IllegalLockError,
|
17
|
-
autoload :KeyValueStore,
|
18
|
-
autoload :
|
19
|
-
autoload :
|
20
|
-
autoload :
|
21
|
-
autoload :
|
22
|
-
autoload :
|
23
|
-
autoload :MessageSetSyntaxError,
|
24
|
-
autoload :Password,
|
25
|
-
autoload :Protocol,
|
26
|
-
autoload :ProtocolError,
|
27
|
-
autoload :RFC822,
|
28
|
-
autoload :ReadLockError,
|
29
|
-
autoload :ReadLockTimeoutError,
|
30
|
-
autoload :
|
31
|
-
autoload :
|
32
|
-
autoload :
|
33
|
-
autoload :
|
34
|
-
autoload :
|
35
|
-
autoload :
|
36
|
-
autoload :
|
8
|
+
autoload :Authentication, 'rims/auth'
|
9
|
+
autoload :Checksum_KeyValueStore, 'rims/cksum_kvs'
|
10
|
+
autoload :Cmd, 'rims/cmd'
|
11
|
+
autoload :CommandSizeTooLargeError, 'rims/protocol'
|
12
|
+
autoload :DB, 'rims/db'
|
13
|
+
autoload :Error, 'rims/error'
|
14
|
+
autoload :GDBM_KeyValueStore, 'rims/gdbm_kvs'
|
15
|
+
autoload :Hash_KeyValueStore, 'rims/hash_kvs'
|
16
|
+
autoload :IllegalLockError, 'rims/lock'
|
17
|
+
autoload :KeyValueStore, 'rims/kvs'
|
18
|
+
autoload :LineTooLongError, 'rims/protocol'
|
19
|
+
autoload :LiteralSizeTooLargeError, 'rims/protocol'
|
20
|
+
autoload :LockError, 'rims/lock'
|
21
|
+
autoload :MailFolder, 'rims/mail_store'
|
22
|
+
autoload :MailStore, 'rims/mail_store'
|
23
|
+
autoload :MessageSetSyntaxError, 'rims/protocol'
|
24
|
+
autoload :Password, 'rims/passwd'
|
25
|
+
autoload :Protocol, 'rims/protocol'
|
26
|
+
autoload :ProtocolError, 'rims/protocol'
|
27
|
+
autoload :RFC822, 'rims/rfc822'
|
28
|
+
autoload :ReadLockError, 'rims/lock'
|
29
|
+
autoload :ReadLockTimeoutError, 'rims/lock'
|
30
|
+
autoload :ReadSizeError, 'rims/protocol'
|
31
|
+
autoload :ReadWriteLock, 'rims/lock'
|
32
|
+
autoload :RecoverableReadSizeError, 'rims/protocol'
|
33
|
+
autoload :ServerResponseChannel, 'rims/channel'
|
34
|
+
autoload :Service, 'rims/service'
|
35
|
+
autoload :SyntaxError, 'rims/protocol'
|
36
|
+
autoload :Test, 'rims/test'
|
37
|
+
autoload :WriteLockError, 'rims/lock'
|
38
|
+
autoload :WriteLockTimeoutError, 'rims/lock'
|
37
39
|
end
|
38
40
|
|
39
41
|
# Local Variables:
|
data/lib/rims/cmd.rb
CHANGED
@@ -472,6 +472,33 @@ module RIMS
|
|
472
472
|
})
|
473
473
|
}
|
474
474
|
end
|
475
|
+
options.on('--line-length-limit=SIZE',
|
476
|
+
Integer
|
477
|
+
) do |size|
|
478
|
+
build.chain{|c|
|
479
|
+
c.load(protocol: {
|
480
|
+
line_length_limit: size
|
481
|
+
})
|
482
|
+
}
|
483
|
+
end
|
484
|
+
options.on('--literal-size-limit=SIZE',
|
485
|
+
Integer
|
486
|
+
) do |size|
|
487
|
+
build.chain{|c|
|
488
|
+
c.load(protocol: {
|
489
|
+
literal_size_limit: size
|
490
|
+
})
|
491
|
+
}
|
492
|
+
end
|
493
|
+
options.on('--command-size-limit=SIZE',
|
494
|
+
Integer
|
495
|
+
) do |size|
|
496
|
+
build.chain{|c|
|
497
|
+
c.load(protocol: {
|
498
|
+
command_size_limit: size
|
499
|
+
})
|
500
|
+
}
|
501
|
+
end
|
475
502
|
options.on('--[no-]use-default-charset-aliases'
|
476
503
|
) do |use_default_aliases|
|
477
504
|
build.chain{|c|
|
@@ -533,7 +560,7 @@ module RIMS
|
|
533
560
|
})
|
534
561
|
}
|
535
562
|
end
|
536
|
-
options.on('--drb-load-limit=
|
563
|
+
options.on('--drb-load-limit=SIZE',
|
537
564
|
Integer
|
538
565
|
) do |size|
|
539
566
|
build.chain{|c|
|
@@ -552,6 +579,16 @@ module RIMS
|
|
552
579
|
})
|
553
580
|
}
|
554
581
|
end
|
582
|
+
options.on('--bulk-response-size=SIZE',
|
583
|
+
Integer) do |size|
|
584
|
+
build.chain{|c|
|
585
|
+
c.load(drb_services: {
|
586
|
+
engine: {
|
587
|
+
bulk_response_size: size
|
588
|
+
}
|
589
|
+
})
|
590
|
+
}
|
591
|
+
end
|
555
592
|
options.on('--read-lock-timeout=SECONDS',
|
556
593
|
Float
|
557
594
|
) do |seconds|
|
data/lib/rims/protocol.rb
CHANGED
@@ -4,6 +4,27 @@ module RIMS
|
|
4
4
|
class ProtocolError < Error
|
5
5
|
end
|
6
6
|
|
7
|
+
class ReadSizeError < ProtocolError
|
8
|
+
end
|
9
|
+
|
10
|
+
class LineTooLongError < ReadSizeError
|
11
|
+
end
|
12
|
+
|
13
|
+
class RecoverableReadSizeError < ReadSizeError
|
14
|
+
def initialize(message=nil, command_tag=nil, **kw_args)
|
15
|
+
super(message, **kw_args)
|
16
|
+
@command_tag = command_tag
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_reader :command_tag
|
20
|
+
end
|
21
|
+
|
22
|
+
class LiteralSizeTooLargeError < RecoverableReadSizeError
|
23
|
+
end
|
24
|
+
|
25
|
+
class CommandSizeTooLargeError < RecoverableReadSizeError
|
26
|
+
end
|
27
|
+
|
7
28
|
class SyntaxError < ProtocolError
|
8
29
|
end
|
9
30
|
|
@@ -57,14 +78,14 @@ module RIMS
|
|
57
78
|
end
|
58
79
|
module_function :decode_base64
|
59
80
|
|
60
|
-
autoload :FetchBody,
|
61
|
-
autoload :RequestReader,
|
81
|
+
autoload :FetchBody, 'rims/protocol/parser'
|
82
|
+
autoload :RequestReader, 'rims/protocol/parser'
|
62
83
|
autoload :AuthenticationReader, 'rims/protocol/parser'
|
63
|
-
autoload :SearchParser,
|
64
|
-
autoload :FetchParser,
|
65
|
-
autoload :ConnectionLimits,
|
66
|
-
autoload :ConnectionTimer,
|
67
|
-
autoload :Decoder,
|
84
|
+
autoload :SearchParser, 'rims/protocol/parser'
|
85
|
+
autoload :FetchParser, 'rims/protocol/parser'
|
86
|
+
autoload :ConnectionLimits, 'rims/protocol/connection'
|
87
|
+
autoload :ConnectionTimer, 'rims/protocol/connection'
|
88
|
+
autoload :Decoder, 'rims/protocol/decoder'
|
68
89
|
|
69
90
|
def body(symbol: nil, option: nil, section: nil, section_list: nil, partial_origin: nil, partial_size: nil)
|
70
91
|
FetchBody.new(symbol, option, section, section_list, partial_origin, partial_size)
|
@@ -37,7 +37,6 @@ module RIMS
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def self.repl(decoder, limits, input, output, logger)
|
40
|
-
input_gets = input.method(:gets)
|
41
40
|
output_write = lambda{|data|
|
42
41
|
begin
|
43
42
|
if (data == :flush) then
|
@@ -85,90 +84,112 @@ module RIMS
|
|
85
84
|
apply_imap_command.call(:ok_greeting)
|
86
85
|
|
87
86
|
conn_timer = ConnectionTimer.new(limits, input.to_io)
|
88
|
-
request_reader =
|
87
|
+
request_reader = decoder.make_requrest_reader(input, output)
|
88
|
+
input_gets = request_reader.method(:gets)
|
89
89
|
|
90
|
-
|
91
|
-
conn_timer.
|
90
|
+
begin
|
91
|
+
until (conn_timer.command_wait_timeout?)
|
92
|
+
conn_timer.command_wait or break
|
92
93
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
94
|
+
begin
|
95
|
+
atom_list = request_reader.read_command
|
96
|
+
rescue LineTooLongError
|
97
|
+
raise
|
98
|
+
rescue LiteralSizeTooLargeError
|
99
|
+
logger.error('literal size too large error.')
|
100
|
+
logging_error_chain($!, logger)
|
101
|
+
response_write.call("#{request_reader.command_tag || '*'} BAD literal size too large\r\n")
|
102
|
+
next
|
103
|
+
rescue CommandSizeTooLargeError
|
104
|
+
logger.error('command size too large error.')
|
105
|
+
logging_error_chain($!, logger)
|
106
|
+
response_write.call("#{request_reader.command_tag || '*'} BAD command size too large\r\n")
|
107
|
+
next
|
108
|
+
rescue
|
109
|
+
logger.error('invalid client command.')
|
110
|
+
logging_error_chain($!, logger)
|
111
|
+
response_write.call("#{request_reader.command_tag || '*'} BAD client command syntax error\r\n")
|
112
|
+
next
|
113
|
+
end
|
101
114
|
|
102
|
-
|
115
|
+
break unless atom_list
|
103
116
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
log_opt_args = opt_args.dup
|
111
|
-
log_opt_args[-1] = '********'
|
112
|
-
when 'AUTHENTICATE'
|
113
|
-
if (opt_args[1]) then
|
117
|
+
tag, command, *opt_args = atom_list
|
118
|
+
normalized_command = imap_command_normalize(command)
|
119
|
+
logger.info("client command: #{tag} #{command}")
|
120
|
+
if (logger.debug?) then
|
121
|
+
case (normalized_command)
|
122
|
+
when 'LOGIN'
|
114
123
|
log_opt_args = opt_args.dup
|
115
|
-
log_opt_args[1] = '********'
|
124
|
+
log_opt_args[-1] = '********'
|
125
|
+
when 'AUTHENTICATE'
|
126
|
+
if (opt_args[1]) then
|
127
|
+
log_opt_args = opt_args.dup
|
128
|
+
log_opt_args[1] = '********'
|
129
|
+
else
|
130
|
+
log_opt_args = opt_args
|
131
|
+
end
|
116
132
|
else
|
117
133
|
log_opt_args = opt_args
|
118
134
|
end
|
119
|
-
|
120
|
-
log_opt_args = opt_args
|
135
|
+
logger.debug("client command parameter: #{log_opt_args.inspect}")
|
121
136
|
end
|
122
|
-
logger.debug("client command parameter: #{log_opt_args.inspect}")
|
123
|
-
end
|
124
137
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
138
|
+
begin
|
139
|
+
if (name = IMAP_CMDs[normalized_command]) then
|
140
|
+
case (name)
|
141
|
+
when :uid
|
142
|
+
unless (opt_args.empty?) then
|
143
|
+
uid_command, *uid_args = opt_args
|
144
|
+
logger.info("uid command: #{uid_command}")
|
145
|
+
logger.debug("uid parameter: #{uid_args}") if logger.debug?
|
146
|
+
if (uid_name = UID_CMDs[imap_command_normalize(uid_command)]) then
|
147
|
+
apply_imap_command.call(uid_name, tag, *uid_args, uid: true)
|
148
|
+
else
|
149
|
+
logger.error("unknown uid command: #{uid_command}")
|
150
|
+
response_write.call("#{tag} BAD unknown uid command\r\n")
|
151
|
+
end
|
135
152
|
else
|
136
|
-
logger.error(
|
137
|
-
response_write.call("#{tag} BAD
|
153
|
+
logger.error('empty uid parameter.')
|
154
|
+
response_write.call("#{tag} BAD empty uid parameter\r\n")
|
138
155
|
end
|
156
|
+
when :authenticate
|
157
|
+
apply_imap_command.call(:authenticate, tag, input_gets, server_output_write, *opt_args)
|
158
|
+
when :idle
|
159
|
+
apply_imap_command.call(:idle, tag, input_gets, server_output_write, conn_timer, *opt_args)
|
139
160
|
else
|
140
|
-
|
141
|
-
response_write.call("#{tag} BAD empty uid parameter\r\n")
|
161
|
+
apply_imap_command.call(name, tag, *opt_args)
|
142
162
|
end
|
143
|
-
when :authenticate
|
144
|
-
apply_imap_command.call(:authenticate, tag, input_gets, server_output_write, *opt_args)
|
145
|
-
when :idle
|
146
|
-
apply_imap_command.call(:idle, tag, input_gets, server_output_write, conn_timer, *opt_args)
|
147
163
|
else
|
148
|
-
|
164
|
+
logger.error("unknown command: #{command}")
|
165
|
+
response_write.call("#{tag} BAD unknown command\r\n")
|
149
166
|
end
|
150
|
-
|
151
|
-
|
152
|
-
|
167
|
+
rescue LineTooLongError
|
168
|
+
raise
|
169
|
+
rescue
|
170
|
+
logger.error('unexpected error.')
|
171
|
+
logging_error_chain($!, logger)
|
172
|
+
response_write.call("#{tag} BAD unexpected error\r\n")
|
153
173
|
end
|
154
|
-
rescue
|
155
|
-
logger.error('unexpected error.')
|
156
|
-
logging_error_chain($!, logger)
|
157
|
-
response_write.call("#{tag} BAD unexpected error\r\n")
|
158
|
-
end
|
159
|
-
|
160
|
-
if (normalized_command == 'LOGOUT') then
|
161
|
-
break
|
162
|
-
end
|
163
174
|
|
164
|
-
|
165
|
-
|
175
|
+
if (normalized_command == 'LOGOUT') then
|
176
|
+
break
|
177
|
+
end
|
166
178
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
179
|
+
decoder = decoder.next_decoder
|
180
|
+
end
|
181
|
+
rescue LineTooLongError
|
182
|
+
logger.error('line too long error.')
|
183
|
+
logging_error_chain($!, logger)
|
184
|
+
response_write.call("* BAD line too long\r\n")
|
185
|
+
response_write.call("* BYE server autologout: connection terminated\r\n")
|
186
|
+
else
|
187
|
+
if (conn_timer.command_wait_timeout?) then
|
188
|
+
if (limits.command_wait_timeout_seconds > 0) then
|
189
|
+
response_write.call("* BYE server autologout: idle for too long\r\n")
|
190
|
+
else
|
191
|
+
response_write.call("* BYE server autologout: shutdown\r\n")
|
192
|
+
end
|
172
193
|
end
|
173
194
|
end
|
174
195
|
|
@@ -198,6 +219,8 @@ module RIMS
|
|
198
219
|
else
|
199
220
|
__send__(imap_command, tag, *args, **kw_args, &block)
|
200
221
|
end
|
222
|
+
rescue LineTooLongError
|
223
|
+
raise
|
201
224
|
rescue SyntaxError
|
202
225
|
@logger.error('client command syntax error.')
|
203
226
|
logging_error_chain($!)
|
@@ -334,13 +357,26 @@ module RIMS
|
|
334
357
|
end
|
335
358
|
|
336
359
|
def initialize(drb_services, auth, logger,
|
337
|
-
mail_delivery_user: Service::DEFAULT_CONFIG.mail_delivery_user
|
360
|
+
mail_delivery_user: Service::DEFAULT_CONFIG.mail_delivery_user,
|
361
|
+
line_length_limit: Service::DEFAULT_CONFIG.protocol_line_length_limit,
|
362
|
+
literal_size_limit: Service::DEFAULT_CONFIG.protocol_literal_size_limit,
|
363
|
+
command_size_limit: Service::DEFAULT_CONFIG.protocol_command_size_limit)
|
338
364
|
super(auth, logger)
|
339
365
|
@drb_services = drb_services
|
340
366
|
@mail_delivery_user = mail_delivery_user
|
367
|
+
@line_length_limit = line_length_limit
|
368
|
+
@literal_size_limit = literal_size_limit
|
369
|
+
@command_size_limit = command_size_limit
|
341
370
|
@logger.debug("RIMS::Protocol::InitialDecoder#initialize at #{self}") if @logger.debug?
|
342
371
|
end
|
343
372
|
|
373
|
+
def make_requrest_reader(input, output)
|
374
|
+
RequestReader.new(input, output, @logger,
|
375
|
+
line_length_limit: @line_length_limit,
|
376
|
+
literal_size_limit: @literal_size_limit,
|
377
|
+
command_size_limit: @command_size_limit)
|
378
|
+
end
|
379
|
+
|
344
380
|
def auth?
|
345
381
|
false
|
346
382
|
end
|
@@ -868,22 +904,40 @@ module RIMS
|
|
868
904
|
|
869
905
|
class << self
|
870
906
|
def imap_command_authenticated(name, **guard_optional)
|
907
|
+
name = name.to_sym
|
871
908
|
orig_name = "_#{name}".to_sym
|
872
909
|
alias_method orig_name, name
|
873
|
-
|
874
|
-
|
875
|
-
}
|
876
|
-
|
910
|
+
|
911
|
+
guard_options_name = "_#{name}_guard_options".to_sym
|
912
|
+
define_method guard_options_name, lambda{ guard_optional }
|
913
|
+
private guard_options_name
|
914
|
+
|
915
|
+
class_eval(<<-EOF, __FILE__, __LINE__ + 1)
|
916
|
+
def #{name}(token, tag, *args, **kw_args, &block)
|
917
|
+
guard_authenticated(:#{orig_name}, token, tag, *args, **kw_args, **#{guard_options_name}, &block)
|
918
|
+
end
|
919
|
+
EOF
|
920
|
+
|
921
|
+
name
|
877
922
|
end
|
878
923
|
private :imap_command_authenticated
|
879
924
|
|
880
925
|
def imap_command_selected(name, **guard_optional)
|
926
|
+
name = name.to_sym
|
881
927
|
orig_name = "_#{name}".to_sym
|
882
928
|
alias_method orig_name, name
|
883
|
-
|
884
|
-
|
885
|
-
}
|
886
|
-
|
929
|
+
|
930
|
+
guard_options_name = "_#{name}_guard_options".to_sym
|
931
|
+
define_method guard_options_name, lambda{ guard_optional }
|
932
|
+
private guard_options_name
|
933
|
+
|
934
|
+
class_eval(<<-EOF, __FILE__, __LINE__ + 1)
|
935
|
+
def #{name}(token, tag, *args, **kw_args, &block)
|
936
|
+
guard_selected(:#{orig_name}, token, tag, *args, **kw_args, **#{guard_options_name}, &block)
|
937
|
+
end
|
938
|
+
EOF
|
939
|
+
|
940
|
+
name
|
887
941
|
end
|
888
942
|
private :imap_command_selected
|
889
943
|
end
|
@@ -1884,7 +1938,7 @@ module RIMS
|
|
1884
1938
|
end
|
1885
1939
|
imap_command :check
|
1886
1940
|
|
1887
|
-
def close(tag
|
1941
|
+
def close(tag)
|
1888
1942
|
ret_val = nil
|
1889
1943
|
old_token = @token
|
1890
1944
|
@token = nil
|
@@ -1946,7 +2000,7 @@ module RIMS
|
|
1946
2000
|
end
|
1947
2001
|
imap_command :store
|
1948
2002
|
|
1949
|
-
def copy(tag, msg_set, mbox_name, uid: false
|
2003
|
+
def copy(tag, msg_set, mbox_name, uid: false)
|
1950
2004
|
ret_val = nil
|
1951
2005
|
@engine.copy(@token, tag, msg_set, mbox_name, uid: uid) {|res|
|
1952
2006
|
for response in res
|
@@ -1958,7 +2012,7 @@ module RIMS
|
|
1958
2012
|
end
|
1959
2013
|
imap_command :copy
|
1960
2014
|
|
1961
|
-
def idle(tag, client_input_gets, server_output_write, connection_timer
|
2015
|
+
def idle(tag, client_input_gets, server_output_write, connection_timer)
|
1962
2016
|
ret_val = nil
|
1963
2017
|
@engine.idle(@token, tag, client_input_gets, server_output_write, connection_timer) {|res|
|
1964
2018
|
for response in res
|