
    ek                        d dl Z d dlZd dlZd dlZd dlZd dlZd dl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mZ d dlmZmZmZmZmZ d dlZd dlmZmZmZmZ d dlmZ 	 d dlZdZ  G d
 d      Z" G d d      Z#y# e!$ r d	Z Y w xY w)    N)gaierror)exc_info)SSLErrorcert_time_to_seconds)LockBoundedSemaphoreThreadEventcurrentThread)imaplibutilimaputil
threadutilOfflineImapError)getglobaluiTFc                       e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd ZddZy)
IMAPServera"  Initializes all variables from an IMAPRepository() instance

    Various functions, such as acquireconnection() return an IMAP4
    object on which we can operate.

    Public instance variables are: self.:
     delim The server's folder delimiter. Only valid after acquireconnection()
    c                    t               | _        || _        |j                         | _        | j                  j                  dd      | _        | j                  j                  dd      | _        |j                         | _	        |j                         | _        | j                  r6| j                  r*t        d|z  dz   t        j                  j                        | j                  r| j                  n| j                  | _        | j                  rdn|j!                         | _        |j%                         | _        |j)                         | _        d| _        d| _        d| _        |j3                         | _        |j7                         | _        | j8                  du rt:        j<                  | _        n9| j8                  du rt:        j@                  | _        nt:        jB                  | _        | j                  s| j                  rdn|jE                         | _#        |jI                         | _%        | jJ                  | j4                  rd	nd
| _%        |jM                         | _'        |jQ                         | _)        |jU                         | _+        | jV                  d| _,        |j[                         | _.        |j_                         | _0        |jc                         | _2        |jg                         | _4        | j4                  r&| j`                  dk7  r| jd                  tk        d      |jm                         | _7        |jq                         | _9        |ju                         | _;        |jy                         | _=        |j}                         | _?        d| _@        d| _A        d| _B        |j                         | _D        g | _E        g | _F        i | _G        t        | j                        | _I        t               | _K        |j                         | _M        |j                         | _O        d| _P        d| _Q        | j                  dt:        j:                        | _S        | j                  d| j                        | _T        y)z":repos: a IMAPRepository instance.generalzignore-keyringzupdate-keyringz%s: zMyou must enable precisely one type of tunnel (preauth or transport), not bothNTF     
tls_compatzNWhen 'tls_level' is not 'tls_compat' the 'ssl_version' must be set explicitly.proxy	authproxy)Ur   uirepos	getconfigconfig
getbooleanignore_keyringupdate_keyringgetpreauthtunnelpreauth_tunnelgettransporttunneltransport_tunnelr   ERRORREPOtunnelgetuserusernameget_remote_identityuser_identityget_auth_mechanisms	authmechspasswordpassworderrorgoodpasswordgetsslusesslgetipv6useipv6socketAF_INET6afAF_INET	AF_UNSPECgethosthostnamegetportportgetsslclientcertsslclientcertgetsslclientkeysslclientkeygetsslcacertfilesslcacertfile_IMAPServer__verifycertget_ssl_fingerprintfingerprintgettlsleveltlslevelgetsslversion
sslversiongetstarttlsstarttls	Exceptiongetoauth2_refresh_tokenoauth2_refresh_tokengetoauth2_access_tokenoauth2_access_tokengetoauth2_client_idoauth2_client_idgetoauth2_client_secretoauth2_client_secretgetoauth2_request_urloauth2_request_urloauth2_access_token_expires_atdelimrootgetmaxconnectionsmaxconnectionsavailableconnectionsassignedconnections	lastownerr   	semaphorer   connectionlockgetreference	referencegetidlefoldersidlefoldersgss_vcgssapi
_get_proxyproxied_socketauthproxied_socket)selfr   s     1/usr/share/offlineimap3/offlineimap/imapserver.py__init__zIMAPServer.__init__5   s    -
oo'"kk44Y@PQ"kk44Y@PQ#446 % 8 8 :4#8#8"6E>$.$. 0@/E/E/J/JL L
 $(#6#6D** 	
 ''DU]]_ 	"668224! lln}}<<4ooDG\\U"nnDG&&DG $ 5 59L9LRWR_R_RaMMO	99#{{DI"335!113"335% $D 446))+--/))+;;MM\1OO+ H I I %*$A$A$C!#(#?#?#A  % 9 9 ;$)$A$A$C!"'"="="?.2+
	#557$&!#% )$*=*=>"f++- //1
 #oogv}}E #'//+262E2E#G    c                    d| j                   j                  j                  z   }| j                  j	                  ||      s|S | j                  j                  ||      }|dk(  rt        j                  S 	 dd l}|j                  d      \  }}}t        |      }|j                  t        ||      ||       |j                  S # t        $ r | j                  j                  d       Y |S t         t"        f$ rQ}	| j                  j                  d|d| j                   j                  j                  d|	d	|d
	       Y d }	~	|S d }	~	ww xY w)NzAccount  r   :z-PySocks not installed, ignoring proxy option.zBad proxy option z for account : z
 Ignoring z option.)r   accountnamer   
has_optiongetr5   sockssplitintsetdefaultproxygetattr
socksocketImportErrorr   warnAttributeError
ValueError)
rk   proxysection
dfltsocket_account_sectionr   rw   
proxy_typehostr=   es
             rl   rh   zIMAPServer._get_proxy   s#   %

(:(:(?(??{{%%&6E 0,?B;== 	L%*[[%5"Jdt9D!!'%"<dDI### 	JGGLLHI
 	 
+ 	LGGLL!3!3!8!8!\K L L 		Ls    4AC $E(E6AEEc                    | j                   | j                   S | j                  | j                  | j                  S | j                  j	                  | j
                        xs; | j                  j                  | j                  | j                  | j                        | _        | j                  r%| j                  j                  | j                         d| _        | j                  S )z#Returns the server password or NoneN)r0   r.   r/   r   getpasswordr   r   getpassr)   r   r    updatepasswordrk   s    rl   __getpasswordzIMAPServer.__getpassword   s     ($$$==$););)C==  

..t/B/BC Xt{{DDVDVW 	JJ%%dmm4!}}rn   c                 `   |j                         }| j                  j                  dd|z         | j                         }| j                  dz   t        j                  t        |d      |t        j                        j                         z   }| j                  j                  dd|z         |S )Nimapz__md5handler: got challenge %s utf-8)encoding)	digestmodz__md5handler: returning %s)stripr   debug_IMAPServer__getpasswordr)   hmacnewbyteshashlibmd5	hexdigest)rk   response	challengepasswdretvals        rl   __md5handlerzIMAPServer.__md5handler   s    NN$	f>JK##%$%99$+KK11:= 	f:VCDrn   c                     | j                   j                  dd       |j                  | j                  | j	                                y)z( Basic authentication via LOGIN command.r   z$Attempting IMAP LOGIN authenticationN)r   r   loginr)   r   rk   imapobjs     rl   __loginauthzIMAPServer.__loginauth   s2     	fDEdmmT%7%7%9:rn   c                 f   | j                   }|s?t        d| j                  j                         z  t        j                  j
                        | j                         }d}d}| j                  | j                  }|j                  |||f      }| j                  j                  dd|d|d       |S )z\Implements SASL PLAIN authentication, RFC 4616,
          http://tools.ietf.org/html/rfc4616zNo username provided for '%s'rp    r   z__plainhandler: returning r   z (passwd hidden for log))r)   r   r   getnamer%   r&   r   r+   joinr   r   )rk   r   authcr   authzNULLr   s          rl   __plainhandlerzIMAPServer.__plainhandler   s     "#B%)ZZ%7%7%9$:#3#9#9#>#>@ @ ##%)&&EE5&12f38%A 	Brn   c                 F   t         j                   j                         }| j                  r2| j                  |k  r#d | _        | j                  j                  dd       | j                  | j                  't        d| z  t        j                  j                        i }| j                  |d<   | j                  |d<   | j                  |d<   d|d<   | j                  j                  dd| j                  z         | j                  j                  dd	|z         t        j                  }| j                  t        _        	 t        j                   j#                  | j                  t        j$                  j'                  |      j)                  d
            j+                         }	 |t        _        t3        j4                  |      }| j                  j                  dd|z         d|v r't        d|z  t        j                  j                        |d   | _        d|v r$|t        j6                  |d   dz        z   | _        | j                  j                  dd| j                  d| j                  d       d| j8                  d| j                  d}	| j                  j                  dd|	z         |	S # t,        $ rR}	 |dt/        |      d}n# t,        $ r}|d|d}Y d }~nd }~ww xY w| j                  j1                  |        d }~ww xY w# |t        _        w xY w)Nr   z+xoauth2handler: oauth2_access_token expiredz;No remote oauth2_request_url for repository '%s' specified.	client_idclient_secretrefresh_token
grant_typezxoauth2handler: url "%s"zxoauth2handler: params "%s"r   z (configuration is: )z  [cannot display configuration: ]zxoauth2handler: response "%s"errorzxoauth2handler got: %saccess_token
expires_in   )secondszxoauth2handler: access_token "z	 expires "zuser=zauth=Bearer zzxoauth2handler: returning "%s")datetimenowrX   rQ   r   r   rW   r   r%   r&   rS   rU   rO   r5   rj   urllibrequesturlopenparse	urlencodeencodereadrM   strr   jsonloads	timedeltar)   )
rk   r   r   paramsoriginal_socketr   msgeparamsrespauth_strings
             rl   __xoauth2handlerzIMAPServer.__xoauth2handler   s   ##%..77#='+D$GGMM&"OP##+&&.& (D'+(,-=-C-C-H-HJ J
 F"&"7"7F;&*&?&?F?#&*&?&?F?##2F< GGMM&"<11#2 3GGMM&"?&"HI$mmO 33FM0!>>11++V\\-C-CF-K-R-RSZ-[]]a]a]c  !0::h'DGGMM&"AD"HI$&'?$'F'7'='='B'BD D'+N';D$t#69H<N<N .2= 73 	f$$d&I&IK 	L MM4335 	f>LM9  Q9:CKHC  QEFPCQ c" !0sI   ?A$J5 5	L?KL	K,K'"L'K,,LLL L c                     |dk(  rd }	 | j                   sWt        j                  d| j                  z   t        j                  j
                        }t        j                  d|      | _         | j                   j                  s!| j                   j                  |      }|r|S dS |y| j                   j                  |      }d|j                  dd z   }|t        | j                  d      z  }| j                   j                  ||j                        }|j                  r|j                  S dS # t        j                  j                   $ r4}| j"                  j%                  d	|j'                                Y d }~y d }~ww xY w)
Nrp   zimap@initiate)usagert            r   r   )rf   rg   Namer;   NameTypehostbased_serviceSecurityContextcompletestepunwrapmessager   r)   wrap	encrypted
exceptionsGSSErrorr   r   gen_message)rk   tokenrt   r   replyerrs         rl   __gsshandlerzIMAPServer.__gsshandler  sF   B;E$	;;{{7T]]#:#)??#D#DF$44::>@ ;;'';;++E2#+x33  {{))%0H
 h..q33EU4=='22E{{''x/A/ABH'/'7'78##?R?  )) 	 GGMM&#//"34		s1   BD, !D, #D, &BD, *D, ,E=	*E88E=c                 <   d|j                   v r;| j                  s.| j                  j                  dd       	 |j	                          y y y # |j
                  $ rA}t        dt        |      z  t        j                  j                  t               d         d }~ww xY w)NSTARTTLSr   zUsing STARTTLS connectionz"Failed to start TLS connection: %sr   )capabilitiesr2   r   r   rL   r   r   r   r%   r&   r   )rk   r   r   s      rl   __start_tlszIMAPServer.__start_tlsH  s    ---dkkGGMM&"=>6  " 7B- == 6& (<>A!f(E'7'='='B'B'/z!}6 66s   A B<BBc                 *   t         sy| j                  j                          	 |j                  d| j                         	 | j                  j                          y# |j                  $ r	 d| _         w xY w# | j                  j                          w xY w)NFGSSAPIT)have_gssra   acquireauthenticate_IMAPServer__gsshandlerreleaser   rg   r   s     rl   __authn_gssapizIMAPServer.__authn_gssapid  s    ##%	*  4+<+<=
 '')	 }} 	DK	 '')s   A A33A6 6Bc                 <    |j                  d| j                         y)NCRAM-MD5T)r   _IMAPServer__md5handlerr   s     rl   __authn_cram_md5zIMAPServer.__authn_cram_md5r  s    Z):):;rn   c                 <    |j                  d| j                         y)NPLAINT)r   _IMAPServer__plainhandlerr   s     rl   __authn_plainzIMAPServer.__authn_plainv  s    Wd&9&9:rn   c                 n    | j                   | j                  y|j                  d| j                         y)NFXOAUTH2T)rO   rQ   r   _IMAPServer__xoauth2handlerr   s     rl   __authn_xoauth2zIMAPServer.__authn_xoauth2z  s6    $$,,,4Y(=(=>rn   c                     d|j                   v r$t        dt        j                  j                        | j	                  |       y)NLOGINDISABLEDz3IMAP LOGIN is disabled by server.  Need to use SSL?T)r   r   r%   r&   _IMAPServer__loginauthr   s     rl   __authn_loginzIMAPServer.__authn_login  sI     g222" $K#3#9#9#>#>@ @ W%rn   c                    g }d}d}| j                   ddf| j                  ddf| j                  ddf| j                  ddf| j                  ddfd}| j
                  D ]  }||vrt        d|z        ||   \  }}}	|r!| j                  r|sd}| j                  |       |	rd|z   }
|
|j                  vrWd}| j                  j                  dd|z         	  ||      r y t!        |      rfd
j#                  |D cg c]$  }dj#                  |d   t%        |d         f      & c}      }t        d|z  t        j&                  j(                        |sdj#                  |j                  D cg c]  }|dd dk(  s| c}D cg c]  }|dd 	 c}      }t        d| j*                  ddj#                  | j
                        d|t        j&                  j(                        y# |j                  t        f$ r>}| j                  j                  |d	|       |j                  ||f       Y d}~d}~ww xY wc c}w c c}w c c}w )ag  Authentication machinery for self.acquireconnection().

        Raises OfflineImapError() of type ERROR.REPO when
        there are either fatal problems or no authentications
        succeeded.

        If any authentication method succeeds, routine should exit:
        warnings for failed methods are to be produced in the
        respective except blocks.FT)r   r   r   r   LOGINz:Bad authentication method %s, please, file OfflineIMAP bugzAUTH=r   zAttempting %s authenticationNz authentication failed: z
	rr   r   r   z$All authentication types failed:
	%sz,    zRepository z;: no supported authentication mechanisms found; configured z, server advertises )_IMAPServer__authn_gssapi_IMAPServer__authn_xoauth2_IMAPServer__authn_cram_md5_IMAPServer__authn_plain_IMAPServer__authn_loginr-   rM   rL   _IMAPServer__start_tlsr   r   r   r   r   r~   appendlenr   r   r%   r&   r   )rk   r   	exc_stacktried_to_authn	tried_tlsauth_methodsmfunctryTLS	check_capcapr   xr   methodss                  rl   __authn_helperzIMAPServer.__authn_helper  s|    		 **E48,,dD9..d;(($5(($6
  	)A$ !?AB!C D D '31o#D&) $--	 	  )kg222!NGGMM& #689#: ;)= !-	)8 y>++YOtyy!A$AaD	):;OPC" $358$9:J:P:P:U:UW W ii-4-A-A!WQqVwEV!!W!Y112 !Y ZG"=AZZ=AYYt~~=VX_$a $4#9#9#>#>	@ @  MM#34 )q!DE  !Q(()
 P "X!Ys0   G(;)H>-I;II(H;=3H66H;c                 >   d}|sd|z  S |j                         }g }|j                  d      }|r't        j                         t        |      k\  r|d|S |j                  dg       D ]/  }|d   \  }}	|dk(  s|j	                  |	j                                1 t        |      dk(  rd|z  S |j                  d	g       D ]*  \  }}	|d
k(  s|j	                  |	j                                , |D ])  }
|
|k(  s!d|v s|
d|j                  dd      d   z   k(  s) y d|z  S )zVerify that cert (in socket.getpeercert() format) matches hostname.

        CRLs are not handled.
        Returns error message if any problems are found and None on success.zCA Cert verifying failed: z%s no certificate receivednotAfterz certificate expired subjectr   
commonNamez%%s no commonName found in certificatesubjectAltNameDNS.z*.r   Nz/%s no matching domain name found in certificate)lowerrv   timer   r  r  rx   )rk   certr;   errstrdnsname	certnamesnotafterskeyvaluecertnames              rl   __verifycertzIMAPServer.__verifycert  sB    ./&88.."	 88J'yy{28<<6<hGG )R( 	0A1JCl"  /	0 y>Q:VCC ((#3R8 	0JCe|  /	0
 " 	HG#7Nx4'--Q:OPQ:R3R'R	
 A6IIrn   c                    | j                   j                          | j                  j                          t               }d}d}d| j                  j
                  v rd}t        | j                        rt        t        | j                        dz
  dd      D ]>  }| j                  |   }| j                  |   |j                  k(  s/|}| j                  |=  n |s| j                  d   }| j                  d= | j                  j                  |       |j                  | j                  |<   | j                  j                          |S | j                  j                          d}	 |dur| j                  r| j                  j                  | j                   j#                         d	| j                         t%        j&                  | j                  t)        j*                         || j,                  
      }d}n| j.                  r=| j                  j                  | j                   j#                         | j0                  | j2                         | j                  j5                  d| j                   j#                         d| j6                  d| j8                  d       t%        j:                  | j0                  | j2                  | j<                  | j>                  | j@                  | jB                  | j8                  |t)        j*                         | jD                  | j,                  | j6                  | jF                        }n| j                  j                  | j                   j#                         | j0                  | j2                         t%        jH                  | j0                  | j2                  t)        j*                         | j,                  || jF                        }d|jJ                  v r0djM                  tN        jP                        }|jS                  |       | jT                  s%	 | jW                  |       | jX                  | _-        d}|dur| j                   jc                  dd      r|je                          |jg                         \  }	}
|
dgk7  rM|
d   ji                         jk                         D cg c]  }|jm                  d       }}to        |      |_%        | jp                  |js                  | jt                  d      d   }|dgk(  s||js                  | jt                  d      d   }|dgk(  s|Qd| j                   j#                         d| jt                  d}| j                  jw                  |       ty        |      t{        j|                  |d         dd \  | _8        | _?        t{        j                  | jp                        | _8        t{        j                  | j~                        | _?        | j                  5  | j                  j                  |       |j                  | j                  |<   ddd       |S # t\        $ r}t_        |      | _0         d}~ww xY wc c}w # 1 sw Y   |S xY w# tx        $ re}	 | j                   j                          t\        j                  j                  }t        |      t        k(  r5d| j0                  d| j                   d}t]        ||t               d         t        |t              r|j                  t        j                  k(  rc| j2                  dk7  rd| j0                  | j2                  |fz  }nd| j0                  d| j                   d|}t]        ||t               d         t        |t(        j                        rj|j                  r^|j                  d   t        j                  k(  r>d | j0                  | j2                  | j                   fz  }t]        ||t               d         t_        |      dd! d"k(  rKt]        d#| j0                  d| j                   d$t\        j                  j                  t               d         |j                  rg	 |j                  d   dd% d&k(  rHt]        d'jM                  | j0                  | j                         t\        j                  j                        	  #  Y  xY w d}~ww xY w)(zFetches a connection from the pool, making sure to create a new one
        if needed, to obey the maximum connection limits, etc.
        Opens a connection to the server and returns an appropriate
        object.Nr   r   r  r   FTr'   )timeoutr   
use_socketz	: level 'z', version '')r   r=   keyfilecertfileca_certscert_verify_cbssl_versionr   r.  rF   r/  	tls_levelr7   )r.  r/  r   r7   IDz%("name" "OfflineIMAP" "version" "{}")usecompressionr   z""z"*"zServer 'z' returned no folders in 'zCould not resolve name 'z' for repository 'zS'. Make sure you have configured the server name correctly and that you are online.r   r   zCould not connect via SSL to host '%s' and non-standard ssl port %d configured. Make sure you connect to the correct port. Got: %sz)Unknown SSL protocol connecting to host 'z'. OpenSSL responded:
zConnection to host '%s:%d' for repository '%s' was refused. Make sure you have the right host and port configured and that you are actually able to access the network.   zcan't open socket; errorz$Could not connect to remote server 'z'. Remote does not answer.#   z#IMAP4 protocol error: socket error:zPCould not connect to remote server '{}' for repository '{}'. Connection Refused.)Nr`   r   ra   r   r   	debuglistr  r]   ranger_   identr^   r  r   r'   
connectingr   r   r   IMAP4_Tunnelr5   getdefaulttimeoutri   r2   r;   r=   r   rH   rJ   WrappedIMAP4_SSLrA   r?   rC   rD   rF   r7   WrappedIMAP4r   formatofflineimap__version__idr"   _IMAPServer__authn_helperr.   r0   r   r   r/   getconfbooleanenable_compression
capabilityupperrx   decodetuplerY   listrc   r~   rM   r   	imapsplitrZ   dequoter%   r&   typer   r   
isinstancer   errnoEPERMr   argsECONNREFUSEDCRITICAL)rk   	curThreadr   
imap_debugitryobjsuccessl_strr   typdatr  s_datlistresr   severityreasons                    rl   acquireconnectionzIMAPServer.acquireconnection  s`    	 ##%!O	
TWW&&&Jt(() 3t889A=r2F 2215>>&)Y__<$G2215 33A6..q1$$++G4&/ooDNN7#'')N##% X	%;;GG&&

**,hE)66 & 8 8 :(#'#6#6	G #G[[GG&&

**,dmmTYYHGGMM&#'::#5#5#7+Y Z)::!]]!YY $ 1 1!%!3!3!%!3!3'+'8'8$(OO( & 8 8 :$($4$4#'#6#6"&--77G  GG&&

**,dmmTYYH)66tyy & 8 8 :#'#6#6(77G 7///CJJ;KbKbcEJJu%**++G4,0MM)"&i %t zz(()91=**, ))+HCtf}47GMMO4I4I4KLq'*LL',U|$zz!!,,t~~t<Q?tf$ &ll4>>5A!DGtf$
  ::--/ACGGLL%#C.(&&wqz2126 &
DI%--djj9
$,,TYY7	$$ :((//8*3//w': NK , -0V* M,: N <	 NN""$'--22HAw(" --5 'vxAGG!X&177ekk+A 99#= "&		1@>>F $ !%tzz1>F 'vxAGG!V\\*qvv!&&)uGYGY:Y$ (,}}dii&LM 'vxAGG 1vcr{88&FJmmUYU_U_a$**//JqM	# #
 vvvvay"~)NN.GGMv $tzzH;,22;;	= = O 	 Ey<	s   !KY> '$Y
 Y> A(Y> 9Y,D:Y> 5Y1 	Y> 
	Y)Y$$Y))Y> 1Y;6Y> ;Y> >
c-G8c(Ac c( c$"c((c-c                 l    | j                   j                          | j                   j                          y)a  Waits until there is a connection available.

        Note that between the time that a connection becomes available and the
        time it is requested, another thread may have grabbed it.  This function
        is mainly present as a way to avoid spawning thousands of threads to
        copy messages, then have them all wait for 3 available connections.
        It's OK if we have maxconnections + 1 or 2 threads, which is what this
        will help us do.N)r`   r   r   r   s    rl   connectionwaitzIMAPServer.connectionwait  s$     	  rn   c                 <   | j                   5  t        j                  | j                  | j                         | j
                  | j                  z   D ]  }|j                           g | _        g | _        i | _        d | _	        d| _
        d d d        y # 1 sw Y   y xY w)NF)ra   r   semaphoreresetr`   r\   r^   r]   logoutr_   rf   rg   r   s     rl   closezIMAPServer.close  s        	 
 %%dnnd6I6IJ33d6O6OO ! !')D$(*D%DNDKDK	  	  	 s   A<BBc                    | j                   j                  dd       |j                         s| j                  j	                          t        | j                        t        | j                        z   }| j                  j                          g }t        |      D ]  }| j                   j                  dd||fz         t        | j                        |kD  rt        | | j                  |         }nt        |       }|j                          |j                  |        | j                   j                  dd       |j                  |       | j                   j                  dd       |D ]"  }|j                          |j!                          $ | j                   j                  dd       |j                         s| j                   j                  dd       y)	a;  Sends a NOOP to each connection recorded.

        It will wait a maximum of timeout seconds between doing this, and will
        continue to do so until the Event object as passed is true.  This method
        is expected to be invoked in a separate thread, which should be join()'d
        after the event is set.r   zkeepalive thread startedz)keepalive: processing connection %d of %dzkeepalive: waiting for timeoutzkeepalive: after waitzkeepalive: all threads joinedz keepalive: event is set; exitingN)r   r   isSetra   r   r  r^   r]   r   r<  re   
IdleThreadstartr  waitstopr   )rk   r.  eventnumconnectionsthreadsrZ  idlers          rl   	keepalivezIMAPServer.keepalive  sz    	f89++-'') !9!9: !:!:;<N'')G>* 
&f&Q .1'2 3t''(1,&tT-=-=a-@AE 't,Eu%
& GGMM&"BCJJwGGMM&"9:  



 GGMM&"AB7 ++-8 	f@Arn   c                 P   |y| j                   j                          | j                  j                  |       |j                  s|r|j                          n| j                  j                  |       | j                   j                          | j                  j                          y)zReleases a connection, returning it to the pool.

        :param connection: Connection object
        :param drop_conn: If True, the connection will be released and
           not be reused. This can be used to indicate broken connections.N)
ra   r   r^   remove	Terminateri  r]   r  r   r`   )rk   
connection	drop_conns      rl   releaseconnectionzIMAPServer.releaseconnection  s     ##%  ''
39%%,,Z8##% rn   N)F)__name__
__module____qualname____doc__rm   rh   r   r   r   r   r   r   r
  r  r  r  r  r	  rG  rD   rd  rf  rj  ru  r{   rn   rl   r   r   +   s}    \G|0"	;*9z'R	68*	F@P%JN~@! $&P!rn   r   c                   8    e Zd Zd	dZd Zd Zd Zd Zd Zd Z	y)
rm  Nc                    || _         || _        t               | _        t	               | _        |t        | j                        | _        nt        | j                        | _        | j                  j                  d       y)zIf invoked without 'folder', perform a NOOP and wait for
        self.stop() to be called. If invoked with folder, switch to IDLE
        mode and synchronize once we have a new messageN)targetT)parentfolderr
   stop_sigr   r   r	   noopthread_IdleThread__idle	setDaemon)rk   r  r  s      rl   rm   zIdleThread.__init__  s[    
 -> 		2DK 4DKd#rn   c                 8    | j                   j                          y N)r  rn  r   s    rl   rn  zIdleThread.start(  s    rn   c                 8    | j                   j                          y r  )r  setr   s    rl   rp  zIdleThread.stop+  s    rn   c                 8    | j                   j                          y r  )r  r   r   s    rl   r   zIdleThread.join.  s    rn   c                    | j                   j                         }	 |j                          |r6| j                   j                  |       | j                  j                          y y # |j                  $ rI | j                  j                  d|j                  z         | j                   j                  |d       d }Y w xY w# |r6| j                   j                  |       | j                  j                          w w xY w)N(Attempting NOOP on dropped connection %sT)
r  rd  r  abortr   r~   
identifierr{  r  ro  r   s     rl   r  zIdleThread.noop1  s     ++//1
	%LLN --g6""$  }} 	GGLLC ++, -KK))'48G		 --g6""$ s$   A% %AB=:C  <B==C   :C:c                    | j                   j                  }|j                  }|j                  }|j	                  | j
                  d      }|j                  dd      }|j                  |d       t        j                  j                  ||d       |j                  dd      }|j                  |d       t               }|j                  t                      y )NF)rL  presynchookrp   idle)quickpostsynchook)r  r   rs   remoterepos	getfolderr  getconfcallhookrD  accounts
syncfolderr   unregisterthreadr   )rk   r  rs   remotefolderhookr   s         rl   __dosynczIdleThread.__dosyncE  s    kk''%%))",,T[[,G}b1v&''U'K~r2v&]
MO,rn   c                      fd} fd} j                   j                         sd _        d}|s; j                  j	                         }	 |j                   j                         d}|s;dj                   v r|j#                  |       n0 j                  j%                  d	|j&                  z          ||        j                   j)                           ||        j                  r* j                   j+                           j-                           j                   j                         syy# t        $ r}|j                  t        j                  j                  k(  rD j                  j                  |t               d           j                  j                  |d       nP|j                  t        j                  j                  k(  r( j                  j                  |t               d          n Y d}~d}~ww xY w)
z9Invoke IDLE mode until timeout or self.stop() is invoked.c                     | \  }}}|!j                   j                         sd_        j                   j                          y)a   IDLE callback function invoked by imaplib2.

            This is invoked when a) The IMAP server tells us something
            while in IDLE mode, b) we get an Exception (e.g. on dropped
            connections, or c) the standard imaplib IDLE timeout of 29
            minutes kicks in.NT)r  rl  needsyncr  )rU  resultcb_argexc_datark   s       rl   callbackz#IdleThread.__idle.<locals>.callbackW  s=     (,$FFH(;(;(= $MMrn   c                    	 | j                          j                  j                  |        y# | j                  $ rG j                  j                  d| j                  z         j                  j                  | d       Y yw xY w)zFactorize the noop code.r  TN)r  r  r{  r  r   r~   r  )r   rk   s    rl   r  zIdleThread.__idle.<locals>.noope  so    7 --g6 == =G$//0 1--gt<=s   / ABBFTr   NIDLE)r  zFIMAP IDLE not supported on server '%s'.Sleep until next refresh cycle.)r  rl  r  r  rd  selectr  r   rb  r%   FOLDER_RETRYr   r   r   r{  FOLDERr   r  r~   r  ro  clear_IdleThread__dosync)rk   r  r  r\  r   r   s   `     rl   __idlezIdleThread.__idleT  s   	 	7 --%%'!DMG++779#NN4;;/ #G! " ---h/ ?AHASAST UWMM M}} ##%E --%%'' ( 
zz%5%;%;%H%HHaA755gtD'7'='='D'DDaA7 
s   D4 4	H=B;G>>Hr  )
r|  r}  r~  rm   rn  rp  r   r  r  r  r  rn   rl   rm  rm    s&    $%(-@ rn   rm  )$r   r   r   r   urllib.requestr   urllib.parseurllib.errorr!  rS  r5   r   sysr   sslr   r   	threadingr   r   r	   r
   r   offlineimap.accountsrD  r   r   r   r   offlineimap.uir   rg   r   r}   r   rm  r  rn   rl   <module>r     s}   $             . J J  K K &H
j! j!Z|  | c  Hs   "A= =BB