1 % ssoma_repository(5) ssoma user manual
5 ssoma_repository - repository and tree description for ssoma
9 ssoma uses a git repository to store each email as a git blob. The tree
10 filename of the blob is based on the SHA1 hexdigest of the Message-ID
11 header. A commit is made for each message delivered. The commit SHA-1
12 identifier is used by ssoma clients to track synchronization state.
14 =head1 PATHNAMES IN TREES
16 A Message-ID may be extremely long and also contain slashes, so using
17 them as a path name is challenging. Instead we use the SHA-1 hexdigest
18 of the Message-ID (excluding the leading "E<lt>" and trailing "E<gt>")
19 to generate a path name. Leading and trailing white space in the
20 Message-ID header is ignored for hashing.
22 A message with Message-ID of: E<lt>20131106023245.GA20224@dcvr.yhbt.netE<gt>
24 Would be stored as: f2/8c6cfd2b0a65f994c3e1be266105413b3d3f63
26 Thus it is easy to look up the contents of a message matching a given
31 Message-ID is a unique-enough identifier for practical purposes, but
32 they may still conflict (especially in case of malicious clients and
33 timing issues). In the case of identical Message-ID and different
34 messages, the blob shall become a tree with multiple messages.
35 Likewise, if there is a (rare) SHA-1 conflict on different Message-ID
36 headers, the tree will contain each message (with different Message-ID
39 Thus the blobs for conflicting Message-IDs will be the SHA-1 hexdigest
40 of the Subject header and raw body (no extra whitespace delimiting the
43 PFX=21/4527ce3741f50bb9afa65e7c5003c8a8ddc4b1
45 $PFX/287d8b67bf8ebdb30e34cb4ca9995dbd465f37aa # first copy
46 $PFX/287d8b67bf8ebdb30e34cb4ca9995dbd465f37ab # second copy
47 $PFX/287d8b67bf8ebdb30e34cb4ca9995dbd465f37ac # third copy
49 Note: public-inbox currently uses "ssoma-mda -1" to disable this
50 conflict resolution feature. This simplifies the implementation
51 and use of public-inbox.
55 The Message-ID (case-insensitive) header is required.
56 "Bytes", "Lines" and "Content-Length" headers are stripped and not
57 allowed, they can interfere with further processing.
58 When using ssoma with public-inbox-mda, the "Status" mbox header
59 is also stripped as that header makes no sense in a public archive.
63 L<flock(2)> locking exclusively locks the empty $GIT_DIR/ssoma.lock file
64 for all non-atomic operations.
66 =head1 EXAMPLE INPUT FLOW (SERVER-SIDE MDA)
68 1. Message is delivered to a mail transport agent (MTA)
70 1a. (optional) reject/discard spam, this should run before ssoma-lda
72 1b. (optional) reject/strip unwanted attachments
74 ssoma-mda handles all steps once invoked.
76 2. Mail transport agent invokes ssoma-mda
78 3. reads message via stdin, extracting Message-ID
80 4. acquires exclusive flock lock on $GIT_DIR/ssoma.lock
82 5. creates or updates the blob of associated 2/38 SHA-1 path
84 6. updates the index and commits
86 7. releases $GIT_DIR/ssoma.lock
88 ssoma-mda can also be used as an L<inotify(7)> trigger to monitor maildirs,
89 and the ability to monitor IMAP mailboxes using IDLE will be available
92 =head1 GIT REPOSITORIES (SERVERS)
94 ssoma uses bare git repositories on both servers and clients.
96 Using the L<git-init(1)> command with --bare is the recommend method
97 of creating a git repository on a server:
99 git init --bare /path/to/wherever/you/want.git
101 There are no standardized paths for servers, administrators make
102 all the choices regarding git repository locations.
104 Special files in $GIT_DIR on the server:
108 =item $GIT_DIR/ssoma.index
110 A git index file used for MDA updates.
111 The normal git index (in $GIT_DIR/index) is not used at all as
112 there is typically no working tree.
114 =item $GIT_DIR/ssoma.lock
116 An empty file for L<flock(2)> locking.
117 This is necessary to ensure the index and commits are updated
118 consistently and multiple processes running MDA do not step on
123 =head1 GIT REPOSITORIES (CLIENTS)
125 ssoma uses bare git repositories for clients (as well as servers).
127 The default is to use GIT_DIR=~/.ssoma/$LISTNAME.git in the user's home
128 directory. This is a bare git repository with two additional files:
132 =item $GIT_DIR/ssoma.lock
134 empty lock file, same as used by L<ssoma-mda(1)>
136 =item $GIT_DIR/ssoma.state
138 a L<git-config(1)> format file used by L<ssoma(1)>
142 Each client $GIT_DIR may have multiple mbox/maildir/command targets.
143 It is possible for a client to extract the mail stored in the git
144 repository to multiple mboxes for compatibility with a variety of
147 =head1 $GIT_DIR/ssoma.state format
149 ; "local" is the default name (analogous to "origin" with remotes)
153 ; this tells ssoma where to start the next import from
154 ; this means ssoma will not redundantly import old
155 ; messages and the user is free to move/delete old
156 ; messages from the mbox.
157 last-imported = 33eaf25f43fd73d8f4f7b0a066b689809d733191
159 ; "alt" is a user-defined name, in case a user wants to output
160 ; the repo in several formats
162 ; note the trailing '/' to denote the maildir path,
163 ; the Email::LocalDelivery Perl module depends on this
164 ; trailing slash to identify it as a maildir
165 path = /path/to/maildir/
166 last-imported = 950815b313a4e616c6fe39f46b2e894b51d7d62f
168 ; users may also choose to pipe to an arbitrary command of their
169 ; choice, this filter may behave like an MDA (and implement
170 ; filtering). Tools like procmail(1)/maildrop(1) may be
173 command = /path/to/executable/which/reads-mail-from-stdin
174 last-imported = 950815b313a4e616c6fe39f46b2e894b51d7d62f
176 =head1 EXAMPLE OUTPUT FLOW (CLIENT)
178 1. clone or fetches to bare git repo (GIT_DIR=~/.ssoma/$LISTNAME.git)
180 2. checks for last-imported commit in ~/.ssoma/$LISTNAME.git/ssoma.state
182 3. diffs last-imported commit with current HEAD
184 4. imports new emails to mbox/maildir since last-imported up to current HEAD
186 5. updates last-imported commit
190 It is NOT recommended to check out the working directory of a git.
191 there may be many files.
193 It is impossible to completely expunge messages, even spam, as git
194 retains full history. Projects may (with adequate notice) cycle to new
195 repositories/branches with history cleaned up via L<git-filter-branch(1)>.
196 This is up to the administrators.
200 Copyright 2013-2016 all contributors L<lt>meta@public-inbox.orgE<gt>
202 License: AGPL-3.0+ L<http://www.gnu.org/licenses/agpl-3.0.txt>
206 L<gitrepository-layout(5)>, L<ssoma(1)>