ó
Qü½cc           @   sà   d  Z  d d l Z d d l Z d d l Z d d l m Z d d l m Z d d l m	 Z	 d d l m
 Z
 d d l m Z d d l m Z d d	 l m Z d d
 l m Z e j d e j e j Bƒ Z d e f d „  ƒ  YZ d S(   s®  Maildir pre-queue runner.

Most MTAs can be configured to deliver messages to a `Maildir'[1].  This
runner will read messages from a maildir's new/ directory and inject them into
Mailman's qfiles/in directory for processing in the normal pipeline.  This
delivery mechanism contrasts with mail program delivery, where incoming
messages end up in qfiles/in via the MTA executing the scripts/post script
(and likewise for the other -aliases for each mailing list).

The advantage to Maildir delivery is that it is more efficient; there's no
need to fork an intervening program just to take the message from the MTA's
standard output, to the qfiles/in directory.

[1] http://cr.yp.to/proto/maildir.html

We're going to use the :info flag == 1, experimental status flag for our own
purposes.  The :1 can be followed by one of these letters:

- P means that MaildirRunner's in the process of parsing and enqueuing the
  message.  If successful, it will delete the file.

- X means something failed during the parse/enqueue phase.  An error message
  will be logged to log/error and the file will be renamed <filename>:1,X.
  MaildirRunner will never automatically return to this file, but once the
  problem is fixed, you can manually move the file back to the new/ directory
  and MaildirRunner will attempt to re-process it.  At some point we may do
  this automatically.

See the variable USE_MAILDIR in Defaults.py.in for enabling this delivery
mechanism.
iÿÿÿÿN(   t   Parser(   t	   parseaddr(   t   mm_cfg(   t   Utils(   t   Message(   t   Runner(   t   get_switchboard(   t   syslogsË  
 ^                        # start of string
 (?P<listname>[^+@]+?)    # listname@ or listname-subq@ (non-greedy)
 (?:                      # non-grouping
   -                      # dash separator
   (?P<subq>              # any known suffix
     admin|
     bounces|
     confirm|
     join|
     leave|
     owner|
     request|
     subscribe|
     unsubscribe
   )
 )?                       # if it exists
 [+@]                     # followed by + or @
 t   MaildirRunnerc           B   s)   e  Z d d  d „ Z d „  Z d „  Z RS(   i   c         C   sR   d |  _  t j j t j d ƒ |  _ t j j t j d ƒ |  _ t t	 ƒ |  _
 d  S(   Ni    t   newt   cur(   t   _stopt   ost   patht   joinR   t   MAILDIR_DIRt   _dirt   _curR    R   t   _parser(   t   selft   slicet	   numslices(    (    s:   /export/web/mailman/mailman/Mailman/Queue/MaildirRunner.pyt   __init__`   s    	c         C   s½  t  j ƒ  } y t j |  j ƒ } Wn, t k
 rP } | j t j k rL ‚  n  d SXxe| D]]} t j j	 |  j | ƒ } t j j	 |  j
 | d ƒ } t j j	 |  j
 | d ƒ } y t j | | ƒ Wn> t k
 r} | j t j k rì qX n  t d d | ƒ ‚  n Xyyt | ƒ } z |  j j | ƒ }	 Wd  | j ƒ  Xg  }
 x' d  D] } |
 j |	 j | g  ƒ ƒ qCWx |
 D]e } t | ƒ d	 } | sqmn  t j | ƒ } | sªqmn  | j d
 d ƒ \ } } | | k rmPqmqmWt d d | ƒ t j | | ƒ wX i | d
 6} | d! k r$t t j ƒ } n:| d k rLd	 | d <t t j ƒ } n| d" k rtd	 | d <t t j ƒ } nê | d# k rœd	 | d <t t j ƒ } nÂ | d k rë| j i d	 d 6t  j d d ƒ d 6t j d 6ƒ t t j ƒ } ns | d  k rd	 | d <t t j ƒ } nK | d k r;d	 | d <t t j ƒ } n# t d d | ƒ t j | | ƒ wX | j  |	 | ƒ t j! | ƒ WqX t" k
 r´} t j | | ƒ t d t# | ƒ ƒ qX XqX Wd  S($   Ni    s   :1,Ps   :1,Xt   errors!   Could not rename maildir file: %ss   delivered-tos   envelope-tos   apparently-toi   t   listnamet   subqs'   Message apparently not for any list: %st   bouncest   admint   confirmt	   toconfirmR   t	   subscribet   tojoint   leavet   unsubscribet   toleavet   ownert   toownert   extrat	   envsendert   pipelinet   tolistt   requestt	   torequests   Unknown sub-queue: %s(   s   delivered-tos   envelope-tos   apparently-to(   R   R   (   R   R   (   R    R!   ($   R   t
   list_namesR   t   listdirR   t   OSErrort   errnot   ENOENTR   R   R   t   renameR   t   openR   t   parset   closet   extendt   get_allR   t   lret   matcht   groupR   R   t   BOUNCEQUEUE_DIRt   CMDQUEUE_DIRt   updatet   get_site_emailt   OWNER_PIPELINEt   INQUEUE_DIRt   Nonet   enqueuet   unlinkt	   Exceptiont   str(   R   t	   listnamest   filest   et   filet   srcnamet   dstnamet   xdstnamet   fpt   msgt   valst   headert   fieldt   tot   moR   R   t   msgdatat   queue(    (    s:   /export/web/mailman/mailman/Mailman/Queue/MaildirRunner.pyt   _onelooph   s     	


	

c         C   s   d  S(   N(    (   R   (    (    s:   /export/web/mailman/mailman/Mailman/Queue/MaildirRunner.pyt   _cleanupÃ   s    N(   t   __name__t
   __module__R?   R   RT   RU   (    (    (    s:   /export/web/mailman/mailman/Mailman/Queue/MaildirRunner.pyR   Z   s   	[(   t   __doc__R   t   reR.   t   email.ParserR    t   email.UtilsR   t   MailmanR   R   t   Mailman.MessageR   t   Mailman.Queue.RunnerR   t   Mailman.Queue.sbcacheR   t   Mailman.Logging.SyslogR   t   compilet   VERBOSEt
   IGNORECASER6   R   (    (    (    s:   /export/web/mailman/mailman/Mailman/Queue/MaildirRunner.pyt   <module>0   s   