/* WARNING: This file was generated by dkct. Changes you make here will be lost if dkct is run again! You should modify the original source and run dkct on it. Original source: dkwt-pr.ctr */ /* Copyright (C) 2011-2017, Dirk Krause Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above opyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. 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. */ /** @file dkwt-pr.c The dkwt-pr module. */ #line 10 "dkwt-pr.ctr" #include "dk3all.h" #include "dkt.h" #include "dkwt.h" #line 18 "dkwt-pr.ctr" /** Job structure for dkwt printers. */ typedef struct { dk3_app_t *app; /**< Application structure. */ dkChar const * const *msg; /**< Localized message texts. */ dkChar const * const *kwnl; /**< Keywords, not localized. */ dk3_option_set_t *opt; /**< Command line options. */ int exval; /**< Exit status code. */ int f_long; /**< Flag: Long output. */ } DKWT_PRINTERS_J; /** Data for the option set. */ static dk3_option_t const dkwt_printers_options[] = { { dkT('l'), dkT("long"), 0 } }; /** Number of options in the dkt_sort_options array. */ static size_t const dkwt_printers_szoptions = sizeof(dkwt_printers_options)/sizeof(dk3_option_t); /** Initialize job structure. @param j Job structure to initialize. */ static void dkwt_printers_job_init(DKWT_PRINTERS_J *j) { j->app = NULL; j->msg = NULL; j->kwnl = NULL; j->opt = NULL; j->exval = DKT_RESULT_ERR_UNSPECIFIC; j->f_long = 0; } /** Clean up job structure. @param j Job structure to clean up. */ static void dkwt_printers_job_cleanup(DKWT_PRINTERS_J *j) { if(j) { if(j->opt) { dk3opt_close(j->opt); } j->opt = NULL; } } /** Process command line arguments. @param j Job structure. @return 1 on success (can continue), 0 on error. */ static int dkwt_printers_process_argv(DKWT_PRINTERS_J *j) { int back = 0; int xargc; dkChar const * const *xargv; xargc = dk3app_get_argc(j->app); xargv = dk3app_get_argv(j->app); #line 92 "dkwt-pr.ctr" xargv++; xargv++; xargc--; xargc--; j->opt = dk3opt_open_app( dkwt_printers_options, dkwt_printers_szoptions, dkT('\0'), NULL, xargc, xargv, j->app ); if(j->opt) { if(0 == dk3opt_get_error_code(j->opt)) { back = 1; if(dk3opt_is_set(j->opt, dkT('l'))) { j->f_long = 1; } } else { j->exval = DKT_RESULT_ERR_OPTION; } } else { j->exval = DKT_RESULT_ERR_OPTION; } return back; } /** Show details about a printer. @param j Job structure. @param txt Detail value. @param mi Index of detail name in message array. */ static void dkwt_pr_details(DKWT_PRINTERS_J *j, dkChar const *txt, size_t mi) { if(txt) { if(dk3str_len(txt)) { dk3sf_fputs((j->msg)[mi], stdout); dk3sf_fputs(txt, stdout); dk3sf_fputc(dkT('\n'), stdout); } } } /** Run the "list printers" command. @param j Job structure. */ static void dkwt_printers_run(DKWT_PRINTERS_J *j) { dkwt_printer_list_t *pl; dkwt_printer_t *pr; int not_first = 0; dkChar const *ptr; pl = dkwt_tool_open_printer_list(j->app, j->f_long); if(pl) { dkwt_tool_printer_list_reset(pl); dk3sf_initialize_stdout(); while((pr = dkwt_tool_printer_list_next(pl)) != NULL) { if((j->f_long) && (not_first)) { dk3sf_fputc(dkT('\n'), stdout); } not_first = 1; if(pr->printerName) { dk3sf_fputs(pr->printerName, stdout); dk3sf_fputc(dkT('\n'), stdout); if(j->f_long) { ptr = pr->printerName; while(*(ptr++)) { dk3sf_fputc(dkT('-'), stdout); } dk3sf_fputc(dkT('\n'), stdout); dkwt_pr_details(j, pr->comment, 44); dkwt_pr_details(j, pr->description, 45); dkwt_pr_details(j, pr->location, 46); dkwt_pr_details(j, pr->serverName, 47); dkwt_pr_details(j, pr->shareName, 48); dkwt_pr_details(j, pr->portName, 49); dkwt_pr_details(j, pr->driverName, 50); dkwt_pr_details(j, pr->deviceName, 51); dkwt_pr_details(j, pr->separatorFile, 52); dkwt_pr_details(j, pr->printProcessor, 53); dkwt_pr_details(j, pr->dataType, 54); dkwt_pr_details(j, pr->parameters, 55); } } } dkwt_tool_close_printer_list(pl); } else { j->exval = DKT_RESULT_ERR_MEMORY; } } int dkwt_printers( dk3_app_t *app, dkChar const * const *msg, dkChar const * const *kwnl ) { int back = DKT_RESULT_ERR_UNSPECIFIC; DKWT_PRINTERS_J j; dkwt_printers_job_init(&j); j.app = app; j.msg = msg; j.kwnl = kwnl; if(dkwt_printers_process_argv(&j)) { back = j.exval = DKT_RESULT_OK; dkwt_printers_run(&j); } dkwt_printers_job_cleanup(&j); return back; } /** Job structure for dkwt print. */ typedef struct { dkChar const *deviceName; /**< Device name from command line. */ dkChar const *printerName; /**< Printer name to use. */ dk3_app_t *app; /**< Application structure. */ dkChar const * const *msg; /**< Localized message texts. */ dkChar const * const *kwnl; /**< Keywords, not localized. */ dk3_option_set_t *opt; /**< Command line options. */ int exval; /**< Exit status code. */ } DKWT_PRINT_J; /** Data for the option set. */ static dk3_option_t const dkwt_print_options[] = { { dkT('d'), dkT("device"), 1 } }; /** Number of options in the dkt_print_options array. */ static size_t const dkwt_print_szoptions = sizeof(dkwt_print_options)/sizeof(dk3_option_t); /** Initialize job structure. @param j Job structure to initialize. */ static void dkwt_print_job_init(DKWT_PRINT_J *j) { j->deviceName = NULL; j->printerName = NULL; j->app = NULL; j->msg = NULL; j->kwnl = NULL; j->opt = NULL; j->exval = DKT_RESULT_ERR_UNSPECIFIC; } /** Clean up job structure. @param j Job structure to clean up. */ static void dkwt_print_job_cleanup(DKWT_PRINT_J *j) { if(j->opt) { dk3opt_close(j->opt); } j->opt = NULL; } /** Process command line arguments. @param j Job structure. @return 1 on success (can continue), 0 on error. */ static int dkwt_print_process_argv(DKWT_PRINT_J *j) { int back = 0; int xargc; dkChar const * const *xargv; #line 276 "dkwt-pr.ctr" xargc = dk3app_get_argc(j->app); xargv = dk3app_get_argv(j->app); xargv++; xargv++; xargc--; xargc--; j->opt = dk3opt_open_app( dkwt_print_options, dkwt_print_szoptions, dkT('\0'), NULL, xargc, xargv, j->app ); if(j->opt) { #line 289 "dkwt-pr.ctr" if(0 == dk3opt_get_error_code(j->opt)) { #line 290 "dkwt-pr.ctr" back = 1; if(dk3opt_is_set(j->opt, dkT('d'))) { #line 292 "dkwt-pr.ctr" j->deviceName = dk3opt_get_short_arg(j->opt, dkT('d')); if(!(j->deviceName)) { #line 294 "dkwt-pr.ctr" j->exval = DKT_RESULT_ERR_OPTION; back = 0; } } } else { j->exval = DKT_RESULT_ERR_OPTION; } } else { j->exval = DKT_RESULT_ERR_OPTION; } #line 304 "dkwt-pr.ctr" return back; } /** Schedule a file to a printer. @param j Job structure. @param hFile Destination file handle. @param fn Source file name. */ static void dkwt_print_schedule_file(DKWT_PRINT_J *j, HANDLE hFile, dkChar const *fn) { FILE *fipo; char buffer[4096]; size_t bytes; DWORD written; #line 323 "dkwt-pr.ctr" fipo = dk3sf_fopen_app(fn, dk3app_not_localized(36), j->app); if(fipo) { do { bytes = dk3sf_fread_app(buffer, 1, sizeof(buffer), fipo, j->app); if(bytes > 0) { written = 0; if(!WriteFile( hFile, (void const *)buffer, (DWORD)bytes, &written, NULL ) ) { dk3app_log_i1(j->app, DK3_LL_ERROR, 120); j->exval = DKT_RESULT_ERR_OUTPUT; } } } while(bytes > 0); fclose(fipo); } else { j->exval = DKT_RESULT_ERR_FILENAME; } #line 343 "dkwt-pr.ctr" } /** Print to a printer. @param j Job structure. @param pn Printer name. */ static void dkwt_print_to_printer(DKWT_PRINT_J *j, dkChar *pn) { HANDLE hPr; HANDLE hFile; char ajbu[sizeof(ADDJOB_INFO_1) + (sizeof(dkChar)*DK3_MAX_PATH)]; DWORD dwLev = (DWORD)1; DWORD dwSz; DWORD dwNeeded; ADDJOB_INFO_1 *aji1; int ok; DWORD dwAcc; DWORD dwSh; DWORD dwDisp; DWORD dwAttr; int oldmode; char db[4096]; int bytes; DWORD written; int nfn; /* Number of file names. */ int i; /* Current file name index. */ dkChar const *curarg; /* Current argument. */ dkChar const *curfn; /* Current file name. */ dk3_dir_t *fne; /* File name expander. */ #line 377 "dkwt-pr.ctr" ok = 0; if(OpenPrinter(pn, &hPr, NULL)) { #line 379 "dkwt-pr.ctr" dwSz = sizeof(ajbu); dwNeeded = (DWORD)0UL; if(AddJob(hPr, dwLev, (LPBYTE)ajbu, dwSz, &dwNeeded)) { aji1 = (ADDJOB_INFO_1 *)ajbu; #line 383 "dkwt-pr.ctr" if(aji1->Path) { #line 384 "dkwt-pr.ctr" hFile = INVALID_HANDLE_VALUE; dwAcc = GENERIC_WRITE; dwSh = FILE_SHARE_READ; dwDisp = CREATE_ALWAYS; dwAttr = FILE_ATTRIBUTE_NORMAL; hFile = CreateFile(aji1->Path,dwAcc,dwSh,NULL,dwDisp,dwAttr,NULL); if(hFile != INVALID_HANDLE_VALUE) { #line 391 "dkwt-pr.ctr" if(dk3opt_get_num_args(j->opt) > 0) { #line 392 "dkwt-pr.ctr" nfn = dk3opt_get_num_args(j->opt); for(i = 0; i < nfn; i++) { curarg = dk3opt_get_arg(j->opt, i); if(curarg) { #line 396 "dkwt-pr.ctr" if(dk3sf_must_expand(curarg)) { #line 397 "dkwt-pr.ctr" fne = dk3dir_fne_open_app(curarg, j->app); if(fne) { if(dk3dir_get_number_of_files(fne) > 0) { while(dk3dir_get_next_file(fne)) { curfn = dk3dir_get_fullname(fne); if(curfn) { #line 403 "dkwt-pr.ctr" dkwt_print_schedule_file(j, hFile, curfn); } else { /* BUG */ } } } else { /* ERROR: No such file */ dk3app_log_i3(j->app, DK3_LL_ERROR, 215, 216, curarg); j->exval = DKT_RESULT_ERR_FILENAME; } dk3dir_close(fne); } else { /* ERROR: No file name expander. */ j->exval = DKT_RESULT_ERR_FILENAME; } } else { #line 419 "dkwt-pr.ctr" dkwt_print_schedule_file(j, hFile, curarg); } } else { j->exval = DKT_RESULT_ERR_UNSPECIFIC; } } } else { #line 426 "dkwt-pr.ctr" oldmode = _setmode(0, _O_BINARY); do { bytes = _read(0, db, sizeof(db)); if(bytes > 0) { #line 430 "dkwt-pr.ctr" written = 0; if(!WriteFile( hFile, (void const *)db, (DWORD)bytes, &written, NULL ) ) { /* ERROR: Failed to write bytes! */ dk3app_log_i1(j->app, DK3_LL_ERROR, 120); j->exval = DKT_RESULT_ERR_OUTPUT; } } } while(bytes > 0); _setmode(0, oldmode); } ok = 1; CloseHandle(hFile); } else { #line 447 "dkwt-pr.ctr" /* ERROR: Failed to create print file! */ dk3app_log_3(j->app, DK3_LL_ERROR, j->msg, 56, 57, aji1->Path); j->exval = DKT_RESULT_ERR_UNSPECIFIC; } if(ok) { if(ScheduleJob(hPr, aji1->JobId)) { } else { /* ERROR: Failed to schedule job */ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 58); } } } else { #line 459 "dkwt-pr.ctr" j->exval = DKT_RESULT_ERR_UNSPECIFIC; } } else { #line 462 "dkwt-pr.ctr" /* ERROR: AddJob failed! */ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 59); j->exval = DKT_RESULT_ERR_UNSPECIFIC; } ClosePrinter(hPr); } else { #line 468 "dkwt-pr.ctr" /* ERROR: Failed to open printer! */ dk3app_log_3(j->app, DK3_LL_ERROR, j->msg, 60, 61, pn); j->exval = DKT_RESULT_ERR_OPTION; } #line 472 "dkwt-pr.ctr" } /** Run the "dkwt print" command. @param j Job structure. */ static void dkwt_print_run(DKWT_PRINT_J *j) { dkwt_printer_list_t *pl; dkwt_printer_t *pr; dkChar bu[DK3_MAX_PATH]; DWORD dwSz; int found = 0; #line 489 "dkwt-pr.ctr" pl = dkwt_tool_open_printer_list(j->app, 1); if(pl) { #line 491 "dkwt-pr.ctr" if(j->deviceName) { #line 492 "dkwt-pr.ctr" dkwt_tool_printer_list_reset(pl); do { pr = dkwt_tool_printer_list_next(pl); if(pr) { if((pr->portName) && (pr->printerName)) { if(dk3str_cmp(pr->portName, j->deviceName) == 0) { found = -1; if(dk3str_len(pr->printerName) < DK3_SIZEOF(bu,dkChar)) { dk3str_cpy_not_overlapped(bu, pr->printerName); found = 1; } else { /* ERROR: Printer name too long! */ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 62); } } } } } while((pr) && (found == 0)); if(found == 1) { dkwt_print_to_printer(j, bu); } else { if(found == 0) { /* ERROR: No printer found for device! */ dk3app_log_3(j->app, DK3_LL_ERROR, j->msg, 63, 64, j->deviceName); j->exval = DKT_RESULT_ERR_OPTION; } } } else { #line 520 "dkwt-pr.ctr" dwSz = DK3_SIZEOF(bu,dkChar); if(GetDefaultPrinter(bu, &dwSz)) { #line 522 "dkwt-pr.ctr" if(dwSz < DK3_SIZEOF(bu,dkChar)) { bu[dwSz] = dkT('\0'); } else { bu[DK3_SIZEOF(bu,dkChar)-1] = dkT('\0'); } #line 527 "dkwt-pr.ctr" dkwt_print_to_printer(j, bu); } else { /* ERROR: Failed to find default printer. */ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 65); j->exval = DKT_RESULT_ERR_UNSPECIFIC; } } dkwt_tool_close_printer_list(pl); } else { j->exval = DKT_RESULT_ERR_MEMORY; } #line 538 "dkwt-pr.ctr" } int dkwt_print( dk3_app_t *app, dkChar const * const *msg, dkChar const * const *kwnl ) { int back = DKT_RESULT_ERR_UNSPECIFIC; DKWT_PRINT_J j; #line 551 "dkwt-pr.ctr" dkwt_print_job_init(&j); j.app = app; j.msg = msg; j.kwnl = kwnl; if(dkwt_print_process_argv(&j)) { back = j.exval = DKT_RESULT_OK; dkwt_print_run(&j); } dkwt_print_job_cleanup(&j); back = j.exval; #line 560 "dkwt-pr.ctr" return back; }