/* Copyright (C) 2011-2020, Dirk Krause SPDX-License-Identifier: BSD-3-Clause */ /* WARNING: This file was generated by the dkct program (see http://dktools.sourceforge.net/ for details). 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 */ /** @file dkwt-pr.c The dkwt-pr module. */ #line 10 "dkwt-pr.ctr" #include "dk3all.h" #include "dkt.h" #include "dkwt.h" #include "dk3unused.h" #line 19 "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 93 "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 277 "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 290 "dkwt-pr.ctr" if(0 == dk3opt_get_error_code(j->opt)) { #line 291 "dkwt-pr.ctr" back = 1; if(dk3opt_is_set(j->opt, dkT('d'))) { #line 293 "dkwt-pr.ctr" j->deviceName = dk3opt_get_short_arg(j->opt, dkT('d')); if(!(j->deviceName)) { #line 295 "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 305 "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 324 "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 344 "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; #if DK3_CHAR_SIZE > 1 ADDJOB_INFO_1W *aji1; #else ADDJOB_INFO_1A *aji1; #endif 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 382 "dkwt-pr.ctr" ok = 0; #if DK3_CHAR_SIZE > 1 if(OpenPrinterW(pn, &hPr, NULL)) #else if(OpenPrinterA(pn, &hPr, NULL)) #endif { dwSz = sizeof(ajbu); dwNeeded = (DWORD)0UL; #if DK3_CHAR_SIZE > 1 if(AddJobW(hPr, dwLev, (LPBYTE)ajbu, dwSz, &dwNeeded)) #else if(AddJobA(hPr, dwLev, (LPBYTE)ajbu, dwSz, &dwNeeded)) #endif { #if DK3_CHAR_SIZE > 1 aji1 = (ADDJOB_INFO_1W *)ajbu; #line 399 "dkwt-pr.ctr" #else aji1 = (ADDJOB_INFO_1A *)ajbu; #endif if(aji1->Path) { #line 403 "dkwt-pr.ctr" hFile = INVALID_HANDLE_VALUE; dwAcc = GENERIC_WRITE; dwSh = FILE_SHARE_READ; dwDisp = CREATE_ALWAYS; dwAttr = FILE_ATTRIBUTE_NORMAL; #if DK3_CHAR_SIZE > 1 hFile = CreateFileW(aji1->Path,dwAcc,dwSh,NULL,dwDisp,dwAttr,NULL); #else hFile = CreateFileA(aji1->Path,dwAcc,dwSh,NULL,dwDisp,dwAttr,NULL); #endif if(hFile != INVALID_HANDLE_VALUE) { #line 414 "dkwt-pr.ctr" if(dk3opt_get_num_args(j->opt) > 0) { #line 415 "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 419 "dkwt-pr.ctr" if(dk3sf_must_expand(curarg)) { #line 420 "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 426 "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 442 "dkwt-pr.ctr" dkwt_print_schedule_file(j, hFile, curarg); } } else { j->exval = DKT_RESULT_ERR_UNSPECIFIC; } } } else { #line 449 "dkwt-pr.ctr" oldmode = _setmode(0, _O_BINARY); do { bytes = _read(0, db, sizeof(db)); if(bytes > 0) { #line 453 "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 470 "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 482 "dkwt-pr.ctr" j->exval = DKT_RESULT_ERR_UNSPECIFIC; } } else { #line 485 "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 491 "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 495 "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 512 "dkwt-pr.ctr" pl = dkwt_tool_open_printer_list(j->app, 1); if(pl) { #line 514 "dkwt-pr.ctr" if(j->deviceName) { #line 515 "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 543 "dkwt-pr.ctr" dwSz = DK3_SIZEOF(bu,dkChar); #if DK3_CHAR_SIZE > 1 if(GetDefaultPrinterW(bu, &dwSz)) #else if(GetDefaultPrinterA(bu, &dwSz)) #endif { #line 550 "dkwt-pr.ctr" if(dwSz < DK3_SIZEOF(bu,dkChar)) { bu[dwSz] = dkT('\0'); } else { bu[DK3_SIZEOF(bu,dkChar)-1] = dkT('\0'); } #line 555 "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 566 "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 579 "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 588 "dkwt-pr.ctr" return back; }