diff options
Diffstat (limited to 'support/dktools/wprclean.c')
-rw-r--r-- | support/dktools/wprclean.c | 800 |
1 files changed, 800 insertions, 0 deletions
diff --git a/support/dktools/wprclean.c b/support/dktools/wprclean.c new file mode 100644 index 0000000000..b2bb5a2f5c --- /dev/null +++ b/support/dktools/wprclean.c @@ -0,0 +1,800 @@ +/* + 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: wprclean.ctr +*/ + +/* +Copyright (C) 2013-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 wprclean.c The wprclean module. +*/ + + +#line 8 "wprclean.ctr" + +#include "dk3all.h" +#include "dk3print.h" +#include "dk3prcfg.h" +#if 0 +#include "dkt-version.h" +#endif +#include "dk4vers.h" + + + + + +#line 20 "wprclean.ctr" + + + +/** Job structure. +*/ +typedef struct { + dk3_app_t *app; /**< Application structure. */ + dkChar const * const *msg; /**< Localized texts. */ + dkChar const * const *nlmsg; /**< Not localized texts. */ + dk3_option_set_t *opt; /**< Options. */ + dk3_print_conf_t *pc; /**< Print configuration. */ + int cmd; /**< Command to execute. */ + int comp; /**< Only jobs from this machine. */ + int exval; /**< Exit status code. */ +} WPC_JOB; + + + +#if DK3_ON_WINDOWS + +/** Information required to delete a print job. +*/ +typedef struct { + DWORD position; /**< Position in queue. */ + DWORD jobid; /**< Job ID. */ +} wprclean_printjob_t; + +#endif + + + +#ifndef WPRCLEAN_QUEUE_JOB_LIST_SIZE +/** Buffer size for job list. +*/ +#define WPRCLEAN_QUEUE_JOB_LIST_SIZE 4096 +#endif + + + +#ifndef WPRCLEAN_NUM_JOBS +/** Number of jobs to retrieve at once. +*/ +#define WPRCLEAN_NUM_JOBS 64 +#endif + + + +/** Texts used by the program, not localized. +*/ +static dkChar const * const wprclean_nlmsg[] = { +/* 0 */ +dkT("dktools"), + +/* 1 */ +dkT("wprclean.str"), + +/* 2 */ +dkT("wprclean.txt"), + +NULL + + +#line 84 "wprclean.ctr" +}; + + + +/** Texts used by the program, replaced by localized versions. +*/ +static dkChar const * const wprclean_msg[] = { +/* 0 */ +dkT("Print job "), + +/* 1 */ +dkT(" deleted."), + +/* 2 */ +dkT("Failed to delete print job "), + +/* 3 */ +dkT(", reason: "), + +/* 4 */ +dkT("."), + +/* 5 */ +dkT("Failed to open printer \""), + +/* 6 */ +dkT("\"!"), + +/* 7 */ +dkT("Printer \""), + +/* 8 */ +dkT("\" not found!"), + +NULL + + +#line 114 "wprclean.ctr" +}; + + + +/** Options for the wprclean program. +*/ +static dk3_option_t const wprclean_options[] = { + { dkT('h'), dkT("help"), 0 }, + { dkT('v'), dkT("version"), 0 }, + { dkT('L'), dkT("license-terms"), 0 }, + { dkT('c'), dkT("computer"), 0} +}; + + +/** Number of options in wprclean_options. +*/ +static size_t const wprclean_sz_options = +sizeof(wprclean_options)/sizeof(dk3_option_t); + + + +/** Default help text shown if help file not found. +*/ +static dkChar const * const wprclean_text_help[] = { +dkT(""), +dkT("NAME"), +dkT(""), +dkT(" wprclean - Windows print cleanup"), +dkT(""), +dkT("SYNOPSIS"), +dkT(""), +dkT(" wprclean [-c] [<printers>]"), +dkT(" wprclean [-h] [-v] [-L]"), +dkT(""), +dkT("DESCRIPTION"), +dkT(""), +dkT("The wprclean program deletes all print jobs created by the current user."), +dkT("It is intended for use in computer labs or PC classrooms in schools and"), +dkT("universities."), +dkT(""), +dkT("OPTIONS"), +dkT(""), +dkT("-c"), +dkT("--computer"), +dkT("\tRemove only print jobs created on the current computer."), +dkT(""), +dkT("-h"), +dkT("--help"), +dkT("\tShow this help text."), +dkT(""), +dkT("-v"), +dkT("--version"), +dkT("\tShow version information."), +dkT(""), +dkT("-L"), +dkT("--license-terms"), +dkT("\tShow the license terms."), +dkT(""), +dkT("EXIT STATUS"), +dkT(""), +dkT("0 on success, all other exit status codes indicate an error."), +dkT(""), +dkT("FILES"), +dkT(""), +dkT("The dk3print.conf file can be used to conigure short alias names for"), +dkT("Windows print queues."), +dkT(""), +dkT("AUTHOR"), +dkT(""), +dkT("Dirk Krause"), +dkT(""), +dkT("COPYRIGHT AND LICENSE"), +dkT(""), +dkT("Run"), +dkT(" wprclean --license"), +dkT("to see the license conditions."), +dkT(""), +dkT("SEE ALSO"), +dkT(""), +dkT("http://dktools.sourceforge.net"), +dkT(""), +NULL + + +#line 197 "wprclean.ctr" +}; + + + +/** License conditions. +*/ +static dkChar const * const wprclean_text_license[] = { +dkT("Copyright (c) 2013-2016, Dirk Krause"), +dkT("All rights reserved."), +dkT(""), +dkT("Redistribution and use in source and binary forms, with or without"), +dkT("modification, are permitted provided that the following conditions are met:"), +dkT(""), +dkT("* Redistributions of source code must retain the above copyright notice,"), +dkT(" this list of conditions and the following disclaimer."), +dkT("* Redistributions in binary form must reproduce the above copyright"), +dkT(" notice, this list of conditions and the following disclaimer in the"), +dkT(" documentation and/or other materials provided with the distribution."), +dkT("* Neither the name of the copyright holder(s) nor the names of"), +dkT(" contributors may be used to endorse or promote products derived from "), +dkT(" this software without specific prior written permission."), +dkT(""), +dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS"), +dkT("\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT"), +dkT("LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR"), +dkT("A PARTICULAR PURPOSE ARE DISCLAIMED."), +dkT(""), +dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY"), +dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"), +dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS"), +dkT("OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"), +dkT("HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,"), +dkT("STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING"), +dkT("IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE"), +dkT("POSSIBILITY OF SUCH DAMAGE."), +dkT(""), +NULL + + +#line 235 "wprclean.ctr" +}; + + + +/** Version information. +*/ +static dkChar const wprclean_version[] = { DKT_VERSION_DK }; + + +#if DK3_ON_WINDOWS + + +/** Delete print job information. + @param jptr Print job to delete. +*/ +static +void +wprclean_printjob_delete(wprclean_printjob_t *jptr) +{ + dk3_release(jptr); +} + + + +static +wprclean_printjob_t * +wprclean_printjob_new(DWORD pos, DWORD jid, dk3_app_t *app) +{ + wprclean_printjob_t *back = NULL; + back = dk3_new_app(wprclean_printjob_t,1,app); + if(back) { + back->position = pos; + back->jobid = jid; + } + return back; +} + + + +/** Compare print jobs by position, largest number first. + @param l Left job. + @param r Right job. + @param cr Comparison criteria (ignored). + @return Comparison result. +*/ +static +int +wprclean_compare_printjobs(void const *l, void const *r, int cr) +{ + wprclean_printjob_t const *pl; /* Left print job. */ + wprclean_printjob_t const *pr; /* Right print job. */ + int back = 0; + if(l) { + if(r) { + pl = (wprclean_printjob_t const *)l; + pr = (wprclean_printjob_t const *)r; + if(pl->position > pr->position) { + back = 1; + } else { + if(pl->position < pr->position) { + back = -1; + } + } + } else { + back = 1; + } + } else { + if(r) { + back = -1; + } + } + + /* Invert. + */ + switch(back) { + case 1: { + back = -1; + } break; + case -1: { + back = 1; + } break; + } + return back; +} + + +#endif +/* DK3_ON_WINDOWS */ + + + + +/** Delete the current users jobs from the printer. + @param job Job structure. + @param pr Printer. +*/ +static +void +wprclean_windows_printer(WPC_JOB *job, dk3_printer_t *pr) +{ +#if DK3_ON_WINDOWS + dkChar cn[DK3_MAX_PATH]; /* Current computer name. */ + dkChar nb1[64]; /* Job ID as text. */ + dkChar nb2[64]; /* Last error as text. */ + char peb[WPRCLEAN_QUEUE_JOB_LIST_SIZE]; + /* Buffer for enumeration. */ +#if DK3_CHAR_SIZE > 1 + JOB_INFO_1W *jobptr; /* Current print job. */ +#else + JOB_INFO_1A *jobptr; /* Current print job. */ +#endif + wprclean_printjob_t *pj; /* Current job to mark for deletion. */ + dk3_sto_t *sJobs; /* Storage for jobs to delete. */ + dk3_sto_it_t *iJobs; /* Iterator through storage. */ + wprclean_printjob_t *jptr; /* Current job to delete. */ + dkChar const *logname; /* Current users login name. */ + HANDLE hPr; /* Handle for printer. */ + DWORD szpeb; /* Size of peb buffer. */ + DWORD cbNeeded; /* Number of bytes needed. */ + DWORD cbReturned; /* Number of print jobs returned. */ + DWORD startindex; /* Start index for enumeration. */ + DWORD i; /* Index of current job. */ + DWORD le; /* Last error code. */ + BOOL bres; /* Operation result. */ + BOOL cc; /* Flag: Can continue. */ + BOOL mustsave; /* Flag: Must mark job for deletion. */ + + +#line 362 "wprclean.ctr" + logname = dk3app_get_logname(job->app); + if(logname) { + +#line 364 "wprclean.ctr" + if(dk3sf_get_hostname_app(cn,DK3_MAX_PATH,job->app)) { + +#line 365 "wprclean.ctr" + sJobs = dk3sto_open_app(job->app); + if(sJobs) { + +#line 367 "wprclean.ctr" + dk3sto_set_comp(sJobs, wprclean_compare_printjobs, 0); + iJobs = dk3sto_it_open(sJobs); + if(iJobs) { + +#line 370 "wprclean.ctr" + hPr = INVALID_HANDLE_VALUE; +#if DK3_CHAR_SIZE > 1 + bres = OpenPrinterW((dkChar *)(pr->name), &hPr, NULL); +#else + bres = OpenPrinterA((dkChar *)(pr->name), &hPr, NULL); +#endif + if(bres) { + +#line 377 "wprclean.ctr" + dk3sf_initialize_stdout(); + dk3sf_fputs(pr->name, stdout); + dk3sf_fputc(dkT('\n'), stdout); + fflush(stdout); + /* Enumerate print jobs. + */ + cc = TRUE; + startindex = 0; + while(cc) { + cbNeeded = 0; cbReturned = 0; szpeb = sizeof(peb); +#if DK3_CHAR_SIZE > 1 + bres = EnumJobsW( + hPr, startindex, (DWORD)WPRCLEAN_NUM_JOBS, 1, + (LPBYTE)peb, szpeb, &cbNeeded, &cbReturned + ); +#else + bres = EnumJobsA( + hPr, startindex, (DWORD)WPRCLEAN_NUM_JOBS, 1, + (LPBYTE)peb, szpeb, &cbNeeded, &cbReturned + ); +#endif + if(bres) { + +#line 399 "wprclean.ctr" + if(cbReturned > 0) { + +#line 400 "wprclean.ctr" +#if DK3_CHAR_SIZE > 1 + jobptr = (JOB_INFO_1W *)peb; +#else + jobptr = (JOB_INFO_1A *)peb; +#endif + for(i = 0; i < cbReturned; i++) { + mustsave = FALSE; + if(jobptr->pUserName) { + +#line 408 "wprclean.ctr" + if(dk3str_casecmp(logname, jobptr->pUserName) == 0) { + + +#line 410 "wprclean.ctr" + if(job->comp) { + if(jobptr->pMachineName) { + + +#line 413 "wprclean.ctr" + if(dk3str_casecmp(cn, jobptr->pMachineName) == 0) { + + +#line 415 "wprclean.ctr" + mustsave = TRUE; + } else { + if(dkT('\\') == (jobptr->pMachineName)[0]) { + if(dkT('\\') == (jobptr->pMachineName)[1]) { + if(dk3str_casecmp(cn, &((jobptr->pMachineName)[2])) == 0) { + mustsave = TRUE; + } + } + } + } + } else { + +#line 426 "wprclean.ctr" + mustsave = TRUE; + } + } else { + mustsave = TRUE; + } + } + } + if(mustsave) { + +#line 434 "wprclean.ctr" + pj = wprclean_printjob_new( + jobptr->Position, jobptr->JobId, job->app + ); + if(pj) { + +#line 438 "wprclean.ctr" + if(!dk3sto_add(sJobs, (void *)pj)) { + wprclean_printjob_delete(pj); + +#line 440 "wprclean.ctr" + job->exval = 1; + } + } else { + +#line 443 "wprclean.ctr" + job->exval = 1; + } + } + jobptr++; + } + startindex += cbReturned; + } else { + +#line 450 "wprclean.ctr" + cc = FALSE; + } + } else { + +#line 453 "wprclean.ctr" + cc = FALSE; + } + } + + /* Remove saved print jobs from queue. + */ + dk3sto_it_reset(iJobs); + while(NULL != (jptr = (wprclean_printjob_t *)dk3sto_it_next(iJobs))) { + + +#line 462 "wprclean.ctr" +#if VERSION_BEFORE_20140716 + dk3sf_sprintf3(nb1,dkT("%lu"),(unsigned long)(jptr->jobid)); +#else + if (!(dk3ma_um_to_string(nb1,DK3_SIZEOF(nb1,dkChar),(dk3_um_t)(jptr->jobid)))) { + nb1[0] = dkT('\0'); + } +#endif +#if DK3_CHAR_SIZE > 1 + bres = SetJobW(hPr, jptr->jobid, 0, NULL, JOB_CONTROL_DELETE); +#else + bres = SetJobA(hPr, jptr->jobid, 0, NULL, JOB_CONTROL_DELETE); +#endif + if(bres) { + /* DELETED */ + dk3sf_fputc(dkT('\t'), stdout); + dk3sf_fputs((job->msg)[0], stdout); + dk3sf_fputs(nb1, stdout); + dk3sf_fputs((job->msg)[1], stdout); + dk3sf_fputc(dkT('\n'), stdout); + fflush(stdout); + } else { + /* FAILED */ + le = GetLastError(); + dk3sf_fputc(dkT('\t'), stdout); +#if VERSION_BEFORE_20140716 + dk3sf_sprintf3(nb2,dkT("%lu"),(unsigned long)le); +#else + if(!(dk3ma_um_to_string(nb2,DK3_SIZEOF(nb2,dkChar),(dk3_um_t)le))) + { + nb2[0] = dkT('\0'); + } +#endif + dk3sf_fputs((job->msg)[2], stdout); + dk3sf_fputs(nb1, stdout); + dk3sf_fputs((job->msg)[3], stdout); + dk3sf_fputs(nb2, stdout); + dk3sf_fputs((job->msg)[4], stdout); + dk3sf_fputc(dkT('\n'), stdout); + fflush(stdout); + job->exval = 1; + } + } + + ClosePrinter(hPr); + } else { + +#line 507 "wprclean.ctr" + /* ERROR: Failed to open printer! */ + dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 5, 6, pr->name); + job->exval = 1; + } + + /* Release saved jobs. + */ + dk3sto_it_reset(iJobs); + while(NULL != (jptr = (wprclean_printjob_t *)dk3sto_it_next(iJobs))) { + wprclean_printjob_delete(jptr); + } + dk3sto_it_close(iJobs); + } else { + job->exval = 1; + } + dk3sto_close(sJobs); + } else { + job->exval = 1; + } + } else { + /* ERROR: Failed to find host name */ + job->exval = 1; + } + } else { + /* ERROR: Failed to find log name */ + job->exval = 1; + } + +#line 534 "wprclean.ctr" +#endif +} + + + +/** Clean up all printers on the system. + @param job Job structure. +*/ +static +void +wprclean_cleanup_all_printers(WPC_JOB *job) +{ + void *vptr; /* Current printer as returned from iterator. */ + dk3_printer_t *pr; /* Current printer. */ + + dk3sto_it_reset((job->pc)->iPrinters); + while(NULL != (vptr = dk3sto_it_next((job->pc)->iPrinters))) { + pr = (dk3_printer_t *)vptr; + if(DK3_PRINTER_TYPE_WINDOWS == pr->t_p) { + wprclean_windows_printer(job, pr); + } + } +} + + + +/** Clean up the named printers. + @param job Job structure. + @param numargs Number of command line arguments. +*/ +static +void +wprclean_cleanup_named_printers(WPC_JOB *job, int numargs) +{ + dkChar const *pn; /* Printer name. */ + dk3_printer_t *pr; /* Printer. */ + int i; /* Index of current printer. */ + + /* Pass 1: Local Windows printers. + */ + for(i = 0; i < numargs; i++) { + pn = dk3opt_get_arg(job->opt, i); + if(pn) { + pr = dk3print_get_printer(job->pc, pn); + if(pr) { + if(DK3_PRINTER_TYPE_WINDOWS == pr->t_p) { + wprclean_windows_printer(job, pr); + } + } else { + job->exval = 1; + /* ERROR: Printer not found! */ + dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 7, 8, pn); + } + } + } +} + + + +/** Do cleanup. + @param job Job structure. +*/ +static +void +wprclean_do_cleanup(WPC_JOB *job) +{ + int numargs; /* Number of command line arguments. */ + + job->pc = dk3print_conf_open(job->app, 1); + if(job->pc) { + numargs = dk3opt_get_num_args(job->opt); + job->exval = 0; + if(0 == numargs) { + wprclean_cleanup_all_printers(job); + } else { + wprclean_cleanup_named_printers(job, numargs); + } + dk3print_conf_close(job->pc); job->pc = NULL; + } +} + + + +/** Run with a configured job structure. + @param job Job structure. +*/ +static +void +wprclean_run(WPC_JOB *job) +{ + job->opt = dk3opt_open_from_app( + wprclean_options, wprclean_sz_options, + dkT('\0'), NULL, + job->app + ); + if(job->opt) { + if(0 == dk3opt_get_error_code(job->opt)) { + if(dk3opt_is_set(job->opt, dkT('h'))) { + job->cmd |= DK3_APP_CMD_HELP; + } + if(dk3opt_is_set(job->opt, dkT('v'))) { + job->cmd |= DK3_APP_CMD_VERSION; + } + if(dk3opt_is_set(job->opt, dkT('L'))) { + job->cmd |= DK3_APP_CMD_LICENSE; + } + if(dk3opt_is_set(job->opt, dkT('c'))) { + job->comp = 1; + } + if(0 == job->cmd) { + wprclean_do_cleanup(job); + } else { + job->exval = 0; + dk3sf_initialize_stdout(); + if((job->cmd) & DK3_APP_CMD_VERSION) { + dk3sf_fputs(wprclean_version, stdout); + dk3sf_fputc(dkT('\n'), stdout); + } + if((job->cmd) & DK3_APP_CMD_LICENSE) { + dk3sf_fputt(wprclean_text_license, stdout); + } + if((job->cmd) & DK3_APP_CMD_HELP) { + dk3app_help(job->app, wprclean_nlmsg[2], wprclean_text_help); + } + } + } + dk3opt_close(job->opt); job->opt = NULL; + } +} + + + +/** Program entry point. + @param argc Number of command line arguments. + @param argv Command line arguments array. + @return 0 on success, any other value indicates an error. +*/ +DK3_MAIN +{ + WPC_JOB job; /* wprclean job. */ + int exval = 1; /* Exit status code. */ + + +#line 676 "wprclean.ctr" + + +#line 677 "wprclean.ctr" + job.app = dk3app_open_command( + argc, (dkChar const * const *)argv, wprclean_nlmsg[0] + ); + if(job.app) { + job.msg = dk3app_messages( + job.app, wprclean_nlmsg[1], (dkChar const **)wprclean_msg + ); + job.nlmsg = wprclean_nlmsg; + job.cmd = 0; + job.comp = 0; + job.exval = 1; + job.pc = NULL; + wprclean_run(&job); + exval = job.exval; + dk3app_close(job.app); + } else { + fputs("wprclean: ERROR: Not enough memory!\n", stderr); + fflush(stderr); + } + + +#line 697 "wprclean.ctr" + + +#line 698 "wprclean.ctr" + fflush(stdout); + exit(exval); return exval; +} + + |