bincimap

Log | Files | Refs | LICENSE

bincimap-tech.html (17972B)


      1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
      2 <HTML>
      3 
      4 <HEAD>
      5   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
      6   <META HTTP-EQUIV="Content-Language" CONTENT="en">
      7 
      8   <TITLE>Binc IMAP - Technical Documentation</TITLE>
      9   <META NAME="revisit-after" CONTENT="14 days">
     10   <META NAME="keywords" CONTENT="Binc IMAP technical documentation checkpassword daemontools tcpserver xinetd Maildir qmail">
     11   <META NAME="description" CONTENT="Andreas Aardal Hanssen">
     12   <META NAME="copyright" CONTENT="Copyright Andreas Aardal Hanssen 2002, 2003">
     13   <META NAME="distribution" CONTENT="global">
     14   <META NAME="author" CONTENT="Andreas Aardal Hanssen">
     15   <LINK REL="stylesheet" HREF="bincimap.css" TYPE="text/css">
     16   <LINK REL="icon" HREF="/favicon.ico" TYPE="image/ico">
     17   <LINK REL="shortcut icon" HREF="/favicon.ico">
     18 
     19 </HEAD>
     20 
     21 <BODY BGCOLOR="#000000">
     22 
     23 <TABLE WIDTH="95%" ALIGN="CENTER" CELLSPACING="0" CELLPADDING="4">
     24 <TR>
     25 <TD BGCOLOR="#004444">
     26 
     27 <TABLE WIDTH="99%" ALIGN="CENTER" CELLSPACING="0" CELLPADDING="4">
     28   <TR>
     29     <TD CLASS="headtext" BGCOLOR="#226666" ALIGN="LEFT">
     30       <TABLE>
     31         <TR>
     32           <TD ALIGN="center" VALIGN="middle"><IMG ALT="Binc IMAP logo" SRC="b-button64.png" BORDER="0"></TD>
     33           <TD ALIGN="center" VALIGN="middle">Binc IMAP - Technical Documentation</TD>
     34         </TR>
     35       </TABLE>
     36     </TD>
     37     <TD CLASS="bodytext" BGCOLOR="#226666" ALIGN="RIGHT">
     38         <A HREF="http://www.gnu.org/licenses/gpl.html">GNU General Public License</A><BR>
     39         Andreas Aardal Hanssen &lt;andreas@hanssen.name&gt;
     40     </TD>
     41   </TR>
     42   <TR>
     43     <TD CLASS="bodytext" BGCOLOR="#FFFFFF" COLSPAN="2"></TD>
     44   </TR>
     45 </TABLE>
     46 
     47 <DIV CLASS="bodytext">
     48 
     49 <P><U><B>Binc in my home area, IMAPdir and cousins</B></U></P>
     50 
     51 <BLOCKQUOTE>
     52 
     53 <P>Binc IMAP uses either <A
     54 HREF="http://www.inter7.com/courierimap/README.maildirquota.html">Maildir++</A>
     55 or a structure called <A HREF="bincimap-imapdir.html">IMAPdir</A> to
     56 store its set of mailboxes. <A
     57 HREF="bincimap-imapdir.html">IMAPdir</A> is more or less similar to <A
     58 HREF="http://www.inter7.com/courierimap/README.maildirquota.html">Maildir++</A>,
     59 but it provides more flexibility with regards to mailbox names and
     60 hierarchy structure.</P>
     61 
     62 <P>In a sense, <A HREF="bincimap-imapdir.html">IMAPdir</A> takes all
     63 the goods from <A
     64 HREF="http://cr.yp.to/proto/maildir.html">Maildir</A> and adds root
     65 level mailboxes, submailboxes both of regular root level mailboxes and
     66 of the special mailbox INBOX, mail in mailboxes of any level, and with
     67 no restrictions.</P>
     68 
     69 <P>In the root of the <A HREF="bincimap-imapdir.html">IMAPdir</A>
     70 structure, Binc IMAP stores the list of a user's subscribed folders in
     71 a file called
     72 <B>bincimap-subscribed</B>. This file should only be edited manually
     73 if you are confident with <B>Binc::Storage</B>. Normally the
     74 administrator and the IMAP user will leave this to Binc IMAP.</P>
     75 
     76 <P>Binc IMAP's <A
     77 HREF="http://cr.yp.to/proto/maildir.html">Maildir</A> backend
     78 (default) will temporarily create a lock file called
     79 <B>bincimap-scan-lock</B> inside a <A
     80 HREF="http://cr.yp.to/proto/maildir.html">Maildir</A> when it is
     81 scanning for mailbox changes and delegating unique message
     82 identifiers. This is to ensure that UIDs are delegated exactly once to
     83 every message that has been detected by any one Binc IMAP server
     84 instance.</P>
     85 
     86 <P>Inside each <A
     87 HREF="http://cr.yp.to/proto/maildir.html">Maildir</A>, Binc IMAP
     88 stores two files that allow multiple instances of the server to
     89 communicate the state and changes of the mailbox:
     90 <B>bincimap-uidvalidity</B> and
     91 <B>bincimap-cache</B>. These files are safe to delete, although that
     92 will trigger UIDVALIDITY to bounce and clients may have to
     93 resynchronize their local state.</P>
     94 
     95 </BLOCKQUOTE>
     96 
     97 <P><U><B>Object Oriented Design: Brokers, Depots, Operators.</B></U></P>
     98 
     99 <BLOCKQUOTE>
    100 
    101 <TABLE WIDTH="100%">
    102   <TR>
    103     <TD VALIGN="TOP">
    104       <P>Binc IMAP's design is <I>simple</I> and <I>modular</I>. This
    105       makes it <I>easy</I> to maintain and extend.</P>
    106 
    107       <P>Although the IMAP protocol is relatively complex, you will
    108       find that Binc IMAP's solution is surprisingly easy to
    109       grasp.</P>
    110 
    111       <P>At the heart of Binc IMAP's implementation lies the basic
    112       functionality for Object Oriented Design provided by the ISO C++
    113       standard and general knowledge in the area of standard Design
    114       Patterns.</P>
    115 
    116       <P>The main components are:</P>
    117       
    118       <UL>
    119         <LI>The <A HREF="#Broker">Broker</A></LI>
    120         <LI>The <A HREF="#BrokerFactory">BrokerFactory</A></LI>
    121 	<LI>The <A HREF="#Command">Command</A></LI>
    122 	<LI>The <A HREF="#Depot">Depot</A></LI>
    123         <LI>The <A HREF="#DepotFactory">DepotFactory</A></LI>
    124 	<LI>The <A HREF="#Mailbox">Mailbox</A></LI>
    125         <LI>The <A HREF="#Operator">Operator</A></LI>
    126 	<LI>The <A HREF="#Session">Session</A></LI>
    127 	<LI>The <A HREF="#IO">IO</A></LI>
    128       </UL>
    129     </TD>
    130     <TD>
    131     <IMG BORDER="0" SRC="bincimap-design-tiny.png" ALT="Binc IMAP, Object Oriented Design">
    132     </TD>
    133   </TR>
    134 </TABLE>
    135 
    136 <HR>
    137 <A NAME="Broker"><B>Broker</B></A>
    138 
    139   <P>One <A HREF="#Broker">Broker</A> holds a set of <A
    140   HREF="#Operator">Operators</A>. For each
    141   <I>state</I> Binc IMAP is in, the <A
    142   HREF="#BrokerFactory">BrokerFactory</A> delegates exactly one <A
    143   HREF="#Broker">Broker</A> to hold the relevant <A
    144   HREF="#Operator">Operator</A> objects.</P>
    145 
    146   <P>Typically, an <A HREF="#Operator">Operator</A> can be assigned to
    147   more than one <A HREF="#Broker">Broker</A>. For example, the <A
    148   HREF="#Operator">Operator</A> that serves the IMAP command "NOOP" (a
    149   command that is available in all three IMAP <I>states</I>),
    150   <B>NoopOperator</B>, is available in all <A
    151   HREF="#Broker">Broker</A> objects.</P>
    152 
    153   <P>The <A HREF="#Broker">Broker</A> is responsible for first passing
    154   the <A HREF="#Depot">Depot</A> and the <A HREF="#IO">IO</A>
    155   singleton to the appropriate <A HREF="#Operator">Operator</A>,
    156   generating a <A HREF="#Command">Command</A> object.</P>
    157 
    158   <P>The <A HREF="#Broker">Broker</A> is also responsible for passing
    159   the resulting <A HREF="#Command">Command</A> object to the <A
    160   HREF="#Operator">Operator</A> together with the <A
    161   HREF="#Depot">Depot</A>, generating the <I>untagged responses</I>
    162   that come as a result of the processing.</P>
    163 
    164   <BR>
    165   <TABLE>
    166     <TR>
    167       <TD BGCOLOR="#555555">
    168         <PRE>
    169 Broker *broker = BrokerFactory.getBroker(STATE_SELECTED);
    170 if (broker != NULL)
    171   throw CriticalException("no broker for selected state");
    172 
    173 Command command;
    174 
    175 try {
    176   broker.parse(com, command);
    177   broker.process(depot, command);
    178 } catch (...
    179         </PRE>
    180       </TD>
    181     </TR>
    182   </TABLE>
    183 
    184 <HR>
    185 <A NAME="BrokerFactory"><B>BrokerFactory</B></A>
    186 
    187   <P>The <A HREF="#BrokerFactory">BrokerFactory</A> manages the <A
    188   HREF="#Broker">Broker</A> objects.</P>
    189 
    190   <P>Given a <I>state</I>, the <A
    191   HREF="#BrokerFactory">BrokerFactory</A> provides a <A
    192   HREF="#Broker">Broker</A> that holds all the <A
    193   HREF="#Operator">Operator</A> objects available to the client.</P>
    194 
    195   <P>This provides a modular and safe separation of the priviledges
    196   available at the different <I>states</I> in the IMAP session.</P>
    197 
    198   <P>The <I>preauthenticate stub</I> has a <A
    199   HREF="#BrokerFactory">BrokerFactory</A> that can only generate <A
    200   HREF="#Broker">Broker</A> objects for the <I>non-authenticated</I>
    201   state.</P>
    202 
    203 <HR>
    204 <A NAME="Command"><B>Command</B></A>
    205 
    206   <P>A <A HREF="#Command">Command</A> object holds all information
    207   that was passed to the <A HREF="#Operator">Operator</A> that served
    208   a specific IMAP command.</P>
    209 
    210   <P><A HREF="#Command">Command</A> objects are named. Examples of
    211   such names are "CHECK", "SUBSCRIBE" and "LOGOUT".</P>
    212 
    213   <P>For the name "FETCH", the <A HREF="#Command">Command</A> object
    214   is decorated with
    215   <I>sequence set</I>, optionally a <I>section</I> and so on. The
    216   <B>parse()</B> method in each <A HREF="#Operator">Operator</A> is
    217   responsible for decorating the <A HREF="#Command">Command</A>
    218   object.</P>
    219 
    220   <P>The <A HREF="#Command">Command</A> object is
    221   <I>short-lived</I>. It is created, decorated, passed on to the <A
    222   HREF="#Operator">Operator</A>, then discarded.</P>
    223 
    224 <HR>
    225 <A NAME="Depot"><B>Depot</B></A>
    226 
    227   <P>A <A HREF="#Depot">Depot</A> is responsible for handling the
    228   different <A HREF="#Mailbox">Mailbox</A> objects, and it is the
    229   mailbox structure authority.</P>
    230 
    231   <P>Given an IMAP mailbox path as input, a <A HREF="#Depot">Depot</A>
    232   can give the caller a corresponding <A HREF="#Mailbox">Mailbox</A>
    233   object if it finds one that successfully identifies the type of <A
    234   HREF="#Mailbox">Mailbox</A>.
    235 
    236   <P>The <A HREF="#Depot">Depot</A> is also aware of what the
    237   <I>default</I> <A HREF="#Mailbox">Mailbox</A> type object is. This
    238   <A HREF="#Mailbox">Mailbox</A> object is used when creating new IMAP
    239   mailboxes.</P>
    240 
    241   <P>Finally, the <A HREF="#Depot">Depot</A> is used to translate
    242   mailbox names to a representation on the file system and back. There
    243   are currently two specializations of the <A HREF="#Depot">Depot</A>
    244   object available: one for <A
    245   HREF="http://www.inter7.com/courierimap/README.maildirquota.html">Maildir++</A>
    246   and one for <A HREF="bincimap-imapdir.html">IMAPdir</A>. Each has
    247   its own characteristics in how do translate the mailbox hierarchy to
    248   the file system.</P>
    249 
    250   <TABLE>
    251     <TR>
    252       <TD BGCOLOR="#555555">
    253         <PRE>
    254 Mailbox *mailbox = depot.getDefaultMailbox();
    255 if (mailbox == NULL)
    256   throw CriticalException("no default mailbox provided");
    257 
    258 try {
    259   mailbox->imapCreate("work/2003/07/todo");
    260 } catch (...
    261         </PRE>
    262       </TD>
    263     </TR>
    264   </TABLE>
    265 
    266 <HR>
    267 <A NAME="DepotFactory"><B>DepotFactory</B></A>
    268 
    269   <P>The <A NAME="DepotFactory">DepotFactory</A> manages the <A
    270   HREF="#Depot">Depot</A> objects.</P>
    271 
    272   <P>New <A HREF="#Depot">Depot</A> objects are assigned to the <A
    273   NAME="DepotFactory">DepotFactory</A> in runtime. This makes it easy
    274   to add new <A HREF="#Depot">Depot</A> objects using loadable
    275   modules. The <A HREF="#Depot">Depot</A> objects are registered and
    276   accessed via their <I>names</I>, such as "<A
    277   HREF="http://www.inter7.com/courierimap/README.maildirquota.html">Maildir++</A>"
    278   or "<A HREF="bincimap-imapdir.html">IMAPdir</A>".</P>
    279 
    280   <P>The <A NAME="DepotFactory">DepotFactory</A> gives individual
    281   users of Binc IMAP the option to choose the <A
    282   HREF="#Depot">Depot</A> object that suits their needs the best.</P>
    283 
    284 <HR>
    285 <A NAME="IO"><B>IO</B></A>
    286 
    287   <P>The <A HREF="#IO">IO</A> is a <I>global</I>. It consists of two instances -
    288   <U>com</U> and <U>logger</U>.</P>
    289 
    290   <P><U>com</U> reads and writes characters to and from the client,
    291   and hides the optional SSL encryption.</P>
    292 
    293   <P><U>logger</U> writes characters to Binc IMAP's log files. It
    294   hides the method used to log data. Currently it supports logging to
    295   stderr and syslog.</P>
    296 
    297 <HR>
    298 <A NAME="Mailbox"><B>Mailbox</B></A>
    299 
    300   <P>The <A HREF="#Mailbox">Mailbox</A> is an abstract for Binc IMAP's different
    301   <I>backends</I>. Bundled with Binc is a backend for <A
    302   HREF="http://cr.yp.to/proto/maildir.html">Maildir</A>. The class
    303   Maildir <I>inherits</I> <A HREF="#Mailbox">Mailbox</A>.</P>
    304 
    305   <P>In short, a <A HREF="#Mailbox">Mailbox</A> contains all methods needed for Binc
    306   IMAP to serve a specific backend. It also holds a method to identify
    307   a <A HREF="#Mailbox">Mailbox</A> of its own kind.</P>
    308 
    309   <P>All registered <A HREF="#Mailbox">Mailbox</A> objects are held by the
    310   <A HREF="#Depot">Depot</A>.</P>
    311 
    312   <BR>
    313   <TABLE>
    314     <TR>
    315       <TD BGCOLOR="#555555">
    316         <PRE>
    317 Mailbox *mailbox = depot.getSelectedMailbox();
    318 if (mailbox == NULL)
    319   throw CriticalException("no selected mailbox in selected state");
    320 
    321 mailbox->imapExpunge();
    322 mailbox->imapClose();
    323         </PRE>
    324       </TD>
    325     </TR>
    326   </TABLE>
    327 
    328 <HR>
    329 <A NAME="Operator"><B>Operator</B></A>
    330 
    331   <P>An <A HREF="#Operator">Operator</A> is associated with an IMAP command such as
    332   "SEARCH" or "AUTHENTICATE". In short, the <A HREF="#Operator">Operator</A> is used to
    333   perform an arbitrary operation on a <A HREF="#Mailbox">Mailbox</A>.<P>
    334 
    335   <P>Typically, an <A HREF="#Operator">Operator</A> can be assigned to one or more
    336   <A HREF="#Broker">Broker</A> objects.
    337 
    338   <P>Operators contain, among others, the two public methods:
    339   <B>parse()</B> and <B>process()</B>.</P>
    340 
    341   <P>When given the <B>IO singleton</B> as input, the <B>parse()</B>
    342   method generates a <A HREF="#Command">Command</A> object. This object can then be
    343   fed to <B>process()</B> together with a <A HREF="#Depot">Depot</A>.</P>
    344 
    345   <P>When processing its command, an <A HREF="#Operator">Operator</A> is allowed to
    346   generate <I>untagged responses</I> and it can also update the
    347   <I>state</I> of a <A HREF="#Mailbox">Mailbox</A>, the <A HREF="#Depot">Depot</A> or the
    348   <A HREF="#Session">Session</A> singleton.</P>
    349 
    350   <P><A HREF="#Operator">Operator</A> objects are assigned
    351   <I>dynamically</I> to each <A HREF="#Broker">Broker</A>, making it
    352   very easy to write
    353   <I>extensions</I> that add or replace existing <A
    354   HREF="#Operator">Operator</A> objects using Binc IMAP's <I>loadable
    355   module support.</I></P>
    356 
    357 <HR>
    358 <A NAME="Session"><B>Session</B></A>
    359 
    360   <P>The <A HREF="#Session">Session</A> is a <I>singleton</I> object that holds
    361   information that is relevant to the current IMAP session.</P>
    362 
    363   <P>Currently, the <A HREF="#Session">Session</A> contains information about:</P>
    364 
    365   <UL>
    366   <LI>Global configuration (administrator settings)</LI>
    367   <LI>Local configuration (user settings)</LI>
    368   <LI>Command line arguments</LI>
    369   <LI>Folder subscription list</LI>
    370   </UL>
    371 
    372 <HR>
    373 
    374 <P>Last updated on <B>2003-03-20</B>.</P>
    375 
    376 <P>Please direct comments on this document to the <A
    377 HREF="/#mailinglist">Binc IMAP mailing list</A>. Remember to <I>search
    378 the archives</I> first.</P>
    379 
    380 </BLOCKQUOTE>
    381 
    382 <TABLE WIDTH="99%" ALIGN="CENTER" CELLSPACING="0" CELLPADDING="4">
    383   <TR>
    384     <TD CLASS="bodytext" BGCOLOR="#FFFFFF"></TD>
    385   </TR>
    386   <TR>
    387     <TD CLASS="headtext" BGCOLOR="#226666">
    388       <A HREF="http://validator.w3.org/check/referer">
    389         <IMG BORDER="0" SRC="http://www.w3.org/Icons/valid-html401"
    390          ALT="Valid HTML 4.01!" HEIGHT="31" WIDTH="88">
    391       </A>
    392       <A HREF="http://cr.yp.to/djbdns.html"><IMG BORDER="0" WIDTH="88"
    393       HEIGHT="31" SRC="djbdns.jpg" ALT="Powered by djbdns!"></A>
    394       <IMG BORDER="0" WIDTH="88" HEIGHT="30" SRC="binclogo.gif"
    395       ALT="Powered by Binc IMAP">
    396     </TD>
    397   </TR>
    398 </TABLE>
    399 
    400 </DIV>
    401 </TD>
    402 </TR>
    403 </TABLE>
    404 <BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>
    405 <BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>
    406 
    407 </BODY>
    408 </HTML>
    409 style with only LF. The MaildirMessage is an
    410   implementation of Message used in Maildir. When using a Maildir
    411   mailbox, Mailbox::iterator will return a reference to a
    412   MaildirMessage. MaildirMessage also uses a MaildirMessageCache
    413   singleton to handle cacheing of messages.</P>
    414 
    415   <P>Although the inside of MaildirMessage both deals with files,
    416   cacheing and MIME, the Operator needs not think about this.</P>
    417 
    418 </BLOCKQUOTE>
    419 
    420 <HR>
    421 <A NAME="Operator"><B>Operator</B></A>
    422 <BLOCKQUOTE>
    423 
    424   <P>An <A HREF="#Operator">Operator</A> is associated with an IMAP command such as
    425   "SEARCH" or "AUTHENTICATE". In short, the <A HREF="#Operator">Operator</A> is used to
    426   perform an arbitrary operation on a <A HREF="#Mailbox">Mailbox</A>.<P>
    427 
    428   <P>Typically, an <A HREF="#Operator">Operator</A> can be assigned to one or more
    429   <A HREF="#Broker">Broker</A> objects.
    430 
    431   <P>Operators contain, among others, the two public methods:
    432   <B>parse()</B> and <B>process()</B>.</P>
    433 
    434   <P>The <B>parse()</B> method decorates a <A
    435   HREF="#Request">Request</A> object. This object can then be fed to
    436   <B>process()</B> together with a <A HREF="#Depot">Depot</A>.</P>
    437 
    438   <P>When processing its request, an <A HREF="#Operator">Operator</A>
    439   is allowed to generate <I>untagged responses</I> and it can also
    440   update the <I>state</I> of a <A HREF="#Mailbox">Mailbox</A>, the <A
    441   HREF="#Depot">Depot</A> or the <A HREF="#Session">Session</A>
    442   singleton.</P>
    443 
    444   <P><A HREF="#Operator">Operator</A> objects are assigned
    445   <I>dynamically</I> to each <A HREF="#Broker">Broker</A>, making it
    446   very easy to write <I>extensions</I> that add or replace existing <A
    447   HREF="#Operator">Operator</A> objects using Binc IMAP's <I>loadable
    448   module support.</I></P>
    449 </BLOCKQUOTE>
    450 
    451 <HR>
    452 <A NAME="Session"><B>Session</B></A>
    453 <BLOCKQUOTE>
    454   <P>The <A HREF="#Session">Session</A> is a <I>singleton</I> object that holds
    455   information that is relevant to the current IMAP session.</P>
    456 
    457   <P>Currently, the <A HREF="#Session">Session</A> contains information about:</P>
    458 
    459   <UL>
    460     <LI>Global configuration (administrator settings)</LI>
    461     <LI>Local configuration (user settings)</LI>
    462     <LI>Command line arguments</LI>
    463     <LI>Folder subscription list</LI>
    464   </UL>
    465 </BLOCKQUOTE>
    466 
    467 <HR>
    468 
    469 <P>Last updated on <B>2003-07-31</B>.</P>
    470 
    471 <P>Please direct comments on this document to the <A
    472 HREF="/#mailinglist">Binc IMAP mailing list</A>. Remember to <I>search
    473 the archives</I> first.</P>
    474 
    475 </BLOCKQUOTE>
    476 
    477 <TABLE WIDTH="99%" ALIGN="CENTER" CELLSPACING="0" CELLPADDING="4">
    478   <TR>
    479     <TD CLASS="bodytext" BGCOLOR="#FFFFFF"></TD>
    480   </TR>
    481   <TR>
    482     <TD CLASS="headtext" BGCOLOR="#226666">
    483       <A HREF="http://validator.w3.org/check/referer">
    484         <IMG BORDER="0" SRC="http://www.w3.org/Icons/valid-html401"
    485          ALT="Valid HTML 4.01!" HEIGHT="31" WIDTH="88">
    486       </A>
    487       <A HREF="http://cr.yp.to/djbdns.html"><IMG BORDER="0" WIDTH="88"
    488       HEIGHT="31" SRC="djbdns.jpg" ALT="Powered by djbdns!"></A>
    489       <IMG BORDER="0" WIDTH="88" HEIGHT="30" SRC="binclogo.gif"
    490       ALT="Powered by Binc IMAP">
    491     </TD>
    492   </TR>
    493 </TABLE>
    494 
    495 </DIV>
    496 </TD>
    497 </TR>
    498 </TABLE>
    499 <BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>
    500 <BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>
    501 
    502 </BODY>
    503 </HTML>