def put(
    state, host, local_filename, remote_filename,
    user=None, group=None, mode=None, add_deploy_dir=True,
):
    '''
    Copy a local file to the remote system.
    + local_filename: local filename
    + remote_filename: remote filename
    + user: user to own the files
    + group: group to own the files
    + mode: permissions of the files
    '''
    if hasattr(local_filename, 'read'):
        local_file = local_filename
    else:
        if add_deploy_dir and state.deploy_dir:
            local_filename = path.join(state.deploy_dir, local_filename)
        local_file = local_filename
        if not path.isfile(local_file):
            raise IOError('No such file: {0}'.format(local_file))
    mode = ensure_mode_int(mode)
    remote_file = host.fact.file(remote_filename)
    if not remote_file:
        yield (local_file, remote_filename)
        if user or group:
            yield chown(remote_filename, user, group)
        if mode:
            yield chmod(remote_filename, mode)
    else:
        local_sum = get_file_sha1(local_filename)
        remote_sum = host.fact.sha1_file(remote_filename)
        if local_sum != remote_sum:
            yield (local_file, remote_filename)
            if user or group:
                yield chown(remote_filename, user, group)
            if mode:
                yield chmod(remote_filename, mode)
        else:
            if mode and remote_file['mode'] != mode:
                yield chmod(remote_filename, mode)
            if (
                (user and remote_file['user'] != user)
                or (group and remote_file['group'] != group)
            ):
                yield chown(remote_filename, user, group)