/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/transport/ftp.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2007-04-01 06:48:38 UTC
  • mfrom: (2389.1.1 0.15-to-trunk)
  • Revision ID: pqm@pqm.ubuntu.com-20070401064838-34903c7b0d0c8007
merge 0.15 back to dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
import errno
30
30
import ftplib
31
31
import os
32
 
import os.path
33
32
import urllib
34
33
import urlparse
35
 
import select
36
34
import stat
37
35
import threading
38
36
import time
41
39
 
42
40
from bzrlib import (
43
41
    errors,
44
 
    osutils,
45
42
    urlutils,
46
43
    )
47
44
from bzrlib.trace import mutter, warning
50
47
    split_url,
51
48
    Transport,
52
49
    )
53
 
from bzrlib.transport.local import LocalURLServer
54
50
import bzrlib.ui
55
51
 
56
52
_have_medusa = False
305
301
        :param retries: Number of retries after temporary failures so far
306
302
                        for this operation.
307
303
 
308
 
        TODO: jam 20051215 ftp as a protocol seems to support chmod, but
309
 
        ftplib does not
 
304
        TODO: jam 20051215 ftp as a protocol seems to support chmod, but ftplib does not
310
305
        """
311
306
        abspath = self._abspath(relpath)
312
307
        tmp_abspath = '%s.tmp.%.9f.%d.%d' % (abspath, time.time(),
318
313
            f = self._get_FTP()
319
314
            try:
320
315
                f.storbinary('STOR '+tmp_abspath, fp)
321
 
                self._rename_and_overwrite(tmp_abspath, abspath, f)
 
316
                f.rename(tmp_abspath, abspath)
322
317
            except (ftplib.error_temp,EOFError), e:
323
318
                warning("Failure during ftp PUT. Deleting temporary file.")
324
319
                try:
437
432
    #       to give it its own address as the 'to' location.
438
433
    #       So implement a fancier 'copy()'
439
434
 
440
 
    def rename(self, rel_from, rel_to):
441
 
        abs_from = self._abspath(rel_from)
442
 
        abs_to = self._abspath(rel_to)
443
 
        mutter("FTP rename: %s => %s", abs_from, abs_to)
444
 
        f = self._get_FTP()
445
 
        return self._rename(abs_from, abs_to, f)
446
 
 
447
 
    def _rename(self, abs_from, abs_to, f):
448
 
        try:
449
 
            f.rename(abs_from, abs_to)
450
 
        except ftplib.error_perm, e:
451
 
            self._translate_perm_error(e, abs_from,
452
 
                ': unable to rename to %r' % (abs_to))
453
 
 
454
435
    def move(self, rel_from, rel_to):
455
436
        """Move the item at rel_from to the location at rel_to"""
456
437
        abs_from = self._abspath(rel_from)
458
439
        try:
459
440
            mutter("FTP mv: %s => %s", abs_from, abs_to)
460
441
            f = self._get_FTP()
461
 
            self._rename_and_overwrite(abs_from, abs_to, f)
 
442
            f.rename(abs_from, abs_to)
462
443
        except ftplib.error_perm, e:
463
444
            self._translate_perm_error(e, abs_from,
464
445
                extra='unable to rename to %r' % (rel_to,), 
465
446
                unknown_exc=errors.PathError)
466
447
 
467
 
    def _rename_and_overwrite(self, abs_from, abs_to, f):
468
 
        """Do a fancy rename on the remote server.
469
 
 
470
 
        Using the implementation provided by osutils.
471
 
        """
472
 
        osutils.fancy_rename(abs_from, abs_to,
473
 
            rename_func=lambda p1, p2: self._rename(p1, p2, f),
474
 
            unlink_func=lambda p: self._delete(p, f))
 
448
    rename = move
475
449
 
476
450
    def delete(self, relpath):
477
451
        """Delete the item at relpath"""
478
452
        abspath = self._abspath(relpath)
479
 
        f = self._get_FTP()
480
 
        self._delete(abspath, f)
481
 
 
482
 
    def _delete(self, abspath, f):
483
453
        try:
484
454
            mutter("FTP rm: %s", abspath)
 
455
            f = self._get_FTP()
485
456
            f.delete(abspath)
486
457
        except ftplib.error_perm, e:
487
458
            self._translate_perm_error(e, abspath, 'error deleting',
579
550
        """This is used by medusa.ftp_server to log connections, etc."""
580
551
        self.logs.append(message)
581
552
 
582
 
    def setUp(self, vfs_server=None):
 
553
    def setUp(self):
 
554
 
583
555
        if not _have_medusa:
584
556
            raise RuntimeError('Must have medusa to run the FtpServer')
585
557
 
586
 
        assert vfs_server is None or isinstance(vfs_server, LocalURLServer), \
587
 
            "FtpServer currently assumes local transport, got %s" % vfs_server
588
 
 
589
558
        self._root = os.getcwdu()
590
559
        self._ftp_server = _ftp_server(
591
560
            authorizer=_test_authorizer(root=self._root),
597
566
        self._port = self._ftp_server.getsockname()[1]
598
567
        # Don't let it loop forever, or handle an infinite number of requests.
599
568
        # In this case it will run for 100s, or 1000 requests
600
 
        self._async_thread = threading.Thread(
601
 
                target=FtpServer._asyncore_loop_ignore_EBADF,
 
569
        self._async_thread = threading.Thread(target=asyncore.loop,
602
570
                kwargs={'timeout':0.1, 'count':1000})
603
571
        self._async_thread.setDaemon(True)
604
572
        self._async_thread.start()
610
578
        asyncore.close_all()
611
579
        self._async_thread.join()
612
580
 
613
 
    @staticmethod
614
 
    def _asyncore_loop_ignore_EBADF(*args, **kwargs):
615
 
        """Ignore EBADF during server shutdown.
616
 
 
617
 
        We close the socket to get the server to shutdown, but this causes
618
 
        select.select() to raise EBADF.
619
 
        """
620
 
        try:
621
 
            asyncore.loop(*args, **kwargs)
622
 
        except select.error, e:
623
 
            if e.args[0] != errno.EBADF:
624
 
                raise
625
 
 
626
581
 
627
582
_ftp_channel = None
628
583
_ftp_server = None
693
648
            pfrom = self.filesystem.translate(self._renaming)
694
649
            self._renaming = None
695
650
            pto = self.filesystem.translate(line[1])
696
 
            if os.path.exists(pto):
697
 
                self.respond('550 RNTO failed: file exists')
698
 
                return
699
651
            try:
700
652
                os.rename(pfrom, pto)
701
653
            except (IOError, OSError), e: