Repository: incubator-guacamole-server Updated Branches: refs/heads/master 0ea95822b -> cd8646b38
GUACAMOLE-200: Clean up PostScript document title search logic. Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/d23a22b7 Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/d23a22b7 Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/d23a22b7 Branch: refs/heads/master Commit: d23a22b7c6e966cde6a175b38cc81f005263483d Parents: 3fc43fb Author: Michael Jumper <[email protected]> Authored: Mon Feb 13 18:42:03 2017 -0800 Committer: Michael Jumper <[email protected]> Committed: Mon Feb 13 18:42:28 2017 -0800 ---------------------------------------------------------------------- src/protocols/rdp/guac_rdpdr/rdpdr_print_job.c | 130 +++++++++++++++----- src/protocols/rdp/guac_rdpdr/rdpdr_print_job.h | 6 + 2 files changed, 106 insertions(+), 30 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/d23a22b7/src/protocols/rdp/guac_rdpdr/rdpdr_print_job.c ---------------------------------------------------------------------- diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_print_job.c b/src/protocols/rdp/guac_rdpdr/rdpdr_print_job.c index 8beaac7..c3cb03c 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_print_job.c +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_print_job.c @@ -498,54 +498,124 @@ void* guac_rdpdr_print_job_alloc(guac_user* user, void* data) { } -int guac_rdpdr_print_job_write(guac_rdpdr_print_job* job, +/** + * Attempts to parse the given PostScript "%%Title:" header, storing the + * contents within the filename of the given print job. If the given buffer + * does not immediately begin with the "%%Title:" header, this function has no + * effect. + * + * @param job + * The job whose filename should be set if the "%%Title:" header is + * successfully parsed. + * + * @param buffer + * The buffer to parse as the "%%Title:" header. + * + * @param length + * The number of bytes within the buffer. + * + * @return + * Non-zero if the given buffer began with the "%%Title:" header and this + * header was successfully parsed, zero otherwise. + */ +static int guac_rdpdr_print_job_parse_title_header(guac_rdpdr_print_job* job, void* buffer, int length) { - /* Create print job, if not yet created */ - if (job->bytes_received == 0) { + int i; + char* current = buffer; + char* filename = job->filename; - char* filename = job->filename; - unsigned char* search = buffer; - int i; + /* Verify that the buffer begins with "%%Title: " */ + if (strncmp(current, "%%Title: ", 9) != 0) + return 0; - /* Search for filename within buffer */ - for (i=0; i<length-9 && i < 2048; i++) { + /* Skip past "%%Title: " */ + current += 9; + length -= 9; - /* If title. use as filename */ - if (memcmp(search, "%%Title: ", 9) == 0) { + /* Calculate space remaining in filename */ + int remaining = sizeof(job->filename) - 5 /* ".pdf\0" */; - /* Skip past "%%Title: " */ - search += 9; + /* Do not exceed bounds of provided buffer */ + if (length < remaining) + remaining = length; - /* Copy as much of title as reasonable */ - int j; - for (j=0; j < GUAC_RDPDR_PRINT_JOB_FILENAME_MAX_LENGTH - 5 /* extension + 1 */ && i<length; i++, j++) { + /* Copy as much of title as reasonable */ + for (i = 0; i < remaining; i++) { - /* Get character, stop at EOL */ - char c = *(search++); - if (c == '\r' || c == '\n') - break; + /* Get character, stop at EOL */ + char c = *(current++); + if (c == '\r' || c == '\n') + break; - /* Copy to filename */ - filename[j] = c; + /* Copy to filename */ + *(filename++) = c; - } + } - /* Append filename with extension */ - strcpy(&(filename[j]), ".pdf"); - break; - } + /* Append extension to filename */ + strcpy(filename, ".pdf"); - /* Next character */ - search++; + /* Title successfully parsed */ + return 1; - } +} + +/** + * Searches through the given buffer for PostScript headers denoting the title + * of the document, assigning the filename of the given print job using the + * discovered title. If no title can be found within + * GUAC_RDPDR_PRINT_JOB_TITLE_SEARCH_LENGTH bytes, this function has no effect. + * + * @param job + * The job whose filename should be set if the document title can be found + * within the given buffer. + * + * @param buffer + * The buffer to search for the document title. + * + * @param length + * The number of bytes within the buffer. + */ +static void guac_rdpdr_print_job_read_filename(guac_rdpdr_print_job* job, + void* buffer, int length) { + + char* current = buffer; + int i; + + /* Restrict search area */ + if (length > GUAC_RDPDR_PRINT_JOB_TITLE_SEARCH_LENGTH) + length = GUAC_RDPDR_PRINT_JOB_TITLE_SEARCH_LENGTH; + + /* Search for document title within buffer */ + for (i = 0; i < length; i++) { + + /* If document title has been found, we're done */ + if (guac_rdpdr_print_job_parse_title_header(job, current, length)) + break; + + /* Advance to next character */ + length--; + current++; + + } + +} + +int guac_rdpdr_print_job_write(guac_rdpdr_print_job* job, + void* buffer, int length) { + + /* Create print job, if not yet created */ + if (job->bytes_received == 0) { + + /* Attempt to read document title from first buffer of data */ + guac_rdpdr_print_job_read_filename(job, buffer, length); /* Begin print stream */ guac_client_for_user(job->client, job->user, guac_rdpdr_print_job_begin_stream, job); - } /* end if print job beginning */ + } /* Update counter of bytes received */ job->bytes_received += length; http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/d23a22b7/src/protocols/rdp/guac_rdpdr/rdpdr_print_job.h ---------------------------------------------------------------------- diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_print_job.h b/src/protocols/rdp/guac_rdpdr/rdpdr_print_job.h index 81b1863..97e3d62 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_print_job.h +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_print_job.h @@ -42,6 +42,12 @@ #define GUAC_RDPDR_PRINT_JOB_DEFAULT_FILENAME "guacamole-print.pdf" /** + * The maximum number of bytes to search through at the beginning of a + * PostScript document when locating the document title. + */ +#define GUAC_RDPDR_PRINT_JOB_TITLE_SEARCH_LENGTH 2048 + +/** * The current state of an RDPDR print job. */ typedef enum guac_rdpdr_print_job_state {
