Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(219)

Side by Side Diff: third_party/twisted_8_1/twisted/conch/scripts/cftp.py

Issue 12261012: Remove third_party/twisted_8_1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 # -*- test-case-name: twisted.conch.test.test_cftp -*-
2 #
3 # Copyright (c) 2001-2004 Twisted Matrix Laboratories.
4 # See LICENSE for details.
5
6 #
7 # $Id: cftp.py,v 1.65 2004/03/11 00:29:14 z3p Exp $
8
9 #""" Implementation module for the `cftp` command.
10 #"""
11 from twisted.conch.client import agent, connect, default, options
12 from twisted.conch.error import ConchError
13 from twisted.conch.ssh import connection, common
14 from twisted.conch.ssh import channel, filetransfer
15 from twisted.protocols import basic
16 from twisted.internet import reactor, stdio, defer, utils
17 from twisted.python import log, usage, failure
18
19 import os, sys, getpass, struct, tty, fcntl, base64, signal, stat, errno
20 import fnmatch, pwd, time, glob
21
22 class ClientOptions(options.ConchOptions):
23
24 synopsis = """Usage: cftp [options] [user@]host
25 cftp [options] [user@]host[:dir[/]]
26 cftp [options] [user@]host[:file [localfile]]
27 """
28
29 optParameters = [
30 ['buffersize', 'B', 32768, 'Size of the buffer to use for se nding/receiving.'],
31 ['batchfile', 'b', None, 'File to read commands from, or \'- \' for stdin.'],
32 ['requests', 'R', 5, 'Number of requests to make before wait ing for a reply.'],
33 ['subsystem', 's', 'sftp', 'Subsystem/server program to conn ect to.']]
34 zsh_altArgDescr = {"buffersize":"Size of send/receive buffer (default: 32768 )"}
35 #zsh_multiUse = ["foo", "bar"]
36 #zsh_mutuallyExclusive = [("foo", "bar"), ("bar", "baz")]
37 #zsh_actions = {"foo":'_files -g "*.foo"', "bar":"(one two three)"}
38 #zsh_actionDescr = {"logfile":"log file name", "random":"random seed"}
39 zsh_extras = ['2::localfile:{if [[ $words[1] == *:* ]]; then; _files; fi}']
40
41 def parseArgs(self, host, localPath=None):
42 self['remotePath'] = ''
43 if ':' in host:
44 host, self['remotePath'] = host.split(':', 1)
45 self['remotePath'].rstrip('/')
46 self['host'] = host
47 self['localPath'] = localPath
48
49 def run():
50 # import hotshot
51 # prof = hotshot.Profile('cftp.prof')
52 # prof.start()
53 args = sys.argv[1:]
54 if '-l' in args: # cvs is an idiot
55 i = args.index('-l')
56 args = args[i:i+2]+args
57 del args[i+2:i+4]
58 options = ClientOptions()
59 try:
60 options.parseOptions(args)
61 except usage.UsageError, u:
62 print 'ERROR: %s' % u
63 sys.exit(1)
64 if options['log']:
65 realout = sys.stdout
66 log.startLogging(sys.stderr)
67 sys.stdout = realout
68 else:
69 log.discardLogs()
70 doConnect(options)
71 reactor.run()
72 # prof.stop()
73 # prof.close()
74
75 def handleError():
76 from twisted.python import failure
77 global exitStatus
78 exitStatus = 2
79 try:
80 reactor.stop()
81 except: pass
82 log.err(failure.Failure())
83 raise
84
85 def doConnect(options):
86 # log.deferr = handleError # HACK
87 if '@' in options['host']:
88 options['user'], options['host'] = options['host'].split('@',1)
89 host = options['host']
90 if not options['user']:
91 options['user'] = getpass.getuser()
92 if not options['port']:
93 options['port'] = 22
94 else:
95 options['port'] = int(options['port'])
96 host = options['host']
97 port = options['port']
98 conn = SSHConnection()
99 conn.options = options
100 vhk = default.verifyHostKey
101 uao = default.SSHUserAuthClient(options['user'], options, conn)
102 connect.connect(host, port, options, vhk, uao).addErrback(_ebExit)
103
104 def _ebExit(f):
105 #global exitStatus
106 if hasattr(f.value, 'value'):
107 s = f.value.value
108 else:
109 s = str(f)
110 print s
111 #exitStatus = "conch: exiting with error %s" % f
112 try:
113 reactor.stop()
114 except: pass
115
116 def _ignore(*args): pass
117
118 class FileWrapper:
119
120 def __init__(self, f):
121 self.f = f
122 self.total = 0.0
123 f.seek(0, 2) # seek to the end
124 self.size = f.tell()
125
126 def __getattr__(self, attr):
127 return getattr(self.f, attr)
128
129 class StdioClient(basic.LineReceiver):
130
131 ps = 'cftp> '
132 delimiter = '\n'
133
134 def __init__(self, client, f = None):
135 self.client = client
136 self.currentDirectory = ''
137 self.file = f
138 self.useProgressBar = (not f and 1) or 0
139
140 def connectionMade(self):
141 self.client.realPath('').addCallback(self._cbSetCurDir)
142
143 def _cbSetCurDir(self, path):
144 self.currentDirectory = path
145 self._newLine()
146
147 def lineReceived(self, line):
148 if self.client.transport.localClosed:
149 return
150 log.msg('got line %s' % repr(line))
151 line = line.lstrip()
152 if not line:
153 self._newLine()
154 return
155 if self.file and line.startswith('-'):
156 self.ignoreErrors = 1
157 line = line[1:]
158 else:
159 self.ignoreErrors = 0
160 if ' ' in line:
161 command, rest = line.split(' ', 1)
162 rest = rest.lstrip()
163 else:
164 command, rest = line, ''
165 if command.startswith('!'): # command
166 f = self.cmd_EXEC
167 rest = (command[1:] + ' ' + rest).strip()
168 else:
169 command = command.upper()
170 log.msg('looking up cmd %s' % command)
171 f = getattr(self, 'cmd_%s' % command, None)
172 if f is not None:
173 d = defer.maybeDeferred(f, rest)
174 d.addCallback(self._cbCommand)
175 d.addErrback(self._ebCommand)
176 else:
177 self._ebCommand(failure.Failure(NotImplementedError(
178 "No command called `%s'" % command)))
179 self._newLine()
180
181 def _printFailure(self, f):
182 log.msg(f)
183 e = f.trap(NotImplementedError, filetransfer.SFTPError, OSError, IOError )
184 if e == NotImplementedError:
185 self.transport.write(self.cmd_HELP(''))
186 elif e == filetransfer.SFTPError:
187 self.transport.write("remote error %i: %s\n" %
188 (f.value.code, f.value.message))
189 elif e in (OSError, IOError):
190 self.transport.write("local error %i: %s\n" %
191 (f.value.errno, f.value.strerror))
192
193 def _newLine(self):
194 if self.client.transport.localClosed:
195 return
196 self.transport.write(self.ps)
197 self.ignoreErrors = 0
198 if self.file:
199 l = self.file.readline()
200 if not l:
201 self.client.transport.loseConnection()
202 else:
203 self.transport.write(l)
204 self.lineReceived(l.strip())
205
206 def _cbCommand(self, result):
207 if result is not None:
208 self.transport.write(result)
209 if not result.endswith('\n'):
210 self.transport.write('\n')
211 self._newLine()
212
213 def _ebCommand(self, f):
214 self._printFailure(f)
215 if self.file and not self.ignoreErrors:
216 self.client.transport.loseConnection()
217 self._newLine()
218
219 def cmd_CD(self, path):
220 path, rest = self._getFilename(path)
221 if not path.endswith('/'):
222 path += '/'
223 newPath = path and os.path.join(self.currentDirectory, path) or ''
224 d = self.client.openDirectory(newPath)
225 d.addCallback(self._cbCd)
226 d.addErrback(self._ebCommand)
227 return d
228
229 def _cbCd(self, directory):
230 directory.close()
231 d = self.client.realPath(directory.name)
232 d.addCallback(self._cbCurDir)
233 return d
234
235 def _cbCurDir(self, path):
236 self.currentDirectory = path
237
238 def cmd_CHGRP(self, rest):
239 grp, rest = rest.split(None, 1)
240 path, rest = self._getFilename(rest)
241 grp = int(grp)
242 d = self.client.getAttrs(path)
243 d.addCallback(self._cbSetUsrGrp, path, grp=grp)
244 return d
245
246 def cmd_CHMOD(self, rest):
247 mod, rest = rest.split(None, 1)
248 path, rest = self._getFilename(rest)
249 mod = int(mod, 8)
250 d = self.client.setAttrs(path, {'permissions':mod})
251 d.addCallback(_ignore)
252 return d
253
254 def cmd_CHOWN(self, rest):
255 usr, rest = rest.split(None, 1)
256 path, rest = self._getFilename(rest)
257 usr = int(usr)
258 d = self.client.getAttrs(path)
259 d.addCallback(self._cbSetUsrGrp, path, usr=usr)
260 return d
261
262 def _cbSetUsrGrp(self, attrs, path, usr=None, grp=None):
263 new = {}
264 new['uid'] = (usr is not None) and usr or attrs['uid']
265 new['gid'] = (grp is not None) and grp or attrs['gid']
266 d = self.client.setAttrs(path, new)
267 d.addCallback(_ignore)
268 return d
269
270 def cmd_GET(self, rest):
271 remote, rest = self._getFilename(rest)
272 if '*' in remote or '?' in remote: # wildcard
273 if rest:
274 local, rest = self._getFilename(rest)
275 if not os.path.isdir(local):
276 return "Wildcard get with non-directory target."
277 else:
278 local = ''
279 d = self._remoteGlob(remote)
280 d.addCallback(self._cbGetMultiple, local)
281 return d
282 if rest:
283 local, rest = self._getFilename(rest)
284 else:
285 local = os.path.split(remote)[1]
286 log.msg((remote, local))
287 lf = file(local, 'w', 0)
288 path = os.path.join(self.currentDirectory, remote)
289 d = self.client.openFile(path, filetransfer.FXF_READ, {})
290 d.addCallback(self._cbGetOpenFile, lf)
291 d.addErrback(self._ebCloseLf, lf)
292 return d
293
294 def _cbGetMultiple(self, files, local):
295 #if self._useProgressBar: # one at a time
296 # XXX this can be optimized for times w/o progress bar
297 return self._cbGetMultipleNext(None, files, local)
298
299 def _cbGetMultipleNext(self, res, files, local):
300 if isinstance(res, failure.Failure):
301 self._printFailure(res)
302 elif res:
303 self.transport.write(res)
304 if not res.endswith('\n'):
305 self.transport.write('\n')
306 if not files:
307 return
308 f = files.pop(0)[0]
309 lf = file(os.path.join(local, os.path.split(f)[1]), 'w', 0)
310 path = os.path.join(self.currentDirectory, f)
311 d = self.client.openFile(path, filetransfer.FXF_READ, {})
312 d.addCallback(self._cbGetOpenFile, lf)
313 d.addErrback(self._ebCloseLf, lf)
314 d.addBoth(self._cbGetMultipleNext, files, local)
315 return d
316
317 def _ebCloseLf(self, f, lf):
318 lf.close()
319 return f
320
321 def _cbGetOpenFile(self, rf, lf):
322 return rf.getAttrs().addCallback(self._cbGetFileSize, rf, lf)
323
324 def _cbGetFileSize(self, attrs, rf, lf):
325 if not stat.S_ISREG(attrs['permissions']):
326 rf.close()
327 lf.close()
328 return "Can't get non-regular file: %s" % rf.name
329 rf.size = attrs['size']
330 bufferSize = self.client.transport.conn.options['buffersize']
331 numRequests = self.client.transport.conn.options['requests']
332 rf.total = 0.0
333 dList = []
334 chunks = []
335 startTime = time.time()
336 for i in range(numRequests):
337 d = self._cbGetRead('', rf, lf, chunks, 0, bufferSize, startTime)
338 dList.append(d)
339 dl = defer.DeferredList(dList, fireOnOneErrback=1)
340 dl.addCallback(self._cbGetDone, rf, lf)
341 return dl
342
343 def _getNextChunk(self, chunks):
344 end = 0
345 for chunk in chunks:
346 if end == 'eof':
347 return # nothing more to get
348 if end != chunk[0]:
349 i = chunks.index(chunk)
350 chunks.insert(i, (end, chunk[0]))
351 return (end, chunk[0] - end)
352 end = chunk[1]
353 bufSize = int(self.client.transport.conn.options['buffersize'])
354 chunks.append((end, end + bufSize))
355 return (end, bufSize)
356
357 def _cbGetRead(self, data, rf, lf, chunks, start, size, startTime):
358 if data and isinstance(data, failure.Failure):
359 log.msg('get read err: %s' % data)
360 reason = data
361 reason.trap(EOFError)
362 i = chunks.index((start, start + size))
363 del chunks[i]
364 chunks.insert(i, (start, 'eof'))
365 elif data:
366 log.msg('get read data: %i' % len(data))
367 lf.seek(start)
368 lf.write(data)
369 if len(data) != size:
370 log.msg('got less than we asked for: %i < %i' %
371 (len(data), size))
372 i = chunks.index((start, start + size))
373 del chunks[i]
374 chunks.insert(i, (start, start + len(data)))
375 rf.total += len(data)
376 if self.useProgressBar:
377 self._printProgessBar(rf, startTime)
378 chunk = self._getNextChunk(chunks)
379 if not chunk:
380 return
381 else:
382 start, length = chunk
383 log.msg('asking for %i -> %i' % (start, start+length))
384 d = rf.readChunk(start, length)
385 d.addBoth(self._cbGetRead, rf, lf, chunks, start, length, startTime)
386 return d
387
388 def _cbGetDone(self, ignored, rf, lf):
389 log.msg('get done')
390 rf.close()
391 lf.close()
392 if self.useProgressBar:
393 self.transport.write('\n')
394 return "Transferred %s to %s" % (rf.name, lf.name)
395
396 def cmd_PUT(self, rest):
397 local, rest = self._getFilename(rest)
398 if '*' in local or '?' in local: # wildcard
399 if rest:
400 remote, rest = self._getFilename(rest)
401 path = os.path.join(self.currentDirectory, remote)
402 d = self.client.getAttrs(path)
403 d.addCallback(self._cbPutTargetAttrs, remote, local)
404 return d
405 else:
406 remote = ''
407 files = glob.glob(local)
408 return self._cbPutMultipleNext(None, files, remote)
409 if rest:
410 remote, rest = self._getFilename(rest)
411 else:
412 remote = os.path.split(local)[1]
413 lf = file(local, 'r')
414 path = os.path.join(self.currentDirectory, remote)
415 d = self.client.openFile(path, filetransfer.FXF_WRITE|filetransfer.FXF_C REAT, {})
416 d.addCallback(self._cbPutOpenFile, lf)
417 d.addErrback(self._ebCloseLf, lf)
418 return d
419
420 def _cbPutTargetAttrs(self, attrs, path, local):
421 if not stat.S_ISDIR(attrs['permissions']):
422 return "Wildcard put with non-directory target."
423 return self._cbPutMultipleNext(None, files, path)
424
425 def _cbPutMultipleNext(self, res, files, path):
426 if isinstance(res, failure.Failure):
427 self._printFailure(res)
428 elif res:
429 self.transport.write(res)
430 if not res.endswith('\n'):
431 self.transport.write('\n')
432 f = None
433 while files and not f:
434 try:
435 f = files.pop(0)
436 lf = file(f, 'r')
437 except:
438 self._printFailure(failure.Failure())
439 f = None
440 if not f:
441 return
442 name = os.path.split(f)[1]
443 remote = os.path.join(self.currentDirectory, path, name)
444 log.msg((name, remote, path))
445 d = self.client.openFile(remote, filetransfer.FXF_WRITE|filetransfer.FXF _CREAT, {})
446 d.addCallback(self._cbPutOpenFile, lf)
447 d.addErrback(self._ebCloseLf, lf)
448 d.addBoth(self._cbPutMultipleNext, files, path)
449 return d
450
451 def _cbPutOpenFile(self, rf, lf):
452 numRequests = self.client.transport.conn.options['requests']
453 if self.useProgressBar:
454 lf = FileWrapper(lf)
455 dList = []
456 chunks = []
457 startTime = time.time()
458 for i in range(numRequests):
459 d = self._cbPutWrite(None, rf, lf, chunks, startTime)
460 if d:
461 dList.append(d)
462 dl = defer.DeferredList(dList, fireOnOneErrback=1)
463 dl.addCallback(self._cbPutDone, rf, lf)
464 return dl
465
466 def _cbPutWrite(self, ignored, rf, lf, chunks, startTime):
467 chunk = self._getNextChunk(chunks)
468 start, size = chunk
469 lf.seek(start)
470 data = lf.read(size)
471 if self.useProgressBar:
472 lf.total += len(data)
473 self._printProgessBar(lf, startTime)
474 if data:
475 d = rf.writeChunk(start, data)
476 d.addCallback(self._cbPutWrite, rf, lf, chunks, startTime)
477 return d
478 else:
479 return
480
481 def _cbPutDone(self, ignored, rf, lf):
482 lf.close()
483 rf.close()
484 if self.useProgressBar:
485 self.transport.write('\n')
486 return 'Transferred %s to %s' % (lf.name, rf.name)
487
488 def cmd_LCD(self, path):
489 os.chdir(path)
490
491 def cmd_LN(self, rest):
492 linkpath, rest = self._getFilename(rest)
493 targetpath, rest = self._getFilename(rest)
494 linkpath, targetpath = map(
495 lambda x: os.path.join(self.currentDirectory, x),
496 (linkpath, targetpath))
497 return self.client.makeLink(linkpath, targetpath).addCallback(_ignore)
498
499 def cmd_LS(self, rest):
500 # possible lines:
501 # ls current directory
502 # ls name_of_file that file
503 # ls name_of_directory that directory
504 # ls some_glob_string current directory, globbed for that string
505 options = []
506 rest = rest.split()
507 while rest and rest[0] and rest[0][0] == '-':
508 opts = rest.pop(0)[1:]
509 for o in opts:
510 if o == 'l':
511 options.append('verbose')
512 elif o == 'a':
513 options.append('all')
514 rest = ' '.join(rest)
515 path, rest = self._getFilename(rest)
516 if not path:
517 fullPath = self.currentDirectory + '/'
518 else:
519 fullPath = os.path.join(self.currentDirectory, path)
520 d = self._remoteGlob(fullPath)
521 d.addCallback(self._cbDisplayFiles, options)
522 return d
523
524 def _cbDisplayFiles(self, files, options):
525 files.sort()
526 if 'all' not in options:
527 files = [f for f in files if not f[0].startswith('.')]
528 if 'verbose' in options:
529 lines = [f[1] for f in files]
530 else:
531 lines = [f[0] for f in files]
532 if not lines:
533 return None
534 else:
535 return '\n'.join(lines)
536
537 def cmd_MKDIR(self, path):
538 path, rest = self._getFilename(path)
539 path = os.path.join(self.currentDirectory, path)
540 return self.client.makeDirectory(path, {}).addCallback(_ignore)
541
542 def cmd_RMDIR(self, path):
543 path, rest = self._getFilename(path)
544 path = os.path.join(self.currentDirectory, path)
545 return self.client.removeDirectory(path).addCallback(_ignore)
546
547 def cmd_LMKDIR(self, path):
548 os.system("mkdir %s" % path)
549
550 def cmd_RM(self, path):
551 path, rest = self._getFilename(path)
552 path = os.path.join(self.currentDirectory, path)
553 return self.client.removeFile(path).addCallback(_ignore)
554
555 def cmd_LLS(self, rest):
556 os.system("ls %s" % rest)
557
558 def cmd_RENAME(self, rest):
559 oldpath, rest = self._getFilename(rest)
560 newpath, rest = self._getFilename(rest)
561 oldpath, newpath = map (
562 lambda x: os.path.join(self.currentDirectory, x),
563 (oldpath, newpath))
564 return self.client.renameFile(oldpath, newpath).addCallback(_ignore)
565
566 def cmd_EXIT(self, ignored):
567 self.client.transport.loseConnection()
568
569 cmd_QUIT = cmd_EXIT
570
571 def cmd_VERSION(self, ignored):
572 return "SFTP version %i" % self.client.version
573
574 def cmd_HELP(self, ignored):
575 return """Available commands:
576 cd path Change remote directory to 'path'.
577 chgrp gid path Change gid of 'path' to 'gid'.
578 chmod mode path Change mode of 'path' to 'mode'.
579 chown uid path Change uid of 'path' to 'uid'.
580 exit Disconnect from the server.
581 get remote-path [local-path] Get remote file.
582 help Get a list of available commands.
583 lcd path Change local directory to 'path'.
584 lls [ls-options] [path] Display local directory listing.
585 lmkdir path Create local directory.
586 ln linkpath targetpath Symlink remote file.
587 lpwd Print the local working directory.
588 ls [-l] [path] Display remote directory listing.
589 mkdir path Create remote directory.
590 progress Toggle progress bar.
591 put local-path [remote-path] Put local file.
592 pwd Print the remote working directory.
593 quit Disconnect from the server.
594 rename oldpath newpath Rename remote file.
595 rmdir path Remove remote directory.
596 rm path Remove remote file.
597 version Print the SFTP version.
598 ? Synonym for 'help'.
599 """
600
601 def cmd_PWD(self, ignored):
602 return self.currentDirectory
603
604 def cmd_LPWD(self, ignored):
605 return os.getcwd()
606
607 def cmd_PROGRESS(self, ignored):
608 self.useProgressBar = not self.useProgressBar
609 return "%ssing progess bar." % (self.useProgressBar and "U" or "Not u")
610
611 def cmd_EXEC(self, rest):
612 shell = pwd.getpwnam(getpass.getuser())[6]
613 print repr(rest)
614 if rest:
615 cmds = ['-c', rest]
616 return utils.getProcessOutput(shell, cmds, errortoo=1)
617 else:
618 os.system(shell)
619
620 # accessory functions
621
622 def _remoteGlob(self, fullPath):
623 log.msg('looking up %s' % fullPath)
624 head, tail = os.path.split(fullPath)
625 if '*' in tail or '?' in tail:
626 glob = 1
627 else:
628 glob = 0
629 if tail and not glob: # could be file or directory
630 # try directory first
631 d = self.client.openDirectory(fullPath)
632 d.addCallback(self._cbOpenList, '')
633 d.addErrback(self._ebNotADirectory, head, tail)
634 else:
635 d = self.client.openDirectory(head)
636 d.addCallback(self._cbOpenList, tail)
637 return d
638
639 def _cbOpenList(self, directory, glob):
640 files = []
641 d = directory.read()
642 d.addBoth(self._cbReadFile, files, directory, glob)
643 return d
644
645 def _ebNotADirectory(self, reason, path, glob):
646 d = self.client.openDirectory(path)
647 d.addCallback(self._cbOpenList, glob)
648 return d
649
650 def _cbReadFile(self, files, l, directory, glob):
651 if not isinstance(files, failure.Failure):
652 if glob:
653 l.extend([f for f in files if fnmatch.fnmatch(f[0], glob)])
654 else:
655 l.extend(files)
656 d = directory.read()
657 d.addBoth(self._cbReadFile, l, directory, glob)
658 return d
659 else:
660 reason = files
661 reason.trap(EOFError)
662 directory.close()
663 return l
664
665 def _abbrevSize(self, size):
666 # from http://mail.python.org/pipermail/python-list/1999-December/018395 .html
667 _abbrevs = [
668 (1<<50L, 'PB'),
669 (1<<40L, 'TB'),
670 (1<<30L, 'GB'),
671 (1<<20L, 'MB'),
672 (1<<10L, 'kb'),
673 (1, '')
674 ]
675
676 for factor, suffix in _abbrevs:
677 if size > factor:
678 break
679 return '%.1f' % (size/factor) + suffix
680
681 def _abbrevTime(self, t):
682 if t > 3600: # 1 hour
683 hours = int(t / 3600)
684 t -= (3600 * hours)
685 mins = int(t / 60)
686 t -= (60 * mins)
687 return "%i:%02i:%02i" % (hours, mins, t)
688 else:
689 mins = int(t/60)
690 t -= (60 * mins)
691 return "%02i:%02i" % (mins, t)
692
693 def _printProgessBar(self, f, startTime):
694 diff = time.time() - startTime
695 total = f.total
696 try:
697 winSize = struct.unpack('4H',
698 fcntl.ioctl(0, tty.TIOCGWINSZ, '12345679'))
699 except IOError:
700 winSize = [None, 80]
701 speed = total/diff
702 if speed:
703 timeLeft = (f.size - total) / speed
704 else:
705 timeLeft = 0
706 front = f.name
707 back = '%3i%% %s %sps %s ' % ((total/f.size)*100, self._abbrevSize(total ),
708 self._abbrevSize(total/diff), self._abbrevTime(timeLeft))
709 spaces = (winSize[1] - (len(front) + len(back) + 1)) * ' '
710 self.transport.write('\r%s%s%s' % (front, spaces, back))
711
712 def _getFilename(self, line):
713 line.lstrip()
714 if not line:
715 return None, ''
716 if line[0] in '\'"':
717 ret = []
718 line = list(line)
719 try:
720 for i in range(1,len(line)):
721 c = line[i]
722 if c == line[0]:
723 return ''.join(ret), ''.join(line[i+1:]).lstrip()
724 elif c == '\\': # quoted character
725 del line[i]
726 if line[i] not in '\'"\\':
727 raise IndexError, "bad quote: \\%s" % line[i]
728 ret.append(line[i])
729 else:
730 ret.append(line[i])
731 except IndexError:
732 raise IndexError, "unterminated quote"
733 ret = line.split(None, 1)
734 if len(ret) == 1:
735 return ret[0], ''
736 else:
737 return ret
738
739 StdioClient.__dict__['cmd_?'] = StdioClient.cmd_HELP
740
741 class SSHConnection(connection.SSHConnection):
742 def serviceStarted(self):
743 self.openChannel(SSHSession())
744
745 class SSHSession(channel.SSHChannel):
746
747 name = 'session'
748
749 def channelOpen(self, foo):
750 log.msg('session %s open' % self.id)
751 if self.conn.options['subsystem'].startswith('/'):
752 request = 'exec'
753 else:
754 request = 'subsystem'
755 d = self.conn.sendRequest(self, request, \
756 common.NS(self.conn.options['subsystem']), wantReply=1)
757 d.addCallback(self._cbSubsystem)
758 d.addErrback(_ebExit)
759
760 def _cbSubsystem(self, result):
761 self.client = filetransfer.FileTransferClient()
762 self.client.makeConnection(self)
763 self.dataReceived = self.client.dataReceived
764 f = None
765 if self.conn.options['batchfile']:
766 fn = self.conn.options['batchfile']
767 if fn != '-':
768 f = file(fn)
769 self.stdio = stdio.StandardIO(StdioClient(self.client, f))
770
771 def extReceived(self, t, data):
772 if t==connection.EXTENDED_DATA_STDERR:
773 log.msg('got %s stderr data' % len(data))
774 sys.stderr.write(data)
775 sys.stderr.flush()
776
777 def eofReceived(self):
778 log.msg('got eof')
779 self.stdio.closeStdin()
780
781 def closeReceived(self):
782 log.msg('remote side closed %s' % self)
783 self.conn.sendClose(self)
784
785 def closed(self):
786 try:
787 reactor.stop()
788 except:
789 pass
790
791 def stopWriting(self):
792 self.stdio.pauseProducing()
793
794 def startWriting(self):
795 self.stdio.resumeProducing()
796
797 if __name__ == '__main__':
798 run()
799
OLDNEW
« no previous file with comments | « third_party/twisted_8_1/twisted/conch/scripts/__init__.py ('k') | third_party/twisted_8_1/twisted/conch/scripts/ckeygen.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698