o ]Lb@Z@sddlmZddlZddlZddlmZddlmZddlm Z mZm Z m Z m Z m Z ddlmZmZmZdd Zdd d ZGd ddeZddZdddZddZddZGddde jZd ddZd!ddZdS)")absolute_importN)_)getattr)errorpycompatutilwireprototypeswireprotov1peerwireprotov1server)procutil stringutilurlutilcCs(|s|Std|r |Sd|ddS)z=quote a string for the remote shell ... which we assume is shs[a-zA-Z0-9@%_+=:,./-]*$s'%s''s'\'')rematchreplace)sr3/usr/lib/python3/dist-packages/mercurial/sshpeer.py _serverquotes  rFcCsV|r#|js%t|}|r'|r|jn|j}|D]}|td|dqdSdSdSdS)zYdisplay all data currently available on pipe as remote output. This is non blocking.remote:  N)closedr readpipewarnstatus splitlinesr)uipiperrdisplaylrrr_forwardoutput's   r"c@sfeZdZdZddZddZddZdd Zd d Zd d Z dddZ ddZ e ddZ ddZdS) doublepipea3Operate a side-channel pipe in addition of a main one The side-channel pipe contains server output to be forwarded to the user input. The double pipe will behave as the "main" pipe, but will ensure the content of the "side" pipe is properly processed while we wait for blocking call on the "main" pipe. If large amounts of data are read from "main", the forward will cease after the first bytes start to appear. This simplifies the implementation without affecting actual output of sshpeer too much as we rarely issue large read for data not yet emitted by the server. The main pipe is expected to be a 'bufferedinputpipe' from the util module that handle all the os specific bits. This class lives in this module because it focus on behavior specific to the ssh protocol.cCs||_||_||_dSN)_ui_main_side)selfrmainsiderrr__init__Ds zdoublepipe.__init__cCspt|jtjr |jjr dS|j|jg}zt|}Wn ty)|}Ynw|j|v|j|vfS)zwait until some data are available on main or side return a pair of boolean (ismainready, issideready) (This will only wait for data if the setup is supported by `util.poll`) )TT) isinstancer&rbufferedinputpipe hasbufferfilenor'pollNotImplementedError)r(fdsactrrr_waitIs  zdoublepipe._waitcCs |d|S)Nswrite_call)r(datarrrwrite_ zdoublepipe.writecC*|d|}|dkr|st|j|j|S)Nsreadrr6r"r%r'r(sizerrrrreadb  zdoublepipe.readcCr:)Nsunbufferedreadrr;r<rrrunbufferedreadmr@zdoublepipe.unbufferedreadcCs |dS)Nsreadliner5r(rrrreadlinex zdoublepipe.readlineNcCsn|dur|r |jjrt|j|jdS |\}}|r#t|j|j|r6t|j|}|dur2|S||Sq)zBcall on "main", forward output of "side" while blockingN)r&rr"r%r'r4r)r(methnamer7 mainready sidereadymethrrrr6{s  zdoublepipe._callcC |jSr$)r&closerBrrrrKrDzdoublepipe.closecCs|jjSr$)r&rrBrrrrszdoublepipe.closedcCrJr$)r&flushrBrrrrLrDzdoublepipe.flushr$)__name__ __module__ __qualname____doc__r+r4r8r?rArCr6rKpropertyrrLrrrrr#3s    r#c Csd}|r |js d}||r|jsd}||r>|js>d}z|D] }|td|q"Wn ttfy9Ynw||rM|durO|d|dSdSdS)z)Clean up pipes used by an SSH connection.FTrNs.missing close on SSH connection created at: %s)rrKrrIOError ValueError develwarn)rpipeipipeopipeer didsomethingr!rrr _cleanuppipess(    rYc CsVd||tdt|t|ff}|d|tj|d|d\}}} } | ||| fS)zCreate an SSH connection to a server. Returns a tuple of (process, stdin, stdout, stderr) for the spawned process. %s %s %ss%s -R %s serve --stdio running %s r)bufsizeenv)r shellquoterdebugpopen4) rsshcmdargs remotecmdpathsshenvcmdstdinstdoutstderrprocrrr_makeconnections  rkcCs6dh}ddtjtjD}|dd||S)zwReturn list of capabilities of this client. Returns a list of capabilities that are supported by this client. s partial-pullcSsg|]}|jqSr)wireprotosupportname).0errr sz'_clientcapabilities..scomp=%s,)r compenginessupportedwireengines CLIENTROLEaddjoin) protoparamscompsrrr_clientcapabilitiess  rycsfdd}dd}ttt}z6dd}ddd t||g}|r5d d t|d d |d || Wn t yX|Ynwt j } tdt|} ddg} d} | dr| rz?|} tdd| | }|r|d} d| Wn4| ddkr| dkrWn(| rd| | | | d8} Wn t y|Ynw| dr| sr|t}| t j krt| D]} | dr|| ddddnq|s|tdd| |fS)Ncs0tddtd}dd}tj||d)NTrs#no suitable response from remote hguis ssherrorhinthint)r"rconfigr RepoError)msgr}rirrr badresponses z&_performhandshake..badresponsedeveldebug.peer-requests%s-%s)(0000000000000000000000000000000000000000rshello sbetween s pairs %d s"devel-peer-request: hello+between s&devel-peer-request: pairs: %d bytes ssending hello command ssending between command rEs^upgraded %s (.*)$sdummyiTrzrsprotocol upgraded to %s s1 rrs capabilities::) configboolrsysbytesstruuiduuid4lenr_r8rvrLrRr SSHV1rcompiler reescaperCr"rgroupappendsetreversed startswithupdatesplit)rrgrhrir requestlogtokenpairsarg handshake protoname reupgradedlines max_noiser!mcapsrrr_performhandshakesn @                     rc@seZdZ d-ddZdhZddZddZd d Zd d Zd dZ ddZ ddZ ddZ d.ddZ ddZd/ddZddZdd Zd!d"Zd#d$Zd%d&Zd'd(Zd)d*Zd/d+d,ZdS)0 sshv1peerTc Csh||_||_||_|rt|t||}t|||}||_||_||_||_ ||_ d t d|_ dS)aCreate a peer from an existing SSH connection. ``proc`` is a handle on the underlying SSH process. ``stdin``, ``stdout``, and ``stderr`` are handles on the stdio pipes for that process. ``caps`` is a set of capabilities supported by the remote. ``autoreadstderr`` denotes whether to automatically read from stderr and to forward its output. rErN)_urlr _subprocessr#rr-_pipeo_pipei_pipee_caps_autoreadstderrrvgetstackframes _initstack) r(rurlrjrgrhrirautoreadstderrrrrr+ws  zsshv1peer.__init__sbatchcC|jSr$)rrBrrrrz sshv1peer.urlcCsdSr$rrBrrrlocalzsshv1peer.localcCs|Sr$rrBrrrpeerrzsshv1peer.peercCsdS)NTrrBrrrcanpushrzsshv1peer.canpushcCs |dSr$_cleanuprBrrrrKr9zsshv1peer.closecCrr$)rrBrrr capabilitiesrzsshv1peer.capabilitiescCst|j|jdSr$)r"rrrBrrr_readerrzsshv1peer._readerrcCs ||r$r)r( exceptionrrr_abortszsshv1peer._abortNcCst|j|j|j|j|ddSNrz)rYrrrr)r(rrrrrszsshv1peer._cleanupcCs|j|jddSr)rrrBrrr__del__rzsshv1peer.__del__FcCs|jjrL|jddrL|jj}d}|||t|D].\}}t|ts3||d|t|fqt|D]\}} ||d||t| fq9q|jd||j d|t j |\} } | } i} | D]}|dkrw|| d<n ||| |<||=qktt| D]8\}}|j d |t|ft|trt|D]\}} |j d |t| f|j | qq|j |q|j |r|}t|j|S|jS) Nrrsdevel-peer-request: %s s %s: %d bytess %s-%s: %dssending %s command s%s *s%s %d )r debugflagrr_sorteditemsr,dictrrr8r commandsrr iteritemsrL _getamountr cappedreaderr)r(rfrbframeddbglinekeyvaluedkdv_funcnameskeyswireargskvamountrrr _sendrequestsH     zsshv1peer._sendrequestcK t|}|j||||jvdSNrr byteskwargsr_FRAMED_COMMANDSr(rfrbrrr _callstream zsshv1peer._callstreamcKrrrrrrr_callcompressablerzsshv1peer._callcompressablecKst|}|j||ddS)NTr)rrrr?rrrrr6s zsshv1peer._callc sn|j|fi|}|rd|fStfdddD]}||q|jddd|}|r1d|fS|dfS)NrEc dSNir?rfprr z%sshv1peer._callpush..TrL)r6iter _writeframed _readframedr(rfrrbr>drrr _callpushs  zsshv1peer._callpushc s^|j|fi|}|rttd|tfdddD]}||q|jddd|jS)Nsunexpected remote reply: %scrrrrrrrrrz-sshv1peer._calltwowaystream..rETr)r6rAbortrrrrrrrr_calltwowaystreams zsshv1peer._calltwowaystreamc Cs~|j}|dkr|jr|td}|tj|d|jr$|zt|WSt y>|t td|YdSw)Nrscheck previous remote outputr|sunexpected response:) rrCrrrrrOutOfBandErrorintrS ResponseError)r(r!rrrrr!s   zsshv1peer._getamountcCs|}|sdS|j|S)NrE)rrr?)r(r=rrrr/s zsshv1peer._readframedcCsH|jdt||r|j||r|j|jr"|dSdS)Ns%d )rr8rrLrr)r(r7rLrrrr6s   zsshv1peer._writeframedTr$F)rMrNrOr+rrrrrrKrrrrrrrrr6rrrrrrrrrrvs0 "  -rTc Csz t||||\}}Wntyt||||ddw|tjkr.t||||||||dSt||||ddttd|)aMake a peer instance from existing pipes. ``path`` and ``proc`` are stored on the eventual peer instance and may not be used for anything meaningful. ``stdin``, ``stdout``, and ``stderr`` are the pipes connected to the SSH server's stdio handles. This function is factored out to allow creating peers that don't actually spawn a new process. It is useful for starting SSH protocol servers and clients via non-standard means, which can be useful for testing. Nrz)rs#unknown version of SSH protocol: %s) r ExceptionrYr rrrrr) rrdrjrgrhrirrrrrrmakepeer@s*    rc Cstj|ddd}|jdks|jr|jdurttd|t||j dur/ttd| dd}| dd}t | d }t |} |jpKd } t ||j|j|j} |r|rbttd d || t d t|t| ff} |d| |j| d| d} | dkrttdt||| || | \}}}}t||||||}d|vrz|jddttdW|Sty|ttdw|S)ziCreate an SSH peer. The returned object conforms to the ``wireprotov1peer.wirepeer`` interface. F) parsequery parsefragmentssshNscouldn't parse location %sspassword in URL not supportedr{s remotecmdssshenv.s8cannot create remote SSH repositories with extra optionsrZs %s init %sr[ssshpeer) blockedtagenvironrscould not create remote repos protocaps )rscapability exchange failed)rrschemehostrdrrr checksafesshpasswdr~r configitemsr shellenvironsshargsuserportr^rr_systemrkrrr6rvrryrRr)rrdcreateintents createoptsurarc sshaddenvre remotepathrbrfresrjrgrhrirrrrinstancefs^          rrr$r)NN) __future__rrri18nrrrrrr r r utilsr r rrr"objectr#rYrkryrwirepeerrrrrrrrs&      d  K&