Ë
    ojº]  ã                   ó,  — d Z ddlZddlZddlmZ ddlmZmZmZ ddl	m
Z
 ddlmZ ddlmZmZ d„ Zdd	„Z G d
„ d«      Z ee«       G d„ de«      «       Z ee
j(                  «       G d„ d«      «       Z ee«       G d„ de«      «       Z G d„ de«      Z ee
j(                  «       G d„ d«      «       Z G d„ dej4                  «      Z ee«       G d„ de«      «       Z ee
j(                  «       G d„ d«      «       Z ee«       G d„ de«      «       Zy)zD
Support for aliases(5) configuration files.

@author: Jp Calderone
é    N)Úimplementer)ÚdeferÚprotocolÚreactor)Úsmtp)ÚIAlias)ÚfailureÚlogc                 óx  — |j                  dd«      D �cg c]  }|j                  «       ‘Œ }}t        |«      dk7  rd}||f}t        j                  ||z  «       y|\  }}	| j                  |j                  «       g «      j                  t        t        j                  |	j                  d«      «      «       yc c}w )að  
    Parse a line from an aliases file.

    @type result: L{dict} mapping L{bytes} to L{list} of L{bytes}
    @param result: A dictionary mapping username to aliases to which
        the results of parsing the line are added.

    @type line: L{bytes}
    @param line: A line from an aliases file.

    @type filename: L{bytes}
    @param filename: The full or relative path to the aliases file.

    @type lineNo: L{int}
    @param lineNo: The position of the line within the aliases file.
    ú:é   é   z+Invalid format on line %d of alias file %s.ú,N)	ÚsplitÚstripÚlenr
   ÚerrÚ
setdefaultÚextendÚmapÚstr)
ÚresultÚlineÚfilenameÚlineNoÚpÚpartsÚfmtÚargÚuserÚaliass
             ú4/usr/lib/python3/dist-packages/twisted/mail/alias.pyÚhandler#      s•   € ð" !%§
¡
¨3°Ó 2Ö3˜1ˆQ�W‰W�YÐ3€EÐ3Ü
ˆ5ƒz�Q‚Ø;ˆØ�xÐ ˆÜ�‰��c‘	Õà‰ˆˆeØ×Ñ˜$Ÿ*™*›,¨Ó+×2Ñ2´3´s·y±yÀ%Ç+Á+ÈcÓBRÓ3SÕTùò 4s   •B7c                 ó  — i }d}|€t        |«      }d}nt        |dd«      }d}d}	 |D ]q  }|dz  }|j                  «       }|j                  «       j	                  d«      rŒ8|j	                  d	«      s|j	                  d
«      r||z   }Œ`|rt        ||||«       |}Œs 	 |r|j                  «        	 |rt        ||||«       |j                  «       D ]  \  }}	t        |	| |«      ||<   Œ |S # |r|j                  «        w w xY w)a¢  
    Load a file containing email aliases.

    Lines in the file should be formatted like so::

         username: alias1, alias2, ..., aliasN

    Aliases beginning with a C{|} will be treated as programs, will be run, and
    the message will be written to their stdin.

    Aliases beginning with a C{:} will be treated as a file containing
    additional aliases for the username.

    Aliases beginning with a C{/} will be treated as the full pathname to a file
    to which the message will be appended.

    Aliases without a host part will be assumed to be addresses on localhost.

    If a username is specified multiple times, the aliases for each are joined
    together as if they had all been on one line.

    Lines beginning with a space or a tab are continuations of the previous
    line.

    Lines beginning with a C{#} are comments.

    @type domains: L{dict} mapping L{bytes} to L{IDomain} provider
    @param domains: A mapping of domain name to domain object.

    @type filename: L{bytes} or L{None}
    @param filename: The full or relative path to a file from which to load
        aliases. If omitted, the C{fp} parameter must be specified.

    @type fp: file-like object or L{None}
    @param fp: The file from which to load aliases. If specified,
        the C{filename} parameter is ignored.

    @rtype: L{dict} mapping L{bytes} to L{AliasGroup}
    @return: A mapping from username to group of aliases.
    FTÚnamez	<unknown>r   Ú r   ú#ú ú	)	ÚopenÚgetattrÚrstripÚlstripÚ
startswithr#   ÚcloseÚitemsÚ
AliasGroup)
Údomainsr   Úfpr   r/   ÚiÚprevr   ÚuÚas
             r"   ÚloadAliasFiler8   3   s  € ðR €FØ€EØ	€zÜ�(‹^ˆØ‰ä˜2˜v {Ó3ˆØ	€AØ€DðØò 
	ˆDØ�‰FˆAØ—;‘;“=ˆDØ�{‰{‹}×'Ñ'¨Ô,ØØ—‘ Ô%¨¯©¸Ô)>Ø˜d‘{‘áÜ˜6 4¨°1Ô5Ø‘ñ
	ñ Ø�H‰H�JÙÜˆv�t˜X qÔ)Ø—‘“ò .‰ˆˆ1Ü˜q '¨1Ó-ˆˆqŠ	ð.à€Møñ Ø�H‰H�Jð ús   §A6C+ Ã+D c                   ó$   — e Zd ZdZd„ Zd„ Zdd„Zy)Ú	AliasBasezª
    The default base class for aliases.

    @ivar domains: See L{__init__}.

    @type original: L{Address}
    @ivar original: The original address being aliased.
    c                 óF   — || _         t        j                  |«      | _        y)zò
        @type domains: L{dict} mapping L{bytes} to L{IDomain} provider
        @param domains: A mapping of domain name to domain object.

        @type original: L{bytes}
        @param original: The original address being aliased.
        N)r2   r   ÚAddressÚoriginal)Úselfr2   r=   s      r"   Ú__init__zAliasBase.__init__…   s   € ð ˆŒÜŸ™ XÓ.ˆ�ó    c                 óH   — | j                   | j                  j                     S )z 
        Return the domain associated with original address.

        @rtype: L{IDomain} provider
        @return: The domain for the original address.
        )r2   r=   Údomain©r>   s    r"   rB   zAliasBase.domain�   s   € ð �|‰|˜DŸM™M×0Ñ0Ñ1Ð1r@   Nc                 ób   — |€i }t        | «      |v ryd|t        | «      <   | j                  «       S ©aY  
        Map this alias to its ultimate destination.

        @type aliasmap: L{dict} mapping L{bytes} to L{AliasBase}
        @param aliasmap: A mapping of username to alias or group of aliases.

        @type memo: L{None} or L{dict} of L{AliasBase}
        @param memo: A record of the aliases already considered in the
            resolution process.  If provided, C{memo} is modified to include
            this alias.

        @rtype: L{IMessage <smtp.IMessage>} or L{None}
        @return: A message receiver for the ultimate destination or None for
            an invalid destination.
        N)r   ÚcreateMessageReceiver©r>   ÚaliasmapÚmemos      r"   ÚresolvezAliasBase.resolve™   s9   € ð  ˆ<ØˆDÜˆt‹9˜ÑØØˆŒS�‹Y‰Ø×)Ñ)Ó+Ð+r@   ©N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r?   rB   rJ   © r@   r"   r:   r:   {   s   „ ñò	/ò2ô,r@   r:   c                   ó0   — e Zd ZdZd„ Zdefd„Zd„ Zdd„Zy)	ÚAddressAliasz‹
    An alias which translates one email address into another.

    @type alias : L{Address}
    @ivar alias: The destination address.
    c                 ód   — t        j                  | g|¢­Ž  t        j                  |«      | _        y)aQ  
        @type alias: L{Address}, L{User}, L{bytes} or object which can be
            converted into L{bytes}
        @param alias: The destination address.

        @type args: 2-L{tuple} of (0) L{dict} mapping L{bytes} to L{IDomain}
            provider, (1) L{bytes}
        @param args: Arguments for L{AliasBase.__init__}.
        N)r:   r?   r   r<   r!   )r>   r!   Úargss      r"   r?   zAddressAlias.__init__º   s'   € ô 	×Ñ˜4Ð' $Ó'Ü—\‘\ %Ó(ˆ�
r@   Úreturnc                 ó"   — d| j                   › d�S )z©
        Build a string representation of this L{AddressAlias} instance.

        @rtype: L{bytes}
        @return: A string containing the destination address.
        z	<Address ú>)r!   rC   s    r"   Ú__str__zAddressAlias.__str__Ç   s   € ð ˜4Ÿ:™:˜, aÐ(Ð(r@   c                 óf   — | j                  «       j                  t        | j                  «      «      S )zÃ
        Create a message receiver which delivers a message to
        the destination address.

        @rtype: L{IMessage <smtp.IMessage>} provider
        @return: A message receiver.
        )rB   Úexistsr   r!   rC   s    r"   rF   z"AddressAlias.createMessageReceiverÐ   s#   € ð �{‰{‹}×#Ñ#¤C¨¯
©
£OÓ4Ð4r@   Nc           	      ó„  — |€i }t        | «      |v ryd|t        | «      <   	  | j                  «       j                  t        j                  | j
                  ddd«      |«      «       S # t        j                  $ r Y nw xY w| j
                  j                  |v r)|| j
                  j                     j                  ||«      S yrE   )	r   rB   rZ   r   ÚUserr!   ÚSMTPBadRcptÚlocalrJ   rG   s      r"   rJ   zAddressAlias.resolveÚ   s°   € ð  ˆ<ØˆDÜˆt‹9˜ÑØØˆŒS�‹Y‰ð	ØV�4—;‘;“=×'Ñ'¬¯	©	°$·*±*¸dÀDÈ$Ó(OÐQUÓVÓXÐXøÜ×Ñò 	Ùð	úà�:‰:×Ñ˜xÑ'Ø˜DŸJ™J×,Ñ,Ñ-×5Ñ5°hÀÓEÐEØs   ¢AA' Á'A=Á<A=rK   )	rL   rM   rN   rO   r?   r   rX   rF   rJ   rP   r@   r"   rR   rR   ±   s"   „ ñò)ð)˜ó )ò5ôr@   rR   c                   ó4   — e Zd ZdZd„ Zd„ Zd„ Zd„ Zdefd„Z	y)	ÚFileWrappera  
    A message receiver which delivers a message to a file.

    @type fp: file-like object
    @ivar fp: A file used for temporary storage of the message.

    @type finalname: L{bytes}
    @ivar finalname: The name of the file in which the message should be
        stored.
    c                 óD   — t        j                  «       | _        || _        y)z‹
        @type filename: L{bytes}
        @param filename: The name of the file in which the message should be
            stored.
        N)ÚtempfileÚTemporaryFiler3   Ú	finalname)r>   r   s     r"   r?   zFileWrapper.__init__  s   € ô ×(Ñ(Ó*ˆŒØ!ˆ�r@   c                 ó@   — | j                   j                  |dz   «       y)z‘
        Write a received line to the temporary file.

        @type line: L{bytes}
        @param line: A received line of the message.
        ú
N)r3   Úwrite©r>   r   s     r"   ÚlineReceivedzFileWrapper.lineReceived  s   € ð 	�‰�‰�d˜T‘kÕ"r@   c                 óÆ  — | j                   j                  dd«       	 t        | j                  d«      }|5  |j                  | j                   j                  «       «       | j                   j                  «        ddd«       t        j                  | j                  «      S # t        $ r* t        j                  t        j                  «       «      cY S w xY w# 1 sw Y   Œ^xY w)ac  
        Handle end of message by writing the message to the file.

        @rtype: L{Deferred <defer.Deferred>} which successfully results in
            L{bytes}
        @return: A deferred which succeeds with the name of the file to which
            the message has been stored or fails if the message cannot be
            saved to the file.
        r   r7   N)r3   Úseekr*   rd   ÚBaseExceptionr   Úfailr	   ÚFailurerg   Úreadr/   Úsucceed)r>   Úfs     r"   ÚeomReceivedzFileWrapper.eomReceived  s¤   € ð 	�‰�‰�Q˜Ôð	1Ü�T—^‘^ SÓ)ˆAð ñ 	Ø�G‰G�D—G‘G—L‘L“NÔ#Ø�G‰G�M‰MŒO÷	ô �}‰}˜TŸ^™^Ó,Ð,øô ò 	1Ü—:‘:œgŸo™oÓ/Ó0Ò0ð	1ú÷	ð 	ús   žB! ¶ACÂ!0CÃCÃC c                 óF   — | j                   j                  «        d| _         y)zG
        Close the temporary file when the connection is lost.
        N)r3   r/   rC   s    r"   ÚconnectionLostzFileWrapper.connectionLost-  s   € ð 	�‰�‰ŒØˆ�r@   rU   c                 ó"   — d| j                   › d�S )z­
        Build a string representation of this L{FileWrapper} instance.

        @rtype: L{bytes}
        @return: A string containing the file name of the message.
        z<FileWrapper rW   )rd   rC   s    r"   rX   zFileWrapper.__str__4  s   € ð ˜tŸ~™~Ð.¨aÐ0Ð0r@   N©
rL   rM   rN   rO   r?   ri   rr   rt   r   rX   rP   r@   r"   r`   r`   ø   s'   „ ñ	ò"ò#ò-ò,ð1˜ô 1r@   r`   c                   ó(   — e Zd ZdZd„ Zdefd„Zd„ Zy)Ú	FileAliasz_
    An alias which translates an address to a file.

    @ivar filename: See L{__init__}.
    c                 ó>   — t        j                  | g|¢­Ž  || _        y)a"  
        @type filename: L{bytes}
        @param filename: The name of the file in which to store the message.

        @type args: 2-L{tuple} of (0) L{dict} mapping L{bytes} to L{IDomain}
            provider, (1) L{bytes}
        @param args: Arguments for L{AliasBase.__init__}.
        N)r:   r?   r   )r>   r   rT   s      r"   r?   zFileAlias.__init__F  s   € ô 	×Ñ˜4Ð' $Ó'Ø ˆ�r@   rU   c                 ó"   — d| j                   › d�S )z£
        Build a string representation of this L{FileAlias} instance.

        @rtype: L{bytes}
        @return: A string containing the name of the file.
        z<File rW   )r   rC   s    r"   rX   zFileAlias.__str__R  s   € ð ˜Ÿ™� aÐ(Ð(r@   c                 ó,   — t        | j                  «      S )z¹
        Create a message receiver which delivers a message to the file.

        @rtype: L{FileWrapper}
        @return: A message receiver which writes a message to the file.
        )r`   r   rC   s    r"   rF   zFileAlias.createMessageReceiver[  s   € ô ˜4Ÿ=™=Ó)Ð)r@   N)rL   rM   rN   rO   r?   r   rX   rF   rP   r@   r"   rx   rx   >  s   „ ñò
!ð)˜ó )ó*r@   rx   c                   ó   — e Zd ZdZy)ÚProcessAliasTimeoutzb
    An error indicating that a timeout occurred while waiting for a process
    to complete.
    N)rL   rM   rN   rO   rP   r@   r"   r}   r}   e  s   „ òr@   r}   c                   óR   — e Zd ZdZdZdZdZeZdd„Zd„ Z	d„ Z
d„ Zd	„ Zd
„ Zdefd„Zy)ÚMessageWrapperaF  
    A message receiver which delivers a message to a child process.

    @type completionTimeout: L{int} or L{float}
    @ivar completionTimeout: The number of seconds to wait for the child
        process to exit before reporting the delivery as a failure.

    @type _timeoutCallID: L{None} or
        L{IDelayedCall <twisted.internet.interfaces.IDelayedCall>} provider
    @ivar _timeoutCallID: The call used to time out delivery, started when the
        connection to the child process is closed.

    @type done: L{bool}
    @ivar done: A flag indicating whether the child process has exited
        (C{True}) or not (C{False}).

    @type reactor: L{IReactorTime <twisted.internet.interfaces.IReactorTime>}
        provider
    @ivar reactor: A reactor which will be used to schedule timeouts.

    @ivar protocol: See L{__init__}.

    @type processName: L{bytes} or L{None}
    @ivar processName: The process name.

    @type completion: L{Deferred <defer.Deferred>}
    @ivar completion: The deferred which will be triggered by the protocol
        when the child process exits.
    Fé<   Nc                 óæ   — || _         || _        t        j                  «       | _        | j                  | j                  _        | j                  j                  | j                  «       |�|| _        yy)a–  
        @type protocol: L{ProcessAliasProtocol}
        @param protocol: The protocol associated with the child process.

        @type process: L{bytes} or L{None}
        @param process: The process name.

        @type reactor: L{None} or L{IReactorTime
            <twisted.internet.interfaces.IReactorTime>} provider
        @param reactor: A reactor which will be used to schedule timeouts.
        N)	ÚprocessNamer   r   ÚDeferredÚ
completionÚonEndÚaddBothÚ_processEndedr   )r>   r   Úprocessr   s       r"   r?   zMessageWrapper.__init__“  s[   € ð #ˆÔØ ˆŒÜŸ.™.Ó*ˆŒØ"Ÿo™oˆ�‰ÔØ�‰×Ñ × 2Ñ 2Ô3àÐØ"ˆD�Lð r@   c                 óp   — d| _         | j                  �"| j                  j                  «        d| _        y|S )a—  
        Record process termination and cancel the timeout call if it is active.

        @type result: L{Failure <failure.Failure>}
        @param result: The reason the child process terminated.

        @rtype: L{None} or L{Failure <failure.Failure>}
        @return: None, if the process end is expected, or the reason the child
            process terminated, if the process end is unexpected.
        TN)ÚdoneÚ_timeoutCallIDÚcancel)r>   r   s     r"   r‡   zMessageWrapper._processEnded¨  s:   € ð ˆŒ	Ø×ÑÐ*ð ×Ñ×&Ñ&Ô(Ø"&ˆDÕð ˆMr@   c                 ón   — | j                   ry| j                  j                  j                  |dz   «       y)z�
        Write a received line to the child process.

        @type line: L{bytes}
        @param line: A received line of the message.
        Nrf   )rŠ   r   Ú	transportrg   rh   s     r"   ri   zMessageWrapper.lineReceived¾  s*   € ð �9Š9ØØ�‰×Ñ×%Ñ% d¨T¡kÕ2r@   c                 óä   — | j                   sY| j                  j                  j                  «        | j                  j                  | j                  | j                  «      | _        | j                  S )zö
        Disconnect from the child process and set up a timeout to wait for it
        to exit.

        @rtype: L{Deferred <defer.Deferred>}
        @return: A deferred which will be called back when the child process
            exits.
        )
rŠ   r   rŽ   ÚloseConnectionr   Ú	callLaterÚcompletionTimeoutÚ_completionCancelr‹   r„   rC   s    r"   rr   zMessageWrapper.eomReceivedÉ  sU   € ð �yŠyØ�M‰M×#Ñ#×2Ñ2Ô4Ø"&§,¡,×"8Ñ"8Ø×&Ñ&¨×(>Ñ(>ó#ˆDÔð �‰Ðr@   c                 ó  — d| _         | j                  j                  j                  d«       t	        d| j
                  › d�«      }d| j                  _        | j                  j                  t        j                  |«      «       y)zÅ
        Handle the expiration of the timeout for the child process to exit by
        terminating the child process forcefully and issuing a failure to the
        L{completion} deferred.
        NÚKILLzNo answer after z seconds)r‹   r   rŽ   ÚsignalProcessr}   r’   r…   r„   Úerrbackr	   rn   )r>   Úexcs     r"   r“   z MessageWrapper._completionCancelÙ  sf   € ð #ˆÔØ�‰×Ñ×-Ñ-¨fÔ5Ü!Ð$4°T×5KÑ5KÐ4LÈHÐ"UÓVˆØ"ˆ�‰ÔØ�‰×Ñ¤§¡°Ó 4Õ5r@   c                  ó   — y)z9
        Ignore notification of lost connection.
        NrP   rC   s    r"   rt   zMessageWrapper.connectionLostå  s   � r@   rU   c                 ó"   — d| j                   › d�S )z«
        Build a string representation of this L{MessageWrapper} instance.

        @rtype: L{bytes}
        @return: A string containing the name of the process.
        z<ProcessWrapper rW   )r‚   rC   s    r"   rX   zMessageWrapper.__str__ê  s   € ð " $×"2Ñ"2Ð!3°1Ð5Ð5r@   ©NN)rL   rM   rN   rO   rŠ   r’   r‹   r   r?   r‡   ri   rr   r“   rt   r   rX   rP   r@   r"   r   r   l  sH   „ ñð< €DàÐØ€Nà€Gó#ò*ò,	3òò 
6òð
6˜ô 6r@   r   c                   ó   — e Zd ZdZdZd„ Zy)ÚProcessAliasProtocolzå
    A process protocol which errbacks a deferred when the associated
    process ends.

    @type onEnd: L{None} or L{Deferred <defer.Deferred>}
    @ivar onEnd: If set, a deferred on which to errback when the process ends.
    Nc                 óT   — | j                   �| j                   j                  |«       yy)z–
        Call an errback.

        @type reason: L{Failure <failure.Failure>}
        @param reason: The reason the child process terminated.
        N)r…   r—   )r>   Úreasons     r"   ÚprocessEndedz!ProcessAliasProtocol.processEndedÿ  s%   € ð �:‰:Ð!Ø�J‰J×Ñ˜vÕ&ð "r@   )rL   rM   rN   rO   r…   r    rP   r@   r"   r�   r�   ô  s   „ ñð €Eó'r@   r�   c                   ó2   — e Zd ZdZeZd„ Zdefd„Zd„ Zd„ Z	y)ÚProcessAliasa6  
    An alias which is handled by the execution of a program.

    @type path: L{list} of L{bytes}
    @ivar path: The arguments to pass to the process. The first string is
        the executable's name.

    @type program: L{bytes}
    @ivar program: The path of the program to be executed.

    @type reactor: L{IReactorTime <twisted.internet.interfaces.IReactorTime>}
        and L{IReactorProcess <twisted.internet.interfaces.IReactorProcess>}
        provider
    @ivar reactor: A reactor which will be used to create and timeout the
        child process.
    c                 ó‚   — t        j                  | g|¢­Ž  |j                  «       | _        | j                  d   | _        y)aX  
        @type path: L{bytes}
        @param path: The command to invoke the program consisting of the path
            to the executable followed by any arguments.

        @type args: 2-L{tuple} of (0) L{dict} mapping L{bytes} to L{IDomain}
            provider, (1) L{bytes}
        @param args: Arguments for L{AliasBase.__init__}.
        r   N)r:   r?   r   ÚpathÚprogram)r>   r¤   rT   s      r"   r?   zProcessAlias.__init__  s3   € ô 	×Ñ˜4Ð' $Ó'Ø—J‘J“LˆŒ	Ø—y‘y ‘|ˆ�r@   rU   c                 ó"   — d| j                   › d�S )z¸
        Build a string representation of this L{ProcessAlias} instance.

        @rtype: L{bytes}
        @return: A string containing the command used to invoke the process.
        z	<Process rW   )r¤   rC   s    r"   rX   zProcessAlias.__str__.  s   € ð ˜4Ÿ9™9˜+ QÐ'Ð'r@   c                 ó<   — | j                   j                  |||«      S )aP  
        Spawn a process.

        This wraps the L{spawnProcess
        <twisted.internet.interfaces.IReactorProcess.spawnProcess>} method on
        L{reactor} so that it can be customized for test purposes.

        @type proto: L{IProcessProtocol
            <twisted.internet.interfaces.IProcessProtocol>} provider
        @param proto: An object which will be notified of all events related to
            the created process.

        @type program: L{bytes}
        @param program: The full path name of the file to execute.

        @type path: L{list} of L{bytes}
        @param path: The arguments to pass to the process. The first string
            should be the executable's name.

        @rtype: L{IProcessTransport
            <twisted.internet.interfaces.IProcessTransport>} provider
        @return: A process transport.
        )r   ÚspawnProcess)r>   Úprotor¥   r¤   s       r"   r¨   zProcessAlias.spawnProcess7  s   € ð0 �|‰|×(Ñ(¨°¸Ó>Ð>r@   c                 óª   — t        «       }t        || j                  | j                  «      }| j	                  || j                  | j
                  «       |S )zÚ
        Launch a process and create a message receiver to pass a message
        to the process.

        @rtype: L{MessageWrapper}
        @return: A message receiver which delivers a message to the process.
        )r�   r   r¥   r   r¨   r¤   )r>   r   Úms      r"   rF   z"ProcessAlias.createMessageReceiverQ  sA   € ô !Ó"ˆÜ˜1˜dŸl™l¨D¯L©LÓ9ˆØ×Ñ˜!˜TŸ\™\¨4¯9©9Ô5Øˆr@   N)
rL   rM   rN   rO   r   r?   r   rX   r¨   rF   rP   r@   r"   r¢   r¢   
  s)   „ ñð" €Gò$ð(˜ó (ò?ó4r@   r¢   c                   ó4   — e Zd ZdZd„ Zd„ Zd„ Zd„ Zdefd„Z	y)	ÚMultiWrapperz‡
    A message receiver which delivers a single message to multiple other
    message receivers.

    @ivar objs: See L{__init__}.
    c                 ó   — || _         y)z²
        @type objs: L{list} of L{IMessage <smtp.IMessage>} provider
        @param objs: Message receivers to which the incoming message should be
            directed.
        N)Úobjs)r>   r¯   s     r"   r?   zMultiWrapper.__init__h  s   € ð ˆ�	r@   c                 óH   — | j                   D ]  }|j                  |«       Œ y)zŠ
        Pass a received line to the message receivers.

        @type line: L{bytes}
        @param line: A line of the message.
        N)r¯   ri   )r>   r   Úos      r"   ri   zMultiWrapper.lineReceivedp  s#   € ð —‘ò 	!ˆAØ�N‰N˜4Õ ñ	!r@   c                 ó‚   — t        j                  | j                  D �cg c]  }|j                  «       ‘Œ c}«      S c c}w )aG  
        Pass the end of message along to the message receivers.

        @rtype: L{DeferredList <defer.DeferredList>} whose successful results
            are L{bytes} or L{None}
        @return: A deferred list which triggers when all of the message
            receivers have finished handling their end of message.
        )r   ÚDeferredListr¯   rr   ©r>   r±   s     r"   rr   zMultiWrapper.eomReceivedz  s-   € ô ×!Ñ!¸D¿I¹IÖ"F°q 1§=¡=¥?Ò"FÓGÐGùÒ"Fs   ž<c                 óF   — | j                   D ]  }|j                  «        Œ y)zQ
        Inform the message receivers that the connection has been lost.
        N)r¯   rt   r´   s     r"   rt   zMultiWrapper.connectionLost…  s#   € ð —‘ò 	ˆAØ×ÑÕñ	r@   rU   c                 ó>   — dt        t        | j                  «      ›d�S )z±
        Build a string representation of this L{MultiWrapper} instance.

        @rtype: L{bytes}
        @return: A string containing a list of the message receivers.
        z<GroupWrapper rW   )r   r   r¯   rC   s    r"   rX   zMultiWrapper.__str__Œ  s   € ð  ¤¤C¨¯©Ó 3Ð6°aÐ8Ð8r@   Nrv   rP   r@   r"   r­   r­   _  s(   „ ñòò!ò	Hòð9˜ô 9r@   r­   c                   ó:   — e Zd ZdZeZd„ Zd„ Zdefd„Z	d„ Z
d	d„Zy)
r1   aL  
    An alias which points to multiple destination aliases.

    @type processAliasFactory: no-argument callable which returns
        L{ProcessAlias}
    @ivar processAliasFactory: A factory for process aliases.

    @type aliases: L{list} of L{AliasBase} which implements L{IAlias}
    @ivar aliases: The destination aliases.
    c                 ó˜  — t        j                  | g|¢­Ž  g | _        |�rn|j                  «       j	                  «       }|j                  d«      rh	 t        |dd «      }|5  dj                  |D �cg c]  }|j	                  «       ‘Œ c}«      }ddd«       |j                  |j                  d«      «       nÒ|j                  d«      r0| j                  j                   | j                  |dd g|¢­Ž «       n‘|j                  d«      r[t        j                   j#                  |«      rt        j                  d	«       nK| j                  j                  t%        |g|¢­Ž «       n%| j                  j                  t'        |g|¢­Ž «       |r�Œmyyc c}w # 1 sw Y   �ŒxY w# t        $ r t        j                  d|dd ›�«       Y Œ>w xY w)
a‚  
        Create a group of aliases.

        Parse a list of alias strings and, for each, create an appropriate
        alias object.

        @type items: L{list} of L{bytes}
        @param items: Aliases.

        @type args: n-L{tuple} of (0) L{dict} mapping L{bytes} to L{IDomain}
            provider, (1) L{bytes}
        @param args: Arguments for L{AliasBase.__init__}.
        r   r   Nr(   r   zInvalid filename in alias file ú|ú/z Directory delivery not supported)r:   r?   ÚaliasesÚpopr   r.   r*   Újoinr   r   rl   r
   r   ÚappendÚprocessAliasFactoryÚosr¤   Úisdirrx   rR   )r>   r0   rT   Úaddrrq   Úls         r"   r?   zAliasGroup.__init__¥  st  € ô 	×Ñ˜4Ð' $Ó'ØˆŒÚØ—9‘9“;×$Ñ$Ó&ˆDØ�‰˜sÔ#ð2Ü˜T ! "˜X›�Að ñ @Ø"Ÿx™x¸AÖ(>°q¨¯©­Ò(>Ó?˜÷@à—L‘L §¡¨C£Õ1Ø—‘ Ô%Ø—‘×#Ñ#Ð$< D×$<Ñ$<¸TÀ!À"¸XÐ$MÈÒ$MÕNØ—‘ Ô%Ü—7‘7—=‘= Ô&Ü—G‘GÐ>Õ?à—L‘L×'Ñ'¬	°$Ð(>¸Ò(>Õ?à—‘×#Ñ#¤L°Ð$=¸Ò$=Ô>õ' ùò )?÷@ñ @ûô %ò LÜ—G‘GÐ=¸dÀ1À2¸h¸\ÐJÖKðLús0   ÁF" Á!FÁ1F
ÂFÆFÆFÆ"$G	ÇG	c                 ó,   — t        | j                  «      S )z‰
        Return the number of aliases in the group.

        @rtype: L{int}
        @return: The number of aliases in the group.
        )r   r»   rC   s    r"   Ú__len__zAliasGroup.__len__Ë  s   € ô �4—<‘<Ó Ð r@   rU   c                 óZ   — ddj                  t        t        | j                  «      «      z  S )z¨
        Build a string representation of this L{AliasGroup} instance.

        @rtype: L{bytes}
        @return: A string containing the aliases in the group.
        z<AliasGroup [%s]>z, )r½   r   r   r»   rC   s    r"   rX   zAliasGroup.__str__Ô  s#   € ð # d§i¡i´´C¸¿¹Ó0FÓ&GÑHÐHr@   c                 ón   — t        | j                  D �cg c]  }|j                  «       ‘Œ c}«      S c c}w )a,  
        Create a message receiver for each alias and return a message receiver
        which will pass on a message to each of those.

        @rtype: L{MultiWrapper}
        @return: A message receiver which passes a message on to message
            receivers for each alias in the group.
        )r­   r»   rF   )r>   r7   s     r"   rF   z AliasGroup.createMessageReceiverÝ  s*   € ô ÀÇÁÖM¸1˜Q×4Ñ4Õ6ÒMÓNÐNùÒMs   ”2Nc                 óœ   — |€i }g }| j                   D ]#  }|j                  |j                  ||«      «       Œ% t        t	        d|«      «      S )a�  
        Map each of the aliases in the group to its ultimate destination.

        @type aliasmap: L{dict} mapping L{bytes} to L{AliasBase}
        @param aliasmap: A mapping of username to alias or group of aliases.

        @type memo: L{None} or L{dict} of L{AliasBase}
        @param memo: A record of the aliases already considered in the
            resolution process.  If provided, C{memo} is modified to include
            this alias.

        @rtype: L{MultiWrapper}
        @return: A message receiver which passes the message on to message
            receivers for the ultimate destination of each alias in the group.
        N)r»   r¾   rJ   r­   Úfilter)r>   rH   rI   Úrr7   s        r"   rJ   zAliasGroup.resolveè  sN   € ð  ˆ<ØˆDØˆØ—‘ò 	0ˆAØ�H‰H�Q—Y‘Y˜x¨Ó.Õ/ð	0äœF 4¨›OÓ,Ð,r@   rK   )rL   rM   rN   rO   r¢   r¿   r?   rÅ   r   rX   rF   rJ   rP   r@   r"   r1   r1   –  s3   „ ñ	ð 'Ðò$?òL!ðI˜ó Iò	Oô-r@   r1   r›   )rO   rÀ   rb   Úzope.interfacer   Útwisted.internetr   r   r   Útwisted.mailr   Útwisted.mail.interfacesr   Útwisted.pythonr	   r
   r#   r8   r:   rR   ÚIMessager`   rx   Ú	Exceptionr}   r   ÚProcessProtocolr�   r¢   r­   r1   rP   r@   r"   ú<module>rÓ      sU  ðñó 
Û å &ç 5Ñ 5Ý Ý *ß 'òUó6E÷P3,ñ 3,ñl ˆVÓôC�9ó Có ðCñL ˆT�]‰]Ó÷B1ð B1ó ðB1ñJ ˆVÓô#*�	ó #*ó ð#*ôL˜)ô ñ ˆT�]‰]Ó÷D6ð D6ó ðD6ôN'˜8×3Ñ3ô 'ñ, ˆVÓôQ�9ó Qó ðQñh ˆT�]‰]Ó÷39ð 39ó ð39ñl ˆVÓôf-�ó f-ó ñf-r@   