vcs 0.1 → 0.2.148

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 (132) hide show
  1. data/Rakefile +17 -3
  2. data/bin/vcs +57 -34
  3. data/doc/jamis.rb +564 -0
  4. data/ruby_ex/abstract.rb +254 -0
  5. data/ruby_ex/abstract_node.rb +85 -0
  6. data/ruby_ex/algorithms/simulated_annealing.rb +140 -0
  7. data/ruby_ex/array_each_pair.rb +18 -0
  8. data/ruby_ex/ask.rb +101 -0
  9. data/ruby_ex/attributed_class.rb +302 -0
  10. data/ruby_ex/cache.rb +373 -0
  11. data/ruby_ex/checkout.rb +12 -0
  12. data/ruby_ex/choose.rb +271 -0
  13. data/ruby_ex/commands.rb +18 -0
  14. data/ruby_ex/commands/command.rb +401 -0
  15. data/ruby_ex/commands/datas.rb +16 -0
  16. data/ruby_ex/commands/datas/data.rb +33 -0
  17. data/ruby_ex/commands/datas/factory.rb +66 -0
  18. data/ruby_ex/commands/factory.rb +66 -0
  19. data/ruby_ex/commands/helpers.rb +67 -0
  20. data/ruby_ex/commands/pipe.rb +64 -0
  21. data/ruby_ex/commands/runners.rb +17 -0
  22. data/ruby_ex/commands/runners/exec.rb +49 -0
  23. data/ruby_ex/commands/runners/fork.rb +97 -0
  24. data/ruby_ex/commands/runners/runner.rb +107 -0
  25. data/ruby_ex/commands/seq.rb +27 -0
  26. data/ruby_ex/config_file.rb +96 -0
  27. data/ruby_ex/const_regexp.rb +59 -0
  28. data/ruby_ex/daemon.rb +134 -0
  29. data/ruby_ex/diff.rb +667 -0
  30. data/ruby_ex/dlogger.rb +62 -0
  31. data/ruby_ex/drb/dispatcher.rb +252 -0
  32. data/ruby_ex/drb/dispatcher_server_test.rb +29 -0
  33. data/ruby_ex/drb/drb_observable.rb +97 -0
  34. data/ruby_ex/drb/drb_observable_pool.rb +27 -0
  35. data/ruby_ex/drb/drb_service.rb +43 -0
  36. data/ruby_ex/drb/drb_undumped_attributes.rb +55 -0
  37. data/ruby_ex/drb/drb_undumped_indexed_object.rb +54 -0
  38. data/ruby_ex/drb/insecure_protected_methods.rb +103 -0
  39. data/ruby_ex/drb/session_client_test.rb +40 -0
  40. data/ruby_ex/drb/session_manager.rb +246 -0
  41. data/ruby_ex/drb/session_server.rb +53 -0
  42. data/ruby_ex/dtime.rb +143 -0
  43. data/ruby_ex/dumpable_proc.rb +63 -0
  44. data/ruby_ex/exception.rb +32 -0
  45. data/ruby_ex/filetype.rb +229 -0
  46. data/ruby_ex/fileutils_ex.rb +44 -0
  47. data/ruby_ex/fold.rb +58 -0
  48. data/ruby_ex/generate_id.rb +44 -0
  49. data/ruby_ex/hookable.rb +262 -0
  50. data/ruby_ex/hooker.rb +54 -0
  51. data/ruby_ex/inactive_timeout.rb +137 -0
  52. data/ruby_ex/indexed_node.rb +66 -0
  53. data/ruby_ex/io_marshal.rb +100 -0
  54. data/ruby_ex/ioo.rb +194 -0
  55. data/ruby_ex/labeled_node.rb +63 -0
  56. data/ruby_ex/logger_observer.rb +23 -0
  57. data/ruby_ex/md5sum.rb +66 -0
  58. data/ruby_ex/mktemp.rb +208 -0
  59. data/ruby_ex/module/attr_once.rb +36 -0
  60. data/ruby_ex/module/autoload_tree.rb +75 -0
  61. data/ruby_ex/module/hierarchy.rb +335 -0
  62. data/ruby_ex/module/instance_method_visibility.rb +73 -0
  63. data/ruby_ex/module_ex.rb +11 -0
  64. data/ruby_ex/node.rb +80 -0
  65. data/ruby_ex/object_monitor.rb +145 -0
  66. data/ruby_ex/object_monitor_activity.rb +33 -0
  67. data/ruby_ex/observable.rb +140 -0
  68. data/ruby_ex/observable_pool.rb +293 -0
  69. data/ruby_ex/orderedhash.rb +252 -0
  70. data/ruby_ex/pathname_ex.rb +152 -0
  71. data/ruby_ex/pp_hierarchy.rb +29 -0
  72. data/ruby_ex/pseudo_cache.rb +190 -0
  73. data/ruby_ex/queue.rb +56 -0
  74. data/ruby_ex/random_generators.rb +25 -0
  75. data/ruby_ex/random_generators/random_generator.rb +31 -0
  76. data/ruby_ex/random_generators/ruby.rb +23 -0
  77. data/ruby_ex/safe_eval.rb +348 -0
  78. data/ruby_ex/sendmail.rb +215 -0
  79. data/ruby_ex/service_manager.rb +121 -0
  80. data/ruby_ex/session/administrable.rb +120 -0
  81. data/ruby_ex/session/client.rb +153 -0
  82. data/ruby_ex/session/const.rb +18 -0
  83. data/ruby_ex/session/dispatcher.rb +184 -0
  84. data/ruby_ex/session/error.rb +21 -0
  85. data/ruby_ex/session/fetchable.rb +57 -0
  86. data/ruby_ex/session/fetcher.rb +62 -0
  87. data/ruby_ex/session/hookable.rb +26 -0
  88. data/ruby_ex/session/profile.rb +110 -0
  89. data/ruby_ex/session/server.rb +582 -0
  90. data/ruby_ex/session/test/administrable_test.rb +337 -0
  91. data/ruby_ex/session/test/basic_test.rb +523 -0
  92. data/ruby_ex/session/test/dispatcher_test.rb +409 -0
  93. data/ruby_ex/session/test/fetchable_test.rb +119 -0
  94. data/ruby_ex/session/test/sub_server_test.rb +188 -0
  95. data/ruby_ex/shuffle.rb +30 -0
  96. data/ruby_ex/spring.rb +136 -0
  97. data/ruby_ex/spring_set.rb +137 -0
  98. data/ruby_ex/string_ex.rb +28 -0
  99. data/ruby_ex/symtbl.rb +106 -0
  100. data/ruby_ex/synflow.rb +474 -0
  101. data/ruby_ex/test/unit/ui/yaml/testrunner.rb +164 -0
  102. data/ruby_ex/thread_mutex.rb +10 -0
  103. data/ruby_ex/timeout_ex.rb +81 -0
  104. data/ruby_ex/top_down.rb +73 -0
  105. data/ruby_ex/trace.rb +26 -0
  106. data/ruby_ex/uri/druby.rb +81 -0
  107. data/ruby_ex/uri/file.rb +65 -0
  108. data/ruby_ex/uri/ftp_ex.rb +37 -0
  109. data/ruby_ex/uri/http_ex.rb +43 -0
  110. data/ruby_ex/uri/ssh.rb +92 -0
  111. data/ruby_ex/uri/svn.rb +118 -0
  112. data/ruby_ex/uri_ex.rb +45 -0
  113. data/ruby_ex/verbose_object.rb +30 -0
  114. data/ruby_ex/version.rb +66 -0
  115. data/ruby_ex/yaml/basenode_ext.rb +63 -0
  116. data/ruby_ex/yaml/chop_header.rb +23 -0
  117. data/ruby_ex/yaml/transform.rb +449 -0
  118. data/ruby_ex/yaml/yregexpath.rb +76 -0
  119. data/src/changelog.rb +28 -18
  120. data/src/conflict.rb +20 -0
  121. data/src/diff.rb +18 -0
  122. data/src/diffstat.rb +9 -3
  123. data/src/last_changed_date.rb +18 -0
  124. data/src/mail.rb +33 -65
  125. data/src/message.rb +15 -9
  126. data/src/mycommit.rb +29 -14
  127. data/src/news.rb +24 -3
  128. data/src/status.rb +17 -0
  129. data/src/svn.rb +2 -2
  130. data/src/vcs.rb +24 -3
  131. metadata +124 -5
  132. data/lrdetools.rb +0 -12
@@ -0,0 +1,26 @@
1
+ # Copyright: Copyright (c) 2004 Nicolas Despres. All rights reserved.
2
+ # Author: Nicolas Despres <polrop@lrde.epita.fr>.
3
+ # License: Gnu General Public License.
4
+
5
+ # $LastChangedBy: ertai $
6
+ # $Id: hookable.rb 53 2004-12-02 22:24:03Z ertai $
7
+
8
+
9
+ require 'drb'
10
+
11
+
12
+ module Session
13
+
14
+ module Hookable
15
+ include DRb::DRbUndumped
16
+
17
+ def hook(sid, profile, request, *args)
18
+ meth = "hook_#{request}"
19
+ if protected_methods.include?(meth)
20
+ send(meth.to_sym, sid, profile, *args)
21
+ end
22
+ end
23
+
24
+ end # module Hook
25
+
26
+ end # module Session
@@ -0,0 +1,110 @@
1
+ # Copyright: Copyright (c) 2004 Nicolas Despres. All rights reserved.
2
+ # Author: Nicolas Despres <polrop@lrde.epita.fr>.
3
+ # License: Gnu General Public License.
4
+
5
+ # $LastChangedBy: polrop $
6
+ # $Id: profile.rb 70 2004-12-07 17:44:50Z polrop $
7
+
8
+
9
+ require 'drb'
10
+
11
+ require 'const_regexp'
12
+
13
+
14
+ module Session
15
+
16
+ class Profile
17
+
18
+ attr_reader :data
19
+
20
+ def initialize(usrname, usrdesc, uri, dispatcher, *hooks)
21
+ @data = usrdesc.dup
22
+ @data[:usrname] = usrname
23
+ @data[:login_time] = Time.now
24
+ @data[:last_request_time] = Time.now
25
+ @data[:uri] = uri
26
+ uri_chunks = Profile.parse_uri(uri)
27
+ @data[:protocol], @data[:hostname], @data[:port] = *uri_chunks
28
+ @data[:hooks] = hooks
29
+ @data[:nb_requests] = 0
30
+ @data[:dispatcher] = dispatcher
31
+ end
32
+
33
+ def Profile.parse_uri(uri)
34
+ return $1, $2, $3.to_i if uri =~ ConstRegexp::DRB_URI
35
+ end
36
+
37
+ def _dump(depth)
38
+ data = {}
39
+ @data.each do |key, val|
40
+ begin
41
+ data[key] = Marshal.dump(val)
42
+ rescue TypeError
43
+ data[key] = Marshal.dump(DRbObject.new(val))
44
+ end
45
+ end
46
+ Marshal.dump([self.class, data])
47
+ end
48
+
49
+ def self._load(data)
50
+ klass, data = Marshal.load(data)
51
+ obj = klass.new(data[:usrname],
52
+ {},
53
+ data[:uri],
54
+ nil,
55
+ nil)
56
+ data.each do |attr, value|
57
+ obj[attr] = Marshal.load(value)
58
+ end
59
+ obj
60
+ end
61
+
62
+ def [](key)
63
+ @data[key]
64
+ end
65
+
66
+ def []=(key, value)
67
+ @data[key] = value
68
+ end
69
+
70
+ def to_hash
71
+ @data.dup
72
+ end
73
+
74
+ def each
75
+ @data.each { |k, v| yield(k, v) }
76
+ end
77
+
78
+ def allowed_request?(request)
79
+ return true if @data[:admin]
80
+ @data[:allowed_requests].include?(request)
81
+ end
82
+
83
+ def add_request(request)
84
+ unless @data[:allowed_requests].include?(request)
85
+ @data[:allowed_requests] << request
86
+ end
87
+ end
88
+
89
+ def allowed_hook?(hook)
90
+ return true if @data[:admin]
91
+ @data[:allowed_hooks].include?(hook)
92
+ end
93
+
94
+ def add_client(uri, client_class, *args)
95
+ @data[:dispatcher].add(uri,
96
+ @data[:usrname],
97
+ @data[:passwd],
98
+ client_class,
99
+ *args)
100
+ end
101
+
102
+ def del_client(uri)
103
+ @data[:dispatcher].del(uri)
104
+ end
105
+
106
+ end # class Profile
107
+
108
+ end # class Session
109
+
110
+
@@ -0,0 +1,582 @@
1
+ # Copyright: Copyright (c) 2004 Nicolas Despres. All rights reserved.
2
+ # Author: Nicolas Despres <polrop@lrde.epita.fr>.
3
+ # License: Gnu General Public License.
4
+
5
+ # $LastChangedBy: ertai $
6
+ # $Id: server.rb 186 2005-04-03 00:07:45Z ertai $
7
+
8
+
9
+ require 'drb'
10
+
11
+ require 'generate_id'
12
+ require 'const_regexp'
13
+ require 'drb/insecure_protected_methods'
14
+ require 'session/profile'
15
+ require 'session/dispatcher'
16
+ require 'session/const'
17
+ require 'session/error'
18
+ require 'exception'
19
+
20
+
21
+ module Session
22
+
23
+ class Server
24
+ include DRb::DRbUndumped
25
+
26
+ #
27
+ # Constants
28
+ #
29
+ MIN_USR = 1
30
+ MIN_WIPEOUT_DELAY = 2 # seconds
31
+ USRDB = {
32
+ 'root' => {
33
+ :passwd => 'root'.crypt(Const::SALT_KEY),
34
+ :admin => true,
35
+ :allowed_requests => [],
36
+ :allowed_hooks => []
37
+ },
38
+ 'admin' => {
39
+ :passwd => 'admin'.crypt(Const::SALT_KEY),
40
+ :admin => true,
41
+ :allowed_requests => [],
42
+ :allowed_hooks => []
43
+ },
44
+ 'guest' => {
45
+ :passwd => 'guest'.crypt(Const::SALT_KEY),
46
+ :admin => false,
47
+ :allowed_requests => [
48
+ :profile, :help, :nb_requests, :ping
49
+ ],
50
+ :allowed_hooks => []
51
+ },
52
+ 'anonymous' => {
53
+ :passwd => 'anonymous'.crypt(Const::SALT_KEY),
54
+ :admin => false,
55
+ :allowed_requests => [
56
+ :profile, :help, :nb_requests, :ping
57
+ ],
58
+ :allowed_hooks => []
59
+ }
60
+ }
61
+ MAX_USR = 10
62
+ WIPEOUT_DELAY = 60 # seconds
63
+ PROFILE_CLASS = Profile
64
+ MAX_DISPATCHER_JOBS = 1
65
+ OPTS = {
66
+ :usrdb => USRDB,
67
+ :max_usr => MAX_USR,
68
+ :wipeout_delay => WIPEOUT_DELAY,
69
+ :profile_class => PROFILE_CLASS,
70
+ :max_dispatcher_jobs => MAX_DISPATCHER_JOBS
71
+ }
72
+ REQUEST_REGEXP = /^request_/
73
+ REQUESTS_DESC = { #FIXME: write description for all the request
74
+ 'logout' => 'disconnect from the server',
75
+ 'help' => '[requests...] return all or several request descriptions',
76
+ 'profile' => 'return the session profile'
77
+ }
78
+ USRNAME_REGEXP = /^[A-Za-z0-9_]+$/
79
+ PASSWD_REGEXP = ConstRegexp::CRYPTED_STRING
80
+ SID_REGEXP = /^[a-f0-9]{16}$/
81
+
82
+ #
83
+ # Constructor
84
+ #
85
+ def initialize(opts=OPTS)
86
+ @nb_requests = 0
87
+ @opts = opts
88
+ @mutex = Mutex.new
89
+ @usrdb = check_usrdb(opts[:usrdb])
90
+ @max_usr = check_max_usr(opts[:max_usr])
91
+ @wipeout_delay = check_wipeout_delay(opts[:wipeout_delay])
92
+ @profile_class = opts[:profile_class]
93
+ @max_dispatcher_jobs = opts[:max_dispatcher_jobs]
94
+ @sessions = {}
95
+ @thread = Thread.new do
96
+ loop do
97
+ sleep_time = MIN_WIPEOUT_DELAY
98
+ @mutex.synchronize { sleep_time = @wipeout_delay }
99
+ sleep(sleep_time)
100
+ wipeout
101
+ end
102
+ end
103
+ @detached = false
104
+ end
105
+
106
+ #
107
+ # Requests
108
+ #
109
+ def login(usrname, passwd, uri, *hooks)
110
+ sid = nil
111
+ profile = nil
112
+ @mutex.synchronize do
113
+ check_usrname(usrname)
114
+ check_passwd(passwd)
115
+ usr = authentification(usrname, passwd)
116
+ if usr.nil?
117
+ raise(AuthError, "#{usrname}:#{passwd} authentification failed")
118
+ end
119
+ hooks.each { |hook| check_hook(hook) }
120
+ usr_name, usr_desc = usr
121
+ dispatcher = Dispatcher.new({}, @max_dispatcher_jobs, Client)
122
+ profile = @profile_class.new(usr_name,
123
+ usr_desc,
124
+ uri,
125
+ dispatcher,
126
+ *hooks)
127
+ if @sessions.size >= @max_usr and (not profile[:admin])
128
+ raise(FullError, "server full")
129
+ end
130
+ sid = generate_id { |id| @sessions.has_key?(id) }
131
+ @sessions[sid] = profile
132
+ end
133
+ call_all_hooks(sid, profile, :login)
134
+ sid
135
+ end
136
+
137
+ def request(sid, request, *args, &block)
138
+ check_sid(sid)
139
+ profile = nil
140
+ req_name = nil
141
+ @mutex.synchronize do
142
+ profile = get_profile(sid)
143
+ req_name = check_request(request)
144
+ check_request_permission(profile, request)
145
+ @nb_requests += 1
146
+ profile[:nb_requests] += 1
147
+ end
148
+ ret = send(req_name.to_sym, sid, profile, *args, &block)
149
+ call_allowed_hooks(sid, profile, request, *args)
150
+ @mutex.synchronize do
151
+ profile[:last_request_time] = Time.now
152
+ @nb_requests -= 1
153
+ profile[:nb_requests] -= 1
154
+ end
155
+ ret
156
+ end
157
+
158
+ #
159
+ # Session-oriented requests
160
+ #
161
+ protected
162
+ def request_logout(sid, profile)
163
+ @mutex.synchronize { logout(sid, profile) }
164
+ end
165
+
166
+ protected
167
+ def request_ping(sid, profile, data)
168
+ data
169
+ end
170
+
171
+ protected
172
+ def request_help(sid, profile, *args)
173
+ res = {}
174
+ args_str = []
175
+ args.each { |arg| args_str << arg.to_s }
176
+ protected_methods.each do |meth|
177
+ meth_str = meth.to_s
178
+ next unless meth_str =~ REQUEST_REGEXP
179
+ m = meth_str.sub(REQUEST_REGEXP, '')
180
+ next if (not args_str.empty?) and (not args_str.include?(m))
181
+ if REQUESTS_DESC.has_key?(m)
182
+ res[m] = REQUESTS_DESC[m]
183
+ else
184
+ res[m] = 'no description available'
185
+ end
186
+ end
187
+ res
188
+ end
189
+
190
+ protected
191
+ def request_profile(sid, profile)
192
+ @mutex.synchronize { profile }
193
+ end
194
+
195
+ protected
196
+ def request_get_usr_profile(sid, profile, usrname)
197
+ @mutex.synchronize do
198
+ @sessions.values.each { |prof| return prof if usrname == prof[:usrname] }
199
+ end
200
+ raise(UserError, "`#{usrname}' - not logged user")
201
+ end
202
+
203
+ protected
204
+ def request_nb_requests(sid, profile)
205
+ @mutex.synchronize { profile[:nb_requests] }
206
+ end
207
+
208
+ protected
209
+ def request_total_nb_requests(sid, profile)
210
+ @mutex.synchronize { @nb_requests }
211
+ end
212
+
213
+ protected
214
+ def request_add_hook(sid, profile, *hooks)
215
+ @mutex.synchronize do
216
+ hooks.each do |hook|
217
+ check_hook(hook)
218
+ profile[:hooks] << hook
219
+ end
220
+ end
221
+ nil
222
+ end
223
+
224
+ protected
225
+ def request_del_hook(sid, profile, hook)
226
+ @mutex.synchronize { profile[:hooks].delete(hook) }
227
+ end
228
+
229
+ protected
230
+ def request_rsend(sid, profile, obj, meth, *args)
231
+ obj.send(meth, *args)
232
+ end
233
+
234
+ protected
235
+ def request_detach(sid, profile)
236
+ return if @detached
237
+ @detached = true
238
+ if pid = fork # father
239
+ exit
240
+ else # son
241
+ Dir.chdir('/')
242
+ Process.setsid
243
+ STDIN.close
244
+ STDOUT.close
245
+ STDERR.close
246
+ end
247
+ end
248
+
249
+ protected
250
+ def request_chdir(sid, profile, dir)
251
+ Dir.chdir(dir)
252
+ end
253
+
254
+ protected
255
+ def request_login_at(sid, profile, uri, *args)
256
+ @mutex.synchronize { profile.add_client(uri, Client, *args) }
257
+ end
258
+
259
+ protected
260
+ def request_request_at(sid, profile, uri, request, *args)
261
+ @mutex.synchronize { client_request(profile, uri, request, *args) }
262
+ end
263
+
264
+ protected
265
+ def request_logout_at(sid, profile, uri)
266
+ @mutex.synchronize { client_request(profile, uri, :logout, *args) }
267
+ end
268
+
269
+ protected
270
+ def request_start_sub_server(sid,
271
+ profile,
272
+ uri,
273
+ server_class=Server,
274
+ *args,
275
+ &block)
276
+ rd, wr = IO.pipe
277
+ if pid = fork # father
278
+ wr.close
279
+ # Process.detach(pid)
280
+ res_key, res_value = Marshal.load(rd)
281
+ rd.close
282
+ case res_key
283
+ when :uri
284
+ request(sid, :login_at, res_value, true)
285
+ return res_value
286
+ when :exc
287
+ Process.waitpid(-1)
288
+ raise(res_value)
289
+ else
290
+ raise(NameError, "`#{res_key}' - bad result key")
291
+ end
292
+ else # son
293
+ rd.close
294
+ begin
295
+ DRb.stop_service
296
+ srv = DRb.start_service(uri, server_class.new(*args))
297
+ block[srv] if block_given?
298
+ Marshal.dump([ :uri, srv.uri ], wr)
299
+ wr.close
300
+ srv.thread.join
301
+ rescue Exception => exc
302
+ data = exc
303
+ begin
304
+ Marshal.dump(exc)
305
+ rescue TypeError
306
+ data = exc.long_pp
307
+ end
308
+ Marshal.dump([ :exc, data ], wr)
309
+ wr.close
310
+ exit(1)
311
+ end
312
+ exit(0)
313
+ end
314
+ end
315
+
316
+ protected
317
+ def request_stop_sub_server(sid, profile, uri)
318
+ @mutex.synchronize { stop_sub_server(profile, uri) }
319
+ end
320
+
321
+ protected
322
+ def request_stop_all_sub_server(sid, profile)
323
+ @mutex.synchronize { stop_all_sub_server(profile) }
324
+ end
325
+
326
+ protected
327
+ def request_stop(sid, profile)
328
+ @sessions.dup.each { |id, prof| logout(id, prof) }
329
+ DRb.stop_service
330
+ end
331
+
332
+ protected
333
+ def request_pid(sid, profile)
334
+ Process.pid
335
+ end
336
+
337
+ #
338
+ # Methods
339
+ #
340
+ protected
341
+ def logout(sid, profile)
342
+ call_all_hooks(sid, profile, :logout)
343
+ stop_all_sub_server(profile)
344
+ @sessions.delete(sid)
345
+ end
346
+
347
+ protected
348
+ def get_profile(sid)
349
+ if @sessions[sid].nil?
350
+ raise(SessionError, "`#{sid}' - not an opened session")
351
+ end
352
+ @sessions[sid]
353
+ end
354
+
355
+ protected
356
+ def authentification(username, passwd)
357
+ @usrdb.each do |usr_name, usr_desc|
358
+ if usr_name == username and usr_desc[:passwd] == passwd
359
+ return usr_name, usr_desc
360
+ end
361
+ end
362
+ return nil
363
+ end
364
+
365
+ protected
366
+ def wipeout
367
+ dead = {}
368
+ @mutex.synchronize do
369
+ now = Time.now
370
+ @sessions.each do |sid, profile|
371
+ if (now - profile[:last_request_time]) > @wipeout_delay
372
+ dead[sid] = profile
373
+ end
374
+ end
375
+ end
376
+ dead.each { |sid, profile| request(sid, :logout) }
377
+ return dead
378
+ end
379
+
380
+ protected
381
+ def call_all_hooks(sid, profile, meth, *args)
382
+ hooks = []
383
+ unless @mutex.locked?
384
+ @mutex.synchronize do
385
+ @sessions.each { |id, prof| hooks += prof[:hooks] }
386
+ end
387
+ else
388
+ @sessions.each { |id, prof| hooks += prof[:hooks] }
389
+ end
390
+ hooks.each do |hook|
391
+ handle_dead_hook(hook, sid, profile, meth, *args)
392
+ end
393
+ end
394
+
395
+ protected
396
+ def call_allowed_hooks(sid, profile, request, *args)
397
+ hooks = []
398
+ @mutex.synchronize do
399
+ @sessions.each do |id, prof|
400
+ hooks += prof[:hooks] if prof.allowed_hook?(request)
401
+ end
402
+ end
403
+ hooks.each do |hook|
404
+ handle_dead_hook(hook, sid, profile, request, *args)
405
+ end
406
+ end
407
+
408
+ # overload me to handle every hook call
409
+ protected
410
+ def handle_dead_hook(hook, sid, profile, meth, *args)
411
+ nb_retry = 0
412
+ begin
413
+ call_hook(hook, sid.dup, profile.dup, meth, *args)
414
+ rescue DRb::DRbConnError
415
+ nb_retry += 1
416
+ retry if nb_retry <= 1
417
+ end
418
+ end
419
+
420
+ # overload me to handle every hook call
421
+ protected
422
+ def call_hook(hook, sid, profile, meth, *args)
423
+ hook.hook(sid, profile, meth, *args)
424
+ end
425
+
426
+ protected
427
+ def get_client_at(profile, uri)
428
+ clt = profile[:dispatcher].select_by(:uri, uri)
429
+ unless clt.nil? or clt.size == 1
430
+ raise(SessionError, "`#{uri}' - cannot opened a session at this uri")
431
+ end
432
+ clt.first
433
+ end
434
+
435
+ protected
436
+ def client_request(profile, uri, request, *args)
437
+ clt = get_client_at(profile, uri)
438
+ clt.send(request, *args)
439
+ end
440
+
441
+ protected
442
+ def stop_sub_server(profile, uri)
443
+ (client_request(profile, uri, :stop)) rescue DRb::DRbConnError
444
+ profile.del_client(uri)
445
+ Process.waitpid(-1)
446
+ $?
447
+ end
448
+
449
+ protected
450
+ def stop_all_sub_server(profile)
451
+ profile[:dispatcher].each do |uri, desc|
452
+ stop_sub_server(profile, uri)
453
+ end
454
+ end
455
+
456
+ protected
457
+ def check_sid(sid)
458
+ unless sid.is_a?(String) and sid =~ SID_REGEXP
459
+ raise(ParameterError, "`#{sid.inspect}' - bad session id format")
460
+ end
461
+ sid
462
+ end
463
+
464
+ protected
465
+ def check_usrdb(usrdb)
466
+ usrdb.each do |name, desc|
467
+ check_usrname(name)
468
+ check_usrdesc(desc)
469
+ end
470
+ usrdb
471
+ end
472
+
473
+ protected
474
+ def check_usrdesc(desc)
475
+ unless desc.is_a?(Hash) and desc.size >= 2
476
+ raise(ParameterError, "`#{desc.inspect}' - bad user description")
477
+ end
478
+ check_passwd(desc[:passwd])
479
+ check_admin(desc[:admin])
480
+ unless desc[:allowed_requests].nil?
481
+ check_allowed_requests(desc[:allowed_requests])
482
+ else
483
+ desc[:allowed_requests] = []
484
+ end
485
+ unless desc[:allowed_hooks].nil?
486
+ check_allowed_hooks(desc[:allowed_hooks])
487
+ else
488
+ desc[:allowed_hooks] = []
489
+ end
490
+ end
491
+
492
+ protected
493
+ def check_max_usr(max_usr)
494
+ unless max_usr.is_a?(Fixnum) and max_usr >= MIN_USR
495
+ raise(ParameterError, "`#{max_usr.inspect}' - bad max users number")
496
+ end
497
+ max_usr
498
+ end
499
+
500
+ protected
501
+ def check_wipeout_delay(wipeout_delay)
502
+ unless wipeout_delay.is_a?(Fixnum) and wipeout_delay >= MIN_WIPEOUT_DELAY
503
+ raise(ParameterError, "`#{wipeout_delay.inspect}' - bad wipeout delay")
504
+ end
505
+ @wipeout_delay = wipeout_delay
506
+ end
507
+
508
+ protected
509
+ def check_request(request)
510
+ unless request.is_a?(Symbol) and request.to_s =~ ConstRegexp::RB_METHOD
511
+ raise(ParameterError, "`#{request.inspect}' - bad request format")
512
+ end
513
+ req_name = 'request_' + request.to_s
514
+ unless self.respond_to?(req_name)
515
+ raise(RequestError, "`#{request.to_s}' - not a request")
516
+ end
517
+ req_name
518
+ end
519
+
520
+ protected
521
+ def check_request_permission(profile, request)
522
+ if (request != :logout) and (not profile.allowed_request?(request))
523
+ raise(PermissionError, "`#{request.to_s}' - request not allowed")
524
+ end
525
+ request
526
+ end
527
+
528
+ protected
529
+ def check_usrname(usrname)
530
+ unless usrname.is_a?(String) and usrname =~ USRNAME_REGEXP
531
+ raise(ParameterError, "`#{usrname.inspect}' - bad user name format")
532
+ end
533
+ usrname
534
+ end
535
+
536
+ protected
537
+ def check_passwd(passwd)
538
+ unless passwd.is_a?(String) and passwd =~ PASSWD_REGEXP
539
+ raise(ParameterError, "`#{passwd.inspect}' - bad password format")
540
+ end
541
+ passwd
542
+ end
543
+
544
+ protected
545
+ def check_allowed_requests(allowed_requests)
546
+ unless allowed_requests.is_a?(Array)
547
+ raise(ParameterError,
548
+ "`#{allowed_requests.inspect}' - bad allowed requests list format")
549
+ end
550
+ allowed_requests.each { |r| check_request(r) }
551
+ allowed_requests
552
+ end
553
+
554
+ protected
555
+ def check_allowed_hooks(allowed_hooks)
556
+ unless allowed_hooks.is_a?(Array)
557
+ raise(ParameterError,
558
+ "`#{allowed_hooks.inspect}' - bad allowed hooks list format")
559
+ end
560
+ allowed_hooks.each { |r| check_request(r) }
561
+ allowed_hooks
562
+ end
563
+
564
+ protected
565
+ def check_admin(admin)
566
+ unless admin.is_a?(TrueClass) or admin.is_a?(FalseClass)
567
+ raise(ParameterError, "`#{admin.inspect}' - bad admin flag")
568
+ end
569
+ admin
570
+ end
571
+
572
+ protected
573
+ def check_hook(hook)
574
+ unless hook.respond_to?(:hook)
575
+ raise(ParameterError, "`#{hook.inspect}' - do not respond to hook")
576
+ end
577
+ hook
578
+ end
579
+
580
+ end # class Server
581
+
582
+ end # module Session