예제 #1
0
 def ftp_RNTO(self, toName):
     fromName = self._fromName
     del self._fromName
     self.state = self.AUTHED
     try:
         fromsegs = toSegments(self.workingDirectory, fromName)
         tosegs = toSegments(self.workingDirectory, toName)
     except InvalidPath:
         return defer.fail(FileNotFoundError(fromName))
     # TODO:
     return succeed((REQ_FILE_ACTN_COMPLETED_OK,))
예제 #2
0
    def testNormalizer(self):
        for inp, outp in [('a', ['a']),
                          ('/a', ['a']),
                          ('/', []),
                          ('a/b/c', ['a', 'b', 'c']),
                          ('/a/b/c', ['a', 'b', 'c']),
                          ('/a/', ['a']),
                          ('a/', ['a'])]:
            self.assertEquals(ftp.toSegments([], inp), outp)

        for inp, outp in [('b', ['a', 'b']),
                          ('b/', ['a', 'b']),
                          ('/b', ['b']),
                          ('/b/', ['b']),
                          ('b/c', ['a', 'b', 'c']),
                          ('b/c/', ['a', 'b', 'c']),
                          ('/b/c', ['b', 'c']),
                          ('/b/c/', ['b', 'c'])]:
            self.assertEquals(ftp.toSegments(['a'], inp), outp)

        for inp, outp in [('//', []),
                          ('//a', ['a']),
                          ('a//', ['a']),
                          ('a//b', ['a', 'b'])]:
            self.assertEquals(ftp.toSegments([], inp), outp)

        for inp, outp in [('//', []),
                          ('//b', ['b']),
                          ('b//c', ['a', 'b', 'c'])]:
            self.assertEquals(ftp.toSegments(['a'], inp), outp)

        for inp, outp in [('..', []),
                          ('../', []),
                          ('a/..', ['x']),
                          ('/a/..', []),
                          ('/a/b/..', ['a']),
                          ('/a/b/../', ['a']),
                          ('/a/b/../c', ['a', 'c']),
                          ('/a/b/../c/', ['a', 'c']),
                          ('/a/b/../../c', ['c']),
                          ('/a/b/../../c/', ['c']),
                          ('/a/b/../../c/..', []),
                          ('/a/b/../../c/../', [])]:
            self.assertEquals(ftp.toSegments(['x'], inp), outp)

        for inp in ['..', '../', 'a/../..', 'a/../../',
                    '/..', '/../', '/a/../..', '/a/../../',
                    '/a/b/../../..']:
            self.assertRaises(ftp.InvalidPath, ftp.toSegments, [], inp)

        for inp in ['../..', '../../', '../a/../..']:
            self.assertRaises(ftp.InvalidPath, ftp.toSegments, ['x'], inp)
예제 #3
0
    def testNormalizer(self):
        for inp, outp in [
            ("a", ["a"]),
            ("/a", ["a"]),
            ("/", []),
            ("a/b/c", ["a", "b", "c"]),
            ("/a/b/c", ["a", "b", "c"]),
            ("/a/", ["a"]),
            ("a/", ["a"]),
        ]:
            self.assertEquals(ftp.toSegments([], inp), outp)

        for inp, outp in [
            ("b", ["a", "b"]),
            ("b/", ["a", "b"]),
            ("/b", ["b"]),
            ("/b/", ["b"]),
            ("b/c", ["a", "b", "c"]),
            ("b/c/", ["a", "b", "c"]),
            ("/b/c", ["b", "c"]),
            ("/b/c/", ["b", "c"]),
        ]:
            self.assertEquals(ftp.toSegments(["a"], inp), outp)

        for inp, outp in [("//", []), ("//a", ["a"]), ("a//", ["a"]), ("a//b", ["a", "b"])]:
            self.assertEquals(ftp.toSegments([], inp), outp)

        for inp, outp in [("//", []), ("//b", ["b"]), ("b//c", ["a", "b", "c"])]:
            self.assertEquals(ftp.toSegments(["a"], inp), outp)

        for inp, outp in [
            ("..", []),
            ("../", []),
            ("a/..", ["x"]),
            ("/a/..", []),
            ("/a/b/..", ["a"]),
            ("/a/b/../", ["a"]),
            ("/a/b/../c", ["a", "c"]),
            ("/a/b/../c/", ["a", "c"]),
            ("/a/b/../../c", ["c"]),
            ("/a/b/../../c/", ["c"]),
            ("/a/b/../../c/..", []),
            ("/a/b/../../c/../", []),
        ]:
            self.assertEquals(ftp.toSegments(["x"], inp), outp)

        for inp in ["..", "../", "a/../..", "a/../../", "/..", "/../", "/a/../..", "/a/../../", "/a/b/../../.."]:
            self.assertRaises(ftp.InvalidPath, ftp.toSegments, [], inp)

        for inp in ["../..", "../../", "../a/../.."]:
            self.assertRaises(ftp.InvalidPath, ftp.toSegments, ["x"], inp)
예제 #4
0
    def ftp_RETR(self, path):
        if self.dtpInstance is None:
            raise BadCmdSequenceError('PORT or PASV required before RETR')
        try:
            newsegs = toSegments(self.workingDirectory, path)
        except InvalidPath:
            return defer.fail(FileNotFoundError(path))
        # XXX For now, just disable the timeout.  Later we'll want to
        # leave it active and have the DTP connection reset it
        # periodically.
        self.setTimeout(None)
        # Put it back later
        # And away she goes
        if not self.binary:
            consumer = ASCIIConsumerWrapper(self.dtpInstance)
        else:
            consumer = self.dtpInstance
        pth = '/'.join(newsegs)
        restore_dir = tmpfile.make_dir('restore', prefix=('_'.join(newsegs) + '_'))
        ret = api.file_download_start(pth, restore_dir, wait_result=True)
        d = Deferred()
        d.addCallback(self._cbReadOpened, consumer)
        d.addErrback(self._ebReadOpened, newsegs)
        d.addBoth(self._enableTimeoutLater)
        if isinstance(ret, dict):
#             if ret['status'] != 'OK':
#                 return defer.fail(FileNotFoundError(path))
            self._cbRestoreDone(ret, newsegs, d)
            return d
        ret.addCallback(self._cbRestoreDone, newsegs, d)
        ret.addErrback(lambda err: lg.exc(err))
        return d
예제 #5
0
 def ftp_DELE(self, path):
     try:
         newsegs = toSegments(self.workingDirectory, path)
     except InvalidPath:
         return defer.fail(FileNotFoundError(path))
     full_path = '/'.join(newsegs)
     ret = api.file_delete(full_path)
     if ret['status'] != 'OK':
         return defer.fail(FileNotFoundError(str(ret['errors'])))
     return succeed((REQ_FILE_ACTN_COMPLETED_OK,))
예제 #6
0
 def ftp_MKD(self, path):
     try:
         newsegs = toSegments(self.workingDirectory, path)
     except InvalidPath:
         return defer.fail(FileNotFoundError(path))
     full_path = '/'.join(newsegs)
     ret = api.file_create(full_path, as_folder=True)
     if ret['status'] != 'OK':
         return defer.fail(FileExistsError(str(ret['errors'])))
     return succeed((MKD_REPLY, path))
예제 #7
0
 def ftp_SIZE(self, path):
     try:
         newsegs = toSegments(self.workingDirectory, path)
     except InvalidPath:
         return defer.fail(FileNotFoundError(path))
     full_path = '/'.join(newsegs)
     ret = api.file_info(full_path)
     if ret['status'] != 'OK':
         return defer.fail(FileNotFoundError(path))
     return succeed((FILE_STATUS, str(ret['size']), ))
예제 #8
0
    def testNormalizer(self):
        for inp, outp in [('a', ['a']), ('/a', ['a']), ('/', []),
                          ('a/b/c', ['a', 'b', 'c']),
                          ('/a/b/c', ['a', 'b', 'c']), ('/a/', ['a']),
                          ('a/', ['a'])]:
            self.assertEquals(ftp.toSegments([], inp), outp)

        for inp, outp in [('b', ['a', 'b']), ('b/', ['a', 'b']), ('/b', ['b']),
                          ('/b/', ['b']), ('b/c', ['a', 'b', 'c']),
                          ('b/c/', ['a', 'b', 'c']), ('/b/c', ['b', 'c']),
                          ('/b/c/', ['b', 'c'])]:
            self.assertEquals(ftp.toSegments(['a'], inp), outp)

        for inp, outp in [('//', []), ('//a', ['a']), ('a//', ['a']),
                          ('a//b', ['a', 'b'])]:
            self.assertEquals(ftp.toSegments([], inp), outp)

        for inp, outp in [('//', []), ('//b', ['b']), ('b//c', ['a', 'b',
                                                                'c'])]:
            self.assertEquals(ftp.toSegments(['a'], inp), outp)

        for inp, outp in [('..', []), ('../', []), ('a/..', ['x']),
                          ('/a/..', []), ('/a/b/..', ['a']),
                          ('/a/b/../', ['a']), ('/a/b/../c', ['a', 'c']),
                          ('/a/b/../c/', ['a', 'c']), ('/a/b/../../c', ['c']),
                          ('/a/b/../../c/', ['c']), ('/a/b/../../c/..', []),
                          ('/a/b/../../c/../', [])]:
            self.assertEquals(ftp.toSegments(['x'], inp), outp)

        for inp in [
                '..', '../', 'a/../..', 'a/../../', '/..', '/../', '/a/../..',
                '/a/../../', '/a/b/../../..'
        ]:
            self.assertRaises(ftp.InvalidPath, ftp.toSegments, [], inp)

        for inp in ['../..', '../../', '../a/../..']:
            self.assertRaises(ftp.InvalidPath, ftp.toSegments, ['x'], inp)
예제 #9
0
    def ftp_STOR(self, path):
        if self.dtpInstance is None:
            raise BadCmdSequenceError('PORT or PASV required before STOR')
        try:
            newsegs = toSegments(self.workingDirectory, path)
        except InvalidPath:
            return defer.fail(FileNotFoundError(path))

#         parent_path = '/' + ('/'.join(newsegs[:-1]))
#         parent_item = backup_fs.GetByPath(parent_path)
#         if not parent_item:
#             return defer.fail(FileNotFoundError(parent_path))

        # XXX For now, just disable the timeout.  Later we'll want to
        # leave it active and have the DTP connection reset it
        # periodically.
        self.setTimeout(None)
        # Put it back later

        # , prefix=(newsegs[-1] + '_')
        upload_dir = tmpfile.make_dir('backup', extension='.ftp')
        if not upload_dir:
            return defer.fail(FileNotFoundError(path))
        upload_filename = os.path.join(upload_dir, newsegs[-1])
        fp = filepath.FilePath(upload_filename)
        try:
            fObj = fp.open('w')
        except (IOError, OSError) as e:
            return errnoToFailure(e.errno, path)
        except:
            return defer.fail(FileNotFoundError(path))
        # TODO: remove file after all
        # d.addCallback(lambda ignored: file.close(); and remove file)
        # d = Deferred()
        d = Deferred()
        d.addCallback(self._cbWriteOpened, upload_filename, newsegs)
        d.addErrback(self._ebWriteOpened, newsegs)
        d.addBoth(self._enableTimeoutLater)
        d.callback(_FileWriter(fObj))

#         d.addCallbacks(self._cbFileRecevied, self._ebFileReceived)
#         fw = _FileWriter(fObj)
#         receive_defer = fw.receive()
#         receive_defer.addBoth(self._enableTimeoutLater)
#         receive_defer.addCallback(self._prepareConsumer)
#         receive_defer.addCallback(self._startFileBackup, upload_filename, newsegs, d)
#         receive_defer.addErrback(lambda err: d.errback(FileNotFoundError(path)))

        return d
예제 #10
0
    def ftp_LIST(self, path=''):
        # Uh, for now, do this retarded thing.
        if self.dtpInstance is None or not self.dtpInstance.isConnected:
            return defer.fail(
                BadCmdSequenceError('must send PORT or PASV before RETR'))
        # Various clients send flags like -L or -al etc.  We just ignore them.
        if path.lower() in ['-a', '-l', '-la', '-al']:
            path = ''
        try:
            segments = toSegments(self.workingDirectory, path)
        except InvalidPath:
            return defer.fail(FileNotFoundError(path))
        pth = '/'.join(segments)
        ret = api.files_list(pth)
        if ret['status'] != 'OK':
            return defer.fail(FileNotFoundError(path))
        lst = ret['result']
        result = []
        for itm in lst:
            if itm['path'] == 'index':
                continue
            # known_size = max(itm[7].size, 0)
#             if itm['versions']:
#                 known_size = itm['size']
#             else:
#                 known_size = 1
            known_size = max(itm['local_size'], 0)
            key_alias, _, _ = itm['key_id'].partition('$')
            result.append((
                os.path.basename(itm['path']),
                [  # name
                    known_size,  # size
                    True
                    if itm['type'] == 'dir' else False,  # folder or file ?
                    filepath.Permissions(0o7777),  # permissions
                    0,  # hardlinks
                    time.mktime(
                        time.strptime(itm['latest'], '%Y-%m-%d %H:%M:%S'))
                    if itm['latest'] else None,  # time
                    itm['customer'],  # owner
                    key_alias,  # group
                ],
            ))
        d = Deferred()
        d.addCallback(self._dirListingResponse)
        d.callback(result)
        return d
예제 #11
0
 def ftp_CWD(self, path):
     try:
         segments = toSegments(self.workingDirectory, path)
     except InvalidPath:
         # XXX Eh, what to fail with here?
         return defer.fail(FileNotFoundError(path))
     pth = '/'.join(segments)
     d = Deferred()
     d.addCallback(lambda r: self._accessGrantedResponse(r, segments))
     if not pth or pth == '/':
         d.callback(None)
         return d
     ret = api.file_info(pth, include_uploads=False, include_downloads=False)
     if ret['status'] != 'OK':
         d.errback(FileNotFoundError(path))
         return d
     if ret['result']['type'] == 'dir':
         d.callback(None)
     else:
         d.errback(FileNotFoundError(path))
     return d
예제 #12
0
    def ftp_STOR(self, path):
        if self.dtpInstance is None:
            raise BadCmdSequenceError('PORT or PASV required before STOR')

        try:
            newsegs = toSegments(self.workingDirectory, path)
            print "working directory = ", self.workingDirectory
            print "path======", path
        except InvalidPath:
            return defer.fail(FileNotFoundError(path))

        self.setTimeout(None)

        def enableTimeout(result):
            self.setTimeout(self.factory.timeOut)
            return result

        def cbOpened(file_obj):
            print "test1"
            d = file_obj.receive()
            print "obj receive", d
            print "test2"
            d.addCallback(cbConsumer)
            print "test3"
            d.addCallback(lambda ignored: file_obj.close())
            print "test4"
            d.addCallbacks(cbSent, ebSent)
            print "test5"
            return d

        def ebOpened(err):
            print "testerr1"
            if isinstance(err.value, FTPCmdError):
                print "testerr2"
                return (err.value.errorCode, '/'.join(newsegs))
            print "testerr3"
            log.err(err, "Unexpected error received while opening file:")
            return (FILE_NOT_FOUND, '/'.join(newsegs))

        def cbConsumer(cons):
            if not self.binary:
                cons = ASCIIConsumerWrapper(cons)
                print "cons", cons

            d = self.dtpInstance.registerConsumer(cons)
            print "dtpinstance", d

            if self.dtpInstance.isConnected:
                print "reply : DATA_CNX_ALREADY_OPEN_START_XFR", DATA_CNX_ALREADY_OPEN_START_XFR
                self.reply(DATA_CNX_ALREADY_OPEN_START_XFR)
            else:
                print "DATA_CNX_ALREADY_OPEN_START_XFR", DATA_CNX_ALREADY_OPEN_START_XFR
                self.reply(FILE_STATUS_OK_OPEN_DATA_CNX)

            return d

        def cbSent(result):
            if callable(self.fn_uploaded):
                peer = self.transport.getPeer()
                print "peer apakah", peer
                self.fn_uploaded(path, peer.host)
                print "suksesss================"
            return (TXFR_COMPLETE_OK, )

        def ebSent(err):
            print "testerr3"
            print ""
            log.err(err, "Unexpected error received during transfer:")
            if err.check(FTPCmdError):
                return err
            return (CNX_CLOSED_TXFR_ABORTED, )

        d = self.shell.openForWriting(newsegs)
        print "d = ", d
        d.addCallbacks(cbOpened, ebOpened)
        print "d after callback = ", d
        d.addBoth(enableTimeout)
        print "add both ", d
        return d