2017-02-13 22:44:06 +00:00
|
|
|
/*
|
|
|
|
* Licensed to the Apache Software Foundation (ASF) under one
|
|
|
|
* or more contributor license agreements. See the NOTICE file
|
|
|
|
* distributed with this work for additional information
|
|
|
|
* regarding copyright ownership. The ASF licenses this file
|
|
|
|
* to you under the Apache License, Version 2.0 (the
|
|
|
|
* "License"); you may not use this file except in compliance
|
|
|
|
* with the License. You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing,
|
|
|
|
* software distributed under the License is distributed on an
|
|
|
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
|
|
* KIND, either express or implied. See the License for the
|
|
|
|
* specific language governing permissions and limitations
|
|
|
|
* under the License.
|
|
|
|
*/
|
|
|
|
|
2017-02-14 07:51:33 +00:00
|
|
|
#ifndef GUAC_RDP_PRINT_JOB_H
|
|
|
|
#define GUAC_RDP_PRINT_JOB_H
|
2017-02-13 22:44:06 +00:00
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include <guacamole/client.h>
|
|
|
|
#include <guacamole/stream.h>
|
|
|
|
#include <guacamole/user.h>
|
|
|
|
|
|
|
|
#include <pthread.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
/**
|
2017-02-14 07:51:33 +00:00
|
|
|
* The maximum number of bytes in the filename of an RDP print job sent as a
|
2017-02-13 22:44:06 +00:00
|
|
|
* file over the Guacamole protocol, including NULL terminator.
|
|
|
|
*/
|
2017-02-14 07:51:33 +00:00
|
|
|
#define GUAC_RDP_PRINT_JOB_FILENAME_MAX_LENGTH 1024
|
2017-02-13 22:44:06 +00:00
|
|
|
|
|
|
|
/**
|
2017-02-14 07:51:33 +00:00
|
|
|
* The default filename to use for the PDF output of an RDP print job if no
|
2017-02-13 22:44:06 +00:00
|
|
|
* document title can be found within the printed data.
|
|
|
|
*/
|
2017-02-14 07:51:33 +00:00
|
|
|
#define GUAC_RDP_PRINT_JOB_DEFAULT_FILENAME "guacamole-print.pdf"
|
2017-02-13 22:44:06 +00:00
|
|
|
|
2017-02-14 02:42:03 +00:00
|
|
|
/**
|
|
|
|
* The maximum number of bytes to search through at the beginning of a
|
|
|
|
* PostScript document when locating the document title.
|
|
|
|
*/
|
2017-02-14 07:51:33 +00:00
|
|
|
#define GUAC_RDP_PRINT_JOB_TITLE_SEARCH_LENGTH 2048
|
2017-02-14 02:42:03 +00:00
|
|
|
|
2017-02-13 22:44:06 +00:00
|
|
|
/**
|
2017-02-14 07:51:33 +00:00
|
|
|
* The current state of an RDP print job.
|
2017-02-13 22:44:06 +00:00
|
|
|
*/
|
2017-02-14 07:51:33 +00:00
|
|
|
typedef enum guac_rdp_print_job_state {
|
2017-02-13 22:44:06 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The print stream has been opened with the Guacamole client, but the
|
|
|
|
* client has not yet confirmed that it is ready to receive data.
|
|
|
|
*/
|
2017-02-14 07:51:33 +00:00
|
|
|
GUAC_RDP_PRINT_JOB_WAITING_FOR_ACK,
|
2017-02-13 22:44:06 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The print stream has been opened with the Guacamole client, and the
|
|
|
|
* client has responded with an "ack", confirming that it is ready to
|
|
|
|
* receive data (or that data has been received and it is ready to receive
|
|
|
|
* more).
|
|
|
|
*/
|
2017-02-14 07:51:33 +00:00
|
|
|
GUAC_RDP_PRINT_JOB_ACK_RECEIVED,
|
2017-02-13 22:44:06 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The print stream has been closed or the printer is terminating, and no
|
|
|
|
* further data should be sent to the client.
|
|
|
|
*/
|
2017-02-14 07:51:33 +00:00
|
|
|
GUAC_RDP_PRINT_JOB_CLOSED
|
2017-02-13 22:44:06 +00:00
|
|
|
|
2017-02-14 07:51:33 +00:00
|
|
|
} guac_rdp_print_job_state;
|
2017-02-13 22:44:06 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Data specific to an instance of the printer device.
|
|
|
|
*/
|
2017-02-14 07:51:33 +00:00
|
|
|
typedef struct guac_rdp_print_job {
|
2017-02-13 22:44:06 +00:00
|
|
|
|
|
|
|
guac_client* client;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The user receiving the output from the print job.
|
|
|
|
*/
|
|
|
|
guac_user* user;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The stream along which the print job output should be sent.
|
|
|
|
*/
|
|
|
|
guac_stream* stream;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The PID of the print filter process converting PostScript data into PDF.
|
|
|
|
*/
|
|
|
|
pid_t filter_pid;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The filename that should be used when the converted PDF output is
|
|
|
|
* streamed to the Guacamole user. This value will be automatically
|
|
|
|
* determined based on the contents of the printed document.
|
|
|
|
*/
|
2017-02-14 07:51:33 +00:00
|
|
|
char filename[GUAC_RDP_PRINT_JOB_FILENAME_MAX_LENGTH];
|
2017-02-13 22:44:06 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* File descriptor that should be written to when sending documents to the
|
|
|
|
* printer.
|
|
|
|
*/
|
|
|
|
int input_fd;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* File descriptor that should be read from when receiving output from the
|
|
|
|
* printer.
|
|
|
|
*/
|
|
|
|
int output_fd;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The current state of the print stream, dependent on whether the client
|
|
|
|
* has acknowledged creation of the stream, whether the client has
|
|
|
|
* acknowledged receipt of data along the steam, and whether the print
|
|
|
|
* stream itself has closed.
|
|
|
|
*/
|
2017-02-14 07:51:33 +00:00
|
|
|
guac_rdp_print_job_state state;
|
2017-02-13 22:44:06 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Lock which is acquired prior to modifying the state property or waiting
|
|
|
|
* on the state_modified conditional.
|
|
|
|
*/
|
|
|
|
pthread_mutex_t state_lock;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Conditional which signals modification to the state property of this
|
|
|
|
* structure.
|
|
|
|
*/
|
|
|
|
pthread_cond_t state_modified;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Thread which transfers data from the printer to the Guacamole client.
|
|
|
|
*/
|
|
|
|
pthread_t output_thread;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The number of bytes received in the current print job.
|
|
|
|
*/
|
|
|
|
int bytes_received;
|
|
|
|
|
2017-02-14 07:51:33 +00:00
|
|
|
} guac_rdp_print_job;
|
2017-02-13 22:44:06 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* A blob of print data being sent to the Guacamole user.
|
|
|
|
*/
|
2017-02-14 07:51:33 +00:00
|
|
|
typedef struct guac_rdp_print_blob {
|
2017-02-13 22:44:06 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The print job which generated the data being sent.
|
|
|
|
*/
|
2017-02-14 07:51:33 +00:00
|
|
|
guac_rdp_print_job* job;
|
2017-02-13 22:44:06 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The data being sent.
|
|
|
|
*/
|
|
|
|
void* buffer;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The number of bytes of data being sent.
|
|
|
|
*/
|
|
|
|
int length;
|
|
|
|
|
2017-02-14 07:51:33 +00:00
|
|
|
} guac_rdp_print_blob;
|
2017-02-13 22:44:06 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Allocates a new print job for the given user. It is expected that this
|
|
|
|
* function will be invoked via a call to guac_client_for_user() or
|
|
|
|
* guac_client_for_owner().
|
|
|
|
*
|
|
|
|
* @param user
|
|
|
|
* The user that should receive the output from the print job.
|
|
|
|
*
|
|
|
|
* @param data
|
|
|
|
* An arbitrary data parameter required by guac_client_for_user() and
|
|
|
|
* guac_client_for_owner() but ignored by this function. This should
|
|
|
|
* always be NULL.
|
|
|
|
*
|
|
|
|
* @return
|
2017-02-14 07:51:33 +00:00
|
|
|
* A pointer to a newly-allocated guac_rdp_print_job, or NULL if the
|
2017-02-13 22:44:06 +00:00
|
|
|
* print job could not be created.
|
|
|
|
*/
|
2017-02-14 07:51:33 +00:00
|
|
|
void* guac_rdp_print_job_alloc(guac_user* user, void* data);
|
2017-02-13 22:44:06 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Writes PostScript print data to the given active print job. The print job
|
|
|
|
* will automatically convert this data to PDF, streaming the result to the
|
|
|
|
* Guacamole user associated with the print job. This function may block if
|
|
|
|
* the print job is not yet ready for more data.
|
|
|
|
*
|
2017-02-16 03:59:50 +00:00
|
|
|
* @param job
|
|
|
|
* The print job to write to.
|
|
|
|
*
|
2017-02-13 22:44:06 +00:00
|
|
|
* @param buffer
|
|
|
|
* The PostScript print data to write to the given print job.
|
|
|
|
*
|
|
|
|
* @param length
|
|
|
|
* The number of bytes of PostScript print data to write.
|
|
|
|
*
|
|
|
|
* @return
|
|
|
|
* The number of bytes written, or -1 if an error occurs which prevents
|
|
|
|
* further writes.
|
|
|
|
*/
|
2017-02-14 07:51:33 +00:00
|
|
|
int guac_rdp_print_job_write(guac_rdp_print_job* job,
|
2017-02-13 22:44:06 +00:00
|
|
|
void* buffer, int length);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Frees the memory associated with the given print job, closing all underlying
|
|
|
|
* file descriptors, and ending the file transfer to the associated Guacamole
|
|
|
|
* user. This function may block if the print filter process has not yet
|
|
|
|
* finished processing the received data.
|
|
|
|
*
|
|
|
|
* @param job
|
|
|
|
* The print job to free.
|
|
|
|
*/
|
2017-02-14 07:51:33 +00:00
|
|
|
void guac_rdp_print_job_free(guac_rdp_print_job* job);
|
2017-02-13 22:44:06 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Forcibly kills the given print job, stopping all associated processing and
|
|
|
|
* streaming. The memory associated with the print job will still need to be
|
2017-02-14 07:51:33 +00:00
|
|
|
* reclaimed via guac_rdp_print_job_free().
|
2017-02-13 22:44:06 +00:00
|
|
|
*
|
|
|
|
* @param job
|
|
|
|
* The print job to kill.
|
|
|
|
*/
|
2017-02-14 07:51:33 +00:00
|
|
|
void guac_rdp_print_job_kill(guac_rdp_print_job* job);
|
2017-02-13 22:44:06 +00:00
|
|
|
|
|
|
|
#endif
|
|
|
|
|