guac_stream* guac_sftp_download_file(guac_client* client, char* filename) { ssh_guac_client_data* client_data = (ssh_guac_client_data*) client->data; guac_stream* stream; LIBSSH2_SFTP_HANDLE* file; /* Attempt to open file for reading */ file = libssh2_sftp_open(client_data->sftp_session, filename, LIBSSH2_FXF_READ, 0); if (file == NULL) { guac_client_log_error(client, "Unable to read file \"%s\": %s", filename, libssh2_sftp_last_error(client_data->sftp_session)); return NULL; } /* Allocate stream */ stream = guac_client_alloc_stream(client); stream->ack_handler = guac_sftp_ack_handler; stream->data = file; /* Send stream start, strip name */ filename = basename(filename); guac_protocol_send_file(client->socket, stream, "application/octet-stream", filename); guac_socket_flush(client->socket); return stream; }
void guac_rdpdr_start_download(guac_rdpdr_device* device, const char* path) { /* Get client and stream */ guac_client* client = device->rdpdr->client; int file_id = guac_rdp_fs_open((guac_rdp_fs*) device->data, path, ACCESS_FILE_READ_DATA, 0, DISP_FILE_OPEN, 0); /* If file opened successfully, start stream */ if (file_id >= 0) { guac_rdp_stream* rdp_stream; const char* basename; int i; char c; /* Associate stream with transfer status */ guac_stream* stream = guac_client_alloc_stream(client); stream->data = rdp_stream = malloc(sizeof(guac_rdp_stream)); stream->ack_handler = guac_rdp_download_ack_handler; rdp_stream->type = GUAC_RDP_DOWNLOAD_STREAM; rdp_stream->download_status.file_id = file_id; rdp_stream->download_status.offset = 0; /* Get basename from absolute path */ i=0; basename = path; do { c = path[i]; if (c == '/' || c == '\\') basename = &(path[i+1]); i++; } while (c != '\0'); GUAC_RDP_DEBUG(2, "Initiating download of \"%s\"", path); /* Begin stream */ guac_protocol_send_file(client->socket, stream, "application/octet-stream", basename); guac_socket_flush(client->socket); } else guac_client_log(client, GUAC_LOG_ERROR, "Unable to download \"%s\"", path); }
void guac_rdpdr_process_print_job_write(guac_rdpdr_device* device, wStream* input_stream, int completion_id) { guac_rdpdr_printer_data* printer_data = (guac_rdpdr_printer_data*) device->data; int status=0, length; unsigned char* buffer; wStream* output_stream; Stream_Read_UINT32(input_stream, length); Stream_Seek(input_stream, 8); /* Offset */ Stream_Seek(input_stream, 20); /* Padding */ buffer = Stream_Pointer(input_stream); /* Create print job, if not yet created */ if (printer_data->bytes_received == 0) { char filename[1024] = "guacamole-print.pdf"; unsigned char* search = buffer; int i; /* Search for filename within buffer */ for (i=0; i<length-9 && i < 2048; i++) { /* If title. use as filename */ if (memcmp(search, "%%Title: ", 9) == 0) { /* Skip past "%%Title: " */ search += 9; /* Copy as much of title as reasonable */ int j; for (j=0; j<sizeof(filename) - 5 /* extension + 1 */ && i<length; i++, j++) { /* Get character, stop at EOL */ char c = *(search++); if (c == '\r' || c == '\n') break; /* Copy to filename */ filename[j] = c; } /* Append filename with extension */ strcpy(&(filename[j]), ".pdf"); break; } /* Next character */ search++; } /* Begin file */ guac_client_log(device->rdpdr->client, GUAC_LOG_INFO, "Print job created"); guac_protocol_send_file(device->rdpdr->client->socket, printer_data->stream, "application/pdf", filename); /* Start print process */ if (guac_rdpdr_create_print_process(device) != 0) { status = STATUS_DEVICE_OFF_LINE; length = 0; } } printer_data->bytes_received += length; /* If not yet failed, write received data */ if (status == 0) { /* Write data to printer, translate output for RDP */ length = write(printer_data->printer_input, buffer, length); if (length == -1) { guac_client_log(device->rdpdr->client, GUAC_LOG_ERROR, "Error writing to printer: %s", strerror(errno)); status = STATUS_DEVICE_OFF_LINE; length = 0; } } output_stream = guac_rdpdr_new_io_completion(device, completion_id, status, 5); Stream_Write_UINT32(output_stream, length); Stream_Write_UINT8(output_stream, 0); /* Padding */ svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); }