print-job.h (6762B)
1/* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20#ifndef GUAC_RDP_PRINT_JOB_H 21#define GUAC_RDP_PRINT_JOB_H 22 23#include <guacamole/client.h> 24#include <guacamole/stream.h> 25#include <guacamole/user.h> 26 27#include <pthread.h> 28#include <unistd.h> 29 30/** 31 * The maximum number of bytes in the filename of an RDP print job sent as a 32 * file over the Guacamole protocol, including NULL terminator. 33 */ 34#define GUAC_RDP_PRINT_JOB_FILENAME_MAX_LENGTH 1024 35 36/** 37 * The default filename to use for the PDF output of an RDP print job if no 38 * document title can be found within the printed data. 39 */ 40#define GUAC_RDP_PRINT_JOB_DEFAULT_FILENAME "guacamole-print.pdf" 41 42/** 43 * The maximum number of bytes to search through at the beginning of a 44 * PostScript document when locating the document title. 45 */ 46#define GUAC_RDP_PRINT_JOB_TITLE_SEARCH_LENGTH 2048 47 48/** 49 * The current state of an RDP print job. 50 */ 51typedef enum guac_rdp_print_job_state { 52 53 /** 54 * The print stream has been opened with the Guacamole client, but the 55 * client has not yet confirmed that it is ready to receive data. 56 */ 57 GUAC_RDP_PRINT_JOB_WAITING_FOR_ACK, 58 59 /** 60 * The print stream has been opened with the Guacamole client, and the 61 * client has responded with an "ack", confirming that it is ready to 62 * receive data (or that data has been received and it is ready to receive 63 * more). 64 */ 65 GUAC_RDP_PRINT_JOB_ACK_RECEIVED, 66 67 /** 68 * The print stream has been closed or the printer is terminating, and no 69 * further data should be sent to the client. 70 */ 71 GUAC_RDP_PRINT_JOB_CLOSED 72 73} guac_rdp_print_job_state; 74 75/** 76 * Data specific to an instance of the printer device. 77 */ 78typedef struct guac_rdp_print_job { 79 80 /** 81 * The Guacamole client associated with the RDP session. 82 */ 83 guac_client* client; 84 85 /** 86 * The user receiving the output from the print job. 87 */ 88 guac_user* user; 89 90 /** 91 * The stream along which the print job output should be sent. 92 */ 93 guac_stream* stream; 94 95 /** 96 * The PID of the print filter process converting PostScript data into PDF. 97 */ 98 pid_t filter_pid; 99 100 /** 101 * The filename that should be used when the converted PDF output is 102 * streamed to the Guacamole user. This value will be automatically 103 * determined based on the contents of the printed document. 104 */ 105 char filename[GUAC_RDP_PRINT_JOB_FILENAME_MAX_LENGTH]; 106 107 /** 108 * File descriptor that should be written to when sending documents to the 109 * printer. 110 */ 111 int input_fd; 112 113 /** 114 * File descriptor that should be read from when receiving output from the 115 * printer. 116 */ 117 int output_fd; 118 119 /** 120 * The current state of the print stream, dependent on whether the client 121 * has acknowledged creation of the stream, whether the client has 122 * acknowledged receipt of data along the steam, and whether the print 123 * stream itself has closed. 124 */ 125 guac_rdp_print_job_state state; 126 127 /** 128 * Lock which is acquired prior to modifying the state property or waiting 129 * on the state_modified conditional. 130 */ 131 pthread_mutex_t state_lock; 132 133 /** 134 * Conditional which signals modification to the state property of this 135 * structure. 136 */ 137 pthread_cond_t state_modified; 138 139 /** 140 * Thread which transfers data from the printer to the Guacamole client. 141 */ 142 pthread_t output_thread; 143 144 /** 145 * The number of bytes received in the current print job. 146 */ 147 int bytes_received; 148 149} guac_rdp_print_job; 150 151/** 152 * A blob of print data being sent to the Guacamole user. 153 */ 154typedef struct guac_rdp_print_blob { 155 156 /** 157 * The print job which generated the data being sent. 158 */ 159 guac_rdp_print_job* job; 160 161 /** 162 * The data being sent. 163 */ 164 void* buffer; 165 166 /** 167 * The number of bytes of data being sent. 168 */ 169 int length; 170 171} guac_rdp_print_blob; 172 173/** 174 * Allocates a new print job for the given user. It is expected that this 175 * function will be invoked via a call to guac_client_for_user() or 176 * guac_client_for_owner(). 177 * 178 * @param user 179 * The user that should receive the output from the print job. 180 * 181 * @param data 182 * An arbitrary data parameter required by guac_client_for_user() and 183 * guac_client_for_owner() but ignored by this function. This should 184 * always be NULL. 185 * 186 * @return 187 * A pointer to a newly-allocated guac_rdp_print_job, or NULL if the 188 * print job could not be created. 189 */ 190void* guac_rdp_print_job_alloc(guac_user* user, void* data); 191 192/** 193 * Writes PostScript print data to the given active print job. The print job 194 * will automatically convert this data to PDF, streaming the result to the 195 * Guacamole user associated with the print job. This function may block if 196 * the print job is not yet ready for more data. 197 * 198 * @param job 199 * The print job to write to. 200 * 201 * @param buffer 202 * The PostScript print data to write to the given print job. 203 * 204 * @param length 205 * The number of bytes of PostScript print data to write. 206 * 207 * @return 208 * The number of bytes written, or -1 if an error occurs which prevents 209 * further writes. 210 */ 211int guac_rdp_print_job_write(guac_rdp_print_job* job, 212 void* buffer, int length); 213 214/** 215 * Frees the memory associated with the given print job, closing all underlying 216 * file descriptors, and ending the file transfer to the associated Guacamole 217 * user. This function may block if the print filter process has not yet 218 * finished processing the received data. 219 * 220 * @param job 221 * The print job to free. 222 */ 223void guac_rdp_print_job_free(guac_rdp_print_job* job); 224 225/** 226 * Forcibly kills the given print job, stopping all associated processing and 227 * streaming. The memory associated with the print job will still need to be 228 * reclaimed via guac_rdp_print_job_free(). 229 * 230 * @param job 231 * The print job to kill. 232 */ 233void guac_rdp_print_job_kill(guac_rdp_print_job* job); 234 235#endif 236