/* Copyright (C) 2015-2020, Dirk Krause SPDX-License-Identifier: BSD-3-Clause */ /* WARNING: This file was generated by the dkct program (see http://dktools.sourceforge.net/ for details). 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: dk-bmm.ctr */ /** @file dk-bmm.c The dk-bmm module. */ #line 10 "dk-bmm.ctr" #include "dk4conf.h" #include #if DK4_ON_WINDOWS #ifndef WINDOWS_H_INCLUDED #include #define WINDOWS_H_INCLUDED 1 #endif #endif #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_TIME_WITH_SYS_TIME #ifndef SYS_TIME_H_INCLUDED #include #define SYS_TIME_H_INCLUDED 1 #endif #ifndef TIME_H_INCLUDED #include #define TIME_H_INCLUDED 1 #endif #else #if DK4_HAVE_TIME_H #ifndef TIME_H_INCLUDED #include #define TIME_H_INCLUDED 1 #endif #else #if DK4_HAVE_SYS_TIME_H #ifndef SYS_TIME_H_INCLUDED #include #define SYS_TIME_H_INCLUDED 1 #endif #endif #endif #endif #include "dk4types.h" #include "dk4const.h" #include "dk4mem.h" #include "dk4app.h" #include "dk4vers.h" #include "dk4fput.h" #include "dk4str8.h" #include "dk4strd.h" #include "dk4enc.h" #include "dk4tsp08.h" #include "dk4tspdk.h" #include "dk4mai8dus.h" #include "dk4mai8ddu.h" #include "dk4maidddu.h" #include "dk4mao8d.h" #include "dk4maodd.h" #include "dk4fopda.h" #include "dk4isadm.h" #include "dk4timec.h" #include "dk4time08.h" #include "dk4aopt.h" #include "dk4mpl.h" #include "dk4pathd.h" #include "dk4unused.h" #ifndef DK4WMAIN_H_INCLUDED #include "dk4wmain.h" #endif #line 135 "dk-bmm.ctr" /** Information about one media. */ typedef struct { unsigned short year; /**< Year of last backup. */ unsigned short month; /**< Month of last backup. */ unsigned short day; /**< Day within month of last backup. */ unsigned short hour; /**< Hour of last backup. */ unsigned short minute; /**< Minute of last backup. */ unsigned short second; /**< Second of last backup. */ unsigned short times; /**< How many times was the media used. */ } dk_bmm_media_t; /** Line handler object. */ typedef struct { int *backptr; /**< Address of result variable. */ } dk_bmm_lh_obj_t; /** Help text shown if no help text file found. */ static const dkChar * const dk_bmm_help_text[] = { dkT(""), dkT("Backup media management"), dkT(""), dkT("dk-bmm [] []"), dkT(""), dkT("Options:"), dkT("-s\t--set\t\tUse media sets instead of media."), dkT("-c\t--confirm\tConfirm success for backup."), dkT("-r\t--report\tCreate tape usage report."), dkT(""), dkT("--help\t\t\tShow this short help text."), dkT("--manual\t\t*** SHOW FULL MANUAL. ***"), dkT("--version\t\tShow version information."), dkT("--license\t\tShow version information."), dkT(""), dkT("Typical operations:"), dkT("dk-bmm -s \tFind name of current backup set."), dkT("dk-bmm \t\tFind number of current media in set."), dkT("dk-bmm -c \t\tConfirm successful backup to current media."), dkT("dk-bmm -c -s \tConfirm successful backup for current set."), dkT(""), dkT("http://sourceforge.net/p/dktools/wiki/dk-bmm/"), dkT(""), NULL #line 188 "dk-bmm.ctr" }; /** License conditions. */ static const dkChar * const dk_bmm_license_text[] = { dkT(""), dkT("This software uses code from the following projects, either directly or as"), dkT("a library:"), dkT(""), dkT("dktools\t\tDirk Krause's tools and libraries."), dkT("\t\tSee http://sourceforge.net/p/dktools/wiki/Home/"), dkT("\t\tfor more information."), #if DK4_HAVE_ZLIB_H dkT(""), dkT("zlib\t\tData compression library."), dkT("\t\tSee http://www.zlib.net/ for more information."), #endif #if DK4_HAVE_BZLIB_H dkT(""), dkT("bzip2\t\tData compression program and library."), dkT("\t\tSee http://www.bzip.org/ for more information."), #endif dkT(""), dkT("All the licenses below apply to the program."), dkT("Licenses for used libraries are shown as found on my Scientific Linux 6.x"), dkT("computer in the /usr/share/doc directory on 2015-04-01. Check the project"), dkT("homepages of the used libraries for additional information and/or updated"), dkT("license terms."), dkT(""), dkT(""), dkT("DK tools and libraries license"), dkT("=============================="), dkT("Copyright (c) 2015-2016, Dirk Krause"), dkT("All rights reserved."), dkT(""), dkT("Redistribution and use in source and binary forms, with or without"), dkT("modification, are permitted provided that the following conditions are met:"), dkT(""), dkT("1. Redistributions of source code must retain the above copyright notice,"), dkT(" this list of conditions and the following disclaimer."), dkT("2. Redistributions in binary form must reproduce the above copyright"), dkT(" notice, this list of conditions and the following disclaimer in the"), dkT(" documentation and/or other materials provided with the distribution."), dkT("3. Neither the name of the copyright holder nor the names of its"), dkT(" contributors may be used to endorse or promote products derived from"), dkT(" this software without specific prior written permission."), dkT(""), dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS"), dkT("``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT"), dkT("LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR"), dkT("A PARTICULAR PURPOSE ARE DISCLAIMED."), dkT("IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY"), dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES"), dkT("(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR"), dkT("SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER"), dkT("CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT"), dkT("LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY"), dkT("OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF"), dkT("SUCH DAMAGE."), dkT(""), #if DK4_HAVE_ZLIB_H dkT(""), dkT(""), dkT("Zlib license"), dkT("============"), dkT("(C) 1995-2004 Jean-loup Gailly and Mark Adler"), dkT(""), dkT("This software is provided 'as-is', without any express or implied"), dkT("warranty. In no event will the authors be held liable for any damages"), dkT("arising from the use of this software."), dkT(""), dkT("Permission is granted to anyone to use this software for any purpose,"), dkT("including commercial applications, and to alter it and redistribute it"), dkT("freely, subject to the following restrictions:"), dkT(""), dkT("1. The origin of this software must not be misrepresented; you must not"), dkT(" claim that you wrote the original software. If you use this software"), dkT(" in a product, an acknowledgment in the product documentation would be"), dkT(" appreciated but is not required."), dkT("2. Altered source versions must be plainly marked as such, and must not be"), dkT(" misrepresented as being the original software."), dkT("3. This notice may not be removed or altered from any source distribution."), dkT(""), dkT("Jean-loup Gailly Mark Adler"), dkT("jloup@gzip.org madler@alumni.caltech.edu"), #endif #if DK4_HAVE_BZLIB_H dkT(""), dkT(""), dkT("Bzip2 and libbzip2 library license"), dkT("=================================="), dkT("This program, \"bzip2\", the associated library \"libbzip2\", and all"), dkT("documentation, are copyright (C) 1996-2007 Julian R Seward. All"), dkT("rights reserved."), dkT(""), dkT("Redistribution and use in source and binary forms, with or without"), dkT("modification, are permitted provided that the following conditions"), dkT("are met:"), dkT(""), dkT("1. Redistributions of source code must retain the above copyright"), dkT(" notice, this list of conditions and the following disclaimer."), dkT(""), dkT("2. The origin of this software must not be misrepresented; you must "), dkT(" not claim that you wrote the original software. If you use this "), dkT(" software in a product, an acknowledgment in the product "), dkT(" documentation would be appreciated but is not required."), dkT(""), dkT("3. Altered source versions must be plainly marked as such, and must"), dkT(" not be misrepresented as being the original software."), dkT(""), dkT("4. The name of the author may not be used to endorse or promote "), dkT(" products derived from this software without specific prior written "), dkT(" permission."), dkT(""), dkT("THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS"), dkT("OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"), dkT("WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"), dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY"), dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"), dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE"), dkT("GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"), dkT("INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"), dkT("WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"), dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"), dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."), dkT(""), dkT("Julian Seward, jseward@bzip.org"), dkT("bzip2/libbzip2 version 1.0.5 of 10 December 2007"), #endif dkT(""), NULL #line 322 "dk-bmm.ctr" }; /** Buffer to save set names line. */ static dkChar dk_bmm_set_line[1024]; /** Buffer for reading the line. */ static dkChar dk_bmm_set_buffer[1024]; /** Pointers to all the set names. */ static dkChar *dk_bmm_set_names[512]; /** Constant text keywords used by the program, not localized. */ static const dkChar * const dk_bmm_kwnl[] = { /* 0 */ dkT("dktools"), /* 1 */ dkT("dk-bmm.txt"), /* 2 */ dkT("dk-bmm.str"), /* 3 */ dkT("\\"), /* 4 */ dkT("rb"), /* 5 */ dkT("w"), NULL #line 373 "dk-bmm.ctr" }; /** Constant text keywords used by the program, localized. */ static const dkChar * const dk_bmm_kw_def[] = { /* 0 */ dkT("Failed to set up signal handlers!"), /* 1 */ dkT("Failed to restore signal handlers!"), /* 2 */ dkT("Write attempt to standard output failed!"), /* 3 */ dkT("SIGPIPE signal received!"), /* 4 */ dkT("Aborted by SIGINT signal!"), /* 5 */ dkT("Aborted by SIGTERM signal!"), /* 6 */ dkT(" (previous cycle)"), /* 7 */ dkT("Media number for next backup: "), /* 8 */ dkT("Option -r is not available for a set names file."), /* 9 */ dkT("Failed to read file, probably not a dk-bmm file!"), /* 10 */ dkT("Exactly one file name allowed!"), /* 11 */ dkT("Cycle completed, please renew media set!"), /* 12 */ dkT("Failed to write new set file!"), /* 13 */ dkT("Not a set names file!"), NULL #line 438 "dk-bmm.ctr" }; /** Options understood by the program. */ static const dk4_option_specification_t dk_bmm_options[] = { /* Process media sets, not media. */ { dkT('s'), dkT("set"), DK4_OPT_ARG_NONE }, /* Confirm previously requested media set or media. */ { dkT('c'), dkT("confirm"), DK4_OPT_ARG_NONE }, /* Report media. */ { dkT('r'), dkT("report"), DK4_OPT_ARG_NONE }, }; /** Media numbers in order of usage. This implements the 10 tape rotation scheme. At every time we will have backups of different ages. During 200 backups each of the 10 media is used 20 times. */ static const unsigned char dk_bmm_media_numbers[] = { 1, 2, 3, 4, 5, 1, 2, 3, 4, 6, 1, 2, 3, 4, 7, 1, 2, 3, 4, 8, 2, 3, 4, 5, 6, 2, 3, 4, 5, 7, 2, 3, 4, 5, 8, 2, 3, 4, 5, 9, 3, 4, 5, 6, 7, 3, 4, 5, 6, 8, 3, 4, 5, 6, 9, 3, 4, 5, 6, 10, 4, 5, 6, 7, 8, 4, 5, 6, 7, 9, 4, 5, 6, 7, 10, 4, 5, 6, 7, 1, 5, 6, 7, 8, 9, 5, 6, 7, 8, 10, 5, 6, 7, 8, 1, 5, 6, 7, 8, 2, 6, 7, 8, 9, 10, 6, 7, 8, 9, 1, 6, 7, 8, 9, 2, 6, 7, 8, 9, 3, 7, 8, 9, 10, 1, 7, 8, 9, 10, 2, 7, 8, 9, 10, 3, 7, 8, 9, 10, 4, 8, 9, 10, 1, 2, 8, 9, 10, 1, 3, 8, 9, 10, 1, 4, 8, 9, 10, 1, 5, 9, 10, 1, 2, 3, 9, 10, 1, 2, 4, 9, 10, 1, 2, 5, 9, 10, 1, 2, 6, 10, 1, 2, 3, 4, 10, 1, 2, 3, 5, 10, 1, 2, 3, 6, 10, 1, 2, 3, 7 }; /** Information for the 10 media in the backup scheme. */ static dk_bmm_media_t media_info[10]; /** Flag: Media found for recoding. */ static unsigned short media_found[10]; /** Pointer to either localized messages or default texts. */ static const dkChar * const *dk_bmm_msg = dk_bmm_kw_def; /** Application structure for diagnostics. */ static dk4_app_t *app = NULL; /** Number of used names in dk_bmm_set_names. */ static size_t dk_bmm_n_set_names = 0; /** Number of elements in the dk_bmm_options array. */ static const size_t dk_bmm_sz_options = sizeof(dk_bmm_options)/sizeof(dk4_option_specification_t); /** Number of elements in the dk_bmm_msg array. */ static size_t dk_bmm_sz_msg = sizeof(dk_bmm_kw_def)/sizeof(DK4_PCDKCHAR) - 1; /** Exit status code of the program. */ static int exval = EXIT_FAILURE; /** Flag: Dealing with media set. */ static int dk_bmm_handle_set = 0; /** Flag: Confirm previous media or set. */ static int dk_bmm_do_confirm = 0; /** Flag: Write report. */ static int dk_bmm_do_report = 0; /** Flag: Output mode for stdout was changed. */ static int dk_bmm_mod_stdout = 0; /** Number of recent day within backup cycle. */ static int dk_bmm_day_in_cycle = 0; /** Flag: Cycle was completed. */ static int dk_bmm_cycle_completed = 0; /** Flag: Write attempt to stdout failed. */ static int output_error = 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 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 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( #ifdef SIGPIPE int check_pipe #else int DK4_ARG_UNUSED(check_pipe) #endif ) { int back = 1; #ifndef SIGPIPE DK4_UNUSED_ARG(check_pipe) #else 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; } /** Check whether we can continue. @return 1 for yes, 0 for no. */ static int dk_bmm_can_continue(void) { int back = 1; if (0 == sig_can_continue(1)) { back = 0; } return back; } /** Handler function for text lines. @param obj Object to modify while processing the character. @param line Text line to process. @param lineno Current line number. @param erp Error report, may be NULL. @return DK4_TSP_RES_OK if the character was processed successfully, DK4_TSP_RES_ERROR if there was an error but we can continue, DK4_TSP_RES_FATAL if there was a fatal error so we should abort processing. */ static int dk_bmm_sets_line_handler( void *obj, dkChar *line, dk4_um_t lineno, dk4_er_t * DK4_ARG_UNUSED(erp) ) { dk_bmm_lh_obj_t *lhoptr; dkChar *p1; const dkChar *pe; dk4_um_t um; size_t i; size_t al; int res; int back = DK4_TSP_RES_FATAL; #line 739 "dk-bmm.ctr" DK4_UNUSED_ARG(erp) lhoptr = (dk_bmm_lh_obj_t *)obj; if ((dk4_um_t)1UL == lineno) { #line 742 "dk-bmm.ctr" dk4str_delnl(line); res = dk4str_cpy_s( dk_bmm_set_line, DK4_SIZEOF(dk_bmm_set_line,dkChar), line, NULL ); if (0 != res) { al = sizeof(dk_bmm_set_names)/sizeof(DK4_PDKCHAR); for (i = 0; i < al; i++) { dk_bmm_set_names[i] = NULL; } i = dk4str_tokenize(dk_bmm_set_names, al, dk_bmm_set_line, NULL, NULL); if (0 < i) { dk_bmm_n_set_names = i; back = DK4_TSP_RES_OK; } } } else { if ((dk4_um_t)2UL == lineno) { #line 757 "dk-bmm.ctr" dk4str_delnl(line); p1 = dk4str_start(line, NULL); if (NULL != p1) { pe = NULL; um = (dk4_um_t)0UL; res = dk4ma_input_dk_dec_dk4_um_t( &um, p1, &pe, 1, NULL ); if (0 != res) { if ((dk4_um_t)INT_MAX >= um) { dk_bmm_day_in_cycle = (int)um; if ((dk4_um_t)dk_bmm_n_set_names > um) { back = DK4_TSP_RES_OK; } } } } else { back = DK4_TSP_RES_OK; } } else { #line 777 "dk-bmm.ctr" } } if ((DK4_TSP_RES_FATAL == back) || (DK4_TSP_RES_ERROR == back)) { *(lhoptr->backptr) = 0; } #line 782 "dk-bmm.ctr" return back; } /** Read sets file. @param filename Name of file to read. @return 1 on success, 0 on error. */ static int dk_bmm_read_sets_file(const dkChar *filename) { dk4_er_t er; dk4_tspdk_t tspdk; dk_bmm_lh_obj_t lhoptr; FILE *fipo; int res; int c; int cc = 1; int back = 0; #line 804 "dk-bmm.ctr" fipo = dk4fopen_app(filename, dk_bmm_kwnl[4], DK4_FOPEN_SC_IS_REGULAR, app); if (NULL != fipo) { lhoptr.backptr = &back; dk4error_init(&er); res = dk4tspdk_setup_line( &tspdk, &lhoptr, dk_bmm_sets_line_handler, dk_bmm_set_buffer, DK4_SIZEOF(dk_bmm_set_buffer,dkChar), dk4app_get_encoding(app), dk4app_get_file_in_encoding(app), &er ); if (0 != res) { back = 1; while (1 == cc) { if (0 != dk_bmm_can_continue()) { c = fgetc(fipo); if (EOF != c) { if (0 != feof(fipo)) { cc = 0; } res = dk4tspdk_add_one_byte(&tspdk, (unsigned char)c); switch (res) { case DK4_TSP_RES_ERROR: case DK4_TSP_RES_FATAL: { cc = -1; } break; } } else { cc = 0; } } else { cc = -1; } } if (0 == cc) { res = dk4tspdk_finish(&tspdk); switch (res) { case DK4_TSP_RES_ERROR: case DK4_TSP_RES_FATAL: { back = 0; } break; } } else { back = 0; } } else { /* ERROR: Failed to set up line processing, bug */ } fclose(fipo); } #line 850 "dk-bmm.ctr" return back; } /** Initialize the media_info structures. */ static void dk_bmm_initialize_media_info(void) { size_t i; for (i = 0; i < 10; i++) { media_info[i].year = media_info[i].month = media_info[i].day = media_info[i].hour = media_info[i].minute = media_info[i].second = media_info[i].times = 0U; } } static int dk_bmm_data_line(dk_bmm_media_t *mptr, char *line) { const char *ep; int back = 0; #line 883 "dk-bmm.ctr" if (21 > dk4str8_len(line)) { #line 885 "dk-bmm.ctr" goto finished; } if ('-' != line[4]) { #line 889 "dk-bmm.ctr" goto finished; } line[4] = '\0'; if ('-' != line[7]) { #line 894 "dk-bmm.ctr" goto finished; } line[7] = '\0'; if (' ' != line[10]) { #line 899 "dk-bmm.ctr" goto finished; } line[10] = '\0'; if (':' != line[13]) { #line 904 "dk-bmm.ctr" goto finished; } line[13] = '\0'; if (':' != line[16]) { #line 909 "dk-bmm.ctr" goto finished; } line[16] = '\0'; if (' ' != line[19]) { #line 914 "dk-bmm.ctr" goto finished; } line[19] = '\0'; ep = NULL; if (0 == dk4ma_input_c8_dec_ushort(&(mptr->year), line, &ep, 0, NULL)) { #line 920 "dk-bmm.ctr" goto finished; } if (0 == dk4ma_input_c8_dec_ushort(&(mptr->month),&(line[5]),&ep,0,NULL)) { #line 924 "dk-bmm.ctr" goto finished; } if (0 == dk4ma_input_c8_dec_ushort(&(mptr->day),&(line[8]),&ep,0,NULL)) { #line 928 "dk-bmm.ctr" goto finished; } if (0 == dk4ma_input_c8_dec_ushort(&(mptr->hour),&(line[11]),&ep,0,NULL)) { #line 932 "dk-bmm.ctr" goto finished; } if (0 == dk4ma_input_c8_dec_ushort(&(mptr->minute),&(line[14]),&ep,0,NULL)) { #line 936 "dk-bmm.ctr" goto finished; } if (0 == dk4ma_input_c8_dec_ushort(&(mptr->second),&(line[17]),&ep,0,NULL)) { #line 940 "dk-bmm.ctr" goto finished; } if (0 == dk4ma_input_c8_dec_ushort(&(mptr->times),(&line[20]),&ep,0,NULL)) { #line 944 "dk-bmm.ctr" goto finished; } back = 1; finished: #line 949 "dk-bmm.ctr" return back; } /** Handler function for text lines. @param obj Object to modify while processing the character. @param line Text line to process. @param lineno Current line number. @param erp Error report, may be NULL. @return DK4_TSP_RES_OK if the character was processed successfully, DK4_TSP_RES_ERROR if there was an error but we can continue, DK4_TSP_RES_FATAL if there was a fatal error so we should abort processing. */ static int dk_bmm_media_line_handler( void *obj, char *line, dk4_um_t lineno, dk4_er_t * DK4_ARG_UNUSED(erp) ) { dk4_er_t er; dk_bmm_lh_obj_t *lhoptr; const char *endptr = NULL; dk4_um_t um; int res; int back = DK4_TSP_RES_FATAL; #line 982 "dk-bmm.ctr" DK4_UNUSED_ARG(erp) lhoptr = (dk_bmm_lh_obj_t *)obj; dk4str8_delnl(line); if ((dk4_um_t)1UL == lineno) { #line 986 "dk-bmm.ctr" /* Process first line */ dk4error_init(&er); res = dk4ma_input_c8_dec_dk4_um_t(&um, line, &endptr, 1, &er); if (0 != res) { if ((dk4_um_t)200UL > um) { dk_bmm_day_in_cycle = (int)um; back = DK4_TSP_RES_OK; } else { /* ERROR: Out of range */ } } else { /* ERROR: Failed to read number */ } } else { if (((dk4_um_t)2UL <= lineno) && ((dk4_um_t)11UL >= lineno)) { /* Process data line */ lineno -= (dk4_um_t)2UL; #line 1007 "dk-bmm.ctr" if (0 != dk_bmm_data_line(&(media_info[(size_t)lineno]), line)) { back = DK4_TSP_RES_OK; } else { /* ERROR: Syntax */ } } else { #line 1013 "dk-bmm.ctr" /* ERROR: Syntax, too many lines */ } } if (DK4_TSP_RES_OK != back) { *(lhoptr->backptr) = 0; } #line 1018 "dk-bmm.ctr" return back; } /** Read media file. @param filename Name of media file to read. @return 1 on success, 0 on error. */ static int dk_bmm_read_media_file(const dkChar *filename) { char inb[256]; dk4_tsp08_t tsp08; dk4_er_t er; dk_bmm_lh_obj_t obj; FILE *fipo = NULL; int c; int res; int cc = 1; int back = 0; #line 1041 "dk-bmm.ctr" obj.backptr = &back; fipo = dk4fopen_app(filename, dk_bmm_kwnl[4], DK4_FOPEN_SC_IS_REGULAR, app); if (NULL != fipo) { dk4error_init(&er); res = dk4tsp08_setup_line( &tsp08, &obj, dk_bmm_media_line_handler, inb, sizeof(inb), DK4_ENCODING_PLAIN, dk4app_get_file_in_encoding(app), &er ); if (0 != res) { back = 1; while (1 == cc) { if (0 != dk_bmm_can_continue()) { c = fgetc(fipo); if (EOF != c) { if (0 != feof(fipo)) { cc = 0; } res = dk4tsp08_add_one_byte(&tsp08, (unsigned char)c); switch (res) { case DK4_TSP_RES_ERROR: case DK4_TSP_RES_FATAL: { cc = -1; /* ERROR: Processing one byte failed */ } break; } } else { cc = 0; } } else { cc = -1; } } if (0 == cc) { res = dk4tsp08_finish(&tsp08); switch (res) { case DK4_TSP_RES_ERROR: case DK4_TSP_RES_FATAL: { back = 0; /* ERROR: Completing failed */ } break; } } else { back = 0; } } else { /* ERROR: Failed to set up line processing */ } fclose(fipo); } else { back = 1; } #line 1088 "dk-bmm.ctr" return back; } static void dk_bmm_show_current_media_number(void) { char buf[16*sizeof(dk4_um_t)]; int res; unsigned char uc; uc = dk_bmm_media_numbers[dk_bmm_day_in_cycle]; res = dk4ma_write_c8_decimal_unsigned( buf, sizeof(buf), (dk4_um_t)uc, 0, NULL ); if (0 != res) { if (EOF == fputs(buf, stdout)) { output_error = 1; } if (EOF == fputc('\n', stdout)) { output_error = 1; } fflush(stdout); } else { /* ERROR: Failed to convert number, bug as buffer size is large enough. */ exval = EXIT_FAILURE; } } static void dk_bmm_update_media_info(dk_bmm_media_t *mptr) { #if DK4_ON_WINDOWS SYSTEMTIME st; GetLocalTime(&st); mptr->year = st.wYear; mptr->month = st.wMonth; mptr->day = st.wDay; mptr->hour = st.wHour; mptr->minute = st.wMinute; mptr->second = st.wSecond; #else time_t timer; struct tm *tm; time(&timer); tm = localtime(&timer); if (NULL != tm) { mptr->year = 1900 + tm->tm_year; mptr->month = 1 + tm->tm_mon; mptr->day = tm->tm_mday; mptr->hour = tm->tm_hour; mptr->minute = tm->tm_min; mptr->second = tm->tm_sec; } #endif mptr->times += 1; } static int dk_bmm_switch_to_next(const dkChar *filename) { char buf[128]; FILE *fipo; size_t mediano; int tests; int res; int back = 0; #line 1160 "dk-bmm.ctr" mediano = (size_t)(dk_bmm_media_numbers[dk_bmm_day_in_cycle]); #line 1162 "dk-bmm.ctr" dk_bmm_update_media_info(&(media_info[mediano - 1])); if (++dk_bmm_day_in_cycle >= 200) { #line 1164 "dk-bmm.ctr" dk_bmm_day_in_cycle = 0; dk_bmm_cycle_completed = 1; for (mediano = 0; mediano < 10; mediano++) { media_info[mediano].times = 0; } } tests = DK4_FOPEN_SC_USER; if (1 == dk4isadmin()) { tests = DK4_FOPEN_SC_PRIVILEGED; } fipo = dk4fopen_app(filename, dk_bmm_kwnl[5], tests, app); if (NULL != fipo) { #line 1174 "dk-bmm.ctr" back = 1; res = dk4ma_write_c8_decimal_signed( buf, sizeof(buf), (dk4_im_t)dk_bmm_day_in_cycle, 0, NULL ); if (0 != res) { #line 1179 "dk-bmm.ctr" if (EOF == fputs(buf, fipo)) { back = 0; } if (EOF == fputc('\n', fipo)) { back = 0; } } else { back = 0; } for (mediano = 0; mediano < 10; mediano++) { res = dk4time_to_text_c8( buf, sizeof(buf), DK4_TIMEFORMAT_DATE_TIME, media_info[mediano].year, media_info[mediano].month, media_info[mediano].day, media_info[mediano].hour, media_info[mediano].minute, media_info[mediano].second, NULL ); if (0 != res) { #line 1196 "dk-bmm.ctr" if (EOF == fputs(buf, fipo)) { back = 0; } if (EOF == fputc(' ', fipo)) { back = 0; } res = dk4ma_write_c8_decimal_unsigned( buf, sizeof(buf), (dk4_um_t)(media_info[mediano].times), 0, NULL ); if (0 != res) { if (EOF == fputs(buf, fipo)) { back = 0; } } else { back = 0; } if (EOF == fputc('\n', fipo)) { back = 0; } } else { back = 0; } } if (0 != fclose(fipo)) { back = 0; } if (0 == back) { exval = EXIT_FAILURE; } } else { #line 1216 "dk-bmm.ctr" exval = EXIT_FAILURE; } #line 1218 "dk-bmm.ctr" return back; } /** Write a report of used media. */ static void dk_bmm_report_media(void) { dkChar b1[16*sizeof(dk4_um_t)]; dkChar b3[16*sizeof(dk4_um_t)]; char b2[128]; char *ptr; size_t i; size_t j; size_t mediano; int res; unsigned short nextlevel = 1; for (i = 0; i < 10; i++) { media_found[i] = 0; } if (0 < dk_bmm_day_in_cycle) { for (i = 0; i < (size_t)dk_bmm_day_in_cycle; i++) { j = (size_t)dk_bmm_day_in_cycle - 1 - i; mediano = (size_t)(dk_bmm_media_numbers[j]); if (0 == media_found[mediano - 1]) { media_found[mediano - 1] = nextlevel++; #line 1247 "dk-bmm.ctr" } } } for (i = (size_t)dk_bmm_day_in_cycle; i < 200; i++) { j = 199 - i; mediano = (size_t)(dk_bmm_media_numbers[j]); if (0 == media_found[mediano - 1]) { media_found[mediano - 1] = nextlevel++; #line 1256 "dk-bmm.ctr" } } dk_bmm_mod_stdout = 1; #line 1259 "dk-bmm.ctr" dk4fput_initialize_stdout(); res = dk4ma_write_decimal_unsigned( b1, DK4_SIZEOF(b1,dkChar), (dk4_um_t)(dk_bmm_media_numbers[dk_bmm_day_in_cycle]), 0, NULL ); if (0 != res) { if (0 == dk4fputs(dk_bmm_kw_def[7], stdout, NULL)) { output_error = 1; } if (0 == dk4fputs(b1, stdout, NULL)) { output_error = 1; } if (0 == dk4fputc(dkT('\n'), stdout, NULL)) { output_error = 1; } } else { /* ERROR: Number conversion failed, bug as buffer is large enough. */ exval = EXIT_FAILURE; } for (i = 1; i < 11; i++) { for (mediano = 1; mediano < 11; mediano++) { if (media_found[mediano - 1] == i) { res = dk4ma_write_decimal_unsigned( b1, DK4_SIZEOF(b1,dkChar), (dk4_um_t)mediano, 2, NULL ); if (0 != res) { res = dk4time_to_text_c8( b2, sizeof(b2), DK4_TIMEFORMAT_DATE_TIME, media_info[mediano - 1].year, media_info[mediano - 1].month, media_info[mediano - 1].day, media_info[mediano - 1].hour, media_info[mediano - 1].minute, media_info[mediano - 1].second, NULL ); if (0 != res) { res = dk4ma_write_decimal_unsigned( b3, DK4_SIZEOF(b3,dkChar), (dk4_um_t)(media_info[mediano - 1].times), 2, NULL ); if (0 != res) { if (0 == dk4fputs(b1, stdout, NULL)) { output_error = 1; } for (j = 0; j < 3; j++) { if (0 == dk4fputc(dkT(' '), stdout, NULL)) { output_error = 1; } } ptr = b2; while ('\0' != *ptr) { if (0 == dk4fputc((dkChar)(*(ptr++)), stdout, NULL)) { output_error = 1; } } for (j = 0; j < 3; j++) { if (0 == dk4fputc(dkT(' '), stdout, NULL)) { output_error = 1; } } if (0 == dk4fputs(b3, stdout, NULL)) { output_error = 1; } if (0 == media_info[mediano - 1].times) { if (0 == dk4fputs(dk_bmm_kw_def[6], stdout, NULL)) { output_error = 1; } } if (0 == dk4fputc(dkT('\n'), stdout, NULL)) { output_error = 1; } } else { /* ERROR: Number conversion failed, bug. */ exval = EXIT_FAILURE; } } else { /* ERROR: Date and time conversion failed, bug. */ exval = EXIT_FAILURE; } } else { /* ERROR: Number conversion failed, bug. */ exval = EXIT_FAILURE; } } } } } static void dk4_bmm_write_set_file(const dkChar *filename) { dkChar buf[16*sizeof(dk4_um_t)]; const dkChar *oldsourcefile; FILE *fipo = NULL; dk4_um_t oldsourceline; size_t i; int res; int we = 0; int tests = DK4_FOPEN_SC_USER; #line 1351 "dk-bmm.ctr" if (1 == dk4isadmin()) { tests = DK4_FOPEN_SC_PRIVILEGED; } fipo = dk4fopen_app(filename, dk_bmm_kwnl[5], tests, app); if (NULL != fipo) { #line 1354 "dk-bmm.ctr" dk4fput_initialize_file(fipo); for (i = 0; i < dk_bmm_n_set_names; i++) { if (0 != i) { if (0 == dk4fputc(dkT(' '), fipo, NULL)) { we = 1; #line 1359 "dk-bmm.ctr" } } if (0 == dk4fputs(dk_bmm_set_names[i], fipo, NULL)) { we = 1; #line 1363 "dk-bmm.ctr" } } if (0 == dk4fputc(dkT('\n'), fipo, NULL)) { #line 1366 "dk-bmm.ctr" we = 1; } res = dk4ma_write_decimal_unsigned( buf, DK4_SIZEOF(buf,dkChar), (dk4_um_t)dk_bmm_day_in_cycle, 0, NULL ); if (0 != res) { if (0 == dk4fputs(buf, fipo, NULL)) { #line 1373 "dk-bmm.ctr" we = 1; } if (0 == dk4fputc(dkT('\n'), fipo, NULL)) { #line 1376 "dk-bmm.ctr" we = 1; } } else { #line 1379 "dk-bmm.ctr" /* ERROR: Number conversion failed, bug */ exval = EXIT_FAILURE; } if (0 != fclose(fipo)) { #line 1383 "dk-bmm.ctr" we = 1; } if (0 != we) { /* ERROR: Writing to file failed */ oldsourcefile = dk4app_get_log_source_file(app); oldsourceline = dk4app_get_log_source_line(app); dk4app_set_log_source_file(app, filename); dk4app_set_log_source_line(app, (dk4_um_t)0UL); dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 12); dk4app_set_log_source_file(app, oldsourcefile); dk4app_set_log_source_line(app, oldsourceline); exval = EXIT_FAILURE; } } else { exval = EXIT_FAILURE; } #line 1400 "dk-bmm.ctr" } #if DK4_CHAR_SIZE > 1 /** Check whether a string can be written using 8 bit character width. @param str String to test. @return 1 on success, 0 on error. */ static int dk_bmm_can_write_8bit(const dkChar *str) { #if DK4_CHAR_SIZE > 1 #if DK4_CHAR_SIZE > 2 int back = 1; #line 1418 "dk-bmm.ctr" while ((dkT('\0') != *str) && (1 == back)) { if (dkC32(0xFF) < *str) { back = 0; } str++; } #line 1424 "dk-bmm.ctr" return back; #else dk4_utf16_decoder_t dec; dk4_c32_t c32; int back = 1; #line 1430 "dk-bmm.ctr" dk4utf16_init(&dec); while((dkT('\0') != *str) && (1 == back)) { switch (dk4utf16_add(&dec, *str)) { case DK4_EDSTM_FINISHED: { c32 = dk4utf16_get(&dec); if (dkC32(0x7F) < c32) { back = 0; } } break; case DK4_EDSTM_ERROR: { back = 0; } break; } str++; } if (1 == back) { if (0 == dk4utf16_is_empty(&dec)) { back = 0; } } #line 1448 "dk-bmm.ctr" return back; #endif #else #line 1452 "dk-bmm.ctr" return 1; #endif } /** Write string using 8 bit character functions. @param str String to write. */ static void dk_bmm_write_8bit(const dkChar *str) { #if DK4_CHAR_SIZE > 2 #line 1467 "dk-bmm.ctr" while (dkT('\0') != *str) { if (EOF == fputc((char)((unsigned char)(*(str++))), stdout)) { output_error = 1; } } $$? "- dk_bmm_write_8bit" #else dk4_utf16_decoder_t dec; dk4_c32_t c32; int back = 1; #line 1477 "dk-bmm.ctr" dk4utf16_init(&dec); while((dkT('\0') != *str) && (1 == back)) { switch (dk4utf16_add(&dec, *str)) { case DK4_EDSTM_FINISHED: { c32 = dk4utf16_get(&dec); if (dkC32(0xF0) > c32) { if (EOF == fputc((char)((unsigned char)c32), stdout)) { output_error = 1; back = 0; } } } break; case DK4_EDSTM_ERROR: { back = 0; } break; } str++; } #line 1495 "dk-bmm.ctr" #endif } #endif /** Write current media set name to stdout. */ static void dk_bmm_write_set_name(void) { const dkChar *sn = NULL; #line 1510 "dk-bmm.ctr" if ((dk4_um_t)dk_bmm_day_in_cycle < (dk4_um_t)dk_bmm_n_set_names) { sn = dk_bmm_set_names[(size_t)dk_bmm_day_in_cycle]; } if (NULL != sn) { #if DK4_CHAR_SIZE > 1 #line 1516 "dk-bmm.ctr" if (0 != dk_bmm_can_write_8bit(sn)) { #line 1517 "dk-bmm.ctr" dk_bmm_write_8bit(sn); if (EOF == fputc('\n', stdout)) { output_error = 1; } } else { #line 1520 "dk-bmm.ctr" dk_bmm_mod_stdout = 1; #line 1521 "dk-bmm.ctr" dk4fput_initialize_stdout(); if (0 == dk4fputs(sn, stdout, NULL)) { output_error = 1; } if (0 == dk4fputc(dkT('\n'), stdout, NULL)) { output_error = 1; } } #else #line 1527 "dk-bmm.ctr" if (EOF == fputs(sn, stdout)) { output_error = 1; } if (EOF == fputc('\n', stdout)) { output_error = 1; } #endif fflush(stdout); } #line 1533 "dk-bmm.ctr" } /** Process the specified file. @param filename Name of file to process. */ static void dk_bmm_run_for_file(const dkChar *filename) { const dkChar *oldsourcefile; dk4_um_t oldsourceline; #line 1547 "dk-bmm.ctr" if (0 != dk_bmm_handle_set) { if (0 != dk_bmm_do_report) { /* ERROR: Option -r not available for sets */ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 8); } else { if (0 != dk_bmm_read_sets_file(filename)) { if (0 != dk_bmm_do_confirm) { /* TODO: Confirm current media set */ exval = EXIT_SUCCESS; dk_bmm_day_in_cycle++; if (0 > dk_bmm_day_in_cycle) { dk_bmm_day_in_cycle = 0; } if ((dk4_um_t)dk_bmm_day_in_cycle >= (dk4_um_t)dk_bmm_n_set_names) { dk_bmm_day_in_cycle = 0; } dk4_bmm_write_set_file(filename); dk_bmm_write_set_name(); } else { exval = EXIT_SUCCESS; dk_bmm_write_set_name(); } } else { /* ERROR: Not a set file name */ oldsourcefile = dk4app_get_log_source_file(app); oldsourceline = dk4app_get_log_source_line(app); dk4app_set_log_source_file(app, filename); dk4app_set_log_source_line(app, (dk4_um_t)0UL); dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 13); dk4app_set_log_source_file(app, oldsourcefile); dk4app_set_log_source_line(app, oldsourceline); } } } else { dk_bmm_initialize_media_info(); if (dk_bmm_read_media_file(filename)) { if (0 != dk_bmm_do_report) { exval = EXIT_SUCCESS; dk_bmm_report_media(); } else { if (0 != dk_bmm_do_confirm) { exval = EXIT_SUCCESS; dk_bmm_switch_to_next(filename); dk_bmm_show_current_media_number(); } else { exval = EXIT_SUCCESS; dk_bmm_show_current_media_number(); } } } else { /* ERROR: Failed to read file, probably not a dk-bmm file. */ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 9); } } #line 1600 "dk-bmm.ctr" } #if DK4_ON_WINDOWS static int dk_bmm_expand_pattern(const dkChar *pattern) { dkChar buf[DK4_MAX_PATH]; dk4_dir_t *fne; const dkChar *shf; const dkChar *pth; int back = 0; #line 1616 "dk-bmm.ctr" fne = dk4app_fne_open(pattern, app); if (NULL != fne) { shf = dk4dir_next_file(fne); if (NULL != shf) { if (NULL == dk4dir_next_file(fne)) { 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_bmm_kwnl[3],NULL)) { if(0 != dk4str_cat_s(buf, DK4_SIZEOF(buf,dkChar), shf, NULL)) { dk_bmm_run_for_file(buf); } else { /* ERROR: Path too long */ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth); } } else { /* ERROR: Path too long */ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth); } } else { /* ERROR: Path too long */ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth); } } else { dk_bmm_run_for_file(shf); } } else { /* ERROR: Multiple files */ dk4app_log_base3(app, DK4_LL_ERROR, 100, 106, pattern); } } else { /* ERROR: No file found */ dk4app_log_base3(app, DK4_LL_ERROR, 100, 107, pattern); } dk4dir_close(fne); } #line 1654 "dk-bmm.ctr" return back; } #endif /** Run after installing signal handlers. */ static void dk_bmm_normal_run(void) { const dkChar *xargv; #line 1669 "dk-bmm.ctr" if (0 != dk4app_opt_is_set_short(app, dkT('c'), NULL)) { dk_bmm_do_confirm = 1; } if (0 != dk4app_opt_is_set_short(app, dkT('r'), NULL)) { dk_bmm_do_report = 1; } if (0 != dk4app_opt_is_set_short(app, dkT('s'), NULL)) { dk_bmm_handle_set = 1; } if (dk4app_get_argc(app) == 1) { xargv = dk4app_get_argv(app, 0); if (NULL != xargv) { #if DK4_ON_WINDOWS if (0 != dk4path_must_expand(xargv)) { dk_bmm_expand_pattern(xargv); } else { #endif dk_bmm_run_for_file(xargv); #if DK4_ON_WINDOWS } #endif } else { /* ERROR: Exactly one file allowed! */ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 10); } } else { /* ERROR: Exactly one file allowed! */ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 10); } #line 1699 "dk-bmm.ctr" } #if DK4_HAVE_SIGACTION /** Set signal handlers and run. */ static void dk_bmm_run_with_signal_handlers(void) { #ifdef SIGPIPE struct sigaction opipe; #endif struct sigaction oint; #ifdef SIGPIPE struct sigaction npipe; #endif struct sigaction nint; struct sigaction oterm; struct sigaction nterm; int success = 0; #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)) { /* ERROR: Failed to set up masked signal set for SIGPIPE */ dk4app_log_1(app, dk_bmm_msg, dk_bmm_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_bmm_msg, dk_bmm_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_bmm_msg, dk_bmm_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)) { /* ERROR: Failed to set up masked signal set for SIGINT */ dk4app_log_1(app, dk_bmm_msg, dk_bmm_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_bmm_msg, dk_bmm_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_bmm_msg, dk_bmm_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)) { /* ERROR: Failed to set up masked signal set for SIGTERM */ dk4app_log_1(app, dk_bmm_msg, dk_bmm_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_bmm_msg, dk_bmm_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_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 0); goto restore_old_int; } success = 1; dk_bmm_normal_run(); /* Restore signal handling for SIGTERM. */ if (0 != sigaction(SIGTERM, &oterm, NULL)) { /* ERROR: Failed to restore old SIGTERM settings */ dk4app_log_1(app, dk_bmm_msg, dk_bmm_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_bmm_msg, dk_bmm_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_bmm_msg, dk_bmm_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_bmm_run_with_signal_handlers(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, sig_handler_pipe); #endif oldint = sigset(SIGINT, sig_handler_int); oldterm = sigset(SIGTERM, sig_handler_term); dk_bmm_normal_run(); 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_bmm_run_with_signal_handlers(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, sig_handler_pipe); #endif oldint = signal(SIGINT, sig_handler_int); oldterm = signal(SIGTERM, sig_handler_term); dk_bmm_normal_run(); signal(SIGTERM, oldterm); signal(SIGINT, oldint); #ifdef SIGPIPE signal(SIGPIPE, oldpipe); #endif } #else /** Set signal handlers and run. */ static void dk_bmm_run_with_signal_handlers(void) { dk_bmm_normal_run(); } #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 oldstdlevel; int oldfilelevel; #line 1904 "dk-bmm.ctr" #line 1905 "dk-bmm.ctr" dk4fput_initialize_stderr(); app = dk4app_open_cmd( argc, argv, dk_bmm_options, dk_bmm_sz_options, dk_bmm_kwnl[0], DKT_VERSION_DK, dk_bmm_kwnl[1], dk_bmm_help_text, dk_bmm_license_text ); if (NULL != app) { dk_bmm_sz_msg = dk4app_string_table_size(dk_bmm_kw_def); dk_bmm_msg = dk4app_string_table(app, dk_bmm_kwnl[2], dk_bmm_kw_def); if (0 != dk4app_can_run_normally(app)) { dk_bmm_run_with_signal_handlers(); if (0 != dk_bmm_cycle_completed) { /* INFO: Cycle completed, change media set */ oldstdlevel = app->ll_stderr; oldfilelevel = app->ll_file; app->ll_file = DK4_LL_INFO; app->ll_stderr = DK4_LL_INFO; dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_INFO, 11); app->ll_file = oldfilelevel; app->ll_stderr = oldstdlevel; } if (0 != output_error) { dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 2); exval = EXIT_FAILURE; } #ifdef SIGPIPE if (0 != sig_read_atomic(&sig_had_pipe)) { dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 3); exval = EXIT_FAILURE; } #endif if (0 != sig_read_atomic(&sig_had_term)) { dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 5); exval = EXIT_FAILURE; } if (0 != sig_read_atomic(&sig_had_int)) { dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 4); exval = EXIT_FAILURE; } } else { dk4fput_initialize_stdout(); dk_bmm_mod_stdout = 1; #line 1947 "dk-bmm.ctr" if (0 != dk4app_help_version_license(app)) { exval = EXIT_SUCCESS; } } dk4app_close(app); app = NULL; } fflush(stdout); fflush(stderr); dk4fput_cleanup_stderr(); if (0 != dk_bmm_mod_stdout) { dk4fput_cleanup_stdout(); } #line 1960 "dk-bmm.ctr" #line 1961 "dk-bmm.ctr" exit(exval); return exval; }