Esempio n. 1
0
def recv_file(i, o, e, progress, target_dir, command, preserve, times, check_hash):
    # TODO: add regex check on the command format
    # ignore the '\n' at the end
    mode, size, path = command[1:-1].split(" ", 2)
    size = int(size)
    mode = int(mode, 8)

    if os.path.isdir(target_dir):
        file_path = os.path.join(target_dir, path)
    else:
        file_path = target_dir

    seek = 0
    if check_hash:
        # command: hash check
        if os.path.exists(file_path):
            file_size = os.stat(file_path).st_size
            hash_str = _calculate_hash(file_path, file_size)
        else:
            file_size = 0
            hash_str = "0" * 40
        i.write("H{0:40s} {1:d}\n".format(hash_str, file_size))
        i.flush()
        ret = o.read(1)
        if ret != "\0":
            e.write(o.readline())
            return error.E_UNK

        # wait for H command
        command = o.readline()
        if len(command) == 0 or command[0] != "H":
            i.write("\2")
            i.write(error.errstr(error.E_UNK))
            i.flush()
            return error.E_UNK
        hash_str, seek = command[1:-1].split(" ", 1)
        seek = int(seek)
        if len(hash_str) != 40 or seek < 0:
            i.write("\2")
            i.write(error.errstr(error.E_FMT))
            i.flush()
            return error.E_FMT
        i.write("\0")
        i.flush()

    _recv_file_data(o, progress, file_path, size, seek)
    os.chmod(file_path, mode)
    if preserve:
        os.utime(file_path, times)
    ret = o.read(1)
    if ret != "\0":
        i.write("\2")
        i.write(error.errstr(error.E_TFR))
        i.flush()
        return error.E_TFR
    else:
        i.write("\0")
        i.flush()

    return error.E_OK
Esempio n. 2
0
def recv(i, o, e, progress, dir_path, preserve, check_hash):
    try:
        if not os.path.exists(os.path.dirname(dir_path)):
            i.write("\2")
            i.write(error.errstr(error.E_MIS))
            i.flush()
            return error.E_MIS
        else:
            i.write("\0")
            i.flush()

        while True:
            ret = recv_file_dir_or_end(i, o, e, progress, dir_path, preserve, check_hash)
            if ret == error.E_END:
                return error.E_OK
            if ret != error.E_OK:
                return ret
    except socket.error as socket_ex:
        # opposite side closed prematurely
        e.write(str(socket_ex) + "\n")
        ret = o.read(1)
        if len(ret) > 0 and ret != "\0":
            e.write(o.readline())
        e.flush()
        return error.E_TFR
    except Exception as ex:
        i.write("\2")
        i.write(str(ex) + "\n")
        i.flush()
        return error.E_TFR
Esempio n. 3
0
def recv_file_dir_or_end(i, o, e, progress, target_dir, preserve, check_hash):
    command = o.readline()
    if len(command) == 0:
        return error.E_END  # end of transfer ?
    if command[0] == "E":
        i.write("\0")
        i.flush()
        return error.E_END  # end of directory
    times = None
    if preserve:
        if command[0] == "T":
            times = command[1:-1].split(" ", 3)
            if len(times) != 4:
                i.write("\2")
                i.write(error.errstr(error.E_UNK))
                i.flush()
                return error.E_UNK
            # ready tuple for utime (atime, mtime)
            times = (int(times[2]), int(times[0]))
            i.write("\0")
            i.flush()
            command = o.readline()
            if len(command) == 0:  # should never happen
                i.write("\2")
                i.write(error.errstr(error.E_UNK))
                i.flush()
                return error.E_UNK
        else:
            i.write("\2")
            i.write(error.errstr(error.E_UNK))
            i.flush()
            return error.E_UNK
    ret = error.E_UNK
    if command[0] == "C":
        i.write("\0")
        i.flush()
        ret = recv_file(i, o, e, progress, target_dir, command, preserve, times, check_hash)
    elif command[0] == "D":
        i.write("\0")
        i.flush()
        ret = recv_dir(i, o, e, progress, target_dir, command, preserve, times, check_hash)
    else:
        i.write("\2")
        i.write(error.errstr(ret))
        i.flush()
    return ret
Esempio n. 4
0
def send_file(i, o, e, progress, file_path, preserve, check_hash):
    stat = os.stat(file_path)

    # command: touch
    if preserve:
        i.write("T{0:d} 0 {1:d} 0\n".format(stat.st_mtime, stat.st_atime))
        i.flush()
        ret = o.read(1)
        if ret != "\0":
            e.write(o.readline())
            return error.E_UNK

    mode = stat.st_mode & 0x1FF
    # command: sending file
    i.write("C{0:0=4o} {1:d} {2:s}\n".format(mode, stat.st_size, os.path.basename(file_path)))
    i.flush()
    ret = o.read(1)
    if ret != "\0":
        e.write(o.readline())
        return error.E_UNK

    seek = 0
    if check_hash:
        # wait for H command
        # format: H<hash> <size>
        command = o.readline()
        if len(command) == 0 or command[0] != "H":
            i.write("\2")
            i.write(error.errstr(error.E_UNK))
            i.flush()
            return error.E_UNK
        hash_str, file_size = command[1:-1].split(" ", 1)
        file_size = int(file_size)
        if len(hash_str) != 40 or file_size < 0:
            i.write("\2")
            i.write(error.errstr(error.E_FMT))
            i.flush()
            return error.E_FMT
        i.write("\0")
        i.flush()

        if file_size > 0 and file_size <= stat.st_size:
            # part of the file might already be at the destination
            # check if the parts are the same
            local_hash = _calculate_hash(file_path, file_size)
            if hash_str == local_hash:
                seek = file_size

        # command: hash ack
        # return 0 hash and seek value
        i.write("H{0:40s} {1:d}\n".format("0" * 40, seek))
        i.flush()
        ret = o.read(1)
        if ret != "\0":
            e.write(o.readline())
            return error.E_UNK

    _send_file_data(i, progress, file_path, stat.st_size, seek)
    # data transfer end
    i.write("\0")
    i.flush()
    ret = o.read(1)
    if ret != "\0":
        e.write(o.readline())
        return error.E_TFR

    return error.E_OK