1%% options 2 3copyright owner = Dirk Krause 4copyright year = 2016-xxxx 5SPDX-License-Identifier: BSD-3-Clause 6 7 8 9%% module 10 11/* 12 Convert text to database. 13 14 See help_text below. 15*/ 16 17#include "dk4conf.h" 18 19#include <stdio.h> 20 21#if DK4_HAVE_STDLIB_H 22#ifndef STDLIB_H_INCLUDED 23#include <stdlib.h> 24#define STDLIB_H_INCLUDED 1 25#endif 26#endif 27 28#if DK4_HAVE_UNISTD_H 29#ifndef UNISTD_H_INCLUDED 30#include <unistd.h> 31#define UNISTD_H_INCLUDED 1 32#endif 33#endif 34 35#if DK4_HAVE_PROCESS_H 36#ifndef PROCESS_H_INCLUDED 37#include <process.h> 38#define PROCESS_H_INCLUDED 1 39#endif 40#endif 41 42#if DK4_HAVE_IO_H 43#ifndef IO_H_INCLUDED 44#include <io.h> 45#define IO_H_INCLUDED 1 46#endif 47#endif 48 49#if DK4_HAVE_FCNTL_H 50#ifndef FCNTL_H_INCLUDED 51#include <fcntl.h> 52#define FCNTL_H_INCLUDED 1 53#endif 54#endif 55 56#if DK4_HAVE_SYS_TYPES_H 57#ifndef SYS_TYPES_H_INCLUDED 58#include <sys/types.h> 59#define SYS_TYPES_H_INCLUDED 1 60#endif 61#endif 62 63#if DK4_HAVE_SIGNAL_H 64#ifndef SIGNAL_H_INCLUDED 65#include <signal.h> 66#define SIGNAL_H_INCLUDED 1 67#endif 68#endif 69 70#include <libdk4base/dk4const.h> 71#include <libdk4base/dk4mem.h> 72#include <libdk4app/dk4mema.h> 73#include <libdk4base/dk4error.h> 74#include <libdk4dbi/dk4dbi.h> 75#include <libdk4dbi/dk4dbit8.h> 76#include <libdk4dbi/dk4dbitw.h> 77#include <libdk4dbi/dk4dbit.h> 78#include <libdk4dbia/dk4dbia.h> 79#include <libdk4c/dk4fput.h> 80#include <libdk4base/dk4vers.h> 81#include <libdk4app/dk4app.h> 82#include <libdk4app/dk4aopt.h> 83#include <libdk4ma/dk4maasz.h> 84#include <libdk4c/dk4enc.h> 85#include <libdk4c/dk4fopt.h> 86#include <libdk4app/dk4fopda.h> 87#include <libdk4c/dk4tspdk.h> 88#include <libdk4base/dk4strd.h> 89#include <libdk4maiodd/dk4maodd.h> 90#include <libdk4base/dk4mpl.h> 91#include <libdk4c/dk4pathd.h> 92#include <libdk4base/dk4unused.h> 93 94#ifndef DK4WMAIN_H_INCLUDED 95#include <libdk4base/dk4wmain.h> 96#endif 97 98 99$!trace-include 100 101 102 103static const dkChar * const help_text[] = { 104$!text macro=dkT 105 106dk-t2db - Convert text to simple database 107----------------------------------------- 108 109dk-t2db [<option>] [<file>...] <database> 110 111Options: 112 113-a --add Append to existing database. 114-l <size> --line-size=<size> Line buffer size. 115-k <size> --key-buffer-size=<size> Key buffer size. 116-v <size> --value-buffer-size=<size> Value buffer size. 117-i <string> --input-encoding=<string> Expected input encoding. 118 119--help Show short help text. 120--manual *** SHOW FULL MANUAL *** 121--version Show version information. 122--license Show license information. 123 124$!end 125}; 126 127 128/** License conditions. 129*/ 130static const dkChar * const license_text[] = { 131$!text macro=dkT,preprocessor 132 133This software uses code from the following projects, either directly or as 134a library: 135 136dktools Dirk Krause's tools and libraries. 137 See http://sourceforge.net/p/dktools/wiki/Home/ 138 for more information. 139#if DK4_HAVE_ZLIB_H 140 141zlib Data compression library. 142 See http://www.zlib.net/ for more information. 143#endif 144#if DK4_HAVE_BZLIB_H 145 146bzip2 Data compression program and library. 147 See http://www.bzip.org/ for more information. 148#endif 149 150All the licenses below apply to the program. 151Licenses for used libraries are shown as found on my Scientific Linux 6.x 152computer in the /usr/share/doc directory on 2015-04-01. Check the project 153homepages of the used libraries for additional information and/or updated 154license terms. 155 156 157DK tools and libraries license 158============================== 159Copyright (c) 2016, Dirk Krause 160All rights reserved. 161 162Redistribution and use in source and binary forms, with or without 163modification, are permitted provided that the following conditions are met: 164 1651. Redistributions of source code must retain the above copyright notice, 166 this list of conditions and the following disclaimer. 1672. Redistributions in binary form must reproduce the above copyright 168 notice, this list of conditions and the following disclaimer in the 169 documentation and/or other materials provided with the distribution. 1703. Neither the name of the copyright holder nor the names of its 171 contributors may be used to endorse or promote products derived from 172 this software without specific prior written permission. 173 174THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 175``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 176LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 177A PARTICULAR PURPOSE ARE DISCLAIMED. 178IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY 179DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 180(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 181SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 182CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 183LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 184OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 185SUCH DAMAGE. 186#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1) 187 188 189Berkeley DB license 190=================== 191This package was debianized by Clint Adams <schizo@debian.org> on 192Wed, 25 Jul 2007 20:37:51 +0700 193 194It was downloaded from 195http://www.oracle.com/technology/software/products/berkeley-db/db/index.html 196 197Copyright and license: 198 199The following is the license that applies to this copy of the Berkeley DB 200software. For a license to use the Berkeley DB software under conditions 201other than those described here, or to purchase support for this software, 202please contact Oracle at berkeleydb-info_us@oracle.com. 203 204=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 205/* 206 * Copyright (c) 1990, 2010 Oracle and/or its affiliates. All rights reserved. 207 * 208 * Redistribution and use in source and binary forms, with or without 209 * modification, are permitted provided that the following conditions 210 * are met: 211 * 1. Redistributions of source code must retain the above copyright 212 * notice, this list of conditions and the following disclaimer. 213 * 2. Redistributions in binary form must reproduce the above copyright 214 * notice, this list of conditions and the following disclaimer in the 215 * documentation and/or other materials provided with the distribution. 216 * 3. Redistributions in any form must be accompanied by information on 217 * how to obtain complete source code for the DB software and any 218 * accompanying software that uses the DB software. The source code 219 * must either be included in the distribution or be available for no 220 * more than the cost of distribution plus a nominal fee, and must be 221 * freely redistributable under reasonable conditions. For an 222 * executable file, complete source code means the source code for all 223 * modules it contains. It does not include source code for modules or 224 * files that typically accompany the major components of the operating 225 * system on which the executable file runs. 226 * 227 * THIS SOFTWARE IS PROVIDED BY ORACLE ``AS IS'' AND ANY EXPRESS OR 228 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 229 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR 230 * NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL ORACLE BE LIABLE 231 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 232 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 233 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 234 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 235 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 236 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 237 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 238 */ 239/* 240 * Copyright (c) 1990, 1993, 1994, 1995 241 * The Regents of the University of California. All rights reserved. 242 * 243 * Redistribution and use in source and binary forms, with or without 244 * modification, are permitted provided that the following conditions 245 * are met: 246 * 1. Redistributions of source code must retain the above copyright 247 * notice, this list of conditions and the following disclaimer. 248 * 2. Redistributions in binary form must reproduce the above copyright 249 * notice, this list of conditions and the following disclaimer in the 250 * documentation and/or other materials provided with the distribution. 251 * 3. Neither the name of the University nor the names of its contributors 252 * may be used to endorse or promote products derived from this software 253 * without specific prior written permission. 254 * 255 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 256 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 257 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 258 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 259 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 260 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 261 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 262 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 263 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 264 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 265 * SUCH DAMAGE. 266 */ 267/* 268 * Copyright (c) 1995, 1996 269 * The President and Fellows of Harvard University. All rights reserved. 270 * 271 * Redistribution and use in source and binary forms, with or without 272 * modification, are permitted provided that the following conditions 273 * are met: 274 * 1. Redistributions of source code must retain the above copyright 275 * notice, this list of conditions and the following disclaimer. 276 * 2. Redistributions in binary form must reproduce the above copyright 277 * notice, this list of conditions and the following disclaimer in the 278 * documentation and/or other materials provided with the distribution. 279 * 3. Neither the name of the University nor the names of its contributors 280 * may be used to endorse or promote products derived from this software 281 * without specific prior written permission. 282 * 283 * THIS SOFTWARE IS PROVIDED BY HARVARD AND ITS CONTRIBUTORS ``AS IS'' AND 284 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 285 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 286 * ARE DISCLAIMED. IN NO EVENT SHALL HARVARD OR ITS CONTRIBUTORS BE LIABLE 287 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 288 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 289 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 290 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 292 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 293 * SUCH DAMAGE. 294 */ 295=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 296/*** 297 * ASM: a very small and fast Java bytecode manipulation framework 298 * Copyright (c) 2000-2005 INRIA, France Telecom 299 * All rights reserved. 300 * 301 * Redistribution and use in source and binary forms, with or without 302 * modification, are permitted provided that the following conditions 303 * are met: 304 * 1. Redistributions of source code must retain the above copyright 305 * notice, this list of conditions and the following disclaimer. 306 * 2. Redistributions in binary form must reproduce the above copyright 307 * notice, this list of conditions and the following disclaimer in the 308 * documentation and/or other materials provided with the distribution. 309 * 3. Neither the name of the copyright holders nor the names of its 310 * contributors may be used to endorse or promote products derived from 311 * this software without specific prior written permission. 312 * 313 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 314 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 315 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 316 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 317 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 318 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 319 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 320 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 321 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 322 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 323 * THE POSSIBILITY OF SUCH DAMAGE. 324 */ 325#endif 326#if DK4_HAVE_ZLIB_H 327 328 329Zlib license 330============ 331(C) 1995-2004 Jean-loup Gailly and Mark Adler 332 333This software is provided 'as-is', without any express or implied 334warranty. In no event will the authors be held liable for any damages 335arising from the use of this software. 336 337Permission is granted to anyone to use this software for any purpose, 338including commercial applications, and to alter it and redistribute it 339freely, subject to the following restrictions: 340 3411. The origin of this software must not be misrepresented; you must not 342 claim that you wrote the original software. If you use this software 343 in a product, an acknowledgment in the product documentation would be 344 appreciated but is not required. 3452. Altered source versions must be plainly marked as such, and must not be 346 misrepresented as being the original software. 3473. This notice may not be removed or altered from any source distribution. 348 349Jean-loup Gailly Mark Adler 350jloup@gzip.org madler@alumni.caltech.edu 351#endif 352#if DK4_HAVE_BZLIB_H 353 354 355Bzip2 and libbzip2 library license 356================================== 357This program, "bzip2", the associated library "libbzip2", and all 358documentation, are copyright (C) 1996-2007 Julian R Seward. All 359rights reserved. 360 361Redistribution and use in source and binary forms, with or without 362modification, are permitted provided that the following conditions 363are met: 364 3651. Redistributions of source code must retain the above copyright 366 notice, this list of conditions and the following disclaimer. 367 3682. The origin of this software must not be misrepresented; you must 369 not claim that you wrote the original software. If you use this 370 software in a product, an acknowledgment in the product 371 documentation would be appreciated but is not required. 372 3733. Altered source versions must be plainly marked as such, and must 374 not be misrepresented as being the original software. 375 3764. The name of the author may not be used to endorse or promote 377 products derived from this software without specific prior written 378 permission. 379 380THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 381OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 382WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 383ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 384DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 385DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 386GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 387INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 388WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 389NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 390SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 391 392Julian Seward, jseward@bzip.org 393bzip2/libbzip2 version 1.0.5 of 10 December 2007 394#endif 395$!end 396}; 397 398 399 400/** Version text. 401*/ 402static const dkChar version_text[] = { 403 DKT_VERSION_DK 404#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1) 405 dkT(" bdb") 406#endif 407#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1) 408 dkT(" ndbm") 409#endif 410 dkT(" mem") 411}; 412 413 414 415/** Constant texts used by the module, not localized. 416*/ 417const dkChar * const dk_t2db_kwnl[] = { 418$!string-table macro=dkT 419# 420# 0 Program group name 421# 422dktools 423# 424# 1 Help text file name 425# 426dk-t2db.txt 427# 428# 2 Error message: Application startup failed! 429# 430ERROR: Application startup failed!\n 431# 432# 3 String table file name 433# 434dk-t2db.str 435# 436# 4 5 6 Preference names for buffer sizes 437# 438line.size 439text-db.key.max-size 440text-db.value.max-size 441# 442# 7 File open mode for binary reading 443# 444rb 445# 446# 8 Path component separator 447# 448\\ 449$!end 450}; 451 452 453 454/** Constant string used by the module, replaced by localized 455 texts if available. 456*/ 457const dkChar * const dk_t2db_kw_def[] = { 458$!string-table macro=dkT 459# 460# 0 Error: Failed to set up signal handlers! 461# 462Failed to set up signal handlers! 463# 464# 1 Error: Failed to restore previous signal handlers! 465# 466Failed to restore previous signal handlers! 467# 468# 2 Default file name to be used for standard input. 469# 470<standard input> 471# 472# 3 4 5 Error: Failed to set database entry "key"="value"! 473# 474Failed to set database entry\n" 475"=" 476"! 477# 478# 6 7 Error: Failed to delete database entry "key"! 479# 480Failed to delete database entry\n" 481"! 482# 483# 8 9 10 11 12 13 484# 485Decoding failed! 486Encoding failed! 487Processing failed! 488Further decoding failures! 489Further encoding failures! 490Further processing failures! 491# 492# 14 15 16 17 18 19 493# 494Decoding failed!\n\tByte: 495Encoding failed!\n\tByte: 496Processing failed!\n\tByte: 497,\n\tCharacter: 498,\n\tPosition in line: 499. 500# 501# 20 ERROR: Failed to read from file! 502# 503Failed to read from file! 504# 505# 21 ERROR: Failed to set up text stream processor! 506# 507Failed to set up text stream processor! 508# 509# 22 23 ERROR: Path too long for pattern "..."! 510# 511Path too long for pattern\n" 512"! 513# 514# 24 25 ERROR: No such file "..."! 515# 516No such file:\n" 517"! 518# 519# 26 ERROR: Failed to close database! 520# 521Failed to close database! 522# 523# 27 ERROR: Database name is required! 524# 525Database name is required! 526# 527# 28 29 ERROR: Illegal text encoding "..."! 528# 529Illegal text encoding: " 530"! 531# 532# 30 ERROR: Aborted by signal 533# 534Aborted by signal! 535$!end 536}; 537 538 539 540/** Options. 541*/ 542static const dk4_option_specification_t dk_t2db_options[] = { 543 { dkT('a'), dkT("add"), DK4_OPT_ARG_NONE } , 544 { dkT('R'), dkT("reset"), DK4_OPT_ARG_NONE } , 545 { dkT('l'), dkT("line-size"), DK4_OPT_ARG_SIZE } , 546 { dkT('k'), dkT("key-buffer-size"), DK4_OPT_ARG_SIZE } , 547 { dkT('v'), dkT("value-buffer-size"), DK4_OPT_ARG_SIZE } , 548 { dkT('i'), dkT("input-encoding"), DK4_OPT_ARG_STRING } , 549 { dkT('c'), dkT("comment"), DK4_OPT_ARG_STRING } 550}; 551 552 553 554/** Input line buffer. 555*/ 556static dkChar linebuf[1024]; 557 558 559 560/** Localized or default messages. 561*/ 562static const dkChar * const * dk_t2db_msg = dk_t2db_kw_def; 563 564 565 566/** Pointer to input buffer to use. 567*/ 568static dkChar *pibuf = linebuf; 569 570 571 572/** Allocated input buffer, if necessary. 573*/ 574static dkChar *abuf = NULL; 575 576 577 578/** Application structure. 579*/ 580static dk4_app_t *app = NULL; 581 582 583 584/** String containing the comment character. 585*/ 586static const dkChar *comment = NULL; 587 588 589 590 591/** Number of elements in the dk_t2db_options array. 592*/ 593static const size_t dk_t2db_sz_options = 594sizeof(dk_t2db_options)/sizeof(dk4_option_specification_t); 595 596 597 598/** Input buffer size. 599*/ 600static size_t szpibuf = DK4_SIZEOF(linebuf,dkChar); 601 602 603 604/** Database key size. 605*/ 606static size_t szkey = DK4_SIZEOF(linebuf,dkChar) / 2; 607 608 609 610/** Database value size. 611*/ 612static size_t szval = DK4_SIZEOF(linebuf,dkChar) / 2; 613 614 615 616/** Number of elements in the dk_t2db_msg array. 617*/ 618static size_t dk_t2db_sz_msg = 619(sizeof(dk_t2db_kw_def)/sizeof(DK4_PDKCHAR) - 1); 620 621 622 623/** Exit status code. 624*/ 625static int exval = EXIT_FAILURE; 626 627 628 629/** Flag: Truncate existing database. 630*/ 631static int truncdb = 1; 632 633 634 635/** Expected encoding when processing an input file. 636*/ 637static int efe = 638#if DK4_ON_WINDOWS 639 DK4_FILE_ENCODING_WIN1252 640#else 641 DK4_FILE_ENCODING_PLAIN 642#endif 643; 644 645 646 647/** Expected encoding when processing standard input. 648*/ 649static int ese = 650#if DK4_ON_WINDOWS 651 DK4_FILE_ENCODING_WIN1252 652#else 653 DK4_FILE_ENCODING_PLAIN 654#endif 655; 656 657 658/** Number of decoding errors already occured. 659*/ 660static int dk_t2db_dec_err = 0; 661 662 663 664/** Number of encoding errors already occured. 665*/ 666static int dk_t2db_enc_err = 0; 667 668 669 670/** Number of processing errors already occured. 671*/ 672static int dk_t2db_pro_err = 0; 673 674 675 676/** Indicator: SIGINT signal received. 677*/ 678static 679DK4_VOLATILE 680dk4_sig_atomic_t sig_had_int = 0; 681 682 683 684/** Indicator: SIGTERM signal received. 685*/ 686static 687DK4_VOLATILE 688dk4_sig_atomic_t sig_had_term = 0; 689 690 691 692/** Pass a volatile pointer to an atomic integer. 693 This function is necessary as some compilers mis-optimize 694 direct access to volatile variables (at least if you believe 695 one of the coding standards). 696 @param ptr Address of atomic integer variable. 697 @return The unmodified pointer. 698*/ 699static 700DK4_VOLATILE 701dk4_sig_atomic_t * 702sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr) 703{ 704 return ptr; 705} 706 707 708 709/** Handler for SIGINT signal. 710 @param signo Signal number (always SIGINT, ignored). 711*/ 712static 713void 714sig_handler_int(int DK4_ARG_UNUSED(signo) ) 715{ 716 DK4_UNUSED_ARG(signo) 717 *sig_pass_pointer(&sig_had_int) = 1; 718} 719 720 721 722/** Handler for SIGTERM signal. 723 @param signo Signal number (always SIGTERM, ignored). 724*/ 725static 726void 727sig_handler_term(int DK4_ARG_UNUSED(signo) ) 728{ 729 DK4_UNUSED_ARG(signo) 730 *sig_pass_pointer(&sig_had_term) = 1; 731} 732 733 734 735/** Read value from volatile atomic type. 736 This function is necessary as some compilers mis-optimize 737 direct access to volatile variables (at least if you believe 738 one of the coding standards). 739 @param ap Pointer to volatile atomic variable. 740 @return Contents of the variable. 741*/ 742static 743dk4_sig_atomic_t 744sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap) 745{ 746 return (*ap); 747} 748 749 750 751/** Check whether we can continue or if a signal was received. 752 @param check_pipe Flag: Check for occured SIGPIPE signal too. 753 @return 1 if the program can continue, 0 if a signal was received. 754*/ 755static 756int 757sig_can_continue(void) 758{ 759 int back = 1; 760 if (0 != sig_read_atomic(&sig_had_int )) { back = 0; } 761 if (0 != sig_read_atomic(&sig_had_term)) { back = 0; } 762 return back; 763} 764 765 766 767static 768void 769dk_t2db_remove_crnl(dkChar *lptr) 770{ 771 while (dkT('\0') != *lptr) { 772 if (dkT('\n') == *lptr) { 773 *lptr = dkT('\0'); 774 } else { 775 if (dkT('\r') == *lptr) { 776 *lptr = dkT('\0'); 777 } else { 778 lptr++; 779 } 780 } 781 } 782} 783 784 785 786/** Handler function to process one text line. 787 @param obj Object to modify. 788 @param line Text line to process. 789 @param lineno Line number of text line. 790 @param erp Error report, may be NULL. 791 @return One from: 792 - DK4_TSP_RES_OK for successful processing, 793 - DK4_TSP_RES_ERROR on errors we can recover from, 794 - DK4_TSP_RES_FATAL on errors requiring to abort processing. 795*/ 796static 797int 798dk_t2db_line_handler( 799 void *obj, 800 dkChar *line, 801 dk4_um_t DK4_ARG_UNUSED(lineno), 802 dk4_er_t *erp 803) 804{ 805 dk4_er_t er; 806 dk4_dbi_t *dbiptr; 807 dkChar *p1; 808 dkChar *p2; 809 int back = DK4_TSP_RES_OK; 810 int must = 1; /* Must process line */ 811 $? "+ dk_t2db_line_handler \"%!ds\"", line 812 DK4_UNUSED_ARG(lineno) 813 p1 = dk4str_start(line, NULL); 814 if (NULL != p1) { $? ". have text" 815 if (NULL != comment) { $? ". have comment \"%!ds\"", comment 816 if (*comment == *p1) { 817 must = 0; $? ". comment line" 818 } 819#if TRACE_DEBUG 820 else { $? ". not a comment line" 821 } 822#endif 823 } 824 if (0 != must) { 825 /* Not a comment line */ 826 dk_t2db_remove_crnl(p1); 827 dbiptr = (dk4_dbi_t *)obj; 828 dk4error_init(&er); 829 p2 = dk4str_next(p1, NULL); 830 if (NULL != p2) { $? ". set \"%!ds\"=\"%!ds\"", p1, p2 831 /* Add or change entry */ 832 if (0 == dk4dbi_text_set(dbiptr, p1, p2, &er)) { 833 dk4error_copy(erp, &er); $? "! failed" 834 back = DK4_TSP_RES_ERROR; 835 exval = EXIT_FAILURE; 836 dk4app_log_5( 837 app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 3, 4, 5, p1, p2 838 ); 839 } 840 } else { $? ". delete \"%!ds\"", p1 841 /* Delete entry */ 842 if (0 == dk4dbi_text_del(dbiptr, p1, &er)) { 843 dk4error_copy(erp, &er); $? "! failed" 844 back = DK4_TSP_RES_ERROR; 845 exval = EXIT_FAILURE; 846 dk4app_log_3( 847 app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 6, 7, p1 848 ); 849 } 850 } 851 } 852 } 853 $? "- dk_t2db_line_handler %d", back 854 return back; 855} 856 857 858/** Report an error with position in source line. 859 @param i1 Index of first message part in array. 860 @param i2 Index of alternative first message part. 861 @param bno Byte processed. 862 @param lno Current line number. 863 @param cno Current character number. 864 @param cil Current character number in line. 865*/ 866static 867void 868dk_t2db_report_with_position( 869 size_t i1, 870 size_t i2, 871 dk4_um_t bno, 872 dk4_um_t lno, 873 dk4_um_t cno, 874 dk4_um_t cil 875) 876{ 877 dkChar b1[8*(1+sizeof(dk4_um_t))]; 878 dkChar b2[8*(1+sizeof(dk4_um_t))]; 879 dkChar b3[8*(1+sizeof(dk4_um_t))]; 880 dk4_um_t oldlogline = (dk4_um_t)0UL; 881 int allbuffersok = 0; 882 883 oldlogline = dk4app_get_log_source_line(app); 884 dk4app_set_log_source_line(app, lno); 885 if (0 != dk4ma_write_decimal_unsigned(b3,DK4_SIZEOF(b3,dkChar),cil,0,NULL)) { 886 if (0 != dk4ma_write_decimal_unsigned(b2,DK4_SIZEOF(b2,dkChar),cno,0,NULL)) { 887 if (0 != dk4ma_write_decimal_unsigned(b1,DK4_SIZEOF(b1,dkChar),bno,0,NULL)) { 888 allbuffersok = 1; 889 } 890 } 891 } 892 if (0 != allbuffersok) { 893 dk4app_log_7( 894 app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 895 i1, 17, 18, 19, b1, b2, b3 896 ); 897 } else { 898 dk4app_log_1( 899 app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, i2 900 ); 901 } 902 dk4app_set_log_source_line(app, oldlogline); 903} 904 905 906/** Report errors from encoding/decoding or processing. 907*/ 908static 909void 910dk_t2db_report_errors(dk4_er_t *er_en, dk4_er_t *er_pr) 911{ 912 913 if (NULL != er_en) { 914 switch (er_en->ec) { 915 case DK4_E_DECODING_FAILED: { 916 switch (dk_t2db_dec_err) { 917 case 0: case 1: { 918 dk_t2db_report_with_position( 919 14, 8, 920 er_en->dt.fpos.byteno, 921 er_en->dt.fpos.lineno, 922 er_en->dt.fpos.charno, 923 er_en->dt.fpos.charinline 924 ); 925 } break; 926 case 2: { 927 dk4app_log_1( 928 app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 11 929 ); 930 } break; 931 } 932 if (3 > dk_t2db_dec_err) { dk_t2db_dec_err++; } 933 } break; 934 case DK4_E_ENCODING_FAILED: { 935 switch (dk_t2db_enc_err) { 936 case 0: case 1: { 937 dk_t2db_report_with_position( 938 15, 9, 939 er_en->dt.fpos.byteno, 940 er_en->dt.fpos.lineno, 941 er_en->dt.fpos.charno, 942 er_en->dt.fpos.charinline 943 ); 944 } break; 945 case 2: { 946 dk4app_log_1( 947 app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 12 948 ); 949 } break; 950 } 951 if (3 > dk_t2db_enc_err) { dk_t2db_enc_err++; } 952 } break; 953 } 954 } 955 if (NULL != er_pr) { 956 if (DK4_E_NONE != er_pr->ec) { 957 switch (dk_t2db_pro_err) { 958 case 0: case 1: { 959 dk_t2db_report_with_position( 960 16, 10, 961 er_pr->dt.fpos.byteno, 962 er_pr->dt.fpos.lineno, 963 er_pr->dt.fpos.charno, 964 er_pr->dt.fpos.charinline 965 ); 966 } break; 967 case 2: { 968 dk4app_log_1( 969 app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 13 970 ); 971 } break; 972 } 973 if (3 > dk_t2db_pro_err) { dk_t2db_pro_err++; } 974 } 975 } 976 977 978} 979 980 981 982/** Process one input file. 983 @param dbiptr Database to modify. 984 @param infile Input file to process, must be in binary mode. 985 @param eie Expected input encoding. 986*/ 987static 988void 989dk_t2db_run_for_file( 990 dk4_dbi_t *dbiptr, 991 FILE *infile, 992 int eie 993) 994{ 995 dk4_tspdk_t tspdk; 996 dk4_er_t er_en; 997 dk4_er_t er_pr; 998 const dkChar *oldsourcefile; 999 int res; 1000 int cc; 1001 int c; 1002 unsigned char ub; 1003 1004 dk_t2db_dec_err = 0; 1005 dk_t2db_enc_err = 0; 1006 dk_t2db_pro_err = 0; 1007 oldsourcefile = dk4app_get_log_source_file(app); 1008 res = dk4tspdk_setup_line( 1009 &tspdk, dbiptr, dk_t2db_line_handler, pibuf, szpibuf, 1010 dk4app_get_encoding(app), eie, NULL 1011 ); 1012 if (0 != res) { 1013 if (DK4_ENCODING_UTF8 == dk4app_get_encoding(app)) { 1014 dk4tspdk_enable_utf8_pass_through(&tspdk, 1); 1015 } 1016 dk4error_init(&er_en); 1017 dk4error_init(&er_pr); 1018 cc = 1; 1019 do { 1020 if (0 != sig_can_continue()) { 1021 c = fgetc(infile); 1022 if (EOF != c) { 1023 ub = (unsigned char)c; 1024 switch (dk4tspdk_add_one_byte(&tspdk, ub)) { 1025 case DK4_TSP_RES_FATAL : { 1026 cc = -1; 1027 exval = EXIT_FAILURE; 1028 dk4tspdk_get_errors(&er_en, &er_pr, &tspdk); 1029 dk_t2db_report_errors(&er_en, &er_pr); 1030 } break; 1031 case DK4_TSP_RES_ERROR : { 1032 exval = EXIT_FAILURE; 1033 dk4tspdk_get_errors(&er_en, &er_pr, &tspdk); 1034 dk_t2db_report_errors(&er_en, &er_pr); 1035 } break; 1036 } 1037 } else { 1038 cc = 0; 1039 if (0 != ferror(infile)) { 1040 cc = -1; 1041 /* ERROR: Failed to read from file */ 1042 dk4app_log_1( 1043 app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 20 1044 ); 1045 exval = EXIT_FAILURE; 1046 } 1047 } 1048 } else { 1049 cc = -1; 1050 } 1051 } while (1 == cc); 1052 if (0 == cc) { 1053 switch (dk4tspdk_finish(&tspdk)) { 1054 case DK4_TSP_RES_FATAL : { 1055 exval = EXIT_FAILURE; 1056 dk4tspdk_get_errors(&er_en, &er_pr, &tspdk); 1057 dk_t2db_report_errors(&er_en, &er_pr); 1058 } break; 1059 case DK4_TSP_RES_ERROR : { 1060 exval = EXIT_FAILURE; 1061 dk4tspdk_get_errors(&er_en, &er_pr, &tspdk); 1062 dk_t2db_report_errors(&er_en, &er_pr); 1063 } break; 1064 } 1065 } 1066 } else { 1067 /* ERROR: Failed to set up text stream processor */ 1068 dk4app_log_1( 1069 app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 21 1070 ); 1071 exval = EXIT_FAILURE; 1072 } 1073 dk4app_set_log_source_file(app, oldsourcefile); 1074} 1075 1076 1077 1078/** Process one input file specified by file name. 1079 @param dbiptr Database to modify. 1080 @param filename Name of file to process. 1081*/ 1082static 1083void 1084dk_t2db_process_name(dk4_dbi_t *dbiptr, const dkChar *filename) 1085{ 1086#if DK4_ON_WINDOWS 1087 dkChar buf[DK4_MAX_PATH]; 1088#endif 1089 FILE *fipo; 1090#if DK4_ON_WINDOWS 1091 dk4_dir_t *fne; 1092 const dkChar *expfn; 1093 const dkChar *expth; 1094 size_t szbuf = DK4_SIZEOF(buf,dkChar); 1095 int any_file_found = 0; 1096 int cc; 1097#endif 1098 1099 if (NULL != filename) { 1100#if DK4_ON_WINDOWS 1101 if (0 != dk4path_must_expand(filename)) { 1102 fne = dk4app_fne_open(filename, app); 1103 if (NULL != fne) { 1104 cc = 1; 1105 do { 1106 if (0 != sig_can_continue()) { 1107 expfn = dk4dir_next_file(fne); 1108 if (NULL != expfn) { 1109 any_file_found = 1; 1110 expth = dk4dir_get_path(fne); 1111 if (NULL != expth) { 1112 if (0 != dk4str_cpy_s(buf, szbuf, expth, NULL)) { 1113 if (0 != dk4str_cat_s(buf, szbuf, dk_t2db_kwnl[8], NULL)) { 1114 if (0 != dk4str_cat_s(buf, szbuf, expfn, NULL)) { 1115 fipo = dk4fopen_app( 1116 buf, dk_t2db_kwnl[7], DK4_FOPEN_SC_IS_REGULAR, app 1117 ); 1118 if (NULL != fipo) { 1119 dk_t2db_run_for_file(dbiptr, fipo, efe); 1120 fclose(fipo); 1121 } else { 1122 exval = EXIT_FAILURE; 1123 } 1124 } else { 1125 /* ERROR: Path too long */ 1126 dk4app_log_3( 1127 app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 1128 22, 23, filename 1129 ); 1130 exval = EXIT_FAILURE; 1131 } 1132 } else { 1133 /* ERROR: Path too long */ 1134 dk4app_log_3( 1135 app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 1136 22, 23, filename 1137 ); 1138 exval = EXIT_FAILURE; 1139 } 1140 } else { 1141 /* ERROR: Path too long */ 1142 dk4app_log_3( 1143 app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 1144 22, 23, filename 1145 ); 1146 exval = EXIT_FAILURE; 1147 } 1148 } else { 1149 fipo = dk4fopen_app( 1150 expfn, dk_t2db_kwnl[7], DK4_FOPEN_SC_IS_REGULAR, app 1151 ); 1152 if (NULL != fipo) { 1153 dk_t2db_run_for_file(dbiptr, fipo, efe); 1154 fclose(fipo); 1155 } else { 1156 exval = EXIT_FAILURE; 1157 } 1158 } 1159 } else { 1160 cc = 0; 1161 } 1162 } else { 1163 cc = -1; 1164 } 1165 } while (1 == cc); 1166 dk4dir_close(fne); 1167 if (0 == any_file_found) { 1168 /* ERROR: No such file */ 1169 dk4app_log_3( 1170 app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 1171 24, 25, filename 1172 ); 1173 exval = EXIT_FAILURE; 1174 } 1175 } else { 1176 exval = EXIT_FAILURE; 1177 } 1178 } else { 1179#endif 1180 fipo = dk4fopen_app( 1181 filename, dk_t2db_kwnl[7], DK4_FOPEN_SC_IS_REGULAR, app 1182 ); 1183 if (NULL != fipo) { 1184 dk_t2db_run_for_file(dbiptr, fipo, efe); 1185 fclose(fipo); 1186 } else { 1187 exval = EXIT_FAILURE; 1188 } 1189#if DK4_ON_WINDOWS 1190 } 1191#endif 1192 } 1193} 1194 1195 1196 1197/** Run for opened database. 1198 @param dbiptr Database to modify. 1199*/ 1200static 1201void 1202dk_t2db_run_with_dbi(dk4_dbi_t *dbiptr) 1203{ 1204 int xargc; 1205 int i; 1206#if DK4_ON_WINDOWS 1207 int oldmode; 1208#endif 1209 1210 xargc = dk4app_get_argc(app); 1211 if (1 < xargc) { 1212 for (i = 0; ((i < (xargc - 1)) && (0 != sig_can_continue())); i++) { 1213 dk_t2db_process_name(dbiptr, dk4app_get_argv(app, i)); 1214 } 1215 } else { 1216#if DK4_ON_WINDOWS 1217 oldmode = _setmode(_fileno(stdin), _O_BINARY); 1218#endif 1219 dk_t2db_run_for_file(dbiptr, stdin, ese); 1220#if DK4_ON_WINDOWS 1221 _setmode(_fileno(stdin), oldmode); 1222#endif 1223 } 1224} 1225 1226 1227 1228/** Open database and do processing. 1229*/ 1230static 1231void 1232dk_t2db_run_with_buffers(void) 1233{ 1234 dk4_er_t er; 1235 dk4_dbi_t *dbiptr; 1236 const dkChar *fn; 1237 1238 fn = dk4app_get_argv(app, (dk4app_get_argc(app)-1)); 1239 if ((0 != sig_can_continue()) && (NULL != fn)) { 1240 dbiptr = dk4dbi_open_sizes_app(fn, 1, truncdb, szkey, szval, NULL, app); 1241 if (NULL != dbiptr) { 1242 exval = EXIT_SUCCESS; 1243 dk_t2db_run_with_dbi(dbiptr); 1244 dk4error_init(&er); 1245 if (0 == dk4dbi_close(dbiptr, &er)) { 1246 /* ERROR: Failed to close database */ 1247 dk4app_log_1( 1248 app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 26 1249 ); 1250 exval = EXIT_FAILURE; 1251 } 1252 } 1253 } 1254} 1255 1256 1257 1258/** Process preferences and command line options, 1259 allocate buffer if necessary and do processing. 1260*/ 1261static 1262void 1263dk_t2db_normal_run(void) 1264{ 1265 dk4_er_t er; 1266 const dkChar *oaptr; 1267 size_t i; 1268 int enc = DK4_FILE_ENCODING_PLAIN; 1269 int bom = 0; 1270 1271#if DK4_ON_WINDOWS 1272 enc = DK4_FILE_ENCODING_WIN1252; 1273#endif 1274 /* Check cmd line arguments, must have at least a database name. 1275 */ 1276 if (0 == dk4app_get_argc(app)) { 1277 /* ERROR: Database name required. */ 1278 dk4app_log_1( 1279 app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 27 1280 ); 1281 goto finished; 1282 } 1283 1284 /* Process preferences and options. 1285 */ 1286 if (0 == dk4app_opt_is_set_short(app, dkT('R'), NULL)) { 1287 if (0 != dk4app_pref_get_size(&i, app, dk_t2db_kwnl[4], 0)) { 1288 szpibuf = i; 1289 } 1290 if (0 != dk4app_pref_get_size(&i, app, dk_t2db_kwnl[5], 0)) { 1291 szkey = i; 1292 } 1293 if (0 != dk4app_pref_get_size(&i, app, dk_t2db_kwnl[6], 0)) { 1294 szval = i; 1295 } 1296 } 1297 if (0 != dk4app_opt_is_set_short(app, dkT('a'), NULL)) { 1298 truncdb = 0; 1299 } 1300 if (0 != dk4app_opt_is_set_short(app, dkT('l'), NULL)) { 1301 if (0 != dk4app_opt_get_size_short(&i, app, dkT('l'), NULL)) { 1302 szpibuf = i; 1303 } 1304 } 1305 if (0 != dk4app_opt_is_set_short(app, dkT('k'), NULL)) { 1306 if (0 != dk4app_opt_get_size_short(&i, app, dkT('k'), NULL)) { 1307 szkey = i; 1308 } 1309 } 1310 if (0 != dk4app_opt_is_set_short(app, dkT('v'), NULL)) { 1311 if (0 != dk4app_opt_get_size_short(&i, app, dkT('v'), NULL)) { 1312 szval = i; 1313 } 1314 } 1315 if (0 != dk4app_opt_is_set_short(app, dkT('i'), NULL)) { 1316 oaptr = dk4app_opt_get_string_ptr_short(app, dkT('i'), NULL); 1317 if (NULL != oaptr) { 1318 if (0 != dk4enc_find(&enc, &bom, oaptr, NULL)) { 1319 efe = ese = enc; 1320 } else { 1321 /* ERROR: Encoding not found */ 1322 dk4app_log_3( 1323 app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 28, 29, oaptr 1324 ); 1325 goto finished; 1326 } 1327 } 1328 } 1329 if (0 != dk4app_opt_is_set_short(app, dkT('c'), NULL)) { 1330 $? ". option -c used" 1331 oaptr = dk4app_opt_get_string_ptr_short(app, dkT('c'), NULL); 1332 if (NULL != oaptr) { $? ". argument found" 1333 comment = oaptr; $? ". comment=\"%!ds\"", comment 1334 } 1335#if TRACE_DEBUG 1336 else { $? "! no argument" 1337 } 1338#endif 1339 } 1340 if (0 == szpibuf) { szpibuf = DK4_SIZEOF(linebuf,dkChar); } 1341 if (0 == szkey) { szkey = DK4_SIZEOF(linebuf,dkChar) / 2; } 1342 if (0 == szval) { szval = DK4_SIZEOF(linebuf,dkChar) / 2; } 1343 1344 /* Calculate key and value buffer size in bytes. 1345 */ 1346 dk4error_init(&er); 1347 szkey = dk4ma_size_t_mul(szkey, sizeof(dkChar), &er); 1348 szval = dk4ma_size_t_mul(szval, sizeof(dkChar), &er); 1349 if (DK4_E_NONE != er.ec) { 1350 /* ERROR: Mathematical overflow in size calculation */ 1351 dk4app_log_base1(app, DK4_LL_ERROR, 82); 1352 goto finished; 1353 } 1354 1355 /* Allocate larger buffer if necessary. 1356 */ 1357 if (DK4_SIZEOF(linebuf,dkChar) < szpibuf) { 1358 abuf = dk4mem_new_app(dkChar,szpibuf,app); 1359 if (NULL != abuf) { 1360 pibuf = abuf; 1361 } else { 1362 goto finished; 1363 } 1364 } 1365 1366 /* Now do the processing. 1367 */ 1368 dk_t2db_run_with_buffers(); 1369 1370 /* Clean up. 1371 */ 1372 finished: 1373 dk4mem_release(abuf) ; 1374} 1375 1376 1377 1378#if DK4_HAVE_SIGACTION 1379/** Set signal handlers and run. 1380*/ 1381static 1382void 1383dk_t2db_run_with_signal_handlers(void) 1384{ 1385 struct sigaction oint; 1386 struct sigaction nint; 1387 struct sigaction oterm; 1388 struct sigaction nterm; 1389 int success = 0; 1390 1391 /* Set up signal handling for SIGINT. 1392 */ 1393 DK4_MEMRES(&nint, sizeof(nint)); 1394 nint.sa_handler = sig_handler_int; 1395 nint.sa_flags = 0; 1396 if (0 != sigemptyset(&nint.sa_mask)) { 1397 /* ERROR: Failed to set up masked signal set for SIGINT */ 1398 dk4app_log_1(app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 0); 1399 goto finished; 1400 } 1401 if (0 != sigaddset(&nint.sa_mask, SIGINT)) { 1402 /* ERROR: Failed to set up masked signal set for SIGINT */ 1403 dk4app_log_1(app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 0); 1404 goto finished; 1405 } 1406 if (0 != sigaction(SIGINT, &nint, &oint)) { 1407 /* ERROR: Failed to set up signal handler for SIGINT */ 1408 dk4app_log_1(app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 0); 1409 goto finished; 1410 } 1411 1412 /* Set up signal handling for SIGTERM 1413 */ 1414 DK4_MEMRES(&nterm, sizeof(nterm)); 1415 nterm.sa_handler = sig_handler_term; 1416 nterm.sa_flags = 0; 1417 if (0 != sigemptyset(&nterm.sa_mask)) { 1418 /* ERROR: Failed to set up masked signal set for SIGTERM */ 1419 dk4app_log_1(app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 0); 1420 goto restore_old_int; 1421 } 1422 if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) { 1423 /* ERROR: Failed to set up masked signal set for SIGTERM */ 1424 dk4app_log_1(app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 0); 1425 goto restore_old_int; 1426 } 1427 if (0 != sigaction(SIGTERM, &nterm, &oterm)) { 1428 /* ERROR: Failed to set up signal handler for SIGTERM */ 1429 dk4app_log_1(app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 0); 1430 goto restore_old_int; 1431 } 1432 1433 success = 1; 1434 dk_t2db_normal_run(); 1435 1436 /* Restore signal handling for SIGTERM. 1437 */ 1438 if (0 != sigaction(SIGTERM, &oterm, NULL)) { 1439 /* ERROR: Failed to restore old SIGTERM settings */ 1440 dk4app_log_1(app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 1); 1441 success = 0; 1442 } 1443 1444 /* Restore signal handling for SIGINT. 1445 */ 1446 restore_old_int: 1447 if (0 != sigaction(SIGINT, &oint, NULL)) { 1448 /* ERROR: Failed to restore old SIGPIPE settings */ 1449 dk4app_log_1(app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 1); 1450 success = 0; 1451 } 1452 1453 /* Set exit status code if error occured. 1454 */ 1455 finished: 1456 if (0 == success) { exval = EXIT_FAILURE; } 1457} 1458#else 1459#if DK4_HAVE_SIGSET 1460/** Set signal handlers and run. 1461*/ 1462static 1463void 1464dk_t2db_run_with_signal_handlers(void) 1465{ 1466 dk4_sig_handler_t *oldint = NULL; 1467 dk4_sig_handler_t *oldterm = NULL; 1468 1469 oldint = sigset(SIGINT, sig_handler_int); 1470 oldterm = sigset(SIGTERM, sig_handler_term); 1471 dk_t2db_normal_run(); 1472 sigset(SIGTERM, oldterm); 1473 sigset(SIGINT, oldint); 1474} 1475#else 1476#if DK4_HAVE_SIGNAL 1477/** Set signal handlers and run. 1478*/ 1479static 1480void 1481dk_t2db_run_with_signal_handlers(void) 1482{ 1483 dk4_sig_handler_t *oldint = NULL; 1484 dk4_sig_handler_t *oldterm = NULL; 1485 1486 oldint = signal(SIGINT, sig_handler_int); 1487 oldterm = signal(SIGTERM, sig_handler_term); 1488 dk_t2db_normal_run(); 1489 signal(SIGTERM, oldterm); 1490 signal(SIGINT, oldint); 1491} 1492#else 1493/** Set signal handlers and run. 1494*/ 1495static 1496void 1497dk_t2db_run_with_signal_handlers(void) 1498{ 1499 dk_t2db_normal_run(); 1500} 1501#endif 1502#endif 1503#endif 1504 1505 1506 1507/** Main function. 1508 @param argc Number of command line arguments. 1509 @param argv Command line arguments array. 1510 @return 0 on success, all other values indicate errors. 1511*/ 1512#if DK4_CHAR_SIZE > 1 1513int wmain(int argc, wchar_t *argv[]) 1514#else 1515int main(int argc, char *argv[]) 1516#endif 1517{ 1518 $!trace-init dk-t2db.deb 1519 $? "+ main" 1520 dk4fput_initialize_stderr(); 1521 app = dk4app_open_cmd( 1522 argc, argv, 1523 dk_t2db_options, dk_t2db_sz_options, 1524 dk_t2db_kwnl[0], version_text, 1525 dk_t2db_kwnl[1], help_text, license_text 1526 ); 1527 if (NULL != app) { 1528 ese = dk4app_get_stdin_encoding(app); 1529 efe = dk4app_get_file_in_encoding(app); 1530 dk_t2db_sz_msg = dk4app_string_table_size(dk_t2db_kw_def); 1531 dk_t2db_msg = dk4app_string_table(app, dk_t2db_kwnl[3], dk_t2db_kw_def); 1532 if (0 != dk4app_can_run_normally(app)) { 1533 dk_t2db_run_with_signal_handlers(); 1534 if (0 != sig_read_atomic(&sig_had_int)) { 1535 /* ERROR: Aborted by SIGINT */ 1536 dk4app_log_1( 1537 app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 30 1538 ); 1539 exval = EXIT_FAILURE; 1540 } 1541 if (0 != sig_read_atomic(&sig_had_term)) { 1542 exval = EXIT_FAILURE; 1543 } 1544 } else { 1545 if (0 != dk4app_help_version_license(app)) { 1546 exval = EXIT_SUCCESS; 1547 } 1548 } 1549 dk4app_close(app); 1550 } else { 1551 dk4fputs(dk_t2db_kwnl[2], stderr, NULL); 1552 } 1553 fflush(stderr); 1554 dk4fput_cleanup_stderr(); 1555 $? "- main %d", exval 1556 $!trace-end 1557 exit(exval); return exval; 1558} 1559 1560