rims 0.2.5 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7acc91008294ca9589a19ecb657d5a04cc9d21c17e6349e059dd371bba0f4dbb
4
- data.tar.gz: f750c5ef8ea6064033d1b6e1e0329964db61e56f1e9e1535883a19fcb1738aa3
3
+ metadata.gz: 302a70ed845d6af656e11c2a6fde78cfda71a33b1d5673654594634b7fe92f63
4
+ data.tar.gz: 468e136c3796d1ea15d9e554be3f6dd38b5d34fe3089c7db71a0d7a87d73e9cb
5
5
  SHA512:
6
- metadata.gz: 003c20745f575ba8801f6b72956b42b3329f45fc84f70fe68146767fae15a657f9a3cb1767f759877e8cf442738873a05182c835d697c702e4fad7a575b560d3
7
- data.tar.gz: 449554fe7059796dd4fbbce1c433b7abc2a411ad5ee24acccc0618bb1043e2fb6b9a006dc0e93eb5c32813409a80b2bb677c37e39437e819153c38233cbaa194
6
+ metadata.gz: 96c2d58c1990e724743581436c0e373bcb147e4afd799f8c9860146cf2c4fa33b5652a2937a4185590a5b7a79c2309bf899d16268eeed92765b08572c74d3884
7
+ data.tar.gz: 816e5242fbf6c361d81306f516c27eab7046d73829ae7a08065a44788ef28afba71923b0eb6b200d7a0b6f2791fda24e8f7c4a6d481ff9502333fa4fc2179c03
data/.gitignore CHANGED
@@ -14,6 +14,9 @@
14
14
  /tmp/
15
15
  /vendor/
16
16
  /Gemfile.lock
17
+ /Gemfile_local*
17
18
  /README.html
18
19
  *~
20
+ .#*
21
+ \#*
19
22
  *.log
@@ -0,0 +1,96 @@
1
+ Change Log
2
+ ==========
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
+
27
+ 0.2.9
28
+ -----
29
+ Released on 2019-12-12.
30
+
31
+ ### Added
32
+ - Add `umask(2)` configuration parameter. [#29](https://github.com/y10k/rims/issues/29)
33
+ - Add debug logging for conflicted subscriber error. This problem is
34
+ not solved because it does not reappear. [#28](https://github.com/y10k/rims/issues/28)
35
+
36
+ ### Changed
37
+ - Ready to Ruby 2.7. [#35](https://github.com/y10k/rims/issues/35)
38
+
39
+ ### Fixed
40
+ - Fix a bug of detached thread finishing a protocol decoder engine.
41
+ - Make bulk message size of inter-process communication not exceeding `DRb`'s `load_limit`.
42
+ [#30](https://github.com/y10k/rims/issues/30)
43
+ [#33](https://github.com/y10k/rims/issues/33)
44
+
45
+ 0.2.8
46
+ -----
47
+ Released on 2019-10-10.
48
+
49
+ 0.2.7
50
+ -----
51
+ Released on 2019-07-27.
52
+
53
+ 0.2.6
54
+ -----
55
+ Released on 2019-07-09.
56
+
57
+ 0.2.5
58
+ -----
59
+ Released on 2019-06-10.
60
+
61
+ 0.2.4
62
+ -----
63
+ Released on 2019-04-25.
64
+
65
+ 0.2.3
66
+ -----
67
+ Released on 2019-04-10.
68
+
69
+ 0.2.2
70
+ -----
71
+ Released on 2019-03-06.
72
+
73
+ 0.2.1
74
+ -----
75
+ Released on 2019-02-18.
76
+
77
+ 0.1.0
78
+ -----
79
+ Released on 2015-02-22.
80
+
81
+ 0.0.4
82
+ -----
83
+ Released on 2014-06-08.
84
+
85
+ 0.0.3
86
+ -----
87
+ Released on 2014-04-15.
88
+
89
+ 0.0.2
90
+ -----
91
+ Released on 2014-03-05.
92
+
93
+ 0.0.1
94
+ -----
95
+ Released on 2014-02-24.
96
+
data/ChangeLog CHANGED
@@ -1,3 +1,112 @@
1
+ 2019-12-12 TOKI Yoshinori <toki@freedom.ne.jp>
2
+
3
+ * ChangeLog: updates to this file have been stopped.
4
+ see CHANGELOG.md from now on.
5
+
6
+ 2019-10-10 TOKI Yoshinori <toki@freedom.ne.jp>
7
+
8
+ * RIMS version 0.2.8 is released.
9
+
10
+ 2019-08-12 TOKI Yoshinori <toki@freedom.ne.jp>
11
+
12
+ * lib/rims/cmd.rb, lib/rims/service.rb: DRb service load_limit
13
+ option.
14
+
15
+ 2019-07-27 TOKI Yoshinori <toki@freedom.ne.jp>
16
+
17
+ * RIMS version 0.2.7 is released.
18
+
19
+ 2019-07-25 TOKI Yoshinori <toki@freedom.ne.jp>
20
+
21
+ * lib/rims/cmd.rb, lib/rims/protocol/decoder.rb,
22
+ lib/rims/protocol/parser.rb, lib/rims/service.rb: message charset
23
+ encoding conversion options.
24
+
25
+ 2019-07-22 TOKI Yoshinori <toki@freedom.ne.jp>
26
+
27
+ * lib/rims/cmd.rb, lib/rims/protocol/decoder.rb,
28
+ lib/rims/protocol/parser.rb, lib/rims/service.rb: charset aliases
29
+ option.
30
+
31
+ 2019-07-20 TOKI Yoshinori <toki@freedom.ne.jp>
32
+
33
+ * lib/rims/protocol/decoder.rb, lib/rims/protocol/parser.rb:
34
+ case-insensitive matching of SEARCH command.
35
+
36
+ See RFC3501 / 6.4.4. SEARCH Command
37
+ <https://tools.ietf.org/html/rfc3501#section-6.4.4>
38
+
39
+ In all search keys that use strings, a message matches the key if
40
+ the string is a substring of the field. The matching is
41
+ case-insensitive.
42
+
43
+ * lib/rims/protocol/parser.rb: search for MIME encoded header
44
+ fields.
45
+
46
+ 2019-07-09 TOKI Yoshinori <toki@freedom.ne.jp>
47
+
48
+ * RIMS version 0.2.6 is released.
49
+
50
+ 2019-07-08 TOKI Yoshinori <toki@freedom.ne.jp>
51
+
52
+ * lib/rims/cmd.rb: disable plug-in name list on plug-in command
53
+ options.
54
+
55
+ * lib/rims/cmd.rb: environment command is defined.
56
+
57
+ 2019-07-02 TOKI Yoshinori <toki@freedom.ne.jp>
58
+
59
+ * lib/rims/protocol/decoder.rb: ALERT message notified to client
60
+ immediately.
61
+
62
+ 2019-07-01 TOKI Yoshinori <toki@freedom.ne.jp>
63
+
64
+ * lib/rims/protocol/decoder.rb, lib/rims/protocol/parser.rb: skip
65
+ encoding error on SEARCH command.
66
+
67
+ * lib/rims/protocol/decoder.rb: BADCHARSET response code for
68
+ unknown charset on SERCH command.
69
+
70
+ See RFC 3501 / 6.4.4. SEARCH Command
71
+ <https://tools.ietf.org/html/rfc3501#section-6.4.4>
72
+
73
+ If the server does not support the specified [CHARSET], it MUST
74
+ return a tagged NO response (not a BAD). This response SHOULD
75
+ contain the BADCHARSET response code, which MAY list the
76
+ [CHARSET]s supported by the server.
77
+
78
+ 2019-06-29 TOKI Yoshinori <toki@freedom.ne.jp>
79
+
80
+ * lib/rims/protocol/decoder.rb: line break before error response
81
+ interrupting search command.
82
+
83
+ 2019-06-25 TOKI Yoshinori <toki@freedom.ne.jp>
84
+
85
+ * lib/rims/protocol/parser.rb: delete unnecessary private methods.
86
+
87
+ 2019-06-23 TOKI Yoshinori <toki@freedom.ne.jp>
88
+
89
+ * lib/rims/protocol/parser.rb: add extension data to
90
+ bodystructure.
91
+
92
+ 2019-06-21 TOKI Yoshinori <toki@freedom.ne.jp>
93
+
94
+ * lib/rims/rfc822.rb, rims.gemspec, test/test_rfc822.rb: repladced
95
+ `RIMS::RFC822' to a external rubygem.
96
+
97
+ 2019-06-15 TOKI Yoshinori <toki@freedom.ne.jp>
98
+
99
+ * lib/rims/protocol/parser.rb: not allowed empty body field
100
+ parameters at attribute parser.
101
+
102
+ when body field parameters are empty, a command to fetch
103
+ `bodystructure' should response `NIL' instead of `()'.
104
+
105
+ see RFC 3501 / 9. Formal Syntax:
106
+ <https://tools.ietf.org/html/rfc3501#section-9>
107
+
108
+ body-fld-param = "(" string SP string *(SP string SP string) ")" / nil
109
+
1
110
  2019-06-10 TOKI Yoshinori <toki@freedom.ne.jp>
2
111
 
3
112
  * RIMS version 0.2.5 is released.
data/Rakefile CHANGED
@@ -28,14 +28,18 @@ Rake::RDocTask.new do |rd|
28
28
  rd.rdoc_files.include('lib/**/*.rb')
29
29
  end
30
30
 
31
+ rule '.html' => '.md' do |t|
32
+ sh "pandoc --from=markdown --to=html5 --standalone --self-contained --css=$HOME/.pandoc/github.css --output=#{t.name} #{t.source}"
33
+ end
34
+
31
35
  desc 'Build README.html from markdown source'
32
36
  task :readme => %w[ README.html ]
33
-
34
- file 'README.html' => [ 'README.md' ] do
35
- sh "pandoc --from=markdown --to=html5 --standalone --self-contained --css=$HOME/.pandoc/github.css --output=README.html README.md"
36
- end
37
37
  CLOBBER.include 'README.html'
38
38
 
39
+ desc 'Build CHANGELOG.html from markdown source'
40
+ task :changelog => %w[ CHANGELOG.html ]
41
+ CLOBBER.include 'CHANGELOG.html'
42
+
39
43
  namespace :test_cert do
40
44
  tls_dir = Pathname('test/tls')
41
45
 
@@ -5,35 +5,37 @@ require "rims/version"
5
5
  autoload :OpenSSL, 'openssl'
6
6
 
7
7
  module RIMS
8
- autoload :Authentication, 'rims/auth'
9
- autoload :Checksum_KeyValueStore, 'rims/cksum_kvs'
10
- autoload :Cmd, 'rims/cmd'
11
- autoload :DB, 'rims/db'
12
- autoload :Error, 'rims/error'
13
- autoload :GDBM_KeyValueStore, 'rims/gdbm_kvs'
14
- autoload :GlobalDB, 'rims/db'
15
- autoload :Hash_KeyValueStore, 'rims/hash_kvs'
16
- autoload :IllegalLockError, 'rims/lock'
17
- autoload :KeyValueStore, 'rims/kvs'
18
- autoload :LockError, 'rims/lock'
19
- autoload :MailFolder, 'rims/mail_store'
20
- autoload :MailStore, 'rims/mail_store'
21
- autoload :MailboxDB, 'rims/db'
22
- autoload :MessageDB, 'rims/db'
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 :ReadWriteLock, 'rims/lock'
31
- autoload :ServerResponseChannel, 'rims/channel'
32
- autoload :Service, 'rims/service'
33
- autoload :SyntaxError, 'rims/protocol'
34
- autoload :Test, 'rims/test'
35
- autoload :WriteLockError, 'rims/lock'
36
- autoload :WriteLockTimeoutError, 'rims/lock'
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:
@@ -1,6 +1,20 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
+ require 'forwardable'
4
+
3
5
  module RIMS
6
+ class ServerResponseChannelError < Error
7
+ end
8
+
9
+ class ServerResponseChannelAttachError < ServerResponseChannelError
10
+ end
11
+
12
+ class ServerResponseChannelDetachError < ServerResponseChannelError
13
+ end
14
+
15
+ class ServerResponseChannelPublishError < ServerResponseChannelError
16
+ end
17
+
4
18
  class ServerResponseChannel
5
19
  def initialize
6
20
  @mutex = Thread::Mutex.new
@@ -9,14 +23,16 @@ module RIMS
9
23
 
10
24
  def make_pub_sub_pair(mbox_id)
11
25
  pub = ServerResponsePublisher.new(self, mbox_id)
12
- sub = ServerResponseSubscriber.new(self, mbox_id, pub.pub_sub_pair_key)
26
+ sub = ServerResponseSubscriber.new(self, pub)
13
27
  return pub, attach(sub)
14
28
  end
15
29
 
16
30
  def attach(sub)
17
31
  @mutex.synchronize{
18
32
  @channel[sub.mbox_id] ||= {}
19
- (@channel[sub.mbox_id].key? sub.pub_sub_pair_key) and raise ArgumentError, 'conflicted subscriber.'
33
+ if (@channel[sub.mbox_id].key? sub.pub_sub_pair_key) then
34
+ raise ServerResponseChannelAttachError.new('conflicted subscriber.', channel: self, subscriber: sub)
35
+ end
20
36
  @channel[sub.mbox_id][sub.pub_sub_pair_key] = sub
21
37
  }
22
38
 
@@ -30,8 +46,13 @@ module RIMS
30
46
  # - ServerResponseSubscriber#detach
31
47
  def detach(sub)
32
48
  @mutex.synchronize{
33
- ((@channel.key? sub.mbox_id) && (@channel[sub.mbox_id].key? sub.pub_sub_pair_key)) or raise ArgumentError, 'unregistered pub-sub pair.'
34
- (@channel[sub.mbox_id][sub.pub_sub_pair_key] == sub) or raise 'internal error: mismatched subscriber.'
49
+ unless ((@channel.key? sub.mbox_id) && (@channel[sub.mbox_id].key? sub.pub_sub_pair_key)) then
50
+ raise ServerResponseChannelDetachError.new('unregistered pub-sub pair.', channel: self, subscriber: sub)
51
+ end
52
+
53
+ unless (@channel[sub.mbox_id][sub.pub_sub_pair_key] == sub) then
54
+ raise ServerResponseChannelDetachError.new('internal error: mismatched subscriber.', channel: self, subscribe: sub)
55
+ end
35
56
 
36
57
  @channel[sub.mbox_id].delete(sub.pub_sub_pair_key)
37
58
  if (@channel[sub.mbox_id].empty?) then
@@ -74,7 +95,12 @@ module RIMS
74
95
  end
75
96
 
76
97
  def publish(response_message)
77
- @channel or raise 'detached publisher.'
98
+ unless (@channel) then
99
+ raise ServerResponseChannelPublishError.new('detached publisher.',
100
+ publisher: self,
101
+ pub_sub_pair_key: pub_sub_pair_key,
102
+ message: response_message)
103
+ end
78
104
  @channel.publish(@mbox_id, pub_sub_pair_key, response_message)
79
105
  nil
80
106
  end
@@ -89,15 +115,14 @@ module RIMS
89
115
  # do not call this method directly, call the following method
90
116
  # instead.
91
117
  # - ServerResponseChannel#make_pub_sub_pair
92
- def initialize(channel, mbox_id, pub_sub_pair_key)
118
+ def initialize(channel, pub)
93
119
  @channel = channel
94
- @mbox_id = mbox_id
95
- @pub_sub_pair_key = pub_sub_pair_key
120
+ @pub = pub
96
121
  @queue = Thread::Queue.new
97
122
  end
98
123
 
99
- attr_reader :mbox_id
100
- attr_reader :pub_sub_pair_key
124
+ extend Forwardable
125
+ def_delegators :@pub, :mbox_id, :pub_sub_pair_key
101
126
 
102
127
  # do not call this method directly, call the following method
103
128
  # instead.
@@ -1,13 +1,10 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  require 'json'
4
- require 'logger'
5
4
  require 'net/imap'
6
5
  require 'optparse'
7
6
  require 'pp'if $DEBUG
8
7
  require 'riser'
9
- require 'syslog'
10
- require 'syslog/logger'
11
8
  require 'yaml'
12
9
 
13
10
  OptionParser.accept(JSON) do |json_data, *_|
@@ -61,7 +58,7 @@ module RIMS
61
58
  puts "commands:"
62
59
  w = CMDs.keys.map{|k| k.length }.max + 4
63
60
  fmt = " %- #{w}s%s"
64
- CMDs.each do |cmd_name, cmd_entry|
61
+ CMDs.sort_by{|cmd_name, _| cmd_name }.each do |cmd_name, cmd_entry|
65
62
  if ((! show_debug_command) && (cmd_name =~ /\A debug/x)) then
66
63
  next
67
64
  end
@@ -328,6 +325,16 @@ module RIMS
328
325
  })
329
326
  }
330
327
  end
328
+ options.on('--daemon-umask=UMASK',
329
+ Integer,
330
+ "Umask(2). effective only with daemon command. default is `#{'%04o' % Service::DEFAULT_CONFIG.daemon_umask}'."
331
+ ) do |umask|
332
+ build.chain{|c|
333
+ c.load(daemon: {
334
+ umask: umask
335
+ })
336
+ }
337
+ end
331
338
  options.on('--status-file=FILE',
332
339
  String,
333
340
  "Name of status file. effective only with daemon command. default is `#{Service::DEFAULT_CONFIG.status_file}'."
@@ -465,6 +472,85 @@ module RIMS
465
472
  })
466
473
  }
467
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
502
+ options.on('--[no-]use-default-charset-aliases'
503
+ ) do |use_default_aliases|
504
+ build.chain{|c|
505
+ c.load(charset: {
506
+ use_default_aliases: use_default_aliases
507
+ })
508
+ }
509
+ end
510
+ options.on('--add-charset-alias=NAME_TO_ENCODING',
511
+ /\A \S+,\S+ \z/x,
512
+ "Set the alias name and encoding separated with comma (,)."
513
+ ) do |name_to_encoding|
514
+ name, encoding = name_to_encoding.split(',', 2)
515
+ build.chain{|c|
516
+ c.load(charset: {
517
+ aliases: [
518
+ { name: name, encoding: encoding }
519
+ ]
520
+ })
521
+ }
522
+ end
523
+ options.on('--[no-]replace-charset-invalid'
524
+ ) do |replace|
525
+ build.chain{|c|
526
+ c.load(charset: {
527
+ convert_options: {
528
+ replace_invalid_byte_sequence: replace
529
+ }
530
+ })
531
+ }
532
+ end
533
+ options.on('--[no-]replace-charset-undef'
534
+ ) do |replace|
535
+ build.chain{|c|
536
+ c.load(charset: {
537
+ convert_options: {
538
+ replace_undefined_character: replace
539
+ }
540
+ })
541
+ }
542
+ end
543
+ options.on('--charset-replaced-mark=MARK',
544
+ String
545
+ ) do |mark|
546
+ build.chain{|c|
547
+ c.load(charset: {
548
+ convert_options: {
549
+ replaced_mark: mark
550
+ }
551
+ })
552
+ }
553
+ end
468
554
  options.on('--drb-process-num=NUMBER',
469
555
  Integer
470
556
  ) do |num|
@@ -474,6 +560,15 @@ module RIMS
474
560
  })
475
561
  }
476
562
  end
563
+ options.on('--drb-load-limit=SIZE',
564
+ Integer
565
+ ) do |size|
566
+ build.chain{|c|
567
+ c.load(drb_services: {
568
+ load_limit: size
569
+ })
570
+ }
571
+ end
477
572
  options.on('--bulk-response-count=COUNT',
478
573
  Integer) do |count|
479
574
  build.chain{|c|
@@ -484,6 +579,16 @@ module RIMS
484
579
  })
485
580
  }
486
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
487
592
  options.on('--read-lock-timeout=SECONDS',
488
593
  Float
489
594
  ) do |seconds|
@@ -518,14 +623,7 @@ module RIMS
518
623
  }
519
624
  end
520
625
  options.on('--meta-kvs-type=TYPE',
521
- KeyValueStore::FactoryBuilder.plug_in_names,
522
- "Choose key-value store type of mailbox meta-data database" +
523
- if (KeyValueStore::FactoryBuilder.plug_in_names.length > 1) then
524
- ' (' + KeyValueStore::FactoryBuilder.plug_in_names.join(' ') + ')'
525
- else
526
- ''
527
- end +
528
- ". default is `" +
626
+ "Choose key-value store type of mailbox meta-data database. default is `" +
529
627
  KeyValueStore::FactoryBuilder.plug_in_names[0] +
530
628
  "'."
531
629
  ) do |kvs_type|
@@ -567,14 +665,7 @@ module RIMS
567
665
  }
568
666
  end
569
667
  options.on('--text-kvs-type=TYPE',
570
- KeyValueStore::FactoryBuilder.plug_in_names,
571
- "Choose key-value store type of mailbox text-data database" +
572
- if (KeyValueStore::FactoryBuilder.plug_in_names.length > 1) then
573
- ' (' + KeyValueStore::FactoryBuilder.plug_in_names.join(' ') + ')'
574
- else
575
- ''
576
- end +
577
- ". default is `" +
668
+ "Choose key-value store type of mailbox text-data database. default is `" +
578
669
  KeyValueStore::FactoryBuilder.plug_in_names[0] +
579
670
  "'."
580
671
  ) do |kvs_type|
@@ -627,7 +718,7 @@ module RIMS
627
718
  end
628
719
  options.on('--passwd-config=TYPE_JSONDATA',
629
720
  /([^:]+)(?::(.*))?/,
630
- "Password source type (#{Authentication.plug_in_names.join(',')}) and configuration. format is `[type]:[json_data]'."
721
+ "Password source type and configuration. format is `[type]:[json_data]'."
631
722
  ) do |_, type, json_data|
632
723
  build.chain{|c|
633
724
  c.load(authentication: {
@@ -641,7 +732,7 @@ module RIMS
641
732
  end
642
733
  options.on('--passwd-file=TYPE_FILE',
643
734
  /([^:]+):(.+)/,
644
- "Password source type (#{Authentication.plug_in_names.join(',')}) and configuration file. format is `[type]:[file]'."
735
+ "Password source type and configuration file. format is `[type]:[file]'."
645
736
  ) do |_, type, path|
646
737
  build.chain{|c|
647
738
  c.load(authentication: {
@@ -699,7 +790,6 @@ module RIMS
699
790
  build.chain{|c| c.load(ip_port: port) }
700
791
  end
701
792
  options.on('--kvs-type=TYPE',
702
- KeyValueStore::FactoryBuilder.plug_in_names,
703
793
  'Deplicated.'
704
794
  ) do |kvs_type|
705
795
  warn("warning: `--kvs-type=TYPE' is deplicated option and should use `--meta-kvs-type=TYPE' or `--text-kvs-type=TYPE'.")
@@ -907,14 +997,7 @@ module RIMS
907
997
  def key_value_store_option
908
998
  @conf[:key_value_store_type] = GDBM_KeyValueStore
909
999
  @options.on('--kvs-type=TYPE',
910
- KeyValueStore::FactoryBuilder.plug_in_names,
911
- "Choose key-value store type of mailbox database" +
912
- if (KeyValueStore::FactoryBuilder.plug_in_names.length > 1) then
913
- ' (' + KeyValueStore::FactoryBuilder.plug_in_names.join(' ') + ')'
914
- else
915
- ''
916
- end +
917
- ". default is `" +
1000
+ "Choose key-value store type of mailbox database. default is `" +
918
1001
  KeyValueStore::FactoryBuilder.plug_in_names[0] +
919
1002
  "'."
920
1003
  ) do |kvs_type|
@@ -1096,6 +1179,7 @@ module RIMS
1096
1179
  Riser::Daemon.start_daemon(daemonize: svc_conf.daemonize?,
1097
1180
  daemon_name: svc_conf.daemon_name,
1098
1181
  daemon_debug: svc_conf.daemon_debug?,
1182
+ daemon_umask: svc_conf.daemon_umask,
1099
1183
  status_file: svc_conf.status_file,
1100
1184
  listen_address: proc{
1101
1185
  # to reload on server restart
@@ -1145,6 +1229,44 @@ module RIMS
1145
1229
  end
1146
1230
  command_function :cmd_daemon, "Daemon start/stop/status tool."
1147
1231
 
1232
+ def cmd_environment(options, args)
1233
+ format = {
1234
+ yaml: lambda{|env|
1235
+ YAML.dump(env)
1236
+ },
1237
+ json: lambda{|env|
1238
+ JSON.pretty_generate(env)
1239
+ }
1240
+ }
1241
+
1242
+ conf = Config.new(options,
1243
+ [ [ :format_type,
1244
+ format.keys.first,
1245
+ '--format=FORMAT',
1246
+ format.keys,
1247
+ "Choose display format (#{format.keys.join(' ')})."
1248
+ ]
1249
+ ])
1250
+ conf.required_feature_option
1251
+ conf.setup_option_list
1252
+ conf.parse_options!(args)
1253
+
1254
+ env = {
1255
+ 'RIMS Environment' => [
1256
+ { 'RUBY VERSION' => RUBY_DESCRIPTION },
1257
+ { 'RIMS VERSION' => RIMS::VERSION },
1258
+ { 'AUTHENTICATION PLUG-IN' => Authentication.plug_in_names },
1259
+ { 'KEY-VALUE STORE PLUG-IN' => KeyValueStore::FactoryBuilder.plug_in_names }
1260
+ ]
1261
+ }
1262
+
1263
+ formatter = format[conf[:format_type]]
1264
+ puts formatter.call(env)
1265
+
1266
+ 0
1267
+ end
1268
+ command_function :cmd_environment, 'Show rims environment.'
1269
+
1148
1270
  def imap_append(imap, mailbox, message, store_flags: [], date_time: nil, verbose: false)
1149
1271
  puts "message date: #{date_time}" if (verbose && date_time)
1150
1272
  store_flags = nil if store_flags.empty?