diff options
Diffstat (limited to 'support/dktools/printqdc.ctr')
-rw-r--r-- | support/dktools/printqdc.ctr | 1369 |
1 files changed, 0 insertions, 1369 deletions
diff --git a/support/dktools/printqdc.ctr b/support/dktools/printqdc.ctr deleted file mode 100644 index 3f94bec715..0000000000 --- a/support/dktools/printqdc.ctr +++ /dev/null @@ -1,1369 +0,0 @@ -%% options - -copyright owner = Dirk Krause -copyright year = 2016-xxxx -SPDX-License-Identifier: BSD-3-Clause - - - -%% module - -#include "dk4conf.h" -#include "dk4types.h" - -#include <stdio.h> - -#if DK4_HAVE_STDLIB_H -#ifndef STDLIB_H_INCLUDED -#include <stdlib.h> -#define STDLIB_H_INCLUDED 1 -#endif -#endif - -#if DK4_HAVE_UNISTD_H -#ifndef UNISTD_H_INCLUDED -#include <unistd.h> -#define UNISTD_H_INCLUDED 1 -#endif -#endif - -#if DK4_HAVE_PROCESS_H -#ifndef PROCESS_H_INCLUDED -#include <process.h> -#define PROCESS_H_INCLUDED 1 -#endif -#endif - - - -/** Requirements to build this program: - * Use 8 bit characters, so we can use the directories from dk4inst.c. - * Signal handling mechanism. -*/ -#if (DK4_CHAR_SIZE == 1) && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET)) - - - -#if DK4_HAVE_MATH_H -#ifndef MATH_H_INCLUDED -#if DK4_ON_WINDOWS -#ifndef _USE_MATH_DEFINES -#define _USE_MATH_DEFINES 1 -#endif -#endif -#include <math.h> -#define MATH_H_INCLUDED 1 -#endif -#endif - -#if DK4_HAVE_ERRNO_H -#ifndef ERRNO_H_INCLUDED -#include <errno.h> -#define ERRNO_H_INCLUDED 1 -#endif -#endif - -#if DK4_HAVE_SYS_TYPES_H -#ifndef SYS_TYPES_H_INCLUDED -#include <sys/types.h> -#define SYS_TYPES_H_INCLUDED 1 -#endif -#endif - -#if DK4_HAVE_IO_H -#ifndef IO_H_INCLUDED -#include <io.h> -#define IO_H_INCLUDED 1 -#endif -#endif - -#if DK4_HAVE_FCNTL_H -#ifndef FCNTL_H_INCLUDED -#include <fcntl.h> -#define FCNTL_H_INCLUDED 1 -#endif -#endif - -#if DK4_HAVE_STRING_H -#ifndef STRING_H_INCLUDED -#include <string.h> -#define STRING_H_INCLUDED 1 -#endif -#endif - -#include "dk4inst.h" -#include "dk4mpl.h" -#include "dk4mem.h" -#include "dk4mai8ddu.h" -#include "dk4mai8dus.h" -#include "dk4str8.h" -#include "dk4lprng.h" -#include "dk4opt.h" -#include "dk4sock.h" -#include "dk4vers.h" -#include "dk4unused.h" - - - -$!trace-include - - - -/** Information from one LPRng accounting line. -*/ -typedef struct { - char *username; - char *queuename; - char *jobtitle; - char *pagecount; -} lprng_info_t; - - - - -/** Command line options for program. -*/ -static dk4_option_t options[] = { - { { dkT('i'), dkT("interactive"), DK4_OPT_ARG_NONE }, { NULL }, 0}, - { { dkT('s'), dkT("socket"), DK4_OPT_ARG_STRING }, { NULL }, 0}, - { { dkT('h'), dkT("host"), DK4_OPT_ARG_STRING }, { NULL }, 0}, - { { dkT('p'), dkT("port"), DK4_OPT_ARG_UNSIGNED }, { NULL }, 0}, - { { dkT('\0'),dkT("help"), DK4_OPT_ARG_NONE}, { NULL }, 0}, - { { dkT('\0'),dkT("version"), DK4_OPT_ARG_NONE}, { NULL }, 0}, - { { dkT('\0'),dkT("license"), DK4_OPT_ARG_NONE}, { NULL }, 0} -}; - - - -/** Help text. -*/ -static const char * const help_text[] = { -$!text - -Print quota daemon client - -printqdc [-i] [-s path] | [-h host -p port] - --i Interactive mode instead of default pipe mode. ---interactive - --s path Path name for local UNIX domain socket. ---socket=path - --h host Host name of remote host. ---host=host - --p port Port number at remote host. ---port=port - ---help Show this help text. ---version Show version number. ---license Show license information. - -$!end -}; - - - -/** License conditions text. -*/ -static const char * const license_text[] = { -$!text preprocessor - -This software uses code from the following projects, either directly or as -a library: - -dktools Dirk Krause's tools and libraries. - See http://sourceforge.net/p/dktools/wiki/Home/ - for more information. - -DK tools and libraries license -============================== -Copyright (c) 2015-2016, Dirk Krause -All rights reserved. - -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. -3. Neither the name of the copyright holder nor the names of its - 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 HOLDER 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. - -$!end -}; - - - -/** Version information. -*/ -static const char version_text[] = { DKT_VERSION_C8 }; - - - -/** Constant text keywords used by the module. -*/ -static const char * const pqdc_kw[] = { -$!string-table -# -# 0 Newline -# -\n -# -# 1 Space -# - -# -# 2 Default job name -# -x@x+1 -# -# 3 Default job title -# -Print job -# -# 4 -# --> -# -# 5 6 -# -<- " -"\n -# -# 7 ... 10 -# -printqdc: -ERROR: Port number too large!\n -ERROR: Port number required!\n -ERROR: Host name required!\n -# -# 11 ... 15 -# -ERROR: Failed to shut down socket!\n -ERROR: Failed to send data!\n -ERROR: Failed to open connection to accounting system!\n -ERROR: Failed to construct request (would be too long)!\n -ERROR: Incomplete information to construct request!\n -# -# 16 ... 20 -# -ERROR: Pagecounter not numeric!\n -ERROR: Too few arguments for request!\n -ERROR: Unknown command keyword!\n -ERROR: Missing arguments!\n -ERROR: Interrupted by signal!\n -# -# 21 ... 22 -# -ERROR: Failed to install signal handlers!\n -ERROR: Failed to restore signal handlers!\n -# -# 23 -# -ERROR: Failed to initialize socket subsystem!\n -$!end -}; - - - -/** Default socket name. -*/ -static const char def_sock_name[] = { - DK4_INST_DIR_RUNSTATE "/printqd/printqd.sock" -}; - - - -/** Protocol keywords at start of accounting line. -*/ -static const char * const command_names[] = { -$!string-table -# -# 0 ... 5 LPRng -# -jobstart -jobend -start -end -filestart -fileend -# -# 6 ... 11 printqd -# -info -acct-check -acct-start -acct-end -acct-charge -control -$!end -}; - - -/** Responses from printqd -*/ -static const char * const responses[] = { -$!string-table -ACCEPT -HOLD -REMOVE -$!end -}; - -/** Data exchange buffer. -*/ -static char inbuf[4096]; - - -/** Copy for inspection. -*/ -static char cpbuf[sizeof(inbuf)]; - - -/** Host name for network connection. -*/ -static char *host_name = NULL; - - -/** Socket file name for local connection. -*/ -static char *sock_name = NULL; - - -/** Number of options. -*/ -static size_t szoptions = sizeof(options)/sizeof(dk4_option_t); - - -/** Normal exit value (when run as pipe). -*/ -static int exval = LPRNG_EXIT_SUCCESS; - - - -/** Help (1), version (2), license (4). -*/ -static int hvl = 0; - - - -/** Exit value for interactive mode. -*/ -static int iexval = EXIT_FAILURE; - - -/** Flag: Interactive mode (-i option). -*/ -static int intera = 0; - - -/** Flag: EOF was found. -*/ -static int eof_found = 0; - - -/** Flag: Response already found and processed. -*/ -static int found_response = 0; - - -#ifdef SIGPIPE -/** Indicator: SIGPIPE signal received. -*/ -static -DK4_VOLATILE -dk4_sig_atomic_t sig_had_pipe = 0; -#endif - - -/** Indicator: SIGINT signal received. -*/ -static -DK4_VOLATILE -dk4_sig_atomic_t sig_had_int = 0; - - -/** Indicator: SIGTERM signal received. -*/ -static -DK4_VOLATILE -dk4_sig_atomic_t sig_had_term = 0; - - - -/** Port number for network connection. -*/ -static unsigned short portno = 0U; - - -/** Pass pointer through. - Use of this function is recommended by CERT C coding standard - to avoid optimizing out. - @param ptr Pointer to pass through. - @return The ptr argument. -*/ -static -DK4_VOLATILE -dk4_sig_atomic_t * -sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr) -{ - return ptr; -} - - -#ifdef SIGPIPE -/** Handler for SIGPIPE signal. - @param signo Signal number (always SIGPIPE, ignored). -*/ -static -void -sig_handler_pipe(int DK4_ARG_UNUSED(signo) ) -{ - DK4_UNUSED_ARG(signo) - *sig_pass_pointer(&sig_had_pipe) = 1; -} -#endif - - -/** Handler for SIGINT signal. - @param signo Signal number (always SIGINT, ignored). -*/ -static -void -sig_handler_int(int DK4_ARG_UNUSED(signo) ) -{ - DK4_UNUSED_ARG(signo) - *sig_pass_pointer(&sig_had_int) = 1; -} - - -/** Handler for SIGTERM signal. - @param signo Signal number (always SIGTERM, ignored). -*/ -static -void -sig_handler_term(int DK4_ARG_UNUSED(signo) ) -{ - DK4_UNUSED_ARG(signo) - *sig_pass_pointer(&sig_had_term) = 1; -} - - -/** Read value from volatile atomic type. - This function is necessary as some compilers mis-optimize - direct access to volatile variables (at least if you believe - one of the coding standards). - @param ap Pointer to volatile atomic variable. - @return Contents of the variable. -*/ -static -dk4_sig_atomic_t -sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap) -{ - return (*ap); -} - - -/** Check whether we can continue or must abort due to signal. - @param dopipe Flag: Check for SIGPIPE too. - @return 1 if we can continue, 0 otherwise. -*/ -static -int -can_continue(void) -{ - int back = 1; - if (0 != sig_read_atomic(&sig_had_term)) { back = 0; } - if (0 != sig_read_atomic(&sig_had_int)) { back = 0; } - return back; -} - - - -/** Log one-component message to stderr. - @param kwind Index of text in printqdc_kw array. -*/ -static -void -log_1(size_t kwind) -{ - if (0 != intera) { - fputs(pqdc_kw[7], stderr); - fputs(pqdc_kw[kwind], stderr); - fflush(stderr); - } -} - - -/** Eat up input to avoid broken pipe in feeder. -*/ -static -void -eatup_input(void) -{ - size_t rdb; - int cc = 1; - do { - if (0 != can_continue()) { - rdb = fread(inbuf, 1, sizeof(inbuf), stdin); - if (0 == rdb) { - cc = 0; - } - } else { - cc = -1; - } - } while(1 == cc); -} - - - -/** Process command line arguments. - @param argc Number of command line arguments. - @param argv Command line arguments array. - @return 1 on success, 0 on error. -*/ -static -int -cmd_line_args(int argc, char *argv[]) -{ - dkChar *filenames[32]; - size_t szfilenames = DK4_SIZEOF(filenames,DK4_PDKCHAR); - int back; - back = dk4opt_process_argv( - options, szoptions, argc, argv, filenames, &szfilenames, - 1, 0, NULL - ); - if (1 == back) { - if (0 != options[4].found) { - hvl |= 1; - } - if (0 != options[5].found) { - hvl |= 2; - } - if (0 != options[6].found) { - hvl |= 4; - } - if (0 != options[0].found) { - intera = 1; - } - if (0 != options[1].found) { - sock_name = options[1].val.t; - } - if (0 != options[2].found) { - host_name = options[2].val.t; - } - if (0 != options[3].found) { - if ((dk4_um_t)0x0000FFFFUL >= options[3].val.u) { - portno = (unsigned short)(options[3].val.u); - } else { - back = 0; - /* ERROR: Port number to large! */ - log_1(8); - } - } - if ((NULL != host_name) && (0 == portno)) { - back = 0; - /* ERROR: Port number required */ - log_1(9); - } - if ((NULL == host_name) && (0 != portno)) { - back = 0; - /* ERROR: Host name required */ - log_1(10); - } - } else { - if (0 != options[0].found) { - (void)dk4opt_process_argv( - options, szoptions, argc, argv, filenames, &szfilenames, - 1, 1, NULL - ); - } - } - return back; -} - - - -/** Data exchange with accounting system. - @param pres Flag: Process response, 0=no, 1=acct-check, 2=info. -*/ -static -void -process_data(int pres) -{ - const char *ep; /* End pointer for text to number conversions */ - char *ptr; /* Traverse data line */ - dk4_um_t um; /* Number obtained from text */ - size_t sl; /* Input buffer string length */ - size_t wrb; /* Bytes we still have to write */ - dk4_socket_t sock; /* Connection to accounting/quota daemon */ - int res; /* Operation result */ - int cc; /* Flag: Can continue */ - $? "+ process_data %d", pres - wrb = sl = strlen(inbuf); - /* LOG/SHOW: Request */ - if (0 != intera) { $? ". log at start" - fputs(pqdc_kw[4], stdout); - if (0 < sl) { - fputs(inbuf, stdout); - if (0 < sl) { - if ('\n' != inbuf[sl - 1]) { - fputc('\n', stdout); - } - } else { - fputc('\n', stdout); - } - } - fflush(stdout); - } - if ((0 < sl) && (0 != can_continue())) { $? ". rq size ok" - if ((NULL != host_name) && (0 < portno)) { $? ". network" - sock = dk4socket_c8_tcp_client_host_port( - host_name, portno, 0, 0L, 0L, NULL - ); - } else { $? ". local" - sock = dk4socket_c8_unix_client( - ((NULL != sock_name) ? sock_name : def_sock_name), NULL - ); - } - if (INVALID_SOCKET != sock) { $? ". sock" - if (0 != can_continue()) { $? ". can continue" - res = dk4socket_send(sock, inbuf, &wrb, 0, 0L, 0L, NULL); - if ((DK4_SOCKET_RESULT_SUCCESS == res) && (wrb == sl)) { $? ". send" - if (0 != can_continue()) { $? ". can continue" - res = dk4socket_shutdown(sock, DK4_SOCKET_SHUT_WRITE, NULL); - if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". shutdown" - cc = 1; - do { - if (0 != can_continue()) { $? ". can continue" - wrb = sizeof(inbuf); - res = dk4socket_recv(sock, inbuf, &wrb, 0, 0L, 0L, NULL); - if ((DK4_SOCKET_RESULT_SUCCESS==res)&&(0 != can_continue())) { - if (0 < wrb) { $? ". data" - if (0 != pres) { $? ". process response" - if (sizeof(inbuf) > wrb) { - inbuf[wrb] = '\0'; - } else { - iexval = EXIT_FAILURE; - inbuf[sizeof(inbuf)-1] = '\0'; - } - dk4str8_normalize(inbuf, NULL); - /* LOG/SHOW: Response */ - if (0 != intera) { - fputs(pqdc_kw[5], stdout); - fputs(inbuf, stdout); - fputs(pqdc_kw[6], stdout); - fflush(stdout); - } - switch (pres) { - case 1: { - if (0 == found_response) { - switch (dk4str8_array_index(responses,inbuf,0)) { - case 1: { - exval = LPRNG_EXIT_HOLD; - } break; - case 2: { - exval = LPRNG_EXIT_REMOVE; - } break; - } - } - found_response = 1; - } break; - case 2: { - if (0 == found_response) { - um = (dk4_um_t)0UL; - ep = NULL; - ptr = dk4str8_start(inbuf, NULL); - if (NULL != ptr) { - ptr = dk4str8_next(ptr, NULL); - if (NULL != ptr) { - ptr = dk4str8_next(ptr, NULL); - if (NULL != ptr) { - ptr = dk4str8_next(ptr, NULL); - if (NULL != ptr) { - res = dk4ma_input_c8_dec_dk4_um_t( - &um, ptr, &ep, 1, NULL - ); - if (0 == res) { - um = (dk4_um_t)0UL; - } - } - } - } - } - if ((dk4_um_t)0UL == um) { - exval = LPRNG_EXIT_REMOVE; - } - } - found_response = 1; - } break; - } - } else { $? ". ignore response" - } - } else { $? ". 0 bytes response" - cc = 0; - } - } else { $? "! recv" - iexval = EXIT_FAILURE; - cc = -1; - } - } else { $? "! signal" - cc = -1; - } - } while (1 == cc); - } else { $? "! shutdown" - iexval = EXIT_FAILURE; - /* ERROR: Failed to shut down socket */ - log_1(11); - } - } else { $? "! signal" - } - } else { $? "! send" - iexval = EXIT_FAILURE; - /* ERROR: Sending data failed */ - log_1(12); - } - } else { $? "! signal" - } - dk4socket_close(sock, NULL); - } else { $? "! sock" - iexval = EXIT_FAILURE; - /* ERROR: Failed to open socket */ - log_1(13); - } - } else { $? "! rq size 0" - } - $? "- process_data" -} - - - -/** Find final quote for current word. - @param str String to find quote in. - @param quote Quote character. - @return Pointer to found quote on success, NULL on error. -*/ -static -char * -lprng_final_quote(char *str, char quote) -{ - char *back = NULL; - $? "+ lprng_final_quote %c %s", quote, TR_8STR(str) - while (('\0' != *str) && (NULL == back)) { - if (quote == *str) { - *str = '\0'; - back = str; - back++; - back = dk4str8_start(back, NULL); - } else { - if ('\\' == *str) { - if ('\0' != str[1]) { - dk4str8_cpy_to_left(str, &(str[1])); - str++; - } else { - *str = '\0'; - } - } else { - str++; - } - } - } - $? "- lprng_final_quote \"%s\"", TR_8STR(back) - return back; -} - - -/** Find start of next text word in LPRng accounting line. - @param str Current word (remaining text) in accounting line. - @return Pointer to next word if found, NULL on error. -*/ -static -char * -lprng_next_word(char *str) -{ - char *back = NULL; - $? "+ lprng_next_word \"%s\"", TR_8STR(str) - switch (*str) { - case '\'' : { - back = lprng_final_quote(&(str[1]), '\''); - } break; - case '"' : { - back = lprng_final_quote(&(str[1]), '"'); - } break; - default : { - back = dk4str8_next(str, NULL); - } break; - } $? "- lprng_next_word \"%s\"", TR_8STR(back) - return back; -} - - - -/** Fill data structure from LPRng accounting line. - @param liptr Structure to fill. - @param textline The text line to use. - @return 1 on success, 0 on error. -*/ -static -int -lprng_info_from_line(lprng_info_t *liptr, char *textline) -{ - char *next; - int back = 1; - $? "+ lprng_info_from_line \"%s\"", TR_8STR(textline) - DK4_MEMRES(liptr, sizeof(lprng_info_t)); - liptr->username = NULL; liptr->queuename = NULL; - liptr->jobtitle = NULL; liptr->pagecount = NULL; - while (NULL != textline) { - next = lprng_next_word(textline); - if (('\'' == *textline) || ('"' == *textline)) { - textline++; - } - if ('-' == *textline) { - textline++; - switch (*textline) { - case 'n': { - liptr->username = ++textline; - } break; - case 'P': { - liptr->queuename = ++textline; - } break; - case 'J': { - liptr->jobtitle = ++textline; - } break; - case 'p': { - liptr->pagecount = ++textline; - } break; - } - } else { $? "! not a minus" -#if 0 - /* 2016-02-15 Simply ignore non-option text. - */ - back = 0; - /* ERROR: No minus sign */ -#endif - } - textline = next; - } - $? "- lprng_info_from_line %d", back - return back; -} - - - -/** Process one line received from LPRng. - @param cmd Index in command names array. - @param args Further arguments in line. -*/ -static -void -lprng_line(int cmd, char *args) -{ - lprng_info_t li; /* All relevant components of line */ - const char *ep = NULL; /* End pointer for numeric conversion */ - const char *jt; /* Job title */ - dk4_um_t um; /* Text to number conversion result */ - int res; /* Operation result */ - int ok = 0; /* Flag: Can process line */ - $? "+ lprng_line %d \"%s\"", cmd, TR_8STR(args) - if (0 != lprng_info_from_line(&li, args)) { - switch (cmd) { - case 0: { - if ((NULL != li.username) && (NULL != li.queuename)) { - if (0 != dk4str8_cpy_s(inbuf,sizeof(inbuf),command_names[7], NULL)) { - if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),pqdc_kw[1], NULL)) { - if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),li.queuename, NULL)) { - if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),pqdc_kw[1], NULL)) { - if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),li.username, NULL)) { - if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),pqdc_kw[0], NULL)) { - ok = 1; $? ". new request constructed" - } - } - } - } - } - } - if (0 != ok) { - process_data(1); - } else { $? "! failed to construct" - iexval = EXIT_FAILURE; - /* ERROR: Failed to construct request */ - log_1(14); - } - } else { $? "! incomplete" - iexval = EXIT_FAILURE; - /* ERROR: Incomplete information */ - log_1(15); - } - } break; - default: { - if ((NULL != li.username) && (NULL != li.queuename)) { - if (NULL != li.pagecount) { - res = dk4ma_input_c8_dec_dk4_um_t(&um, li.pagecount, &ep, 1, NULL); - if (0 != res) { - cmd += 4; - if(0 !=dk4str8_cpy_s(inbuf,sizeof(inbuf),command_names[cmd],NULL)) - { - if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),pqdc_kw[1], NULL)) { - if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),li.queuename, NULL)) { - if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),pqdc_kw[1], NULL)) { - if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),li.username, NULL)) { - if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),pqdc_kw[1], NULL)) { - if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),li.pagecount, NULL)) { - if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),pqdc_kw[1], NULL)) { - if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),pqdc_kw[2], NULL)) { - if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),pqdc_kw[1], NULL)) { - jt = li.jobtitle; - if (NULL == jt) { jt = pqdc_kw[3]; } - if (0 != dk4str8_cat_s(inbuf, sizeof(inbuf), jt, NULL)) { - if (0 != dk4str8_cat_s(inbuf, sizeof(inbuf), pqdc_kw[0], NULL)) { - ok = 1; - } - } - } - } - } - } - } - } - } - } - } - } - if (0 != ok) { $? ". rq constructed" - process_data(0); - } else { $? "! failed to construct rq" - iexval = EXIT_FAILURE; - /* ERROR: Failed to construct request */ - log_1(14); - } - } else { $? "! pc not numeric" - iexval = EXIT_FAILURE; - /* ERROR: Pagecounter not numeric */ - log_1(16); - } - } else { $? "! incomplete rq" - iexval = EXIT_FAILURE; - /* ERROR: Incomplete information */ - log_1(15); - } - } else { $? "! incomplete rq" - iexval = EXIT_FAILURE; - /* ERROR: Incomplete information */ - log_1(15); - } - } break; - } - } else { - iexval = EXIT_FAILURE; - } - $? "- lprng_line" -} - - - -/** Process one line containing printqd style data. - @param args Arguments text. - @param minargs Minimum required number of arguments. - @param num3 Flag: Argument 3 must be unsigned number. - @param pres Flag: Process response. -*/ -static -void -printqd_line(char *args, size_t minargs, int num3, int pres) -{ - const char *ep = NULL; /* End of usable data */ - char *next; /* Start of arguments */ - dk4_um_t um = (dk4_um_t)0UL; /* Numeric conversion result */ - size_t i; /* Current argument index */ - int res; /* Operation result */ - int errnum = 0; /* Flag: Numeric error */ - $? "+ printqd_line" - dk4str8_normalize(args, NULL); - i = 0; $? ". line = \"%s\"", args - while(args) { - i++; - next = dk4str8_next(args, NULL); - if ((3 == i) && (0 != num3)) { $? ". check \"%s\"", args - res = dk4ma_input_c8_dec_dk4_um_t(&um, args, &ep, 1, NULL); - if (0 == res) { errnum = 1; } - } - args = next; - } $? ". i=%u errnum=%d", (unsigned)i, errnum - if ((i >= minargs) && (0 == errnum)) { - process_data(pres); - } else { - if (i < minargs) { - /* ERROR: Too few arguments */ - log_1(17); - } - if (0 != errnum) { - /* ERROR: Page counter not numeric */ - log_1(16); - } - iexval = EXIT_FAILURE; - } - $? "- printqd_line" -} - - - -/** Process input from stdin. -*/ -static -void -process_input(void) -{ - char *args; /* Start of arguments after command */ - int cc; /* Flag: Can continue */ - int res; /* Operation result for numeric conversions */ - $? "+ process_input" - cc = 1; - do { - if (0 != can_continue()) { $? ". can continue" - if (fgets(inbuf, sizeof(inbuf), stdin)) { $? ". data" - dk4str8_cpy_s(cpbuf, sizeof(cpbuf), inbuf, NULL); - dk4str8_delnl(cpbuf); - if (NULL != dk4str8_start(cpbuf, NULL)) { - if (0 != intera) { $? ". interactive" - fputs(cpbuf, stdout); - fputc('\n', stdout); - fflush(stdout); - } - args = dk4str8_next(cpbuf, NULL); - if (NULL != args) { $? ". arguments" - res = dk4str8_array_index(command_names, cpbuf, 0); - if (0 != can_continue()) { - switch (res) { - case 0: { - lprng_line(res, args); - } break; - case 1: { - } break; - case 2: { - } break; - case 3: { - } break; - case 4: { - lprng_line(res, args); - } break; - case 5: { - lprng_line(res, args); - } break; - case 6: { - printqd_line(args, 2, 0, 2); - } break; - case 7: { - printqd_line(args, 2, 0, 1); - } break; - case 8: { - printqd_line(args, 4, 1, 0); - } break; - case 9: { - printqd_line(args, 4, 1, 0); - } break; - case 10: { - printqd_line(args, 3, 1, 0); - } break; - case 11: { - printqd_line(args, 1, 0, 0); - } break; - default: { - iexval = EXIT_FAILURE; - /* ERROR: Unknown keyword */ - log_1(18); - } break; - } - } else { - cc = -1; - } - } else { $? "! no arguments" - /* ERROR: No arguments */ - log_1(19); - iexval = EXIT_FAILURE; - } - } else { $? ". skip empty line" - } - } else { $? ". end of data" - eof_found = 1; - cc = 0; - } - } else { $? "! aborted" - cc = -1; - } - } while (1 == cc); - $? "- process_input" -} - - - -/** Show a text paragraph on standard output. - @param txt Text to show. -*/ -static -void -show_text(const char * const *txt) -{ - if (NULL != txt) { - while (NULL != *txt) { - fputs(*(txt++), stdout); - fputc('\n', stdout); - } - fflush(stdout); - } -} - - - -/** Handle --help, --version, --license options. -*/ -static -void -run_hvl(void) -{ - if (0 != (1 & hvl)) { - show_text(help_text); - } - if (0 != (2 & hvl)) { - fputs(version_text, stdout); - fputc('\n', stdout); - fflush(stdout); - } - if (0 != (4 & hvl)) { - show_text(license_text); - } -} - - - -/** Main program. - @param argc Number of command line arguments. - @param argv Command line arguments array. - @return Exit status code. -*/ -int -main(int argc, char *argv[]) -{ -#ifdef DK4_HAVE_SIGACTION -#ifdef SIGPIPE - struct sigaction opipe; - struct sigaction npipe; -#endif - struct sigaction oint; - struct sigaction nint; - struct sigaction oterm; - struct sigaction nterm; -#else -#ifdef SIGPIPE - dk4_sig_handler_t *opipe = NULL; -#endif - dk4_sig_handler_t *oterm = NULL; - dk4_sig_handler_t *oint = NULL; -#endif -#ifdef DK4_HAVE_SIGACTION -#ifdef SIGPIPE - int spipe = 0; -#endif - int sint = 0; - int sterm = 0; - int s_f_i = 0; - int s_f_r = 0; -#endif - int socki = 0; - - /* Set signal handlers - */ -#if DK4_HAVE_SIGACTION -#ifdef SIGPIPE - DK4_MEMRES(&npipe, sizeof(npipe)); - npipe.sa_handler = sig_handler_pipe; - npipe.sa_flags = 0; - if (0 != sigemptyset(&npipe.sa_mask)) { - s_f_i = 1; - goto finished; - } - if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) { - s_f_i = 1; - goto finished; - } - if (0 != sigaction(SIGPIPE, &npipe, &opipe)) { - s_f_i = 1; - goto finished; - } - spipe = 1; -#endif - DK4_MEMRES(&nterm, sizeof(nterm)); - nterm.sa_handler = sig_handler_term; - nterm.sa_flags = 0; - if (0 != sigemptyset(&nterm.sa_mask)) { - s_f_i = 1; - goto finished; - } - if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) { - s_f_i = 1; - goto finished; - } - if (0 != sigaction(SIGTERM, &nterm, &oterm)) { - s_f_i = 1; - goto finished; - } - sterm = 1; - DK4_MEMRES(&nint, sizeof(nint)); - nint.sa_handler = sig_handler_int; - nint.sa_flags = 0; - if (0 != sigemptyset(&nint.sa_mask)) { - s_f_i = 1; - goto finished; - } - if (0 != sigaddset(&nint.sa_mask, SIGINT)) { - s_f_i = 1; - goto finished; - } - if (0 != sigaction(SIGINT, &nint, &oint)) { - s_f_i = 1; - goto finished; - } - sint = 1; -#else -#ifdef SIGPIPE - opipe = sigset(SIGPIPE, sig_handler_pipe); -#endif - oint = sigset(SIGINT, sig_handler_int); - oterm = sigset(SIGTERM, sig_handler_term); -#endif - - /* Start tracing - */ - $!trace-init printqdc.deb - $? "+ main" - - /* Process command line arguments - */ - if (0 == cmd_line_args(argc, argv)) { goto finished; } - - /* Help, version, license. - */ - if (0 != hvl) { - run_hvl(); - goto finished; - } - - /* Bring socket subsystem up. - */ - if (DK4_SOCKET_RESULT_SUCCESS != dk4socket_up(NULL)) { - /* ERROR: Failed to initialize socket subsystem */ - log_1(23); - goto finished; - } - socki = 1; - - iexval = EXIT_SUCCESS; - $? ". comman line arguments processed, going to process input" - process_input(); - - finished: - - /* Eat up remaining input, if any. - */ - if ((0 == hvl) && (0 == eof_found)) { eatup_input(); } - - /* Log notification about abort by signal. - */ - if (0 == can_continue()) { - /* LOG: Interrupted by signal */ - log_1(20); - iexval = EXIT_FAILURE; - } - - /* Release socket subsystem. - */ - if (0 != socki) { (void)dk4socket_down(NULL); } - - /* Restore signal handlers - */ -#if DK4_HAVE_SIGACTION - if (0 != s_f_i) { - /* ERROR: Failed to install signal handlers */ - log_1(21); - iexval = EXIT_FAILURE; - } - if (0 != sint) { - if (0 != sigaction(SIGINT, &oint, NULL)) { - s_f_r = 1; - } - } - if (0 != sterm) { - if (0 != sigaction(SIGTERM, &oterm, NULL)) { - s_f_r = 1; - } - } -#ifdef SIGPIPE - if (0 != spipe) { - if (0 != sigaction(SIGPIPE, &opipe, NULL)) { - s_f_r = 1; - } - } -#endif - if (0 != s_f_r) { - /* ERROR: Failed to restore signal handlers */ - log_1(22); - iexval = EXIT_FAILURE; - } -#else - if (NULL != oterm) { sigset(SIGTERM, oterm); } - if (NULL != oint ) { sigset(SIGINT, oint ); } -#ifdef SIGPIPE - if (NULL != opipe) { sigset(SIGPIPE, opipe); } -#endif -#endif - - /* Set exit status code depending on interactive mode - */ - if (0 != intera) { exval = iexval; } - - /* Finish tracing - */ - $? "- main %d", exval - $!trace-end - - /* Exit - */ - exit(exval); return exval; -} - -#else -/* if (DK4_CHAR_SIZE == 1) && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET)) */ - -/** Main program. - @param argc Number of command line arguments. - @param argv Command line arguments array. - @return Exit status code. -*/ -int main(int argc, char *argv[]) -{ - fputs("printqdc: ERROR: Program can not be used on this system!\n", stderr); - fflush(stderr); - exit(EXIT_FAILURE); return EXIT_FAILURE; -} - -#endif -/* if (DK4_CHAR_SIZE == 1) && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET)) */ - |