/* 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: pqdproto.ctr */ /* Copyright (C) 2012-2013, 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 pqdproto.c The pqdproto module. */ #line 8 "pqdproto.ctr" #include "printqd.h" #line 13 "pqdproto.ctr" #if DK3_CHAR_SIZE == 1 #if DK3_HAVE_STRUCT_SOCKADDR_UN #if DK3_HAVE_SIGSET #if DK3_HAVE_GETPWNAM && DK3_HAVE_GETGRNAM /** Information about a users printed pages in a class. */ typedef struct { unsigned long limit; /**< Limit. */ unsigned long used; /**< Pages used from limit. */ unsigned long account; /**< Pages in personal account. */ int canprint; /**< Summary flag: Can print. */ int da; /**< Deny action from class. */ } pqdproto_info_t; /** Request arguments for control request. */ typedef struct { char *un; /**< User name. */ char *cn; /**< Class name. */ FILE *fp; /**< Temporary file pointer. */ pqd_job_t *jb; /**< Job structure. */ unsigned long pa; /**< Number of pages to increase. */ int ac; /**< Action (control request type). */ } pqdproto_ctrl_t; /** Request type keywords. */ static char const * const pqdproto_request_types[] = { /* 0 */ "info", /* 1 */ "acct-check", /* 2 */ "acct-start", /* 3 */ "acct-end", /* 4 */ "control", NULL #line 56 "pqdproto.ctr" }; /** Control request types. */ static char const * const pqdproto_control_requests[] = { /* 0 */ "r$eset", /* 1 */ "a$dd", /* 2 */ "d$atabase-cleanup", NULL #line 68 "pqdproto.ctr" }; /** Keywords in control request arguments. */ static char const * const pqdproto_control_args[] = { /* 0 */ "c$lass", /* 1 */ "u$ser", /* 2 */ "p$ages", NULL #line 80 "pqdproto.ctr" }; /** Keywords used by the module. */ static char const * const pqdproto_c8_kw[] = { /* 0 */ "p:", /* 1 */ "a:", /* 2 */ ":", /* 3 */ "%lu", /* 4 */ "ACCEPT", /* 5 */ "REMOVE", /* 6 */ "HOLD", /* 7 */ "-1", /* 8 */ " ", /* 9 */ "\n", /* 10 */ "j:", /* 11 */ "*", /* 12 */ "w", /* 13 */ "r", /* 14 */ "1", /* 15 */ "0", /* 16 */ "0 0 0 0", /* 17 */ "REMOVE", NULL #line 126 "pqdproto.ctr" }; /** Construct a database key. @param bp Buffer pointer to result buffer. @param sz Result buffer size. @param pr Prefix index (0 for pages, 1 for account) @param cl Class name. @param un User name. @return 1 on success, 0 on error. */ static int pqdproto_create_key( char *bp, size_t sz, size_t pr, char const *cl, char const *un ) { size_t sl; /* String length needed by all components. */ int back = 0; #line 151 "pqdproto.ctr" sl = strlen(pqdproto_c8_kw[pr]) + strlen(cl) + strlen(un) + 3; if(sl < sz) { back = 1; strcpy(bp, pqdproto_c8_kw[pr]); strcat(bp, cl); strcat(bp, pqdproto_c8_kw[2]); strcat(bp, un); #line 158 "pqdproto.ctr" } #line 159 "pqdproto.ctr" return back; } /** Initialize information structure. @param info Structure to initialize. */ static void pqdproto_initialize_info(pqdproto_info_t *info) { info->limit = 0UL; info->used = 0UL; info->account = 0UL; info->da = 0; info->canprint = 0; } /** Fill user info structure for printer and user name. @param job Job structure, @param info Information structure to fill. @param pn Printer name. @param un User name. @return 1 on success, 0 on error. */ static int pqdproto_get_printer_user_info( pqd_job_t *job, pqdproto_info_t *info, char *pn, char *un ) { char kb[PQD_CONFIG_BUFFER_SIZE]; /* Database key buffer. */ char vb[PQD_CONFIG_BUFFER_SIZE]; /* Database value buffer. */ pqd_printer_t *pr; /* Printer data. */ pqd_alias_t *al; /* Printer alias data. */ pqd_class_t *cl; /* Class data for printer. */ pqd_limit_t *li; /* Page limit data. */ struct passwd *pw; /* User account. */ struct group *gr; /* Group data. */ char **mp; /* Group member list. */ unsigned long ul; /* Scanf result. */ int back = 0; #line 208 "pqdproto.ctr" pqdproto_initialize_info(info); pr = NULL; al = NULL; cl = NULL; /* Find real printer and class for printer name. */ al = (pqd_alias_t *)dk3sto_it_find_like((job->cfg).i_a, (void *)pn, 1); if(al) { pr = al->pr; } else { pr = (pqd_printer_t *)dk3sto_it_find_like((job->cfg).i_p, (void *)pn, 1); } if(pr) { cl = pr->cl; } if(cl) { back = 1; /* Use class default limit. */ info->limit = cl->dl; info->da = cl->da; /* Check for users personal limit. */ li = (pqd_limit_t *)dk3sto_it_find_like(cl->i_u, (void *)un, 1); if(li) { /* Use personal limit. */ info->limit = li->limit; } else { /* Check all group memberships. */ pw = getpwnam(un); if(pw) { dk3sto_it_reset(cl->i_g); while(NULL != (li = (pqd_limit_t *)dk3sto_it_next(cl->i_g))) { if(li->limit > info->limit) { gr = getgrnam(li->name); if(gr) { if(pw->pw_gid == gr->gr_gid) { info->limit = li->limit; } else { if(gr->gr_mem) { mp = gr->gr_mem; while((*mp) && (li->limit > info->limit)) { if(0 == strcmp(*mp, un)) { info->limit = li->limit; } } } } } } } } } /* Get number of pages printed. */ if(pqdproto_create_key(kb, sizeof(kb), 0, cl->name, un)) { if(dk3dbi_get_c8_string(job->db, kb, vb, sizeof(vb))) { if(1 == sscanf(vb, pqdproto_c8_kw[3], &ul)) { info->used = ul; } } } else { back = 0; /* ERROR: Database key name too long! */ } /* Get number of pages in personal account. */ if(pqdproto_create_key(kb, sizeof(kb), 1, cl->name, un)) { if(dk3dbi_get_c8_string(job->db, kb, vb, sizeof(vb))) { if(1 == sscanf(vb, pqdproto_c8_kw[3], &ul)) { info->account = ul; } } } else { back = 0; /* ERROR: Database key name too long! */ } /* Find summary. */ if(info->limit > info->used) { info->canprint = 1; } else { if(0UL < info->account) { info->canprint = 1; } } } #line 301 "pqdproto.ctr" return back; } /** Fill user info structure from request arguments. @param job job structure. @param info Information structure to fill. @param args Request arguments. @return 1 on success, 0 on error. */ static int pqdproto_get_info(pqd_job_t *job, pqdproto_info_t *info, char *args) { char *pn; /* Printer name. */ char *un; /* User name. */ int back = 0; #line 320 "pqdproto.ctr" pqdproto_initialize_info(info); pn = dk3str_c8_start(args, NULL); if(pn) { un = dk3str_c8_next(pn, NULL); if(un) { (void)dk3str_c8_next(un, NULL); back = pqdproto_get_printer_user_info(job, info, pn, un); } } #line 329 "pqdproto.ctr" return back; } /** Process info request. @param job Job structure. @param args Request arguments. */ static void pqdproto_info(pqd_job_t *job, char *args) { char vb[128]; pqdproto_info_t info; #line 345 "pqdproto.ctr" (job->p_o)[0] = '\0'; strcpy(job->p_o, pqdproto_c8_kw[16]); job->fres = 1; if(pqdproto_get_info(job, &info, args)) { if(DK3_UL_MAX == info.limit) { strcpy(job->p_o, pqdproto_c8_kw[7]); } else { sprintf(job->p_o, pqdproto_c8_kw[3], info.limit); } strcat(job->p_o, pqdproto_c8_kw[8]); sprintf(vb, pqdproto_c8_kw[3], info.used); strcat(job->p_o, vb); strcat(job->p_o, pqdproto_c8_kw[8]); sprintf(vb, pqdproto_c8_kw[3], info.account); strcat(job->p_o, vb); strcat(job->p_o, pqdproto_c8_kw[8]); strcat(job->p_o, pqdproto_c8_kw[(info.canprint) ? 14 : 15]); strcat(job->p_o, pqdproto_c8_kw[9]); } #line 364 "pqdproto.ctr" } /** Process acct-check request. @param job Job structure. @param args Request arguments. */ static void pqdproto_check(pqd_job_t *job, char *args) { pqdproto_info_t info; #line 378 "pqdproto.ctr" strcpy(job->p_o, pqdproto_c8_kw[17]); job->fres = 1; if(pqdproto_get_info(job, &info, args)) { if(info.canprint) { strcpy(job->p_o, pqdproto_c8_kw[4]); } else { if(info.da) { strcpy(job->p_o, pqdproto_c8_kw[6]); } else { strcpy(job->p_o, pqdproto_c8_kw[5]); } } } #line 391 "pqdproto.ctr" } /** Process acct-start request. @param job Job structure. @param args Request arguments. */ static void pqdproto_start(pqd_job_t *job, char *args) { char kb[PQD_CONFIG_BUFFER_SIZE]; /* Database key buffer. */ char vb[PQD_CONFIG_BUFFER_SIZE]; /* Database value buffer. */ pqd_printer_t *pr; /* Printer data. */ pqd_alias_t *al; /* Printer alias data. */ char *pn; /* Printer name from args. */ char *un; /* User name from args. */ char *pc; /* Pagecount from args. */ char *jn; /* Job name from args. */ char *jt; /* Job title from args. */ unsigned long ul; /* Scanf result. */ size_t sl; /* String length. */ #line 415 "pqdproto.ctr" pn = un = pc = jn = jt = NULL; pn = dk3str_c8_start(args, NULL); if(pn) { #line 418 "pqdproto.ctr" un = dk3str_c8_next(pn, NULL); if(un) { #line 420 "pqdproto.ctr" pc = dk3str_c8_next(un, NULL); if(pc) { #line 422 "pqdproto.ctr" jn = dk3str_c8_next(pc, NULL); if(jn) { #line 424 "pqdproto.ctr" jt = dk3str_c8_next(jn, NULL); if(jt) { #line 426 "pqdproto.ctr" if(1 == sscanf(pc, pqdproto_c8_kw[3], &ul)) { pr = NULL; al = NULL; al = (pqd_alias_t *)dk3sto_it_find_like( (job->cfg).i_a, (void *)pn, 1 ); if(al) { pr = al->pr; } else { pr = (pqd_printer_t *)dk3sto_it_find_like( (job->cfg).i_p, (void *)pn, 1 ); } if(pr) { sl = strlen(pr->name) + strlen(pqdproto_c8_kw[10]); if(sl < sizeof(kb)) { strcpy(kb, pqdproto_c8_kw[10]); strcat(kb, pr->name); #line 443 "pqdproto.ctr" dk3dbi_delete_c8_string(job->db, kb); sl = strlen(pc) + strlen(un) + strlen(jn) + 3; if(sl < sizeof(vb)) { strcpy(vb, pc); strcat(vb, pqdproto_c8_kw[2]); strcat(vb, un); strcat(vb, pqdproto_c8_kw[2]); strcat(vb, jn); #line 451 "pqdproto.ctr" dk3dbi_set_c8_string(job->db, kb, vb); } else { #line 453 "pqdproto.ctr" } } else { #line 455 "pqdproto.ctr" } } else { #line 457 "pqdproto.ctr" } } else { #line 459 "pqdproto.ctr" } } else { #line 461 "pqdproto.ctr" } } else { #line 463 "pqdproto.ctr" } } else { #line 465 "pqdproto.ctr" } } else { #line 467 "pqdproto.ctr" } } else { #line 469 "pqdproto.ctr" } #line 471 "pqdproto.ctr" } /** Write a line to log file containing page limit, old used pages, old account, job size, new used pages, and new account. @param job Job structure. @param info Info structure containing user limit and account. @param prp Pages printed for job. @param usn New value for used pages. @param acn New value for account. */ static void pqdproto_log_result( pqd_job_t *job, pqdproto_info_t *info, unsigned long prp, unsigned long usn, unsigned long acn ) { char bu[256]; char *ptr[2]; sprintf(bu,(job->lmsg)[5],info->limit,info->used,info->account,prp,usn,acn); #if VERSION_BEFORE_20120526 dk3app_log_3(job->app, DK3_LL_INFO, job->lmsg, 6, 7, bu); #else ptr[0] = bu; ptr[1] = NULL; dk3app_log_msg(job->app, DK3_LL_INFO, (char const * const *)ptr, 1); #endif } /** Process acct-end request. @param job Job structure. @param args Request arguments. */ static void pqdproto_end(pqd_job_t *job, char *args) { char kb[PQD_CONFIG_BUFFER_SIZE]; /* Database key buffer. */ char vb[PQD_CONFIG_BUFFER_SIZE]; /* Database value buffer. */ pqdproto_info_t info; /* User account information. */ pqd_printer_t *pr; /* Printer data. */ pqd_alias_t *al; /* Printer alias data. */ pqd_class_t *cl; /* Printer class data. */ char *pn; /* Printer name from args. */ char *un; /* User name from args. */ char *pc; /* Pagecount from args. */ char *jn; /* Job name from args. */ char *jt; /* Job title from args. */ char *p1; /* Job start page count. */ char *p2; /* Job start user name. */ char *p3; /* Job start job name. */ unsigned long ul; /* Scanf result. */ unsigned long pco; /* Page counter value old. */ unsigned long pcn; /* Page counter value new. */ unsigned long prp; /* Printed pages in job. */ unsigned long usn; /* Used pages new. */ unsigned long acn; /* Account value new. */ unsigned long ovl; /* Pages printed over limit. */ size_t sl; /* String length. */ int res; /* Operation result. */ #line 538 "pqdproto.ctr" pr = NULL; al = NULL; cl = NULL; pn = un = pc = jn = jt = NULL; pco = pcn = prp = usn = acn = 0UL; pn = dk3str_c8_start(args, NULL); if(pn) { un = dk3str_c8_next(pn, NULL); if(un) { pc = dk3str_c8_next(un, NULL); if(pc) { jn = dk3str_c8_next(pc, NULL); if(jn) { jt = dk3str_c8_next(jn, NULL); if(jt) { #line 551 "pqdproto.ctr" if(1 == sscanf(pc, pqdproto_c8_kw[3], &ul)) { #line 552 "pqdproto.ctr" pcn = ul; pr = NULL; al = NULL; al = (pqd_alias_t *)dk3sto_it_find_like( (job->cfg).i_a, (void *)pn, 1 ); if(al) { pr = al->pr; } else { pr = (pqd_printer_t *)dk3sto_it_find_like( (job->cfg).i_p, (void *)pn, 1 ); } if(pr) { #line 565 "pqdproto.ctr" cl = pr->cl; if(cl) { #line 567 "pqdproto.ctr" sl = strlen(pr->name) + strlen(pqdproto_c8_kw[10]); if(sl < sizeof(kb)) { #line 569 "pqdproto.ctr" strcpy(kb, pqdproto_c8_kw[10]); strcat(kb, pr->name); if(dk3dbi_get_c8_string(job->db, kb, vb, sizeof(vb))) { #line 573 "pqdproto.ctr" dk3dbi_delete_c8_string(job->db, kb); p1 = dk3str_c8_start(vb, NULL); #line 575 "pqdproto.ctr" if(p1) { #line 576 "pqdproto.ctr" p2 = dk3str_chr(p1, ':'); if(p2) { #line 578 "pqdproto.ctr" *(p2++) = '\0'; p3 = dk3str_chr(p2, ':'); if(p3) { #line 581 "pqdproto.ctr" *(p3++) = '\0'; if(0 == strcmp(un, p2)) { #line 583 "pqdproto.ctr" if(0 == strcmp(jn, p3)) { #line 584 "pqdproto.ctr" if(1 == sscanf(p1, pqdproto_c8_kw[3], &ul)) { pco = ul; #line 586 "pqdproto.ctr" if(pcn > pco) { #line 587 "pqdproto.ctr" res = pqdproto_get_printer_user_info( job, &info, pn, un ); if(res) { #line 591 "pqdproto.ctr" usn = info.used; acn = info.account; prp = pcn - pco; usn = info.used + prp; if(usn > info.limit) { ovl = usn - info.limit; if(info.account >= ovl) { usn = info.limit; acn = info.account - ovl; } else { ovl = ovl - info.account; acn = 0UL; usn = info.limit + ovl; } } /* Save new value for used pages. */ res = pqdproto_create_key( kb, sizeof(kb), 0, cl->name, un ); if(res) { if(usn) { sprintf(vb, pqdproto_c8_kw[3], usn); dk3dbi_set_c8_string(job->db, kb, vb); } else { #line 617 "pqdproto.ctr" dk3dbi_delete_c8_string(job->db, kb); } } /* Save new value for account. */ res = pqdproto_create_key( kb, sizeof(kb), 1, cl->name, un ); if(res) { if(acn) { #line 628 "pqdproto.ctr" sprintf(vb, pqdproto_c8_kw[3], acn); dk3dbi_set_c8_string(job->db, kb, vb); #line 631 "pqdproto.ctr" } else { #line 632 "pqdproto.ctr" dk3dbi_delete_c8_string(job->db, kb); } } /* LOG RESULT */ pqdproto_log_result( job, &info, prp, usn, acn ); } else { #line 640 "pqdproto.ctr" } } else { #line 642 "pqdproto.ctr" } } else { #line 644 "pqdproto.ctr" } } else { #line 646 "pqdproto.ctr" } } else { #line 648 "pqdproto.ctr" } } else { #line 650 "pqdproto.ctr" } } else { #line 652 "pqdproto.ctr" } } else { #line 654 "pqdproto.ctr" } } else { #line 656 "pqdproto.ctr" } } else { #line 658 "pqdproto.ctr" } } else { #line 660 "pqdproto.ctr" } } else { #line 662 "pqdproto.ctr" } } else { #line 664 "pqdproto.ctr" } } else { #line 666 "pqdproto.ctr" } } else { #line 668 "pqdproto.ctr" } } else { #line 670 "pqdproto.ctr" } } else { #line 672 "pqdproto.ctr" } } else { #line 674 "pqdproto.ctr" } #line 676 "pqdproto.ctr" } /** Process request arguments, fill control structure. @param ctrl Control structure to fill. @param args Control request arguments. @param job Job structure. */ static void pqdproto_fill_control_data(pqdproto_ctrl_t *ctrl, char *args, pqd_job_t *job) { char *pc; /* Pointer to current argument. */ char *pn; /* Pointer to next argument. */ char *pv; /* Pointer to argument value. */ unsigned long ul; /* Result from sscanf(). */ int act; /* Action to take. */ #line 695 "pqdproto.ctr" ctrl->un = NULL; ctrl->cn = NULL; ctrl->pa = 0UL; ctrl->fp = NULL; ctrl->jb = job; ctrl->ac = 0; pc = args; while(pc) { pn = dk3str_c8_next(pc, NULL); #line 704 "pqdproto.ctr" pv = dk3str_chr(pc, '='); if(pv) { *(pv++) = '\0'; pv = dk3str_c8_start(pv, NULL); if(pv) { act = dk3str_c8_array_abbr(pqdproto_control_args, pc, '$', 0); switch(act) { case 0: { #line 712 "pqdproto.ctr" ctrl->cn = pv; } break; case 1: { #line 715 "pqdproto.ctr" ctrl->un = pv; } break; case 2: { #line 718 "pqdproto.ctr" if(1 == sscanf(pv, pqdproto_c8_kw[3], &ul)) { ctrl->pa = ul; } } break; } } else { #line 724 "pqdproto.ctr" } } else { #line 726 "pqdproto.ctr" } pc = pn; } #line 730 "pqdproto.ctr" } /** Set pointers to information parts in database key. @param p1 Address of first part pointer. @param p2 Address of second part pointer. @param str Original string. */ static void pqdproto_set_part_pointers(char **p1, char **p2, char *str) { char *x1; char *x2; #line 746 "pqdproto.ctr" x1 = NULL; x2 = NULL; x1 = dk3str_c8_chr(str, ':'); if(x1) { *(x1++) = '\0'; x1 = dk3str_c8_start(x1, NULL); if(x1) { x2 = dk3str_c8_chr(x1, ':'); if(x2) { *(x2++) = '\0'; x2 = dk3str_c8_start(x2, NULL); } } } *p1 = x1; *p2 = x2; #line 763 "pqdproto.ctr" } /** Check wether a string matches a given name. @param p String to check. @param n Name to check, may also be NULL or "*". @return 1 if the strings match, 0 otherwise. */ static int pqdproto_string_matches(char const *p, char const *n) { int back = 0; #line 778 "pqdproto.ctr" if(p) { if(n) { if(0 == strcmp(pqdproto_c8_kw[11], n)) { back = 1; } else { if(0 == strcmp(p, n)) { back = 1; } } } else { back = 1; } } #line 791 "pqdproto.ctr" return back; } /** Database traversal function to reset and clean up the database. @param obj Control structure. @param key Database key. @param val Database value. @return 1 on success, 0 on minor error, -1 on error. */ static int pqdproto_traverse_db(void *obj, dk3_datum_t *key, dk3_datum_t *val) { char kb[PQD_CONFIG_BUFFER_SIZE]; /* DB key buffer. */ char vb[PQD_CONFIG_BUFFER_SIZE]; /* DB val buffer. */ pqdproto_ctrl_t *ctrl; /* Control structure. */ char *p1; /* Class name. */ char *p2; /* User name. */ pqd_class_t *cl; /* Class data. */ pqd_limit_t *pl; /* Limit data. */ pqd_printer_t *pr; /* Printer data. */ unsigned long ul; /* Result sscanf. */ int mr; /* Flag: Must remove. */ int back = 1; #line 818 "pqdproto.ctr" ctrl = (pqdproto_ctrl_t *)obj; if(key) { if(key->dt) { if(key->sz < sizeof(kb)) { dk3mem_cpy(kb, key->dt, key->sz); kb[key->sz] = '\0'; #line 824 "pqdproto.ctr" mr = 0; p1 = NULL; p2 = NULL; switch(ctrl->ac) { case 0: { #line 829 "pqdproto.ctr" if('p' == kb[0]) { pqdproto_set_part_pointers(&p1, &p2, kb); if((p1) && (p2)) { #line 832 "pqdproto.ctr" if(pqdproto_string_matches(p2, ctrl->un)) { #line 833 "pqdproto.ctr" if(pqdproto_string_matches(p1, ctrl->cn)) { #line 834 "pqdproto.ctr" mr = 1; #line 835 "pqdproto.ctr" } } } } } break; case 2: { #line 841 "pqdproto.ctr" switch(kb[0]) { case 'p': case 'a': { #line 843 "pqdproto.ctr" pqdproto_set_part_pointers(&p1, &p2, kb); if((p1) && (p2)) { #line 845 "pqdproto.ctr" cl = (pqd_class_t *)dk3sto_it_find_like( ((ctrl->jb)->cfg).i_c, p1, 1 ); if(cl) { pl = (pqd_limit_t *)dk3sto_it_find_like( cl->i_u, p2, 1 ); if(!(pl)) { if(!getpwnam(p2)) { #line 854 "pqdproto.ctr" mr = 1; } } } else { #line 858 "pqdproto.ctr" mr = 1; } } } break; case 'j': { #line 863 "pqdproto.ctr" pqdproto_set_part_pointers(&p1, &p2, kb); if(p1) { #line 865 "pqdproto.ctr" pr = (pqd_printer_t *)dk3sto_it_find_like( ((ctrl->jb)->cfg).i_p, p1, 1 ); if(!(pr)) { #line 869 "pqdproto.ctr" mr = 1; } } } break; } if((!(mr)) && ((kb[0] == 'p') || (kb[0] == 'a'))) { if(val) { if(val->dt) { if(val->sz < sizeof(vb)) { dk3mem_cpy(vb, val->dt, val->sz); vb[val->sz] = '\0'; if(1 == sscanf(vb, pqdproto_c8_kw[3], &ul)) { if(0UL == ul) { #line 882 "pqdproto.ctr" mr = 1; } } } } else { mr = 1; } } else { mr = 1; } } } break; } if(mr) { dk3mem_cpy(kb, key->dt, key->sz); kb[key->sz] = '\0'; #line 898 "pqdproto.ctr" fputs(kb, ctrl->fp); fputc('\n', ctrl->fp); } } } } #line 904 "pqdproto.ctr" return back; } /** Clean up database. @param job Job structure. @param args Request arguments. @param act Action (0=reset, 2=database-cleanup). */ static void pqdproto_cleanup_database(pqd_job_t *job, char *args, int act) { char kb[PQD_CONFIG_BUFFER_SIZE]; /* DB key name. */ pqdproto_ctrl_t ctrl; /* Control struct. */ int res; /* Traverse result. */ #line 922 "pqdproto.ctr" pqdproto_fill_control_data(&ctrl, args, job); ctrl.ac = act; ctrl.fp = dk3sf_fopen_app(job->tmpn, pqdproto_c8_kw[12], job->app); if(ctrl.fp) { #line 926 "pqdproto.ctr" res = dk3dbi_traverse(job->db, (void *)(&ctrl), pqdproto_traverse_db); fclose(ctrl.fp); ctrl.fp = NULL; ctrl.fp = dk3sf_fopen_app(job->tmpn, pqdproto_c8_kw[13], job->app); if(ctrl.fp) { #line 930 "pqdproto.ctr" while(fgets(kb, sizeof(kb), ctrl.fp)) { dk3str_c8_delnl(kb); #line 932 "pqdproto.ctr" dk3dbi_delete_c8_string(job->db, kb); } fclose(ctrl.fp); ctrl.fp = NULL; } else { #line 936 "pqdproto.ctr" } dk3sf_c8_remove_file_app(job->tmpn, job->app); } else { #line 939 "pqdproto.ctr" } #line 940 "pqdproto.ctr" } /** Reset number of used pages for specified user(s) and class(es). @param job Job structure. @param args Request arguments. */ static void pqdproto_control_reset(pqd_job_t *job, char *args) { pqdproto_cleanup_database(job, args, 0); } /** Add pages to a personal print account. @param job Job structure. @param args Request arguments. */ static void pqdproto_control_add(pqd_job_t *job, char *args) { char kb[PQD_CONFIG_BUFFER_SIZE]; /* DB key name. */ char vb[PQD_CONFIG_BUFFER_SIZE]; /* DB value buffer. */ pqdproto_ctrl_t ctrl; /* Control struct. */ unsigned long ul; /* Result sscanf. */ size_t sl; /* String length. */ pqdproto_fill_control_data(&ctrl, args, job); ctrl.ac = 1; #line 973 "pqdproto.ctr" if((ctrl.un) && (ctrl.cn) && (ctrl.pa)) { sl = strlen(ctrl.un) + strlen(ctrl.cn) + strlen(pqdproto_c8_kw[1]) + 2; if(sl < sizeof(kb)) { #line 976 "pqdproto.ctr" strcpy(kb, pqdproto_c8_kw[1]); strcat(kb, ctrl.cn); strcat(kb, pqdproto_c8_kw[2]); strcat(kb, ctrl.un); #line 980 "pqdproto.ctr" if(dk3dbi_get_c8_string(job->db, kb, vb, sizeof(vb))) { if(1 == sscanf(vb, pqdproto_c8_kw[3], &ul)) { ctrl.pa += ul; #line 983 "pqdproto.ctr" } } sprintf(vb, pqdproto_c8_kw[3], ctrl.pa); dk3dbi_set_c8_string(job->db, kb, vb); } } #line 989 "pqdproto.ctr" } /** Clean up database, remove entries for non-existent classes, printers, and users. @param job Job structure. @param args Request arguments. */ static void pqdproto_control_cleanup(pqd_job_t *job, char *args) { pqdproto_cleanup_database(job, args, 2); } /** Process control request. @param job Job structure. @param args Request arguments. */ static void pqdproto_control(pqd_job_t *job, char *args) { char *arg; /* Argumens after control request. */ int act; /* Action to take. */ #line 1018 "pqdproto.ctr" arg = dk3str_c8_next(args, NULL); act = dk3str_c8_array_abbr(pqdproto_control_requests, args, '$', 0); switch(act) { case 0: { #line 1022 "pqdproto.ctr" pqdproto_control_reset(job, arg); } break; case 1: { #line 1025 "pqdproto.ctr" pqdproto_control_add(job, arg); } break; case 2: { #line 1028 "pqdproto.ctr" pqdproto_control_cleanup(job, arg); } break; } #line 1031 "pqdproto.ctr" } void pqdproto_process(pqd_job_t *job) { char bu[PQD_INPUT_BUFFER_SIZE]; /* Request copy. */ char *p1; /* Request keyword. */ char *p2; /* Request arguments. */ int rt; /* Request type. */ #line 1043 "pqdproto.ctr" if(strlen(job->p_i) < sizeof(bu)) { strcpy(bu, job->p_i); p1 = dk3str_c8_start(bu, NULL); if(p1) { p2 = dk3str_c8_next(p1, NULL); if(p2) { rt = dk3str_c8_array_index(pqdproto_request_types, p1, 0); job->rqt = rt; if(0 < rt) { #line 1052 "pqdproto.ctr" /* LOG REQUEST */ #if VERSION_BEFORE_20120526 dk3app_log_3(job->app, DK3_LL_INFO, job->lmsg, 1, 2, job->p_i); #else dk3app_log_msg( job->app, DK3_LL_INFO, (dkChar const * const *)(&(job->p_i)), 1 ); #endif } #line 1061 "pqdproto.ctr" switch(rt) { case 0: { pqdproto_info(job, p2); } break; case 1: { pqdproto_check(job, p2); } break; case 2: { pqdproto_start(job, p2); } break; case 3: { pqdproto_end(job, p2); } break; case 4: { pqdproto_control(job, p2); } break; } if(0 < rt) { if(job->fres) { /* LOG RESPONSE */ #if VERSION_BEFORE_20120526 dk3app_log_3(job->app, DK3_LL_INFO, job->lmsg, 3, 4, job->p_o); #else dk3app_log_msg( job->app, DK3_LL_INFO, (dkChar const * const *)(&(job->p_o)), 1 ); #endif } } } } } else { /* ERROR: Request too long! */ } #line 1096 "pqdproto.ctr" } #endif #endif #endif #endif