/* 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-ls.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-ls.c The dk-ls module. */ #line 87 "dk-ls.ctr" #include "dk4conf.h" #if DK4_ON_WINDOWS #ifndef WINDOWS_H_INCLUDED #include #define WINDOWS_H_INCLUDED #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_UNISTD_H #ifndef UNISTD_H_INCLUDED #include #define UNISTD_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_SIGNAL_H #ifndef SIGNAL_H_INCLUDED #include #define SIGNAL_H_INCLUDED 1 #endif #endif #include "dk4types.h" #include "dk4const.h" #include "dk4vers.h" #include "dk4app.h" #include "dk4aopt.h" #include "dk4mem.h" #include "dk4mema.h" #include "dk4fput.h" #include "dk-ls.h" #include "dk4mpl.h" #include "dk4stat.h" #include "dk4statd.h" #include "dk4strd.h" #include "dk4fileit.h" #include "dk4filei.h" #include "dk4fileia.h" #include "dk4masz.h" #include "dk4maadu.h" #include "dk4maodd.h" #include "dk4maodh.h" #include "dk4numl.h" #include "dk4dira.h" #include "dk4pathd.h" #include "dk4fopda.h" #include "dk4symlink.h" #line 168 "dk-ls.ctr" /** Default help text, used if help text file is not found. */ static const dkChar * const dk_ls_help_text[] = { dkT(""), dkT("List files"), dkT(""), dkT("dk-ls [] []"), dkT(""), dkT("Options:"), dkT("-p ... Output column order, see below. -r Recursive listing."), dkT("-t ... File types to list. -m ... Message digest type."), dkT("-f Stay on current file system. -s Show summary at end."), dkT("--help Show this short help text. --manual *** SHOW FULL MANUAL. ***"), dkT("--version Show version information. --license Show license information. "), dkT(""), dkT("Column order characters: n=name, s=size, t=type, p=permissions/attributes,"), dkT("c=creation, m=modification, a=access, l=links, u=UID, g=GID, d=device,"), dkT("i=inode, r=relative device, w=reparse tag (Widnows), x=message digest."), dkT("Default: ``mtpn'' (``mtn'' on Windows)."), dkT(""), dkT("File type characters: d=directories, f=non-directory entries."), dkT(""), dkT("Message digest types: md5, sha-1, sha-224, sha-256, sha-384, sha-512,"), dkT("ripemd-160. Optionally add encoding hex or a85, i.e. ``sha-1.hex''."), dkT(""), dkT("http://dktools.sourceforge.net"), dkT(""), NULL #line 200 "dk-ls.ctr" }; /** License conditions. */ static const dkChar * const dk_ls_license_text[] = { 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 #if DK4_HAVE_OPENSSL_MD5_H && DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_OPENSSL_RIPEMD_H dkT(""), dkT("OpenSSL\t\tCryptographic toolkit, used to build file checksums here."), dkT("\t\tSee http://www.openssl.org/ for more information."), dkT(""), dkT("This product includes software developed by the OpenSSL Project for use in"), dkT("the OpenSSL Toolkit (http://www.openssl.org/)."), dkT("This product includes cryptographic software written by"), dkT("Eric Young (eay@cryptsoft.com)."), dkT("This product includes software written by Tim Hudson (tjh@cryptsoft.com)."), #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 #if DK4_HAVE_OPENSSL_MD5_H && DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_OPENSSL_RIPEMD_H dkT(""), dkT(""), dkT("OpenSSL license"), dkT("==============="), dkT(""), dkT("LICENSE ISSUES"), dkT("--------------"), dkT(""), dkT("The OpenSSL toolkit stays under a dual license, i.e. both the conditions of"), dkT("the OpenSSL License and the original SSLeay license apply to the toolkit."), dkT("See below for the actual license texts. Actually both licenses are BSD-style"), dkT("Open Source licenses. In case of any license issues related to OpenSSL"), dkT("please contact openssl-core@openssl.org."), dkT(""), dkT("OpenSSL License"), dkT("---------------"), dkT(""), dkT("Copyright (c) 1998-2011 The OpenSSL Project. 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"), 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. Redistributions in binary form must reproduce the above copyright"), dkT(" notice, this list of conditions and the following disclaimer in"), dkT(" the documentation and/or other materials provided with the"), dkT(" distribution."), dkT(""), dkT("3. All advertising materials mentioning features or use of this"), dkT(" software must display the following acknowledgment:"), dkT(" \"This product includes software developed by the OpenSSL Project"), dkT(" for use in the OpenSSL Toolkit. (http://www.openssl.org/)\""), dkT(""), dkT("4. The names \"OpenSSL Toolkit\" and \"OpenSSL Project\" must not be used to"), dkT(" endorse or promote products derived from this software without"), dkT(" prior written permission. For written permission, please contact"), dkT(" openssl-core@openssl.org."), dkT(""), dkT("5. Products derived from this software may not be called \"OpenSSL\""), dkT(" nor may \"OpenSSL\" appear in their names without prior written"), dkT(" permission of the OpenSSL Project."), dkT(""), dkT("6. Redistributions of any form whatsoever must retain the following"), dkT(" acknowledgment:"), dkT(" \"This product includes software developed by the OpenSSL Project"), dkT(" for use in the OpenSSL Toolkit (http://www.openssl.org/)\""), dkT(""), dkT("THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY"), dkT("EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"), dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR"), dkT("PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR"), dkT("ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,"), dkT("SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT"), dkT("NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;"), dkT("LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"), dkT("HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,"), dkT("STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)"), dkT("ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED"), dkT("OF THE POSSIBILITY OF SUCH DAMAGE."), dkT(""), dkT("This product includes cryptographic software written by Eric Young"), dkT("(eay@cryptsoft.com). This product includes software written by Tim"), dkT("Hudson (tjh@cryptsoft.com)."), dkT(""), dkT(""), dkT("Original SSLeay License"), dkT("-----------------------"), dkT(""), dkT("Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)"), dkT("All rights reserved."), dkT(""), dkT("This package is an SSL implementation written"), dkT("by Eric Young (eay@cryptsoft.com)."), dkT("The implementation was written so as to conform with Netscapes SSL."), dkT(""), dkT("This library is free for commercial and non-commercial use as long as"), dkT("the following conditions are aheared to. The following conditions"), dkT("apply to all code found in this distribution, be it the RC4, RSA,"), dkT("lhash, DES, etc., code; not just the SSL code. The SSL documentation"), dkT("included with this distribution is covered by the same copyright terms"), dkT("except that the holder is Tim Hudson (tjh@cryptsoft.com)."), dkT(""), dkT("Copyright remains Eric Young's, and as such any Copyright notices in"), dkT("the code are not to be removed."), dkT("If this package is used in a product, Eric Young should be given attribution"), dkT("as the author of the parts of the library used."), dkT("This can be in the form of a textual message at program startup or"), dkT("in documentation (online or textual) provided with the package."), 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("1. Redistributions of source code must retain the copyright"), dkT(" notice, 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. All advertising materials mentioning features or use of this software"), dkT(" must display the following acknowledgement:"), dkT(" \"This product includes cryptographic software written by"), dkT(" Eric Young (eay@cryptsoft.com)\""), dkT(" The word 'cryptographic' can be left out if the rouines from the library"), dkT(" being used are not cryptographic related :-)."), dkT("4. If you include any Windows specific code (or a derivative thereof) from "), dkT(" the apps directory (application code) you must include an acknowledgement:"), dkT(" \"This product includes software written by Tim Hudson (tjh@cryptsoft.com)\""), dkT(""), dkT("THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND"), dkT("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. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE"), dkT("FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"), dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS"), dkT("OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"), dkT("HOWEVER 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(""), dkT("The licence and distribution terms for any publically available version or"), dkT("derivative of this code cannot be changed. i.e. this code cannot simply be"), dkT("copied and put under another distribution licence"), dkT("[including the GNU Public Licence.]"), dkT(""), #endif dkT(""), NULL #line 471 "dk-ls.ctr" }; /** Constant texts used by program, not localized. */ static const dkChar * const dk_ls_kwnl[] = { /* 0 */ dkT("dktools"), /* 1 */ dkT("dk-ls.txt"), /* 2 */ dkT("dk-ls.str"), /* 3 */ dkT("mtpn"), /* 4 */ dkT("."), /* 5 */ dkT("\\"), /* 6 */ dkT("/"), /* 7 */ dkT(" -> "), /* 8 */ dkT("mtn"), /* 9 */ dkT("message.digest"), /* 10 */ dkT("print.order"), /* 11 */ dkT("ERROR: Application startup failed!\n"), NULL #line 529 "dk-ls.ctr" }; /** Constant texts used by program, replaced by localized texts if available. */ static const dkChar * const dk_ls_kw_def[] = { /* 0 */ dkT("Failed to set up signal handlers!"), /* 1 */ dkT("Failed to restore previous signal handlers!"), /* 2 */ dkT("OVERFLOW"), /* 3 */ dkT("Failed to obtain file size for symbolic link:\n\t\""), /* 4 */ dkT("Failed to obtain file size for target:\n\t\""), /* 5 */ dkT("\"!\n\tInformation not available!"), /* 6 */ dkT("Path grows too long while recursing directory!"), /* 7 */ dkT("Failed to obtain timestamp for symbolic link:\n\t\""), /* 8 */ dkT("Failed to obtain timestamp for target:\n\t\""), /* 9 */ dkT("\"!\nInformation not available!"), /* 10 */ dkT("Failed to obtain file type and attributes (bug)!"), /* 11 */ dkT("Invalid text in print order!"), /* 12 */ dkT("Failed to find target for symbolic link:\n\t\""), /* 13 */ dkT("\"!"), /* 14 */ dkT("Failed to obtain unique file identifier:\n\t\""), /* 15 */ dkT("\"!"), /* 16 */ dkT("File names too long for expansion:\n\t\""), /* 17 */ dkT("\",\n\t\""), /* 18 */ dkT("\"!"), /* 19 */ dkT("Message digest type not supported!"), /* 20 */ dkT("Message digest type not supported: \""), /* 21 */ dkT("\"!"), /* 22 */ dkT("Not a message digest type name: \""), /* 23 */ dkT("\"!"), /* 24 */ dkT("Invalid encoding for message digest: \""), /* 25 */ dkT("\"!"), /* 26 */ dkT("Failed to initialize digest context (error from library function)!"), /* 27 */ dkT("Failed to initialize message digest context!"), /* 28 */ dkT("Failed to add data to message digest!"), /* 29 */ dkT("Failed to finish message digest!"), /* 30 */ dkT("# Number of directories: "), /* 31 */ dkT("# Number of files: "), /* 32 */ dkT("# Total number of bytes: "), NULL #line 632 "dk-ls.ctr" }; #if DK4_ON_WINDOWS /** Buffer to store symbolic link destination. */ static dkChar dk_ls_sl_target[32784]; #else /** Buffer to store symbolic link destination. */ static dkChar dk_ls_sl_target[DK4_MAX_PATH]; #endif /** Options used by program. */ static const dk4_option_specification_t dk_ls_options[] = { /* Reset (ignore preferences). */ { dkT('R'), dkT("reset"), DK4_OPT_ARG_NONE }, /* Print order. */ { dkT('p'), dkT("print-order"), DK4_OPT_ARG_STRING }, /* Recursive listing. */ { dkT('r'), dkT("recursive"), DK4_OPT_ARG_NONE }, /* For recursive listings, stay on the current file system. */ { dkT('f'), dkT("stay-on-filesystem"), DK4_OPT_ARG_NONE }, /* File types to show (all others are ignored). */ { dkT('t'), dkT("types"), DK4_OPT_ARG_STRING }, { dkT('s'), dkT("summary"), DK4_OPT_ARG_NONE }, #if DK4_HAVE_OPENSSL_MD5_H && DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_OPENSSL_RIPEMD_H { dkT('m'), dkT("message-digest"), DK4_OPT_ARG_STRING }, #endif }; /** Buffer for print order from command line. */ static dkChar po_buf[32]; /** Application structure. */ static dk4_app_t *app = NULL; /** Print order. */ static const dkChar *print_order = NULL; /** Message texts, uses localized texts if possible. */ static const dkChar * const *dk_ls_msg = dk_ls_kw_def; /** Error report for bytes counting. */ static dk4_er_t er_bytes; /** Error report for files counting. */ static dk4_er_t er_files; /** Error report for directory counting. */ static dk4_er_t er_dirs; /** Size found so far. */ static dk4_um_t size_bytes = (dk4_um_t)0UL; /** Number of files shown. */ static dk4_um_t num_files = (dk4_um_t)0UL; /** Number of directories shown. */ static dk4_um_t num_dirs = (dk4_um_t)0UL; /** Number of elements in the dk_ls_kw_def array and in dk_ls_msg. */ static size_t dk_ls_sz_msg = (sizeof(dk_ls_kw_def)/sizeof(DK4_PDKCHAR) - 1); #if DK4_ON_WINDOWS /** Limit for incrementing path construction buffer. On Windows systems a special notation allows very long path names up to 32767 characters. */ static const size_t dk_ls_max_path = 32784U; #else /** Limit for incrementing path construction buffer. On non-Windows systems the path is restricted to DK4_MAX_PATH. */ static const size_t dk_ls_max_path = 2 * DK4_MAX_PATH; #endif /** Number of elements in the dk_ls_options array. */ static const size_t dk_ls_sz_options = sizeof(dk_ls_options)/sizeof(dk4_option_specification_t); /** Flag: Size output wanted. */ static int size_wanted = 0; /** Flag: Name output wanted. */ static int name_wanted = 0; /** Flag: Show non-directories. */ static int show_files = 1; /** Flag: Show directories. */ static int show_dirs = 1; /** Flag: Recursive listing. */ static int recursive = 0; /** Flag: Show summary. */ static int show_summary = 0; /** Flag: Stay on file system when recursing directories. */ static int stay_on_fs = 0; /** Message digest type. */ static int digest_type = DK4_MD_SHA1; /** Message digest encoding. */ static int digest_enco = DK4_BINARY_TO_TEXT_ENCODING_HEX; /** Flag: Unsupported digest type already reported. */ static int digest_erep = 0; /** Flag: Write error occured while writing to standard output. */ static int write_error = 0; /** Exit status code. */ static int exval = EXIT_FAILURE; /** Flag: Illegal characters in print order reported. */ static int print_order_error_reported = 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; /** Pass a volatile pointer to an atomic integer. This function is necessary as some compilers mis-optimize direct access to volatile variables (at least if you believe one of the coding standards). @param ptr Address of atomic integer variable. @return The unmodified pointer. */ static DK4_VOLATILE dk4_sig_atomic_t * sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr) { return ptr; } #ifdef SIGPIPE /** Handler for SIGPIPE signal. @param signo Signal number (always SIGPIPE, ignored). */ static void 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_ls_can_continue(void) { int back = 1; if (0 == sig_can_continue(1)) { back = 0; } return back; } /** Node type for a directory. */ typedef struct _dk_ls_node_t_ { struct _dk_ls_node_t_ *parent; /**< Pointer to parent node. */ struct _dk_ls_node_t_ *child; /**< Pointer to current child. */ dk4_dir_t *dirptr; /**< Directory. */ dk4_file_info_t fi; /**< File information. */ dk4_um_t size; /**< Directory size. */ int level; /**< Processing level. */ int ovsize; /**< Flag: Overflow in size calc. */ } dk_ls_node_t; /** Destroy node object, release memory. @param cn Node to destroy. */ static void dk_ls_delete_node(dk_ls_node_t *cn) { #line 989 "dk-ls.ctr" if (NULL != cn) { cn->parent = NULL; cn->child = NULL; if (NULL != cn->dirptr) { dk4dir_close(cn->dirptr); } cn->dirptr = NULL; dk4mem_free(cn); } #line 998 "dk-ls.ctr" } /** Create new new directory node. @param dn Directory name for node. @param pa Parent node. @param level Processing level. @return Pointer to new node on success, NULL on error. */ static dk_ls_node_t * dk_ls_new_node(const dkChar *dn, dk_ls_node_t *pa, int level) { dk4_er_t er; dk_ls_node_t *back = NULL; int om = DK4_DIR_OPEN_SORTED; int ch = DK4_FILE_INFO_CONTENTS_DATA_TARGET; #line 1017 "dk-ls.ctr" back = dk4mem_new_app(dk_ls_node_t,1,app); if (NULL != back) { DK4_MEMRES(back, sizeof(dk_ls_node_t)); back->parent = pa; back->child = NULL; back->dirptr = NULL; back->level = level; back->size = (dk4_um_t)0UL; back->ovsize = 0; if (3 < back->level) { back->level = 3; } om |= DK4_DIR_SYMLINK_DIR_AS_FILE; dk4error_init(&er); back->dirptr = dk4dir_open_app(dn, om, app); if (NULL == back->dirptr) { #line 1031 "dk-ls.ctr" exval = EXIT_FAILURE; dk_ls_delete_node(back); back = NULL; } if (NULL != back) { #line 1036 "dk-ls.ctr" dk4fileinfo_init(&(back->fi)); if (0 != dk4fileinfo_app(&(back->fi), dn, app)) { if (0 == dk4fileinfo_size(&(back->size), &(back->fi), ch, NULL)) { back->size = (dk4_um_t)0UL; #line 1040 "dk-ls.ctr" /* ERROR: Failed to retrieve directory size */ dk_ls_report_fileinfo_size_error(app,dn,ch,dk_ls_msg,dk_ls_sz_msg); exval = EXIT_FAILURE; } } else { #line 1045 "dk-ls.ctr" /* ERROR: Failed to retrieve file information, already reported */ exval = EXIT_FAILURE; } } else { #line 1049 "dk-ls.ctr" /* ERROR: Failed to open directory, already reported */ exval = EXIT_FAILURE; } } else { #line 1053 "dk-ls.ctr" /* ERROR: Allocation failed, already reported */ exval = EXIT_FAILURE; } #line 1057 "dk-ls.ctr" return back; } /** Construct a path name consisting of directory and file or subdirectory name into an existing buffer. @param bufptr Buffer address. @param szbuf Size of buffer. @param dirname Leading part of path name. @param filename Trailing part of path name. @param erp Error report, may be NULL. @return 1 on success, 0 on error (buffer too short). */ static int dk_ls_dir_and_file( dkChar *bufptr, size_t szbuf, const dkChar *dirname, const dkChar *filename ) { int back = 0; int nsep = 1; /* Flag: Separator needed */ #line 1083 "dk-ls.ctr" if (NULL != dirname) { if (0 != dk4str_cpy_s(bufptr, szbuf, dirname, NULL)) { while(dkT('\0') != *dirname) { #if DK4_ON_WINDOWS if (dkT('\\') == *dirname) #else if (dkT('/') == *dirname) #endif { nsep = 0; } else { nsep = 1; } dirname++; } if (0 != nsep) { #if DK4_ON_WINDOWS if (0 != dk4str_cat_s(bufptr, szbuf, dk_ls_kwnl[5], NULL)) #else if (0 != dk4str_cat_s(bufptr, szbuf, dk_ls_kwnl[6], NULL)) #endif { back = 1; } } else { back = 1; } if (0 != back) { back = 0; if (0 != dk4str_cat_s(bufptr, szbuf, filename, NULL)) { back = 1; } else { #line 1115 "dk-ls.ctr" /* BUG: Buffer too small */ exval = EXIT_FAILURE; } } else { #line 1119 "dk-ls.ctr" /* BUG: Buffer too small */ exval = EXIT_FAILURE; } } else { #line 1123 "dk-ls.ctr" /* BUG: Buffer too small */ exval = EXIT_FAILURE; } } else { back = dk4str_cpy_s(bufptr, szbuf, filename, NULL); if (0 == back) { #line 1129 "dk-ls.ctr" /* BUG: Buffer too small */ exval = EXIT_FAILURE; } } #line 1133 "dk-ls.ctr" return back; } /** Construct a file or directory name, resize buffer if necessary. @param bufptr Address of pointer to buffer. @param szbufptr Address of buffer size variable. @param dirname Directory part of path to construct. @param filename File name part of path to construct. @return 1 on success, 0 on error. */ static int dk_ls_construct_path( dkChar **bufptr, size_t *szbufptr, const dkChar *dirname, const dkChar *filename ) { dk4_er_t er; /* Error code */ dkChar *nb; /* New buffer */ size_t lgt; /* Required buffer size */ int back = 0; #line 1160 "dk-ls.ctr" dk4error_init(&er); lgt = dk4str_len(filename); if (NULL != dirname) { lgt = dk4ma_size_t_add(lgt, dk4str_len(dirname), &er); lgt = dk4ma_size_t_add(lgt, 2, &er); } if (DK4_E_NONE == er.ec) { if (lgt <= *szbufptr) { /* Keep current buffer. */ #line 1172 "dk-ls.ctr" back = dk_ls_dir_and_file(*bufptr, *szbufptr, dirname, filename); } else { if (dk_ls_max_path > lgt) { /* Allocate new larger buffer. */ #line 1179 "dk-ls.ctr" nb = dk4mem_new_app(dkChar, lgt, app); if (NULL != nb) { #line 1181 "dk-ls.ctr" dk4mem_release(*bufptr); *bufptr = nb; *szbufptr = lgt; back = dk_ls_dir_and_file(*bufptr, *szbufptr, dirname, filename); } else { #line 1186 "dk-ls.ctr" /* ERROR: Memory allocation failed, already reported */ exval = EXIT_FAILURE; } } else { /* ERROR: Path size too long */ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 6); exval = EXIT_FAILURE; } } } else { /* ERROR: Overflow in size calculation */ dk4app_log_base1(app, DK4_LL_ERROR, 82); exval = EXIT_FAILURE; } #line 1201 "dk-ls.ctr" return back; } static void dk_ls_write_decimal_number(dk4_um_t value, size_t width) { dkChar buf[16 + 8 * sizeof(dk4_um_t)]; dk4_er_t er; size_t sl; int res; dk4error_init(&er); res = dk4ma_write_decimal_unsigned( buf, DK4_SIZEOF(buf,dkChar), value, 0, &er ); if (0 != res) { sl = dk4str_len(buf); while (sl++ < width) { if (0 == dk4fputc(dkT(' '), stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } if (0 == dk4fputs(buf, stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } else { #line 1229 "dk-ls.ctr" /* ERROR: Failed to write decimal number to buffer (bug) */ exval = EXIT_FAILURE; } } static void dk_ls_write_hexadecimal_number(dk4_um_t value, size_t width) { dkChar buf[16 + 8 * sizeof(dk4_um_t)]; dk4_er_t er; size_t sl; int res; #line 1245 "dk-ls.ctr" dk4error_init(&er); res = dk4ma_write_hex_unsigned( buf, DK4_SIZEOF(buf,dkChar), value, width, &er ); if (0 != res) { #line 1250 "dk-ls.ctr" sl = dk4str_len(buf); while (sl++ < width) { #line 1252 "dk-ls.ctr" if (0 == dk4fputc(dkT('0'), stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } if (0 == dk4fputs(buf, stdout, NULL)) { #line 1257 "dk-ls.ctr" write_error = 1; exval = EXIT_FAILURE; } } else { #line 1260 "dk-ls.ctr" /* BUG: Failed to write hexadecimal number to buffer */ exval = EXIT_FAILURE; } #line 1264 "dk-ls.ctr" } /** Write file timestamp. @param fiptr File information. @param fn File name. @param what Choose the timestamp. @param issl Flag: Object is symbolic link. */ static void dk_ls_write_timestamp( dk4_file_info_t *fiptr, const dkChar *fn, int what, int issl ) { dk4_er_t er; dkChar buf[64]; int ch; int res; dk4error_init(&er); ch = ( (0 != issl) ? DK4_FILE_INFO_CONTENTS_DATA_LINK : DK4_FILE_INFO_CONTENTS_DATA_TARGET ); res = dk4fileinfo_timestamp(buf,DK4_SIZEOF(buf,dkChar),fiptr,ch,what,&er); if (0 != res) { if (0 == dk4fputs(buf, stdout, &er)) { write_error = 1; exval = EXIT_FAILURE; } } else { /* ERRROR: Failed to obtain time */ dk_ls_report_fileinfo_timestamp_error( app, fn, ch, dk_ls_msg, dk_ls_sz_msg ); exval = EXIT_FAILURE; } } /** Write indicator for unkown data. @param width Field width. @param compl Fill complete field. */ static void dk_ls_write_unknown(size_t width, int compl) { if (0 != compl) { while (0 < width--) { if (0 == dk4fputc(dkT('?'), stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } } else { while (1 < width--) { if (0 == dk4fputc(dkT(' '), stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } if (0 == dk4fputc(dkT('?'), stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } } static int dk_ls_can_create_md(const dkChar *fn, dk4_file_info_t *fiptr) { int back = 0; if (0 == dk4fileinfo_is_symlink(fiptr)) { #if DK4_ON_WINDOWS if (0 == (FILE_ATTRIBUTE_REPARSE_POINT & (fiptr->fattr))) { if (0 == (FILE_ATTRIBUTE_DIRECTORY & (fiptr->fattr))) { if (0 == (FILE_ATTRIBUTE_DEVICE & (fiptr->fattr))) { back = 1; } } } #else if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & (fiptr->contents))) { if (S_IFREG == (S_IFMT & ((fiptr->tstb).st_mode))) { back = 1; } } #endif } return back; } /** Write message digest. @param fn File name. @param fiptr File information pointer. @param digest_type Message digest type. @param digest_enco Message digest encoding. @param app Application structure for diagnostics. @param dk_ls_msg Message texts array. @param dk_ls_sz_msg Size of message texts error. */ static void dk_ls_write_md( const dkChar *fn, dk4_file_info_t *fiptr, int digest_type, int digest_enco, dk4_app_t *app, const dkChar * const *dk_ls_msg, size_t dk_ls_sz_msg ) { char buf[4096]; /* Buffer to read file */ dk4_md_ctx_t ctx; /* Message digest context */ dk4_er_t er; /* Error report */ FILE *fipo; /* Input file to process */ const char *resptr; /* Pointer to encoded digest buffer */ size_t rdbytes; /* Number of bytes read */ int mdok = 0; /* Flag: Digesting ok so far */ if (0 != dk_ls_can_create_md(fn, fiptr)) { #line 1391 "dk-ls.ctr" dk4error_init(&er); if (0 != dk4md_ctx_init(&ctx, digest_type, digest_enco, &er)) { #line 1394 "dk-ls.ctr" fipo = dk4fopen_app(fn, dkT("rb"), DK4_FOPEN_SC_IS_REGULAR, app); if (NULL != fipo) { #line 1396 "dk-ls.ctr" mdok = 1; do { if (0 != dk_ls_can_continue()) { rdbytes = fread(buf, 1, sizeof(buf), fipo); if (0 < rdbytes) { #line 1401 "dk-ls.ctr" dk4error_init(&er); if (1 != dk4md_ctx_add(&ctx, buf, rdbytes, &er)) { mdok = 0; #line 1404 "dk-ls.ctr" /* ERROR: Digest failed */ switch (er.ec) { case DK4_E_NOT_SUPPORTED : { dk4app_log_1(app,dk_ls_msg,dk_ls_sz_msg,DK4_LL_ERROR,19); } break; default : { dk4app_log_1(app,dk_ls_msg,dk_ls_sz_msg,DK4_LL_ERROR,28); } break; } } } } else { mdok = 0; rdbytes = 0; } } while((0 < rdbytes) && (1 == mdok)); fclose(fipo); if (1 == mdok) { #line 1422 "dk-ls.ctr" resptr = NULL; rdbytes = 0; dk4error_init(&er); if (1 == dk4md_ctx_finish(&resptr, &rdbytes, &ctx, &er)) { #line 1426 "dk-ls.ctr" if ((NULL != resptr) && (0 < rdbytes)) { #line 1427 "dk-ls.ctr" while(rdbytes--) { if (0 == dk4fputc((dkChar)(*(resptr++)), stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; #line 1430 "dk-ls.ctr" } } } else { #line 1433 "dk-ls.ctr" mdok = 0; /* ERROR: No digest obtained */ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 29); } } else { #line 1438 "dk-ls.ctr" mdok = 0; /* ERROR: Failed to obtain digest */ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 29); } } else { #line 1443 "dk-ls.ctr" } } else { #line 1445 "dk-ls.ctr" /* ERROR: Failed to open file, already reported */ } } else { #line 1448 "dk-ls.ctr" /* ERROR: Failed to initialize digest ctx */ switch (er.ec) { case DK4_E_NOT_SUPPORTED : { dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 19); } break; case DK4_E_SYSTEM : { dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 26); } break; default : { dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 27); } break; } } } else { #line 1462 "dk-ls.ctr" } if (0 == mdok) { rdbytes = dk4md_size(digest_type, digest_enco, NULL); while (rdbytes--) { if (0 == dk4fputc(dkT('x'), stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } } } /** Write information about file to standard output. @param fn File name. @param fiptr File information. @param use_size Flag: Use specified size. @param size Size to use. @param ovsize Flag: Numeric overflow in size calculation. */ static void dk_ls_process_item_information( const dkChar *fn, dk4_file_info_t *fiptr, int use_size, dk4_um_t size, int ovsize ) { dkChar abuf[8*sizeof(dk4_um_t) + 16]; /* Attributes */ dkChar buf[8*sizeof(dk4_um_t) + 16]; /* Numbers */ dk4_er_t er; /* Error report */ const dkChar *piptr; /* Print order */ dk4_um_t fs; /* File size */ size_t numl; /* Number length */ size_t slen; /* String length */ size_t tlen; /* First part length */ size_t i; /* Index variable */ int issl; /* Flag: Is symbolic link */ int res; /* Result from information retrieval */ int showi; /* Flag: Show this item */ int habuf; /* Flag: Data in abuf */ int last_was_n; /* Flag: n was last character */ dkChar lasti; /* Last information printed */ #line 1507 "dk-ls.ctr" last_was_n = habuf = 0; if ((NULL != fn) && (NULL != fiptr)) { #line 1509 "dk-ls.ctr" showi = 1; res = dk4fileinfo_type_attributes( buf, DK4_SIZEOF(buf,dkChar), fiptr, &er ); if (0 != res) { showi = 0; if (dkT('d') == buf[1]) { if (0 != show_dirs) { showi = 1; if (0 != show_summary) { num_dirs = dk4ma_um_add(num_dirs, 1, &er_dirs); } } } else { if (0 != show_files) { showi = 1; if (0 != show_summary) { num_files = dk4ma_um_add(num_files, 1, &er_files); } } } } else { #line 1531 "dk-ls.ctr" /* BUG: Failed to write file attributes to buffer */ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 10); exval = EXIT_FAILURE; } if (0 != showi) { #line 1536 "dk-ls.ctr" issl = dk4fileinfo_is_symlink(fiptr); lasti = dkT('\0'); piptr = print_order; while (dkT('\0') != *piptr) { #line 1540 "dk-ls.ctr" last_was_n = 0; if ((int)(*piptr) <= 255) { #line 1542 "dk-ls.ctr" switch ((char)(*piptr)) { case 'n' : { #line 1544 "dk-ls.ctr" if (dkT('\0') != lasti) { if (0 == dk4fputc(dkT(' '), stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } if (0 == dk4fputs(fn, stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } last_was_n = 1; } break; case 'N' : { #line 1555 "dk-ls.ctr" if (dkT('\0') != lasti) { if (0 == dk4fputc(dkT(' '), stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } if (0 == dk4fputs(fn, stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } break; case 's' : { #line 1565 "dk-ls.ctr" if (dkT('\0') != lasti) { if (0 == dk4fputc(dkT(' '), stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } res = 0; if (0 != use_size) { if (0 != ovsize) { /* Show Overflow */ dk4error_set_simple_error_code(&er_bytes, DK4_E_MATH_OVERFLOW); slen = dk4str_len(dk_ls_msg[2]); numl = dk4numlength(sizeof(dk4_um_t), 0); tlen = (numl - slen) / 2; for (i = 0; i < tlen; i++) { if (0 == dk4fputc(dkT('-'), stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } if (0 == dk4fputs(dk_ls_msg[2], stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } for (i = (tlen + slen); i < numl; i++) { if (0 == dk4fputc(dkT('-'), stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } } else { /* Show size */ fs = size; res = 1; } } else { dk4error_init(&er); res = dk4fileinfo_size( &fs, fiptr, ( (0 != issl) ? (DK4_FILE_INFO_CONTENTS_DATA_LINK) : (DK4_FILE_INFO_CONTENTS_DATA_TARGET) ), &er ); if (0 == res) { /* ERROR: Failed to obtain size */ #line 1610 "dk-ls.ctr" dk_ls_report_fileinfo_size_error( app, fn, ( (0 != issl) ? (DK4_FILE_INFO_CONTENTS_DATA_LINK) : (DK4_FILE_INFO_CONTENTS_DATA_TARGET) ), dk_ls_msg, dk_ls_sz_msg ); } } if (0 != res) { numl = dk4numlength(sizeof(dk4_um_t), 0); dk_ls_write_decimal_number(fs, numl); if (0 != show_summary) { size_bytes = dk4ma_um_add(size_bytes, fs, &er_bytes); } } } break; case 't' : { #line 1630 "dk-ls.ctr" dk4error_init(&er); if (0 == habuf) { habuf = dk4fileinfo_type_attributes( abuf, DK4_SIZEOF(abuf,dkChar), fiptr, &er ); } if (0 != habuf) { if (dkT('\0') != lasti) { if (0 == dk4fputc(dkT(' '), stdout, &er)) { write_error = 1; exval = EXIT_FAILURE; } } if (0 == dk4fputc(abuf[0], stdout, &er)) { write_error = 1; exval = EXIT_FAILURE; } if (0 == dk4fputc(abuf[1], stdout, &er)) { write_error = 1; exval = EXIT_FAILURE; } } else { /* ERROR: Failed to obtain file type */ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 10); } } break; case 'p' : { if (0 == habuf) { habuf = dk4fileinfo_type_attributes( abuf, DK4_SIZEOF(abuf,dkChar), fiptr, &er ); } if (0 != habuf) { if ((dkT('\0') != lasti) && (dkT('t') != lasti)) { if (0 == dk4fputc(dkT(' '), stdout, &er)) { write_error = 1; exval = EXIT_FAILURE; } } if (0 == dk4fputs(&(abuf[2]), stdout, &er)) { write_error = 1; exval = EXIT_FAILURE; } } else { /* ERROR: Failed to obtain file type */ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 10); } } break; case 'l' : { #line 1674 "dk-ls.ctr" fs = (dk4_um_t)1UL; if (0 != issl) { if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & fiptr->contents)) { #if DK4_ON_WINDOWS fs = (dk4_um_t)((fiptr->linfo).nNumberOfLinks); #else fs = (dk4_um_t)((fiptr->lstb).st_nlink); #endif } } else { if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & fiptr->contents)) { #if DK4_ON_WINDOWS fs = (dk4_um_t)((fiptr->tinfo).nNumberOfLinks); #else fs = (dk4_um_t)((fiptr->tstb).st_nlink); #endif } } #if DK4_ON_WINDOWS if ((DWORD)0UL == fiptr->resio) { #endif dk_ls_write_decimal_number( fs, #if DK4_ON_WINDOWS dk4numlength(sizeof(DWORD), 0) #else dk4numlength(sizeof(nlink_t), 0) #endif ); #if DK4_ON_WINDOWS } else { slen = dk4numlength(sizeof(DWORD), 0); for (i = 1; i < slen; i++) { if (0 == dk4fputc(dkT(' '), stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } if (0 == dk4fputc(dkT('?'), stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } #endif } break; case 'c' : { #line 1720 "dk-ls.ctr" if (dkT('\0') != lasti) { if (0 == dk4fputc(dkT(' '), stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } dk_ls_write_timestamp(fiptr, fn, DK4_FILE_INFO_TIME_CREATE, issl); } break; case 'm' : { #line 1728 "dk-ls.ctr" if (dkT('\0') != lasti) { if (0 == dk4fputc(dkT(' '), stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } dk_ls_write_timestamp(fiptr, fn, DK4_FILE_INFO_TIME_MODIFY, issl); } break; case 'a' : { #line 1736 "dk-ls.ctr" if (dkT('\0') != lasti) { if (0 == dk4fputc(dkT(' '), stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } dk_ls_write_timestamp(fiptr, fn, DK4_FILE_INFO_TIME_ACCESS, issl); } break; #if !DK4_ON_WINDOWS case 'u' : { #line 1745 "dk-ls.ctr" if (dkT('\0') != lasti) { if (0 == dk4fputc(dkT(' '), stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } if (0 != issl) { if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & fiptr->contents)) { dk_ls_write_decimal_number( (fiptr->lstb).st_uid, dk4numlength(sizeof(uid_t), 0) ); } else { dk_ls_write_unknown(dk4numlength(sizeof(uid_t), 0), 0); } } else { if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & fiptr->contents)) { dk_ls_write_decimal_number( (fiptr->tstb).st_uid, dk4numlength(sizeof(uid_t), 0) ); } else { dk_ls_write_unknown(dk4numlength(sizeof(uid_t), 0), 0); } } } break; #endif #if !DK4_ON_WINDOWS case 'g' : { #line 1779 "dk-ls.ctr" if (dkT('\0') != lasti) { if (0 == dk4fputc(dkT(' '), stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } if (0 != issl) { if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & fiptr->contents)) { dk_ls_write_decimal_number( (fiptr->lstb).st_gid, dk4numlength(sizeof(gid_t), 0) ); } else { dk_ls_write_unknown(dk4numlength(sizeof(gid_t), 0), 0); } } else { if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & fiptr->contents)) { dk_ls_write_decimal_number( (fiptr->tstb).st_gid, dk4numlength(sizeof(gid_t), 0) ); } else { dk_ls_write_unknown(dk4numlength(sizeof(gid_t), 0), 0); } } } break; #endif case 'd' : { #line 1812 "dk-ls.ctr" if (dkT('\0') != lasti) { if (0 == dk4fputc(dkT(' '), stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } #if DK4_ON_WINDOWS if (0 != issl) { if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & fiptr->contents)) { if ((DWORD)0UL == fiptr->resio) { dk_ls_write_hexadecimal_number( (fiptr->linfo).dwVolumeSerialNumber, 2*sizeof(DWORD) ); } else { dk_ls_write_unknown(2*sizeof(DWORD), 1); } } else { dk_ls_write_unknown(2*sizeof(DWORD), 1); } } else { if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & fiptr->contents)) { if ((DWORD)0UL == fiptr->resio) { dk_ls_write_hexadecimal_number( (fiptr->tinfo).dwVolumeSerialNumber, 2*sizeof(DWORD) ); } else { dk_ls_write_unknown(2*sizeof(DWORD), 1); } } else { dk_ls_write_unknown(2*sizeof(DWORD), 1); } } #else if (0 != issl) { if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & fiptr->contents)) { dk_ls_write_hexadecimal_number( (fiptr->lstb).st_dev, 2*sizeof(dev_t) ); } else { dk_ls_write_unknown(2*sizeof(dev_t), 1); } } else { if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & fiptr->contents)) { dk_ls_write_hexadecimal_number( (fiptr->tstb).st_dev, 2*sizeof(dev_t) ); } else { dk_ls_write_unknown(2*sizeof(dev_t), 1); } } #endif } break; case 'r' : { #line 1876 "dk-ls.ctr" #if DK4_ON_WINDOWS if (0 != issl) { if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & fiptr->contents)) { if ((DWORD)0UL == fiptr->resio) { dk_ls_write_hexadecimal_number( (fiptr->linfo).dwVolumeSerialNumber, 2*sizeof(DWORD) ); } else { dk_ls_write_unknown(2*sizeof(DWORD), 1); } } else { dk_ls_write_unknown(2*sizeof(DWORD), 1); } } else { if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & fiptr->contents)) { if ((DWORD)0UL == fiptr->resio) { dk_ls_write_hexadecimal_number( (fiptr->tinfo).dwVolumeSerialNumber, 2*sizeof(DWORD) ); } else { dk_ls_write_unknown(2*sizeof(DWORD), 1); } } else { dk_ls_write_unknown(2*sizeof(DWORD), 1); } } #else if (0 != issl) { if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & fiptr->contents)) { dk_ls_write_hexadecimal_number( (fiptr->lstb).st_rdev, 2*sizeof(dev_t) ); } else { dk_ls_write_unknown(2*sizeof(dev_t), 1); } } else { if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & fiptr->contents)) { dk_ls_write_hexadecimal_number( (fiptr->tstb).st_rdev, 2*sizeof(dev_t) ); } else { dk_ls_write_unknown(2*sizeof(dev_t), 1); } } #endif } break; case 'i' : { #line 1935 "dk-ls.ctr" if (dkT('\0') != lasti) { if (dkT('d') != lasti) { if (0 == dk4fputc(dkT(' '), stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } else { if (0 == dk4fputc(dkT(':'), stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } } #if DK4_ON_WINDOWS if (0 != issl) { if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & fiptr->contents)) { if ((DWORD)0UL == fiptr->resio) { dk_ls_write_hexadecimal_number( (fiptr->linfo).nFileIndexHigh, 2*sizeof(DWORD) ); dk_ls_write_hexadecimal_number( (fiptr->linfo).nFileIndexLow, 2*sizeof(DWORD) ); } else { dk_ls_write_unknown(4*sizeof(DWORD), 1); } } else { dk_ls_write_unknown(4*sizeof(DWORD), 1); } } else { if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & fiptr->contents)) { if ((DWORD)0UL == fiptr->resio) { dk_ls_write_hexadecimal_number( (fiptr->tinfo).nFileIndexHigh, 2*sizeof(DWORD) ); dk_ls_write_hexadecimal_number( (fiptr->tinfo).nFileIndexLow, 2*sizeof(DWORD) ); } else { dk_ls_write_unknown(4*sizeof(DWORD), 1); } } else { dk_ls_write_unknown(4*sizeof(DWORD), 1); } } #else if (0 != issl) { if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & fiptr->contents)) { dk_ls_write_hexadecimal_number( (fiptr->lstb).st_ino, 2*sizeof(ino_t) ); } else { dk_ls_write_unknown(2*sizeof(ino_t), 1); } } else { if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & fiptr->contents)) { dk_ls_write_hexadecimal_number( (fiptr->tstb).st_ino, 2*sizeof(ino_t) ); } else { dk_ls_write_unknown(2*sizeof(ino_t), 1); } } #endif } break; #if DK4_ON_WINDOWS case 'w' : { #line 2012 "dk-ls.ctr" if (dkT('\0') != lasti) { if (0 == dk4fputc(dkT(' '), stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } dk_ls_write_hexadecimal_number( fiptr->rppnt, 2*sizeof(DWORD) ); } break; #endif case 'x' : { if (0 != dk4md_check_type(digest_type)) { if (dkT('\0') != lasti) { if (0 == dk4fputc(dkT(' '), stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } dk_ls_write_md( fn, fiptr, digest_type, digest_enco, app, dk_ls_msg, dk_ls_sz_msg ); } else { /* ERROR (once) Message digest type not supported */ if (0 == digest_erep) { dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 19); digest_erep = 1; } } } break; default : { /* ERROR (once): Invalid text in -p argument */ if (0 == print_order_error_reported) { dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 11); print_order_error_reported = 1; } exval = EXIT_FAILURE; } break; } } else { /* ERROR (once): Invalid text in -p argument */ if (0 == print_order_error_reported) { dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 11); print_order_error_reported = 1; } exval = EXIT_FAILURE; } lasti = *(piptr++); } if (0 != last_was_n) { if (0 != dk4fileinfo_is_symlink(fiptr)) { res = dk4symlink_target( dk_ls_sl_target, DK4_SIZEOF(dk_ls_sl_target,dkChar), fn, NULL ); if (0 != res) { if (0 == dk4fputs(dk_ls_kwnl[7], stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } if (0 == dk4fputs(dk_ls_sl_target, stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } else { /* ERROR: Failed to find symlink target */ dk4app_log_3(app,dk_ls_msg,dk_ls_sz_msg,DK4_LL_ERROR,12,13,fn); exval = EXIT_FAILURE; } } } if (0 == dk4fputc(dkT('\n'), stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } else { #line 2083 "dk-ls.ctr" } } else { #line 2085 "dk-ls.ctr" } #line 2087 "dk-ls.ctr" } /** Process non-directory file. @param fn File name. @param level Processing level (0=cmd line arg, 1=direct child, 2 and above=further indicrect siblings). */ static void dk_ls_process_non_directory(const dkChar *fn, int level) { dk4_file_info_t fili; dk4fileinfo_init(&fili); if (0 != dk4fileinfo_app(&fili, fn, app)) { dk_ls_process_item_information(fn, &fili, 0, (dk4_um_t)0UL, 0); } else { /* ERROR: Failed to obtain information about file, already reported */ exval = EXIT_FAILURE; } } /** Process one directory item. @param dirnode Node for the items parent directory. @param filename Path name for item. */ static void dk_ls_process_item_for_node( dk_ls_node_t *dirnode, const dkChar *filename ) { dk4_file_info_t fili; dk4_er_t er; dk4_um_t fs; int ch = DK4_FILE_INFO_CONTENTS_DATA_TARGET; #line 2129 "dk-ls.ctr" if ((0 >= dirnode->level) || (0 != recursive) || (0 != size_wanted)) { dk4error_init(&er); dk4fileinfo_init(&fili); if (0 != dk4fileinfo_app(&fili, filename, app)) { if (0 != dk4fileinfo_is_symlink(&fili)) { ch = DK4_FILE_INFO_CONTENTS_DATA_LINK ; } if (0 != dk4fileinfo_size(&fs, &fili, ch, &er)) { dirnode->size = dk4ma_um_add(dirnode->size, fs, &er); if (DK4_E_MATH_OVERFLOW == er.ec) { dirnode->ovsize = 1; } } else { /* ERROR: Failed to retrieve size */ #line 2145 "dk-ls.ctr" dk_ls_report_fileinfo_size_error( app, filename, ch, dk_ls_msg, dk_ls_sz_msg ); fs = (dk4_um_t)0UL; exval = EXIT_FAILURE; } if ((0 >= dirnode->level ) || (0 != recursive)) { /* Show file information */ dk_ls_process_item_information( filename, &fili, 0, (dk4_um_t)0UL, 0 ); } } else { /* ERROR: Failed to obtain file information, already reported */ exval = EXIT_FAILURE; } } #line 2163 "dk-ls.ctr" } /** Process directory. Unless required otherwise by a non-zero value for recursive, show contents and directory for level=0, directory itself for level=1. @param dn Directory name. @param level Processing level (0=cmd line arg, 1=direct child, 2 and above=further siblings). */ static void dk_ls_process_directory(const dkChar *dn, int level) { dk4_ufi_t pdufi; /* UFI for parent directory */ dk4_ufi_t sdufi; /* UFI for sub directory */ dk4_er_t er; /* Error report for size addition */ dkChar *mybu; /* Buffer for path name construction */ #if VERSION_BEFORE_20150821 dk_ls_node_t *rn; /* Root node */ #endif dk_ls_node_t *cn; /* Current node */ dk_ls_node_t *on; /* Other node */ const dkChar *pa; /* Directory path */ const dkChar *ndn; /* Next directory name */ size_t szmb; /* Size of mybu (number of dkChar) */ int gosub; /* Flag: Go into sub directory */ int ufich; /* Channel to retrieve UFI */ #line 2193 "dk-ls.ctr" /* Allocate path name construction buffer. */ ufich = DK4_FILE_INFO_CONTENTS_DATA_TARGET; szmb = DK4_MAX_PATH; mybu = dk4mem_new_app(dkChar,szmb,app); /* If path name construction buffer available, run normally. */ if (NULL != mybu) { #if VERSION_BEFORE_20150821 rn = cn = dk_ls_new_node(dn, NULL, level); #else cn = dk_ls_new_node(dn, NULL, level); #endif while (NULL != cn) { #line 2209 "dk-ls.ctr" if (0 != dk_ls_can_continue()) { #line 2210 "dk-ls.ctr" ndn = dk4dir_next_dir(cn->dirptr); if (NULL != ndn) { /* Handle sub directory. */ pa = dk4dir_get_path(cn->dirptr); if (0 != dk_ls_construct_path(&mybu, &szmb, pa, ndn)) { /* Decide whether or not to go into subdirectory */ gosub = 0; #if 0 /* 2015-04-14 There is no reason to open a node for the subdirectory unless recursive output or size calculation is wanted. */ if (0 == cn->level) { /* Processing cmd line argument */ gosub = 1; } #endif if (0 != recursive) { /* Recursive output wanted */ gosub = 1; } if (0 != size_wanted) { /* Size calculation required */ if (0 != show_dirs) { /* ... and directory information wanted */ gosub = 1; } } if (0 != gosub) { if (0 != dk4ufi_get(&sdufi, mybu, NULL)) { if (0 != stay_on_fs) { /* Check for same filesystem */ if (0 != dk4fileinfo_ufi(&pdufi, &(cn->fi), ufich, NULL)) { #if DK4_ON_WINDOWS if (pdufi.ser != sdufi.ser) { gosub = 0; } #else if (pdufi.dev != sdufi.dev) { gosub = 0; } #endif } else { /* ERROR: Failed to obtain file identifier */ dk4app_log_3( app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 14, 15, dk4dir_get_path(cn->dirptr) ); gosub = 0; exval = EXIT_FAILURE; } } if (0 != gosub) { /* Check for symlink loop */ on = cn; while ((0 != gosub) && (NULL != on)) { if (0 != dk4fileinfo_ufi(&pdufi, &(on->fi), ufich, NULL)) { #if DK4_ON_WINDOWS if (pdufi.ser == sdufi.ser) { if (pdufi.inh == sdufi.inh) { if (pdufi.inl == sdufi.inl) { gosub = 0; } } } #else if (pdufi.dev == sdufi.dev) { if (pdufi.ino == sdufi.ino) { gosub = 0; } } #endif } else { /* ERROR: Failed to retrieve UFI for directory */ dk4app_log_3( app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 14, 15, dk4dir_get_path(on->dirptr) ); exval = EXIT_FAILURE; gosub = 0; } on = on->parent; } } } else { /* ERROR: Failed to retrieve unique file identifier */ dk4app_log_3( app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 14, 15, mybu ); exval = EXIT_FAILURE; gosub = 0; } } if (0 != gosub) { /* Go into subdirectory. */ on = dk_ls_new_node( mybu, cn, ((3 >= cn->level) ? (1 + cn->level) : 3) ); if (NULL != on) { cn->child = on; cn = on; } else { /* ERROR: Failed to create node, already reported */ exval = EXIT_FAILURE; } } else { /* Do not go into subdirectory, probably show directory details. */ dk_ls_process_item_for_node(cn, mybu); } } else { /* ERROR: Failed to construct path, already reported */ exval = EXIT_FAILURE; } } else { /* Finalize node, report non-directory entries and the directories, finally move to parent node. */ if ((0 != size_wanted) || (0 != show_files)) { if (0 != dk_ls_can_continue()) { do { ndn = dk4dir_next_file(cn->dirptr); if (NULL != ndn) { #line 2336 "dk-ls.ctr" pa = dk4dir_get_path(cn->dirptr); if (0 != dk_ls_construct_path(&mybu, &szmb, pa, ndn)) { dk_ls_process_item_for_node(cn, mybu); } else { /* ERROR: Failed to construct path, already reported */ exval = EXIT_FAILURE; } } } while((0 != dk_ls_can_continue()) && (NULL != ndn)) ; } } if (0 != dk_ls_can_continue()) { #line 2348 "dk-ls.ctr" if ((0 != size_wanted) || (0 != show_dirs)) { if ((1 >= cn->level) || (0 != recursive)) { dk_ls_process_item_information( dk4dir_get_path(cn->dirptr), &(cn->fi), 1, cn->size, cn->ovsize ); } } } on = cn->parent; if (NULL != on) { on->child = NULL; dk4error_init(&er); on->size = dk4ma_size_t_add(on->size, cn->size, &er); if (DK4_E_NONE != er.ec) { on->ovsize = 1; } if (0 != cn->ovsize) { on->ovsize = 1; } } dk_ls_delete_node(cn); cn = on; } } else { /* Abort: Close current node and move to parent. No output. */ #line 2377 "dk-ls.ctr" on = cn->parent; if (NULL != on) { on->child = NULL; } dk_ls_delete_node(cn); cn = on; } } } else { #line 2384 "dk-ls.ctr" /* ERROR: Allocation failed, already reported */ exval = EXIT_FAILURE; } /* Release path name construction buffer. */ if (NULL != mybu) { dk4mem_release(mybu); } #line 2394 "dk-ls.ctr" } /** Check whether the specified file name is a directory. @param fn File name. @return 1 for directories, 0 for non-directory entries, -1 on errors. */ static int dk_ls_is_directory(const dkChar *fn) { #if DK4_ON_WINDOWS DWORD dwattr; HANDLE ha; LONG lasterror; #if DK4_CHAR_SIZE > 1 WIN32_FIND_DATAW finddata; #else WIN32_FIND_DATAA finddata; #endif #else dk4_stat_t stb; dk4_er_t er; #endif int back = -1; #line 2422 "dk-ls.ctr" if (NULL != fn) { #if DK4_ON_WINDOWS #if DK4_CHAR_SIZE > 1 dwattr = GetFileAttributesW(fn); #else dwattr = GetFileAttributesA(fn); #endif if (INVALID_FILE_ATTRIBUTES != dwattr) { if (0 != (FILE_ATTRIBUTE_DIRECTORY & dwattr)) { back = 1; } else { back = 0; } } else { lasterror = GetLastError(); #if DK4_CHAR_SIZE > 1 ha = FindFirstFileW(fn, &finddata); #else ha = FindFirstFileA(fn, &finddata); #endif if (INVALID_HANDLE_VALUE != ha) { if (0 != (FILE_ATTRIBUTE_DIRECTORY & (finddata.dwFileAttributes))) { back = 1; } else { back = 0; } FindClose(ha); } else { /* ERROR: Failed to retrieve file attributes */ dk4fileinfo_report_win_failed(app, fn, lasterror); exval = EXIT_FAILURE; } } #else dk4error_init(&er); if (0 != dk4stat(&stb, fn, &er)) { if (0 != dk4stat_is_directory(&stb, &er)) { back = 1; } else { back = 0; } } else { /* ERROR: Failed to retrieve file information */ dk4fileinfo_report_stat_failed(app, fn, er.dt.iDetails1); exval = EXIT_FAILURE; } #endif } #line 2470 "dk-ls.ctr" return back; } /* !!!!! For files explicitly mentioned on the command line processing starts here, probably after name expansion. */ /** Run for one file or directory directly named on the command line. @param arg Path name. */ static void run_for_one_name(const dkChar *arg) { #line 2488 "dk-ls.ctr" switch (dk_ls_is_directory(arg)) { case 1 : { #line 2490 "dk-ls.ctr" dk_ls_process_directory(arg, 0); } break; case 0 : { #line 2493 "dk-ls.ctr" if (0 != show_files) { dk_ls_process_non_directory(arg, 0); } } break; default : { #line 2498 "dk-ls.ctr" /* ERROR: Failed to obtain information about file, already reported */ exval = EXIT_FAILURE; } break; } #line 2503 "dk-ls.ctr" } /** Process command line arguments. @param xargc Number of command line arguments. */ static void run_for_command_line_arguments(int xargc) { #if DK4_ON_WINDOWS dkChar buf[DK4_MAX_PATH]; dk4_dir_t *fne; const dkChar *pth; const dkChar *fn; int cc2; #endif const dkChar *xargv; int i; int cc = 1; #line 2525 "dk-ls.ctr" for (i = 0; ((i < xargc) && (1 == cc)); i++) { #line 2526 "dk-ls.ctr" if (0 != dk_ls_can_continue()) { #line 2527 "dk-ls.ctr" xargv = dk4app_get_argv(app, i); #line 2528 "dk-ls.ctr" #if DK4_ON_WINDOWS if (0 != dk4path_must_expand(xargv)) { /* !!!!! For file names we need to expand processing starts here. */ fne = dk4app_fne_open(xargv, app); if (NULL != fne) { cc2 = 1; while (1 == cc2) { if (0 != dk_ls_can_continue()) { fn = dk4dir_next_dir(fne); if (NULL != fn) { 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_ls_kwnl[5],NULL)) { if (0 != dk4str_cat_s(buf,DK4_SIZEOF(buf,dkChar),fn,NULL)) { dk_ls_process_directory(buf, 0); } else { /* ERROR: File name too long! */ dk4app_log_5( app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 16, 17, 18, pth, fn ); exval = EXIT_FAILURE; } } else { /* ERROR: File name too long! */ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth); exval = EXIT_FAILURE; } } else { /* ERROR: File name too long! */ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth); exval = EXIT_FAILURE; } } else { run_for_one_name(fn); } } else { cc2 = 0; } } else { cc2 = 0; } } cc2 = 1; while (1 == cc2) { if (0 != dk_ls_can_continue()) { fn = dk4dir_next_file(fne); if (NULL != fn) { 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_ls_kwnl[5],NULL)) { if (0 != dk4str_cat_s(buf,DK4_SIZEOF(buf,dkChar),fn,NULL)) { dk_ls_process_non_directory(buf, 0); } else { /* ERROR: File name too long! */ dk4app_log_5( app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 16, 17, 18, pth, fn ); exval = EXIT_FAILURE; } } else { /* ERROR: File name too long! */ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth); exval = EXIT_FAILURE; } } else { /* ERROR: File name too long! */ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth); exval = EXIT_FAILURE; } } else { run_for_one_name(fn); } } else { cc2 = 0; } } else { cc2 = 0; } } dk4dir_close(fne); } else { /* ERROR: Failed to expand file name, already reported */ exval = EXIT_FAILURE; } } else { #endif #line 2624 "dk-ls.ctr" run_for_one_name(xargv); #if DK4_ON_WINDOWS } #endif } else { cc = 0; } } #line 2633 "dk-ls.ctr" } /* !!!!! If no file names was given on the command line processing starts here. */ /** Show contents of current directory. */ static void run_for_current_dir_contents(void) { dk4_er_t er; dk4_dir_t *dirptr; const dkChar *fn; int cc; int om; #line 2654 "dk-ls.ctr" dk4error_init(&er); om = DK4_DIR_OPEN_SORTED | DK4_DIR_SYMLINK_DIR_AS_FILE; dirptr = dk4dir_open_app(dk_ls_kwnl[4], om, app); if (NULL != dirptr) { if ((0 != recursive) || (0 != show_dirs)) { cc = 1; while(1 == cc) { if (0 != dk_ls_can_continue()) { fn = dk4dir_next_dir(dirptr); if (NULL != fn) { if ((0 != recursive) || (0 != size_wanted)) { dk_ls_process_directory(fn, 1); } else { dk_ls_process_non_directory(fn, 1); } } else { cc = 0; } } else { cc = 0; } } } if (0 != show_files) { cc = 1; while (1 == cc) { if (0 != dk_ls_can_continue()) { fn = dk4dir_next_file(dirptr); if (NULL != fn) { dk_ls_process_non_directory(fn, 1); } else { cc = 0; } } else { cc = 0; } } } dk4dir_close(dirptr); } else { /* ERROR: Failed to open current directory, already reported */ exval = EXIT_FAILURE; } #line 2698 "dk-ls.ctr" } /** Process command line arguments (if any). */ static void dk_ls_normal_run(void) { dkChar mdbuf[32]; dkChar *bptr; int res; int xargc; int mdset; #line 2714 "dk-ls.ctr" exval = EXIT_SUCCESS; /* Process options. */ if (0 != dk4app_opt_is_set_short(app, dkT('p'), NULL)) { res = dk4app_opt_get_string_short( po_buf, DK4_SIZEOF(po_buf,dkChar), app, dkT('p'), NULL ); if (0 != res) { print_order = po_buf; } } if (NULL == print_order) { if (0 == dk4app_opt_is_set_short(app, dkT('R'), NULL)) { res = dk4app_pref_get( po_buf, DK4_SIZEOF(po_buf,dkChar), app, dk_ls_kwnl[10], 0 ); if (0 != res) { dk4str_rtwh(po_buf, NULL); print_order = dk4str_start(po_buf, NULL); } } } if (NULL == print_order) { #if DK4_ON_WINDOWS print_order = dk_ls_kwnl[8]; #else print_order = dk_ls_kwnl[3]; #endif } if (NULL != dk4str_chr(print_order, dkT('s'))) { size_wanted = 1; } if (NULL != dk4str_chr(print_order, dkT('n'))) { name_wanted = 1; } if (0 != dk4app_opt_is_set_short(app, dkT('r'), NULL)) { recursive = 1; } if (0 != dk4app_opt_is_set_short(app, dkT('f'), NULL)) { stay_on_fs = 1; } if (0 != dk4app_opt_is_set_short(app, dkT('t'), NULL)) { res = dk4app_opt_get_string_short( mdbuf, DK4_SIZEOF(mdbuf,dkChar), app, dkT('t'), NULL ); if (0 != res) { bptr = mdbuf; show_files = 0; show_dirs = 0; while (dkT('\0') != *bptr) { if (dkT('d') == *bptr) { show_dirs = 1; } if (dkT('f') == *bptr) { show_files = 1; } bptr++; } } } mdset = 0; if (0 != dk4app_opt_is_set_short(app, dkT('m'), NULL)) { res = dk4app_opt_get_string_short( mdbuf, DK4_SIZEOF(mdbuf,dkChar), app, dkT('m'), NULL ); if (0 != res) { /* Process string, find digest and encoding */ mdset = 1; dk_ls_set_md( &digest_type, &digest_enco, mdbuf, app, dk_ls_msg, dk_ls_sz_msg ); } } if (0 != dk4app_opt_is_set_short(app, dkT('s'), NULL)) { show_summary = 1; } if ((0 == mdset) && (0 == dk4app_opt_is_set_short(app, dkT('R'), NULL))) { res = dk4app_pref_get( mdbuf, DK4_SIZEOF(mdbuf,dkChar), app, dk_ls_kwnl[9], 0 ); if (0 != res) { dk_ls_set_md( &digest_type, &digest_enco, mdbuf, app, dk_ls_msg, dk_ls_sz_msg ); } } /* Process command line arguments or current directory contents. */ xargc = dk4app_get_argc(app); if (0 < xargc) { #line 2801 "dk-ls.ctr" run_for_command_line_arguments(xargc); } else { #line 2803 "dk-ls.ctr" run_for_current_dir_contents(); } if (0 != show_summary) { if (((dk4_um_t)0UL != num_dirs) && (DK4_E_NONE == er_dirs.ec)) { if (0 == dk4fputs(dk_ls_msg[30], stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } dk_ls_write_decimal_number(num_dirs,dk4numlength(sizeof(dk4_um_t),0)); if (0 == dk4fputc(dkT('\n'), stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } if (((dk4_um_t)0UL != num_files) && (DK4_E_NONE == er_files.ec)) { if (0 == dk4fputs(dk_ls_msg[31], stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } dk_ls_write_decimal_number(num_files,dk4numlength(sizeof(dk4_um_t),0)); if (0 == dk4fputc(dkT('\n'), stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } if (((dk4_um_t)0UL != size_bytes) && (DK4_E_NONE == er_bytes.ec)) { if (0 == dk4fputs(dk_ls_msg[32], stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } dk_ls_write_decimal_number(size_bytes,dk4numlength(sizeof(dk4_um_t),0)); if (0 == dk4fputc(dkT('\n'), stdout, NULL)) { write_error = 1; exval = EXIT_FAILURE; } } } #line 2835 "dk-ls.ctr" } #if DK4_HAVE_SIGACTION /** Set signal handlers and run. */ static void dk_ls_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_ls_msg, dk_ls_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_ls_msg, dk_ls_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_ls_msg, dk_ls_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_ls_msg, dk_ls_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_ls_msg, dk_ls_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_ls_msg, dk_ls_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_ls_msg, dk_ls_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_ls_msg, dk_ls_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_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 0); goto restore_old_int; } success = 1; dk_ls_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_ls_msg, dk_ls_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_ls_msg, dk_ls_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_ls_msg, dk_ls_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_ls_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_ls_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_ls_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_ls_normal_run(); signal(SIGTERM, oldterm); signal(SIGINT, oldint); #ifdef SIGPIPE signal(SIGPIPE, oldpipe); #endif } #else /** Set signal handlers and run. */ static void dk_ls_run_with_signal_handlers(void) { dk_ls_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 { #line 3039 "dk-ls.ctr" #line 3040 "dk-ls.ctr" dk4fput_initialize_stdout(); dk4fput_initialize_stderr(); dk4error_init(&er_dirs); dk4error_init(&er_files); dk4error_init(&er_bytes); app = dk4app_open_cmd( argc, argv, dk_ls_options, dk_ls_sz_options, dk_ls_kwnl[0], DKT_VERSION_DK, dk_ls_kwnl[1], dk_ls_help_text, dk_ls_license_text ); if (NULL != app) { #line 3051 "dk-ls.ctr" dk_ls_sz_msg = dk4app_string_table_size(dk_ls_kw_def); dk_ls_msg = dk4app_string_table(app, dk_ls_kwnl[2], dk_ls_kw_def); if (0 != dk4app_can_run_normally(app)) { #line 3054 "dk-ls.ctr" dk_ls_run_with_signal_handlers(); } else { if (0 != dk4app_help_version_license(app)) { #line 3057 "dk-ls.ctr" exval = EXIT_SUCCESS; } } dk4app_close(app); } else { #line 3062 "dk-ls.ctr" dk4fputs(dk_ls_kwnl[11], stdout, NULL); fflush(stdout); } fflush(stdout); fflush(stderr); dk4fput_cleanup_stderr(); dk4fput_cleanup_stdout(); #line 3070 "dk-ls.ctr" #line 3071 "dk-ls.ctr" exit(exval); return exval; }