/* WARNING: This file was generated by dkct. Changes you make here will be lost if dkct is run again! You should modify the original source and run dkct on it. Original source: dk-bmm.ctr */ /* Copyright (C) 2015-2017, Dirk Krause Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above opyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @file 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" #line 131 "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://dktools.sourceforge.net"), dkT(""), NULL #line 184 "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://dktools.sourceforge.net/ for 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("* Redistributions of source code must retain the above copyright notice,"), dkT(" this list of conditions and the following disclaimer."), dkT("* 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("* Neither the name of the Dirk Krause nor the names of contributors may be"), dkT(" used to endorse or promote products derived from this software without"), dkT(" specific prior written permission."), dkT(""), dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""), dkT("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"), dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"), dkT("ARE DISCLAIMED."), dkT(""), dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,"), dkT("INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,"), dkT("BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,"), dkT("DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY"), dkT("OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"), dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,"), dkT("EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."), #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 316 "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 367 "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 432 "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 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; } /** 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 *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 722 "dk-bmm.ctr" lhoptr = (dk_bmm_lh_obj_t *)obj; if ((dk4_um_t)1UL == lineno) { #line 724 "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 739 "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 > dk_bmm_day_in_cycle) { back = DK4_TSP_RES_OK; } } } } else { back = DK4_TSP_RES_OK; } } else { #line 759 "dk-bmm.ctr" } } if ((DK4_TSP_RES_FATAL == back) || (DK4_TSP_RES_ERROR == back)) { *(lhoptr->backptr) = 0; } #line 764 "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 786 "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 832 "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 865 "dk-bmm.ctr" if (21 > dk4str8_len(line)) { #line 867 "dk-bmm.ctr" goto finished; } if ('-' != line[4]) { #line 871 "dk-bmm.ctr" goto finished; } line[4] = '\0'; if ('-' != line[7]) { #line 876 "dk-bmm.ctr" goto finished; } line[7] = '\0'; if (' ' != line[10]) { #line 881 "dk-bmm.ctr" goto finished; } line[10] = '\0'; if (':' != line[13]) { #line 886 "dk-bmm.ctr" goto finished; } line[13] = '\0'; if (':' != line[16]) { #line 891 "dk-bmm.ctr" goto finished; } line[16] = '\0'; if (' ' != line[19]) { #line 896 "dk-bmm.ctr" goto finished; } line[19] = '\0'; ep = NULL; if (0 == dk4ma_input_c8_dec_ushort(&(mptr->year), line, &ep, 0, NULL)) { #line 902 "dk-bmm.ctr" goto finished; } if (0 == dk4ma_input_c8_dec_ushort(&(mptr->month),&(line[5]),&ep,0,NULL)) { #line 906 "dk-bmm.ctr" goto finished; } if (0 == dk4ma_input_c8_dec_ushort(&(mptr->day),&(line[8]),&ep,0,NULL)) { #line 910 "dk-bmm.ctr" goto finished; } if (0 == dk4ma_input_c8_dec_ushort(&(mptr->hour),&(line[11]),&ep,0,NULL)) { #line 914 "dk-bmm.ctr" goto finished; } if (0 == dk4ma_input_c8_dec_ushort(&(mptr->minute),&(line[14]),&ep,0,NULL)) { #line 918 "dk-bmm.ctr" goto finished; } if (0 == dk4ma_input_c8_dec_ushort(&(mptr->second),&(line[17]),&ep,0,NULL)) { #line 922 "dk-bmm.ctr" goto finished; } if (0 == dk4ma_input_c8_dec_ushort(&(mptr->times),(&line[20]),&ep,0,NULL)) { #line 926 "dk-bmm.ctr" goto finished; } back = 1; finished: #line 931 "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 *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 964 "dk-bmm.ctr" lhoptr = (dk_bmm_lh_obj_t *)obj; dk4str8_delnl(line); if ((dk4_um_t)1UL == lineno) { #line 967 "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 988 "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 994 "dk-bmm.ctr" /* ERROR: Syntax, too many lines */ } } if (DK4_TSP_RES_OK != back) { *(lhoptr->backptr) = 0; } #line 999 "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 1022 "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_ASCII, 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 1069 "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 1141 "dk-bmm.ctr" mediano = (size_t)(dk_bmm_media_numbers[dk_bmm_day_in_cycle]); #line 1143 "dk-bmm.ctr" dk_bmm_update_media_info(&(media_info[mediano - 1])); if (++dk_bmm_day_in_cycle >= 200) { #line 1145 "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 1155 "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 1160 "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 1177 "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 1197 "dk-bmm.ctr" exval = EXIT_FAILURE; } #line 1199 "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 1228 "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 1237 "dk-bmm.ctr" } } dk_bmm_mod_stdout = 1; #line 1240 "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 1332 "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 1335 "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 1340 "dk-bmm.ctr" } } if (0 == dk4fputs(dk_bmm_set_names[i], fipo, NULL)) { we = 1; #line 1344 "dk-bmm.ctr" } } if (0 == dk4fputc(dkT('\n'), fipo, NULL)) { #line 1347 "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 1354 "dk-bmm.ctr" we = 1; } if (0 == dk4fputc(dkT('\n'), fipo, NULL)) { #line 1357 "dk-bmm.ctr" we = 1; } } else { #line 1360 "dk-bmm.ctr" /* ERROR: Number conversion failed, bug */ exval = EXIT_FAILURE; } if (0 != fclose(fipo)) { #line 1364 "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 1381 "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 1399 "dk-bmm.ctr" while ((dkT('\0') != *str) && (1 == back)) { if (dkC32(0xFF) < *str) { back = 0; } str++; } #line 1405 "dk-bmm.ctr" return back; #else dk4_utf16_decoder_t dec; dk4_c32_t c32; int back = 1; #line 1411 "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 1429 "dk-bmm.ctr" return back; #endif #else #line 1433 "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 1448 "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 1458 "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 1476 "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 1491 "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 1497 "dk-bmm.ctr" if (0 != dk_bmm_can_write_8bit(sn)) { #line 1498 "dk-bmm.ctr" dk_bmm_write_8bit(sn); if (EOF == fputc('\n', stdout)) { output_error = 1; } } else { #line 1501 "dk-bmm.ctr" dk_bmm_mod_stdout = 1; #line 1502 "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 1508 "dk-bmm.ctr" if (EOF == fputs(sn, stdout)) { output_error = 1; } if (EOF == fputc('\n', stdout)) { output_error = 1; } #endif fflush(stdout); } #line 1514 "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 1528 "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 1581 "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 1597 "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 1635 "dk-bmm.ctr" return back; } #endif /** Run after installing signal handlers. */ static void dk_bmm_normal_run(void) { const dkChar *xargv; #line 1650 "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 1680 "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 1885 "dk-bmm.ctr" #line 1886 "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 1928 "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 1941 "dk-bmm.ctr" #line 1942 "dk-bmm.ctr" exit(exval); return exval; }