{"id":22205281,"url":"https://github.com/y10k/rims","last_synced_at":"2025-06-25T07:37:02.024Z","repository":{"id":12606809,"uuid":"15277818","full_name":"y10k/rims","owner":"y10k","description":"Ruby IMap Server","archived":false,"fork":false,"pushed_at":"2020-10-05T13:42:02.000Z","size":1589,"stargazers_count":44,"open_issues_count":10,"forks_count":7,"subscribers_count":10,"default_branch":"master","last_synced_at":"2024-04-21T02:13:22.161Z","etag":null,"topics":["daemon-process","imap-server","mailbox","rims","ruby"],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/y10k.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-12-18T08:30:04.000Z","updated_at":"2024-01-17T05:22:37.000Z","dependencies_parsed_at":"2022-08-27T00:41:44.828Z","dependency_job_id":null,"html_url":"https://github.com/y10k/rims","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/y10k%2Frims","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/y10k%2Frims/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/y10k%2Frims/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/y10k%2Frims/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/y10k","download_url":"https://codeload.github.com/y10k/rims/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227614438,"owners_count":17793940,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["daemon-process","imap-server","mailbox","rims","ruby"],"created_at":"2024-12-02T17:29:39.515Z","updated_at":"2024-12-02T17:29:40.466Z","avatar_url":"https://github.com/y10k.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"RIMS\n====\n\nRIMS is Ruby IMap Server.\nThis gem provides a complete IMAP server by itself.  The IMAP\nserver can run as a daemon, mailboxes are provided and messages\ncan be delivered to them.\n\nInstallation\n------------\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'rims'\n```\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install rims\n\nSimple Usage\n------------\n\nType following to show usage.\n\n    $ bundle exec rims help\n    usage: rims command options\n    \n    commands:\n        help               Show this message.\n        version            Show software version.\n        server             Run IMAP server.\n        daemon             Daemon start/stop/status tool.\n        post-mail          Post mail to any user.\n        imap-append        Append message to IMAP mailbox.\n        mbox-dirty-flag    Show/enable/disable dirty flag of mailbox database.\n        unique-user-id     Show unique user ID from username.\n        show-user-mbox     Show the path in which user's mailbox data is stored.\n    \n    command help options:\n        -h, --help\n\nTutorial\n--------\n\nSomething to need for RIMS setup are following:\n\n* IP address of your server to run RIMS.\n* At least one pair of username and password.\n* Your e-mail client that can use IMAP.\n\nIn this tutorial, IP address is `192.168.56.101`, username is `foo`,\nand password is `bar`.\n\n### First step\n\nLet's try to start RIMS. Type following on your console. And some\nmessages are shown at console.\n\n    $ bundle exec rims server -u foo -w bar\n    I, [2015-01-24T21:02:37.030415 #24475]  INFO -- : start server.\n    I, [2015-01-24T21:02:37.035052 #24475]  INFO -- : open socket: 0.0.0.0:1430\n    I, [2015-01-24T21:02:37.036329 #24475]  INFO -- : opened: [AF_INET][1430][0.0.0.0][0.0.0.0]\n    I, [2015-01-24T21:02:37.036569 #24475]  INFO -- : process ID: 24475\n    I, [2015-01-24T21:02:37.037105 #24475]  INFO -- : process privilege user: toki(1000)\n    I, [2015-01-24T21:02:37.037401 #24475]  INFO -- : process privilege group: toki(1000)\n\nAdd e-mail account to your e-mail client:\n\n* Username is `foo`.\n* IMAP server is `192.168.56.101`. This may be replaced to your server\n  hostname or IP address.\n* IMAP port number is `1430`. This is default of RIMS.\n* IMAP authentication password is `bar`.\n\nIf setup is success, empty mailbox named INBOX is shown at new mail\naccount of your e-mail client.\n\nLast, type Ctrl+C on your console to stop server.\n\n### Configuration file\n\nPassword at command line parameter is insecure because password is\npeeped from another user using `ps aux`. Username and password should\nbe written at configuration file.\n\nRIMS configuration file format is YAML. Type following in file of\n`config.yml` and save.\n\n```yaml\nuser_list:\n  - { user: foo, pass: bar }\n```\n\nAnd start RIMS with `-f config.yml` option.\n\n    $ bundle exec rims server -f config.yml\n    I, [2015-01-26T23:20:24.573462 #6106]  INFO -- : start server.\n    I, [2015-01-26T23:20:24.574507 #6106]  INFO -- : open socket: 0.0.0.0:1430\n    I, [2015-01-26T23:20:24.581892 #6106]  INFO -- : opened: [AF_INET][1430][0.0.0.0][0.0.0.0]\n    I, [2015-01-26T23:20:24.582044 #6106]  INFO -- : process ID: 6106\n    I, [2015-01-26T23:20:24.596335 #6106]  INFO -- : process privilege user: toki(1000)\n    I, [2015-01-26T23:20:24.596985 #6106]  INFO -- : process privilege group: toki(1000)\n\nIf setup is success, empty mailbox named INBOX is shown at mail\naccount of your e-mail client.\n\nLast, type Ctrl+C on your console to stop server.\n\n### Mail delivery to mailbox\n\nIn this section, the way that you deliver mail to mailbox on RIMS is\ndescribed. Prepare a sample mail text file that is picked from your\ne-mail client. The sample mail file is named `mail.txt` on description\nof this section.\n\nSimple way is that you use IMAP APPEND command. `rims` tool has IMAP\nAPPEND command. Type following on your console.\n\n    $ bundle exec rims imap-append -v -n 192.168.56.101 -o 1430 -u foo -w bar mail.txt\n    store flags: ()\n    server greeting: OK RIMS vX.Y.Z IMAP4rev1 service ready.\n    server capability: IMAP4REV1 UIDPLUS AUTH=PLAIN AUTH=CRAM-MD5\n    login: OK LOGIN completed\n    append: OK  APPEND completed\n\nThe option of `-v` is verbose mode. If you don't need display\ninformation, no verbose option exists. If mail delivery is success,\nyou will see that message appears in INBOX on your e-mail client.\n\nThe advantage of IMAP APPEND is to be able to use it by any IMAP mail\nserver as well as RIMS. The disadvantage of IMAP APPEND is that it\nrequires your password. This may be insecure.\n\nSpecial user is defined to deliver mail to any user's mailbox on RIMS.\nBy special user, it is possible to deliver mail without your password.\nThe disadvantage of special user is that it can be used only in RIMS.\n\nAt first, you prepare a special user to deliver mail. Type following\nin configuration file. And start RIMS.\n\n```yaml\nuser_list:\n  - { user: foo, pass: bar }\n  - { user: \"#postman\", pass: \"#postman\" }\n```\n\nAnd type following on your console.\n\n    $ bundle exec rims post-mail -v -n 192.168.56.101 -o 1430 -w '#postman' foo mail.txt\n    store flags: ()\n    server greeting: OK RIMS vX.Y.Z IMAP4rev1 service ready.\n    server capability: IMAP4REV1 UIDPLUS AUTH=PLAIN AUTH=CRAM-MD5\n    login: OK LOGIN completed\n    append: OK  APPEND completed\n\nThe option of `-v` is verbose mode. If you don't need display\ninformation, no verbose option exists. If mail delivery is success,\nyou will see that message appears in INBOX on your e-mail client.\n\n### IMAP well known port and server process privilege\n\nDefault port number of RIMS is 1430. IMAP protocol well known port\nnumber is 143. If RIMS opens server socket with 143 port, it needs to\nbe root user process at unix. But RIMS doesn't need to be root user\nprocess as IMAP server.\n\nTo open server socket with well known 143 port at RIMS:\n\n1. RIMS starts at root user.\n2. RIMS opens server socket with 143 port by root user privilege.\n3. RIMS calls setuid(2). And privilege of process is changed from root\n   user to another.\n4. RIMS starts IMAP server with another's process privilege.\n\nFor example, port number is `imap2` (it is service name of well known\nport of 143), process user privilege is `toki` (uid 1000), and process\ngroup privilege is `toki` (gid 1000). Type following in configuration\nfile.\n\n```yaml\nuser_list:\n  - { user: foo, pass: bar }\n  - { user: \"#postman\", pass: \"#postman\" }\nimap_port: imap2\nprocess_privilege_user: toki\nprocess_privilege_group: toki\n```\n\nAnd type following on your console.\n\n    $ sudo bundle exec rims server -f config.yml\n    [sudo] password for toki: \n    I, [2015-01-31T21:32:30.069848 #9381]  INFO -- : start server.\n    I, [2015-01-31T21:32:30.070068 #9381]  INFO -- : open socket: 0.0.0.0:imap2\n    I, [2015-01-31T21:32:30.070374 #9381]  INFO -- : opened: [AF_INET][143][0.0.0.0][0.0.0.0]\n    I, [2015-01-31T21:32:30.070559 #9381]  INFO -- : process ID: 9381\n    I, [2015-01-31T21:32:30.070699 #9381]  INFO -- : process privilege user: toki(1000)\n    I, [2015-01-31T21:32:30.070875 #9381]  INFO -- : process privilege group: toki(1000)\n\n### Daemon\n\nIf RIMS server is started from console terminal, RIMS server process\nis terminated on closing its console terminal.  At unix, server\nprocess has to be started as daemon process for the server to keep\nrunning its service.\n\nRIMS server can start as daemon process. Type following on your\nconsole.\n\n    $ sudo bundle exec rims daemon start -f config.yml\n\n`sudo` is required for well known 143 port (see previous section).\nDaemon process is started quietly and prompt of console terminal is\nreturned immediately. But daemon process is running at background.\nTo see background daemon process, type following on your console.\n\n    $ ps -elf | grep rims\n    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\n    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\n\nRIMS daemon is two processes. 1st root process is controller process.\n2nd process that isn't root is server process. RIMS daemon doesn't\ndisplay messages and errors at console. You should see log files to\nverify normal running of RIMS daemon.\n\nTo see log of controller process, watch syslog at system directory.\nType following on your console.\n\n    $ tail -f /var/log/syslog\n    Feb  1 21:10:00 vbox-linux rims-daemon[3191]: start daemon.\n    Feb  1 21:10:00 vbox-linux rims-daemon[3191]: run server process: 3194\n\nTo see log of server process, watch imap.log at local directory. Type\nfollowing on your console.\n\n    $ tail -f imap.log\n    I, [2015-02-01T21:10:00.989859 #3194]  INFO -- : start server.\n    I, [2015-02-01T21:10:00.990084 #3194]  INFO -- : open socket: 0.0.0.0:imap2\n    I, [2015-02-01T21:10:00.990989 #3194]  INFO -- : opened: [AF_INET][143][0.0.0.0][0.0.0.0]\n    I, [2015-02-01T21:10:00.991393 #3194]  INFO -- : process ID: 3194\n    I, [2015-02-01T21:10:00.991615 #3194]  INFO -- : process privilege user: toki(1000)\n    I, [2015-02-01T21:10:00.991703 #3194]  INFO -- : process privilege group: toki(1000)\n\nRIMS daemon process can be controlled from command line tool. Defined\noperations are start, stop, restart and status. Start operation is\nalready described.\n\nStop operation:\n\n    $ sudo bundle exec rims daemon stop -f config.yml\n\nRestart operation:\n\n    $ sudo bundle exec rims daemon restart -f config.yml\n\nStatus operation:\n\n    $ sudo bundle exec rims daemon status -f config.yml\n    daemon is running.\n\n    $ sudo bundle exec rims daemon status -f config.yml\n    daemon is stopped.\n\nServer Configuration\n--------------------\n\nServer options on start may be described at config.yml file.\nConfig.yml is a YAML format file and its contents are explained\nat later.\n\nTo start server with config.yml file, type following.\n\n    $ bundle exec rims server -f a_server_directory/config.yml\n\n### Config.yml Parameters\n\n\u003cdl\u003e\n  \u003cdt\u003ebase_dir\u003c/dt\u003e\n  \u003cdd\u003eThis parameter describes a base directory of server. Mailbox\n  data is located at inside of base directory. Default is a parent\n  directory of config.yml file. Explicit description of this parameter\n  is interpreted as a relative path from a parent directory of\n  config.yml file.\u003c/dd\u003e\n\n  \u003cdt\u003elog_stdout\u003c/dt\u003e\n  \u003cdd\u003eThis parameter describes a severity level of logging messages\n  that is written to standard output.  See description of Logger class\n  for more detail of logging. This parameter is one value selected\n  from DEBUG, INFO, WARN, ERROR or FATAL. If QUIET value is chosen,\n  standard output logging is disabled. Default is INFO. The danger is\n  that password may be embedded in message on user authentication in\n  DEBUG logging level.\u003c/dd\u003e\n\n  \u003cdt\u003elog_file\u003c/dt\u003e\n  \u003cdd\u003eThis parameter describes a path of log file. Default is\n  \"imap.log\" under the base_dir. Explicit description of this\n  parameter is interpreted as a relative path from a base_dir.\u003c/dd\u003e\n\n  \u003cdt\u003elog_level\u003c/dt\u003e\n  \u003cdd\u003eThis parameter describes a severity level of logging\n  messages. See description of Logger class for more detail of\n  logging. This parameter is one value selected from DEBUG, INFO,\n  WARN, ERROR or FATAL. Default is INFO. The danger is that password\n  may be embedded in message on user authentication in DEBUG logging\n  level.\u003c/dd\u003e\n\n  \u003cdt\u003elog_shift_age\u003c/dt\u003e\n  \u003cdd\u003eThis parameter describes a number of old rotated log files to\n  keep or periodical log rotation. Decimal number is interpreted as a\n  number of files to keep. Periodical log rotation is one value\n  selected from daily, weekly or monthly. Default is none. See\n  description of Logger.new class method for more detail of log\n  rotation.\u003c/dd\u003e\n\n  \u003cdt\u003elog_shift_size\u003c/dt\u003e\n  \u003cdd\u003eThis parameter describes a maximum log file size on log file\n  rotation. Default is none. See description of Logger.new class\n  method for more detail of log rotation.\u003c/dd\u003e\n\n  \u003cdt\u003ekey_value_store_type\u003c/dt\u003e\n  \u003cdd\u003eThis parameter describes a type of key-value store. Key-value\n  store is used to save a mailbox data. This parameter is only one\n  value of GDBM, and it is default value.\u003c/dd\u003e\n\n  \u003cdt\u003euse_key_value_store_checksum\u003c/dt\u003e\n  \u003cdd\u003eThis parameter decides whether to use checksum. This parameter\n  is boolean, true or false. If this parameter is true, a mailbox data\n  is saved with its checksum to an entry of key-value store, and a\n  checksum is checked on loading a mailbox data from an entry of\n  key-value store. Default is true.\u003c/dd\u003e\n\n  \u003cdt\u003ehostname\u003c/dt\u003e\n  \u003cdd\u003eThis parameter describes a hostname of server. Default is the\n  name displayed by hostname(1) command.\u003c/dd\u003e\n\n  \u003cdt\u003eusername\u003c/dt\u003e\n  \u003cdd\u003eThis parameter describes a name of mailbox user. This parameter\n  and the next password parameter are the pair. If there are two or\n  many users, user_list parameter should be used instead of this\n  parameter. At least one user is need to start a server.\u003c/dd\u003e\n\n  \u003cdt\u003epassword\u003c/dt\u003e\n  \u003cdd\u003eThis parameter describes a password of mailbox user. This\n  parameter and the previous username parameter are the pair. If there\n  are two or many users, user_list parameter should be used instead of\n  this parameter. At least one user is need to start a server.\u003c/dd\u003e\n\n  \u003cdt\u003euser_list\u003c/dt\u003e\n  \u003cdd\u003eThis parameter describes many users of mailbox. The value of\n  this parameter is a sequence of maps. A map in the sequence should\n  have two entries, the two entries are user and pass. user entry\n  describes name of a user. pass entry describes password of a\n  user. At least one user is need to start a server.\u003c/dd\u003e\n\n  \u003cdt\u003eimap_host\u003c/dt\u003e\n  \u003cdd\u003eThis parameter describes hostname or IP address of a server\n  socket to listen(2) and accept(2). Default is 0.0.0.0.\u003c/dd\u003e\n\n  \u003cdt\u003eimap_port\u003c/dt\u003e\n  \u003cdd\u003eThis parameter describes IP port number or service name of a\n  server socket to listen(2) and accept(2). Default is 1430.\u003c/dd\u003e\n\n  \u003cdt\u003email_delivery_user\u003c/dt\u003e\n  \u003cdd\u003eThis parameter describes a special user to deliver mail to any\n  user. Password definition of this special user is same to a normal\n  user. Default is \"#postman\".\u003c/dd\u003e\n\n  \u003cdt\u003eprocess_privilege_user\u003c/dt\u003e\n  \u003cdd\u003eThis parameter describes a privilege user name or ID for server\n  process.  When server process starts on root user, setuid(2) is\n  called and server process privilege user is changed from root user\n  to this parameter user.  Default is 65534 (typical user ID of\n  nobody) and should be changed.\u003c/dd\u003e\n\n  \u003cdt\u003eprocess_privilege_group\u003c/dt\u003e\n  \u003cdd\u003eThis parameter describes a privilege group name or ID for server\n  process.  When server process starts on root user, setgid(2) is\n  called and server process privilege group is changed from root group\n  to this parameter group.  Default is 65534 (typical group ID of\n  nogroup) and should be changed.\u003c/dd\u003e\n\u003c/dl\u003e\n\nMailbox Data\n------------\n\nMailbox data exists under the base directory. Next picture is a\noverview of mailbox data filesystem under the base directory.\n\n    a_base_directory\n    |\n    +-- mailbox.2/\n        |\n        +-- 2c/\n            |\n            +-- 26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae/\n                |\n                +-- message\n                |\n                +-- meta\n                |\n                +-- mailbox_1\n                |\n                +-- mailbox_2\n                |\n                ...\n\nThere is a MAILBOX\\_DATA\\_STRUCTURE\\_VERSION directory under first\ninside of the base directory.  When mailbox data structure will be\nchanged in future, MAILBOX\\_DATA\\_STRUCTURE\\_VERSION directory will be\nchanged too.  Now latest version is \"mailbox.2\".\n\nThere are user directories under the MAILBOX\\_DATA\\_STRUCTURE\\_VERSION\ndirectory.  A user is identified by unique user ID.  Unique user ID is\na SHA256 HEX digest of a username.  For example, type following to\ndisplay a \"foo\" user's unique user ID.\n\n    $ bundle exec rims unique-user-id foo\n    2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae \n\nFirst two characters of unique user ID is used as a bucket directory.\nUnique user ID substring from 3rd character to last exists as a user\ndirectory under the bucket directory.  Shortcut tool to search a two\nlevel directory of a user under a base directory exists.  For example,\ntype following to display a \"foo\" user's directory.\n\n    $ bundle exec rims show-user-mbox a_base_directory foo\n    a_base_directory/mailbox.2/2c/26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae\n\nThere are three types of files under the user directory.  Three types\nare message, meta and mailbox.  Each file is key-value store.  Only\none type of key-value store is available now, it is GDBM.  A GDBM\nkey-value store file has a filename suffix, the suffix is \".gdbm\".\nMailbox data does not depend on a specific type of key-value store.\n\n### Message key-value store\n\nMessage key-value store file preserves all messages of a user.  Per\none user, only one file exists about this file type.  Contents of\nmessage key-value store is simple.  A key is a message ID, and a value\nis message text.  A message ID is a unique number of a message in RIMS\ninternal.  For example, type following to see overview of contents at\na message key-value store.\n\n    $ bundle exec rims debug-dump-kvs --dump-size --no-dump-value a_base_directory/mailbox.2/2c/26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae/message\n    \"2\": 21938 bytes\n    \"1\": 126014 bytes\n    \"4\": 22928 bytes\n    \"0\": 6326 bytes\n    \"3\": 65168 bytes\n\n### Meta key-value store\n\nMeta key-value store file preserves all meta data of message and\nfolders.  Per one user, only one file exists about this file type.\nContents of meta key-value store is complex, and only outline of\ncontent is described here.\n\n\u003cdl\u003e\n  \u003cdt\u003edirty\u003c/dt\u003e\n  \u003cdd\u003eDirty flag. If enabled, this flag exists. If disabled, this flag\n  doesn't exists. This flag will be enabled on updating mailbox\n  data.\u003c/dd\u003e\n\n  \u003cdt\u003ecnum\u003c/dt\u003e\n  \u003cdd\u003eA change number of mailbox data. If mailbox data is modified,\n  this number is increased.\u003c/dd\u003e\n\n  \u003cdt\u003emsg_id\u003c/dt\u003e\n  \u003cdd\u003eThe next number of message ID. Message ID is unique number of\n  message in RIMS internal.\u003c/dd\u003e\n\n  \u003cdt\u003euidvalidity\u003c/dt\u003e\n  \u003cdd\u003eThe next number of uidvalidity. Uidvalidity is unique number of\n  mailbox in IMAP.\u003c/dd\u003e\n\n  \u003cdt\u003embox_set\u003c/dt\u003e\n  \u003cdd\u003eMailbox set of a user.\u003c/dd\u003e\n\n  \u003cdt\u003embox_id2name-#\u003c/dt\u003e\n  \u003cdd\u003eMapping from mailbox ID to mailbox name.\u003c/dd\u003e\n\n  \u003cdt\u003embox_name2id-#\u003c/dt\u003e\n  \u003cdd\u003eMapping from mailbox name to mailbox ID.\u003c/dd\u003e\n\n  \u003cdt\u003embox_id2uid-#\u003c/dt\u003e\n  \u003cdd\u003eThe next uid at a mailbox. Uid is unique number of message at a\n  mailbox in IMAP.\u003c/dd\u003e\n\n  \u003cdt\u003embox_id2msgnum-#\u003c/dt\u003e\n  \u003cdd\u003eNumber of messages at a mailbox.\u003c/dd\u003e\n\n  \u003cdt\u003embox_id2flagnum-#-#\u003c/dt\u003e\n  \u003cdd\u003eNumber of flags at a mailbox.\u003c/dd\u003e\n\n  \u003cdt\u003emsg_id2date-#\u003c/dt\u003e\n  \u003cdd\u003eMapping from message ID to internal date of a message. Internal\n  date is a message attribute in IMAP.\u003c/dd\u003e\n\n  \u003cdt\u003emsg_id2flag-#\u003c/dt\u003e\n  \u003cdd\u003eSet of flags at a message.\u003c/dd\u003e\n\n  \u003cdt\u003emsg_id2mbox-#\u003c/dt\u003e\n  \u003cdd\u003eMapping from message ID to mailbox's uid.\u003c/dd\u003e\n\u003c/dl\u003e\n\nFor example, type following to see overview of contents at a meta key-value store.\n\n    $ bundle exec rims debug-dump-kvs a_base_directory/mailbox.2/2c/26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae/meta\n    \"msg_id2mbox-3\": 25 bytes: {1=\u003e#\u003cSet: {4}\u003e}\n    \"msg_id2date-2\": 49 bytes: 2013-11-08 13:34:10 +0900\n    \"mbox_id2uid-1\": 1 bytes: \"6\"\n    \"msg_id2mbox-1\": 25 bytes: {1=\u003e#\u003cSet: {2}\u003e}\n    \"msg_id2flag-2\": 6 bytes: \"recent\"\n    \"mbox_id2msgnum-1\": 1 bytes: \"5\"\n    \"uidvalidity\": 1 bytes: \"2\"\n    \"mbox_id2flagnum-1-recent\": 1 bytes: \"5\"\n    \"msg_id2date-0\": 49 bytes: 2013-11-08 06:47:50 +0900\n    \"cnum\": 1 bytes: \"6\"\n    \"msg_id2date-4\": 49 bytes: 2013-11-08 11:57:28 +0900\n    \"msg_id2mbox-2\": 25 bytes: {1=\u003e#\u003cSet: {3}\u003e}\n    \"mbox_set\": 1 bytes: \"1\"\n    \"msg_id2flag-0\": 6 bytes: \"recent\"\n    \"msg_id2flag-4\": 6 bytes: \"recent\"\n    \"msg_id2date-1\": 49 bytes: 2013-11-08 19:31:03 +0900\n    \"msg_id\": 1 bytes: \"5\"\n    \"mbox_id2name-1\": 5 bytes: \"INBOX\"\n    \"msg_id2mbox-0\": 25 bytes: {1=\u003e#\u003cSet: {1}\u003e}\n    \"mbox_name2id-INBOX\": 1 bytes: \"1\"\n    \"msg_id2mbox-4\": 25 bytes: {1=\u003e#\u003cSet: {5}\u003e}\n    \"msg_id2flag-1\": 6 bytes: \"recent\"\n    \"msg_id2date-3\": 49 bytes: 2013-11-08 12:47:17 +0900\n    \"msg_id2flag-3\": 6 bytes: \"recent\"\n\n### Mailbox key-value store\n\nMailbox key-value store file preserves key-value pairs of uid and\nmessage ID.  Per one user, plural files exist about this type of file\nbecause plural mailboxes are allowed at one user.  Mailbox key-value\nstore filenames are \"mailbox\\_1\", \"mailbox\\_2\", ...  And 1,2,... are\nmailbox ID.  Contents of mailbox key-value store is simple.  A key is\na uid, and a value is message ID.  A uid is a unique number of a\nmessage in a mailbox in IMAP.  A message ID is a unique number of a\nmessage in RIMS internal.  For example, type following to see overview\nof contents at a mailbox key-value store.\n\n    $ bundle exec rims debug-dump-kvs a_base_directory/mailbox.2/2c/26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae/mailbox_1\n    \"2\": 1 bytes: \"1\"\n    \"5\": 1 bytes: \"4\"\n    \"1\": 1 bytes: \"0\"\n    \"4\": 1 bytes: \"3\"\n    \"3\": 1 bytes: \"2\"\n\nContributing\n------------\n\n1. Fork it\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create new Pull Request\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fy10k%2Frims","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fy10k%2Frims","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fy10k%2Frims/lists"}