Warning, /pim/trojita/docs/user-spec.txt is written in an unsupported language. File is not indexed.
0001 The trojita IMAP Client 0002 ----------------------- 0003 0004 What is it? 0005 ----------- 0006 0007 At the time I started to work with e-mail on a more advanced level than a free 0008 e-mail provider could offer, my quest for an advanced and standards-compliant 0009 "Mail Client" (MUA) begun. At first, I have no idea about various mail-related 0010 protocols, but during the process, I learned the meaning of abbreviations like 0011 SMTP, POP and IMAP. As I'm a fan of open solutions, I have immediately put 0012 proprietary protocols out of consideration. This left me with essentially just 0013 two choices for accessing my mail collection, either POP3 or IMAP4. 0014 0015 POP3 is an older protocol. While it certainly has its advantages (it's really 0016 simple to implement, for one), it wasn't designed for managing mail from 0017 multiple places, and it doesn't really support multiple mailboxes. As I used to 0018 read my e-mails from at least four computers, I went on and had a closer look on 0019 the only remaining protocol, the IMAP4. 0020 0021 Unlike POP, which was designed for retrieval of messages and wasn't designed 0022 for use-cases where they remain on the central server, the IMAP is built in a 0023 server-centric way. The only place where the messages are kept permanently is 0024 the IMAP server. The protocol, defined in RFC 3501, offers a rich suite of 0025 commands for both data access and data manipulation. It is no longer needed to 0026 download a whole 5MB mail that has three lines of text and a JPEG attachment 0027 just because you wanted to see the text. IMAP offers a comprehensive set of 0028 commands for determining message structure, partial message retrieval and even 0029 server-side message sorting based on message threading. 0030 0031 This power of IMAP is, however, often not exploited by today's IMAP clients. In 0032 fact, most of them are just dumb POP-clients upgraded to speak the IMAP 0033 language. Such clients are more vulnerable to various attacks (one 0034 badly-formatted mail is parsed not only by the IMAP server, but then by the MUA 0035 again, increasing the risk of buffer overflows and other security-related issue) 0036 and are also wasting system resources. 0037 0038 The aim of the trojita MUA is to create a nice and efficient IMAP-only mail 0039 client that makes use of advanced concepts found in the IMAP protocol (and 0040 its numerous extensions) and in modern programming libraries. If I create a 0041 tool for working with mail that I find comfortable, then I'll call trojita a 0042 success. 0043 0044 0045 Use cases 0046 --------- 0047 0048 Connecting to an IMAP server, working with mailboxes ("folders") and messages 0049 contained therein. Being able to display as many data formats as possible and 0050 convenient, while staying secure (beware of HTML stuff with remote images etc). 0051 Support for various forms of cryptographic contents (X.509 and PGP 0052 signatures/encrypted messages) is planned for later releases. Being able to 0053 compose mail (again, with the cryptographic stuff) and send it either via a SMTP 0054 connection or possibly through a local sendmail-compatible interface. Being 0055 able to utilize a not-so-common way of talking to the IMAP server via a UNIX 0056 pipe (handy for IMAP-over-SSH for example). 0057 0058 0059 Goals 0060 ----- 0061 0062 Respecting all related RFC standards. Using the IMAP protocol in an efficient 0063 way. Making use of convenient and effective programming technologies and modern 0064 libraries. Being cross-platform friendly, providing a graphical user interface. 0065 Utilizing a unit-testing framework for early regressions detection. 0066 0067 0068 Technologies used 0069 ----------------- 0070 0071 Due to the emphasis on modern libraries, portability and the joy of programming, 0072 I've chosen the Qt library. When combined with the C++ STL, it provides an 0073 extremely rich toolbox that is essential for writing large applications in a 0074 pleasant way. 0075 0076 0077 Overview 0078 -------- 0079 0080 On the very lowest layer of trojita, we can find the library that handles the 0081 low-level layer of the IMAP protocol. It is used to parse bytes flowing from 0082 the IMAP server to slightly higher objects like "atoms", "strings", "numbers" 0083 and "lists". It is pretty simple and can be found in the Imap::LowLevelParser 0084 namespace (files Imap/LowLevelParser.* with corresponding unit tests in 0085 test/test_Imap_LowLevelParser.* ). 0086 0087 Building on the top of the Low Level Parser, we find the Parser. It is the 0088 point of interaction with the IMAP server. It is being fed with IMAP commands 0089 (via calling the appropriate member functions of the Imap::Parser class 0090 instance) and emits Qt signals when it receives and parses a response from the 0091 server. 0092 0093 (Due to the nature of C++, where working with virtual functions de facto 0094 forces the programmer to use pointers or references, this layer makes heavy use 0095 of the std::tr1::shared_ptr template as defined in the Technical Report 1. The 0096 build system of trojita tries to use system-provided tr1/memory header, but will 0097 fall back to the one provided by Boost in case the system compiler doesn't 0098 support the TR1.) 0099 0100 So, now we have an interface that we can feed with IMAP commands and which 0101 returns us parsed data back. This is how a typical conversation looks like: 0102 0103 me: perform the SELECT operation on mailbox INBOX 0104 parser: queued as command y001 0105 imap: response: total message count, number: 18 0106 imap: response: defined flags, list: (\Answered \Recent \Deleted \Seen \Draft) 0107 imap: response: # of recent messages, number: 2 0108 imap: untagged reply: OK, response: first unseen message, number: 13 0109 imap: untagged reply: OK, response: UIDVALIDITY, number: 1337666 0110 imap: command y001 completed successfully, message: bla bla bla 0111 me: give me the envelope of the 12th message in this mailbox 0112 imap: ... 0113 0114 While this is certainly cool feature, it isn't really useful for humans. We 0115 usually prefer to see a nice graphical list of messages that we can click at, 0116 shuffle them around and otherwise mess with them, and we want that window with a 0117 quoted text to appear when we click the "reply" button. Here's where the next 0118 layer comes in. 0119 0120 We have a choice to make here -- either we can use a traditional IMAP-like 0121 approach and treat mailboxes as a completely separated hierarchy, or we can 0122 deal with the IMAP server as a whole. The former is what older development 0123 versions (as of end of May 2008) used, the latter is what the Right Thing (TM) 0124 is :). In this new approach, there's only one tree-like model representing all 0125 mailboxes on the IMAP server, as one user sees it. All views interact with this 0126 huge model only, and each of these views might be tied to a subtree of the whole 0127 model. 0128 0129 While this design choice has numerous advantages (like simplified sharing of 0130 Parser instances, which in turn enables working with servers that don't 0131 particularly like dozens of open connections per one user), it has to be 0132 carefully thought-out before implementation. In the following, we'll discuss 0133 how we employ the whole Interview framework of Qt in trojitá. 0134 0135 There's only one top-level item in our view. 0136 0137 Children of this top-level item represent mailbox hierarchy, possibly in 0138 different namespaces (a namespace is a term from IMAP, see RFC 3501 for 0139 details). A mailbox can hold number of other mailboxes (properly nested), or a 0140 list of messages, or a combination of thereof. 0141 0142 A message itself is hierarchically structured. The structure matches closely 0143 the MIME structure of the real email message. In addition, there are some 0144 metadata (like IMAP flags or envelope) that are also part of the message 0145 representation in the view. 0146 0147 This scenario has a problem that needs to be solved -- if a mailbox can contain 0148 both messages and other mailboxes, how does one distinguish among them? 0149 0150 The purpose of the Imap::Mailbox::Model is to provide a nice high-level 0151 overview of an IMAP mailbox. This is implemented using a standard Qt 0152 model-view-architecture interface. This means that it is extremely easy to add 0153 a graphical view to the application, as the Qt library already provides one. 0154 The idea here is that all the views could be extremely stupid (they indeed are), 0155 and all the IMAP logic like caching is to be provided by the lower layers. 0156 0157 FIXME: describe (and implement :) ) Imap::Mailbox::Cache and 0158 (yet-to-be-thought-about) Imap::Mailbox::ParserPool for multiplexing of Parsers 0159 among multiple Models.