/* __ _ * ____ / /_ ____ ___ __ ___________ _(_) * / __ \/ __ \/ __ `__ \/ / / / ___/ __ `/ / * / /_/ / / / / / / / / / /_/ / /__/ /_/ / / * \____/_/ /_/_/ /_/ /_/\__, /\___/\__, /_/ * /____/ /____/ * * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2021, Max Christian Pohle * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * {{{ DISCLAIMER * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * }}} */ #include "main.h" #include static const char * line1 = NULL, * line2 = NULL; int print_on_correct_printer(void * user_data, unsigned flags, cups_dest_t * dest) { if(!strstr(dest->name, user_data)) { printf("> Wrong name: %s continue search\n", dest->name); return 1; } if(!dest || !line1 || !line2) { printf("FAILED: %p %p %p\n", dest, line1, line2); return 1; } int job_id = 0; int num_options = 0; cups_option_t * options = NULL; num_options = cupsAddOption(CUPS_MEDIA_TYPE, CUPS_MEDIA_TYPE_LABELS, num_options, &options); num_options = cupsAddOption(CUPS_MEDIA, CUPS_MEDIA_SOURCE_MANUAL, num_options, &options); num_options = cupsAddOption(CUPS_PRINT_QUALITY, CUPS_PRINT_QUALITY_HIGH, num_options, &options); num_options = cupsAddOption(CUPS_MEDIA, "62x15mm", num_options, &options); cups_dinfo_t * info = cupsCopyDestInfo(CUPS_HTTP_DEFAULT, dest); if (cupsCreateDestJob(CUPS_HTTP_DEFAULT, dest, info, &job_id, "My Document", num_options, options) == IPP_STATUS_OK) printf("Created job: %d\n", job_id); else printf("Unable to create job: %s\n", cupsLastErrorString()); if (cupsStartDestDocument(CUPS_HTTP_DEFAULT, dest, info, job_id, "filename.pdf", CUPS_FORMAT_TEXT, num_options, options, 1) == HTTP_STATUS_CONTINUE) { cupsWriteRequestData(CUPS_HTTP_DEFAULT, line1, strlen(line1)); cupsWriteRequestData(CUPS_HTTP_DEFAULT, "\n", 1); cupsWriteRequestData(CUPS_HTTP_DEFAULT, line2, strlen(line2)); if (cupsFinishDestDocument(CUPS_HTTP_DEFAULT, dest, info) == IPP_STATUS_OK) puts("Document send succeeded."); else printf("Document send failed: %s\n", cupsLastErrorString()); } return 0; } void send_answer(Http_Header * http_header, int fd_socket) { FILE * f = fdopen((size_t) fd_socket, "w"); fputs("HTTP/1.0 200 OK\n", f); fputs("content-type: text/html\n\n", f); fflush(f); char * printer_name = "Brother_QL-720NW"; cupsEnumDests(CUPS_DEST_FLAGS_NONE, 0, NULL, CUPS_PRINTER_VARIABLE, CUPS_PRINTER_LOCAL, print_on_correct_printer, printer_name ); line1 = NULL; line2 = NULL; int file = open("index.html", O_RDONLY); if(0 < file) { struct stat stat; fstat(file, &stat); sendfile (fileno(f), file, NULL, stat.st_size); } else { if(http_header->url) // TODO: too dangerous to check that here, that is too late. fprintf(f, "could not open file \"%s\"\n", &http_header->url[1]); } } void send_answer_file(Http_Header * http_header, int fd_socket) { FILE * f = fdopen((size_t) fd_socket, "w"); fputs("HTTP/1.0 200 OK\n", f); fputs("content-type: text/plain\n\n", f); fflush(f); int file = open(&http_header->url[1], O_RDONLY); if(0 < file) { struct stat stat; fstat(file, &stat); sendfile (fileno(f), file, NULL, stat.st_size); } else { if(http_header->url) // TODO: too dangerous to check that here, that is too late. fprintf(f, "could not open file \"%s\"\n", &http_header->url[1]); } fclose(f); return; } void next_part(Http_Header * http_header, const char * content, size_t content_size) { if(!http_header->content_disposition) return; if(strstr(http_header->content_disposition, "name=\"line1\"")) { line1 = content; } else if(strstr(http_header->content_disposition, "name=\"line2\"")) { line2 = content; } printf("> content_disposition: %s\n", http_header->content_disposition); printf("> size: %ld\n", content_size); fwrite(content, content_size, 1, stdout); puts(""); fflush(stdout); return; } // modeline for vim: shiftwidth=2 tabstop=2 number foldmethod=marker