rims 0.2.5 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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?