From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- support/dktools/dk-hex.ctr | 1162 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1162 insertions(+) create mode 100644 support/dktools/dk-hex.ctr (limited to 'support/dktools/dk-hex.ctr') diff --git a/support/dktools/dk-hex.ctr b/support/dktools/dk-hex.ctr new file mode 100644 index 0000000000..441d3bfcc1 --- /dev/null +++ b/support/dktools/dk-hex.ctr @@ -0,0 +1,1162 @@ +%% options + +copyright owner = Dirk Krause +copyright year = 2015-xxxx +license = bsd + + + +%% module + +/** @file dk-hex.c Show file contents in hexadecimal notation. + +See dk_hex_help_text for details. + +*/ + +#include "dk4conf.h" + +#include + +#if DK4_HAVE_STDLIB_H +#ifndef STDLIB_H_INCLUDED +#include +#define STDLIB_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_UNISTD_H +#ifndef UNISTD_H_INCLUDED +#include +#define UNISTD_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_SYS_TYPES_H +#ifndef SYS_TYPES_H_INCLUDED +#include +#define SYS_TYPES_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_SIGNAL_H +#ifndef SIGNAL_H_INCLUDED +#include +#define SIGNAL_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_PROCESS_H +#ifndef PROCESS_H_INCLUDED +#include +#define PROCESS_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_IO_H +#ifndef IO_H_INCLUDED +#include +#define IO_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_FCNTL_H +#ifndef FCNTL_H_INCLUDED +#include +#define FCNTL_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_ERRNO_H +#ifndef ERRNO_H_INCLUDED +#include +#define ERRNO_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_CTYPE_H +#ifndef CTYPE_H_INCLUDED +#include +#define CTYPE_H_INCLUDED 1 +#endif +#endif + +#include "dk4types.h" +#include "dk4const.h" +#include "dk4mem.h" +#include "dk4app.h" +#include "dk4aopt.h" +#include "dk4mem.h" +#include "dk4fput.h" +#include "dk4vers.h" +#include "dk4maodd.h" +#include "dk4maodh.h" +#include "dk4maodo.h" +#include "dk4fopda.h" +#include "dk4mpl.h" +#include "dk4strd.h" +#include "dk4pathd.h" + + + +$!trace-include + + + +/** Constant text keywords used by the module, not localized. +*/ +static const dkChar * const dk_hex_kwnl[] = { +$!string-table macro=dkT +# +# 0 Program group name +# +dktools +# +# 1 Help file name +# +dk-hex.txt +# +# 2 String table file name +# +dk-hex.str +# +# 3 File name: stdin +# +stdin +# +# 4 File mode to read binary +# +rb +# +# 5 Separator for path name components on Windows +# +\\ +# +# 6 Long option name. +# +verbose +$!end +}; + + + +/** Help text shown if no localized help file is found. +*/ +static const dkChar * const dk_hex_help_text[] = { +$!text macro=dkT + +Show file contents in hexadecimal notation + +dk-hex [] [] + +Options: +-a --addresses Show addresses. +-t --text Show printable characters as text. +-o --octal Use octal notation instead of hexadecimal notation. + --verbose Show error message on SIGPIPE. + +--help Show this short help text. +--manual *** SHOW FULL MANUAL. *** +--version Show version information. +--license Show license information. + +http://dktools.sourceforge.net + +$!end +}; + + + +/** License conditions. +*/ +static const dkChar * const dk_hex_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 +}; + + + +/** Constant text keywords, localized. +*/ +static const dkChar * const dk_hex_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: Signal SIGPIPE received! +# +Signal SIGPIPE received! +# +# 3 Error: Aborted by SIGINT signal! +# +Aborted by SIGINT signal! +# +# 4 Error: Aborted by SIGTERM signal! +# +Aborted by SIGTERM signal! +# +# 5 Error: Write attempts to standard output failed! +# +Write attempts to standard output failed! +$!end +}; + + + +/** Line output buffer. +*/ +static dkChar lbuf[128]; + + + +/** Command line options. +*/ +static const dk4_option_specification_t dk_hex_options[] = { + /* Show addresses. + */ + { dkT('a'), dkT("addresses"), DK4_OPT_ARG_NONE }, + + /* Show text characters. + */ + { dkT('t'), dkT("text"), DK4_OPT_ARG_NONE }, + + /* Show values in octal notation. + */ + { dkT('o'), dkT("octal"), DK4_OPT_ARG_NONE }, + + /* Verbose mode (report SIGPIPE). + */ + { dkT('\0'), dkT("verbose"), DK4_OPT_ARG_NONE } +}; + + + +/** Text keyword array, either localized or not localized. +*/ +static const dkChar * const *dk_hex_msg = dk_hex_kw_def; + + + +/** Application structure. +*/ +static dk4_app_t *app = NULL; + + + +/** Number of elements in the dk_hex_options array. +*/ +static const size_t dk_hex_sz_options = +sizeof(dk_hex_options)/sizeof(dk4_option_specification_t); + + + +/** Number of elements in dk_hex_kw_def, set at start of main() function. +*/ +static size_t dk_hex_sz_msg = +sizeof(dk_hex_kw_def)/sizeof(DK4_PCDKCHAR) - 1; + + + +/** Start of contents in buffer. +*/ +static size_t st_co = 0; + + + +/** Start of printable text in buffer. +*/ +static size_t st_tx = 0; + + + +/** Line size in buffer. +*/ +static size_t sz_line = 0; + + + +/** Bytes to show per line. +*/ +static size_t el_per_line = 16; + + + +/** Start address of current line. +*/ +static dk4_um_t st_addr = (dk4_um_t)0UL; + + + +/** Number of elements currently in line. +*/ +static size_t el_in_line = 0; + + + +/** Flag: Show addresses. +*/ +static int sh_addr = 0; + + + +/** Flag: Show printable characters. +*/ +static int sh_text = 0; + + + +/** Flag: Show contents in octal notation. +*/ +static int sh_octal = 0; + + + +/** Exit status code. +*/ +static int exval = EXIT_FAILURE; + + + +/** Flag: Errors occured while writing to standard output. +*/ +static int output_error = 0; + + + +/** Flag: Verbose mode (report SIGPIPE). +*/ +static int verbose = 0; + + + +#ifdef SIGPIPE +/** Indicator: SIGPIPE signal received. +*/ +static +DK4_VOLATILE +dk4_sig_atomic_t dk_hex_sig_had_pipe = 0; +#endif + +/** Indicator: SIGINT signal received. +*/ +static +DK4_VOLATILE +dk4_sig_atomic_t dk_hex_sig_had_int = 0; + +/** Indicator: SIGTERM signal received. +*/ +static +DK4_VOLATILE +dk4_sig_atomic_t dk_hex_sig_had_term = 0; + + + +/** Pass a volatile pointer to an atomic integer. + 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 ptr Address of atomic integer variable. + @return The unmodified pointer. +*/ +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 +dk_hex_sig_handler_pipe(int signo) +{ + *sig_pass_pointer(&dk_hex_sig_had_pipe) = 1; +} +#endif + +/** Handler for SIGINT signal. + @param signo Signal number (always SIGINT, ignored). +*/ +static +void +dk_hex_sig_handler_int(int signo) +{ + *sig_pass_pointer(&dk_hex_sig_had_int) = 1; +} + +/** Handler for SIGTERM signal. + @param signo Signal number (always SIGTERM, ignored). +*/ +static +void +dk_hex_sig_handler_term(int signo) +{ + *sig_pass_pointer(&dk_hex_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 +dk_hex_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 != dk_hex_sig_read_atomic(&dk_hex_sig_had_pipe)) { back = 0; } + } +#endif + if (0 != dk_hex_sig_read_atomic(&dk_hex_sig_had_int )) { back = 0; } + if (0 != dk_hex_sig_read_atomic(&dk_hex_sig_had_term)) { back = 0; } + return back; +} + + + +static +void +dk_hex_cpy(dkChar *dptr, const dkChar *sptr) +{ + while(dkT('\0') != *sptr) { *(dptr++) = *(sptr++); } +} + + +/** Check whether we can continue. + @return 1 if we can continue, 0 otherwise. +*/ +static +int +dk_hex_can_continue(void) +{ + return (sig_can_continue(1)); +} + + + +/** Prepare output line buffer (fill with spaces, set finalizer byte). +*/ +static +void +dk_hex_prepare_line(void) +{ + dkChar abuf[16*sizeof(dk4_um_t)]; + dkChar *ptr; + size_t llgt; + int res; + + ptr = lbuf; + llgt = sz_line; + while (llgt--) { + *(ptr++) = dkT(' '); + } + lbuf[sz_line] = dkT('\0'); + if (0 != sh_addr) { + res = dk4ma_write_hex_unsigned( + abuf, DK4_SIZEOF(abuf,dkChar), st_addr, 2*sizeof(dk4_um_t), NULL + ); + if (0 != res) { + dk_hex_cpy(lbuf, abuf); + } + } +} + + + +static +void +dk_hex_flush_line(void) +{ + if (0 == dk4fputs(lbuf, stdout, NULL)) { + output_error = 1; + } + if (0 == dk4fputc(dkT('\n'), stdout, NULL)) { + output_error = 1; + } + el_in_line = 0; + st_addr += el_per_line; + dk_hex_prepare_line(); +} + + + +static +void +dk_hex_add_byte(unsigned char uc) +{ + dkChar mybuf[16 * sizeof(dk4_um_t)]; + int res; + if (0 != sh_octal) { + res = dk4ma_write_octal_unsigned( + mybuf, DK4_SIZEOF(mybuf,dkChar), + ( (dk4_um_t)0xFFUL & (dk4_um_t)uc ), + 3, NULL + ); + } else { + res = dk4ma_write_hex_unsigned( + mybuf, DK4_SIZEOF(mybuf,dkChar), + ( (dk4_um_t)0xFFUL & (dk4_um_t)uc ), + 2, NULL + ); + } + if (0 != res) { + dk_hex_cpy( + &(lbuf[st_co + el_in_line * ((0 != sh_octal) ? 4 : 3)]), + mybuf + ); + } + if (0 != sh_text) { + if (!((isascii(uc)) && (isprint(uc)))) { uc = '.'; } + lbuf[st_tx + el_in_line] = (dkChar)uc; + } + if (++el_in_line >= el_per_line) { + dk_hex_flush_line(); + } +} + + + +/** Process one file. + @param fipo Opened file. + @param filename File name, (NULL for stdin). +*/ +static +void +dk_hex_process_file(FILE *fipo, const dkChar *filename) +{ + const dkChar *oldsourcefile = NULL; + dk4_um_t oldsourceline = (dk4_um_t)0UL; + int cc = 1; /* Flag: Continue */ + int c = 0; /* Current char */ + + oldsourcefile = dk4app_get_log_source_file(app); + oldsourceline = dk4app_get_log_source_line(app); + + dk4app_set_log_source_file( + app, ((NULL != filename) ? filename: dk_hex_kwnl[3]) + ); + dk4app_set_log_source_line(app, (dk4_um_t)0UL); + if (NULL != filename) { + if (0 == dk4fputs(filename, stdout, NULL)) { output_error = 1; } + if (0 == dk4fputc(dkT('\n'), stdout, NULL)) { output_error = 1; } + } + el_in_line = 0; + dk_hex_prepare_line(); + while (1 == cc) { + if (0 != dk_hex_can_continue()) { + c = fgetc(fipo); + if (EOF != c) { + if (0 != feof(fipo)) { cc = 0; } + dk_hex_add_byte((unsigned char)c); + } else { + cc = 0; + } + } else { + cc = -1; + } + } + if (0 == cc) { + if (0 < el_in_line) { + dk_hex_flush_line(); + } + } + dk4app_set_log_source_file(app, oldsourcefile); + dk4app_set_log_source_line(app, oldsourceline); +} + + + +/** Open one named file and process it. + @param filename File name. +*/ +static +void +dk_hex_process_one_name(const dkChar *filename) +{ + FILE *fipo = NULL; + fipo = dk4fopen_app( + filename, dk_hex_kwnl[4], DK4_FOPEN_SC_IS_REGULAR, app + ); + if (NULL != fipo) { + dk_hex_process_file(fipo, filename); + fclose(fipo); + } +} + + + +#if DK4_ON_WINDOWS + +/** Expand file name pattern, process file names. + @param pattern File name pattern. + @return 1 if files were found, 0 otherwise. +*/ +static +int +dk_hex_expand_filename(const dkChar *pattern) +{ + dkChar buf[DK4_MAX_PATH]; + dk4_dir_t *fne; + const dkChar *shf; + const dkChar *pth; + int cc; + int back = 0; + fne = dk4app_fne_open(pattern, app); + if (NULL != fne) { + cc = 1; + while (1 == cc) { + if (0 != dk_hex_can_continue()) { + shf = dk4dir_next_file(fne); + if (NULL != shf) { + back = 1; + pth = dk4dir_get_path(fne); + if (NULL != pth) { + if (0 != dk4str_cpy_s(buf, DK4_SIZEOF(buf,dkChar), pth, NULL)) { + if(0!=dk4str_cat_s(buf,DK4_SIZEOF(buf,dkChar),dk_hex_kwnl[5],NULL)) + { + if(0 != dk4str_cat_s(buf, DK4_SIZEOF(buf,dkChar), shf, NULL)) { + dk_hex_process_one_name(buf); + } else { + /* ERROR: Path too long */ + dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth); + exval = EXIT_FAILURE; + } + } + else + { + /* ERROR: Path too long */ + dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth); + exval = EXIT_FAILURE; + } + } else { + /* ERROR: Path too long */ + dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth); + exval = EXIT_FAILURE; + } + } else { + dk_hex_process_one_name(shf); + } + } else { + cc = 0; + } + } else { + cc = -1; + } + } + dk4dir_close(fne); + } else { + exval = EXIT_FAILURE; + } + return back; +} + +#endif + + + +/** Run normal functionality after setting up signal handlers. +*/ +static +void +dk_hex_run_the_functions(void) +{ + const dkChar *xargv; /* Current file name to process */ +#if DK4_ON_WINDOWS + int oldmode; /* File mode for windows */ +#endif + int xargc; /* Number of file names to process */ + int i; /* Index of current file name processed */ + /* + Check options + */ + if (0 != dk4app_opt_is_set_long(app, dk_hex_kwnl[6], NULL)) { verbose = 1; } + if (0 != dk4app_opt_is_set_short(app, dkT('o'), NULL)) { sh_octal = 1; } + if (0 != dk4app_opt_is_set_short(app, dkT('a'), NULL)) { sh_addr = 1; } + if (0 != dk4app_opt_is_set_short(app, dkT('t'), NULL)) { sh_text = 1; } + /* + Calculate sizes and indices + */ + if (0 != sh_octal) { + if (0 != sh_addr) { + st_co = 3 + 2 * sizeof(dk4_um_t); + el_per_line = 8; + sz_line = st_co + el_per_line * 4 - 1; + if (0 != sh_text) { /* octal, addresses, text */ + st_tx = sz_line + 3; + sz_line += (3 + el_per_line); + } + } else { + st_co = 0; + if (0 != sh_text) { /* octal, no addresses, text */ + el_per_line = 8; + sz_line = st_co + el_per_line * 4 - 1; + st_tx = sz_line + 3; + sz_line += (3 + el_per_line); + } else { /* octal, no addresses, no text */ + el_per_line = 16; + sz_line = st_co + el_per_line * 4 - 1; + } + } + } else { + if (0 != sh_addr) { + st_co = 3 + 2 * sizeof(dk4_um_t); + if (0 != sh_text) { /* hexadecimal, addresses, text */ + el_per_line = 8; + sz_line = st_co + el_per_line * 3 - 1; + st_tx = sz_line + 3; + sz_line += (3 + el_per_line); + } else { /* hexadecimal, addresses, no text */ + el_per_line = 16; + sz_line = st_co + el_per_line * 3 - 1; + } + } else { + st_co = 0; + el_per_line = 16; + sz_line = st_co + el_per_line * 3 - 1; + if (0 != sh_text) { /* hexadecimal, no addresses, text */ + st_tx = sz_line + 3; + sz_line += (3 + el_per_line); + } + } + } + $? ". st_co= %u", (unsigned)st_co + $? ". st_tx= %u", (unsigned)st_tx + $? ". sz_line=%u", (unsigned)sz_line + /* + Process input files or standard input + */ + exval = EXIT_SUCCESS; + xargc = dk4app_get_argc(app); + if (0 < xargc) { + for (i = 0; ((0 != dk_hex_can_continue()) && (i < xargc)); i++) { + xargv = dk4app_get_argv(app, i); + if (NULL != xargv) { +#if DK4_ON_WINDOWS + if (0 != dk4path_must_expand(xargv)) { + if (0 == dk_hex_expand_filename(xargv)) { + /* ERROR: No file found */ + dk4app_log_base3(app, DK4_LL_ERROR, 100, 107, xargv); + exval = EXIT_FAILURE; + } + } else { +#endif + dk_hex_process_one_name(xargv); +#if DK4_ON_WINDOWS + } +#endif + } + } + } else { +#if DK4_ON_WINDOWS + oldmode = _setmode(_fileno(stdin), _O_BINARY); +#endif + dk_hex_process_file(stdin, NULL); +#if DK4_ON_WINDOWS + _setmode(_fileno(stdin), oldmode); +#endif + } +} + + + +#if DK4_HAVE_SIGACTION +/** Set signal handlers and run. +*/ +static +void +dk_hex_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; + +#ifdef SIGPIPE + /* Set up signal handling for SIGPIPE. + */ + DK4_MEMRES(&npipe, sizeof(npipe)); + npipe.sa_handler = dk_hex_sig_handler_pipe; + npipe.sa_flags = 0; + if (0 != sigemptyset(&npipe.sa_mask)) { + /* ERROR: Failed to set up masked signal set for SIGPIPE */ + dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 0); + goto finished; + } + if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) { + /* ERROR: Failed to set up masked signal set for SIGPIPE */ + dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 0); + goto finished; + } + if (0 != sigaction(SIGPIPE, &npipe, &opipe)) { + /* ERROR: Failed to set up signal handler for SIGPIPE */ + dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 0); + goto finished; + } +#endif + + /* Set up signal handling for SIGINT. + */ + DK4_MEMRES(&nint, sizeof(nint)); + nint.sa_handler = dk_hex_sig_handler_int; + nint.sa_flags = 0; + if (0 != sigemptyset(&nint.sa_mask)) { + /* ERROR: Failed to set up masked signal set for SIGINT */ + dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 0); + goto restore_old_pipe; + } + if (0 != sigaddset(&nint.sa_mask, SIGINT)) { + /* ERROR: Failed to set up masked signal set for SIGINT */ + dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 0); + goto restore_old_pipe; + } + if (0 != sigaction(SIGINT, &nint, &oint)) { + /* ERROR: Failed to set up signal handler for SIGINT */ + dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 0); + goto restore_old_pipe; + } + + /* Set up signal handling for SIGTERM + */ + DK4_MEMRES(&nterm, sizeof(nterm)); + nterm.sa_handler = dk_hex_sig_handler_term; + nterm.sa_flags = 0; + if (0 != sigemptyset(&nterm.sa_mask)) { + /* ERROR: Failed to set up masked signal set for SIGTERM */ + dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 0); + goto restore_old_int; + } + if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) { + /* ERROR: Failed to set up masked signal set for SIGTERM */ + dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 0); + goto restore_old_int; + } + if (0 != sigaction(SIGTERM, &nterm, &oterm)) { + /* ERROR: Failed to set up signal handler for SIGTERM */ + dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 0); + goto restore_old_int; + } + + success = 1; + dk_hex_run_the_functions(); + + /* Restore signal handling for SIGTERM. + */ + if (0 != sigaction(SIGTERM, &oterm, NULL)) { + /* ERROR: Failed to restore old SIGTERM settings */ + dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 1); + success = 0; + } + + /* Restore signal handling for SIGINT. + */ + restore_old_int: + if (0 != sigaction(SIGINT, &oint, NULL)) { + /* ERROR: Failed to restore old SIGPIPE settings */ + dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 1); + success = 0; + } + +#ifdef SIGPIPE + /* Restore signal handling for SIGPIPE. + */ + restore_old_pipe: + if (0 != sigaction(SIGPIPE, &opipe, NULL)) { + /* ERROR: Failed to restore old SIGPIPE settings */ + dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 1); + success = 0; + } +#endif + + /* Set exit status code if error occured. + */ + finished: + if (0 == success) { exval = EXIT_FAILURE; } +} +#else +#if DK4_HAVE_SIGSET +/** Set signal handlers and run. +*/ +static +void +dk_hex_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; + +#ifdef SIGPIPE + oldpipe = sigset(SIGPIPE, dk_hex_sig_handler_pipe); +#endif + oldint = sigset(SIGINT, dk_hex_sig_handler_int); + oldterm = sigset(SIGTERM, dk_hex_sig_handler_term); + dk_hex_run_the_functions(); + sigset(SIGTERM, oldterm); + sigset(SIGINT, oldint); +#ifdef SIGPIPE + sigset(SIGPIPE, oldpipe); +#endif +} +#else +#if DK4_HAVE_SIGNAL +/** Set signal handlers and run. +*/ +static +void +dk_hex_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; +#ifdef SIGPIPE + oldpipe = signal(SIGPIPE, dk_hex_sig_handler_pipe); +#endif + oldint = signal(SIGINT, dk_hex_sig_handler_int); + oldterm = signal(SIGTERM, dk_hex_sig_handler_term); + dk_hex_run_the_functions(); + signal(SIGTERM, oldterm); + signal(SIGINT, oldint); +#ifdef SIGPIPE + signal(SIGPIPE, oldpipe); +#endif +} +#else +/** Set signal handlers and run. +*/ +static +void +dk_hex_run_with_signals(void) +{ + dk_hex_run_the_functions(); +} +#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 +{ + int shp; + $!trace-init dk-hex.deb + $? "+ main" + dk4fput_initialize_stdout(); + dk4fput_initialize_stderr(); + app = dk4app_open_cmd( + argc, argv, dk_hex_options, dk_hex_sz_options, + dk_hex_kwnl[0], DKT_VERSION_DK, + dk_hex_kwnl[1], dk_hex_help_text, dk_hex_license_text + ); + if (NULL != app) { + dk_hex_sz_msg = dk4app_string_table_size(dk_hex_kw_def); + dk_hex_msg = dk4app_string_table(app, dk_hex_kwnl[2], dk_hex_kw_def); + if (0 != dk4app_can_run_normally(app)) { + dk_hex_run_with_signals(); +#ifdef SIGPIPE + if (0 != dk_hex_sig_read_atomic(&dk_hex_sig_had_pipe)) { + if (0 != verbose) { + dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 2); + } + exval = EXIT_FAILURE; + shp = 1; + } else { + shp = 0; + } +#else + shp = 0; +#endif + if (0 != dk_hex_sig_read_atomic(&dk_hex_sig_had_int )) { + dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 3); + exval = EXIT_FAILURE; + } + if (0 != dk_hex_sig_read_atomic(&dk_hex_sig_had_term)) { + dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 4); + exval = EXIT_FAILURE; + } + if ((0 == shp) && (0 != output_error)) { + dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 5); + exval = EXIT_FAILURE; + } + } else { + if (0 != dk4app_help_version_license(app)) { + exval = EXIT_SUCCESS; + } + } + dk4app_close(app); + } + fflush(stdout); + fflush(stderr); + dk4fput_cleanup_stderr(); + dk4fput_cleanup_stdout(); + $? "- main %d", exval + $!trace-end + exit(exval); return exval; +} + -- cgit v1.2.3