ϪfdZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl m Z m Z mZmZddlmZmZmZddlmZmZmZmZddlmZmZmZmZddlmZddl m!Z!m"Z"m#Z#dd l$m%Z%Gd d ejLZ'd Z(d Z)dZ*dZ+dZ,GddZ-Gddej\Z/e0e/de/jbGddejdZ2GddejfZ4e5dk(re(yy)z0 Implementation module for the I{cftp} command. N)ListOptionalTextIOUnion)connectdefaultoptions)channelcommon connection filetransfer)deferreactorstdioutils)basic)failurelogusage)FilePathceZdZUdZdZgdgdgdgdgZeeeee e fe d<e jdd ie je jd g ZddZy ) ClientOptionszUsage: cftp [options] [user@]host cftp [options] [user@]host[:dir[/]] cftp [options] [user@]host[:file [localfile]] zncftp is a client for logging into a remote machine and executing commands to send and receive file information) buffersizeBiz0Size of the buffer to use for sending/receiving.) batchfilebNz-File to read commands from, or '-' for stdin.)requestsRz6Number of requests to make before waiting for a reply.) subsystemssftpz'Subsystem/server program to connect to. optParametersrz,Size of send/receive buffer (default: 32768)z local file)descr) descriptions extraActionsNcd|d<d|vr,|jdd\}|d<|djd||d<||d<y)N remotePath:/host localPath)splitrstrip)selfr-r.s s 88ABd:Z?d;Z@d<ZAd=ZBd>ZCy)B StdioClientzcftp>  NcN||_d|_||_| xrdxsd|_y)Nr(r+r)clientcurrentDirectoryfileuseProgressBar)r1rrps r2r|zStdioClient.__init__s+ " #$u{0qr4cl|jjdj|jy)Nr()rrealPath addCallback _cbSetCurDirr1s r2connectionMadezStdioClient.connectionMades% R ,,T->->?r4c2||_|jyr5)r_newLiner1paths r2rzStdioClient._cbSetCurDirs $ r4czt|tr|jd}|jj |S)Nutf-8) isinstancer;encode transportwrite)r1msgs r2_writeToTransportzStdioClient._writeToTransports/ c3 **W%C~~##C((r4c|jjjryt|tr|j d}t jd|z|j}|s|jy|jr|jdr d|_ |dd}nd|_ |j|}|7|j|j|j!|j"yy)Nrz got line %s-r+r)rr localClosedrbytesdecoderrlstriprr startswith ignoreErrors_dispatchCommandr _cbCommandrh _ebCommand)r1lineds r2 lineReceivedzStdioClient.lineReceiveds ;; , ,  dE ";;w'D  $%{{} MMO  99- !D 8D !D   ! !$ ' = MM$// * LL ) r4cd|vr&|jdd\}}|j}n|d}}|jdr&|j}|dddz|zj }n8|j }t jd|zt|d|zd}|tj||Sd|z}|jtjt||jy)N r+r(!zlooking up cmd %szcmd_%szNo command called `%s')r/rrcmd_EXECstripupperrrr~r maybeDeferredrrr\NotImplementedErrorr)r1rcommandrestrperrMsgs r2rzStdioClient._dispatchCommands $; JJsA.MGT;;=D "TG   c " AABK#%,335DmmoG GG''1 2h0$7A =&&q$/ /-9F OOGOO,?,GH I MMOr4c$tj||jttj t t}|tk(r!|j|jdy|tj k(rAd|jj|jjfz}|j|y|t tfvrAd|jj|jjfz}|j|yy)Nr(zremote error %i: %s zlocal error %i: %s )rrtraprr SFTPErrorOSErrorIOErrorrcmd_HELPrncodemessageerrnostrerror)r1rpers r2 _printFailurezStdioClient._printFailures  FF& (>(> Q # #  " "4==#4 5 ,(( (, aggoo/NNF  " "6 * 7G$ $+qww}}agg>N>N.OOF  " "6 *%r4c|jjjry|j|jd|_|j rr|j j}|s%|jjjy|j||j|jyy)Nr) rrrrpsrrreadlineloseConnectionrr)r1ls r2rzStdioClient._newLines ;; , ,  tww' 99 ""$A %%446&&q)!!!''), r4c|Tt|tr|jd}|j||j ds|jd|j y)Nrr)rr;rrendswithr)r1results r2rzStdioClient._cbCommandsQ  &#&w/  " "6 *??5)&&u- r4c|j||jr0|js$|jjj |j yr5)rrrrrrrr{s r2rzStdioClient._ebCommands> 1 99T.. KK ! ! 0 0 2 r4c`|j|\}}|jds|dz }|xr*tjj |j |xsd}|j j|}|j|j|j|j|S)Nr,r() _getFilenamerosrjoinrr openDirectoryr_cbCdrhr)r1rrnewPathrs r2cmd_CDzStdioClient.cmd_CDs&&t, d}}S! CKDD277<<(=(=tDJ KK % %g . djj! T__%r4c|j|jj|j}|j |j |Sr5)closerrnamer _cbCurDir)r1 directoryrs r2rzStdioClient._cbCds9 KK  0 dnn%r4c||_yr5rrs r2rzStdioClient._cbCurDirs $r4c|jdd\}}|j|\}}t|}|jj |}|j |j |||S)Nr+)grpr/rr<rgetAttrsr _cbSetUsrGrp)r1rrrrs r2 cmd_CHGRPzStdioClient.cmd_CHGRP dJJtQ' T&&t, d#h KK  & d''3 7r4c|jdd\}}|j|\}}t|d}|jj |d|i}|j t |S)Nr+ permissions)r/rr<rsetAttrsrrr)r1rmodrrs r2 cmd_CHMODzStdioClient.cmd_CHMODsaJJtQ' T&&t, d#qk KK  s'; < gr4c|jdd\}}|j|\}}t|}|jj |}|j |j |||S)Nr+)usrr)r1rrrrs r2 cmd_CHOWNzStdioClient.cmd_CHOWNrr4ci}|duxr|xs|d|d<|duxr|xs|d|d<|jj||}|jt|S)Nuidgid)rrrrr)r1attrsrrrnewrs r2rzStdioClient._cbSetUsrGrp"sdo.3>%,E o.3>%,E KK s + gr4c|j|\}}d|vsd|vrg|r4|j|\}}tjj|syd}|j |}|j |j ||S|r|j|\}}n"tjj|d}tj||ft|dd}t|jj|}|jj|jt j"i}|j |j$||j'|j(||S)N*?z'Wildcard get with non-directory target.r4r+wbr)rrrisdir _remoteGlobr_cbGetMultipler/rropenrrchildropenFiler FXF_READ_cbGetOpenFilerh _ebCloseLf)r1rremotelocalrlfrs r2cmd_GETzStdioClient.cmd_GET*s/((.  &=C6M"//5 tww}}U+D  (A MM$--u 5H ++D1KE4GGMM&)!,E  %q !--.44V< KK L,A,A2 F d))2. T__b)r4c(|jd||Sr5)_cbGetMultipleNext)r1filesrs r2rzStdioClient._cbGetMultipleBs&&tUE::r4ct|tjr|j|n5|r3|j ||j ds|j d|sy|j dd}ttjj|tjj|ddd}t|jj|}|jj!|jt"j$i}|j'|j(||j+|j,||j/|j0|||S)N rr+r)rrr\rrrpoprrrrr/rrrrrr rrrrhraddBothr)r1resrrrprrrs r2rzStdioClient._cbGetMultipleNextFs  c7?? +   s #   " "3 '<<%&&t,  IIaLO "'',,ubggmmA&6q&9:D! D--.44Q7 KK L,A,A2 F d))2. T__b) $))5%8r4c&|j|Sr5)r)r1rprs r2rzStdioClient._ebCloseLfXs  r4cX|jj|j||Sr5)rr_cbGetFileSize)r1rfrs r2rzStdioClient._cbGetOpenFile\s#{{}(()<) %i)rrr\rrrEOFErrorrHrlenrxrrwr_printProgressBarr! readChunkrr) r1datar rrstartrzrreasonrTrlengthrs r2rzStdioClient._cbGetReads JtW__5 GG&- .F KK ! eUT\23Aq MM!eU^ ,  GG'#d)3 4 GGEN HHTN4yD =TD@QQRLL%!671I a%T):!;< HHD !H     " "2y 1""6* !ME6 %(??@ LL ' $//2r65&)Lr4ctjd|j|j|jr|j dd|j d|j S)Nzget doner Transferred  to )rrrrrrr1ignoredr rs r2rzStdioClient._cbGetDonesR          " "4 (bggYd277)44r4c|j|\}}d|vsd|vrj|r?|j|\}}tjj|j|}nd}t j |}|j ||S|r|j|\}}n"tjj|d}|j||S)a# Do an upload request for a single local file or a globing expression. @param rest: Requested command line for the PUT command. @type rest: L{str} @return: A deferred which fires with L{None} when transfer is done. @rtype: L{defer.Deferred} rrr(r+) rrrrrglob_putMultipleFilesr/_putSingleFile)r1rrrrs r2cmd_PUTzStdioClient.cmd_PUTs''- t %<3%<#006 d&;&;VDIIe$E))%8 8#006 u-a0&&uf5 5r4c.|jd|g|dS)aB Perform an upload for a single file. @param local: Path to local file. @type local: L{str}. @param remote: Remote path for the request relative to current working directory. @type remote: L{str} @return: A deferred which fires when transfer is done. NT)single_cbPutMultipleNext)r1rrs r2r3zStdioClient._putSingleFiles &&teWfT&JJr4c(|jd||S)aV Perform an upload for a list of local files. @param files: List of local files. @type files: C{list} of L{str}. @param remote: Remote path for the request relative to current working directory. @type remote: L{str} @return: A deferred which fires when transfer is done. Nr7)r1rrs r2r2zStdioClient._putMultipleFiless&&tUF;;r4ct|tjr|j|nV|rTt|tr|j d}|j ||jds|j dd}|r%|s# |jd}t|d}|r|s#|sy|r|}nZtjj|d}tjj||}tj |||f|j#|} | j%|j&||| S#t$r(|jtjd}YwxYw)a Perform an upload for the next file in the list of local files. @param previousResult: Result form previous file form the list. @type previousResult: L{str} @param files: List of local files. @type files: C{list} of L{str} @param remotePath: Remote path for the request relative to current working directory. @type remotePath: L{str} @param single: A flag which signals if this is a transfer for a single file in which case we use the exact remote path @type single: L{bool} @return: A deferred which fires when transfer is done. rrNrrbr+)rrr\rr;rrrrrrZrrr/rrr_putRemoteFilerr8) r1previousResultrr)r6 currentFile localStreamrrrs r2r8zStdioClient._cbPutMultipleNexts<( ngoo 6   ~ . .#.!/!6!6w!?  " "> 2!**51&&u- K ##iil ";5 K F77==-a0DWW\\*d3F GGT6:. /    V 4 $))5*=#! #""7??#45"  #s D??.E0/E0chtjj|j|}tj tj ztjz}|jj||i}|j|j||j|j||S)aW Do an upload request. @param localStream: Local stream from where data is read. @type localStream: File like object. @param remotePath: Remote path for the request relative to current working directory. @type remotePath: L{str} @return: A deferred which fires when transfer is done. )rrrrr FXF_WRITE FXF_CREAT FXF_TRUNCrrr_cbPutOpenFilerhr)r1r?r)rflagsrs r2r<zStdioClient._putRemoteFilesd33Z@&&)?)??,BXBXX KK  3 d));7 T__k2r4c|jjjjd}|jr t |}g}g}|j j}t|D]+}|jd||||}|s|j|-tj|d} | j|j||| S)Nrr+r )rrrjr rrtrrr _cbPutWriterrrr _cbPutDone) r1r rrrrrrTrrs r2rDzStdioClient._cbPutOpenFile+skk++0088D   RBLL((* {# A  r2vyAA Q    : tB/ r4cV|j|}|\}}|j||j|} |jr0|xjt | z c_|j ||| r3|j|| } | j|j||||| Syr5) r!rxreadrrwr$r% writeChunkrrG) r1r/r rrrrr(rzr'rs r2rGzStdioClient._cbPutWrite:s""6* t wwt}    HHD !H  " "2y 1  eT*A MM$**BFI FH r4c|j|j|jr|jdd|jd|jS)Nrr,r-)rrrrr.s r2rHzStdioClient._cbPutDoneIsF        " "4 (bggYd277)44r4c.tj|yr5)rchdirrs r2cmd_LCDzStdioClient.cmd_LCDPs  r4cj|\}}j|\}}tfd||f\}}jj||j t S)NcXtjjj|Sr5rrrrxr1s r2z$StdioClient.cmd_LN..Wbggll4#8#8!<r4)rmaprmakeLinkrrr)r1rlinkpath targetpaths` r2cmd_LNzStdioClient.cmd_LNSsi**40$,,T2 D" T *{{##Hj9EEgNNr4c&g}|j}|rn|dri|dddk(r^|jddd}|D]2}|dk(r|jd|dk(s!|jd4|r|dr |dddk(r^dj|}|j |\}}|s|j d z}n*t jj|j |}|j|}|j|j||S) Nrrr+rverboseaallrr,) r/rrrrrrrrr_cbDisplayFiles)r1rr optsorfullPathrs r2cmd_LSzStdioClient.cmd_LS[s  zz|tAw471:#488A;qr?D *8"GNN9-#X"GNN5)  *tAw471:#4xx~&&t, d,,s2Hww||D$9$94@H   X & d**G4r4c |jd|vr$|Dcgc]}|djdr|}}d|vr|Dcgc]}|d }}n|Dcgc]}|d }}|sydj|Scc}wcc}wcc}w)Nr_r.r]r+r)sortrr)r1rr rpliness r2r`zStdioClient._cbDisplayFilests   %C1QqT__T-BQCEC  #()aQqT)E)#()aQqT)E)::e$ $D))sA6A6 A; Bc|j|\}}tjj|j|}|j j |ijtSr5) rrrrrr makeDirectoryrrrr1rrs r2 cmd_MKDIRzStdioClient.cmd_MKDIRsR&&t, dww||D1148{{((r2>>wGGr4c|j|\}}tjj|j|}|j j |jtSr5) rrrrrrremoveDirectoryrrrrks r2 cmd_RMDIRzStdioClient.cmd_RMDIRsP&&t, dww||D1148{{**40<.rVr4)rrWr renameFilerrr)r1roldpathnewpaths` r2 cmd_RENAMEzStdioClient.cmd_RENAMEsh))$/ ))$/  P {{%%gw7CCGLLr4cL|jjjyr5)rrrr1r/s r2cmd_EXITzStdioClient.cmd_EXITs ,,.r4czd|jjz}t|tr|j d}|S)NzSFTP version %ir)rversionrr;r)r1r/rs r2 cmd_VERSIONzStdioClient.cmd_VERSIONs3#dkk&9&99 gs #nnW-Gr4cy)NaeAvailable commands: cd path Change remote directory to 'path'. chgrp gid path Change gid of 'path' to 'gid'. chmod mode path Change mode of 'path' to 'mode'. chown uid path Change uid of 'path' to 'uid'. exit Disconnect from the server. get remote-path [local-path] Get remote file. help Get a list of available commands. lcd path Change local directory to 'path'. lls [ls-options] [path] Display local directory listing. lmkdir path Create local directory. ln linkpath targetpath Symlink remote file. lpwd Print the local working directory. ls [-l] [path] Display remote directory listing. mkdir path Create remote directory. progress Toggle progress bar. put local-path [remote-path] Put local file. pwd Print the remote working directory. quit Disconnect from the server. rename oldpath newpath Rename remote file. rmdir path Remove remote directory. rm path Remove remote file. version Print the SFTP version. ? Synonym for 'help'. rBrs r2rzStdioClient.cmd_HELPsr4c|jSr5rrs r2cmd_PWDzStdioClient.cmd_PWDs$$$r4c*tjSr5)rgetcwdrs r2cmd_LPWDzStdioClient.cmd_LPWDsyy{r4cT|j |_d|jxrdxsdzS)Nz%ssing progess bar.UzNot u)rrs r2 cmd_PROGRESSzStdioClient.cmd_PROGRESSs."&"5"55$(;(;(C(NwOOr4c|jjtjd}|sd}|rd|g}t j ||dSt j|y)zb Run C{rest} using the user's shell (or /bin/sh if they do not have one). z/bin/shz-cr+)errortooN)_pwdgetpwnamrcrdrgetProcessOutputrrr)r1rshellcmdss r2rzStdioClient.cmd_EXECsY  ""7??#45a8E $ ' NFFf} '&00r4c|dkDr4t|dz }|d|zz}t|dz }|d|zz}d|||fzSt|dz }|d|zz}d||fzS)Ni<z %i:%02i:%02iz %02i:%02i)r<)r1thoursminss r2 _abbrevTimezStdioClient._abbrevTimesy t8DME  Aq2v;D dNA!UD!$44 4q2v;D dNA$* *r4cx|jj|z }|j} tjdt j dtjd}|dk(rd}n||z }|r|j|z |z }nd}|j}|jr||jz dz} nd} d| |j||j||j|fz} |d t|t| zd zz d z} d || | } |j| y#t$rddg}YwxYw) a Update a console progress bar on this L{StdioClient}'s transport, based on the difference between the start time of the operation and the current time according to the reactor, and appropriate to the size of the console window. @param f: a wrapper around the file which is being written or read @type f: L{FileWrapper} @param startTime: The time at which the operation being tracked began. @type startTime: L{float} 4Hr12345679NPrvdz%3i%% %s %sps %s r+r )rrrwstructunpackfcntlioctltty TIOCGWINSZrrzrrrr$r) r1rprdiffrwwinSizespeedtimeLeftfront percentagebackspacesrs r2r%zStdioClient._printProgressBar&sA||##% 1 !mmD%++a*TUG 3;EDLE %/HH 66!&&.C/JJ"    U #   U #   X & &   !*E SY 6 :;sBugfXdV, w'/ !RjG !s9D)) D98D9c6|j}|sy|ddvrg}t|} tdt|D]}||}||dk(r8dj |dj ||dzdj fcS|dk(r0||=||dvrt d |||j||}|j|| |jdd}t|dk(r|ddfS|d|dfS#t $r t d wxYw) aW Parse line received as command line input and return first filename together with the remaining line. @param line: Arguments received from command line input. @type line: L{str} @return: Tupple with filename and rest. Return empty values when no path was not found. @rtype: C{tupple} )r(r(rz'"r+r(N\z'"\z bad quote: \zunterminated quote) rlistrr$rr IndexErrorrr/)r1rretrTcs r2rzStdioClient._getFilenamePs;zz| 7e C:D 7q#d), ,AQADG|!wws|RWWT!a%']-C-J-J-LLLd G7'1",}T!WI-F"GG 47+ 47+ ,jjq! s8q=q62: q63q6> !  7 !566 7sADA DDr5)NN)F)Dr6r7r8pwdrr delimiterrr|rrrrrrrrrrrrrrrrrrrrrrr!rrr4r3r2r8r<rDrGrHrOr[rdr`rlrorsrvrxr~rcmd_QUITrrrrrrrrrrrrr%rrBr4r2rrsO D BIG1 @) *(( + -  %0;$F& <56> K <3j&  5O2 %H F %A "M/H 6%P  "   1 +((T#"r4rzcmd_?ceZdZdZy)rec6|jtyr5) openChannel SSHSessionrs r2serviceStartedzSSHConnection.serviceStartedzs &r4N)r6r7r8rrBr4r2rereys'r4rec|eZdZUdZeed<ejZeed<dZ dZ de dedd fd Z d Z d Zd ZdZdZy )rssessionrrOctjd|jz|jjdj drd}nd}|jj ||tj|jjdd}|j|j|jty)Nzsession %s openr r,execr+) wantReply) rridrjr r sendRequestr NSr _cbSubsystemrhri)r1foorequestrs r2 channelOpenzSSHSession.channelOpens !DGG+, 99  [ ) 4 4S 9G!G II ! ! '699TYY%6%6{%CDPQ "  d''( Wr4ctj|_|jj||jj|_d}|j j dr)|j j d}|dk7r t|}tjt|j||_y)Nrr) r FileTransferClientrmakeConnection dataReceivedrjr rr StandardIOr)r1rrpfns r2rzSSHSession._cbSubsystems"557  ""4( KK44  99  [ )"";/BSyH%%k$++q&AB r4rr'returnNc|tjk(rgtjdt |z|j j |jdd|j jyy)Nzgot %s stderr datarbackslashreplace) r EXTENDED_DATA_STDERRrrr$rOrrflush)r1rr's r2 extReceivedzSSHSession.extReceiveds] // / GG(3t94 5l KK  dkk'3EF G KK   q 0r4cbtjd|jjy)Nzgot eof)rrrloseWriteConnectionrs r2 eofReceivedzSSHSession.eofReceiveds   &&(r4cjtjd|z|jj|y)Nzremote side closed %s)rrrj sendClosers r2 closeReceivedzSSHSession.closeReceiveds& '$./ D!r4cL tjy#t$rYywxYwr5)rrYrZrs r2closedzSSHSession.closeds"  LLN   s  ##c8|jjyr5)rpauseProducingrs r2 stopWritingzSSHSession.stopWritings !!#r4c8|jjyr5)rresumeProducingrs r2 startWritingzSSHSession.startWritings ""$r4)r6r7r8rrr=rFrOrrrr<rrrrrrrBr4r2rr~sYD%ZZFF  C9 S9 9 $9 v)" $%r4r__main__)6__doc__rrrcr1rrr rrFrtypingrrrrtwisted.conch.clientrrr twisted.conch.sshr r r r twisted.internetrrrrtwisted.protocolsrtwisted.pythonrrrtwisted.python.filepathr ConchOptionsrrRr]rQrirrrt LineReceiverrsetattrrre SSHChannelrr6rBr4r2rs   00::GG99#..,&G((&D, G&   %%f "%$$f "R Wk223'J,,' h%##h%V zEr4