[[email protected]: failure notice]

Charles Cazabon <[email protected]> Mon, 3 Mar 2003 18:08:34 -0600
Newsgroups gmane.mail.bikini.devel
Message-ID <[email protected]>
Snapshot 20030303-1610 released and uploaded.  Diff follows.

diff -urN --exclude=bikini.html --exclude=bikini.txt bikini-20030303-1153/bikini/constants.py bikini-20030303-1610/bikini/constants.py
--- bikini-20030303-1153/bikini/constants.py	Mon Mar  3 11:53:43 2003
+++ bikini-20030303-1610/bikini/constants.py	Mon Mar  3 16:10:07 2003
@@ -33,7 +33,7 @@
     'AUTH-ANONYMOUS',           # 'auth anonymous' support
     'AUTH-PLAIN',               # 'auth plain' support
     'AUTH-LOGIN',               # 'auth login' support
-    #'SEND',                    # 'send' not yet implemented
+    'SEND',                    # 'send' implemented as a stub
     'MESSAGE-SIZE %d' % os.environ.get ('DATABYTES', 0),  # max message size for put
 )
 
diff -urN --exclude=bikini.html --exclude=bikini.txt bikini-20030303-1153/bikini/server.py bikini-20030303-1610/bikini/server.py
--- bikini-20030303-1153/bikini/server.py	Mon Mar  3 11:53:43 2003
+++ bikini-20030303-1610/bikini/server.py	Mon Mar  3 16:10:07 2003
@@ -371,7 +371,7 @@
                 raise PermanentCommandError, 'negative or zero size'
             if os.environ.get ('DATABYTES', 0) and size > os.environ.get ('DATABYTES', 0):
                 raise TemporaryCommandError, 'message too big'
-            self.respond ('information', str (size))
+            self.respond ('success', str (size))
             msg = self.fi.read (size)
             if len (msg) != size:
                 raise TemporaryCommandError, 'short message'
@@ -392,6 +392,47 @@
         return newmsg
 
     ###################################
+    def sendmsg (self, path, size):
+        '''Send a previously stored message.
+        '''
+        log (TRACE, 'path %s size %s\n' % (path, size))
+        maildir, msgfile = os.path.split (path)
+        # Make sure client isn't playing tricks
+        assert_maildir (maildir)
+        try:
+            self.foldercontents (maildir)
+            p = self.folders[maildir][msgfile]
+            f = os.path.join (maildir, p)
+            validate_file (f)
+            size = int (size)
+            if size < 12: # min size '[email protected]\0' * 2
+                raise PermanentCommandError, 'envelope size too small'
+            self.respond ('success', str (size))
+            envelope = self.fi.read (size)
+            if len (envelope) != size:
+                raise TemporaryCommandError, 'short message'
+            confirm, unused = self.getcmd ()
+            if confirm != 'finished' or unused:
+                raise TemporaryCommandError, 'envelope reception failed'
+            # We've now received the envelope and confirmed it's the right size,
+            # and that the client thinks so too.
+            parts = envelope.split ('\0')
+            if (parts[-1] != ''                         # No trailing NUL
+                or len (parts) < 3):                    # Not enough parts
+                raise bSyntaxError, 'bad envelope format'
+
+            receipt = deliver_message (f, envelope)     # ??? Currently a stub
+
+        except KeyError, err:
+            raise PermanentCommandError, 'no such message %s' % path
+        except ValueError, err:
+            raise PermanentCommandError, 'envelope size invalid'
+        except (OSError, os.error, IOError), err:
+            log (ERROR, 'failure sending message %s: %s\n' % (path, err))
+            raise TemporaryCommandError, 'failure sending message'
+        return receipt
+
+    ###################################
     def mkdir (self, path):
         '''Create a directory.
         '''
@@ -545,7 +586,7 @@
                 elif cmd == 'PUT':
                     if len (args) != 2:  raise bSyntaxError
                     rc = self.putmsg (args[0], args[1])
-                    self.respond ('information', rc)
+                    self.respond ('success', rc)
                 elif cmd == 'RMMSG':
                     if len (args) != 1:  raise bSyntaxError
                     rc = self.rmmsg (args[0])
@@ -553,7 +594,7 @@
                 elif cmd == 'MVMSG':
                     if len (args) != 2:  raise bSyntaxError
                     rc = self.mvmsg (args[0], args[1])
-                    self.respond ('information', rc)
+                    self.respond ('success', rc)
                 elif cmd == 'MKDIR':
                     if len (args) != 1:  raise bSyntaxError
                     rc = self.mkdir (args[0])
@@ -573,6 +614,10 @@
                 elif cmd == 'RMFOLDER':
                     if len (args) != 1:  raise bSyntaxError
                     rc = self.rmfolder (args[0])
+                    self.respond ('success', rc)
+                elif cmd == 'SEND':
+                    if len (args) != 2:  raise bSyntaxError
+                    rc = self.sendmsg (args[0], args[1])
                     self.respond ('success', rc)
                 else:
                     raise bSyntaxError, 'invalid command'
diff -urN --exclude=bikini.html --exclude=bikini.txt bikini-20030303-1153/bikini/utilities.py bikini-20030303-1610/bikini/utilities.py
--- bikini-20030303-1153/bikini/utilities.py	Mon Mar  3 11:53:43 2003
+++ bikini-20030303-1610/bikini/utilities.py	Mon Mar  3 16:10:07 2003
@@ -35,11 +35,18 @@
         and os.path.isdir (os.path.join (path, 'new')))
 
 #######################################
+def deliver_message (path, envelope):
+    '''Ask the local MTA to deliver the message.  Currently a stub that does nothing.
+    '''
+    log (TRACE, 'path %s envelope %s\n' % (path, envelope))
+    return 'this is a receipt, should be a queue id or similar'
+
+#######################################
 def utcdate (timestamp):
     '''
     '''
     log (TRACE, 'timestamp %s\n' % timestamp)
-    return '%04d-%02d-%02d %02d:%02d:%02d' % time.gmtime (timestamp)[0:6]
+    return '%04d%02d%02dT%02d%02d%02dZ' % time.gmtime (timestamp)[0:6]
 
 #######################################
 def split_response (line):
diff -urN --exclude=bikini.html --exclude=bikini.txt bikini-20030303-1153/bikini.texi bikini-20030303-1610/bikini.texi
--- bikini-20030303-1153/bikini.texi	Mon Mar  3 11:53:43 2003
+++ bikini-20030303-1610/bikini.texi	Mon Mar  3 16:10:07 2003
@@ -191,6 +191,11 @@
 commands, arguments, or responses other than that explicitly stated in
 this protocol specification.
 
+Consideration has been given to make this protocol suitable for sites which have
+high numbers of active clients.  In particular, the immediate disconnect
+response modifier removes the need for large numbers of idle connections on such
+systems.
+
 @c ****************************************************************************
 @chapter Protocol Overview
 
@@ -305,7 +310,8 @@
 @subsection Server Response Codes
 
 Response codes are a single character, followed immediately by zero or more 
-response modifiers, followed by a single space and additional information.
+response modifiers, followed by a single space and zero or more characters of
+additional information.
 The server must not send a space between the response code and optional response 
 modifiers.
 
@@ -316,7 +322,7 @@
 When the additional information section is optional, it is free-form and
 continues until the end of the line.
 
-The server must not send a space between the response code and the @samp{CR LF} 
+The server MUST send a space between the response code and the @samp{CR LF} 
 which terminates the response line if the additional information section is not 
 supplied.
 
@@ -518,12 +524,19 @@
 In the case of messages delivered by the @samp{MVMSG} command, this
 MUST be the internal timestamp of the source message.
 
-The timestamp is represented in the following format, with a timezone offset
-of -0000 (UTC).  Servers MUST NOT use any other timezone offset when presenting
-the timestamp messages attribute to a client.
+The format used is that of the W3C's Date and Time Formats
+@samp{YYYY-MM-DDThh:mm:ssTZD} without punctuation, with a timezone offset 
+indicator of @samp{Z} to indicate UTC (-0000).
 
-The format used is the equivalent of the C @samp{strftime} format string
-@code{'%a, %d %b %Y %H:%M:%S -0000'}.
+@strong{Examples:}
+
+@example
+	19970716T192030Z
+	20030301T120000Z
+@end example
+
+Servers MUST NOT use any other timezone offset when presenting the timestamp 
+messages attribute to a client.
 
 @c ----------------------------------------------------------------------------
 @node message size
@@ -1151,8 +1164,8 @@
 
 @example
 C:  LISTMSGS projects/alpha
-S:  + 1046273407.M181707P22689Q2.localhost :3050:2003-02-26-15:30:07
-    + 1045853047.5854.localhost RS:3191:2003-02-21-18:44:07
+S:  + 1046273407.M181707P22689Q2.localhost :20030302T121535Z
+    + 1045853047.5854.localhost RS:3191:19961225T150824Z
     K ok
 @end example
 
@@ -1244,7 +1257,9 @@
 
 @strong{Notes:}
 @itemize @bullet
-@item
+@item Once the server has responded to the @samp{PUT} command with a positive
+response, the client sends exactly @samp{content-size} octets of 8-bit message
+data to the server, followed by @samp{finished} plus CRLF.
 @end itemize
 
 @strong{Examples:}
@@ -1419,9 +1434,17 @@
 
 @strong{Notes:}
 @itemize @bullet
+@item Once the server has responded to the @samp{SEND} command with a positive
+response, the client sends exactly @samp{content-size} octets of 8-bit envelope
+data to the server, followed by @samp{finished} plus CRLF.  The format of
+the envelope is an envelope sender address, followed by an ASCII NUL, followed
+by an envelope recipient address, followed by an ASCII NUL, optionally
+followed by additional envelope recipient addresses, each followed by an
+ASCII NUL.
+@item All addresses in the envelope data MUST be in fully-qualified form.
 @item The server MAY use any method it chooses to deliver the message to the 
 recipients.  This may be by handing the message to the local Mail Transfer Agent 
-(MTA) for delivery via SMTP or another protocol, by delivering directly into 
+(MTA) for delivery via SMTP @emph{or another protocol}, by delivering directly into 
 another BikINI mail store on the server, other methods, or a combination of 
 these methods.
 @item Some delivery methods may impose stricter requirements on the format of

-- 
-----------------------------------------------------------------------
Charles Cazabon                           <[email protected]>
BikINI project website:    http://www.qcc.ca/~charlesc/software/bikini/
GPL'ed software available at:     http://www.qcc.ca/~charlesc/software/
-----------------------------------------------------------------------