diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/lprngcl.ctr |
Initial commit
Diffstat (limited to 'support/dktools/lprngcl.ctr')
-rw-r--r-- | support/dktools/lprngcl.ctr | 1149 |
1 files changed, 1149 insertions, 0 deletions
diff --git a/support/dktools/lprngcl.ctr b/support/dktools/lprngcl.ctr new file mode 100644 index 0000000000..5d73928ccc --- /dev/null +++ b/support/dktools/lprngcl.ctr @@ -0,0 +1,1149 @@ +%% options + +copyright owner = Dirk Krause +copyright year = 2016-xxxx +license = bsd + + + +%% module + +/** @file lprngcl.c Lprng Cleanup. +*/ + +#include "dk4conf.h" + +#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_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 + +#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_SIGNAL_H +#ifndef SIGNAL_H_INCLUDED +#include <signal.h> +#define SIGNAL_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_MATH_H +#ifndef MATH_H_INCLUDED +#include <math.h> +#define MATH_H_INCLUDED 1 +#endif +#endif + +#include "dk4types.h" +#include "dk4const.h" +#include "dk4vers.h" +#include "dk4str8.h" +#include "dk4strd.h" +#include "dk4app.h" +#include "dk4aopt.h" +#include "dk4enc.h" +#include "dk4fput.h" +#include "dk4mem.h" +#include "dk4mema.h" +#include "dk4fput.h" +#include "dk4tspdk.h" +#include "dk4sock.h" +#include "dk4socka.h" +#include "dk4user.h" +#include "dk4rec.h" + + + +$!trace-include + + +/** Buffer for request and response data. +*/ +static char buf[4096]; + + +/** Current queue complete name. +*/ +static dkChar curqueue[1024]; + + +/** Current user name. +*/ +static dkChar username[1024]; + + +/** Queue name in 8 bit characters. +*/ +static char queue8[1024]; + + +/** User name in 8 bit characters. +*/ +static char user8[1024]; + + +/** Default help text, used if help text file is not found. +*/ +static const dkChar * const lprngcl_help_text[] = { +$!text macro=dkT,preprocessor + +Clean up LPRng queues + +lprngcl [-t seconds] [-a] <queue>... +lprngcl [--help] [--version] [--license] [--manual] + +Specify queues in name@host notation. + +-t seconds --timeout=seconds Timeout for network operations. +-a --ascii Server uses ASCII, not UTF-8. + + --help Show this short help text. + --version Show version information. + --license Show license information. + --manual *** SHOW FULL MANUAL *** + +$!end +}; + + + +/** License conditions. +*/ +static const dkChar * const lprngcl_license_text[] = { +$!text macro=dkT,preprocessor +This software uses code from the following projects, either directly or as +a library: + +dktools Dirk Krause's tools and libraries. + See http://dktools.sourceforge.net/ for more information. +#if DK4_HAVE_ZLIB_H + +zlib Data compression library. + See http://www.zlib.net/ for more information. +#endif +#if DK4_HAVE_BZLIB_H + +bzip2 Data compression program and library. + See http://www.bzip.org/ for more information. +#endif + +All the licenses below apply to the program. +Licenses for used libraries are shown as found on my Scientific Linux 6.x +computer in the /usr/share/doc directory on 2015-04-01. Check the project +homepages of the used libraries for additional information and/or updated +license terms. + + +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: + +* 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 copyright + 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 Dirk Krause 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. +#if DK4_HAVE_ZLIB_H + + +Zlib license +============ +(C) 1995-2004 Jean-loup Gailly and Mark Adler + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +Jean-loup Gailly Mark Adler +jloup@gzip.org madler@alumni.caltech.edu +#endif +#if DK4_HAVE_BZLIB_H + + +Bzip2 and libbzip2 library license +================================== +This program, "bzip2", the associated library "libbzip2", and all +documentation, are copyright (C) 1996-2007 Julian R Seward. 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. The origin of this software must not be misrepresented; you must + not claim that you wrote the original software. If you use this + software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. + +3. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. + +4. The name of the author may not be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + +Julian Seward, jseward@bzip.org +bzip2/libbzip2 version 1.0.5 of 10 December 2007 +#endif + +$!end +}; + + + +/** Options used by the program. +*/ +static const dk4_option_specification_t lprngcl_options[] = { + + /* Timeout for connection attempts and other network operations. + */ + { dkT('t'), dkT("timeout"), DK4_OPT_ARG_DOUBLE }, + + /* Remote host uses ASCII encoding, not UTF-8. + */ + { dkT('a'), dkT("ascii"), DK4_OPT_ARG_NONE }, + + /* Verbose output. + */ + { dkT('v'), dkT("verbose"), DK4_OPT_ARG_NONE } + +}; + + + +/** Constant texts used by the program, not localized. +*/ +static const dkChar * const lprngcl_kwnl[] = { +$!string-table macro=dkT +# +# 0 1 2 Group, help text file, string table file +# +dktools +lprngcl.txt +lprngcl.str +$!end +}; + + + +/** Defaults for keywords, replaced by localized version if found. +*/ +static const dkChar * const lprngcl_kw_def[] = { +$!string-table macro=dkT +# +# 0 ERROR: Failed to set up signal handlers! +# +Failed to set up signal handlers! +# +# 1 ERROR: Failed to restore signal handlers! +# +Failed to restore signal handlers! +# +# 2 ERROR: Failed to set up text stream processor! +# +Failed to set up text stream processor! +# +# 3 ERROR: Failed to construct request! +# +Failed to construct request!\nQueue or user name too long! +# +# 4 ERROR: Failed to convert queue name to 8 bit text! +# +Failed to convert queue name to 8 bit text! +# +# 5 ERROR: No host name specified in queue! +# +No host name specified in queue! +# +# 6 ERROR: Queue name too long! +# +Queue name too long! +# +# 7 ERROR: Failed to obtain command line argument (bug)! +# +Failed to obtain command line argument (bug)! +# +# 8 ERROR: Failed to convert user name to 8 bit text! +# +Failed to convert user name to 8 bit text! +# +# 9 ERROR: Failed to find current user name! +# +Failed to find current user name! +# +# 10 ERROR: Queue name(s) required! +# +Queue name(s) required! +# +# 11 ERROR: Failed to write to standard output! +# +Failed to write to standard output! +# +# 12 13 +# +Request:\n" +". +$!end +}; + + + +static const char * const lprngcl_c8_kw[] = { +$!string-table +# +# 0 Space +# + +# +# 1 Newline +# +\n +# +# 2 all print jobs +# +all +$!end +}; + + +/** Application object. +*/ +static dk4_app_t *app = NULL; + + +/** Message texts, changed to localized texts if possible. +*/ +static const dkChar * const *msg = lprngcl_kw_def; + + +/** Size of lprngcl_options array. +*/ +static const size_t lprngcl_sz_options = +sizeof(lprngcl_options)/sizeof(dk4_option_specification_t); + + +/** Size of lprngcl_kw_def array. +*/ +static size_t sz_msg = (sizeof(lprngcl_kw_def)/sizeof(DK4_PDKCHAR) - 1); + + +/** Size of buffer for current queue. +*/ +static const size_t szcurqueue = DK4_SIZEOF(curqueue,dkChar); + + +/** Size of buffer. +*/ +static size_t szbuf = sizeof(buf); + + +/** Timeout (seconds) for network operations. +*/ +static long to_secs = 0L; + + +/** Timeout (microseconds) for network operations. +*/ +static long to_usecs = 0L; + + +/** Exit status code. +*/ +static int exval = EXIT_FAILURE; + + +/** Flag: Errors while writing to stdout. +*/ +static int wrerror = 0; + + +/** Flag: Remote host uses UTF-8 encoding. +*/ +static int isUtf8 = 1; + + +/** Flag: Produce verbose output. +*/ +static int isVerbose = 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; + + + +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 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 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 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 if a signal was received. + @param check_pipe Flag: Check for occured SIGPIPE signal too. + @return 1 if the program can continue, 0 if a signal was received. +*/ +static +int +sig_can_continue(int check_pipe) +{ + int back = 1; +#ifdef SIGPIPE + if (0 != check_pipe) { + if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; } + } +#endif + if (0 != sig_read_atomic(&sig_had_int )) { back = 0; } + if (0 != sig_read_atomic(&sig_had_term)) { back = 0; } + return back; +} + + + +/** Use timeout value specified as double. + @param to Timeout for network operations. +*/ +static +void +use_timeout(double to) +{ + $? "+ use_timeout %lg", to + if (0.0 > to) { to = -1.0 * to; } + to_secs = (long)floor(to); + to = to - floor(to); + to = to * 1000000.0; + to_usecs = (long)floor(to); + $? "- use_timeout secs=%ld usecs=%ld", to_secs, to_usecs +} + + + +/** Process command line options. + @return 1 on success, 0 on error. +*/ +static +int +process_options(void) +{ + double to = 0.0; + int back = 1; + $? "+ process_options" + if (0 != dk4app_opt_is_set_short(app, dkT('t'), NULL)) { + if (0 != dk4app_opt_get_double_short(&to, app, dkT('t'), NULL)) { + $? ". timeout" + use_timeout(to); + } + } else { + } + if (0 != dk4app_opt_is_set_short(app, dkT('a'), NULL)) { + $? ". ASCII" + isUtf8 = 0; + } + if (0 != dk4app_opt_is_set_short(app, dkT('v'), NULL)) { + $? ". verbose" + isVerbose = 1; + } + $? "- process_options %d", back + return back; +} + + + +/** Character handler for text stream processing. +*/ +static +int +lprngcl_char_handler( + void *obj, + dkChar c, + dk4_text_stream_position_t *pos, + dk4_er_t *erp +) +{ + int back = DK4_TSP_RES_OK; + if (0 == dk4fputc(c, stdout, NULL)) { + exval = EXIT_FAILURE; + wrerror = 1; + } + return back; +} + + + +/** Process one request to delete print jobs. + @param hptr Host name pointer. + @param fullqueue Full queue name. +*/ +static +void +process_one_delete_request(const dkChar *hptr, const dkChar *fullqueue) +{ + dk4_tspdk_t tspdk; + size_t rql; + size_t wrb; + int cc; + int tspok; + int res; + dk4_socket_t sock; + $? "+ process_one_delete_request" + rql = dk4str8_len(buf); + sock = dk4socket_tcp_client_for_host_port_app( + hptr, 515, 0, to_secs, to_usecs, app + ); + if (INVALID_SOCKET != sock) { $? ". socket" + wrb = rql; + if (0 != isVerbose) { $? ". verbose" + if (0 == dk4fputs(fullqueue, stdout, NULL)) { + wrerror = 1; $? "! fputs" + exval = EXIT_FAILURE; + } + if (0 == dk4fputc(dkT('\n'), stdout, NULL)) { + wrerror = 1; $? "! fputc" + exval = EXIT_FAILURE; + } + } $? ". attempt send" + res = dk4socket_send_attempt_app( + sock, buf, &wrb, 0, to_secs, to_usecs, app, 1 + ); $? ". attempt send done" + switch (res) { + case DK4_SOCKET_RESULT_SUCCESS : + case DK4_SOCKET_RESULT_IN_PROGRESS : + { $? ". send ok" + if ((0 != isVerbose) && (DK4_SOCKET_RESULT_SUCCESS == res)) { + $? ". verbose" + res = dk4socket_shutdown_app(sock, DK4_SOCKET_SHUT_WRITE, app); + if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". shutdown" + tspok = dk4tspdk_setup_char( + &tspdk, NULL, lprngcl_char_handler, + dk4app_get_stdout_encoding(app), + ( + (0 != isUtf8) + ? (DK4_FILE_ENCODING_UTF8) + : (DK4_FILE_ENCODING_ASCII) + ), + NULL + ); + if (0 == tspok) { $? "! text processing" + /* ERROR: Failed to set up text stream processor */ + dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 2); + exval = EXIT_FAILURE; + } + cc = 1; + do { + if (0 != sig_can_continue(0)) { $? ". loop pass" + wrb = sizeof(buf); + res = dk4socket_recv_app( + sock, buf, &wrb, 0, to_secs, to_usecs, app + ); + if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". recv" + if (0 == wrb) { $? ". 0 bytes" + cc = 0; + } else { $? ". data found" + if (0 != tspok) { $? ". text processing" + res = dk4tspdk_add_bytes(&tspdk,(unsigned char *)buf,wrb); + if (DK4_TSP_RES_OK != res) { $? "! text processing" + exval = EXIT_FAILURE; + tspok = 0; + } + } + } + } else { $? "! recv" + cc = 0; + } + } else { $? ". signal" + cc = -1; + } + } while(1 == cc); + if ((0 == cc) && (0 != tspok)) { $? ". regular loop end" + res = dk4tspdk_finish(&tspdk); + if (DK4_TSP_RES_OK != res) { $? "! text processing" + exval = EXIT_FAILURE; + } + } + } else { $? "! shutdown" + exval = EXIT_FAILURE; + } + } else { $? ". not verbose" + res = dk4socket_shutdown_app(sock, DK4_SOCKET_SHUT_WRITE, app); + if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". shutdown" + cc = 1; + do { + if (0 != sig_can_continue(0)) { $? ". loop pass" + wrb = sizeof(buf); + res = dk4socket_recv_app( + sock, buf, &wrb, 0, to_secs, to_usecs, app + ); + if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". recv" + if (0 == wrb) { $? ". 0 bytes" + cc = 0; + } + } else { $? "! recv" + cc = 0; + } + } else { $? "! signal" + cc = -1; + } + } while(1 == cc); + } else { $? "! shutdown" + exval = EXIT_FAILURE; + } + } + } break; +#if TRACE_DEBUG + default : { $? "! send failed" + } break; +#endif + } + res = dk4socket_close_app(sock, app); + if (DK4_SOCKET_RESULT_SUCCESS != res) { $? "! close" + exval = EXIT_FAILURE; + } + } else { $? "! socket" + exval = EXIT_FAILURE; + } + $? "- process_one_delete_request" +} + + + +/** Send requests to delete the users print jobs. + @param xargc Number of queue names. +*/ +static +void +send_delete_requests(int xargc) +{ + const dkChar *xargv = NULL; /* Current cmd line argument */ + dkChar *hptr = NULL; /* Start of host name */ + int res = 0; /* Text conversion result */ + int i = 0; /* Current cmd line arg index */ + $? "+ send_delete_requests %d", xargc + if (0 != dk4user_get_logname(username, DK4_SIZEOF(username,dkChar),0, NULL)) { + $? ". logname = \"%!ds\"", username + if (0 != isUtf8) { $? ". UTF-8" + res = dk4recode_dk_to_any( + user8, sizeof(user8), DK4_ENCODING_UTF8, username, + dk4app_get_encoding(app), NULL + ); + } else { $? ". ASCII" + res = dk4recode_dk_to_any( + user8, sizeof(user8), DK4_ENCODING_ASCII, username, + dk4app_get_encoding(app), NULL + ); + } + if (0 != res) { $? ". conversion to 8 bit text" + exval = EXIT_SUCCESS; + for (i = 0; ((i < xargc) && (sig_can_continue(0))); i++) { + $? ". pass %d", i + xargv = dk4app_get_argv(app, i); + if (NULL != xargv) { $? ". argv = \"%!ds\"", xargv + if (0 != dk4str_cpy_s(curqueue, szcurqueue, xargv, NULL)) { + $? ". copied" + hptr = dk4str_chr(curqueue, dkT('@')); + if (NULL != hptr) { + *(hptr++) = dkT('\0'); + hptr = dk4str_start(hptr, NULL); + if (NULL != hptr) { $? ". host = \"%!ds\"", hptr + if (0 != isUtf8) { $? ". UTF-8" + res = dk4recode_dk_to_any( + queue8, sizeof(queue8), DK4_ENCODING_UTF8, curqueue, + dk4app_get_encoding(app), NULL + ); + } else { $? ". ASCII" + res = dk4recode_dk_to_any( + queue8, sizeof(queue8), DK4_ENCODING_ASCII, curqueue, + dk4app_get_encoding(app), NULL + ); + } + if (0 != res) { $? ". conversion to 8 bit text" + res = 1; + if (0 == dk4str8_cpy_s(buf, szbuf, lprngcl_c8_kw[0], NULL)) { + res = 0; $? "! request construction" + buf[0] = '\0'; + } + if (0 == dk4str8_cat_s(buf, szbuf, queue8, NULL)) { + res = 0; $? "! request construction" + } + if (0 == dk4str8_cat_s(buf, szbuf, lprngcl_c8_kw[0], NULL)) { + res = 0; $? "! request construction" + } + if (0 == dk4str8_cat_s(buf, szbuf, user8, NULL)) { + res = 0; $? "! request construction" + } + if (0 == dk4str8_cat_s(buf, szbuf, lprngcl_c8_kw[0], NULL)) { + res = 0; $? "! request construction" + } + if (0 == dk4str8_cat_s(buf, szbuf, user8, NULL)) { + res = 0; $? "! request construction" + } + if (0 != res) { $? ". request=\"%!8s\"", buf + /* LOG Print removal request */ +#if DK4_CHAR_SIZE == 1 + dk4app_log_3(app, msg, sz_msg, DK4_LL_INFO, 12, 13, buf); +#endif + } + if (0 == dk4str8_cat_s(buf, szbuf, lprngcl_c8_kw[1], NULL)) { + res = 0; $? "! request construction" + } + buf[0] = 0x05; + if (0 != res) { $? ". process rq" + process_one_delete_request(hptr, xargv); + } else { $? "! failed to construct rq" + /* ERROR: Failed to construct request */ + dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 3); + } + } else { $? "! conversion to 8 bit text" + exval = EXIT_FAILURE; + /* ERROR: Failed to convert queue name to 8 bit text */ + dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 4); + } + } else { $? "! no host name in queue" + exval = EXIT_FAILURE; + /* ERROR: No host name in queue */ + dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 5); + } + } else { $? "! no host name in queue" + exval = EXIT_FAILURE; + /* ERROR: No host name in queue */ + dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 5); + } + } else { $? "! buffer too small" + exval = EXIT_FAILURE; + /* ERROR: Queue name too long */ + dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 6); + } + } else { $? "! bug, no argv" + exval = EXIT_FAILURE; + /* ERROR: Failed to obtain command line argument */ + dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 7); + } + } + } else { $? "! conversion to 8 bit text" + /* ERROR: Failed to recode user name to 8 bit characters */ + dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 8); + } + } else { $? "! user name" + /* ERROR: Failed to find current user name */ + dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 9); + } + $? "- send_delete_requests" +} + + + +/** The real work. +*/ +static +void +run_the_functions(void) +{ + int xargc = 0; + $? "+ run_the_functions" + if (0 != process_options()) { $? ". option processing ok" + xargc = dk4app_get_argc(app); + if (0 < xargc) { $? ". cmd line arguments" + if (0 != dk4socket_up_app(app)) { $? ". socket subsys up" + send_delete_requests(xargc); + dk4socket_down_app(app); + } else { $? "! socket subsys" + exval = EXIT_FAILURE; + } + } else { $? "! no cmd line arguments" + /* ERROR: No queues specified */ + dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 10); + } + } +#if TRACE_DEBUG + else { $? "! option processing failed" + } +#endif + $? "- run_the_functions" +} + + + +#if DK4_HAVE_SIGACTION +/** Set signal handlers and run. +*/ +static +void +run_with_signals(void) +{ +#ifdef SIGPIPE + struct sigaction opipe; +#endif + struct sigaction oint; + struct sigaction oterm; +#ifdef SIGPIPE + struct sigaction npipe; +#endif + struct sigaction nint; + struct sigaction nterm; + int success = 0; + $? "+ run_with_signals DK4_HAVE_SIGACTION" +#ifdef SIGPIPE + /* Set up signal handling for SIGPIPE. + */ + DK4_MEMRES(&npipe, sizeof(npipe)); + npipe.sa_handler = sig_handler_pipe; + npipe.sa_flags = 0; + if (0 != sigemptyset(&npipe.sa_mask)) { $? "! pipe sigemtpyset" + /* ERROR: Failed to set up masked signal set for SIGPIPE */ + dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0); + goto finished; + } + if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) { $? "! pipe sigaddset" + /* ERROR: Failed to set up masked signal set for SIGPIPE */ + dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0); + goto finished; + } + if (0 != sigaction(SIGPIPE, &npipe, &opipe)) { $? "! pipe sigaction" + /* ERROR: Failed to set up signal handler for SIGPIPE */ + dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0); + goto finished; + } +#endif + + /* Set up signal handling for SIGINT. + */ + DK4_MEMRES(&nint, sizeof(nint)); + nint.sa_handler = sig_handler_int; + nint.sa_flags = 0; + if (0 != sigemptyset(&nint.sa_mask)) { $? "! int sigemptyset" + /* ERROR: Failed to set up masked signal set for SIGINT */ + dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0); + goto restore_old_pipe; + } + if (0 != sigaddset(&nint.sa_mask, SIGINT)) { $? "! int sigaddset" + /* ERROR: Failed to set up masked signal set for SIGINT */ + dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0); + goto restore_old_pipe; + } + if (0 != sigaction(SIGINT, &nint, &oint)) { $? "! int sigaction" + /* ERROR: Failed to set up signal handler for SIGINT */ + dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0); + goto restore_old_pipe; + } + + /* Set up signal handling for SIGTERM + */ + DK4_MEMRES(&nterm, sizeof(nterm)); + nterm.sa_handler = sig_handler_term; + nterm.sa_flags = 0; + if (0 != sigemptyset(&nterm.sa_mask)) { $? "! term sigemptyset" + /* ERROR: Failed to set up masked signal set for SIGTERM */ + dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0); + goto restore_old_int; + } + if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) { $? "! term sigaddset" + /* ERROR: Failed to set up masked signal set for SIGTERM */ + dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0); + goto restore_old_int; + } + if (0 != sigaction(SIGTERM, &nterm, &oterm)) { $? "! term sigaction" + /* ERROR: Failed to set up signal handler for SIGTERM */ + dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0); + goto restore_old_int; + } + + success = 1; $? ". signals ok" + run_the_functions(); + + /* Restore signal handling for SIGTERM. + */ + if (0 != sigaction(SIGTERM, &oterm, NULL)) { $? "! term sigaction" + /* ERROR: Failed to restore old SIGTERM settings */ + dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 1); + success = 0; + } + + /* Restore signal handling for SIGINT. + */ + restore_old_int: + if (0 != sigaction(SIGINT, &oint, NULL)) { $? "! int sigaction" + /* ERROR: Failed to restore old SIGPIPE settings */ + dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 1); + success = 0; + } + +#ifdef SIGPIPE + /* Restore signal handling for SIGPIPE. + */ + restore_old_pipe: + if (0 != sigaction(SIGPIPE, &opipe, NULL)) { $? "! pipe sigaction" + /* ERROR: Failed to restore old SIGPIPE settings */ + dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 1); + success = 0; + } +#endif + + /* Set exit status code if error occured. + */ + finished: + if (0 == success) { $? "! errors occured" + exval = EXIT_FAILURE; + } + $? "- run_with_signals DK4_HAVE_SIGACTION" +} +#else +#if DK4_HAVE_SIGSET +/** Set signal handlers and run. +*/ +static +void +run_with_signals(void) +{ +#ifdef SIGPIPE + dk4_sig_handler_t *oldpipe = NULL; +#endif + dk4_sig_handler_t *oldint = NULL; + dk4_sig_handler_t *oldterm = NULL; + $? "+ run_with_signals DK4_HAVE_SIGSET" +#ifdef SIGPIPE + oldpipe = sigset(SIGPIPE, sig_handler_pipe); +#endif + oldint = sigset(SIGINT, sig_handler_int); + oldterm = sigset(SIGTERM, sig_handler_term); + run_the_functions(); + sigset(SIGTERM, oldterm); + sigset(SIGINT, oldint); +#ifdef SIGPIPE + sigset(SIGPIPE, oldpipe); +#endif + $? "- run_with_signals DK4_HAVE_SIGSET" +} +#else +#if DK4_HAVE_SIGNAL +/** Set signal handlers and run. +*/ +static +void +run_with_signals(void) +{ +#ifdef SIGPIPE + dk4_sig_handler_t *oldpipe = NULL; +#endif + dk4_sig_handler_t *oldint = NULL; + dk4_sig_handler_t *oldterm = NULL; + $? "+ run_with_signals DK4_HAVE_SIGNAL" +#ifdef SIGPIPE + oldpipe = signal(SIGPIPE, sig_handler_pipe); +#endif + oldint = signal(SIGINT, sig_handler_int); + oldterm = signal(SIGTERM, sig_handler_term); + run_the_functions(); + signal(SIGTERM, oldterm); + signal(SIGINT, oldint); +#ifdef SIGPIPE + signal(SIGPIPE, oldpipe); +#endif + $? "- run_with_signals DK4_HAVE_SIGNAL" +} +#else +/** Set signal handlers and run. +*/ +static +void +run_with_signals(void) +{ + $? "+ run_with_signals NO SIGNALS" + run_the_functions(); + $? "- run_with_signals NO SIGNALS" +} +#endif +#endif +#endif + + + +/** Main function. + @param argc Number of command line arguments. + @param argv Command line arguments array. + @return 0 on success, all other values indicate errors. +*/ +#if DK4_CHAR_SIZE > 1 +int wmain(int argc, wchar_t *argv[]) +#else +int main(int argc, char *argv[]) +#endif +{ + $!trace-init lprngcl.deb + $? "+ main" + dk4fput_initialize_stdout(); + dk4fput_initialize_stderr(); + app = dk4app_open_cmd( + argc, argv, lprngcl_options, lprngcl_sz_options, + lprngcl_kwnl[0], DKT_VERSION_DK, + lprngcl_kwnl[1], lprngcl_help_text, lprngcl_license_text + ); + if (NULL != app) { $? ". app" + sz_msg = dk4app_string_table_size(lprngcl_kw_def); + msg = dk4app_string_table(app, lprngcl_kwnl[2], lprngcl_kw_def); + if (0 != dk4app_can_run_normally(app)) { $? ". run normally" + run_with_signals(); + } else { $? ". help, version, license" + if (0 != dk4app_help_version_license(app)) { + exval = EXIT_SUCCESS; + } + } + if (0 != wrerror) { $? "! stdout write error" + /* ERROR: Failed to write to standard output */ + dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 11); + } + dk4app_close(app); + } +#if TRACE_DEBUG + else { $? "! app" + } +#endif + fflush(stdout); + fflush(stderr); + dk4fput_cleanup_stderr(); + dk4fput_cleanup_stdout(); + $? "- main %d", exval + $!trace-end + exit(exval); return exval; +} + |