static int guac_common_ssh_sftp_get_handler()

in src/common-ssh/sftp.c [739:840]


static int guac_common_ssh_sftp_get_handler(guac_user* user,
        guac_object* object, char* name) {

    char fullpath[GUAC_COMMON_SSH_SFTP_MAX_PATH];

    guac_common_ssh_sftp_filesystem* filesystem =
        (guac_common_ssh_sftp_filesystem*) object->data;

    LIBSSH2_SFTP* sftp = filesystem->sftp_session;
    LIBSSH2_SFTP_ATTRIBUTES attributes;

    /* Translate stream name into filesystem path */
    if (!guac_common_ssh_sftp_translate_name(fullpath, object, name)) {
        guac_user_log(user, GUAC_LOG_INFO, "Unable to generate real path "
                "for stream \"%s\"", name);
        return 0;
    }

    /* Attempt to read file information */
    if (libssh2_sftp_stat(sftp, fullpath, &attributes)) {
        guac_user_log(user, GUAC_LOG_INFO, "Unable to read file \"%s\"",
                fullpath);
        return 0;
    }

    /* If directory, send contents of directory */
    if (LIBSSH2_SFTP_S_ISDIR(attributes.permissions)) {

        /* Open as directory */
        LIBSSH2_SFTP_HANDLE* dir = libssh2_sftp_opendir(sftp, fullpath);
        if (dir == NULL) {
            guac_user_log(user, GUAC_LOG_INFO,
                    "Unable to read directory \"%s\"", fullpath);
            return 0;
        }

        /* Init directory listing state */
        guac_common_ssh_sftp_ls_state* list_state =
            malloc(sizeof(guac_common_ssh_sftp_ls_state));

        list_state->directory = dir;
        list_state->filesystem = filesystem;

        int length = guac_strlcpy(list_state->directory_name, name,
                sizeof(list_state->directory_name));

        /* Bail out if directory name is too long to store */
        if (length >= sizeof(list_state->directory_name)) {
            guac_user_log(user, GUAC_LOG_INFO, "Unable to read directory "
                    "\"%s\": Path too long", fullpath);
            free(list_state);
            return 0;
        }

        /* Allocate stream for body */
        guac_stream* stream = guac_user_alloc_stream(user);
        stream->ack_handler = guac_common_ssh_sftp_ls_ack_handler;
        stream->data = list_state;

        /* Init JSON object state */
        guac_common_json_begin_object(user, stream, &list_state->json_state);

        /* Associate new stream with get request */
        guac_protocol_send_body(user->socket, object, stream,
                GUAC_USER_STREAM_INDEX_MIMETYPE, name);

    }

    /* Otherwise, send file contents */
    else {

        /* If downloads are disabled, log and return. */
        if (filesystem->disable_download) {
            guac_user_log(user, GUAC_LOG_INFO,
                    "Unable to download file \"%s\", "
                    "file downloads have been disabled.", fullpath);
            return 0;
        }
        
        /* Open as normal file */
        LIBSSH2_SFTP_HANDLE* file = libssh2_sftp_open(sftp, fullpath,
            LIBSSH2_FXF_READ, 0);
        if (file == NULL) {
            guac_user_log(user, GUAC_LOG_INFO,
                    "Unable to read file \"%s\"", fullpath);
            return 0;
        }

        /* Allocate stream for body */
        guac_stream* stream = guac_user_alloc_stream(user);
        stream->ack_handler = guac_common_ssh_sftp_ack_handler;
        stream->data = file;

        /* Associate new stream with get request */
        guac_protocol_send_body(user->socket, object, stream,
                "application/octet-stream", name);

    }

    guac_socket_flush(user->socket);
    return 0;
}