예제 #1
0
파일: handlers.py 프로젝트: delan/pony-ssh
def handle_delete(args):
    path = os.path.expanduser(args['path'])
    if os.path.isdir(path) and not os.path.islink(path):
        shutil.rmtree(path)
    else:
        os.remove(path)
    send_response_header({})
예제 #2
0
파일: handlers.py 프로젝트: delan/pony-ssh
def handle_file_read(args):
    path = os.path.expanduser(args['path'])

    # Open the file before sending a response header
    fh = open(path, 'rb')

    # If a hash has been supplied, check if it matches. IF so, shortcut download.
    if 'cachedHash' in args:
        hash = hashlib.md5(fh.read()).hexdigest()
        if hash == args['cachedHash']:
            send_response_header({'hashMatch': True})
            return
        fh.seek(0, 0)

    length = os.path.getsize(path)
    send_response_header({'length': length})

    if length == 0:
        return

    chunkSize = 200 * 1024
    while True:
        chunk = fh.read(chunkSize)
        if not chunk:
            break
        send_parcel(ParcelType.BODY, chunk)

    fh.close()

    send_parcel(ParcelType.ENDOFBODY, b'')
예제 #3
0
파일: handlers.py 프로젝트: delan/pony-ssh
def handle_expand_path(args):
    path = os.path.expanduser(args['path'])
    if not os.path.exists(path):
        send_error(Error.ENOENT, 'Path not found')
    elif not os.path.isdir(path):
        send_error(Error.ENOTDIR, 'Not a directory')
    else:
        send_response_header({'path': path})
예제 #4
0
파일: handlers.py 프로젝트: delan/pony-ssh
def handle_rename(args):
    fromPath = os.path.expanduser(args['from'])
    toPath = os.path.expanduser(args['to'])

    if os.path.exists(toPath):
        if args['overwrite']:
            os.unlink(toPath)
        else:
            raise OSError(Error.EEXIST, 'File already exists')

    os.rename(fromPath, toPath)
    send_response_header({})
예제 #5
0
파일: handlers.py 프로젝트: delan/pony-ssh
def handle_file_write(args):
    path = os.path.expanduser(args['path'])

    alreadyExists = os.path.exists(path)
    if alreadyExists and not args['overwrite']:
        raise OSError(Error.EEXIST, 'File already exists')
    elif not alreadyExists and not args['create']:
        raise OSError(Error.ENOENT, 'File not found')

    fh = open(path, 'wb')
    fh.write(args['data'])
    fh.close()

    send_response_header({})
예제 #6
0
파일: handlers.py 프로젝트: delan/pony-ssh
def handle_ls(args):
    base = os.path.expanduser(args['path'])
    selfStat = os.stat(base)

    result = {'stat': process_stat(selfStat)}
    if not stat.S_ISDIR(selfStat[stat.ST_MODE]):
        send_response_header(result)
        return

    dirs = {}
    dirLimit = 25
    entryLimit = 2000
    explore = deque(['.'])
    while len(explore) > 0 and dirLimit > 0 and entryLimit > 0:
        dirLimit -= 1

        relPath = explore.popleft()
        absPath = base if relPath == '.' else os.path.join(base, relPath)

        try:
            children = {}
            for childName in os.listdir(absPath):
                entryLimit -= 1
                if entryLimit < 0 and len(dirs) > 0:
                    children = None
                    break

                child_path = os.path.join(absPath, childName)
                try:
                    childStat = os.stat(child_path)
                    children[childName] = process_stat(childStat)

                    isDir = stat.S_ISDIR(childStat[stat.ST_MODE])
                    if isDir and len(explore) < dirLimit:
                        explore.append(os.path.join(relPath, childName))
                except OSError as err:
                    logging.warning('Skipping ' + child_path + ': ' + str(err))

            if children is not None:
                dirs[relPath] = children
        except OSError as err:
            logging.warning('Error: ' + str(err))
            if len(dirs) == 0:
                raise err  # Only raise read errors on the first item.

    result['dirs'] = dirs
    send_response_header(result)
예제 #7
0
파일: handlers.py 프로젝트: delan/pony-ssh
def handle_file_write_diff(args):
    path = os.path.expanduser(args['path'])

    if not os.path.exists(path):
        raise OSError(Error.ENOENT, 'File not found')

    with open(path, 'r', encoding='latin-1') as fh:
        original_data = bytearray(fh.read(), 'latin-1')

    original_hash = hashlib.md5(original_data).hexdigest()
    if original_hash != args['hashBefore']:
        raise CodedError(
            Error.EIO, 'File hash does not match client cached value: ' +
            args['hashBefore'] + ' vs ' + original_hash)

    # Apply diff; comes in as a flat array containing pairs; action, action data.
    updated_data = bytearray()
    read_cursor = 0
    diff = args['diff']

    for i in range(0, len(diff), 2):
        action = diff[i]
        action_data = diff[i + 1]

        if action == DiffAction.INSERTED:
            updated_data.extend(
                bytearray(action_data,
                          'latin-1'))  # Action data contains new data inserted
        elif action == DiffAction.REMOVED:
            read_cursor += action_data  # Action data contains number of bytes to remove
        else:
            # Action data contains number of bytes to copy from original
            updated_data.extend(original_data[read_cursor:read_cursor +
                                              action_data])
            read_cursor += action_data

    updated_hash = hashlib.md5(updated_data).hexdigest()
    if updated_hash != args['hashAfter']:
        raise CodedError(
            Error.EINVAL,
            'File hash after changes applied does not match expected')

    with open(path, 'wb') as fh:
        fh.write(updated_data)

    send_response_header({})
예제 #8
0
파일: handlers.py 프로젝트: delan/pony-ssh
def handle_get_server_info(args):
    settingsPath = os.path.expanduser('~/.pony-ssh/')
    if not os.path.exists(settingsPath):
        os.makedirs(settingsPath)

    # Load or generate a cache key.
    cacheKey = None
    cacheKeyIsNew = False
    cacheKeyFile = settingsPath + 'cache.key'
    if os.path.exists(cacheKeyFile):
        with open(cacheKeyFile, 'r') as keyFileHandle:
            cacheKey = keyFileHandle.read(64)

    if cacheKey == None or len(cacheKey) < 64:
        cacheKeyIsNew = True
        cacheKey = os.urandom(32).encode('hex')
        with open(cacheKeyFile, 'wb') as keyFileHandle:
            keyFileHandle.write(cacheKey)

    send_response_header({
        'home': os.path.expanduser('~'),
        'cacheKey': cacheKey,
        'newCacheKey': cacheKeyIsNew
    })
예제 #9
0
파일: handlers.py 프로젝트: delan/pony-ssh
def handle_mkdir(args):
    path = os.path.expanduser(args['path'])
    os.mkdir(path)
    send_response_header({})