rims 0.2.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 (52) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/ChangeLog +379 -0
  4. data/Gemfile +11 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +566 -0
  7. data/Rakefile +29 -0
  8. data/bin/rims +11 -0
  9. data/lib/rims.rb +45 -0
  10. data/lib/rims/auth.rb +133 -0
  11. data/lib/rims/cksum_kvs.rb +68 -0
  12. data/lib/rims/cmd.rb +809 -0
  13. data/lib/rims/daemon.rb +338 -0
  14. data/lib/rims/db.rb +793 -0
  15. data/lib/rims/error.rb +23 -0
  16. data/lib/rims/gdbm_kvs.rb +76 -0
  17. data/lib/rims/hash_kvs.rb +66 -0
  18. data/lib/rims/kvs.rb +101 -0
  19. data/lib/rims/lock.rb +151 -0
  20. data/lib/rims/mail_store.rb +663 -0
  21. data/lib/rims/passwd.rb +251 -0
  22. data/lib/rims/pool.rb +88 -0
  23. data/lib/rims/protocol.rb +71 -0
  24. data/lib/rims/protocol/decoder.rb +1469 -0
  25. data/lib/rims/protocol/parser.rb +1114 -0
  26. data/lib/rims/rfc822.rb +456 -0
  27. data/lib/rims/server.rb +567 -0
  28. data/lib/rims/test.rb +391 -0
  29. data/lib/rims/version.rb +11 -0
  30. data/load_test/Rakefile +93 -0
  31. data/rims.gemspec +38 -0
  32. data/test/test_auth.rb +174 -0
  33. data/test/test_cksum_kvs.rb +121 -0
  34. data/test/test_config.rb +533 -0
  35. data/test/test_daemon_status_file.rb +169 -0
  36. data/test/test_daemon_waitpid.rb +72 -0
  37. data/test/test_db.rb +602 -0
  38. data/test/test_db_recovery.rb +732 -0
  39. data/test/test_error.rb +97 -0
  40. data/test/test_gdbm_kvs.rb +32 -0
  41. data/test/test_hash_kvs.rb +116 -0
  42. data/test/test_lock.rb +161 -0
  43. data/test/test_mail_store.rb +750 -0
  44. data/test/test_passwd.rb +203 -0
  45. data/test/test_protocol.rb +91 -0
  46. data/test/test_protocol_auth.rb +121 -0
  47. data/test/test_protocol_decoder.rb +6490 -0
  48. data/test/test_protocol_fetch.rb +994 -0
  49. data/test/test_protocol_request.rb +332 -0
  50. data/test/test_protocol_search.rb +974 -0
  51. data/test/test_rfc822.rb +696 -0
  52. metadata +174 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 29c18b0a88fc771e30319973c66baff76e8a4c6c9d7bc9c8c239dd78cf25b9c1
4
+ data.tar.gz: d6e6f213bfea0ff8684de0b79e625face9f6ad22c6e6f94d23aaa900ca526805
5
+ SHA512:
6
+ metadata.gz: ee07de390442b50d654e4290488be4ca99b72ee42ca6f4dcae6a745a43155d001284d8356a56ab4231ecd3dfc19a02965efd6fd007e5ec44c2f3128d9e296896
7
+ data.tar.gz: 4519d3182df3ada8bf8a9cf6fa1a8d89673db9fdb7f500735fbf703e211dce4a851e5e9630976be3de89839eb79541aec75d87fc409a11560005d1b10a110064
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
@@ -0,0 +1,379 @@
1
+ 2019-02-18 TOKI Yoshinori <toki@freedom.ne.jp>
2
+
3
+ * README.md, rims.gemspec: fixed for release to rubygems.
4
+
5
+ * lib/rims/version.rb : start to version 0.2.1.
6
+
7
+ 2018-12-02 TOKI Yoshinori <toki@freedom.ne.jp>
8
+
9
+ * lib/rims/cmd.rb, lib/rims/gdbm_kvs.rb, lib/rims/kvs.rb,
10
+ lib/rims/server.rb ,lib/rims/test.rb:
11
+ key-value store. added plug-in API.
12
+
13
+ 2018-11-13 TOKI Yoshinori <toki@freedom.ne.jp>
14
+
15
+ * README.md: modified installation example.
16
+
17
+ * lib/rims/mail_store.rb (RIMS::MailFolder),
18
+ lib/rims/protocol/decoder.rb (RIMS::Protocol::UserMailboxDecoder):
19
+ IMAP IDLE interruption control is moved from
20
+ RIMS::Protocol::UserMailboxDecoder class to
21
+ RIMS::MailFolder class.
22
+
23
+ * lib/rims/mail_store.rb (RIMS::MailStore): open a mailbox
24
+ database on demand.
25
+
26
+ 2018-11-03 TOKI Yoshinori <toki@freedom.ne.jp>
27
+
28
+ * lib/rims/cmd.rb (RIMS::Cmd#cmd_post_mail, RIMS::Cmd#cmd_imap_append):
29
+ it should be treated as binary to be neutral to message
30
+ encoding. the message from standard input was not binary, so it
31
+ was fixed to binary.
32
+
33
+ 2018-10-05 TOKI Yoshinori <toki@freedom.ne.jp>
34
+
35
+ * lib/rims/protocol/parser.rb, lib/rims/protocol/decoder.rb:
36
+ split from lib/rims/protocol.rb.
37
+
38
+ 2017-06-17 TOKI Yoshinori <toki@freedom.ne.jp>
39
+
40
+ * lib/rims.rb, lib/rims/error.rb, lib/rims/lock.rb,
41
+ lib/rims/protocol.rb: API errors should be defined at API
42
+ implementations.
43
+
44
+ 2017-03-26 TOKI Yoshinori <toki@freedom.ne.jp>
45
+
46
+ * test/test_protocol_fetch.rb: fixed for warning: constant
47
+ ::Bignum is deprecated.
48
+
49
+ 2016-12-25 TOKI Yoshinori <toki@freedom.ne.jp>
50
+
51
+ * lib/rims/protocol.rb, lib/rims/rfc822.rb: some body fields at
52
+ BODYSTRUCTURE response should be uppercase letters.
53
+
54
+ 2016-12-11 TOKI Yoshinori <toki@freedom.ne.jp>
55
+
56
+ * lib/rims/mail_store.rb, lib/rims/protocol.rb: IMAP IDLE command
57
+ is implemented.
58
+
59
+ 2016-09-22 TOKI Yoshinori <toki@freedom.ne.jp>
60
+
61
+ * lib/rims.rb, lib/rims/mail_store.rb, lib/rims/pool.rb,
62
+ lib/rims/protocol.rb, lib/rims/server.rb, test/test_mail_store.rb,
63
+ test/test_protocol_decoder.rb: untagged server response.
64
+
65
+ 2016-08-22 TOKI Yoshinori <toki@freedom.ne.jp>
66
+
67
+ * lib/rims/mail_store.rb, lib/rims/protocol.rb: the message
68
+ numbers that are returned from a folder's expunge_mbox method
69
+ should be always consistent with a client side message number
70
+ list. and close command should be return expunge response.
71
+
72
+ * lib/rims/mail_store.rb: late loading message number list of
73
+ mailbox folder.
74
+
75
+ * lib/rims/error.rb, lib/rims/lock.rb, lib/rims/mail_store.rb,
76
+ lib/rims/protocol.rb: read-write lock and lock-try timeout is
77
+ defined for IMAP command interaction.
78
+
79
+ 2016-08-21 TOKI Yoshinori <toki@freedom.ne.jp>
80
+
81
+ * lib/rims/server.rb: defined I/O-buffered writer for response
82
+ sender socket.
83
+
84
+ 2016-07-18 TOKI Yoshinori <toki@freedom.ne.jp>
85
+
86
+ * lib/rims/protocol.rb: protocol decoder. IMAP commands I/F are
87
+ changed to block method. refactoring IMAP command implementations
88
+ to suit a method call given block.
89
+
90
+ 2016-07-02 TOKI Yoshinori <toki@freedom.ne.jp>
91
+
92
+ * lib/rims/rfc822.rb: header field name should not contain a colon
93
+ character.
94
+
95
+ 2016-06-29 TOKI Yoshinori <toki@freedom.ne.jp>
96
+
97
+ * lib/rims/protocol.rb: fixed a bug of protocol decoder chain
98
+ cleanup. cleanup method should be called from last decoder of
99
+ chain. the bug is that cleanup method was called from first
100
+ decoder of chain. therefor next decoders cleanup method was not
101
+ called.
102
+
103
+ 2016-06-26 TOKI Yoshinori <toki@freedom.ne.jp>
104
+
105
+ * lib/rims/auth.rb: a unique user ID should not be modified.
106
+
107
+ 2016-06-05 TOKI Yoshinori <toki@freedom.ne.jp>
108
+
109
+ * lib/rims/protocol.rb, lib/rims/rfc822.rb,
110
+ test/test_db_recovery.rb, test/test_mail_store.rb,
111
+ test/test_protocol_auth.rb, test/test_protocol_decoder.rb,
112
+ test/test_protocol_fetch.rb: clear warning messages
113
+
114
+ * lib/rims/mail_store.rb: abort handling of transaction is
115
+ changed.
116
+
117
+ 2016-05-29 TOKI Yoshinori <toki@freedom.ne.jp>
118
+
119
+ * lib/rims/rfc822.rb: special character double-quote is handled to
120
+ parsing mail address
121
+
122
+ 2016-03-27 TOKI Yoshinori <toki@freedom.ne.jp>
123
+
124
+ * lib/rims/version.rb: version number is changed to 0.2.0.
125
+
126
+ 2015-11-03 TOKI Yoshinori <toki@freedom.ne.jp>
127
+
128
+ * lib/rims/auth.rb, lib/rims/passwd.rb, test/test_passwd.rb:
129
+ refactored API of password source plug-in. explanation comments
130
+ are added for passowrd source plug-in API.
131
+
132
+ 2015-10-11 TOKI Yoshinori <toki@freedom.ne.jp>
133
+
134
+ * lib/rims/auth.rb, lib/rims/passwd.rb, lib/rims/server.rb:
135
+ logging and start/stop hooks are defined at password source plug-in
136
+ mechanism.
137
+
138
+ 2015-05-10 TOKI Yoshinori <toki@freedom.ne.jp>
139
+
140
+ * lib/rims/server.rb: a configuration parameter to load libraries
141
+ is defined.
142
+
143
+ * lib/rims.rb, lib/rims/auth.rb, lib/rims/cmd.rb,
144
+ lib/rims/passwd.rb, lib/rims/server.rb: password source plug-in
145
+ mechanism is defined. plain password source and hash password
146
+ soruce are registered. pass-hash tool for hash password source is
147
+ defined.
148
+
149
+ 2015-02-22 TOKI Yoshinori <toki@freedom.ne.jp>
150
+
151
+ * RIMS version 0.1.0 is released.
152
+
153
+ 2015-02-08 TOKI Yoshinori <toki@freedom.ne.jp>
154
+
155
+ * lib/rims/protocol.rb: returning response with user data recovery
156
+ message from IMAP server is step by step.
157
+
158
+ 2015-02-03 TOKI Yoshinori <toki@freedom.ne.jp>
159
+
160
+ * README.md: Tutorial section is written.
161
+
162
+ 2015-01-25 TOKI Yoshinori <toki@freedom.ne.jp>
163
+
164
+ * lib/rims/protocol.rb: fixed response of search command bad pattern.
165
+
166
+ 2015-01-24 TOKI Yoshinori <toki@freedom.ne.jp>
167
+
168
+ * lib/rims/protocol.rb: search command optimization.
169
+
170
+ * lib/rims/mail_store.rb: message list attribute of mailbox folder
171
+ is encapsulated. and small message sequence set access on mailbox
172
+ folder may be fast.
173
+
174
+ 2015-01-22 TOKI Yoshinori <toki@freedom.ne.jp>
175
+
176
+ * lib/rims/protocol.rb: fixed a bug of store command response.
177
+
178
+ 2015-01-20 TOKI Yoshinori <toki@freedom.ne.jp>
179
+
180
+ * rims.gemspec: explicit dependency for test-unit is defined.
181
+ changed for ruby-2.2.0.
182
+
183
+ 2015-01-10 TOKI Yoshinori <toki@freedom.ne.jp>
184
+
185
+ * lib/rims/daemon.rb: signal(2) interruption robust event loop for
186
+ daemon process.
187
+
188
+ 2015-01-04 TOKI Yoshinori <toki@freedom.ne.jp>
189
+
190
+ * lib/rims/cmd.rb, lib/rims/server.rb: unsuitable named server
191
+ configuration parameters and command line options are renamed to
192
+ suitable names.
193
+
194
+ 2015-01-02 TOKI Yoshinori <toki@freedom.ne.jp>
195
+
196
+ * lib/rims/cmd.rb, lib/rims/daemon.rb: daemon process is
197
+ implemented and daemon process start/stop/status tool is defined.
198
+
199
+ 2014-12-26 Joe Yates <joe.g.yates@gmail.com>
200
+
201
+ * lib/rims/mail_store.rb, lib/rims/protocol.rb: Implement the UIDPLUS extension
202
+
203
+ * test/test_protocol_decoder.rb, test/test_protocol_fetch.rb:
204
+ Ensure Time objects have the correct timezone
205
+
206
+ 2014-12-21 TOKI Yoshinori <toki@freedom.ne.jp>
207
+
208
+ * lib/rims/cmd.rb, lib/rims/server.rb: server process privilege separated from root user.
209
+
210
+ 2014-12-10 TOKI Yoshinori <toki@freedom.ne.jp>
211
+
212
+ * lib/rims/cmd.rb, lib/rims/server.rb: stdout logging.
213
+
214
+ 2014-12-01 TOKI Yoshinori <toki@freedom.ne.jp>
215
+
216
+ * lib/rims/auth.rb, lib/rims/cmd.rb, lib/rims/protocol.rb:
217
+ post-mail mechanism is defined. `post-mail user' and `post-mail
218
+ command' are defined for this mechanism. authenticated special
219
+ user is able to post message to any user.
220
+
221
+ * load_test/Rakefile: load test of post-mail command.
222
+
223
+ 2014-11-19 TOKI Yoshinori <toki@freedom.ne.jp>
224
+
225
+ * load_test/Rakefile: load test of imap-append command.
226
+
227
+ 2014-08-21 TOKI Yoshinori <toki@freedom.ne.jp>
228
+
229
+ * lib/rims/server.rb: path location described at config.yml is changed.
230
+ on loading config.yml, base_dir is a relative path from a parent
231
+ directory of config.yml file. log file path is a relative path
232
+ from a base_dir.
233
+
234
+ 2014-08-18 TOKI Yoshinori <toki@freedom.ne.jp>
235
+
236
+ * lib/rims/server.rb: stop server message.
237
+
238
+ * lib/rims/protocol.rb: I/O string debug log utility function.
239
+
240
+ 2014-08-12 TOKI Yoshinori <toki@freedom.ne.jp>
241
+
242
+ * lib/rims/cmd.rb, lib/rims/server.rb: user list entry for
243
+ multi-user account is defined at server configuration file. some
244
+ maintenance commands of multi-user mailbox is defined.
245
+
246
+ 2014-07-30 TOKI Yoshinori <toki@freedom.ne.jp>
247
+
248
+ * lib/rims/mail_store.rb, lib/rims/protocol.rb,
249
+ lib/rims/server.rb, lib/rims/version.rb:
250
+ multi-user mailbox. layout of parent directory of mailbox
251
+ key-value store is changed from single user layout.
252
+
253
+ 2014-07-11 TOKI Yoshinori <toki@freedom.ne.jp>
254
+
255
+ * lib/rims/auth.rb, lib/rims/cmd.rb, lib/rims/server.rb:
256
+ reformed server configuration API.
257
+
258
+ 2014-07-09 TOKI Yoshinori <toki@freedom.ne.jp>
259
+
260
+ * lib/rims/protocol.rb: logging message for user data recovery.
261
+
262
+ * lib/rims/cmd.rb: new `--auth-type' option is defiend to choose a
263
+ method of IMAP user authentication at imap-append command utility.
264
+
265
+ 2014-07-03 TOKI Yoshinori <toki@freedom.ne.jp>
266
+
267
+ * lib/rims/auth.rb, lib/rims/protocol.rb, lib/rims/server.rb,
268
+ test/test_auth.rb, test/test_protocol_auth.rb, test/test_protocol_decoder.rb:
269
+ implemented user authentication mechanism and added IMAP authenticate command.
270
+ capable authentication types are `plain' and `cram-md5'.
271
+
272
+ 2014-06-08 TOKI Yoshinori <toki@freedom.ne.jp>
273
+
274
+ * RIMS version 0.0.4 is released.
275
+
276
+ 2014-06-06 TOKI Yoshinori <toki@freedom.ne.jp>
277
+
278
+ * lib/rims/protocol.rb, test/test_protocol_search.rb,
279
+ test/test_protocol_decoder.rb: charset parameter can be used on
280
+ search command.
281
+
282
+ 2014-06-05 TOKI Yoshinori <toki@freedom.ne.jp>
283
+
284
+ * lib/rims/test.rb, test/test_protocol_decoder.rb,
285
+ test/test_protocol_fetch.rb, test/test_protocol_search.rb: refactored unit test.
286
+
287
+ 2014-05-21 TOKI Yoshinori <toki@freedom.ne.jp>
288
+
289
+ * lib/rims/test.rb, test/test_rfc822.rb, test/test_mail_store.rb,
290
+ test/test_protocol.rb, test/test_protocol_fetch.rb,
291
+ test/test_protocol_search.rb: refactored unit test.
292
+
293
+ 2014-05-08 TOKI Yoshinori <toki@freedom.ne.jp>
294
+
295
+ * lib/rims/rfc822.rb, lib/rims/protocol.rb, lib/rims/cmd.rb, rims.gemspec:
296
+ mail parser is replaced from mail gem to RIMS::RFC822 parser.
297
+ mail gem is not need and deleted from gemspec.
298
+
299
+ 2014-04-15 TOKI Yoshinori <toki@freedom.ne.jp>
300
+
301
+ * RIMS version 0.0.3 is released.
302
+
303
+ 2014-04-10 TOKI Yoshinori <toki@freedom.ne.jp>
304
+
305
+ * lib/rims/cmd.rb: version command is defined.
306
+
307
+ 2014-04-09 TOKI Yoshinori <toki@freedom.ne.jp>
308
+
309
+ * lib/rims/cmd.rb: added mbox-dirty-flag command. this command
310
+ show/enable/disable dirty flag of mailbox to force recovery.
311
+
312
+ * lib/rims/db.rb, lib/rims/mail_store.rb, lib/rims/protocol.rb:
313
+ dirty flag check and data recovery process are added to storage
314
+ backend of mail store.
315
+
316
+ 2014-03-20 TOKI Yoshinori <toki@freedom.ne.jp>
317
+
318
+ * lib/rims/cksum_kvs.rb, lib/rims/kvs.rb, lib/rims/server.rb, lib/rims/cmd.rb:
319
+ checksum key-value store is defined. server mailbox data is
320
+ verified with checksum at default.
321
+
322
+ * lib/rims/cmd.rb: added entry size dump option to debug-dump-kvs
323
+ command.
324
+
325
+ 2014-03-15 TOKI Yoshinori <toki@freedom.ne.jp>
326
+
327
+ * lib/rims/kvs.rb, lib/rims/gdbm_kvs.rb, lib/rims/db.rb, lib/rims/mail_store.rb:
328
+ destroy API is defined at key-value store and mailbox DB file is
329
+ removed on mailbox deletion.
330
+
331
+ * lib/rims/kvs.rb: key-value store. fixed a bug of abstract method.
332
+ origin of bug is commit of 4f4ce383b8df541a60ba7d62e7626d3e34b29888.
333
+ bug file was `kv.rb'. the file was renamed to `kvs.rb'. basic
334
+ method name was changed. but its call name in abstract method was
335
+ not changed.
336
+
337
+ * lib/rims/server.rb: mail store path of server is changed because
338
+ of incompatibility between new DB and old DB.
339
+
340
+ 2014-03-14 TOKI Yoshinori <toki@freedom.ne.jp>
341
+
342
+ * lib/rims/db.rb, lib/rims/mail_store.rb, lib/rims/protocol.rb:
343
+ backend storage of mail store is replaced to new DB.
344
+
345
+ 2014-03-06 TOKI Yoshinori <toki@freedom.ne.jp>
346
+
347
+ * rename key-value store filename (kv.rb -> kvs.rb, gdbm_kv.rb ->
348
+ gdbm_kvs.rb).
349
+
350
+ * lib/rims/gdbm_kv.rb, lib/rims/cmd.rb: read-only GDBM DB open at
351
+ debug-dump-kvs command.
352
+
353
+ * lib/rims/cmd.rb: add assertion check of command name following
354
+ contract naming rule.
355
+
356
+ 2014-03-05 TOKI Yoshinori <toki@freedom.ne.jp>
357
+
358
+ * RIMS version 0.0.2 is released.
359
+
360
+ * lib/rims/protocol.rb, lib/rims/mail_store.rb: add fine grain
361
+ lock for one user multiple connection.
362
+
363
+ 2014-03-04 TOKI Yoshinori <toki@freedom.ne.jp>
364
+
365
+ * lib/rims/cmd.rb: add debug-dump-kvs command.
366
+
367
+ 2014-03-01 TOKI Yoshinori <toki@freedom.ne.jp>
368
+
369
+ * lib/rims/server.rb, lib/rims/cmd.rb: add server log rotation.
370
+
371
+ 2014-02-27 TOKI Yoshinori <toki@freedom.ne.jp>
372
+
373
+ * lib/rims/protocol.rb: fast error recovery on connection fatal
374
+ error (ex. Errno::EPIPE).
375
+
376
+ 2014-02-24 TOKI Yoshinori <toki@freedom.ne.jp>
377
+
378
+ * RIMS version 0.0.1 is released.
379
+
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in rims.gemspec
6
+ gemspec
7
+
8
+ # Local Variables:
9
+ # mode: Ruby
10
+ # indent-tabs-mode: nil
11
+ # End:
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013-2014 TOKI Yoshinori
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,566 @@
1
+ RIMS
2
+ ====
3
+
4
+ RIMS is Ruby IMap Server.
5
+ This gem provides a complete IMAP server by itself. The IMAP
6
+ server can run as a daemon, mailboxes are provided and messages
7
+ can be delivered to them.
8
+
9
+ Installation
10
+ ------------
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ ```ruby
15
+ gem 'rims'
16
+ ```
17
+
18
+ And then execute:
19
+
20
+ $ bundle
21
+
22
+ Or install it yourself as:
23
+
24
+ $ gem install rims
25
+
26
+ Simple Usage
27
+ ------------
28
+
29
+ Type following to show usage.
30
+
31
+ $ bundle exec rims help
32
+ usage: rims command options
33
+
34
+ commands:
35
+ help Show this message.
36
+ version Show software version.
37
+ server Run IMAP server.
38
+ daemon Daemon start/stop/status tool.
39
+ post-mail Post mail to any user.
40
+ imap-append Append message to IMAP mailbox.
41
+ mbox-dirty-flag Show/enable/disable dirty flag of mailbox database.
42
+ unique-user-id Show unique user ID from username.
43
+ show-user-mbox Show the path in which user's mailbox data is stored.
44
+
45
+ command help options:
46
+ -h, --help
47
+
48
+ Tutorial
49
+ --------
50
+
51
+ Something to need for RIMS setup are following:
52
+
53
+ * IP address of your server to run RIMS.
54
+ * At least one pair of username and password.
55
+ * Your e-mail client that can use IMAP.
56
+
57
+ In this tutorial, IP address is `192.168.56.101`, username is `foo`,
58
+ and password is `bar`.
59
+
60
+ ### First step
61
+
62
+ Let's try to start RIMS. Type following on your console. And some
63
+ messages are shown at console.
64
+
65
+ $ bundle exec rims server -u foo -w bar
66
+ I, [2015-01-24T21:02:37.030415 #24475] INFO -- : start server.
67
+ I, [2015-01-24T21:02:37.035052 #24475] INFO -- : open socket: 0.0.0.0:1430
68
+ I, [2015-01-24T21:02:37.036329 #24475] INFO -- : opened: [AF_INET][1430][0.0.0.0][0.0.0.0]
69
+ I, [2015-01-24T21:02:37.036569 #24475] INFO -- : process ID: 24475
70
+ I, [2015-01-24T21:02:37.037105 #24475] INFO -- : process privilege user: toki(1000)
71
+ I, [2015-01-24T21:02:37.037401 #24475] INFO -- : process privilege group: toki(1000)
72
+
73
+ Add e-mail account to your e-mail client:
74
+
75
+ * Username is `foo`.
76
+ * IMAP server is `192.168.56.101`. This may be replaced to your server
77
+ hostname or IP address.
78
+ * IMAP port number is `1430`. This is default of RIMS.
79
+ * IMAP authentication password is `bar`.
80
+
81
+ If setup is success, empty mailbox named INBOX is shown at new mail
82
+ account of your e-mail client.
83
+
84
+ Last, type Ctrl+C on your console to stop server.
85
+
86
+ ### Configuration file
87
+
88
+ Password at command line parameter is insecure because password is
89
+ peeped from another user using `ps aux`. Username and password should
90
+ be written at configuration file.
91
+
92
+ RIMS configuration file format is YAML. Type following in file of
93
+ `config.yml` and save.
94
+
95
+ ```yaml
96
+ user_list:
97
+ - { user: foo, pass: bar }
98
+ ```
99
+
100
+ And start RIMS with `-f config.yml` option.
101
+
102
+ $ bundle exec rims server -f config.yml
103
+ I, [2015-01-26T23:20:24.573462 #6106] INFO -- : start server.
104
+ I, [2015-01-26T23:20:24.574507 #6106] INFO -- : open socket: 0.0.0.0:1430
105
+ I, [2015-01-26T23:20:24.581892 #6106] INFO -- : opened: [AF_INET][1430][0.0.0.0][0.0.0.0]
106
+ I, [2015-01-26T23:20:24.582044 #6106] INFO -- : process ID: 6106
107
+ I, [2015-01-26T23:20:24.596335 #6106] INFO -- : process privilege user: toki(1000)
108
+ I, [2015-01-26T23:20:24.596985 #6106] INFO -- : process privilege group: toki(1000)
109
+
110
+ If setup is success, empty mailbox named INBOX is shown at mail
111
+ account of your e-mail client.
112
+
113
+ Last, type Ctrl+C on your console to stop server.
114
+
115
+ ### Mail delivery to mailbox
116
+
117
+ In this section, the way that you deliver mail to mailbox on RIMS is
118
+ described. Prepare a sample mail text file that is picked from your
119
+ e-mail client. The sample mail file is named `mail.txt` on description
120
+ of this section.
121
+
122
+ Simple way is that you use IMAP APPEND command. `rims` tool has IMAP
123
+ APPEND command. Type following on your console.
124
+
125
+ $ bundle exec rims imap-append -v -n 192.168.56.101 -o 1430 -u foo -w bar mail.txt
126
+ store flags: ()
127
+ server greeting: OK RIMS vX.Y.Z IMAP4rev1 service ready.
128
+ server capability: IMAP4REV1 UIDPLUS AUTH=PLAIN AUTH=CRAM-MD5
129
+ login: OK LOGIN completed
130
+ append: OK APPEND completed
131
+
132
+ The option of `-v` is verbose mode. If you don't need display
133
+ information, no verbose option exists. If mail delivery is success,
134
+ you will see that message appears in INBOX on your e-mail client.
135
+
136
+ The advantage of IMAP APPEND is to be able to use it by any IMAP mail
137
+ server as well as RIMS. The disadvantage of IMAP APPEND is that it
138
+ requires your password. This may be insecure.
139
+
140
+ Special user is defined to deliver mail to any user's mailbox on RIMS.
141
+ By special user, it is possible to deliver mail without your password.
142
+ The disadvantage of special user is that it can be used only in RIMS.
143
+
144
+ At first, you prepare a special user to deliver mail. Type following
145
+ in configuration file. And start RIMS.
146
+
147
+ ```yaml
148
+ user_list:
149
+ - { user: foo, pass: bar }
150
+ - { user: "#postman", pass: "#postman" }
151
+ ```
152
+
153
+ And type following on your console.
154
+
155
+ $ bundle exec rims post-mail -v -n 192.168.56.101 -o 1430 -w '#postman' foo mail.txt
156
+ store flags: ()
157
+ server greeting: OK RIMS vX.Y.Z IMAP4rev1 service ready.
158
+ server capability: IMAP4REV1 UIDPLUS AUTH=PLAIN AUTH=CRAM-MD5
159
+ login: OK LOGIN completed
160
+ append: OK APPEND completed
161
+
162
+ The option of `-v` is verbose mode. If you don't need display
163
+ information, no verbose option exists. If mail delivery is success,
164
+ you will see that message appears in INBOX on your e-mail client.
165
+
166
+ ### IMAP well known port and server process privilege
167
+
168
+ Default port number of RIMS is 1430. IMAP protocol well known port
169
+ number is 143. If RIMS opens server socket with 143 port, it needs to
170
+ be root user process at unix. But RIMS doesn't need to be root user
171
+ process as IMAP server.
172
+
173
+ To open server socket with well known 143 port at RIMS:
174
+
175
+ 1. RIMS starts at root user.
176
+ 2. RIMS opens server socket with 143 port by root user privilege.
177
+ 3. RIMS calls setuid(2). And privilege of process is changed from root
178
+ user to another.
179
+ 4. RIMS starts IMAP server with another's process privilege.
180
+
181
+ For example, port number is `imap2` (it is service name of well known
182
+ port of 143), process user privilege is `toki` (uid 1000), and process
183
+ group privilege is `toki` (gid 1000). Type following in configuration
184
+ file.
185
+
186
+ ```yaml
187
+ user_list:
188
+ - { user: foo, pass: bar }
189
+ - { user: "#postman", pass: "#postman" }
190
+ imap_port: imap2
191
+ process_privilege_user: toki
192
+ process_privilege_group: toki
193
+ ```
194
+
195
+ And type following on your console.
196
+
197
+ $ sudo bundle exec rims server -f config.yml
198
+ [sudo] password for toki:
199
+ I, [2015-01-31T21:32:30.069848 #9381] INFO -- : start server.
200
+ I, [2015-01-31T21:32:30.070068 #9381] INFO -- : open socket: 0.0.0.0:imap2
201
+ I, [2015-01-31T21:32:30.070374 #9381] INFO -- : opened: [AF_INET][143][0.0.0.0][0.0.0.0]
202
+ I, [2015-01-31T21:32:30.070559 #9381] INFO -- : process ID: 9381
203
+ I, [2015-01-31T21:32:30.070699 #9381] INFO -- : process privilege user: toki(1000)
204
+ I, [2015-01-31T21:32:30.070875 #9381] INFO -- : process privilege group: toki(1000)
205
+
206
+ ### Daemon
207
+
208
+ If RIMS server is started from console terminal, RIMS server process
209
+ is terminated on closing its console terminal. At unix, server
210
+ process has to be started as daemon process for the server to keep
211
+ running its service.
212
+
213
+ RIMS server can start as daemon process. Type following on your
214
+ console.
215
+
216
+ $ sudo bundle exec rims daemon start -f config.yml
217
+
218
+ `sudo` is required for well known 143 port (see previous section).
219
+ Daemon process is started quietly and prompt of console terminal is
220
+ returned immediately. But daemon process is running at background.
221
+ To see background daemon process, type following on your console.
222
+
223
+ $ ps -elf | grep rims
224
+ 5 S root 3191 1720 0 80 0 - 23026 wait 21:10 ? 00:00:00 ruby /home/toki/rims/vendor/ruby/2.2.0/bin/rims daemon start -f config.yml
225
+ 5 S toki 3194 3191 0 80 0 - 26382 inet_c 21:10 ? 00:00:00 ruby /home/toki/rims/vendor/ruby/2.2.0/bin/rims daemon start -f config.yml
226
+
227
+ RIMS daemon is two processes. 1st root process is controller process.
228
+ 2nd process that isn't root is server process. RIMS daemon doesn't
229
+ display messages and errors at console. You should see log files to
230
+ verify normal running of RIMS daemon.
231
+
232
+ To see log of controller process, watch syslog at system directory.
233
+ Type following on your console.
234
+
235
+ $ tail -f /var/log/syslog
236
+ Feb 1 21:10:00 vbox-linux rims-daemon[3191]: start daemon.
237
+ Feb 1 21:10:00 vbox-linux rims-daemon[3191]: run server process: 3194
238
+
239
+ To see log of server process, watch imap.log at local directory. Type
240
+ following on your console.
241
+
242
+ $ tail -f imap.log
243
+ I, [2015-02-01T21:10:00.989859 #3194] INFO -- : start server.
244
+ I, [2015-02-01T21:10:00.990084 #3194] INFO -- : open socket: 0.0.0.0:imap2
245
+ I, [2015-02-01T21:10:00.990989 #3194] INFO -- : opened: [AF_INET][143][0.0.0.0][0.0.0.0]
246
+ I, [2015-02-01T21:10:00.991393 #3194] INFO -- : process ID: 3194
247
+ I, [2015-02-01T21:10:00.991615 #3194] INFO -- : process privilege user: toki(1000)
248
+ I, [2015-02-01T21:10:00.991703 #3194] INFO -- : process privilege group: toki(1000)
249
+
250
+ RIMS daemon process can be controlled from command line tool. Defined
251
+ operations are start, stop, restart and status. Start operation is
252
+ already described.
253
+
254
+ Stop operation:
255
+
256
+ $ sudo bundle exec rims daemon stop -f config.yml
257
+
258
+ Restart operation:
259
+
260
+ $ sudo bundle exec rims daemon restart -f config.yml
261
+
262
+ Status operation:
263
+
264
+ $ sudo bundle exec rims daemon status -f config.yml
265
+ daemon is running.
266
+
267
+ $ sudo bundle exec rims daemon status -f config.yml
268
+ daemon is stopped.
269
+
270
+ Server Configuration
271
+ --------------------
272
+
273
+ Server options on start may be described at config.yml file.
274
+ Config.yml is a YAML format file and its contents are explained
275
+ at later.
276
+
277
+ To start server with config.yml file, type following.
278
+
279
+ $ bundle exec rims server -f a_server_directory/config.yml
280
+
281
+ ### Config.yml Parameters
282
+
283
+ <dl>
284
+ <dt>base_dir</dt>
285
+ <dd>This parameter describes a base directory of server. Mailbox
286
+ data is located at inside of base directory. Default is a parent
287
+ directory of config.yml file. Explicit description of this parameter
288
+ is interpreted as a relative path from a parent directory of
289
+ config.yml file.</dd>
290
+
291
+ <dt>log_stdout</dt>
292
+ <dd>This parameter describes a severity level of logging messages
293
+ that is written to standard output. See description of Logger class
294
+ for more detail of logging. This parameter is one value selected
295
+ from DEBUG, INFO, WARN, ERROR or FATAL. If QUIET value is chosen,
296
+ standard output logging is disabled. Default is INFO. The danger is
297
+ that password may be embedded in message on user authentication in
298
+ DEBUG logging level.</dd>
299
+
300
+ <dt>log_file</dt>
301
+ <dd>This parameter describes a path of log file. Default is
302
+ "imap.log" under the base_dir. Explicit description of this
303
+ parameter is interpreted as a relative path from a base_dir.</dd>
304
+
305
+ <dt>log_level</dt>
306
+ <dd>This parameter describes a severity level of logging
307
+ messages. See description of Logger class for more detail of
308
+ logging. This parameter is one value selected from DEBUG, INFO,
309
+ WARN, ERROR or FATAL. Default is INFO. The danger is that password
310
+ may be embedded in message on user authentication in DEBUG logging
311
+ level.</dd>
312
+
313
+ <dt>log_shift_age</dt>
314
+ <dd>This parameter describes a number of old rotated log files to
315
+ keep or periodical log rotation. Decimal number is interpreted as a
316
+ number of files to keep. Periodical log rotation is one value
317
+ selected from daily, weekly or monthly. Default is none. See
318
+ description of Logger.new class method for more detail of log
319
+ rotation.</dd>
320
+
321
+ <dt>log_shift_size</dt>
322
+ <dd>This parameter describes a maximum log file size on log file
323
+ rotation. Default is none. See description of Logger.new class
324
+ method for more detail of log rotation.</dd>
325
+
326
+ <dt>key_value_store_type</dt>
327
+ <dd>This parameter describes a type of key-value store. Key-value
328
+ store is used to save a mailbox data. This parameter is only one
329
+ value of GDBM, and it is default value.</dd>
330
+
331
+ <dt>use_key_value_store_checksum</dt>
332
+ <dd>This parameter decides whether to use checksum. This parameter
333
+ is boolean, true or false. If this parameter is true, a mailbox data
334
+ is saved with its checksum to an entry of key-value store, and a
335
+ checksum is checked on loading a mailbox data from an entry of
336
+ key-value store. Default is true.</dd>
337
+
338
+ <dt>hostname</dt>
339
+ <dd>This parameter describes a hostname of server. Default is the
340
+ name displayed by hostname(1) command.</dd>
341
+
342
+ <dt>username</dt>
343
+ <dd>This parameter describes a name of mailbox user. This parameter
344
+ and the next password parameter are the pair. If there are two or
345
+ many users, user_list parameter should be used instead of this
346
+ parameter. At least one user is need to start a server.</dd>
347
+
348
+ <dt>password</dt>
349
+ <dd>This parameter describes a password of mailbox user. This
350
+ parameter and the previous username parameter are the pair. If there
351
+ are two or many users, user_list parameter should be used instead of
352
+ this parameter. At least one user is need to start a server.</dd>
353
+
354
+ <dt>user_list</dt>
355
+ <dd>This parameter describes many users of mailbox. The value of
356
+ this parameter is a sequence of maps. A map in the sequence should
357
+ have two entries, the two entries are user and pass. user entry
358
+ describes name of a user. pass entry describes password of a
359
+ user. At least one user is need to start a server.</dd>
360
+
361
+ <dt>imap_host</dt>
362
+ <dd>This parameter describes hostname or IP address of a server
363
+ socket to listen(2) and accept(2). Default is 0.0.0.0.</dd>
364
+
365
+ <dt>imap_port</dt>
366
+ <dd>This parameter describes IP port number or service name of a
367
+ server socket to listen(2) and accept(2). Default is 1430.</dd>
368
+
369
+ <dt>mail_delivery_user</dt>
370
+ <dd>This parameter describes a special user to deliver mail to any
371
+ user. Password definition of this special user is same to a normal
372
+ user. Default is "#postman".</dd>
373
+
374
+ <dt>process_privilege_user</dt>
375
+ <dd>This parameter describes a privilege user name or ID for server
376
+ process. When server process starts on root user, setuid(2) is
377
+ called and server process privilege user is changed from root user
378
+ to this parameter user. Default is 65534 (typical user ID of
379
+ nobody) and should be changed.</dd>
380
+
381
+ <dt>process_privilege_group</dt>
382
+ <dd>This parameter describes a privilege group name or ID for server
383
+ process. When server process starts on root user, setgid(2) is
384
+ called and server process privilege group is changed from root group
385
+ to this parameter group. Default is 65534 (typical group ID of
386
+ nogroup) and should be changed.</dd>
387
+ </dl>
388
+
389
+ Mailbox Data
390
+ ------------
391
+
392
+ Mailbox data exists under the base directory. Next picture is a
393
+ overview of mailbox data filesystem under the base directory.
394
+
395
+ a_base_directory
396
+ |
397
+ +-- mailbox.2/
398
+ |
399
+ +-- 2c/
400
+ |
401
+ +-- 26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae/
402
+ |
403
+ +-- message
404
+ |
405
+ +-- meta
406
+ |
407
+ +-- mailbox_1
408
+ |
409
+ +-- mailbox_2
410
+ |
411
+ ...
412
+
413
+ There is a MAILBOX\_DATA\_STRUCTURE\_VERSION directory under first
414
+ inside of the base directory. When mailbox data structure will be
415
+ changed in future, MAILBOX\_DATA\_STRUCTURE\_VERSION directory will be
416
+ changed too. Now latest version is "mailbox.2".
417
+
418
+ There are user directories under the MAILBOX\_DATA\_STRUCTURE\_VERSION
419
+ directory. A user is identified by unique user ID. Unique user ID is
420
+ a SHA256 HEX digest of a username. For example, type following to
421
+ display a "foo" user's unique user ID.
422
+
423
+ $ bundle exec rims unique-user-id foo
424
+ 2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae
425
+
426
+ First two characters of unique user ID is used as a bucket directory.
427
+ Unique user ID substring from 3rd character to last exists as a user
428
+ directory under the bucket directory. Shortcut tool to search a two
429
+ level directory of a user under a base directory exists. For example,
430
+ type following to display a "foo" user's directory.
431
+
432
+ $ bundle exec rims show-user-mbox a_base_directory foo
433
+ a_base_directory/mailbox.2/2c/26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae
434
+
435
+ There are three types of files under the user directory. Three types
436
+ are message, meta and mailbox. Each file is key-value store. Only
437
+ one type of key-value store is available now, it is GDBM. A GDBM
438
+ key-value store file has a filename suffix, the suffix is ".gdbm".
439
+ Mailbox data does not depend on a specific type of key-value store.
440
+
441
+ ### Message key-value store
442
+
443
+ Message key-value store file preserves all messages of a user. Per
444
+ one user, only one file exists about this file type. Contents of
445
+ message key-value store is simple. A key is a message ID, and a value
446
+ is message text. A message ID is a unique number of a message in RIMS
447
+ internal. For example, type following to see overview of contents at
448
+ a message key-value store.
449
+
450
+ $ bundle exec rims debug-dump-kvs --dump-size --no-dump-value a_base_directory/mailbox.2/2c/26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae/message
451
+ "2": 21938 bytes
452
+ "1": 126014 bytes
453
+ "4": 22928 bytes
454
+ "0": 6326 bytes
455
+ "3": 65168 bytes
456
+
457
+ ### Meta key-value store
458
+
459
+ Meta key-value store file preserves all meta data of message and
460
+ folders. Per one user, only one file exists about this file type.
461
+ Contents of meta key-value store is complex, and only outline of
462
+ content is described here.
463
+
464
+ <dl>
465
+ <dt>dirty</dt>
466
+ <dd>Dirty flag. If enabled, this flag exists. If disabled, this flag
467
+ doesn't exists. This flag will be enabled on updating mailbox
468
+ data.</dd>
469
+
470
+ <dt>cnum</dt>
471
+ <dd>A change number of mailbox data. If mailbox data is modified,
472
+ this number is increased.</dd>
473
+
474
+ <dt>msg_id</dt>
475
+ <dd>The next number of message ID. Message ID is unique number of
476
+ message in RIMS internal.</dd>
477
+
478
+ <dt>uidvalidity</dt>
479
+ <dd>The next number of uidvalidity. Uidvalidity is unique number of
480
+ mailbox in IMAP.</dd>
481
+
482
+ <dt>mbox_set</dt>
483
+ <dd>Mailbox set of a user.</dd>
484
+
485
+ <dt>mbox_id2name-#</dt>
486
+ <dd>Mapping from mailbox ID to mailbox name.</dd>
487
+
488
+ <dt>mbox_name2id-#</dt>
489
+ <dd>Mapping from mailbox name to mailbox ID.</dd>
490
+
491
+ <dt>mbox_id2uid-#</dt>
492
+ <dd>The next uid at a mailbox. Uid is unique number of message at a
493
+ mailbox in IMAP.</dd>
494
+
495
+ <dt>mbox_id2msgnum-#</dt>
496
+ <dd>Number of messages at a mailbox.</dd>
497
+
498
+ <dt>mbox_id2flagnum-#-#</dt>
499
+ <dd>Number of flags at a mailbox.</dd>
500
+
501
+ <dt>msg_id2date-#</dt>
502
+ <dd>Mapping from message ID to internal date of a message. Internal
503
+ date is a message attribute in IMAP.</dd>
504
+
505
+ <dt>msg_id2flag-#</dt>
506
+ <dd>Set of flags at a message.</dd>
507
+
508
+ <dt>msg_id2mbox-#</dt>
509
+ <dd>Mapping from message ID to mailbox's uid.</dd>
510
+ </dl>
511
+
512
+ For example, type following to see overview of contents at a meta key-value store.
513
+
514
+ $ bundle exec rims debug-dump-kvs a_base_directory/mailbox.2/2c/26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae/meta
515
+ "msg_id2mbox-3": 25 bytes: {1=>#<Set: {4}>}
516
+ "msg_id2date-2": 49 bytes: 2013-11-08 13:34:10 +0900
517
+ "mbox_id2uid-1": 1 bytes: "6"
518
+ "msg_id2mbox-1": 25 bytes: {1=>#<Set: {2}>}
519
+ "msg_id2flag-2": 6 bytes: "recent"
520
+ "mbox_id2msgnum-1": 1 bytes: "5"
521
+ "uidvalidity": 1 bytes: "2"
522
+ "mbox_id2flagnum-1-recent": 1 bytes: "5"
523
+ "msg_id2date-0": 49 bytes: 2013-11-08 06:47:50 +0900
524
+ "cnum": 1 bytes: "6"
525
+ "msg_id2date-4": 49 bytes: 2013-11-08 11:57:28 +0900
526
+ "msg_id2mbox-2": 25 bytes: {1=>#<Set: {3}>}
527
+ "mbox_set": 1 bytes: "1"
528
+ "msg_id2flag-0": 6 bytes: "recent"
529
+ "msg_id2flag-4": 6 bytes: "recent"
530
+ "msg_id2date-1": 49 bytes: 2013-11-08 19:31:03 +0900
531
+ "msg_id": 1 bytes: "5"
532
+ "mbox_id2name-1": 5 bytes: "INBOX"
533
+ "msg_id2mbox-0": 25 bytes: {1=>#<Set: {1}>}
534
+ "mbox_name2id-INBOX": 1 bytes: "1"
535
+ "msg_id2mbox-4": 25 bytes: {1=>#<Set: {5}>}
536
+ "msg_id2flag-1": 6 bytes: "recent"
537
+ "msg_id2date-3": 49 bytes: 2013-11-08 12:47:17 +0900
538
+ "msg_id2flag-3": 6 bytes: "recent"
539
+
540
+ ### Mailbox key-value store
541
+
542
+ Mailbox key-value store file preserves key-value pairs of uid and
543
+ message ID. Per one user, plural files exist about this type of file
544
+ because plural mailboxes are allowed at one user. Mailbox key-value
545
+ store filenames are "mailbox\_1", "mailbox\_2", ... And 1,2,... are
546
+ mailbox ID. Contents of mailbox key-value store is simple. A key is
547
+ a uid, and a value is message ID. A uid is a unique number of a
548
+ message in a mailbox in IMAP. A message ID is a unique number of a
549
+ message in RIMS internal. For example, type following to see overview
550
+ of contents at a mailbox key-value store.
551
+
552
+ $ bundle exec rims debug-dump-kvs a_base_directory/mailbox.2/2c/26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae/mailbox_1
553
+ "2": 1 bytes: "1"
554
+ "5": 1 bytes: "4"
555
+ "1": 1 bytes: "0"
556
+ "4": 1 bytes: "3"
557
+ "3": 1 bytes: "2"
558
+
559
+ Contributing
560
+ ------------
561
+
562
+ 1. Fork it
563
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
564
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
565
+ 4. Push to the branch (`git push origin my-new-feature`)
566
+ 5. Create new Pull Request