
[[\7                 @   s  d  Z  d d l Z d d l Z d d l Z y d d l Z d Z Wn e k
 rZ d Z Yn Xd d g Z Gd d   d e  Z	 d Z
 d	 Z d
 Z d Z e e Z d Z Gd d   d  Z e r Gd d   d e  Z e j d  n  e d k rd d l Z e e j d  Z e e j    e j e j d  e j e j d  e j   e j   \ Z Z xj e d e d  D]U Z  e j! e   \ Z" Z# Z$ e d e   x e# D] Z% e d e%  qWe d  qwWe j&   n  d S)z@A POP3 client class.

Based on the J. Myers POP3 draft, Jan. 96
    NTFPOP3error_protoc               @   s   e  Z d  Z d S)r   N)__name__
__module____qualname__ r   r   /usr/lib/python3.4/poplib.pyr      s    n   i  s   s   
i   c               @   s  e  Z d  Z d Z d Z e e j d d  Z d d   Z	 d d   Z
 d	 d
   Z d d   Z d d   Z d d   Z d d   Z d d   Z d d   Z d d   Z d d   Z d d   Z d d   Z d d  d!  Z d" d#   Z d$ d%   Z d& d'   Z d( d)   Z d* d+   Z d, d-   Z d. d/   Z e j d0  Z  d1 d2   Z! d3 d4   Z" d d5 d6  Z# d7 d8   Z$ d d9 d:  Z% d S);r   a%  This class supports both the minimal and optional command sets.
    Arguments can be strings or integers (where appropriate)
    (e.g.: retr(1) and retr('1') both work equally well.

    Minimal Command Set:
            USER name               user(name)
            PASS string             pass_(string)
            STAT                    stat()
            LIST [msg]              list(msg = None)
            RETR msg                retr(msg)
            DELE msg                dele(msg)
            NOOP                    noop()
            RSET                    rset()
            QUIT                    quit()

    Optional Commands (some servers support these):
            RPOP name               rpop(name)
            APOP name digest        apop(name, digest)
            TOP msg n               top(msg, n)
            UIDL [msg]              uidl(msg = None)
            CAPA                    capa()
            STLS                    stls()

    Raises one exception: 'error_proto'.

    Instantiate with:
            POP3(hostname, port=110)

    NB:     the POP protocol locks the mailbox from user
            authorization until QUIT, so be sure to get in, suck
            the messages, and quit, each time you access the
            mailbox.

            POP is a line-based protocol, which means large mail
            messages consume lots of python cycles reading them
            line-by-line.

            If it's available on your mail server, use IMAP4
            instead, it doesn't suffer from the two problems
            above.
    zUTF-8c             C   s^   | |  _  | |  _ d |  _ |  j |  |  _ |  j j d  |  _ d |  _ |  j   |  _	 d  S)NFrbr   )
hostport_tls_established_create_socketsockmakefilefile
_debugging_getrespwelcome)selfr   r   timeoutr   r   r   __init__`   s    				zPOP3.__init__c             C   s   t  j |  j |  j f |  S)N)socketZcreate_connectionr   r   )r   r   r   r   r   r   j   s    zPOP3._create_socketc             C   s=   |  j  d k r% t d t |   n  |  j j | t  d  S)N   z*put*)r   printreprr   ZsendallCRLF)r   liner   r   r   _putlinem   s     zPOP3._putlinec             C   sB   |  j  r t d t |   n  t | |  j  } |  j |  d  S)Nz*cmd*)r   r   r   bytesencodingr   )r   r   r   r   r   _putcmdt   s    	 zPOP3._putcmdc             C   s   |  j  j t d  } t |  t k r7 t d   n  |  j d k r\ t d t |   n  | sq t d   n  t |  } | d d   t k r | d  d  | f S| d t	 k r | d d	  | f S| d  d
  | f S)Nr   zline too longz*get*z-ERR EOF   r   r#   r$   )
r   readline_MAXLINElenr   r   r   r   r   CR)r   r   octetsr   r   r   _getline~   s      zPOP3._getlinec             C   sY   |  j    \ } } |  j d k r7 t d t |   n  | j d  sU t |   n  | S)Nr   z*resp*   +)r*   r   r   r   
startswithr   )r   respor   r   r   r      s     zPOP3._getrespc             C   s   |  j    } g  } d } |  j   \ } } xe | d k r | j d  re | d } | d d   } n  | | } | j |  |  j   \ } } q- W| | | f S)Nr      .s   ..r   )r   r*   r,   append)r   r-   listr)   r   r.   r   r   r   _getlongresp   s     

zPOP3._getlongrespc             C   s   |  j  |  |  j   S)N)r!   r   )r   r   r   r   r   	_shortcmd   s    zPOP3._shortcmdc             C   s   |  j  |  |  j   S)N)r!   r2   )r   r   r   r   r   _longcmd   s    zPOP3._longcmdc             C   s   |  j  S)N)r   )r   r   r   r   
getwelcome   s    zPOP3.getwelcomec             C   s   | |  _  d  S)N)r   )r   levelr   r   r   set_debuglevel   s    zPOP3.set_debuglevelc             C   s   |  j  d |  S)zVSend user name, return response

        (should indicate password required).
        zUSER %s)r3   )r   userr   r   r   r8      s    z	POP3.userc             C   s   |  j  d |  S)zSend password, return response

        (response includes message count, mailbox size).

        NB: mailbox is locked by server from here to 'quit()'
        zPASS %s)r3   )r   Zpswdr   r   r   pass_   s    z
POP3.pass_c             C   sd   |  j  d  } | j   } |  j r: t d t |   n  t | d  } t | d  } | | f S)z]Get mailbox status.

        Result is tuple of 2 ints (message count, mailbox size)
        ZSTATz*stat*r   r"   )r3   splitr   r   r   int)r   ZretvalZretsZnumMessagesZsizeMessagesr   r   r   stat   s    	 z	POP3.statNc             C   s*   | d k	 r |  j  d |  S|  j d  S)a  Request listing, return result.

        Result without a message number argument is in form
        ['response', ['mesg_num octets', ...], octets].

        Result when a message number argument is given is a
        single response: the "scan listing" for that message.
        NzLIST %sZLIST)r3   r4   )r   whichr   r   r   r1      s    	z	POP3.listc             C   s   |  j  d |  S)zoRetrieve whole message number 'which'.

        Result is in form ['response', ['line', ...], octets].
        zRETR %s)r4   )r   r=   r   r   r   retr   s    z	POP3.retrc             C   s   |  j  d |  S)zFDelete message number 'which'.

        Result is 'response'.
        zDELE %s)r3   )r   r=   r   r   r   dele   s    z	POP3.delec             C   s   |  j  d  S)zXDoes nothing.

        One supposes the response indicates the server is alive.
        ZNOOP)r3   )r   r   r   r   noop  s    z	POP3.noopc             C   s   |  j  d  S)z(Unmark all messages marked for deletion.ZRSET)r3   )r   r   r   r   rset
  s    z	POP3.rsetc             C   s   |  j  d  } |  j   | S)zDSignoff: commit changes on server, unlock mailbox, close connection.ZQUIT)r3   close)r   r-   r   r   r   quit  s    
z	POP3.quitc             C   s   |  j  d k	 r |  j  j   n  |  j d k	 r z[ y |  j j t j  Wn= t k
 r } z | j t j k ru   n  WYd d } ~ Xn XWd |  j j   Xn  d |  _  |  _ d S)z8Close the connection without assuming anything about it.N)	r   rB   r   Zshutdownr   Z	SHUT_RDWROSErrorerrnoZENOTCONN)r   er   r   r   rB     s    z
POP3.closec             C   s   |  j  d |  S)zNot sure what this does.zRPOP %s)r3   )r   r8   r   r   r   rpop)  s    z	POP3.rpops   \+OK.[^<]*(<.*>)c             C   s   t  | |  j  } |  j j |  j  } | s< t d   n  d d l } | j d  | } | j |  j	   } |  j
 d | | f  S)a  Authorisation

        - only possible if server has supplied a timestamp in initial greeting.

        Args:
                user     - mailbox user;
                password - mailbox password.

        NB: mailbox is locked by server from here to 'quit()'
        z!-ERR APOP not supported by serverr   Nr   z
APOP %s %s)r   r    	timestampmatchr   r   hashlibgroupZmd5Z	hexdigestr3   )r   r8   ZpasswordZsecretmrJ   Zdigestr   r   r   apop0  s    z	POP3.apopc             C   s   |  j  d | | f  S)zRetrieve message header of message number 'which'
        and first 'howmuch' lines of message body.

        Result is in form ['response', ['line', ...], octets].
        z	TOP %s %s)r4   )r   r=   Zhowmuchr   r   r   topE  s    zPOP3.topc             C   s*   | d k	 r |  j  d |  S|  j d  S)zReturn message digest (unique id) list.

        If 'which', result contains unique id for that message
        in the form 'response mesgnum uid', otherwise result is
        the list ['response', ['mesgnum uid', ...], octets]
        NzUIDL %sZUIDL)r3   r4   )r   r=   r   r   r   uidlN  s    z	POP3.uidlc       	      C   s   d d   } i  } yJ |  j  d  } | d } x* | D]" } | |  \ } } | | | <q5 WWn1 t k
 r } z t d   WYd d } ~ Xn X| S)a   Return server capabilities (RFC 2449) as a dictionary
        >>> c=poplib.POP3('localhost')
        >>> c.capa()
        {'IMPLEMENTATION': ['Cyrus', 'POP3', 'server', 'v2.2.12'],
         'TOP': [], 'LOGIN-DELAY': ['0'], 'AUTH-RESP-CODE': [],
         'EXPIRE': ['NEVER'], 'USER': [], 'STLS': [], 'PIPELINING': [],
         'UIDL': [], 'RESP-CODES': []}
        >>>

        Really, according to RFC 2449, the cyrus folks should avoid
        having the implementation split into multiple arguments...
        c             S   s-   |  j  d  j   } | d | d d   f S)Nasciir   r   )decoder:   )r   Zlstr   r   r   	_parsecapg  s    zPOP3.capa.<locals>._parsecapZCAPAr   z!-ERR CAPA not supported by serverN)r4   r   )	r   rR   capsr-   ZrawcapsZcaplineZcapnmZcapargsZ_errr   r   r   capaZ  s    
z	POP3.capac             C   s   t  s t d   n  |  j r- t d   n  |  j   } d | k rT t d   n  | d k ro t j   } n  |  j d  } t j r |  j n d } | j	 |  j
 d | |  _
 |  j
 j d  |  _ d |  _ | S)	z{Start a TLS session on the active connection as specified in RFC 2595.

                context - a ssl.SSLContext
        z-ERR TLS support missingz$-ERR TLS session already establishedZSTLSz!-ERR STLS not supported by serverNserver_hostnamer
   T)HAVE_SSLr   r   rT   ssl_create_stdlib_contextr3   HAS_SNIr   wrap_socketr   r   r   )r   contextrS   r-   rU   r   r   r   stlsw  s     		z	POP3.stls)&r   r   r   __doc__r    	POP3_PORTr   _GLOBAL_DEFAULT_TIMEOUTr   r   r   r!   r*   r   r2   r3   r4   r5   r7   r8   r9   r<   r1   r>   r?   r@   rA   rC   rB   rG   recompilerH   rM   rN   rO   rT   r\   r   r   r   r   r   2   s>   *	


	c               @   sU   e  Z d  Z d Z e d d e j d d d  Z d d   Z d d d d d  Z	 d S)	POP3_SSLa  POP3 client class over SSL connection

        Instantiate with: POP3_SSL(hostname, port=995, keyfile=None, certfile=None,
                                   context=None)

               hostname - the hostname of the pop3 over ssl server
               port - port number
               keyfile - PEM formatted file that contains your private key
               certfile - PEM formatted certificate chain file
               context - a ssl.SSLContext

        See the methods of the parent class POP3 for more documentation.
        Nc             C   s   | d  k	 r' | d  k	 r' t  d   n  | d  k	 rN | d  k	 rN t  d   n  | |  _ | |  _ | d  k r t j d | d |  } n  | |  _ t j |  | | |  d  S)Nz4context and keyfile arguments are mutually exclusivez5context and certfile arguments are mutually exclusivecertfilekeyfile)
ValueErrorrd   rc   rW   rX   r[   r   r   )r   r   r   rd   rc   r   r[   r   r   r   r     s    			zPOP3_SSL.__init__c             C   sF   t  j |  |  } t j r$ |  j n d  } |  j j | d | } | S)NrU   )r   r   rW   rY   r   r[   rZ   )r   r   r   rU   r   r   r   r     s
    	zPOP3_SSL._create_socketc             C   s   t  d   d S)zThe method unconditionally raises an exception since the
            STLS command doesn't make any sense on an already established
            SSL/TLS session.
            z$-ERR TLS session already establishedN)r   )r   rd   rc   r[   r   r   r   r\     s    zPOP3_SSL.stls)
r   r   r   r]   POP3_SSL_PORTr   r_   r   r   r\   r   r   r   r   rb     s
   	rb   __main__r   r"      zMessage %d:z   z-----------------------)'r]   rE   r`   r   rW   rV   ImportError__all__	Exceptionr   r^   rf   r(   ZLFr   r&   r   rb   r0   r   sysargvar   r5   r8   r9   r1   r<   ZnumMsgsZ	totalSizerangeir>   headermsgr)   r   rC   r   r   r   r   <module>   sH   

 ]-
