
    \d]                        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j                  Z ee           G d de                      Z ee
j                   G d d                      Z ee           G d de                      ZdS )zD
Support for aliases(5) configuration files.

@author: Jp Calderone
    N)implementer)deferprotocolreactor)smtp)IAlias)failurelogc                    d |                     dd          D             }t          |          dk    rd}||f}t          j        ||z             dS |\  }}|                     |                                g                               t          t          j        |                     d                               dS )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.
    c                 6    g | ]}|                                 S  strip).0ps     2lib/python3.11/site-packages/twisted/mail/alias.py
<listcomp>zhandle.<locals>.<listcomp>)   s     3331QWWYY333    :      z+Invalid format on line %d of alias file %s.,N)	splitlenr
   err
setdefaultr   extendmapstr)	resultlinefilenamelineNopartsfmtarguseraliass	            r   handler)      s    " 43

3 2 2333E
5zzQ;x c	e$**,,++223sy%++cBRBR3S3STTTTTr   c                 f   i }d}|t          |          }d}nt          |dd          }d}d}	 |D ]}|dz  }|                                }|                                                    d	          rC|                    d
          s|                    d          r||z   }s|rt          ||||           |}	 |r|                                 n# |r|                                 w w xY w|rt          ||||           |                                D ]\  }}	t          |	| |          ||<   |S )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.
    FNTnamez	<unknown>r    r   # 	)	opengetattrrstriplstrip
startswithr)   closeitems
AliasGroup)
domainsr"   fpr    r5   iprevr!   uas
             r   loadAliasFiler>   3   ss   R FE	z(^^2v{33	AD 
	 
	DFA;;==D{{}}'',, %% )>)> d{ 6641555
	  	HHJJJ  	HHJJJJ	 *vtXq))),,.. . .Aq'1--q		Ms   BC C,c                   &    e Zd ZdZd Zd ZddZdS )	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        |          | _        dS )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)r8   r   Addressoriginal)selfr8   rC   s      r   __init__zAliasBase.__init__   s      X..r   c                 0    | j         | j        j                 S )z
        Return the domain associated with original address.

        @rtype: L{IDomain} provider
        @return: The domain for the original address.
        )r8   rC   domainrD   s    r   rG   zAliasBase.domain   s     |DM011r   Nc                 |    |i }t          |           |v rdS d|t          |           <   |                                 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rD   aliasmapmemos      r   resolvezAliasBase.resolve   sE      <Dt994SYY))+++r   N)__name__
__module____qualname____doc__rE   rG   rO   r   r   r   r@   r@   {   sP         	/ 	/ 	/2 2 2, , , , , ,r   r@   c                   2    e Zd ZdZd ZdefdZd ZddZdS )	AddressAliasz
    An alias which translates one email address into another.

    @type alias : L{Address}
    @ivar alias: The destination address.
    c                 \    t          j        | g|R   t          j        |          | _        dS )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@   rE   r   rB   r(   )rD   r(   argss      r   rE   zAddressAlias.__init__   s2     	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(   rH   s    r   __str__zAddressAlias.__str__   s     )4:((((r   c                 t    |                                                      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.
        )rG   existsr   r(   rH   s    r   rK   z"AddressAlias.createMessageReceiver   s(     {{}}##C
OO444r   Nc           	         |i }t          |           |v rdS d|t          |           <   	  |                                                     t          j        | j        ddd          |                      S # t          j        $ r Y nw xY w| j        j        |v r&|| j        j                                     ||          S dS rJ   )	r   rG   r^   r   Userr(   SMTPBadRcptlocalrO   rL   s      r   rO   zAddressAlias.resolve   s      <Dt994SYY	V4;;==''	$*dD$(O(OQUVVXXX 	 	 	D	:x''DJ,-55hEEEts   A	A5 5BBrP   )	rQ   rR   rS   rT   rE   r   r\   rK   rO   r   r   r   rV   rV      sk         ) ) )) ) ) ) )5 5 5     r   rV   c                   6    e Zd ZdZd Zd Zd Zd ZdefdZ	dS )	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                    | _        || _        dS )z
        @type filename: L{bytes}
        @param filename: The name of the file in which the message should be
            stored.
        N)tempfileTemporaryFiler9   	finalname)rD   r"   s     r   rE   zFileWrapper.__init__  s     (**!r   c                 @    | j                             |dz              dS )z
        Write a received line to the temporary file.

        @type line: L{bytes}
        @param line: A received line of the message.
        
N)r9   writerD   r!   s     r   lineReceivedzFileWrapper.lineReceived  s"     	dTk"""""r   c                    | j                             dd           	 t          | j        d          }n5# t          $ r( t          j        t          j                              cY S w xY w|5  |	                    | j         
                                           | j                                          ddd           n# 1 swxY w Y   t          j        | j                  S )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   r=   N)r9   seekr0   rh   BaseExceptionr   failr	   Failurerk   readr5   succeed)rD   fs     r   eomReceivedzFileWrapper.eomReceived  s    	Q	1T^S))AA 	1 	1 	1:go//00000	1  	 	GGDGLLNN###GMMOOO	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 }T^,,,s"   3 /A%$A%*AB<<C C c                 F    | j                                          d| _         dS )zG
        Close the temporary file when the connection is lost.
        N)r9   r5   rH   s    r   connectionLostzFileWrapper.connectionLost-  s     	r   rY   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 r[   )rh   rH   s    r   r\   zFileWrapper.__str__4  s     1t~0000r   N
rQ   rR   rS   rT   rE   rm   rv   rx   r   r\   r   r   r   rd   rd      su        	 	" " "# # #- - -,  1 1 1 1 1 1 1r   rd   c                   *    e Zd ZdZd ZdefdZd ZdS )	FileAliasz_
    An alias which translates an address to a file.

    @ivar filename: See L{__init__}.
    c                 8    t          j        | g|R   || _        dS )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@   rE   r"   )rD   r"   rX   s      r   rE   zFileAlias.__init__F  s(     	4'$'''' r   rY   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 r[   )r"   rH   s    r   r\   zFileAlias.__str__R  s     )((((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.
        )rd   r"   rH   s    r   rK   zFileAlias.createMessageReceiver[  s     4=)))r   N)rQ   rR   rS   rT   rE   r   r\   rK   r   r   r   r|   r|   >  sW         
! 
! 
!) ) ) ) )* * * * *r   r|   c                       e Zd ZdZdS )ProcessAliasTimeoutzb
    An error indicating that a timeout occurred while waiting for a process
    to complete.
    N)rQ   rR   rS   rT   r   r   r   r   r   e  s           r   r   c                   T    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dS )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                   |	|| _        dS dS )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   )rD   r   processr   s       r   rE   zMessageWrapper.__init__  s`     # .**"o 2333"DLLL r   c                 f    d| _         | j        "| j                                         d| _        dS |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)rD   r    s     r   r   zMessageWrapper._processEnded  s@     	* &&((("&D Mr   c                 \    | j         rdS | j        j                            |dz              dS )z
        Write a received line to the child process.

        @type line: L{bytes}
        @param line: A received line of the message.
        Nrj   )r   r   	transportrk   rl   s     r   rm   zMessageWrapper.lineReceived  s6     9 	F%%dTk22222r   c                     | j         sH| 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   rH   s    r   rv   zMessageWrapper.eomReceived  sT     y 	M#22444"&,"8"8&(># #D r   c                     d| _         | j        j                            d           t	          d| j         d          }d| j        _        | j                            t          j
        |                     dS )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	   rr   )rD   excs     r   r   z MessageWrapper._completionCancel  sq     #--f555!"UT5K"U"U"UVV" 4 455555r   c                     dS )z9
        Ignore notification of lost connection.
        Nr   rH   s    r   rx   zMessageWrapper.connectionLost  s      r   rY   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 r[   )r   rH   s    r   r\   zMessageWrapper.__str__  s     6$"25555r   NN)rQ   rR   rS   rT   r   r   r   r   rE   r   rm   rv   r   rx   r   r\   r   r   r   r   r   l  s         < DNG# # # #*  ,	3 	3 	3   
6 
6 
6  
6 6 6 6 6 6 6r   r   c                       e Zd ZdZdZd ZdS )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                 L    | j         | j                             |           dS dS )z
        Call an errback.

        @type reason: L{Failure <failure.Failure>}
        @param reason: The reason the child process terminated.
        N)r   r   )rD   reasons     r   processEndedz!ProcessAliasProtocol.processEnded  s0     :!Jv&&&&& "!r   )rQ   rR   rS   rT   r   r   r   r   r   r   r     s4          E' ' ' ' 'r   r   c                   4    e Zd ZdZeZd ZdefdZd Zd Z	dS )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|R   |                                | _        | j        d         | _        dS )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@   rE   r   pathprogram)rD   r   rX   s      r   rE   zProcessAlias.__init__  s=     	4'$''''JJLL	y|r   rY   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 r[   )r   rH   s    r   r\   zProcessAlias.__str__.  s     (49''''r   c                 :    | 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)rD   protor   r   s       r   r   zProcessAlias.spawnProcess7  s    0 |((>>>r   c                     t                      }t          || 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   )rD   r   ms      r   rK   z"ProcessAlias.createMessageReceiverQ  sE     !""1dlDL99!T\49555r   N)
rQ   rR   rS   rT   r   rE   r   r\   r   rK   r   r   r   r   r   
  sm         " G$ $ $( ( ( ( (? ? ?4    r   r   c                   6    e Zd ZdZd Zd Zd Zd ZdefdZ	dS )	MultiWrapperz
    A message receiver which delivers a single message to multiple other
    message receivers.

    @ivar objs: See L{__init__}.
    c                     || _         dS )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)rD   r   s     r   rE   zMultiWrapper.__init__h  s     			r   c                 D    | j         D ]}|                    |           dS )z
        Pass a received line to the message receivers.

        @type line: L{bytes}
        @param line: A line of the message.
        N)r   rm   )rD   r!   os      r   rm   zMultiWrapper.lineReceivedp  s4      	! 	!ANN4    	! 	!r   c                 H    t          j        d | j        D                       S )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.
        c                 6    g | ]}|                                 S r   )rv   )r   r   s     r   r   z,MultiWrapper.eomReceived.<locals>.<listcomp>  s     "F"F"Fq1==??"F"F"Fr   )r   DeferredListr   rH   s    r   rv   zMultiWrapper.eomReceivedz  s&     !"F"FDI"F"F"FGGGr   c                 B    | j         D ]}|                                 dS )zQ
        Inform the message receivers that the connection has been lost.
        N)r   rx   )rD   r   s     r   rx   zMultiWrapper.connectionLost  s4      	 	A	 	r   rY   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 r[   )r   r   r   rH   s    r   r\   zMultiWrapper.__str__  s!     9C 3 38888r   Nrz   r   r   r   r   r   _  sx           ! ! !	H 	H 	H  9 9 9 9 9 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dS )
r7   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|R   g | _        |r|                                                                }|                    d          r	 t          |dd                   }|5  d                    d |D                       }ddd           n# 1 swxY w Y   |                    |	                    d                     n# t          $ r" t          j        d|dd                    Y nw xY w|                    d          r/| j                             | j        |dd         g|R             n|                    d	          rZt          j                            |          rt          j        d
           nK| j                            t%          |g|R             n%| j                            t'          |g|R             |dS dS )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.   c                 6    g | ]}|                                 S r   r   )r   ls     r   r   z'AliasGroup.__init__.<locals>.<listcomp>  s     (>(>(>q(>(>(>r   r   zInvalid filename in alias file |/z Directory delivery not supported)r@   rE   aliasespopr   r4   r0   joinr   r   rp   r
   r   appendprocessAliasFactoryosr   isdirr|   rV   )rD   r6   rX   addrru   s        r   rE   zAliasGroup.__init__  s_    	4'$'''' 	?99;;$$&&Ds## ?2T!""XA  @ @"xx(>(>A(>(>(>??@ @ @ @ @ @ @ @ @ @ @ @ @ @ @LLC1111 % L L LGJd122hJJKKKKKL %% ?##$<D$<T!""X$M$M$M$MNNNN%% ?7==&& @G>????L''	$(>(>(>(>????##L$=$=$=$=>>>'  	? 	? 	? 	? 	?s$   C 2 BB"%B")C?>C?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   rH   s    r   __len__zAliasGroup.__len__  s     4<   r   rY   c                 b    dd                     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   rH   s    r   r\   zAliasGroup.__str__  s'     #diiC0F0F&G&GHHr   c                 >    t          d | j        D                       S )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.
        c                 6    g | ]}|                                 S r   )rK   )r   r=   s     r   r   z4AliasGroup.createMessageReceiver.<locals>.<listcomp>  s$    MMM1Q4466MMMr   )r   r   rH   s    r   rK   z AliasGroup.createMessageReceiver  s#     MMMMMNNNr   Nc                     |i }g }| j         D ]+}|                    |                    ||                     ,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   rO   r   filter)rD   rM   rN   rr=   s        r   rO   zAliasGroup.resolve  s]      <D 	0 	0AHHQYYx..////F4OO,,,r   rP   )rQ   rR   rS   rT   r   r   rE   r   r   r\   rK   rO   r   r   r   r7   r7     s        	 	 '$? $? $?L! ! !I I I I I	O 	O 	O- - - - - -r   r7   r   )rT   r   rf   zope.interfacer   twisted.internetr   r   r   twisted.mailr   twisted.mail.interfacesr   twisted.pythonr	   r
   r)   r>   r@   rV   IMessagerd   r|   	Exceptionr   r   ProcessProtocolr   r   r   r7   r   r   r   <module>r      s;    
			  & & & & & & 5 5 5 5 5 5 5 5 5 5       * * * * * * ' ' ' ' ' ' ' 'U U U6E E E EP3, 3, 3, 3, 3, 3, 3, 3,l VC C C C C9 C C CL T]B1 B1 B1 B1 B1 B1 B1 B1J V#* #* #* #* #*	 #* #* #*L    )    T]D6 D6 D6 D6 D6 D6 D6 D6N' ' ' ' '83 ' ' ', VQ Q Q Q Q9 Q Q Qh T]39 39 39 39 39 39 39 39l Vf- f- f- f- f- f- f- f- f- f-r   